Ludovic Courtès (2017-06-03 23:21 +0200) wrote: > Ludovic Courtès skribis: > >> 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. > > I found a better name: “customizations”. I kinda like "finalization" more :-) But "customization" is fine with me, not a big deal. >> 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. > > Not liking the “sudo” aspect of this patch, I thought it would be > natural if service types could control how customizations apply. That > way, the PAM or /etc service could still guarantee, for instance, that > customization does not add or remove entries, and so on. Ouch, that's what I don't like. I think a full control is better. You'll never know what a user might want to do, and giving a user a full freedom (even to break a system!) would be a great feature. So I'm against such guarantees that strict users in modifying their systems. > In the end, this control by the service type makes it easier to reason > about what extensions do, whereas the “sudo” style means that an > extension can alter the service’s value in any possible way. Right, "any possible way" is exactly what I want! > So I started modifying this patch set to add a ‘customize’ field to > , next to ‘extend’. For the PAM and /etc services, > ‘customize’ would compose and apply procedures that modify an entry, for > instance. > > Then I realized that the only difference between ‘customize’ and > ‘extend’ would be the meaning attached to it. IOW, both are some kind > of an extension. > > So at this point, I started wondering whether we should just allow > service types to declare several extension points. So for PAM, we’d do: > > (define pam-service-addition > ;; The extension point to add PAM services. > (service-extension-point > (compose concatenate) > (extend append))) > > (define pam-service-cutomization > ;; The extension point to customize PAM services. > (service-extension-point > (compose compose) > (extend append))) > > (define pam-root-service-type > (service-type (name 'pam) > (extensions (list (service-extension etc-service-type > /etc-entry))) > > (extension-points (list pam-service-addtion > pam-service-customization)))) > > But then ‘service-extension’ would need to specify not only the target > service type but also the target extension point, which means more > boilerplate, etc. I don't have a deep understanding of services, but your suggestion seems (to me) to have the following downsides: - More additional work – to determine (and implement) what aspects of services should and what should not be modified by a user. - Less freedom (comparing to your previous solution) for users in modifying services. > So after so much thought and hacking, I feel like the ad hoc solution at > > was not that bad after all. He-he :-) > Sorry to bother you with philosophical design questions when we already > have two ways to solve the problem at hand, but I feel like there’s a > pattern worth looking for! No problem, looking for patterns is always an interesting occupation! As for me, I agree with any solution that allows me to replace "/etc/profile". But in general, I vote for that solution that allows users to customize as much things as possible. -- Alex