From patchwork Mon Jun 26 21:59:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Victal X-Patchwork-Id: 51381 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 9F36F27BBEA; Mon, 26 Jun 2023 23:09:53 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 03BBA27BBE2 for ; Mon, 26 Jun 2023 23:09:53 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qDuNR-00076D-FH; Mon, 26 Jun 2023 18:08:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qDuNP-0006ua-2I for guix-patches@gnu.org; Mon, 26 Jun 2023 18:08:03 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qDuNO-0007PV-Pl for guix-patches@gnu.org; Mon, 26 Jun 2023 18:08:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qDuNO-0000CU-Fh for guix-patches@gnu.org; Mon, 26 Jun 2023 18:08:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63985] [PATCH v3 01/11] services: configuration: Simplify normalize-extra-args. Resent-From: Bruno Victal Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 26 Jun 2023 22:08:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63985 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63985@debbugs.gnu.org Cc: Bruno Victal Received: via spool by 63985-submit@debbugs.gnu.org id=B63985.1687817222677 (code B ref 63985); Mon, 26 Jun 2023 22:08:02 +0000 Received: (at 63985) by debbugs.gnu.org; 26 Jun 2023 22:07:02 +0000 Received: from localhost ([127.0.0.1]:47216 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuMQ-0000Am-3w for submit@debbugs.gnu.org; Mon, 26 Jun 2023 18:07:02 -0400 Received: from smtpm1.myservices.hosting ([185.26.105.232]:59692) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuMO-0000Aa-Ob for 63985@debbugs.gnu.org; Mon, 26 Jun 2023 18:07:01 -0400 Received: from mail1.netim.hosting (unknown [185.26.106.173]) by smtpm1.myservices.hosting (Postfix) with ESMTP id ADCF520512 for <63985@debbugs.gnu.org>; Tue, 27 Jun 2023 00:06:59 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail1.netim.hosting (Postfix) with ESMTP id 6D48480099; Mon, 26 Jun 2023 23:59:45 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mail1.netim.hosting Received: from mail1.netim.hosting ([127.0.0.1]) by localhost (mail1-2.netim.hosting [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id m87NYcERUslH; Mon, 26 Jun 2023 23:59:45 +0200 (CEST) Received: from guix-nuc.home.arpa (unknown [10.192.1.83]) (Authenticated sender: lumen@makinata.eu) by mail1.netim.hosting (Postfix) with ESMTPSA id E8E8E80060; Mon, 26 Jun 2023 23:59:44 +0200 (CEST) From: Bruno Victal Date: Mon, 26 Jun 2023 22:59:27 +0100 Message-Id: <22471a74b258f7169961898eed9e18cee7504f60.1687816734.git.mirai@makinata.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * gnu/services/configuration.scm (define-configuration-helper, normalize-extra-args): Use #f instead of %unset-value. --- gnu/services/configuration.scm | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) base-commit: ac86174e22fcd762893bd4515786b1376af9397b diff --git a/gnu/services/configuration.scm b/gnu/services/configuration.scm index 367b85c1be..dafe72f4fe 100644 --- a/gnu/services/configuration.scm +++ b/gnu/services/configuration.scm @@ -190,32 +190,32 @@ (define (define-configuration-helper serialize? serializer-prefix syn) (define (normalize-extra-args s) "Extract and normalize arguments following @var{doc}." (let loop ((s s) - (sanitizer* %unset-value) - (serializer* %unset-value)) + (sanitizer* #f) + (serializer* #f)) (syntax-case s (sanitizer serializer empty-serializer) (((sanitizer proc) tail ...) - (if (maybe-value-set? sanitizer*) - (syntax-violation 'sanitizer "duplicate entry" - #'proc) + (if sanitizer* + (syntax-violation 'sanitizer + "duplicate entry" #'proc) (loop #'(tail ...) #'proc serializer*))) (((serializer proc) tail ...) - (if (maybe-value-set? serializer*) - (syntax-violation 'serializer "duplicate or conflicting entry" - #'proc) + (if serializer* + (syntax-violation 'serializer + "duplicate or conflicting entry" #'proc) (loop #'(tail ...) sanitizer* #'proc))) ((empty-serializer tail ...) - (if (maybe-value-set? serializer*) + (if serializer* (syntax-violation 'empty-serializer "duplicate or conflicting entry" #f) (loop #'(tail ...) sanitizer* #'empty-serializer))) (() ; stop condition (values (list sanitizer* serializer*))) ((proc) ; TODO: deprecated, to be removed. - (null? (filter-map maybe-value-set? (list sanitizer* serializer*))) + (every not (list sanitizer* serializer*)) (begin (warning #f (G_ "specifying serializers after documentation is \ deprecated, use (serializer ~a) instead~%") (syntax->datum #'proc)) - (values (list %unset-value #'proc))))))) + (values (list #f #'proc))))))) (syntax-case syn () ((_ stem (field field-type+def doc extra-args ...) ...) @@ -239,11 +239,11 @@ (define (define-configuration-helper serialize? serializer-prefix syn) default-value)) #'((field-type def) ...))) ((field-sanitizer ...) - (map maybe-value #'(sanitizer* ...))) + #'(sanitizer* ...)) ((field-serializer ...) (map (lambda (type proc) (and serialize? - (or (maybe-value proc) + (or proc (if serializer-prefix (id #'stem serializer-prefix #'serialize- type) (id #'stem #'serialize- type))))) From patchwork Mon Jun 26 21:59:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Victal X-Patchwork-Id: 51374 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id E5BB927BBEA; Mon, 26 Jun 2023 23:02:09 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id DD7C327BBE2 for ; Mon, 26 Jun 2023 23:02:08 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qDuGv-0005qZ-04; Mon, 26 Jun 2023 18:01:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qDuGi-00051l-5T for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:10 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qDuGc-0005X1-Ea for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:04 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qDuGc-0008SP-34 for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63985] [PATCH v3 02/11] services: configuration: Use transducers within serialize-configuration. Resent-From: Bruno Victal Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 26 Jun 2023 22:01:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63985 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63985@debbugs.gnu.org Cc: Bruno Victal Received: via spool by 63985-submit@debbugs.gnu.org id=B63985.168781680232243 (code B ref 63985); Mon, 26 Jun 2023 22:01:02 +0000 Received: (at 63985) by debbugs.gnu.org; 26 Jun 2023 22:00:02 +0000 Received: from localhost ([127.0.0.1]:47170 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuFd-0008NY-DX for submit@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:02 -0400 Received: from smtpm2.myservices.hosting ([185.26.105.233]:34198) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuFb-0008NK-BD for 63985@debbugs.gnu.org; Mon, 26 Jun 2023 17:59:59 -0400 Received: from mail1.netim.hosting (unknown [185.26.106.173]) by smtpm2.myservices.hosting (Postfix) with ESMTP id 86F0820F16 for <63985@debbugs.gnu.org>; Mon, 26 Jun 2023 23:59:58 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail1.netim.hosting (Postfix) with ESMTP id 0228A8009B; Mon, 26 Jun 2023 23:59:55 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mail1.netim.hosting Received: from mail1.netim.hosting ([127.0.0.1]) by localhost (mail1-2.netim.hosting [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 22Uu61zbYXcM; Mon, 26 Jun 2023 23:59:54 +0200 (CEST) Received: from guix-nuc.home.arpa (unknown [10.192.1.83]) (Authenticated sender: lumen@makinata.eu) by mail1.netim.hosting (Postfix) with ESMTPSA id 6DB028009A; Mon, 26 Jun 2023 23:59:54 +0200 (CEST) From: Bruno Victal Date: Mon, 26 Jun 2023 22:59:28 +0100 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches Introduces 'base-transducer', a SRFI-171 based transducer that can be used as a starting point for writing custom configuration record serializing procedures. This also fixes the symbol maybe-value serialization test case. * gnu/services/configuration.scm (empty-serializer?): New predicate. (base-transducer, tfilter-maybe-value): New procedure. (serialize-configuration): Adapt to use base-transducer. * gnu/services/telephony.scm (jami-account->alist): Use transducers to skip fields that are unserializable or whose field maybe-value is unset. * tests/services/configuration.scm: Remove test-expect-fail. --- gnu/services/configuration.scm | 29 ++++++++++++++++++++++++----- gnu/services/telephony.scm | 27 +++++++++++++-------------- tests/services/configuration.scm | 6 +----- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/gnu/services/configuration.scm b/gnu/services/configuration.scm index dafe72f4fe..cd2cb8318b 100644 --- a/gnu/services/configuration.scm +++ b/gnu/services/configuration.scm @@ -42,6 +42,7 @@ (define-module (gnu services configuration) #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) + #:use-module (srfi srfi-171) #:export (configuration-field configuration-field-name configuration-field-type @@ -59,6 +60,10 @@ (define-module (gnu services configuration) define-configuration/no-serialization no-serialization + empty-serializer? + tfilter-maybe-value + base-transducer + serialize-configuration define-maybe define-maybe/no-serialization @@ -125,13 +130,27 @@ (define-record-type* (default-value-thunk configuration-field-default-value-thunk) (documentation configuration-field-documentation)) +(define (empty-serializer? field) + (eq? empty-serializer + (configuration-field-serializer field))) + +(define (tfilter-maybe-value config) + (tfilter (lambda (field) + (let ((field-value ((configuration-field-getter field) config))) + (maybe-value-set? field-value))))) + +(define (base-transducer config) + (compose (tremove empty-serializer?) + ;; Only serialize fields whose value isn't '%unset-marker%. + (tfilter-maybe-value config) + (tmap (lambda (field) + ((configuration-field-serializer field) + (configuration-field-name field) + ((configuration-field-getter field) config)))))) + (define (serialize-configuration config fields) #~(string-append - #$@(map (lambda (field) - ((configuration-field-serializer field) - (configuration-field-name field) - ((configuration-field-getter field) config))) - fields))) + #$@(list-transduce (base-transducer config) rcons fields))) (define-syntax-rule (id ctx parts ...) "Assemble PARTS into a raw (unhygienic) identifier." diff --git a/gnu/services/telephony.scm b/gnu/services/telephony.scm index 23ccb8d403..56b7772f58 100644 --- a/gnu/services/telephony.scm +++ b/gnu/services/telephony.scm @@ -37,6 +37,7 @@ (define-module (gnu services telephony) #:use-module (srfi srfi-1) #:use-module (srfi srfi-2) #:use-module (srfi srfi-26) + #:use-module (srfi srfi-171) #:use-module (ice-9 format) #:use-module (ice-9 match) #:export (jami-account @@ -204,22 +205,20 @@ (define (jami-account->alist jami-account-object) ('rendezvous-point? "Account.rendezVous") ('peer-discovery? "Account.peerDiscovery") ('bootstrap-hostnames "Account.hostname") - ('name-server-uri "RingNS.uri") - (_ #f))) + ('name-server-uri "RingNS.uri"))) - (filter-map (lambda (field) - (and-let* ((name (field-name->account-detail + (define jami-account-transducer + (compose (tremove empty-serializer?) + (tfilter-maybe-value jami-account-object) + (tmap (lambda (field) + (let* ((name (field-name->account-detail (configuration-field-name field))) - (value ((configuration-field-serializer field) - name ((configuration-field-getter field) - jami-account-object))) - ;; The define-maybe default serializer produces an - ;; empty string for unspecified values. - (value* (if (string-null? value) - #f - value))) - (cons name value*))) - jami-account-fields)) + (value ((configuration-field-serializer field) + name ((configuration-field-getter field) + jami-account-object)))) + (cons name value)))))) + + (list-transduce jami-account-transducer rcons jami-account-fields)) (define (jami-account-list? val) (and (list? val) diff --git a/tests/services/configuration.scm b/tests/services/configuration.scm index 8ad5907f37..40a4e74b4d 100644 --- a/tests/services/configuration.scm +++ b/tests/services/configuration.scm @@ -337,13 +337,9 @@ (define-maybe symbol) (define-configuration config-with-maybe-symbol (protocol maybe-symbol "")) -;;; Maybe symbol values are currently seen as serializable, because the -;;; unspecified value is '%unset-marker%, which is a symbol itself. -;;; TODO: Remove expected fail marker after resolution. -(test-expect-fail 1) (test-equal "symbol maybe value serialization, unspecified" "" - (gexp->approximate-sexp + (eval-gexp (serialize-configuration (config-with-maybe-symbol) config-with-maybe-symbol-fields))) From patchwork Mon Jun 26 21:59:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Victal X-Patchwork-Id: 51379 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 6A39D27BBEA; Mon, 26 Jun 2023 23:03:31 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id E642627BBE2 for ; Mon, 26 Jun 2023 23:03:30 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qDuGr-0005aF-92; Mon, 26 Jun 2023 18:01:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qDuGi-00051r-9L for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:10 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qDuGe-0005XE-Aq for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:06 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qDuGe-0008Sv-60 for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:04 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63985] [PATCH v3 03/11] services: fstrim-service-type: Serialize with SRFI-171 transducers. Resent-From: Bruno Victal Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 26 Jun 2023 22:01:04 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63985 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63985@debbugs.gnu.org Cc: Bruno Victal Received: via spool by 63985-submit@debbugs.gnu.org id=B63985.168781683632424 (code B ref 63985); Mon, 26 Jun 2023 22:01:04 +0000 Received: (at 63985) by debbugs.gnu.org; 26 Jun 2023 22:00:36 +0000 Received: from localhost ([127.0.0.1]:47183 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuGB-0008Qp-VU for submit@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:36 -0400 Received: from smtpmciv1.myservices.hosting ([185.26.107.237]:37948) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuG5-0008QF-4d for 63985@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:31 -0400 Received: from mail1.netim.hosting (unknown [185.26.106.173]) by smtpmciv1.myservices.hosting (Postfix) with ESMTP id 8116020E27 for <63985@debbugs.gnu.org>; Tue, 27 Jun 2023 00:00:12 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail1.netim.hosting (Postfix) with ESMTP id 900DD8009B; Tue, 27 Jun 2023 00:00:00 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mail1.netim.hosting Received: from mail1.netim.hosting ([127.0.0.1]) by localhost (mail1-2.netim.hosting [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id UcJKeTEHG0fw; Tue, 27 Jun 2023 00:00:00 +0200 (CEST) Received: from guix-nuc.home.arpa (unknown [10.192.1.83]) (Authenticated sender: lumen@makinata.eu) by mail1.netim.hosting (Postfix) with ESMTPSA id 108568009A; Tue, 27 Jun 2023 00:00:00 +0200 (CEST) From: Bruno Victal Date: Mon, 26 Jun 2023 22:59:29 +0100 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * gnu/services/linux.scm (serialize-fstrim-configuration): Refactor to use base-transducer. --- gnu/services/linux.scm | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/gnu/services/linux.scm b/gnu/services/linux.scm index d105c42850..3cfa6d6855 100644 --- a/gnu/services/linux.scm +++ b/gnu/services/linux.scm @@ -40,6 +40,7 @@ (define-module (gnu services linux) #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) + #:use-module (srfi srfi-171) #:use-module (ice-9 format) #:use-module (ice-9 match) #:export (earlyoom-configuration @@ -227,13 +228,9 @@ (define-configuration fstrim-configuration (prefix fstrim-)) (define (serialize-fstrim-configuration config) - (concatenate - (filter list? - (map (lambda (field) - ((configuration-field-serializer field) - (configuration-field-name field) - ((configuration-field-getter field) config))) - fstrim-configuration-fields)))) + (list-transduce (compose (base-transducer config) tconcatenate) + rcons + fstrim-configuration-fields)) (define (fstrim-mcron-job config) (match-record config (package schedule) From patchwork Mon Jun 26 21:59:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Victal X-Patchwork-Id: 51380 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 06E5127BBE9; Mon, 26 Jun 2023 23:09:51 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 4CBC927BBE2 for ; Mon, 26 Jun 2023 23:09:48 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qDuGs-0005eI-Id; Mon, 26 Jun 2023 18:01:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qDuGi-00051t-S4 for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:10 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qDuGe-0005XG-Ng for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:06 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qDuGe-0008T3-JM for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:04 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63985] [PATCH v3 04/11] doc: Rewrite define-configuration. Resent-From: Bruno Victal Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 26 Jun 2023 22:01:04 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63985 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63985@debbugs.gnu.org Cc: Bruno Victal Received: via spool by 63985-submit@debbugs.gnu.org id=B63985.168781684732456 (code B ref 63985); Mon, 26 Jun 2023 22:01:04 +0000 Received: (at 63985) by debbugs.gnu.org; 26 Jun 2023 22:00:47 +0000 Received: from localhost ([127.0.0.1]:47187 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuGM-0008RO-DS for submit@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:46 -0400 Received: from smtpmciv1.myservices.hosting ([185.26.107.237]:37968) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuGA-0008Qe-FE for 63985@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:35 -0400 Received: from mail1.netim.hosting (unknown [185.26.106.173]) by smtpmciv1.myservices.hosting (Postfix) with ESMTP id 775BD20CB0 for <63985@debbugs.gnu.org>; Tue, 27 Jun 2023 00:00:21 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail1.netim.hosting (Postfix) with ESMTP id C61758009C; Tue, 27 Jun 2023 00:00:05 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mail1.netim.hosting Received: from mail1.netim.hosting ([127.0.0.1]) by localhost (mail1-2.netim.hosting [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id xFp_QWaTk86t; Tue, 27 Jun 2023 00:00:05 +0200 (CEST) Received: from guix-nuc.home.arpa (unknown [10.192.1.83]) (Authenticated sender: lumen@makinata.eu) by mail1.netim.hosting (Postfix) with ESMTPSA id C99698009A; Tue, 27 Jun 2023 00:00:04 +0200 (CEST) From: Bruno Victal Date: Mon, 26 Jun 2023 22:59:30 +0100 Message-Id: <3c9e04b336d5627af5167ff3b786918df724f3f6.1687816734.git.mirai@makinata.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches Rewrite this section to make it easier to document later syntactical changes. * doc/guix.texi (Complex Configurations): Rewrite define-configuration documentation. Fix simple serializer example. --- doc/guix.texi | 102 +++++++++++++++++++++----------------------------- 1 file changed, 42 insertions(+), 60 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 853396f776..8355260378 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -41953,54 +41953,33 @@ Complex Configurations files, you can use the utilities defined in the @code{(gnu services configuration)} module. -The main utility is the @code{define-configuration} macro, which you -will use to define a Scheme record type (@pxref{Record Overview,,, -guile, GNU Guile Reference Manual}). The Scheme record will be -serialized to a configuration file by using @dfn{serializers}, which are -procedures that take some kind of Scheme value and returns a -G-expression (@pxref{G-Expressions}), which should, once serialized to -the disk, return a string. More details are listed below. +The main utility is the @code{define-configuration} macro, a helper +used to define a Scheme record type (@pxref{Record Overview,,, +guile, GNU Guile Reference Manual}). The fields from this Scheme record +can be serialized using @dfn{serializers}, which are procedures that take +some kind of Scheme value and translates them into another Scheme value or +@ref{G-Expressions}. @defmac define-configuration name clause1 clause2 @dots{} Create a record type named @code{@var{name}} that contains the fields found in the clauses. -A clause can have one of the following forms: +A clause has the following form: @example (@var{field-name} - (@var{type} @var{default-value}) - @var{documentation}) - -(@var{field-name} - (@var{type} @var{default-value}) - @var{documentation} - (serializer @var{serializer})) - -(@var{field-name} - (@var{type}) - @var{documentation}) - -(@var{field-name} - (@var{type}) - @var{documentation} - (serializer @var{serializer})) - -(@var{field-name} - (@var{type}) + @var{type-decl} @var{documentation} - (sanitizer @var{sanitizer}) - -(@var{field-name} - (@var{type}) - @var{documentation} - (sanitizer @var{sanitizer}) - (serializer @var{serializer})) + @var{option*} + @dots{}) @end example @var{field-name} is an identifier that denotes the name of the field in the generated record. +@var{type-decl} is either @code{@var{type}} for fields that require a +value to be set or @code{(@var{type} @var{default})} otherwise. + @var{type} is the type of the value corresponding to @var{field-name}; since Guile is untyped, a predicate procedure---@code{@var{type}?}---will be called on the value @@ -42018,6 +41997,28 @@ Complex Configurations @var{documentation} is a string formatted with Texinfo syntax which should provide a description of what setting this field does. +@var{option*} is one of the following subclauses: + +@table @asis +@item @code{empty-serializer} +Exclude this field from serialization. + +@item @code{(serializer @var{serializer})} +@var{serializer} is the name of a procedure which takes two arguments, +the first is the name of the field, and the second is the value +corresponding to the field. The procedure should return a string or +@ref{G-Expressions} that represents the content that will be serialized +to the configuration file. If none is specified, a procedure of the +name @code{serialize-@var{type}} will be used. + +An example of a simple serializer procedure: +@lisp +(define (serialize-boolean field-name value) + (let ((value (if value "true" "false"))) + #~(string-append '#$field-name #$value))) +@end lisp + +@item @code{(sanitizer @var{sanitizer})} @var{sanitizer} is a procedure which takes one argument, a user-supplied value, and returns a ``sanitized'' value for the field. If no sanitizer is specified, a default sanitizer is used, which raises @@ -42031,21 +42032,7 @@ Complex Configurations ((symbol? value) (symbol->string value)) (else (error "bad value")))) @end lisp - -@var{serializer} is the name of a procedure which takes two arguments, -the first is the name of the field, and the second is the value -corresponding to the field. The procedure should return a string or -G-expression (@pxref{G-Expressions}) that represents the content that -will be serialized to the configuration file. If none is specified, a -procedure of the name @code{serialize-@var{type}} will be used. - -A simple serializer procedure could look like this: - -@lisp -(define (serialize-boolean field-name value) - (let ((value (if value "true" "false"))) - #~(string-append #$field-name #$value))) -@end lisp +@end table In some cases multiple different configuration records might be defined in the same file, but their serializers for the same type might have to @@ -42066,13 +42053,13 @@ Complex Configurations (define-configuration foo-configuration (label - (string) + string "The name of label.") (prefix foo-)) (define-configuration bar-configuration (ip-address - (string) + string "The IPv4 address for this device.") (prefix bar-)) @end lisp @@ -42164,11 +42151,6 @@ Complex Configurations disk by using something like @code{mixed-text-file}. @end deffn -@deffn {Procedure} empty-serializer field-name value -A serializer that just returns an empty string. The -@code{serialize-package} procedure is an alias for this. -@end deffn - Once you have defined a configuration record, you will most likely also want to document it so that other people know to use it. To help with that, there are two procedures, both of which are documented below. @@ -42271,7 +42253,7 @@ Complex Configurations (define-configuration contact-configuration (name - (string) + string "The name of the contact." serialize-contact-name) (phone-number @@ -42281,15 +42263,15 @@ Complex Configurations maybe-string "The person's email address.") (married? - (boolean) + boolean "Whether the person is married.")) (define-configuration contacts-list-configuration (name - (string) + string "The name of the owner of this contact list.") (email - (string) + string "The owner's email address.") (contacts (list-of-contact-configurations '()) From patchwork Mon Jun 26 21:59:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Victal X-Patchwork-Id: 51371 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id DBD7927BBE9; Mon, 26 Jun 2023 23:01:45 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id EA95D27BBE2 for ; Mon, 26 Jun 2023 23:01:42 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qDuGq-0005WG-9Y; Mon, 26 Jun 2023 18:01:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qDuGi-00051u-Ru for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:10 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qDuGd-0005XB-UD for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:06 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qDuGd-0008So-PT for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:03 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63985] [PATCH v3 05/11] services: configuration: Add serializer-options field. Resent-From: Bruno Victal Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 26 Jun 2023 22:01:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63985 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63985@debbugs.gnu.org Cc: Bruno Victal Received: via spool by 63985-submit@debbugs.gnu.org id=B63985.168781683632418 (code B ref 63985); Mon, 26 Jun 2023 22:01:03 +0000 Received: (at 63985) by debbugs.gnu.org; 26 Jun 2023 22:00:36 +0000 Received: from localhost ([127.0.0.1]:47181 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuGB-0008Ql-9g for submit@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:35 -0400 Received: from smtpmciv4.myservices.hosting ([185.26.107.240]:44064) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuG4-0008QG-Bz for 63985@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:29 -0400 Received: from mail1.netim.hosting (unknown [185.26.106.173]) by smtpmciv4.myservices.hosting (Postfix) with ESMTP id 64250207A8 for <63985@debbugs.gnu.org>; Tue, 27 Jun 2023 00:00:11 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail1.netim.hosting (Postfix) with ESMTP id 451B2800A0; Tue, 27 Jun 2023 00:00:11 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mail1.netim.hosting Received: from mail1.netim.hosting ([127.0.0.1]) by localhost (mail1-2.netim.hosting [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 1BqnHD56ZU7V; Tue, 27 Jun 2023 00:00:10 +0200 (CEST) Received: from guix-nuc.home.arpa (unknown [10.192.1.83]) (Authenticated sender: lumen@makinata.eu) by mail1.netim.hosting (Postfix) with ESMTPSA id 8A6698009A; Tue, 27 Jun 2023 00:00:10 +0200 (CEST) From: Bruno Victal Date: Mon, 26 Jun 2023 22:59:31 +0100 Message-Id: <3ff11bf98a7658400615305609654432a4f30bb0.1687816734.git.mirai@makinata.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches Allow relaying additional arguments to a serialize- procedure. * gnu/services/configuration.scm (configuration-field) : New field. (base-transducer, define-maybe-helper): Adjust to relay additional arguments. (normalize-extra-args): Implement serializer-options literal. * tests/services/configuration.scm: Add tests for serializer-options. * doc/guix.texi (Complex Configurations): Document serializer-options. --- doc/guix.texi | 11 +++++ gnu/services/configuration.scm | 49 ++++++++++++------- tests/services/configuration.scm | 82 ++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 16 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 8355260378..14802e9366 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -42032,6 +42032,17 @@ Complex Configurations ((symbol? value) (symbol->string value)) (else (error "bad value")))) @end lisp + +@item @code{(serializer-options @var{arglst})} +@var{arglst} is a list of extra arguments that are relayed to the +serializing procedure. This allows for writing serialization +procedures that take more than two arguments. + +An example of a serializer procedure that requires additional data: +@lisp +(define* (serialize-port field value #:key context) + #~(format #f "section=~a,port=~d" #$context #$value)) +@end lisp @end table In some cases multiple different configuration records might be defined diff --git a/gnu/services/configuration.scm b/gnu/services/configuration.scm index cd2cb8318b..4eee5a26c2 100644 --- a/gnu/services/configuration.scm +++ b/gnu/services/configuration.scm @@ -50,6 +50,7 @@ (define-module (gnu services configuration) configuration-field-error configuration-field-sanitizer configuration-field-serializer + configuration-field-serializer-options configuration-field-getter configuration-field-default-value-thunk configuration-field-documentation @@ -127,6 +128,7 @@ (define-record-type* (predicate configuration-field-predicate) (sanitizer configuration-field-sanitizer) (serializer configuration-field-serializer) + (serializer-options configuration-field-serializer-options) (default-value-thunk configuration-field-default-value-thunk) (documentation configuration-field-documentation)) @@ -144,9 +146,13 @@ (define (base-transducer config) ;; Only serialize fields whose value isn't '%unset-marker%. (tfilter-maybe-value config) (tmap (lambda (field) - ((configuration-field-serializer field) - (configuration-field-name field) - ((configuration-field-getter field) config)))))) + (let ((serializer (configuration-field-serializer field)) + (field-name (configuration-field-name field)) + (value + ((configuration-field-getter field) config)) + (serializer-options + (configuration-field-serializer-options field))) + (apply serializer field-name value serializer-options)))))) (define (serialize-configuration config fields) #~(string-append @@ -173,10 +179,9 @@ (define (define-maybe-helper serialize? prefix syn) (or (not (maybe-value-set? val)) (stem? val))) #,@(if serialize? - (list #'(define (serialize-maybe-stem field-name val) - (if (stem? val) - (serialize-stem field-name val) - ""))) + (list #'(define (serialize-maybe-stem field-name val . rest) + (when (maybe-value-set? val) + (apply serialize-stem field-name val rest)))) '())))))) (define-syntax define-maybe @@ -210,38 +215,49 @@ (define (define-configuration-helper serialize? serializer-prefix syn) "Extract and normalize arguments following @var{doc}." (let loop ((s s) (sanitizer* #f) - (serializer* #f)) - (syntax-case s (sanitizer serializer empty-serializer) + (serializer* #f) + (serializer-options* #f)) + (syntax-case s (sanitizer serializer empty-serializer serializer-options) (((sanitizer proc) tail ...) (if sanitizer* (syntax-violation 'sanitizer "duplicate entry" #'proc) - (loop #'(tail ...) #'proc serializer*))) + (loop #'(tail ...) + #'proc serializer* serializer-options*))) (((serializer proc) tail ...) (if serializer* (syntax-violation 'serializer "duplicate or conflicting entry" #'proc) - (loop #'(tail ...) sanitizer* #'proc))) + (loop #'(tail ...) + sanitizer* #'proc serializer-options*))) ((empty-serializer tail ...) (if serializer* (syntax-violation 'empty-serializer "duplicate or conflicting entry" #f) - (loop #'(tail ...) sanitizer* #'empty-serializer))) + (loop #'(tail ...) + sanitizer* #'empty-serializer #f))) + (((serializer-options args) tail ...) + (if serializer-options* + (syntax-violation 'serializer-options + "duplicate or conflicting entry" #f) + (loop #'(tail ...) + sanitizer* serializer* #'args))) (() ; stop condition - (values (list sanitizer* serializer*))) + (values (list sanitizer* serializer* + (or serializer-options* #'(quote ()))))) ((proc) ; TODO: deprecated, to be removed. - (every not (list sanitizer* serializer*)) + (every not (list sanitizer* serializer* serializer-options*)) (begin (warning #f (G_ "specifying serializers after documentation is \ deprecated, use (serializer ~a) instead~%") (syntax->datum #'proc)) - (values (list #f #'proc))))))) + (values (list #f #'proc #'(quote ())))))))) (syntax-case syn () ((_ stem (field field-type+def doc extra-args ...) ...) (with-syntax ((((field-type def) ...) (map normalize-field-type+def #'(field-type+def ...))) - (((sanitizer* serializer*) ...) + (((sanitizer* serializer* serializer-options*) ...) (map normalize-extra-args #'((extra-args ...) ...)))) (with-syntax (((field-getter ...) @@ -327,6 +343,7 @@ (define (define-configuration-helper serialize? serializer-prefix syn) (or field-sanitizer (id #'stem #'validate- #'stem #'- #'field))) (serializer field-serializer) + (serializer-options serializer-options*) (default-value-thunk (lambda () (if (maybe-value-set? (syntax->datum field-default)) diff --git a/tests/services/configuration.scm b/tests/services/configuration.scm index 40a4e74b4d..8b1d1e4749 100644 --- a/tests/services/configuration.scm +++ b/tests/services/configuration.scm @@ -297,6 +297,88 @@ (define (sanitize-port value) (lambda _ "lorem") (sanitizer (lambda () #t))))))) +(test-group "Serializer options" + (test-group "Serialize keyword arguments" + (define* (serialize-port field value #:key host) + (format #f "host=~a,port=~d" host value)) + + (define-configuration kwarg-config + (port + (port 80) + "Lorem Ipsum." + (serializer-options '(#:host "[2001:db8::1]")))) + + (define-maybe port) + (define-configuration kwarg-maybe-config + (port + (maybe-port 80) + "Lorem Ipsum." + (serializer-options '(#:host "[2001:db8::1]")))) + + (test-equal "keyword argument provided" + "host=[2001:db8::1],port=80" + (eval-gexp + (serialize-configuration (kwarg-config) + kwarg-config-fields))) + + (test-equal "keyword argument provided, maybe type" + "host=[2001:db8::1],port=80" + (eval-gexp + (serialize-configuration (kwarg-maybe-config) + kwarg-maybe-config-fields)))) + + (test-group "Serialize optional arguments" + (define* (serialize-port field-name value #:optional override-name) + (format #f "~a=~d" (or override-name field-name) value)) + + (define-configuration with-optarg + (port + (port 80) + "Lorem Ipsum." + (serializer-options '(service-port)))) + + (define-configuration without-optarg + (port + (port 80) + "Lorem Ipsum.")) + + (test-equal "optional argument, provided" + "service-port=80" + (eval-gexp (serialize-configuration (with-optarg) + with-optarg-fields))) + + (test-equal "optional argument, absent" + "port=80" + (eval-gexp (serialize-configuration (without-optarg) + without-optarg-fields)))) + + (test-group "Serialize optional & keyword arguments" + (define* (serialize-port field-name value #:optional override-name + #:key host) + (format #f "host=~a,~a=~d" host (or override-name field-name) value)) + + (define-configuration mixed-args + (port + (port 80) + "Lorem Ipsum." + (serializer-options '(service-port #:host "example.com")))) + + (define-configuration mixed-no-optarg + (port + (port 80) + "Lorem Ipsum." + (serializer-options '(#:host "example.com")))) + + (test-equal "mixed arguments, optional provided" + "host=example.com,service-port=80" + (eval-gexp (serialize-configuration (mixed-args) + mixed-args-fields))) + + (test-equal "mixed arguments, optional absent" + "host=example.com,port=80" + (eval-gexp (serialize-configuration (mixed-no-optarg) + mixed-no-optarg-fields))))) + ;;; ;;; define-maybe macro. From patchwork Mon Jun 26 21:59:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Bruno Victal X-Patchwork-Id: 51372 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id DF72427BBE2; Mon, 26 Jun 2023 23:01:46 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 3835C27BBEA for ; Mon, 26 Jun 2023 23:01:44 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qDuGo-0005Lm-OX; Mon, 26 Jun 2023 18:01:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qDuGi-00051s-9c for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:10 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qDuGc-0005X2-TM for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:05 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qDuGc-0008SY-O3 for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63985] [PATCH v3 06/11] services: configuration: New generic-ini module. Resent-From: Bruno Victal Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 26 Jun 2023 22:01:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63985 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63985@debbugs.gnu.org Cc: Bruno Victal Received: via spool by 63985-submit@debbugs.gnu.org id=B63985.168781682232367 (code B ref 63985); Mon, 26 Jun 2023 22:01:02 +0000 Received: (at 63985) by debbugs.gnu.org; 26 Jun 2023 22:00:22 +0000 Received: from localhost ([127.0.0.1]:47174 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuFx-0008Pv-Ex for submit@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:22 -0400 Received: from smtpm3.myservices.hosting ([185.26.105.234]:32906) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuFu-0008Pk-4i for 63985@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:19 -0400 Received: from mail1.netim.hosting (unknown [185.26.106.173]) by smtpm3.myservices.hosting (Postfix) with ESMTP id 5B82D20FAB for <63985@debbugs.gnu.org>; Tue, 27 Jun 2023 00:00:17 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail1.netim.hosting (Postfix) with ESMTP id A1EB28009B; Tue, 27 Jun 2023 00:00:16 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mail1.netim.hosting Received: from mail1.netim.hosting ([127.0.0.1]) by localhost (mail1-2.netim.hosting [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id yhy3_izi1NZy; Tue, 27 Jun 2023 00:00:15 +0200 (CEST) Received: from guix-nuc.home.arpa (unknown [10.192.1.83]) (Authenticated sender: lumen@makinata.eu) by mail1.netim.hosting (Postfix) with ESMTPSA id 023A98009A; Tue, 27 Jun 2023 00:00:14 +0200 (CEST) From: Bruno Victal Date: Mon, 26 Jun 2023 22:59:32 +0100 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches Implements a ‘serialize-ini-configuration’ procedure for serializing record-types defined with define-configuration into generic INI files. * gnu/services/configuration/generic-ini.scm: New module. * tests/services/configuration/generic-ini.scm: Add tests for new module. * Makefile.am: Register tests. * gnu/local.mk: Register module. --- Makefile.am | 1 + gnu/local.mk | 1 + gnu/services/configuration/generic-ini.scm | 165 +++++++++++++++++++ tests/services/configuration/generic-ini.scm | 129 +++++++++++++++ 4 files changed, 296 insertions(+) create mode 100644 gnu/services/configuration/generic-ini.scm create mode 100644 tests/services/configuration/generic-ini.scm diff --git a/Makefile.am b/Makefile.am index a386e6033c..b6d048f140 100644 --- a/Makefile.am +++ b/Makefile.am @@ -553,6 +553,7 @@ SCM_TESTS = \ tests/services.scm \ tests/services/file-sharing.scm \ tests/services/configuration.scm \ + tests/services/configuration/generic-ini.scm \ tests/services/lightdm.scm \ tests/services/linux.scm \ tests/services/telephony.scm \ diff --git a/gnu/local.mk b/gnu/local.mk index e65888a044..796ac33107 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -670,6 +670,7 @@ GNU_SYSTEM_MODULES = \ %D%/services/cgit.scm \ %D%/services/ci.scm \ %D%/services/configuration.scm \ + %D%/services/configuration/generic-ini.scm \ %D%/services/cuirass.scm \ %D%/services/cups.scm \ %D%/services/databases.scm \ diff --git a/gnu/services/configuration/generic-ini.scm b/gnu/services/configuration/generic-ini.scm new file mode 100644 index 0000000000..4f83cce13a --- /dev/null +++ b/gnu/services/configuration/generic-ini.scm @@ -0,0 +1,165 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2023 Bruno Victal +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (gnu services configuration generic-ini) + #:use-module (gnu services configuration) + #:use-module (guix gexp) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-171) + #:use-module (srfi srfi-171 meta) + #:use-module (ice-9 match) + #:export (ini-entry? + list-of-ini-entries? + + ini-entries + ini-entries? + entries + + serialize-ini-configuration + generic-ini-serialize-string + generic-ini-serialize-boolean + generic-ini-serialize-ini-entry + generic-ini-serialize-list-of-ini-entries)) + +;;; +;;; Generic INI serializer +;;; + + +;;; +;;; Predicates +;;; + +;; This is the same format used in SRFI-233 but without comment support. +(define ini-entry? + (match-lambda + (((? symbol?) (? symbol?) (? string?)) #t) + (_ #f))) + +(define list-of-ini-entries? + (list-of ini-entry?)) + +;; +;; Overall design document +;; +;; This module implements a generic INI serializer for a record-type defined +;; using define-configuration. +;; It expects that the serialize- procedures return a list with +;; three elements of the form: +;; (list section key value) +;; Where ‘section’ and ‘key’ are symbols and ‘value’ is a string. +;; For serializing procedures that have to return multiple entries at once, +;; such as encountered when synthesizing configuration from a record object +;; or “escape hatch fields”, it must wrap the result by calling ‘ini-entries’ +;; with a list of INI-entries as described above. +;; This is implemented as a constructor for a SRFI-9 record type named +;; “”. +;; +;; The fields within define-configuration do not have to be ordered in, +;; any way whatsoever as the ‘serialize-ini’ will group them up automatically. +;; This implies that no assumptions should be made regarding the order of the +;; values in the serializied INI output. +;; +;; Additional notes: +;; Q: Why not replace rcons with string-append and forego the ungexp-splice? +;; A: The transduction happens outside of the G-Exp while the final string-append +;; takes place in the G-Exp. +;; +;; Debugging tips: Open a REPL and try one transducer at a time from +;; ‘ini-transducer’. +;; + +;; A “bag” holding multiple ini-entries. +(define-record-type + (ini-entries val) + ini-entries? + (val entries)) + +(define (add-section-header partition) + (let ((header (caar partition))) + (cons (list header) + partition))) + +(define serializer + (match-lambda + ((section) + #~(format #f "[~a]~%" '#$section)) + ((section key value) + #~(format #f "~a=~a~%" '#$key #$value)) + ;; Used for the newline between sections. + ('*section-separator* "\n"))) + +(define ini-transducer + (compose (tpartition car) + (tmap add-section-header) + (tadd-between '(*section-separator*)) + tconcatenate + (tmap serializer))) + +;; A selective version of ‘tconcatenate’ but for ‘’ objects only. +(define (tconcatenate-ini-entries reducer) + (case-lambda + (() '()) + ((result) (reducer result)) + ((result input) + (if (ini-entries? input) + (list-reduce (preserving-reduced reducer) result (entries input)) + (reducer result input))))) + +;; A “first-pass” serialization is performed and sorted in order +;; to group up the fields by “section” before passing through the +;; transducer. +(define (serialize-ini-configuration config fields) + (let* ((srfi-233-IR + ;; First pass: “serialize” into a (disordered) list of + ;; SRFI-233 entries. + (list-transduce (compose (base-transducer config) + tconcatenate-ini-entries) + rcons fields)) + (comparator (lambda (x y) + ;; Sort the SRFI-233 entries by section. + (string<=? (symbol->string (car x)) + (symbol->string (car y))))) + (sorted-entries (sort srfi-233-IR comparator))) + #~(string-append + #$@(list-transduce ini-transducer rcons sorted-entries)))) + + +;;; +;;; Serializers +;;; + +;; These are “gratuitous” serializers that can be readily used by +;; using the literal (prefix generic-ini-) within define-configuration. + +;; Notes: field-name-transform can be used to “uglify” a field-name, +;; e.g. want-ipv6? -> want_ipv6 +(define* (generic-ini-serialize-string field-name value #:key section + (field-name-transform identity)) + (list section (field-name-transform field-name) value)) + +(define* (generic-ini-serialize-boolean field-name value #:key section + (field-name-transform identity)) + (list section (field-name-transform field-name) + (if value "true" "false"))) + +(define (generic-ini-serialize-ini-entry field-name value) + value) + +(define (generic-ini-serialize-list-of-ini-entries field-name value) + (ini-entries value)) diff --git a/tests/services/configuration/generic-ini.scm b/tests/services/configuration/generic-ini.scm new file mode 100644 index 0000000000..797a01af31 --- /dev/null +++ b/tests/services/configuration/generic-ini.scm @@ -0,0 +1,129 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2023 Bruno Victal +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (tests services configuration generic-ini) + #:use-module (gnu services configuration) + #:use-module (gnu services configuration generic-ini) + #:use-module (guix diagnostics) + #:use-module (guix gexp) + #:use-module (guix store) + #:autoload (guix i18n) (G_) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-64) + #:use-module (srfi srfi-71)) + +;;; Tests for the (gnu services configuration generic-ini) module. + +(test-begin "generic-ini serializer") + + +(define expected-output "\ +[guardians] +llamas=Tommy,Isabella +donkeys=Franz,Olly + +[ranch] +shepherd=Emma + +[shed] +colours=Alizarin +enabled=true +capacity=50 +production=wool + +[vehicles] +cars=313 +bikes=Amaryllis +") + + +;;; +;;; Serializers +;;; +(define (strip-trailing-?-character field-name) + "Drop rightmost '?' character" + (let ((str (symbol->string field-name))) + (if (string-suffix? "?" str) + (string->symbol (string-drop-right str 1)) + field-name))) + +(define* (serialize-string field-name value #:key section) + (list section field-name value)) + +(define* (serialize-number field-name value #:key section) + (list section field-name (number->string value))) + +(define* (serialize-boolean field-name value #:key section) + (list section (strip-trailing-?-character field-name) + (if value "true" "false"))) + +(define serialize-ini-entry + generic-ini-serialize-ini-entry) + +(define serialize-list-of-ini-entries + generic-ini-serialize-list-of-ini-entries) + + +;;; +;;; Record-type definition +;;; + +(define-configuration foo-configuration + (production + (string "wool") + "Lorem Ipsum …" + (serializer-options '(#:section shed))) + + (capacity + (number 50) + "Lorem Ipsum …" + (serializer-options '(#:section shed))) + + (enabled? + (boolean #t) + "Lorem Ipsum …" + (serializer-options '(#:section shed))) + + (shepherd + (string "Emma") + "Lorem Ipsum …" + (serializer-options '(#:section ranch))) + + (raw-entry + (ini-entry '(shed colours "Alizarin")) + "Lorem Ipsum …") + + (escape-hatch + (list-of-ini-entries '((vehicles bikes "Amaryllis") + (vehicles cars "313") + (guardians donkeys "Franz,Olly") + (guardians llamas "Tommy,Isabella"))) + "Lorem Ipsum …")) + +(test-equal "Well-formed INI output from serialize-ini" + expected-output + ;; Serialize the above into a string, properly resolving any potential + ;; nested G-Exps as well. + (let* ((serialized-ini + (serialize-ini-configuration (foo-configuration) + foo-configuration-fields)) + (lowered conn (with-store store + ((lower-gexp serialized-ini) store)))) + (eval (lowered-gexp-sexp lowered) (current-module)))) + +(test-end) From patchwork Mon Jun 26 21:59:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Bruno Victal X-Patchwork-Id: 51377 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 31EB427BBEA; Mon, 26 Jun 2023 23:03:20 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 1DBAF27BBE2 for ; Mon, 26 Jun 2023 23:03:19 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qDuGn-0005E9-LU; Mon, 26 Jun 2023 18:01:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qDuGi-00051q-8y for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:10 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qDuGd-0005X8-Fo for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:05 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qDuGd-0008Sg-7K for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:03 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63985] [PATCH v3 07/11] services: configuration: Add some commonly used predicates. Resent-From: Bruno Victal Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 26 Jun 2023 22:01:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63985 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63985@debbugs.gnu.org Cc: Bruno Victal Received: via spool by 63985-submit@debbugs.gnu.org id=B63985.168781682932386 (code B ref 63985); Mon, 26 Jun 2023 22:01:03 +0000 Received: (at 63985) by debbugs.gnu.org; 26 Jun 2023 22:00:29 +0000 Received: from localhost ([127.0.0.1]:47177 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuG4-0008QH-IL for submit@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:29 -0400 Received: from smtpm1.myservices.hosting ([185.26.105.232]:58444) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuFx-0008Pt-7k for 63985@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:22 -0400 Received: from mail1.netim.hosting (unknown [185.26.106.173]) by smtpm1.myservices.hosting (Postfix) with ESMTP id A97D520512 for <63985@debbugs.gnu.org>; Tue, 27 Jun 2023 00:00:20 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail1.netim.hosting (Postfix) with ESMTP id 0CCB88009B; Tue, 27 Jun 2023 00:00:20 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mail1.netim.hosting Received: from mail1.netim.hosting ([127.0.0.1]) by localhost (mail1-2.netim.hosting [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 2l1PFbt-_Fo0; Tue, 27 Jun 2023 00:00:19 +0200 (CEST) Received: from guix-nuc.home.arpa (unknown [10.192.1.83]) (Authenticated sender: lumen@makinata.eu) by mail1.netim.hosting (Postfix) with ESMTPSA id 3BF1D8009A; Tue, 27 Jun 2023 00:00:19 +0200 (CEST) From: Bruno Victal Date: Mon, 26 Jun 2023 22:59:33 +0100 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * gnu/services/configuration.scm (list-of-packages?, list-of-symbols?): New predicate. * gnu/services/audio.scm (list-of-symbol?): Remove. * gnu/services/telephony.scm (string-list?): Remove. (serialize-string-list): Rename to … (serialize-list-of-strings): … this. (account-fingerprint-list?, jami-account-list?): Use list-of. * doc/guix.texi: Update it. --- doc/guix.texi | 4 ++-- gnu/services/audio.scm | 7 ++----- gnu/services/configuration.scm | 16 ++++++++++++++++ gnu/services/telephony.scm | 20 +++++++------------- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 14802e9366..2f7e734874 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -27850,7 +27850,7 @@ Telephony Services connection to the Internet has been lost. When left unspecified, the value from the account archive prevails. -@item @code{bootstrap-hostnames} (type: maybe-string-list) +@item @code{bootstrap-hostnames} (type: maybe-list-of-strings) A list of hostnames or IPs pointing to OpenDHT nodes, that should be used to initially join the OpenDHT network. When left unspecified, the value from the account archive prevails. @@ -34244,7 +34244,7 @@ Audio Services The group to run mpd as. The default @code{%mpd-group} is a system group with name ``mpd''. -@item @code{shepherd-requirement} (default: @code{'()}) (type: list-of-symbol) +@item @code{shepherd-requirement} (default: @code{'()}) (type: list-of-symbols) A list of symbols naming Shepherd services that this service will depend on. diff --git a/gnu/services/audio.scm b/gnu/services/audio.scm index 690409b7a1..89ab9c51c6 100644 --- a/gnu/services/audio.scm +++ b/gnu/services/audio.scm @@ -137,9 +137,6 @@ (define (uglify-field-name field-name) str) #\-) "_"))) -(define list-of-symbol? - (list-of symbol?)) - ;; Helpers for deprecated field types, to be removed later. (define %lazy-group (make-symbol "%lazy-group")) @@ -413,7 +410,7 @@ (define-configuration mpd-configuration (sanitizer mpd-group-sanitizer)) (shepherd-requirement - (list-of-symbol '()) + (list-of-symbols '()) "This is a list of symbols naming Shepherd services that this service will depend on." empty-serializer) @@ -711,7 +708,7 @@ (define-configuration/no-serialization mympd-configuration empty-serializer) (shepherd-requirement - (list-of-symbol '()) + (list-of-symbols '()) "This is a list of symbols naming Shepherd services that this service will depend on." empty-serializer) diff --git a/gnu/services/configuration.scm b/gnu/services/configuration.scm index 4eee5a26c2..fd9130b1ea 100644 --- a/gnu/services/configuration.scm +++ b/gnu/services/configuration.scm @@ -81,7 +81,9 @@ (define-module (gnu services configuration) interpose list-of + list-of-packages? list-of-strings? + list-of-symbols? alist? serialize-file-like text-config? @@ -508,6 +510,10 @@ (define* (interpose ls #:optional (delimiter "\n") (grammar 'infix)) (cons delimiter acc)))) '() ls)) + +;;; +;;; Commonly used predicates + (define (list-of pred?) "Return a procedure that takes a list and check if all the elements of the list result in @code{#t} when applying PRED? on them." @@ -516,10 +522,20 @@ (define (list-of pred?) (every pred? x) #f))) +(define list-of-packages? + (list-of package?)) (define list-of-strings? (list-of string?)) +(define list-of-symbols? + (list-of symbol?)) + + +;;; +;;; Special serializers +;;; + (define alist? (list-of pair?)) diff --git a/gnu/services/telephony.scm b/gnu/services/telephony.scm index 56b7772f58..c9b5d6cd99 100644 --- a/gnu/services/telephony.scm +++ b/gnu/services/telephony.scm @@ -117,15 +117,10 @@ (define (string-or-computed-file? val) (or (string? val) (computed-file? val))) -(define (string-list? val) - (and (list? val) - (and-map string? val))) +(define account-fingerprint-list? + (list-of account-fingerprint?)) -(define (account-fingerprint-list? val) - (and (list? val) - (and-map account-fingerprint? val))) - -(define-maybe string-list) +(define-maybe list-of-strings) (define-maybe/no-serialization account-fingerprint-list) @@ -135,7 +130,7 @@ (define-maybe string) ;;; The following serializers are used to derive an account details alist from ;;; a record. -(define (serialize-string-list _ val) +(define (serialize-list-of-strings _ val) (string-join val ";")) (define (serialize-boolean _ val) @@ -188,7 +183,7 @@ (define-configuration jami-account connection to the the Internet has been lost. When left unspecified, the value from the account archive prevails.") (bootstrap-hostnames - maybe-string-list + maybe-list-of-strings "A list of hostnames or IPs pointing to OpenDHT nodes, that should be used to initially join the OpenDHT network. When left unspecified, the value from the account archive prevails.") @@ -220,9 +215,8 @@ (define (jami-account->alist jami-account-object) (list-transduce jami-account-transducer rcons jami-account-fields)) -(define (jami-account-list? val) - (and (list? val) - (and-map jami-account? val))) +(define jami-account-list? + (list-of jami-account?)) (define-maybe/no-serialization jami-account-list) From patchwork Mon Jun 26 21:59:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Victal X-Patchwork-Id: 51376 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id C4FD827BBE9; Mon, 26 Jun 2023 23:02:21 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 2EF1527BBE2 for ; Mon, 26 Jun 2023 23:02:19 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qDuGq-0005WJ-Jv; Mon, 26 Jun 2023 18:01:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qDuGj-00052L-Um for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:10 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qDuGf-0005XK-Sm for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:07 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qDuGf-0008TP-OT for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:05 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63985] [PATCH v3 08/11] services: NetworkManager: Use define-configuration and generic-ini. Resent-From: Bruno Victal Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 26 Jun 2023 22:01:05 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63985 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63985@debbugs.gnu.org Cc: Bruno Victal Received: via spool by 63985-submit@debbugs.gnu.org id=B63985.168781684832477 (code B ref 63985); Mon, 26 Jun 2023 22:01:05 +0000 Received: (at 63985) by debbugs.gnu.org; 26 Jun 2023 22:00:48 +0000 Received: from localhost ([127.0.0.1]:47192 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuGN-0008RZ-LZ for submit@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:48 -0400 Received: from smtpmciv1.myservices.hosting ([185.26.107.237]:37982) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuGE-0008R9-GU for 63985@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:39 -0400 Received: from mail1.netim.hosting (unknown [185.26.106.173]) by smtpmciv1.myservices.hosting (Postfix) with ESMTP id 00A4220E27 for <63985@debbugs.gnu.org>; Tue, 27 Jun 2023 00:00:31 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail1.netim.hosting (Postfix) with ESMTP id 245D98009B; Tue, 27 Jun 2023 00:00:26 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mail1.netim.hosting Received: from mail1.netim.hosting ([127.0.0.1]) by localhost (mail1-2.netim.hosting [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id aBm-A5OjAj0H; Tue, 27 Jun 2023 00:00:25 +0200 (CEST) Received: from guix-nuc.home.arpa (unknown [10.192.1.83]) (Authenticated sender: lumen@makinata.eu) by mail1.netim.hosting (Postfix) with ESMTPSA id 691588009A; Tue, 27 Jun 2023 00:00:25 +0200 (CEST) From: Bruno Victal Date: Mon, 26 Jun 2023 22:59:34 +0100 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * gnu/services/networking.scm (): Define with define-configuration. (warn-iwd?-field-deprecation): Use regular define. (network-manager-accounts): Use match-record. (network-manager-environment): Subsume logic from vpn-plugin-directory. (network-manager-shepherd-service): Subsume logic from network-manager-activation. (vpn-plugin-directory, network-manager-activation): Remove. (network-manager-service-type): Adjust to changes listed above. --- gnu/services/networking.scm | 199 +++++++++++++++++++++++------------- 1 file changed, 127 insertions(+), 72 deletions(-) diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm index 5657b141d9..a4d3affa6c 100644 --- a/gnu/services/networking.scm +++ b/gnu/services/networking.scm @@ -41,6 +41,7 @@ (define-module (gnu services networking) #:use-module (gnu services) #:use-module (gnu services base) #:use-module (gnu services configuration) + #:use-module (gnu services configuration generic-ini) #:use-module (gnu services linux) #:use-module (gnu services shepherd) #:use-module (gnu services dbus) @@ -1157,92 +1158,145 @@ (define-record-type* ;;; ;; TODO: deprecated field, remove later. -(define-with-syntax-properties (warn-iwd?-field-deprecation - (value properties)) +(define (warn-iwd?-field-deprecation value) (when value - (warning (source-properties->location properties) - (G_ "the 'iwd?' field is deprecated, please use \ + (warning (G_ "the 'iwd?' field is deprecated, please use \ 'shepherd-requirement' field instead~%"))) value) -(define-record-type* - network-manager-configuration make-network-manager-configuration - network-manager-configuration? - (network-manager network-manager-configuration-network-manager - (default network-manager)) - (shepherd-requirement network-manager-configuration-shepherd-requirement - (default '(wpa-supplicant))) - (dns network-manager-configuration-dns - (default "default")) - (vpn-plugins network-manager-configuration-vpn-plugins ;list of file-like - (default '())) - (iwd? network-manager-configuration-iwd? ; TODO: deprecated field, remove. - (default #f) - (sanitize warn-iwd?-field-deprecation))) +(define-configuration network-manager-configuration + (network-manager + (package network-manager) + "The NetworkManager package to use." + empty-serializer) + + (shepherd-requirement + (list-of-symbols '(wpa-supplicant)) + "This option can be used to provide a list of symbols naming Shepherd +services that this service will depend on, such as @code{'wpa-supplicant} or +@code{'iwd} if you require authenticated access for encrypted WiFi or Ethernet +networks." + empty-serializer) + + (dns + (string "default") + "Processing mode for DNS, which affects how NetworkManager uses the +@code{resolv.conf} configuration file. + +@table @samp +@item default +NetworkManager will update @code{resolv.conf} to reflect the nameservers +provided by currently active connections. + +@item dnsmasq +NetworkManager will run @code{dnsmasq} as a local caching nameserver, using a +@dfn{conditional forwarding} configuration if you are connected to a VPN, and +then update @code{resolv.conf} to point to the local nameserver. + +With this setting, you can share your network connection. For example when +you want to share your network connection to another laptop @i{via} an +Ethernet cable, you can open @command{nm-connection-editor} and configure the +Wired connection's method for IPv4 and IPv6 to be ``Shared to other computers'' +and reestablish the connection (or reboot). + +You can also set up a @dfn{host-to-guest connection} to QEMU VMs +(@pxref{Installing Guix in a VM}). With a host-to-guest connection, you can +e.g.@: access a Web server running on the VM (@pxref{Web Services}) from a Web +browser on your host system, or connect to the VM @i{via} SSH +(@pxref{Networking Services, @code{openssh-service-type}}). To set up a +host-to-guest connection, run this command once: -(define (network-manager-activation config) - ;; Activation gexp for NetworkManager - (match-record config - (network-manager dns vpn-plugins) - #~(begin - (use-modules (guix build utils)) - (mkdir-p "/etc/NetworkManager/system-connections") - #$@(if (equal? dns "dnsmasq") - ;; create directory to store dnsmasq lease file - '((mkdir-p "/var/lib/misc")) - '())))) +@example +nmcli connection add type tun \ + connection.interface-name tap0 \ + tun.mode tap tun.owner $(id -u) \ + ipv4.method shared \ + ipv4.addresses 172.28.112.1/24 +@end example -(define (vpn-plugin-directory plugins) - "Return a directory containing PLUGINS, the NM VPN plugins." - (directory-union "network-manager-vpn-plugins" plugins)) +Then each time you launch your QEMU VM (@pxref{Running Guix in a VM}), pass +@option{-nic tap,ifname=tap0,script=no,downscript=no} to +@command{qemu-system-...}. + +@item none +NetworkManager will not modify @code{resolv.conf}. +@end table" + (serializer-options '(#:section main))) + + (vpn-plugins + (list-of-packages '()) + "This is the list of available plugins for virtual private networks +(VPNs). An example of this is the @code{network-manager-openvpn} +package, which allows NetworkManager to manage VPNs @i{via} OpenVPN." + empty-serializer) + + ;; Deprecated options + (iwd? + (boolean #f) + "Deprecated." + (sanitizer warn-iwd?-field-deprecation) + (serializer-options '(#:section device)) + (serializer + (lambda (_ value . rest) + (let ((value (if value "iwd" "wpa_supplicant"))) + (apply generic-ini-serialize-string + 'wifi.backend value rest))))) + + (prefix generic-ini-)) + +(define (network-manager-serialize-configuration config) + (mixed-text-file + "NetworkManager.conf" + (serialize-ini-configuration config + network-manager-configuration-fields))) (define (network-manager-accounts config) "Return the list of and for CONFIG." - (define nologin - (file-append shadow "/sbin/nologin")) - - (define accounts - (append-map (lambda (package) - (map (lambda (name) - (user-account (system? #t) - (name name) - (group "network-manager") - (comment "NetworkManager helper") - (home-directory "/var/empty") - (create-home-directory? #f) - (shell nologin))) - (or (assoc-ref (package-properties package) - 'user-accounts) - '()))) - (network-manager-configuration-vpn-plugins config))) - - (match accounts - (() - '()) - (_ - (cons (user-group (name "network-manager") (system? #t)) - accounts)))) + (match-record config + (vpn-plugins) + (let* ((nologin (file-append shadow "/sbin/nologin")) + (accounts + (append-map (lambda (package) + (map (lambda (name) + (user-account + (system? #t) + (name name) + (group "network-manager") + (comment "NetworkManager helper") + (home-directory "/var/empty") + (create-home-directory? #f) + (shell nologin))) + (or (assoc-ref (package-properties package) + 'user-accounts) + '()))) + vpn-plugins))) + (cond + ((null? accounts) '()) + (else (cons (user-group (name "network-manager") + (system? #t)) + accounts)))))) (define (network-manager-environment config) + "Define NM_VPN_PLUGIN_DIR variable in the global environment such that +\"nmcli connection import type openvpn file foo.ovpn\" works." (match-record config - (network-manager dns vpn-plugins) - ;; Define this variable in the global environment such that - ;; "nmcli connection import type openvpn file foo.ovpn" works. - `(("NM_VPN_PLUGIN_DIR" - . ,(file-append (vpn-plugin-directory vpn-plugins) - "/lib/NetworkManager/VPN"))))) + (vpn-plugins) + (let ((plugin-union (directory-union "network-manager-vpn-plugins" + vpn-plugins))) + `(("NM_VPN_PLUGIN_DIR" . ,(file-append plugin-union + "/lib/NetworkManager/VPN")))))) (define (network-manager-shepherd-service config) (match-record config - (network-manager shepherd-requirement dns vpn-plugins iwd?) + (network-manager shepherd-requirement dns iwd?) (let* ((iwd? (or iwd? ; TODO: deprecated field, remove later. (and shepherd-requirement (memq 'iwd shepherd-requirement)))) - (conf (plain-file "NetworkManager.conf" - (string-append - "[main]\ndns=" dns "\n" - (if iwd? "[device]\nwifi.backend=iwd\n" "")))) - (vpn (vpn-plugin-directory vpn-plugins))) + (conf (network-manager-serialize-configuration config)) + (vpn-plugin-env (map (match-lambda + ((key . value) + #~(string-append #$key "=" #$value))) + (network-manager-environment config)))) (list (shepherd-service (documentation "Run the NetworkManager.") (provision '(NetworkManager networking)) @@ -1254,6 +1308,10 @@ (define (network-manager-shepherd-service config) (actions (list (shepherd-configuration-action conf))) (start #~(lambda _ + (mkdir-p "/etc/NetworkManager/system-connections") + ;; Create directory to store dnsmasq lease file. + #$@(if (equal? dns "dnsmasq") + '((mkdir-p "/var/lib/misc")) '()) (let ((pid (fork+exec-command (list #$(file-append network-manager @@ -1261,8 +1319,7 @@ (define (network-manager-shepherd-service config) (string-append "--config=" #$conf) "--no-daemon") #:environment-variables - (list (string-append "NM_VPN_PLUGIN_DIR=" #$vpn - "/lib/NetworkManager/VPN") + (list #$@vpn-plugin-env ;; Override non-existent default users "NM_OPENVPN_USER=" "NM_OPENVPN_GROUP=" @@ -1301,8 +1358,6 @@ (define network-manager-service-type network-manager-configuration-network-manager)) (service-extension account-service-type network-manager-accounts) - (service-extension activation-service-type - network-manager-activation) (service-extension session-environment-service-type network-manager-environment) ;; Add network-manager to the system profile. From patchwork Mon Jun 26 21:59:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Victal X-Patchwork-Id: 51375 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 59E7327BBEC; Mon, 26 Jun 2023 23:02:20 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 4281727BBE9 for ; Mon, 26 Jun 2023 23:02:19 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qDuGq-0005VY-4a; Mon, 26 Jun 2023 18:01:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qDuGi-00051v-S6 for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:10 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qDuGf-0005XH-8Y for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:06 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qDuGf-0008TB-3c for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:05 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63985] [PATCH v3 09/11] services: NetworkManager: Prefer package over network-manager. Resent-From: Bruno Victal Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 26 Jun 2023 22:01:05 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63985 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63985@debbugs.gnu.org Cc: Bruno Victal Received: via spool by 63985-submit@debbugs.gnu.org id=B63985.168781684732465 (code B ref 63985); Mon, 26 Jun 2023 22:01:05 +0000 Received: (at 63985) by debbugs.gnu.org; 26 Jun 2023 22:00:47 +0000 Received: from localhost ([127.0.0.1]:47190 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuGN-0008RR-0b for submit@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:47 -0400 Received: from smtpmciv3.myservices.hosting ([185.26.107.239]:50424) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuGC-0008Qn-I3 for 63985@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:37 -0400 Received: from mail1.netim.hosting (unknown [185.26.106.173]) by smtpmciv3.myservices.hosting (Postfix) with ESMTP id B7439203C4 for <63985@debbugs.gnu.org>; Tue, 27 Jun 2023 00:00:35 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail1.netim.hosting (Postfix) with ESMTP id 1C7568009B; Tue, 27 Jun 2023 00:00:35 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mail1.netim.hosting Received: from mail1.netim.hosting ([127.0.0.1]) by localhost (mail1-2.netim.hosting [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id vtDQBfPRZ3Qi; Tue, 27 Jun 2023 00:00:34 +0200 (CEST) Received: from guix-nuc.home.arpa (unknown [10.192.1.83]) (Authenticated sender: lumen@makinata.eu) by mail1.netim.hosting (Postfix) with ESMTPSA id 8FB448009A; Tue, 27 Jun 2023 00:00:34 +0200 (CEST) From: Bruno Victal Date: Mon, 26 Jun 2023 22:59:35 +0100 Message-Id: <81521d94a397b288655c9bc8b68b9a0efe09bc38.1687816734.git.mirai@makinata.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * gnu/services/networking.scm () [package]: New field. [network-manager]: Deprecate field. (network-manager-environment, network-manager-shepherd) (network-manager-service-type): Adjust to use 'package'. * doc/guix.texi (Networking Setup): Replace mentions of network-manager with package. --- doc/guix.texi | 2 +- gnu/services/networking.scm | 41 +++++++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 2f7e734874..974bfa3fb0 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -20352,7 +20352,7 @@ Networking Setup Data type representing the configuration of NetworkManager. @table @asis -@item @code{network-manager} (default: @code{network-manager}) +@item @code{package} (default: @code{network-manager}) The NetworkManager package to use. @item @code{shepherd-requirement} (default: @code{'(wpa-supplicant)}) diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm index a4d3affa6c..496ff0f0ec 100644 --- a/gnu/services/networking.scm +++ b/gnu/services/networking.scm @@ -166,6 +166,7 @@ (define-module (gnu services networking) network-manager-configuration network-manager-configuration? + network-manager-configuration-package network-manager-configuration-shepherd-requirement network-manager-configuration-dns network-manager-configuration-vpn-plugins @@ -1164,8 +1165,10 @@ (define (warn-iwd?-field-deprecation value) 'shepherd-requirement' field instead~%"))) value) +(define-maybe/no-serialization package) + (define-configuration network-manager-configuration - (network-manager + (package (package network-manager) "The NetworkManager package to use." empty-serializer) @@ -1242,6 +1245,17 @@ (define-configuration network-manager-configuration (apply generic-ini-serialize-string 'wifi.backend value rest))))) + (network-manager + maybe-package + "Deprecated. Use ``package'' field instead." + (sanitizer + (lambda (value) + (when (maybe-value-set? value) + (warning (G_ "the 'network-manager' field is deprecated, please use \ +'package' field instead~%"))) + value)) + empty-serializer) + (prefix generic-ini-)) (define (network-manager-serialize-configuration config) @@ -1288,10 +1302,11 @@ (define (network-manager-environment config) (define (network-manager-shepherd-service config) (match-record config - (network-manager shepherd-requirement dns iwd?) + (package shepherd-requirement dns iwd?) (let* ((iwd? (or iwd? ; TODO: deprecated field, remove later. (and shepherd-requirement (memq 'iwd shepherd-requirement)))) + (package (maybe-value network-manager package)) (conf (network-manager-serialize-configuration config)) (vpn-plugin-env (map (match-lambda ((key . value) @@ -1314,7 +1329,7 @@ (define (network-manager-shepherd-service config) '((mkdir-p "/var/lib/misc")) '()) (let ((pid (fork+exec-command - (list #$(file-append network-manager + (list #$(file-append package "/sbin/NetworkManager") (string-append "--config=" #$conf) "--no-daemon") @@ -1332,7 +1347,7 @@ (define (network-manager-shepherd-service config) ;; to finish starting-up. This is required otherwise ;; services will fail since the network interfaces be ;; absent until NetworkManager finishes setting them up. - (system* #$(file-append network-manager "/bin/nm-online") + (system* #$(file-append package "/bin/nm-online") "--wait-for-startup" "--quiet") ;; XXX: Finally, return the pid from running ;; fork+exec-command to shepherd. @@ -1342,10 +1357,18 @@ (define (network-manager-shepherd-service config) (define network-manager-service-type (let ((config->packages (lambda (config) - (match-record config - (network-manager vpn-plugins) - `(,network-manager ,@vpn-plugins))))) - + (match-record config + (package network-manager vpn-plugins) + (let ((package (or (maybe-value network-manager) + package))) + `(,package ,@vpn-plugins))))) + ;; Handle network-manager field deprecation for + ;; polkit-service-type extension. + (network-manager-configuration-package* + (lambda (config) + (match-record config + (package network-manager) + (maybe-value network-manager package))))) (service-type (name 'network-manager) (extensions @@ -1355,7 +1378,7 @@ (define network-manager-service-type (service-extension polkit-service-type (compose list - network-manager-configuration-network-manager)) + network-manager-configuration-package*)) (service-extension account-service-type network-manager-accounts) (service-extension session-environment-service-type From patchwork Mon Jun 26 21:59:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Bruno Victal X-Patchwork-Id: 51378 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id C1E3827BBE2; Mon, 26 Jun 2023 23:03:28 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id E2B6727BBE9 for ; Mon, 26 Jun 2023 23:03:25 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qDuGr-0005ak-9n; Mon, 26 Jun 2023 18:01:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qDuGk-00052Z-3h for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:11 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qDuGg-0005XN-G0 for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:07 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qDuGg-0008Tc-At for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:06 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63985] [PATCH v3 10/11] services: NetworkManager: add log-configuration field. Resent-From: Bruno Victal Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 26 Jun 2023 22:01:06 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63985 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63985@debbugs.gnu.org Cc: Bruno Victal Received: via spool by 63985-submit@debbugs.gnu.org id=B63985.168781686532573 (code B ref 63985); Mon, 26 Jun 2023 22:01:06 +0000 Received: (at 63985) by debbugs.gnu.org; 26 Jun 2023 22:01:05 +0000 Received: from localhost ([127.0.0.1]:47201 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuGe-0008T9-OI for submit@debbugs.gnu.org; Mon, 26 Jun 2023 18:01:05 -0400 Received: from smtpm5.myservices.hosting ([185.26.105.236]:55252) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuGM-0008RN-QT for 63985@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:48 -0400 Received: from mail1.netim.hosting (unknown [185.26.106.173]) by smtpm5.myservices.hosting (Postfix) with ESMTP id 2991A20DB5 for <63985@debbugs.gnu.org>; Tue, 27 Jun 2023 00:00:45 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail1.netim.hosting (Postfix) with ESMTP id 3CE728009B; Tue, 27 Jun 2023 00:00:45 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mail1.netim.hosting Received: from mail1.netim.hosting ([127.0.0.1]) by localhost (mail1-2.netim.hosting [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 6-L-W1LkITRE; Tue, 27 Jun 2023 00:00:44 +0200 (CEST) Received: from guix-nuc.home.arpa (unknown [10.192.1.83]) (Authenticated sender: lumen@makinata.eu) by mail1.netim.hosting (Postfix) with ESMTPSA id 501658009A; Tue, 27 Jun 2023 00:00:44 +0200 (CEST) From: Bruno Victal Date: Mon, 26 Jun 2023 22:59:36 +0100 Message-Id: <79ae045eeb94e92221fcff8272cae9673c376f9b.1687816734.git.mirai@makinata.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * gnu/services/networking.scm (network-manager-log-level?) (network-manager-log-domain?, network-manager-log-domains?): New predicate. (serialize-network-manager-log-level, serialize-network-manager-log-domains): New procedure. (network-manager-log-configuration): New record type. (network-manager-configuration)[log-configuration]: New field. * doc/guix.texi (Networking Setup): Document it. --- doc/guix.texi | 43 +++++++++++++++ gnu/services/networking.scm | 107 ++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) diff --git a/doc/guix.texi b/doc/guix.texi index 974bfa3fb0..76bd1b1413 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -20361,6 +20361,10 @@ Networking Setup @code{'iwd} if you require authenticated access for encrypted WiFi or Ethernet networks. +@item @code{log-configuration} (default: @code{(network-manager-log-configuration)}) +Logging configuration for NetworkManager. +This is a @code{} record object. + @item @code{dns} (default: @code{"default"}) Processing mode for DNS, which affects how NetworkManager uses the @code{resolv.conf} configuration file. @@ -20412,6 +20416,45 @@ Networking Setup @end table @end deftp +@deftp {Data Type} network-manager-log-configuration +Available @code{network-manager-log-configuration} fields are: + +@table @asis +@item @code{level} (type: maybe-network-manager-log-level) +The default logging verbosity level. Valid values are (in increasing +order of verbosity): @code{'off}, @code{'err}, @code{'warn}, +@code{'info}, @code{'debug} and @code{'trace}. + +@item @code{domains} (type: maybe-network-manager-log-domains) +Log messages by topic. The value for this field is a list of +@var{domains} or pairs of @var{domains} and @var{levels} where the valid +values for @var{levels} are the same as those described in the ``level'' +field and @var{domains} are any of: @code{'platform}, @code{'rfkill}, +@code{'ether}, @code{'wifi}, @code{'bt}, @code{'mb}, @code{'dhcp4}, +@code{'dhcp6}, @code{'ppp}, @code{'wifi-scan}, @code{'ip4}, @code{'ip6}, +@code{'autoip4}, @code{'dns}, @code{'vpn}, @code{'sharing}, +@code{'supplicant}, @code{'agents}, @code{'settings}, @code{'suspend}, +@code{'core}, @code{'device}, @code{'olpc}, @code{'wimax}, +@code{'infiniband}, @code{'firewall}, @code{'adsl}, @code{'bond}, +@code{'vlan}, @code{'bridge}, @code{'dbus-props}, @code{'team}, +@code{'concheck}, @code{'dcb}, @code{'dispatch}, @code{'audit}, +@code{'systemd}, @code{'vpn-plugin}, @code{'proxy}, @code{'none}, +@code{'all}, @code{'default}, @code{'dhcp} and @code{'ip}. The log +level can be overrided per-domain in a pair with a @var{level}. +For example: +@lisp +(network-manager-log-configuration + (level 'warn) + (domains '(all (wifi . debug) (wifi-scan . off)))) +@end lisp + +@item @code{audit?} (type: maybe-boolean) +Whether to send audit records to @command{auditd}. + +@end table +@end deftp + + @cindex Connman @defvar connman-service-type This is the service type to run @url{https://01.org/connman,Connman}, diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm index 496ff0f0ec..33ff5e040f 100644 --- a/gnu/services/networking.scm +++ b/gnu/services/networking.scm @@ -78,7 +78,10 @@ (define-module (gnu services networking) #:use-module (srfi srfi-9) #:use-module (srfi srfi-26) #:use-module (srfi srfi-43) + #:use-module (srfi srfi-171) + #:use-module (ice-9 format) #:use-module (ice-9 match) + #:use-module (ice-9 string-fun) #:use-module (json) #:re-export (static-networking-service static-networking-service-type) @@ -164,10 +167,16 @@ (define-module (gnu services networking) tor-hidden-service ; deprecated tor-service-type + network-manager-log-configuration + network-manager-log-configuration? + network-manager-log-configuration-level + network-manager-log-configuration-domains? + network-manager-log-configuration-audit? network-manager-configuration network-manager-configuration? network-manager-configuration-package network-manager-configuration-shepherd-requirement + network-manager-configuration-log-configuration network-manager-configuration-dns network-manager-configuration-vpn-plugins network-manager-service-type @@ -1158,6 +1167,92 @@ (define-record-type* ;;; NetworkManager ;;; +(define-maybe boolean) + +;; See the logging section at +;; for +;; the list of valid values for the predicates below. +(define (network-manager-log-level? x) + (memq x '(off err warn info debug trace))) + +(define (network-manager-log-domain? x) + (memq x '(platform rfkill ether wifi bt mb dhcp4 dhcp6 ppp wifi-scan ip4 ip6 + autoip4 dns vpn sharing supplicant agents settings + suspend core device olpc wimax infiniband firewall adsl + bond vlan bridge dbus-props team concheck dcb dispatch + audit systemd vpn-plugin proxy + ;; Special NetworkManager domains: + none all default dhcp ip))) + +(define (network-manager-log-domains? x) + (every + (match-lambda + (((? network-manager-log-domain?) . (? network-manager-log-level?)) #t) + ((? network-manager-log-domain?) #t) + (_ #f)) + x)) + +(define (serialize-network-manager-log-level field-name value) + `(logging level ,(format #f "~:@(~a~)" value))) + +(define (serialize-network-manager-log-domains field-name value) + (define (uglify-domain-symbol x) + (string-replace-substring (symbol->string x) "-" "_")) + + (define serialize-entry + (match-lambda + (((= uglify-domain-symbol domain) . value) + (format #f "~:@(~a:~a~)" domain value)) + ((= uglify-domain-symbol domain) + (format #f "~:@(~a~)" domain)))) + + (let ((serialized-value (list-transduce (compose (tmap serialize-entry) + (tadd-between ",")) + string-append value))) + `(logging domains ,serialized-value))) + +(define-maybe network-manager-log-level) +(define-maybe network-manager-log-domains) + +;; This implicitly belongs to the INI "logging" section. +(define-configuration network-manager-log-configuration + (level + maybe-network-manager-log-level + "The default logging verbosity level. Valid values are (in increasing +order of verbosity): @code{'off}, @code{'err}, @code{'warn}, @code{'info}, +@code{'debug} and @code{'trace}.") + + (domains + maybe-network-manager-log-domains + "Log messages by topic. The value for this field is a list of @var{domains} +or pairs of @var{domains} and @var{levels} where the valid values for +@var{levels} are the same as those described in the ``level'' field and +@var{domains} are any of: @code{'platform}, @code{'rfkill}, @code{'ether}, +@code{'wifi}, @code{'bt}, @code{'mb}, @code{'dhcp4}, @code{'dhcp6}, +@code{'ppp}, @code{'wifi-scan}, @code{'ip4}, @code{'ip6}, @code{'autoip4}, +@code{'dns}, @code{'vpn}, @code{'sharing}, @code{'supplicant}, @code{'agents}, +@code{'settings}, @code{'suspend}, @code{'core}, @code{'device}, @code{'olpc}, +@code{'wimax}, @code{'infiniband}, @code{'firewall}, @code{'adsl}, @code{'bond}, +@code{'vlan}, @code{'bridge}, @code{'dbus-props}, @code{'team}, @code{'concheck}, +@code{'dcb}, @code{'dispatch}, @code{'audit}, @code{'systemd}, +@code{'vpn-plugin}, @code{'proxy}, @code{'none}, @code{'all}, @code{'default}, +@code{'dhcp} and @code{'ip}. + +The log level can be overrided per-domain in a pair with a @var{level}. +For example: +@lisp +(network-manager-log-configuration + (level 'warn) + (domains '(all (wifi . debug) (wifi-scan . off)))) +@end lisp") + + (audit? + maybe-boolean + "Whether to send audit records to @command{auditd}." + (serializer generic-ini-serialize-boolean) + (serializer-options `(#:section logging + #:field-name-transform ,(const 'audit))))) + ;; TODO: deprecated field, remove later. (define (warn-iwd?-field-deprecation value) (when value @@ -1181,6 +1276,18 @@ (define-configuration network-manager-configuration networks." empty-serializer) + (log-configuration + (network-manager-log-configuration (network-manager-log-configuration)) + "Logging configuration for NetworkManager. This is a +@code{} record object." + (serializer + (lambda (_ value) + ;; Wrap the serialization of the log-configuration which is a list + ;; of INI entries in a ‘ini-entries’ object. + (ini-entries (list-transduce + (base-transducer value) rcons + network-manager-log-configuration-fields))))) + (dns (string "default") "Processing mode for DNS, which affects how NetworkManager uses the From patchwork Mon Jun 26 21:59:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruno Victal X-Patchwork-Id: 51373 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id CE1A327BBE9; Mon, 26 Jun 2023 23:02:01 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, SPF_HELO_PASS autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 7FA8827BBE2 for ; Mon, 26 Jun 2023 23:02:01 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qDuGp-0005SR-Jb; Mon, 26 Jun 2023 18:01:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qDuGk-00052t-6a for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:11 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qDuGg-0005XO-QT for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:08 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qDuGg-0008Tl-MO for guix-patches@gnu.org; Mon, 26 Jun 2023 18:01:06 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63985] [PATCH v3 11/11] services: NetworkManager: Add extra-options field. Resent-From: Bruno Victal Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 26 Jun 2023 22:01:06 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63985 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63985@debbugs.gnu.org Cc: Bruno Victal Received: via spool by 63985-submit@debbugs.gnu.org id=B63985.168781686632586 (code B ref 63985); Mon, 26 Jun 2023 22:01:06 +0000 Received: (at 63985) by debbugs.gnu.org; 26 Jun 2023 22:01:06 +0000 Received: from localhost ([127.0.0.1]:47204 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuGf-0008TK-L3 for submit@debbugs.gnu.org; Mon, 26 Jun 2023 18:01:06 -0400 Received: from smtpm2.myservices.hosting ([185.26.105.233]:34376) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDuGS-0008Rw-Qj for 63985@debbugs.gnu.org; Mon, 26 Jun 2023 18:00:53 -0400 Received: from mail1.netim.hosting (unknown [185.26.106.173]) by smtpm2.myservices.hosting (Postfix) with ESMTP id 6769320E6F for <63985@debbugs.gnu.org>; Tue, 27 Jun 2023 00:00:52 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail1.netim.hosting (Postfix) with ESMTP id C28258009B; Tue, 27 Jun 2023 00:00:51 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mail1.netim.hosting Received: from mail1.netim.hosting ([127.0.0.1]) by localhost (mail1-2.netim.hosting [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 0OtqaWwF1hKi; Tue, 27 Jun 2023 00:00:51 +0200 (CEST) Received: from guix-nuc.home.arpa (unknown [10.192.1.83]) (Authenticated sender: lumen@makinata.eu) by mail1.netim.hosting (Postfix) with ESMTPSA id 5A4548009A; Tue, 27 Jun 2023 00:00:51 +0200 (CEST) From: Bruno Victal Date: Mon, 26 Jun 2023 22:59:37 +0100 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * gnu/services/networking.scm (network-manager-configuration) [extra-options]: New field. * doc/guix.texi (Networking Setup): Document it. --- doc/guix.texi | 7 +++++++ gnu/services/networking.scm | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/doc/guix.texi b/doc/guix.texi index 76bd1b1413..a74718f216 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -20413,6 +20413,13 @@ Networking Setup (VPNs). An example of this is the @code{network-manager-openvpn} package, which allows NetworkManager to manage VPNs @i{via} OpenVPN. +@item @code{extra-options} (default: @code{'()}) (type: list-of-ini-entries) +Additional options to be appended to @file{NetworkManager.conf} (run +@samp{man networkmanager.conf} for more information). It expects a list +whose elements are lists of the form @code{'(@var{section} @var{key} +@var{value})}, where @var{section} and @var{key} are symbols and +@var{value} is a string. + @end table @end deftp diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm index 33ff5e040f..4cb1cd60cb 100644 --- a/gnu/services/networking.scm +++ b/gnu/services/networking.scm @@ -179,6 +179,7 @@ (define-module (gnu services networking) network-manager-configuration-log-configuration network-manager-configuration-dns network-manager-configuration-vpn-plugins + network-manager-configuration-extra-options network-manager-service-type connman-configuration @@ -1340,6 +1341,14 @@ (define-configuration network-manager-configuration package, which allows NetworkManager to manage VPNs @i{via} OpenVPN." empty-serializer) + (extra-options + (list-of-ini-entries '()) + "Additional options to be appended to @file{NetworkManager.conf} (run +@samp{man networkmanager.conf} for more information). +It expects a list whose elements are lists of the form +@code{'(@var{section} @var{key} @var{value})}, where @var{section} and +@var{key} are symbols and @var{value} is a string.") + ;; Deprecated options (iwd? (boolean #f)