From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp10.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id uLPMA8UEDWOCYwAAbAwnHQ (envelope-from ) for ; Mon, 29 Aug 2022 20:26:13 +0200 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp10.migadu.com with LMTPS id OHvRAsUEDWOgagEAG6o9tA (envelope-from ) for ; Mon, 29 Aug 2022 20:26:13 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id B5BB12C44F for ; Mon, 29 Aug 2022 20:26:12 +0200 (CEST) Received: from localhost ([::1]:52292 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oSjSd-0005TD-UP for larch@yhetil.org; Mon, 29 Aug 2022 14:26:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:32902) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oSjSP-0005Sy-N5 for guix-devel@gnu.org; Mon, 29 Aug 2022 14:25:57 -0400 Received: from mail-ed1-x535.google.com ([2a00:1450:4864:20::535]:40592) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oSjSN-0005ZR-RI for guix-devel@gnu.org; Mon, 29 Aug 2022 14:25:57 -0400 Received: by mail-ed1-x535.google.com with SMTP id m1so11246451edb.7 for ; Mon, 29 Aug 2022 11:25:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:user-agent:from:to:cc:subject:date; bh=h6HOmmmID1qYdg4E/6xVV/q329cLQ10SfFSY08onfCU=; b=qTZeOIwQg+T8/NuI18SF6n51u6j/DN+4m0juuFDYZpCdYyhc8DShnWEXjq01vwxHEj x7B/UUXc36/vob6B3lmRATBKwIOWKOIvw7DOxOApoAZdHZGUdZdoea57e2W6zUgqqHmN Y8raqY5K0F3tdLN61jigxJ0NfBYnrhwB7gc6HHDAr21JfbLBW6Ob31HsuZhSevIEQ8xO aUETUB7X3OFmAFIJl6JtTBcvKmXFU4HdylZtpdfDvCJchY905C61I7ERVPI8jrCvUQqo eQDnJjVP+bN2arCSRHFuFE8FM/9vUQXoK6ghtC0pCUO/6lrUw9/hda78lYtzgOSV9z5i SeqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:user-agent:x-gm-message-state:from:to:cc:subject:date; bh=h6HOmmmID1qYdg4E/6xVV/q329cLQ10SfFSY08onfCU=; b=OJx4IqVkRPqeMLFhCTscwYo7cPgyP66cszbUEYAefpyASpirKqksnQpJi1JjvdXvTn 6d3cgS5KYpoqWTAV/I4cni1rBc9k2CP3FGm3aH9C1SYFd3MGLIV98Vb4AV95OHncFHG9 XXA+/fcA/w4KUsgtOY/2EgRs6vVON+T0mlllmhEfKL0equN9KhE0gCILroqfS/1Yk3Nf w/sfRh/oXIK8PYC44g36r6itqkcVwKRkHrynn4KcNp+p5TALUYgHIIs+jQaZik32jiZR 7Vyhp7YvjlRtsRN1SH0HB5MG1vdfD2yEs/t1rcD/xduzniPukE9Nf40MLyVepsU3CJck KpBw== X-Gm-Message-State: ACgBeo1Dom/SLEXLshyAa9+rHom/4jwxYi6BNwE4zemnsyPcEN/g/DN6 AVNO92mh+r5YXjRLgyvy1LvB4+MKAtw= X-Google-Smtp-Source: AA6agR7gFU/8iCJG1CqIEmzgzfrzWo4hkPArlg0Z6A0Z/XGMPCs+X3ZKLAM/liP0j6jaWYssfZBJTA== X-Received: by 2002:a05:6402:c10:b0:447:60b6:583 with SMTP id co16-20020a0564020c1000b0044760b60583mr17550575edb.115.1661797553686; Mon, 29 Aug 2022 11:25:53 -0700 (PDT) Received: from gazelle.gmail.com (p579ad9b0.dip0.t-ipconnect.de. [87.154.217.176]) by smtp.gmail.com with ESMTPSA id vp10-20020a17090712ca00b0072b1bc9b37fsm4742752ejb.22.2022.08.29.11.25.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Aug 2022 11:25:52 -0700 (PDT) User-agent: mu4e 1.8.7; emacs 28.1.90 From: =?utf-8?Q?Th=C3=A9o?= Maxime Tyburn To: guix-devel@gnu.org Subject: Idea: Function composition to declare operating-system Date: Mon, 29 Aug 2022 17:14:11 +0200 Message-ID: <87edwylxe9.fsf@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Received-SPF: pass client-ip=2a00:1450:4864:20::535; envelope-from=theo.tyburn@gmail.com; helo=mail-ed1-x535.google.com X-Spam_score_int: -4 X-Spam_score: -0.5 X-Spam_bar: / X-Spam_report: (-0.5 / 5.0 requ) BAYES_00=-1.9, DATE_IN_PAST_03_06=1.592, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: guix-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+larch=yhetil.org@gnu.org Sender: "Guix-devel" X-Migadu-Flow: FLOW_IN X-Migadu-To: larch@yhetil.org X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1661797572; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:list-id:list-help: list-unsubscribe:list-subscribe:list-post:dkim-signature; bh=h6HOmmmID1qYdg4E/6xVV/q329cLQ10SfFSY08onfCU=; b=NO3ee5FqVV/wKU/TsMbWqqaCjjtlml8HN9d2srftqIH0GK8yxJrupbCdEhPe8DhrHc2/E0 CyrKLk1zu+2ude6rf3AayCpSAoXRH6HfS0ZAbQsmRX3/X5gNWm2ZlmpAllR0iowX9XePVI 67wsjwu6gv2ie09wOHX0BrpoSFHhlMLf6CXvqCC1WFuEi2JVICV/ONSSSnFnI5arJ4ns7N k41Pf1xuGcvdo3P++DwMMD53kq3T0DPEJSEJKTzvJPklj3hQgkHjB7rSaVBa/XV+OqpiqL KxKW2k9wk09OeF42xDrQm2lWNqruhabngstj1jRc4MKUW2+fUEiHwZgrFsNw6A== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1661797572; a=rsa-sha256; cv=none; b=kSfW7YzOVNHrqa7OnU7t+5JOro2ccBc7DEcAPQWFr5a5Rpt65LMU3IJOweInJ887m1CLoa u50f8uC2WaAt2oUSY52HoSmHnQzGzuEUIjKbTnQa0qw6sH3EkZDmQdwQ13/wxU+syXaYy3 z4N15ziRwfOTjSIV9QPlO5H2M9dvwb3YU0ru0BSRaIoVMyal42YR8PkD2cWqun59fm/SQQ HyUx63bcEec9S10HpossqCQtF5rycJrjOvYmHY2Ockf6oV1AKVKbfpXvqxGE8zFdYIPv+H 7xEvMfboSnuX0XBVVPkPpwk9eYzUHDhbBnW99qeAyE2+gCyx9iQIoglh7aZ/+A== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=qTZeOIwQ; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of "guix-devel-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-devel-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: -7.80 Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=qTZeOIwQ; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of "guix-devel-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-devel-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: B5BB12C44F X-Spam-Score: -7.80 X-Migadu-Scanner: scn0.migadu.com X-TUID: m7q2e78qaBFf Hi guix! I experimented on a functional approach to the operating system declaration. My goal was to be able to pass an operating-system instance to a composition of functions, modifying it one after another and returning the desired operating-system object. I find this approach more convenient because it allows for better segmentation of the system features. I achieved to make it work for the system declaration I usually use and I=E2=80=99d like to share it with you. --BEGIN USE_CASE For example to add jackd to my system I need to add the "realtime" group, add some users to this group and add a pam-limits-service. If I want to remove this functionality from my system using the declarative approach I have to look down my config file for places where I added these things. Usually I partially solve this problem by putting comments to signal the purpose of each code block in the system declaration. But wouldn=E2=80=99t it be better if I just had a function `add-jackd` that= takes an operating-system instance and returns the os with the extra functionalities= ? --END USE_CASE So that was the purpose of the experimentation. It didn=E2=80=99t turn out = to be too complicated to implement. At least for my use case, I just needed to ad= d two helper functions to extend users and services fields. The rest is handled directly= by record inheritance and by accessing the fields of the input operating-syste= m. The final declaration looks like this: --8<---------------cut here---------------start------------->8--- ((apply compose (reverse os-functions)) minimal-os) --8<---------------cut here---------------end--------------->8--- Where `minimal-os` is roughly an (operation-system) declaration with at least all the required fields. `os-functions` is a list of procedures taking an operating-system as input and returning an operating-system. An example for one such function that adds a label: --8<---------------cut here---------------start------------->8--- (define (label-os os) (operating-system (inherit os) (label (string-append (operating-system-host-name os) ":" "refactor-functional-os" ;; my custom tag " " (operating-system-default-label this-operating-system))))) --8<---------------cut here---------------end--------------->8--- The most problematic thing is handling services. For some reason I ignore, there is a set of services that always gets added again to the list of services when you call (operating-system ...) with a services field with more than one service. So you can=E2=80=99t just do like above and --8<---------------cut here---------------start------------->8--- (define (add-some-service os) (operating-system (inherit os) (services (cons (simple-service ...) (operating-system-services os))))) --8<---------------cut here---------------end--------------->8--- because some services that need to be unique would come more than once in the final operating-system object. So I just added a simple function to filter them out --8<---------------cut here---------------start------------->8--- (define* (extend-operating-system-services os services #:key (drop '()) (ke= ep '())) (append (filter (lambda (service) (not (member (service-type-name (service-kind service)) (filter (lambda (s) (not (member s keep))) (append drop %fixed-system-service-types))))) (operating-system-services os)) services)) --8<---------------cut here---------------end--------------->8--- and also force keeping or dropping of some services if needed. The list of services that gets duplicated seems to be this one: --8<---------------cut here---------------start------------->8--- (define %fixed-system-service-types '(account activate boot cleanup etc file-systems firmware fstab guix host= -name linux-bare-metal linux-builder pam profile root-file-system session-e= nvironment setuid-program shepherd-root system user-processes)) --8<---------------cut here---------------end--------------->8--- I generated the list by just checking which services get duplicated, so I a= m not very sure about it. There surely is a better way to get it.=20 Anyway I can now define a function adding desktop functionalities: --8<---------------cut here---------------start------------->8--- (define (x-os os) (operating-system (inherit os) (services (extend-operating-system-services os (list ;; slim display manager (service slim-service-type (slim-configuration (display ":0") (vt "vt7") (theme %default-slim-theme) (theme-name %default-slim-theme-name) (xorg-configuration (xorg-configuration (keyboard-layout (operating-system-keyboard-layout os))))))) #:drop '(gdm))) (packages (cons* ;; window managers i3-wm python-py3status emacs-nc-exwm-xdg (operating-system-packages os) )))) --8<---------------cut here---------------end--------------->8--- Of course there is room for some macros to make this more elegant, but this is the rough idea. In a way it feels like treating the operating-system like a service you can extend. Maybe it would even make sense to implement this as a service ? Not sure about that. It seems it would also be reasonable to have something like an operating-system-configuration record and a way to compose some before putting them into an operating-system record (it seems to be the approach rde `features` are based on). But I felt too lazy to copy all the fields from the operating-system record definition. There might be a way to get all the fields programatically and define a record/configuration though. Anyway, what do you think about this functionality? Have you already experi= mented with similar things? Did I reinvent the wheel? Is there a better approach? Anyway that was a very fun hacking session :) Happy Hacking! Th=C3=A9o