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 (nmeum packages networking)
  3  #:use-module (guix gexp)
  4  #:use-module (gnu packages admin)
  5  #:use-module (gnu packages dns)
  6  #:use-module (gnu services)
  7  #:use-module (gnu system shadow)
  8  #:use-module (gnu system accounts)
  9  #:use-module (gnu services configuration)
 10  #:use-module (gnu services shepherd)
 11  #:use-module ((srfi srfi-1) #:select (concatenate))
 12  #:use-module ((srfi srfi-13) #:select (string-join))
 13  #:use-module ((srfi srfi-26) #:select (cut))
 14
 15  #:export (dhcpcd-service-type
 16            dhcpcd-configuration
 17            dhcpcd-configuration?
 18            dhcpcd-configuration-interfaces
 19            dhcpcd-configuration-options))
 20
 21;;
 22;; dhcpcd
 23;;
 24
 25(define-maybe list)
 26
 27;; Ensure that strings within the unbound configuration
 28;; are not enclosed in double quotes by the serialization.
 29(define (->string obj)
 30  (if (string? obj)
 31    obj
 32    (object->string obj)))
 33
 34(define (serialize-list-of-opts field-name lst)
 35  #~(string-append
 36      (string-join
 37        (list
 38          #$@(map
 39               (lambda (lst)
 40                 (string-join (map ->string lst) " "))
 41               lst)) "\n") "\n"))
 42
 43(define (list-of-opts? lst)
 44  (list? lst))
 45
 46(define-configuration dhcpcd-configuration
 47  (interfaces
 48    maybe-list
 49    "List of interfaces to start a DHCP client for."
 50    empty-serializer)
 51  (options
 52    ;; Replicate the default dhcpcd configuration file.
 53    ;; See: https://github.com/NetworkConfiguration/dhcpcd#configuration
 54    (list-of-opts '((hostname)
 55                    (duid)
 56                    (persistent)
 57                    (option rapid_commit)
 58                    (option interface_mtu)
 59                    (require dhcp_server_identifier)
 60                    (slaac private)))
 61    "List of configuration options for dhcpcd."))
 62
 63(define (dhcpcd-config-file config)
 64  (mixed-text-file "dhcpcd.conf"
 65    (serialize-configuration
 66      config
 67      dhcpcd-configuration-fields)))
 68
 69(define dhcpcd-account-service
 70  (list (user-group (name "dhcpcd") (system? #t))
 71        (user-account
 72          (name "dhcpcd")
 73          (group "dhcpcd")
 74          (system? #t)
 75          (comment "dhcpcd daemon user")
 76          (home-directory "/var/empty")
 77          (shell "/run/current-system/profile/sbin/nologin"))))
 78
 79(define (dhcpcd-shepherd-service config)
 80  (let* ((config-file (dhcpcd-config-file config))
 81         (interfaces (dhcpcd-configuration-interfaces config)))
 82    (list (shepherd-service
 83            (documentation "dhcp daemon.")
 84            (provision '(networking))
 85            (requirement '(user-processes udev))
 86            (actions (list (shepherd-configuration-action config-file)))
 87            (start #~(lambda _
 88                       ;; When invoked without any arguments, the client discovers all
 89                       ;; non-loopback interfaces *that are up*.  However, the relevant
 90                       ;; interfaces are typically down at this point.  Thus we perform
 91                       ;; our own interface discovery here.
 92                       ;;
 93                       ;; Taken from the `dhcp-client-shepherd-service`.
 94                       (define valid?
 95                         (lambda (interface)
 96                           (and (arp-network-interface? interface)
 97                                (not (loopback-network-interface? interface))
 98                                ;; XXX: Make sure the interfaces are up so that
 99                                ;; 'dhclient' can actually send/receive over them.
100                                ;; Ignore those that cannot be activated.
101                                (false-if-exception
102                                  (set-network-interface-up interface)))))
103                       (define ifaces
104                         (filter valid?
105                                 #$(if (maybe-value-set? interfaces)
106                                     #~'#$interfaces
107                                     #~(all-network-interface-names))))
108
109                       (fork+exec-command
110                         (cons* (string-append #$dhcpcd "/sbin/dhcpcd")
111                                "-q" "-q" "-B" "-f" #$config-file ifaces))))
112            (stop #~(make-kill-destructor))))))
113
114(define dhcpcd-service-type
115  (service-type (name 'dhcpcd)
116                (description "Run the dhcpcd daemon.")
117                (extensions
118                 (list (service-extension account-service-type
119                                          (const dhcpcd-account-service))
120                       (service-extension shepherd-root-service-type
121                                          dhcpcd-shepherd-service)))
122                (compose concatenate)
123                (default-value (dhcpcd-configuration))))