guix-channel

A channel for the Guix package manager

git clone https://git.8pit.net/guix-channel.git

  1(define-module (nmeum services networking)
  2  #:use-module (guix gexp)
  3  #:use-module (gnu packages admin)
  4  #:use-module (gnu packages dns)
  5  #:use-module (gnu services)
  6  #:use-module (gnu system shadow)
  7  #:use-module (gnu system accounts)
  8  #:use-module (gnu services configuration)
  9  #:use-module (gnu services shepherd)
 10  #:use-module ((srfi srfi-1) #:select (concatenate))
 11  #:use-module ((srfi srfi-13) #:select (string-join))
 12  #:use-module ((srfi srfi-26) #:select (cut))
 13
 14  #:export (dhcpcd-service-type
 15            dhcpcd-configuration
 16            dhcpcd-configuration?
 17            dhcpcd-configuration-interfaces
 18            dhcpcd-configuration-command-args
 19            dhcpcd-configuration-hostname
 20            dhcpcd-configuration-duid
 21            dhcpcd-configuration-persistent
 22            dhcpcd-configuration-option
 23            dhcpcd-configuration-require
 24            dhcpcd-configuration-slaac
 25            dhcpcd-configuration-nooption
 26            dhcpcd-configuration-nohook
 27            dhcpcd-configuration-static
 28            dhcpcd-configuration-vendorclassid
 29            dhcpcd-configuration-clientid
 30            dhcpcd-configuration-extra-content))
 31
 32;;
 33;; DHCPCD.
 34;;
 35
 36(define (dhcpcd-serialize-string field-name value)
 37  (let ((field (object->string field-name)))
 38    (if (string=? field "extra-content")
 39      #~(string-append #$value "\n")
 40      #~(format #f "~a ~a~%" #$field #$value))))
 41
 42(define (dhcpcd-serialize-boolean field-name value)
 43  (if value
 44    #~(format #f "~a~%" #$(object->string field-name))
 45    ""))
 46
 47(define (dhcpcd-serialize-list-of-strings field-name value)
 48  #~(string-append #$@(map (cut dhcpcd-serialize-string field-name <>) value)))
 49
 50;; Some fields (e.g. hostname) can be specified with an empty string argument.
 51;; Therefore, we need a maybe type to differentiate disabled/empty-string.
 52(define-maybe string (prefix dhcpcd-))
 53
 54(define-configuration dhcpcd-configuration
 55  (interfaces
 56    (list '())
 57    "List of interfaces to start a DHCP client for."
 58    empty-serializer)
 59  (command-args
 60    (list '("-q" "-q"))
 61    "List of additional command-line options."
 62    empty-serializer)
 63
 64  ;; The following defaults replicate the default dhcpcd configuration file.
 65  ;;
 66  ;; See https://github.com/NetworkConfiguration/dhcpcd/tree/v10.0.10#configuration
 67  (hostname
 68    (maybe-string "")
 69    "Hostname to send via DHCP, defaults to the current system hostname.")
 70  (duid
 71    (maybe-string "")
 72    "Use and generate a DHCP Unique Identifier.")
 73  (persistent
 74    (boolean #t)
 75    "Do not de-configure on shutdown.")
 76  (option
 77    (list-of-strings
 78      '("rapid_commit"
 79        "domain_name_servers"
 80        "domain_name"
 81        "domain_search"
 82        "host_name"
 83        "classless_static_routes"
 84        "interface_mtu"))
 85    "List of options to request from the server.")
 86  (require
 87    (list-of-strings '("dhcp_server_identifier"))
 88    "List of options to require in responses.")
 89  (slaac
 90    (maybe-string "private")
 91    "Interface identifier used for SLAAC generated IPv6 addresses.")
 92
 93  ;; Common options not set in the default configuration file.
 94  (nooption
 95    (list-of-strings '())
 96    "List of options to remove from the message before it's processed.")
 97  (nohook
 98    (list-of-strings '())
 99    "List of hook script which should not be invoked.")
100  (static
101    (list-of-strings '())
102    "Configure a static value (e.g. ip_address).")
103  (vendorclassid
104    maybe-string
105    "Set the DHCP Vendor Class.")
106  (clientid
107    maybe-string
108    "Use the interface hardware address or the given string as a Client ID.")
109
110  ;; Escape hatch for the generated configuration file.
111  (extra-content
112    maybe-string
113    "Extra content to append to the configuration as-is.")
114
115  (prefix dhcpcd-))
116
117(define (dhcpcd-config-file config)
118  (mixed-text-file "dhcpcd.conf"
119    (serialize-configuration
120      config
121      dhcpcd-configuration-fields)))
122
123(define dhcpcd-account-service
124  (list (user-group (name "dhcpcd") (system? #t))
125        (user-account
126          (name "dhcpcd")
127          (group "dhcpcd")
128          (system? #t)
129          (comment "dhcpcd daemon user")
130          (home-directory "/var/empty")
131          (shell (file-append shadow "/sbin/nologin")))))
132
133(define (dhcpcd-shepherd-service config)
134  (let* ((config-file (dhcpcd-config-file config))
135         (command-args (dhcpcd-configuration-command-args config))
136         (ifaces (dhcpcd-configuration-interfaces config)))
137    (list (shepherd-service
138            (documentation "dhcpcd daemon.")
139            (provision '(networking))
140            (requirement '(user-processes udev))
141            (actions (list (shepherd-configuration-action config-file)))
142            (start
143              #~(lambda _
144                  (fork+exec-command
145                    (list (string-append #$dhcpcd "/sbin/dhcpcd")
146                          #$@command-args "-B" "-f" #$config-file #$@ifaces))))
147            (stop #~(make-kill-destructor))))))
148
149(define dhcpcd-service-type
150  (service-type (name 'dhcpcd)
151                (description "Run the dhcpcd daemon.")
152                (extensions
153                 (list (service-extension account-service-type
154                                          (const dhcpcd-account-service))
155                       (service-extension shepherd-root-service-type
156                                          dhcpcd-shepherd-service)))
157                (compose concatenate)
158                (default-value (dhcpcd-configuration))))