Subject: bug#76698: Activations interfere with each other modules

From: Tomas Volf <[email-masked]>
Date: Fri, 07 Mar 2025 22:29:51 +0100

Hilton Chain <[email-masked]> writes:

> Hi Tomas,
>
> On Mon, 03 Mar 2025 09:02:22 +0800,
> Tomas Volf wrote:
>>
>> Hello,
>>
>> when using `activation-service-type' combined with `with-extension', the
>> various modules seem to interfere with each other.
>>
>> In my case the samba-service-type interferes with my custom service:
>>
>> --8<---------------cut here---------------start------------->8---
>> (define (watcher-activation* config)
>>   (match-record config <watcher-configuration>
>>                 (user group cache-dir state-dir)
>>     (with-extension/guile-wolfsden
>>      #~(begin
>>          (use-modules (wolfsden fs)
>>                       (wolfsden sh))
>>          (for-each (lambda (dir)
>>                      (mkdir-p dir)
>>                      (invoke* #$(file-append coreutils "/bin/chown")
>>                               "-Rv" (string-append #$user ":" #$group) dir)
>>                      (chmod dir #o700))
>>                    '(#$cache-dir
>>                      #$state-dir))))))
>> --8<---------------cut here---------------end--------------->8---
>>
>> samba-service-type's activation starts with:
>>
>> --8<---------------cut here---------------start------------->8---
>> (define (samba-activation config)
>>   (let ((package (samba-configuration-package config))
>>         (config-file (samba-configuration-config-file config)))
>>     (with-imported-modules '((guix build utils))
>> --8<---------------cut here---------------end--------------->8---
>>
>> Both (guix build utils) and (wolfsden sh) provide (invoke) procedure,
>> however with incompatible parameters, leading to somewhat annoying to
>> debug issues.  In my case the error was:
>>
>> --8<---------------cut here---------------start------------->8---
>> guix deploy: error: failed to deploy x: failed to switch systems while deploying '127.0.0.1':
>> keyword-argument-error #f "Invalid keyword" () ("/etc/samba/smb.conf")
>> --8<---------------cut here---------------end--------------->8---
>>
>> Which makes sense now when I understand what the problem is, but it took
>> while to get to it.
>>
>> I do not think this should be the case.  Either each activation service
>> should be isolated into a fresh user module, or the services provided by
>> Guix should not introduce any additional modules into the scope.
>> Alternatively, each activation service could be wrapped into
>> program-file, that would ensure isolation as well.
>
> Activation scripts are already ‘program-file’s,

Ah, yes, on second look you are right.  I did not realized at first,
since they are sourced using primitive-load instead of executed.

> but unfortunately (gnu build activation) and (guix build utils) are
> implicit dependencies.  This is hard to change at the moment.

I do not think this is true.  When I look at the activation script for
my service, I do not see any additional code then my service has.  So
assuming it would be executed, instead of loaded, (guix build utils)
should not be in the environment.  Am I missing something?

>
> I have sent a patch which might partially address your issue:
>
> [PATCH v2 3/3] services: activation: Continue on exceptions.
> https://issues.guix.gnu.org/73494#26
>
> It executes activation scripts by ‘invoke’, so they won't change the
> environment.
>
> What I'm trying to achieve is to avoid blocking the activation process when one
> script fails.

Well, that patch would probably resolve my issues, correct.  What I am
unsure about is whether ignoring errors is a good idea and what (if any)
impact it will have on the rest of the deploy process.  Like, if the
activation fails, would it not be better to rollback instead of push
forward?  Dunno, I probably just do not know enough about this. :)

Tomas

-- 
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.