Hello! Currently ‘guix system reconfigure’ doesn’t try to dynamically update the set of running services, which is a shame.
A simple strategy would be to have it: 1. Stop and unregister services currently known to dmd that are missing in the new configuration. 2. Load and start (if they have ‘auto-start?’) services that are in the new configuration and currently unknown to dmd. 3. The rest is the most difficult part: dealing with services that already exist but that have changed (see below.) One step towards this has been the fact that each service has its code in a module of its own (commit fae685b), making it easy to have dmd load it. For #3, the difficulty is that we cannot do deco stop/load/start for core services like udev or file-system-root because stopping these would effectively halt the system. However, we can safely restart services that are leaves of the dmd graph (unless the user explicitly asks not to do it.) Here’s what it would mean on my system, which uses ‘%desktop-services’ and a few more: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> ,use(guix) scheme@(guile-user)> ,use(gnu) scheme@(guile-user)> ,use(gnu services dmd) scheme@(guile-user)> (define os (load "/home/ludo/src/configuration/pluto-configuration.scm")) scheme@(guile-user)> ,use(gnu services) scheme@(guile-user)> (define dmds (fold-services (operating-system-services os) #:target-type dmd-root-service-type)) scheme@(guile-user)> ,use(gnu services) scheme@(guile-user)> (length (service-parameters dmds)) $2 = 49 scheme@(guile-user)> (define back-edges (dmd-service-back-edges (service-parameters dmds))) scheme@(guile-user)> ,use(srfi srfi-1) scheme@(guile-user)> (map dmd-service-provision (filter (lambda (s) (null? (back-edges s))) (service-parameters dmds))) $3 = ((swap-/dev/sda4) (nscd) (guix-daemon) (console-font-tty6) (console-font-tty5) (console-font-tty4) (console-font-tty3) (console-font-tty2) (console-font-tty1) (ntpd) (elogind) (upower-daemon) (avahi-daemon) (xorg-server) (tor) (ssh-daemon) (bitlbee)) scheme@(guile-user)> (length $3) $4 = 17 --8<---------------cut here---------------end--------------->8--- 17 out of 49 services could be restarted. As a first step, we could ignore the other services. As a second step, we could maybe have an ‘upgrade’ action that would mutate their <service> instance in place, but without actually restarting them, such that the changes would only take effect on the next restart. Roughly, we’d be doing, say: deco upgrade udev /gnu/store/…-dmd-udev.scm where …-dmd-udev.scm is the service file that contains: (make <service> #:provides '(udev) …) The ‘upgrade’ action would ‘set!’ all the fields of the old service instance to those of the new instance, such that they are ‘equal?’ (but not ‘eq?’.) The caveat is that this is not atomic. Thoughts? The prerequisite to all this work is to make the dmd RPCs machine-processable, which is not too much work. Thanks, Ludo’.