[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Idea: Function composition to declare operating-system
From: |
muradm |
Subject: |
Re: Idea: Function composition to declare operating-system |
Date: |
Tue, 30 Aug 2022 11:49:35 +0300 |
User-agent: |
mu4e 1.8.9; emacs 29.0.50 |
Hi,
I had similar problem popping up periodically.
So here are my 10 cents..
Théo Maxime Tyburn <theo.tyburn@gmail.com> writes:
Hi guix!
[...]
--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’t 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
To clarify, do you ask that in the end of the day, some where
in (gnu services ...) there should be exported `add-jackd`
function? If so, I beleive that this will increase cross
dependency between things, thus decreasing flexibility.
Imagine `add-jackd` maintainer should always keep track on
what is being added into guix, that potentially may cause
conflict with jackd and/or require adjustments in `add-jackd`
function implementation.
Also, IMHO, implementation of `add-jackd` would be very
much opinionated.
So that was the purpose of the experimentation. It didn’t turn
out to be
too complicated to implement. At least for my use case, I just
needed to add 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-system.
The final declaration looks like this:
((apply compose (reverse os-functions)) minimal-os)
[...]
(define* (extend-operating-system-services os services #:key
(drop '()) (keep '()))
(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))
I suppose this could be useful to have it in guix toolbox,
although I would prefer to have (required '(account activate ...))
or (required %fixed-system-service-types) optional argument,
instead of refering to global constant
%fixed-system-service-types,
which might not satisfy everyone requirements.
and also force keeping or dropping of some services if needed.
The list
of services that gets duplicated seems to be this one:
(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-environment setuid-program
shepherd-root system user-processes))
I generated the list by just checking which services get
duplicated, so I am not
very sure about it. There surely is a better way to get it.
Anyway I can now define a function adding desktop
functionalities:
(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)
))))
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 experimented with similar things?
Did I reinvent the wheel? Is there a better approach?
Did you try using (modify-services ...)? Basically, you can
achieve similar goal within services list only with it.
Anyway that was a very fun hacking session :)
Happy Hacking!
Théo
Thanks in advance,
muradm
signature.asc
Description: PGP signature