ohwgiles / laminar

Fast and lightweight Continuous Integration
https://laminar.ohwg.net
GNU General Public License v3.0
298 stars 54 forks source link

Shell not sourcing /etc/profile on NixOS #202

Closed roomcays closed 10 months ago

roomcays commented 10 months ago

Hello! I'm not sure if this issue is related to laminar or NixOS. I have migrated from Debian to NixOS and have encountered many problems, one of them is that job scripts I can't use typical shebang as such:

#!/usr/bin/env bash

This gives me:

/usr/bin/env: ‘bash’: No such file or directory

in the job's log.

However, the dedicated laminar's user (laminar) has defined Bash as default shell, excerpt from /etc/group below:

laminar:x:989:987::/data/laminar:/run/current-system/sw/bin/bash

and if I log in as this user I can run laminar jobs successfully.

When investigating the issue I have arrived to the point where I suspect that laminar's subshell does not parse either /etc/profile nor /etc/bashrc, because these are the files where correct, final $PATH is set and without it even bash executable can not be found...

So my question is: is laminar calling subshell with some non-login/non-interactive switches that may cause /etc/profile to be skipped?

ohwgiles commented 10 months ago

So my question is: is laminar calling subshell with some non-login/non-interactive switches that may cause /etc/profile to be skipped?

This is not quite the right angle. /etc/profile and /etc/bashrc are parsed by bash itself, but in your case the child process spawned by laminar has not even executed bash yet.

The error /usr/bin/env: ‘bash’: No such file or directory means that env cannot find bash, which means PATH is probably not set correctly, but this will be in the laminard process itself, not in its subshell.

You can check the environment of a process at /proc/$pid/environ. You should be able to confirm that the path to bash is not in laminard's PATH.

How are you starting laminard? Using systemd? I'm not a NixOS user but I suspect there will be some method of adding Environment="PATH=/path/to/nix/bash/dir" to the [Service] section of laminar's unit file.

Tagging @maralorn as I believe they set up the Nix package.

roomcays commented 10 months ago

@ohwgiles you are right. The $PATH environment variable is not set correctly and because of that bash executable can not be found.

Experimenting (and trying to make things work) I've changed shebang for:

#!/run/current-system/sw/bin/bash

which executed Bash correctly, but the commands in script (like wget, git, etc) also could not be found because $PATH was set to (parsed):

/data/laminar/cfg/scripts
/nix/store/j4fwy5gi1rdlrlbk2c0vnbs7fmlm60a7-coreutils-9.1/bin
/nix/store/x6rwgp1jl5sgzwbsaigqkdbdc7krzwj7-findutils-4.9.0/bin
/nix/store/8mzvz6kk57p9aqdk72pq1adsl38bkzi6-gnugrep-3.7/bin
/nix/store/vqj2w8rqghmmp4wkn9lkcym5kzlqk372-gnused-4.9/bin
/nix/store/4mvn48zibv588i7ijbylw3d035kxndr1-systemd-253.6/bin
/nix/store/j4fwy5gi1rdlrlbk2c0vnbs7fmlm60a7-coreutils-9.1/sbin
/nix/store/x6rwgp1jl5sgzwbsaigqkdbdc7krzwj7-findutils-4.9.0/sbin
/nix/store/8mzvz6kk57p9aqdk72pq1adsl38bkzi6-gnugrep-3.7/sbin
/nix/store/vqj2w8rqghmmp4wkn9lkcym5kzlqk372-gnused-4.9/sbin
/nix/store/4mvn48zibv588i7ijbylw3d035kxndr1-systemd-253.6/sbin

instead of:

/run/wrappers/bin
/data/laminar/.nix-profile/bin
/etc/profiles/per-user/laminar/bin
/nix/var/nix/profiles/default/bin
/run/current-system/sw/bin

which I get when I log in to a laminar user.

The first one looks to me like paths used for building laminar.

How are you starting laminard? Using systemd? I'm not a NixOS user but I suspect there will be some method of adding Environment="PATH=/path/to/nix/bash/dir" to the [Service] section of laminar's unit file.

Yes. I've created myself (as a novice NixOS user, by lots of trials and errors) a systemd service script, that after "nixing" looks like that:

[Unit]
After=network.target
Description=Laminar continuous integration service

[Service]
Environment="LAMINAR_ARCHIVE_URL=https://example.com/archive"
Environment="LAMINAR_BIND_HTTP=unix:/run/laminar/laminar.socket"
Environment="LAMINAR_HOME=/data/laminar"
Environment="LOCALE_ARCHIVE=/nix/store/iv839p4x1k1y7nv1sfgqbbrrk5h99xfg-glibc-locales-2.37-8/lib/locale/locale-archive"
Environment="PATH=/nix/store/j4fwy5gi1rdlrlbk2c0vnbs7fmlm60a7-coreutils-9.1/bin:/nix/store/x6rwgp1jl5sgzwbsaigqkdbdc7krzwj7-findutils-4.9.0/bin:/nix/store/8mzvz6kk57p9aqdk72pq1adsl38bkzi6-gnugrep-3.7/bin:/nix/store/vqj2w8rqghmmp4wkn9lkcym5kzlqk372-gnused-4.9/bin:/nix/store/4mvn48zibv588i7ijbylw3d035kxndr1-systemd-253.6/bin:/nix/store/j4fwy5gi1rdlrlbk2c0vnbs7fmlm60a7-coreutils-9.1/sbin:/nix/store/x6rwgp1jl5sgzwbsaigqkdbdc7krzwj7-findutils-4.9.0/sbin:/nix/store/8mzvz6kk57p9aqdk72pq1adsl38bkzi6-gnugrep-3.7/sbin:/nix/store/vqj2w8rqghmmp4wkn9lkcym5kzlqk372-gnused-4.9/sbin:/nix/store/4mvn48zibv588i7ijbylw3d035kxndr1-systemd-253.6/sbin"
Environment="TZDIR=/nix/store/3yx6fa7gxgp4p6d79skvscvdd21alclp-tzdata-2023c/share/zoneinfo"
ExecStart=/nix/store/zczdbp2jlw0qhsz8jw7zkmckkvrd5nzk-laminar-1.2/bin/laminard -v
RuntimeDirectory=laminar
User=laminar

I have now noticed the $PATH set in that service! Thank you @ohwgiles ! I will now try to experiment with setting Environment="PATH=.... I'd like to make it the same as after sourcing /etc/profile.

roomcays commented 10 months ago

Success! I've added:

    path = [
      pkgs.bash
      pkgs.wget
      pkgs.git
      pkgs.docker
      pkgs.openssh
      pkgs.rsync
    ];

to the systemd.services.laminar definition and bash and other utils are now available.

I've learned a lot today. Thank you @ohwgiles for prompt reply and navigating to the solution :)