Skip to content

Instantly share code, notes, and snippets.

@emandret
Created June 27, 2023 17:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emandret/6f21b9d8bad6d7e4eb1346b144481a7c to your computer and use it in GitHub Desktop.
Save emandret/6f21b9d8bad6d7e4eb1346b144481a7c to your computer and use it in GitHub Desktop.
Stub script to emulate systemd in WSL
#!/bin/bash
# NOTE: replace the root user shell by placing this script at /usr/local/bin/systemd-stub
# login user
user=ed
if [[ -p /dev/stdin ]] || [[ "$BASH_ARGC" -gt 0 ]]; then
shell=/bin/bash
else
shell=$(getent passwd $user | cut -d : -f 7)
fi
if [[ "$PWD" =~ ^/root ]]; then
cd $(eval 'echo ~$user')
fi
systemd_is_running() {
systemd_pid=$(pgrep -xo systemd)
if [[ $? -eq 0 ]]; then
export SYSTEMD_PID=$systemd_pid
return 0
fi
return 1
}
# if systemd is already running as PID 1, we just start a shell
if systemd_is_running && [[ $SYSTEMD_PID -eq 1 ]]; then
exec "$shell" "$@"
fi
if ! systemd_is_running; then
# start systemd as a daemon process
/usr/sbin/daemonize -l "$HOME/.systemd.lock" /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd
if [[ $? -ne 0 ]]; then
echo 'Error: systemd failed to start.' 1>&2
exit 1
fi
# wait for systemd to start
max_retries=60
while ! systemd_is_running && [[ "$retries" -le "$max_retries" ]]; do
sleep 1
(( retries++ ))
done
if [[ "$retries" -gt "$max_retries" ]]; then
echo 'Error: systemd timed out; aborting.' 1>&2
exit 1
fi
fi
# save WSL mountpoints in PATH
if [[ ! -z $PATH ]]; then
export WINPATH=$(echo "$PATH" | grep -oP ':/mnt/c/[^:]+' | tr -d '\n' | cut -c 2-)
fi
runopts=""
runopts="$runopts --login"
runopts="$runopts --whitelist-environment=WINPATH"
runopts="$runopts --shell=$shell"
# enter systemd namespaces and execute a login shell
exec /usr/bin/nsenter --all --target $SYSTEMD_PID --wd="$PWD" /sbin/runuser $runopts $user -- $@
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment