Ludovic Courtès (2017-05-30 23:58 +0200) wrote: > Hello! > > This patch adds support for service extensions that modify the > "final" values of a service. This is meant to implement cross-cutting > concerns as well as system-wide customization as discussed with Alex > long ago: > > https://lists.gnu.org/archive/html/guix-devel/2015-11/msg00623.html > https://lists.gnu.org/archive/html/guix-devel/2016-09/msg01505.html > > To summarize, a "finalization extension" (for lack of a better name) > gets the final value of a service and returns a new value for that > service. This is in contrast with a "normal" extension which can only > contribute to the value of a target service, and not inspect the value > of that target service. > > For example, for the /etc service, a "normal" extension can only add > entries for /etc. A "finalization" extension can instead inspect and > change all the /etc entries. IOW, it is a sort of a "sudo" for service > extensions; it's also quite inelegant compared to the "normal" extension > mechanism, but it's certainly useful. Definitely! > A use case is given in the second patch: we change all the PAM services > to use pam_elogind.so or pam_limits.so. Likewise, the 'rename-etc-files' > service below shows how to rename all the files in /etc (for illustration > purposes only :-)): > > (define rename-etc-files > (let ((rename (lambda (prefix entries) > (map (match-lambda > ((name . rest) > (cons (string-append prefix name) > rest))) > entries)))) > (service-type > (name 'rename-etc-files) > (extensions (list (service-extension etc-service-type > (const '()) > rename)))))) > > > (operating-system > ;; ... > (services (cons* (service rename-etc-files "foo-") > ...))) > > I think this should fulfill the need that Alex had expressed, which is > to not only be able to add files to /etc, but also to have the ability > to inspect and modify what goes to /etc. This is great! Just what I wanted, and thanks for this example! Based on it, I made the following service: (define replace-etc/profile-type (let ((replace (lambda (file entries) (cons `("profile" ,file) (map (match-lambda ((name . rest) (cons (if (string= name "profile") (string-append "original-profile") name) rest))) entries))))) (service-type (name 'replace-etc/profile) (extensions (list (service-extension etc-service-type (const '()) replace)))))) (service replace-etc/profile-type (local-file ".../my-system-profile")) So now I can use my own "/etc/profile", moreover I can look at the "/etc/original-profile" anytime. I already use a system with this service and I enjoy it, thanks a lot! > The first patch currently lacks doc. I'll work on it if there's consensus > on the approach. I agree with this approach! -- Alex