Closed IngwiePhoenix closed 5 months ago
You can see me experimenting between revisions of the script and the results here:
id
is executed, showing that the script indeed runs as laminar
)echo $HOME
is used - and it shows /root
!)I'm a bit unsure whether this is the wrong behaviour. The run-as
setting just sets the identity that runs the process - that's all it was meant to do; the load-options = export-passwd-vars
exists precisely for this kind of case where you also want various environment variables to be set. I do see why it was unexpected, but I think that's because your use case is a bit unusual: you're seemingly running dinit as root, with HOME
set (to root's home directory). Normally when dinit is run by root it's a system instance and wouldn't have HOME
set. How are you starting dinit
?
One option if you don't want to have to specify load-options
for several services might be to clear HOME
via the environment file, /etc/dinit/environment
. If not running dinit as a system instance you need to explicitly pass -e /etc/dinit/environment
to use this. The contents can be:
!unset HOME
... to clear just the home directory, or:
!clear
... to completely clear the environment. (These are documented in the dinit
man page).
Thanks for the reply!
I looked into the details a little more once you mentioned "system service".
So I was running dinit
as part of OpenWrt before but had installed Alpine's APK to get some dev packages installed too. However, the apk installed packages and OpenWrt packages soon started to "meld" and cause a heap of linkage problems... so, I reinstalled.
Since then, I am using Alpine in a chroot off of their own chroot installer script (I realized I had ujail
from OpenWrt only a while later...) and thus used the entry script to run dinit
on system startup.
Here are the details:
## /etc/init.d/dinit
#!/bin/sh /etc/rc.common
START=50
USE_PROCD=1
PROG=/sdcard/bin/dinit
start_service() {
procd_open_instance
procd_set_param command /usb/alpine/enter-chroot dinit -d /sdcard/dinit.d
procd_set_param respawn
procd_close_instance
}
## /usb/alpine/enter-chroot
#!/bin/sh
set -e
try_to_mount() {
local mto mfrom
mfrom="$1"
mto="/usb/alpine/$2"
if [ -z "$2" ]; then
mto="/usb/alpine/$1"
fi
# Exists?
if [ ! -d "$mto" ]; then
mkdir -p "$mto"
fi
# is not mounted?
mountpoint -q "$mto" \
|| mount --bind "$mfrom" "$mto"
}
# Mounts
## Dirs
try_to_mount /proc
try_to_mount /sys
### /dev needs --rbind...
mount --rbind /dev /usb/alpine/dev
try_to_mount /root
## Drives
try_to_mount /usb
try_to_mount /sdcard
try_to_mount /mnt/diskstation/bunker
try_to_mount /mnt/diskstation/scratch
## Socks
try_to_mount /var/run/tailscale /run/tailscale
ENV_FILTER_REGEX='(TERM|ARCH|CI|QEMU_EMULATOR|TRAVIS_.*)'
user='root'
if [ $# -ge 2 ] && [ "$1" = '-u' ]; then
user="$2"; shift 2
fi
oldpwd="$(pwd)"
[ "$(id -u)" -eq 0 ] || _sudo='sudo'
tmpfile="$(mktemp)"
chmod 644 "$tmpfile"
export | sed -En "s/^([^=]+ ${ENV_FILTER_REGEX}=)('.*'|\".*\")$/\1\3/p" > "$tmpfile" || true
cd "$(dirname "$0")"
$_sudo mv "$tmpfile" env.sh
$_sudo chroot . /usr/bin/env -i su -l "$user" \
sh -c ". /etc/profile; . /env.sh; cd '$oldpwd' 2>/dev/null; \"\$@\"" \
-- "${@:-fish}"
After reading your reply, I believe the su -l
part in the chroot
line is what is causing the issue; a login is requested.
I had completely forgotten that there was an environment
file alltogether; so I will probably use that going forward. Maybe !clear
is what I do need indeed. Though wouldn't that wipe out every process' $HOME
variable as well? I have two others that actually rely on it to find their configuration.
Kind regards, Ingwie
Though wouldn't that wipe out every process' $HOME variable as well?
Yes, it would prevent HOME
from being set, to any value. Whether this is a problem or not depends on the applications that use it: if it's not set, they might choose to lookup the home directory in the user database ("pwd database"). So, simply not having it set (to the wrong value) might be enough to solve any issues.
Regardless, using load-options = export-passwd-vars
for affected services should resolve it. This is not the default because it requires accessing the user database, and it isn't needed by most system services even if they do run as another user.
@IngwiePhoenix ok if I close this? I know it's probably not working exactly as you would like it to, but it is by design. There are always trade-offs that have to be managed...
Hello!
Apologies for my late reply; this had slipped to the far bottom of my notifications list... so I only see this now.
I made some tests with load-options = export-passwd-vars
and that, together with clearing the dinit environment entirely, seems to be what I needed. I do wish there was like a "defaults service" for things like this; most services I use actually do use $HOME
of their respective account they run under. So having a way to configure this, as well as logging options and file locations, would be very handy. :)
Hello!
I found a bit of a bug. While setting up laminar CI/CD and running a few jobs, I got a weird error from Yarn. Maybe you can spot the problem right away ;)
And here is the dinit unit:
The problem: The unit was
run-as = laminar
but still had$HOME
set to/root
! This is obviously wrong. So, I usedload-options = export-passwd-vars
to work around that.But honestly, this should actually be the default whenever you use
run-as
.Is there a way I can just make this the default for all units going forward?
Kind regards, Ingwie