From mboxrd@z Thu Jan 1 00:00:00 1970 From: Chris Marusich Subject: Re: isc-bind service draft Date: Tue, 14 Nov 2017 20:48:07 -0800 Message-ID: <87po8kno54.fsf@gmail.com> References: <87vaijkyam.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:36001) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eEpcX-0000tA-6o for guix-devel@gnu.org; Tue, 14 Nov 2017 23:48:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eEpcV-0000fk-Iw for guix-devel@gnu.org; Tue, 14 Nov 2017 23:48:17 -0500 Received: from mail-pf0-x22b.google.com ([2607:f8b0:400e:c00::22b]:49720) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eEpcV-0000eJ-9n for guix-devel@gnu.org; Tue, 14 Nov 2017 23:48:15 -0500 Received: by mail-pf0-x22b.google.com with SMTP id l24so3726178pfj.6 for ; Tue, 14 Nov 2017 20:48:14 -0800 (PST) In-Reply-To: <87vaijkyam.fsf@gmail.com> (Oleg Pykhalov's message of "Thu, 09 Nov 2017 23:11:13 +0300") List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: "Guix-devel" To: Oleg Pykhalov Cc: guix-devel@gnu.org --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Hi Oleg, Oleg Pykhalov writes: > I work on isc-bind service. Currently generation of named.conf is done. > Ideas and suggestions are welcome! :-) Awesome! Thank you for working on this. I'm not familiar with BIND configuration, so I can't really comment much on the particular fields you've chosen to include in the various configuration objects you've created. It'd be nice if someone more familiar with BIND could give it a look. > (define-record-type* Are these options intended to be used when invoking bind? If so, maybe a name like "bind-options" is probably good enough. > bind-options-configuration make-bind-options-configuration > bind-options-configuration? > (user bind-options-configuration-user ; string > (default "bind")) > (group bind-options-configuration-group ; string > (default "bind")) > (run-directory bind-options-configuration-run-directory ; string > (default "/var/run/bind")) > (pid-file bind-options-configuration-pid-file ; string > (default "/var/run/bind/named.pid")) For what it's worth, nowadays some distros use /run as the "run directory" [1]. I don't know if GuixSD has adopted any particular policy about whether to use /var/run or /run for the default "run directory". I don't currently know of any reason why it matters much, so I think it's fine to use /var/run here. > (listen-v4 bind-options-configuration-listen-v4 ; string > (default "0.0.0.0")) > (listen-v6 bind-options-configuration-listen-v6 ; string > (default "::")) > (listen-port bind-options-configuration-listen-port ; integer > (default 53)) > (allow-recursion? bind-configuration-allow-recursion? ; list > (default (list "127.0.0.1"))) > (allow-transfer? bind-configuration-allow-transfer? ; list > (default (list "none"))) > (allow-update? bind-configuration-allow-update? ; list > (default (list "none"))) > (version bind-configuration-version ; string > (default "none")) > (hostname bind-configuration-hostname ; string > (default "none")) Why not use the system's host name by default? For example: (hostname bind-configuration-hostname ; string (default (gethostname))) >=20=20=20 > (server-id bind-configuration-server-id ; string (default "none"))) > > (define (bind-configuration-statement-string statements) > (string-join (list "{" (string-join statements ";\n") "}"))) > You could also write it like this: (define (bind-configuration-statement-string statements) (string-append "{" (string-join statements ";\n") "}")) > > (define-record-type* > bind-zone-configuration make-bind-zone-configuration > bind-zone-configuration? > (network bind-zone-configuration-network ; string > (default '())) > (class bind-zone-configuration-class ; string > (default '())) > (type bind-zone-configuration-type ; string > (default '())) > (file bind-zone-configuration-filename ; string > (default '()))) > > (define-record-type* > bind-configuration-file make-bind-configuration-file > bind-configuration-file? > > ;; > (config-options bind-configuration-file-config-options > (default (bind-options-configuration))) > > ;; list of > (config-zones bind-configuration-file-config-zones > (default (list (bind-zone-configuration > (network "localhost") > (class "IN") > (type "master") > (file "localhost.zone")) > (bind-zone-configuration > (network "0.0.127.in-addr.arpa") > (class "IN") > (type "master") > (file "127.0.0.zone")) > (bind-zone-configuration > (network (string-append "1.0.0.0.0.0.0.= 0.0.0." > "0.0.0.0.0.0.0.= 0.0.0." > "0.0.0.0.0.0.0.= 0.0.0." > "0.0.ip6.arpa")) > (class "IN") > (type "master") > (file "localhost.ip6.zone")) > (bind-zone-configuration > (network "255.in-addr.arpa") > (class "IN") > (type "master") > (file "empty.zone")) > (bind-zone-configuration > (network "0.in-addr.arpa") > (class "IN") > (type "master") > (file "empty.zone")) > (bind-zone-configuration > (network ".") > (class "IN") > (type "master") > (file "root.hint")))))) What is the intended behavior of these defaults? In what situations will they work, and in what situations will they not? It might be good to put a comment in that explains the intended default behavior and why it is reasonable. > (define-record-type* > bind-configuration make-bind-configuration > bind-configuration? > (config-file bind-configuration-config-file > (default (bind-configuration-file))) > (package bind-configuration-package ; > (default bind))) > > (define-syntax option > (syntax-rules () > ((_ key value) (if value > (list " " (string-join (list key value)) ";" "\= n") > '())))) Does this need to be a macro? By the way, you could use string-append here, too, to make it simpler. > (define-syntax key/value > (syntax-rules () > ((_ (key value) rest ...) > (append (option key value) > (key/value rest ...))) > ((_) '()))) Does this need to be a macro? > (define (emit-bind-zones-config zone) > (match zone > (($ network class type file) > (list (string-join `(,(string-join (list "zone" > (string-append "\"" > network > "\"") > class "{\n")) > ,@(key/value ("type" type) > ("file" file)) > "};\n") > ""))))) > > (define (emit-bind-options-config options) > (match options > (($ user _ run-directory pid-file > listen-v4 listen-v6 listen-port > allow-recursion? allow-transfer? > allow-update? > version hostname server-id) Some of these slots (e.g., listen-v4) appear to be un-used. Instead of listing positional slots by name, maybe it would be better to bind the entire to a variable, and then use the accessor procedures (e.g., bind-options-configuration-listen-v4) to get just the attributes you need. This has the benefit of being more resilient to refactorings which change the order of fields in the record, also. I realize that a lot of the code in Guix relies on positional matching of slots like this, so I don't mind if you keep it as-is, but consider my suggestion as food for thought. > `("options {\n" > ,@(key/value ("directory" run-directory) > ("pid-file" pid-file) > ("allow-recursion" > (bind-configuration-statement-string allow-recursion= ?)) > ("allow-transfer" > (bind-configuration-statement-string allow-transfer?= )) > ("allow-update" > (bind-configuration-statement-string allow-update?)) > ("version" version) > ("hostname" hostname) > ("server-id" server-id)) > "};\n")))) > > (define-gexp-compiler (bind-configuration-compiler > (file ) system target) > (match file > (($ config-file) > (match config-file > (($ config-options config-zones) > (apply text-file* "named.conf" > (append (fold append '() (map emit-bind-zones-config confi= g-zones)) > (emit-bind-options-config config-options)))))))) > Is it necessary to define a gexp compiler here? I would have thought we could just invoke plain-file or text-file instead (see (guix) G-Expressions in the Guix manual). Why can't we? Other services do this; for example, see the service definitions in gnu/services/mail.scm. Also, is it possible for a user to pass in an existing configuration file to be used verbatim, or included somewhere in the config? Having an "escape hatch" like that seems useful for most services; perhaps it could be useful here, too. Footnotes:=20 [1] https://unix.stackexchange.com/questions/13972/what-is-this-new-run-fi= lesystem =2D-=20 Chris --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEy/WXVcvn5+/vGD+x3UCaFdgiRp0FAloLxwcACgkQ3UCaFdgi Rp1+7A/9H4S4+cSY4BLGyCvIARw4G9ZvNRly6UoGadHlACCg+cUJwIYBT+NLPm08 yj4Djyz9VcmwOhKr0unbZXaSjoy8DKJkugPaIvup+cl2yaVNG1ksAmXP0xoAlRaK A+VoaqRFpFCPj8Bb3D7IxUc0Tl6to82bAGD0oIB9ibhkIRod42WcLZ7h7qC7z3r4 oXRgoeY15FJs1z4SjuBuVP7yleGf94noB8UIoOAG1SZ0CyiDVWCeF/K/wGztGtZU Ysce0+LFB6Jr3VeQDlG4aV7IOvEhjj3et1WLeQ4F7nD3sJvg5PVeUXYyt76gEHht OOvs9Pbgp6oZVCLIK3t8EtO1QJMgd5X4YmbbgqlpqwXLkVJZFA+pJcE6sC1UkhCC qWAHo856SNqAOTm/RiqZTytqduuq39Hfeiz7QGMAN5xB/1UUMh/x/2pl/bC0f14U iaJiZ+XPuHYdC+HUXEIfjjSBMQsAcgS1mzeA6bX0sAwwJtN+AsBgXhT0JrOjU39L 6iniIoPKU63dmOjaZn0pmxB9NaFm8KQcdV45EsfzIHRaFHVzFraor1n5UkEeEz1z EBNyh7QWxla3RsfZn9Ozobq+pqcl7eVSexieSwXLdWEcz4NikQiKwWkW8BEGxU7l Ie22D45Z9DvIHCoiu33Lg4xtnvFu1M6F4IxAxgVOj3N4Uca+dGE= =5pSD -----END PGP SIGNATURE----- --=-=-=--