-
-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rewrite syschdemd #126
Rewrite syschdemd #126
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
{ runCommand | ||
, makeWrapper | ||
, lib | ||
, coreutils | ||
, daemonize | ||
, glibc | ||
, gnugrep | ||
, systemd | ||
, util-linux | ||
, defaultUser | ||
, automountPath | ||
, | ||
}: | ||
let | ||
mkWrappedScript = | ||
{ name | ||
, src | ||
, path | ||
, ... | ||
} @ args: | ||
runCommand name ({ nativeBuildInputs = [ makeWrapper ]; } // args) '' | ||
install -Dm755 ${src} $out/bin/${name} | ||
patchShebangs $out/bin/${name} | ||
substituteAllInPlace $out/bin/${name} | ||
wrapProgram $out/bin/${name} --prefix PATH ':' ${lib.escapeShellArg path} | ||
''; | ||
|
||
wrapper = mkWrappedScript { | ||
name = "nixos-wsl-systemd-wrapper"; | ||
src = ./wrapper.sh; | ||
path = lib.makeSearchPath "" [ | ||
"/run/wrappers/bin" # mount | ||
"${systemd}/lib/systemd" # systemd | ||
]; | ||
}; | ||
in | ||
mkWrappedScript { | ||
name = "syschdemd"; | ||
src = ./syschdemd.sh; | ||
path = lib.makeBinPath [ | ||
"/run/wrappers" # mount | ||
coreutils | ||
daemonize | ||
glibc # getent | ||
gnugrep | ||
systemd # machinectl | ||
util-linux # nsenter | ||
wrapper | ||
]; | ||
inherit defaultUser automountPath; | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,136 @@ | ||||||
#!/usr/bin/env bash | ||||||
set -euo pipefail | ||||||
|
||||||
[ "${NIXOS_WSL_DEBUG:-}" == "1" ] && set -x | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
testing if it is set to anything maybe makes it easier if people accidentally use true There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, applied. |
||||||
|
||||||
rundir="/run/nixos-wsl" | ||||||
pidfile="$rundir/unshare.pid" | ||||||
|
||||||
ensure_root() { | ||||||
if [ $EUID -ne 0 ]; then | ||||||
echo "[ERROR] Requires root! :( Make sure the WSL default user is set to root" >&2 | ||||||
exit 1 | ||||||
fi | ||||||
} | ||||||
|
||||||
activate() { | ||||||
mount --bind -o ro /nix/store /nix/store | ||||||
|
||||||
LANG="C.UTF-8" /nix/var/nix/profiles/system/activate | ||||||
} | ||||||
|
||||||
create_rundir() { | ||||||
if [ ! -d $rundir ]; then | ||||||
mkdir -p $rundir/ns | ||||||
touch $rundir/ns/{pid,mount} | ||||||
fi | ||||||
} | ||||||
|
||||||
is_unshare_alive() { | ||||||
[ -e $pidfile ] && [ -d "/proc/$(<$pidfile)" ] | ||||||
} | ||||||
|
||||||
run_in_namespace() { | ||||||
nsenter \ | ||||||
--pid=$rundir/ns/pid \ | ||||||
--mount=$rundir/ns/mount \ | ||||||
-- "$@" | ||||||
} | ||||||
|
||||||
start_systemd() { | ||||||
daemonize \ | ||||||
-o $rundir/stdout \ | ||||||
-e $rundir/stderr \ | ||||||
-l $rundir/systemd.lock \ | ||||||
-p $pidfile \ | ||||||
-E LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive \ | ||||||
"$(command -v unshare)" \ | ||||||
--fork \ | ||||||
--pid=$rundir/ns/pid \ | ||||||
--mount=$rundir/ns/mount \ | ||||||
--mount-proc=/proc \ | ||||||
--propagation=unchanged \ | ||||||
nixos-wsl-systemd-wrapper | ||||||
|
||||||
# Wait for systemd to start | ||||||
while ! (run_in_namespace systemctl is-system-running -q --wait) &>/dev/null; do | ||||||
sleep 1 | ||||||
|
||||||
if ! is_unshare_alive; then | ||||||
echo "[ERROR] systemd startup failed!" | ||||||
|
||||||
echo "[ERROR] stderr:" | ||||||
cat $rundir/stderr | ||||||
|
||||||
echo "[ERROR] stdout:" | ||||||
cat $rundir/stdout | ||||||
|
||||||
exit 1 | ||||||
fi | ||||||
done | ||||||
} | ||||||
|
||||||
get_shell() { | ||||||
getent passwd "$1" | cut -d: -f7 | ||||||
} | ||||||
|
||||||
get_home() { | ||||||
getent passwd "$1" | cut -d: -f6 | ||||||
} | ||||||
|
||||||
is_in_container() { | ||||||
[ "${INSIDE_NAMESPACE:-}" == "true" ] | ||||||
} | ||||||
|
||||||
clean_wslpath() { | ||||||
echo "$PATH" | tr ':' '\n' | grep -E "^@automountPath@" | tr '\n' ':' | ||||||
} | ||||||
|
||||||
main() { | ||||||
ensure_root | ||||||
|
||||||
if [ ! -e "/run/current-system" ]; then | ||||||
activate | ||||||
fi | ||||||
|
||||||
if [ ! -e "$rundir" ]; then | ||||||
create_rundir | ||||||
fi | ||||||
|
||||||
if ! is_in_container && ! is_unshare_alive; then | ||||||
start_systemd | ||||||
fi | ||||||
|
||||||
if [ $# -gt 0 ]; then | ||||||
# wsl seems to prefix with "-c" | ||||||
shift | ||||||
command="$*" | ||||||
else | ||||||
command=$(get_shell @defaultUser@) | ||||||
fi | ||||||
|
||||||
# If we're executed from inside the container, e.g. sudo | ||||||
if is_in_container; then | ||||||
exec $command | ||||||
fi | ||||||
|
||||||
# If we are currently in /root, this is probably because the directory that WSL was started is inaccessible | ||||||
# cd to the user's home to prevent a warning about permission being denied on /root | ||||||
if [ "$PWD" == "/root" ]; then | ||||||
cd "$(get_home @defaultUser@)" | ||||||
fi | ||||||
|
||||||
# Pass external environment but filter variables specific to root user. | ||||||
exportCmd="$(export -p | grep -vE ' (HOME|LOGNAME|SHELL|USER)=')" | ||||||
|
||||||
run_in_namespace \ | ||||||
machinectl \ | ||||||
--quiet \ | ||||||
--uid=@defaultUser@ \ | ||||||
--setenv=INSIDE_NAMESPACE=true \ | ||||||
--setenv=WSLPATH="$(clean_wslpath)" \ | ||||||
shell .host \ | ||||||
/bin/sh -c "cd \"$PWD\"; $exportCmd; source /etc/set-environment; exec $command" | ||||||
} | ||||||
|
||||||
main "$@" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/usr/bin/env bash | ||
set -euxo pipefail | ||
|
||
mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc | ||
|
||
exec systemd |
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.