This repository has been archived by the owner on Oct 28, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathinit-systemd
executable file
·68 lines (58 loc) · 2.87 KB
/
init-systemd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/bin/bash
# Copyright 2020 (c) Ayane Satomi
# Licensed under MIT
# Parts of this code is based from https://forum.snapcraft.io/t/running-snaps-on-wsl2-insiders-only-for-now/13033
set -eo pipefail
if [ -z "$1" ]; then
echo "Usage: $0 -u (USER) -c (command)"
echo "This script spawns a namespace to be able to use systemd in a specified user."
echo "This requires unshare (from util-linux)."
echo "If -c is provided, the command will be executed in the namespace's context non-interactively."
exit 1;
fi
# I ran out of ideas here so feel free to do some weird lettering shit that matches this more
while getopts ":u:c:" o; do
case "${o}" in
u)
user=${OPTARG}
;;
c)
exec_command=${OPTARG}
;;
*)
echo "Usage: $0 -u (USER) -c (command)"
echo "This script spawns a namespace to be able to use systemd in a specified user."
echo "This requires unshare (from util-linux)."
echo "If -c is provided, the command will be executed in the namespace's context non-interactively."
exit 1;
;;
esac
done
shift $((OPTIND-1))
# Required checks: Obviously we're looking for
# * root
# * unshare
# * a existing user based on what was provided.
user_exists=$(id -u $user > /dev/null 2>&1; echo $?)
if [ ! $(whoami) == "root" ]; then echo "Must run as root!"; exit 1; fi
if [ -z $(command -v unshare) ]; then echo "util-linux is not installed!"; exit 1; fi
if [ -z $(command -v nsenter) ]; then echo "nsenter is not installed!"; exit 1; fi
if [ "$user_exists" -eq 1 ]; then echo "Cannot proceed, user does not exist!"; exit 127; fi
# We want to spawn a namespace but not spawn anymore if it exists already.
SYSTEMD_PID=$(ps -eo pid=,args= | awk '$2=="/lib/systemd/systemd" && $3=="--system-unit=basic.target" {print $1}')
if [ -z "$SYSTEMD_PID" ]; then
unshare --kill-child --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target <&- &
SYSTEMD_PID=$(ps -eo pid=,args= | awk '$2=="/lib/systemd/systemd" && $3=="--system-unit=basic.target" {print $1}')
fi
if [ -n "$exec_command" ]; then
# Run this inside the namespace!
nsenter -t "$SYSTEMD_PID" -m -p su $(id -un $user) - sh -c "cd $PWD; exec $exec_command"
# FIXME: Since we keep forking systemd per namespace session its wise to dispose them after.
kill -9 "$SYSTEMD_PID"
else
# The idea here is we want to preserve WSL's PWD so we don't need to walk manually back to the directory.
# So when "bash" is typed on PowerShell, the experience is seamless - it behaves similarly and the directory is already walked for your convenience.
nsenter -t "$SYSTEMD_PID" -m -p su $(id -un $user) - sh -c 'cd $PWD; exec "${SHELL:-sh}"'
# FIXME: Since we keep forking systemd per namespace session its wise to dispose them after.
kill -9 "$SYSTEMD_PID"
fi