home mcron service overwrites PATH with a GuixSD-only directory

  • Open
  • quality assurance status badge
Details
5 participants
  • Oleg Pykhalov
  • Gary Johnson
  • Ludovic Courtès
  • nils
  • Tanguy LE CARROUR
Owner
unassigned
Submitted by
nils
Severity
normal
N
(name . bug-guix@gnu.org)(address . bug-guix@gnu.org)
509099431.327298.1692786160360@office.mailbox.org
Hello,
when using the home-mcron-service, PATH is set to /run/current-system/profile/bin . This directory is empty when using guix home on a foreign distro, meaning all executable paths would need to be absolute. This includes stuff like /usr/bin/ssh, /usr/bin/nice etc..
My guess for the culprit was 1c30d5a6bfc5d48137f4bdcc271189a06fdc6ed3 , which replaced the custom home-mcron-service-type with mapping it to mcron-service-type.
The mcron shepherd service in old service type did not mess with the environment variables, the inherited one does:
#:environment-variables
(cons* "GUILE_AUTO_COMPILE=0"
"PATH=/run/current-system/profile/bin"
(remove (cut string-prefix? "PATH=" <>)
(environ)))
Strange thing is that the commit is from 2023-08-06, and I update guix almost every day, but did not run into the issue until today. But the commit seems to fit the issue perfectly, so I'm not sure what's going on at all.
Attachment: file
L
L
Ludovic Courtès wrote on 20 Nov 2023 23:10
(address . nils@landt.email)(address . 65471@debbugs.gnu.org)
87jzqcoz3a.fsf@gnu.org
Hi,

Apologies for the delay.

nils@landt.email skribis:

Toggle quote (10 lines)
> when using the home-mcron-service, PATH is set to /run/current-system/profile/bin . This directory is empty when using guix home on a foreign distro, meaning all executable paths would need to be absolute. This includes stuff like /usr/bin/ssh, /usr/bin/nice etc..
>
> My guess for the culprit was 1c30d5a6bfc5d48137f4bdcc271189a06fdc6ed3 , which replaced the custom home-mcron-service-type with mapping it to mcron-service-type.
> The mcron shepherd service in old service type did not mess with the environment variables, the inherited one does:
> #:environment-variables
> (cons* "GUILE_AUTO_COMPILE=0"
> "PATH=/run/current-system/profile/bin"
> (remove (cut string-prefix? "PATH=" <>)
> (environ)))

As a rule of thumb, I personally always provide absolute file names, as
in #~(job … #$(file-append coreutils "/bin/ls") …).

I wonder what the preferred behavior would be. Restore PATH to whatever
value it had when the user ‘shepherd’ process was started, at the
expense of making things harder to track/less reproducible? Should we
leave it unset, possibly breaking programs that expect it to be set?
Should we set it to “/run/current-system/profile/bin:/usr/bin” or
similar?

Thanks,
Ludo’.
O
O
Oleg Pykhalov wrote on 21 Nov 2023 01:46
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 65471@debbugs.gnu.org)
87msv8szk5.fsf@gmail.com
Hi Ludovic,

Ludovic Courtès <ludo@gnu.org> writes:
[…]

Toggle quote (7 lines)
> I wonder what the preferred behavior would be. Restore PATH to whatever
> value it had when the user ‘shepherd’ process was started, at the
> expense of making things harder to track/less reproducible? Should we
> leave it unset, possibly breaking programs that expect it to be set?
> Should we set it to “/run/current-system/profile/bin:/usr/bin” or
> similar?

1c30d5a6 was almost 3 months ago, so we could assume most of the users
are already reconfigured to this (or newer) commit and fixed their
configurations accordingly.

Because we probably cannot be sure how they fixed it, I think the best
that we could do is not to change the current behavior again and provide
a support and documentation if needed, so we don't break users
configurations again.

Also, the current behavior ‘PATH=/run/current-system/profile/bin’
matches with mcron started by Shepherd on a Guix System on pretty recent
commit ‘fc6bdaad57bf91609849623c5f485403c030cb49’, which probably is
better than difference of PATH dependending on is it system's Shepherd
or user's Shepherd instance running.

We could allow users to control an environment of mcron, but I think it
should be:

- optional for both system's and user's Shepherd instances;
- not a default behavior, because we already switched from PATH=<IMPURE>
to ‘PATH=/run/current-system/profile/bin’.


Regards,
Oleg.
-----BEGIN PGP SIGNATURE-----

iQJIBAEBCgAyFiEEcjhxI46s62NFSFhXFn+OpQAa+pwFAmVb/foUHGdvLndpZ3Vz
dEBnbWFpbC5jb20ACgkQFn+OpQAa+pzUOQ/+NT9PM7NurGNIo5KCYSxR+VHxRQY+
LjjVlbk/kH7WE+DHIAJCq6XqJVEdgblsIK97vRlgHn/+ytSYEmdXoFH3RL7eR0fO
OfmDX+5AlMPtmt8DMAttv0MVt87bKRTjnG4k7hpIIEPbuY3Sln/SJd8y0/LbbziW
UxUhn5U2hCjHo3gi1+BNvmTlwgZgUCnAbQup/crPo7aEFyeGQapVRSOqmjR4X/PU
xgwwc9UOpkvM2yspeqBTzmP6x+l8bB4LsK4j27F0c+I4U/DwoGFdi3B/27/DT9ZD
Jr9maU9YUJya5kXI0H/GraxaLg6KW0xCERfMW9XrQQ8JDckweB4aZA3+Y+bb8iXK
uEWwCGGdSTZl3GI3r09bCNCJDizGp1ITgd7g9d9kawts/CMy+PL1XGbapcZ5CW/1
CNU76waPxGbJRfPmTkSuKCPGbPh6PIe/q6c0Zx6i3jd6Mn+QQCcJwOAVUA+Og+Fp
qTFmK/ZAT56h91hbsS0xoyMPp/3/iSuZnRwLGK3ug6+JIq4jhGPc35qFy2LDl/KZ
da7qdpHw9zxkv6dnrWTmI0hZJkzWXPNwWQF9DiNvVqz3EZicYsl2N6EQoZOqS+p0
ag/R0vZ7xI2oUgdAYx9kDf4hrq00jRIxr2nSZZCbY1tvnS6fOiub6OVb+KmjvAW4
ZkA1v98m12B99Dw=
=6PxZ
-----END PGP SIGNATURE-----

N
N
Nils Landt wrote on 21 Nov 2023 16:09
(name . Ludovic Courtès)(address . ludo@gnu.org)(name . 65471@debbugs.gnu.org)(address . 65471@debbugs.gnu.org)
1041149717.395497.1700579341071@office.mailbox.org
Toggle quote (17 lines)
> Ludovic Courtès <ludo@gnu.org> hat am 20.11.2023 23:10 CET geschrieben:

> nils@landt.email skribis:
>
> > when using the home-mcron-service, PATH is set to /run/current-system/profile/bin . This directory is empty when using guix home on a foreign distro, meaning all executable paths would need to be absolute. This includes stuff like /usr/bin/ssh, /usr/bin/nice etc..
> >
> > My guess for the culprit was 1c30d5a6bfc5d48137f4bdcc271189a06fdc6ed3 , which replaced the custom home-mcron-service-type with mapping it to mcron-service-type.
> > The mcron shepherd service in old service type did not mess with the environment variables, the inherited one does:
> > #:environment-variables
> > (cons* "GUILE_AUTO_COMPILE=0"
> > "PATH=/run/current-system/profile/bin"
> > (remove (cut string-prefix? "PATH=" <>)
> > (environ)))
>
> As a rule of thumb, I personally always provide absolute file names, as
> in #~(job … #$(file-append coreutils "/bin/ls") …).

I do the same, but occasionally a program I call expects something to be available in PATH. For me (guix home in Debian 12), this includes Guix itself.
Running
/home/nl/.config/guix/current/bin/guix pull
in a terminal works perfectly fine, but
unset PATH
/home/nl/.config/guix/current/bin/guix pull
results in a stacktrace that ends in:
In guix/scripts/pull.scm:
453:4 4 (_)
In guix/build/utils.scm:
625:6 3 (which "guix")
In unknown file:
2 (string-tokenize #f #<charset {#\nul..#\9 #\;..#\15377…> …)
In ice-9/boot-9.scm:
1685:16 1 (raise-exception _ #:continuable? _)
1685:16 0 (raise-exception _ #:continuable? _)

ice-9/boot-9.scm:1685:16: In procedure raise-exception:
In procedure string-tokenize: Wrong type argument in position 1 (expecting string): #f

Toggle quote (7 lines)
> I wonder what the preferred behavior would be. Restore PATH to whatever
> value it had when the user ‘shepherd’ process was started, at the
> expense of making things harder to track/less reproducible? Should we
> leave it unset, possibly breaking programs that expect it to be set?
> Should we set it to “/run/current-system/profile/bin:/usr/bin” or
> similar?

I think the previous behaviour was fine for a user level service. I'm guessing this was inheriting the environment variables from the shepherd process that started mcron?

Otherwise, adding /usr/local/bin:/usr/bin:/bin should be a good default I think.

I'm not emotionally invested either way, I have moved away from shepherd / mcron.
T
T
Tanguy LE CARROUR wrote on 15 Jan 13:39 +0100
(address . 65471@debbugs.gnu.org)
170532239853.11028.2082972878645432596@bioneland.org
Hi,

I've just experienced the problem first hand:

Nils suggested to set the `PATH` environment variable, but 1) I have no
clue how to do that ? and 2) it is not exactly the behaviour I would
expect from a home service.

Has anything been decided?

Regards,

--
Tanguy
G
G
Gary Johnson wrote 3 days ago
Re: home mcron service overwrites PATH with a GuixSD-only directory
(address . 65471@debbugs.gnu.org)
87r0gwps6b.fsf@disroot.org
Hi Guix,

The bug in which home-mcron-service-type overwrites the user's PATH with a single non-existent directory makes mcron completely unusable on foreign distros. Since it seems to me that foreign distros are the main target for home mcron services (since there is no global shepherd to run mcron for you), this really should be elevated to a high priority bug.

I see that earlier in this message thread questions were raised as to what the proper behavior should be for setting the PATH, but I think we can say with no reservations that setting PATH to a directory that is guaranteed not to exist on a foreign distro is definitely not the correct choice. Also, setting it explicitly to directories not managed by Guix profiles or Guix Home like /bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin, and so on also isn't a great idea since users of the home-cron-service-type are obviously using it through Guix Home. The correct choice IMHO is to follow the principle of least surprise here.

Namely, in the Guix info pages at "(guix)Top > Home Configuration > Home Services > Mcron Home Service", we have section "13.3.3 Scheduled User’s Job Execution". Under home-mcron-configuration, we see the "jobs" field, which links us to "mcron job specifications(mcron)" for explanations of how to define our mcron jobs.

Following this link on to "(mcron)Top > Syntax > Guile Syntax", we encounter section "3.1.1 Job specification". The final paragraph in this section reads as follows:

Toggle quote (2 lines)
> The second argument to the 'job' function can be either a string, a list, or a function. The command is executed in the home directory and with the UID of USER. If a string is passed, it is assumed to be shell script and is executed with the user's default shell. If a list is passed it is assumed to be Scheme code and is _eval_'d as such. A supplied function should take exactly zero arguments, and will be called at the pertinent times.

Note the third sentence:

"If a string is passed, it is assumed to be shell script and is executed with the user's default shell."

Reading that, I (and I imagine most mcron users) will infer that the environment my job command will run in will be the same as what I would get if I spawned a new non-interactive shell. That is, the new mcron job shell should inherit all the environment variables that were defined when the user's sheperd process was launched (which will be everything loaded into a standard login shell, such as /etc/profile, ~/.bash_profile, and everything that they source like Guix Home's ~/.profile) plus a fresh run of ~/.bashrc (or the equivalent non-interactive shell config file for whatever shell the user has chosen). It seems to me that this is what most people reading the manual are going to understand (and therefore expect) and that it is the most compatible with Guix Home since all environment variables set in the `home-environment` will be available to our mcron jobs.

However, with the current behavior, it appears that the shell spawned for the user mcron job actually reads /etc/profile and ~/.profile (but not ~/.bash_profile or ~/.bashrc). The ~/.profile file sources ~/.guix-home/setup-environment and then runs ~/.guix-home/on-first-login. While being very confusing and unintuitive (because my default shell is /bin/bash and is reported correctly within the mcron job environment as "SHELL=/bin/bash"), this at least loads ~/.guix-home/profile/etc/profile and ~/.guix-profile/etc/profile. However, since mcron then promptly erases the correctly built up PATH from Guix Home and the user's main Guix profile, the commands executed in this PATH-less shell are borked.

As others in this thread have previously noted, with the current behavior of providing an unintuitive and completely unusable PATH to user mcron jobs, the home-mcron-service-type is largely unusable except for the simplest commands in which you can use ungexp package directory expansion to build up the locations of a Guix-installed executable. However, if any job command ever needs to shell out to any other executable, it will not be found, and the job will crash and burn.

Please fix this, folks. And if you aren't willing to implement the intuitive, documented, and Guix Home compatible shell behavior described above, please at the very least extend the "job" function with a keyword to allow us to pass environment variables into the mcron job shell along with something like the "(default-environment-variables)" function that is available for shepherd service "start" functions.

Thanks!
Gary

--
GPG Key ID: C4FBEDBD
Use `gpg --search-keys tracker@disroot.org' to find me
Protect yourself from surveillance: https://emailselfdefense.fsf.org
=======================================================================
() ascii ribbon campaign - against html e-mail
/\ www.asciiribbon.org - against proprietary attachments

Why is HTML email a security nightmare? See https://useplaintext.email/

Please avoid sending me MS-Office attachments.
?