Hi, I had similar problem popping up periodically. So here are my 10 cents.. Théo Maxime Tyburn 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