mirror of
https://github.com/containers/podman.git
synced 2025-12-01 10:38:05 +08:00
this patch changes how the detection of wsl works. The old way of using wsl --status command output to detect some missing features required by WSL is not fully reliable. WSL checks if the wsl feature is enabled and if the vmcompute service do exist. However, this is not enough to identify if the virtual machine platform feature is enabled. The vmcompute service could exist because it has been installed by other tools or it could exist but being stopped. The way proposed by this patch is to try execute the import command and, if it fails, check the error and if it is related to the Host Compute Service try to install all features required by WSL. The flow is the same as before, the user is asked to execute the podman machine init command with elevated privileges. Eventually, after enabling WSL and VMP features, the user is asked to reboot the machine. When the machine restarts, the powershell gets invoked again and execute the command init. The code also fixes some issues that could cause misbehaviors when invoking recursively the elevated shell, like an unreleased lock, or a missing file. Signed-off-by: lstocchi <lstocchi@redhat.com>
207 lines
6.5 KiB
Go
207 lines
6.5 KiB
Go
//go:build windows
|
|
|
|
package wsl
|
|
|
|
const (
|
|
ErrorSuccessRebootInitiated = 1641
|
|
ErrorSuccessRebootRequired = 3010
|
|
currentMachineVersion = 3
|
|
)
|
|
|
|
const containersConf = `[containers]
|
|
|
|
[engine]
|
|
cgroup_manager = "cgroupfs"
|
|
|
|
# Using iptables until we fix nftables on WSL:
|
|
# https://github.com/containers/podman/issues/25201
|
|
[network]
|
|
firewall_driver="iptables"
|
|
`
|
|
|
|
const registriesConf = `unqualified-search-registries=["docker.io"]
|
|
`
|
|
|
|
const appendPort = `grep -q Port\ %d /etc/ssh/sshd_config || echo Port %d >> /etc/ssh/sshd_config`
|
|
|
|
const changePort = `sed -E -i 's/^Port[[:space:]]+[0-9]+/Port %d/' /etc/ssh/sshd_config`
|
|
|
|
const configServices = `ln -fs /usr/lib/systemd/system/sshd.service /etc/systemd/system/multi-user.target.wants/sshd.service
|
|
ln -fs /usr/lib/systemd/system/podman.socket /etc/systemd/system/sockets.target.wants/podman.socket
|
|
rm -f /etc/systemd/system/getty.target.wants/console-getty.service
|
|
rm -f /etc/systemd/system/getty.target.wants/getty@tty1.service
|
|
rm -f /etc/systemd/system/multi-user.target.wants/systemd-resolved.service
|
|
rm -f /etc/systemd/system/sysinit.target.wants//systemd-resolved.service
|
|
rm -f /etc/systemd/system/dbus-org.freedesktop.resolve1.service
|
|
ln -fs /dev/null /etc/systemd/system/console-getty.service
|
|
ln -fs /dev/null /etc/systemd/system/systemd-oomd.socket
|
|
mkdir -p /etc/systemd/system/systemd-sysusers.service.d/
|
|
echo CREATE_MAIL_SPOOL=no >> /etc/default/useradd
|
|
adduser -m [USER] -G wheel
|
|
mkdir -p /home/[USER]/.config/systemd/[USER]/
|
|
chown [USER]:[USER] /home/[USER]/.config
|
|
`
|
|
|
|
const sudoers = `%wheel ALL=(ALL) NOPASSWD: ALL
|
|
`
|
|
|
|
const bootstrap = `#!/bin/bash
|
|
ps -ef | grep -v grep | grep -q systemd && exit 0
|
|
nohup unshare --kill-child --fork --pid --mount --mount-proc --propagation shared /lib/systemd/systemd >/dev/null 2>&1 &
|
|
sleep 0.1
|
|
`
|
|
|
|
const wslmotd = `
|
|
You will be automatically entered into a nested process namespace where
|
|
systemd is running. If you need to access the parent namespace, hit ctrl-d
|
|
or type exit. This also means to log out you need to exit twice.
|
|
|
|
`
|
|
|
|
const sysdpid = "SYSDPID=`ps -eo cmd,pid | grep -m 1 ^/lib/systemd/systemd | awk '{print $2}'`"
|
|
|
|
const profile = sysdpid + `
|
|
if [ ! -z "$SYSDPID" ] && [ "$SYSDPID" != "1" ]; then
|
|
cat /etc/wslmotd
|
|
/usr/local/bin/enterns
|
|
fi
|
|
`
|
|
|
|
const enterns = "#!/bin/bash\n" + sysdpid + `
|
|
if [ ! -z "$SYSDPID" ] && [ "$SYSDPID" != "1" ]; then
|
|
NSENTER=("nsenter" "-m" "-p" "-t" "$SYSDPID" "--wd=$PWD")
|
|
|
|
if [ "$UID" != "0" ]; then
|
|
NSENTER=("sudo" "${NSENTER[@]}")
|
|
if [ "$#" != "0" ]; then
|
|
NSENTER+=("sudo" "-u" "$USER")
|
|
else
|
|
NSENTER+=("su" "-l" "$USER")
|
|
fi
|
|
fi
|
|
"${NSENTER[@]}" "$@"
|
|
fi`
|
|
|
|
const waitTerm = sysdpid + `
|
|
if [ ! -z "$SYSDPID" ]; then
|
|
timeout 60 tail -f /dev/null --pid $SYSDPID
|
|
fi
|
|
`
|
|
|
|
const wslConf = `[user]
|
|
default=[USER]
|
|
`
|
|
|
|
const wslConfUserNet = `
|
|
[network]
|
|
generateResolvConf = false
|
|
`
|
|
|
|
const resolvConfUserNet = `
|
|
nameserver 192.168.127.1
|
|
`
|
|
|
|
// WSL kernel does not have sg and crypto_user modules
|
|
const overrideSysusers = `[Service]
|
|
LoadCredential=
|
|
`
|
|
|
|
const lingerService = `[Unit]
|
|
Description=A systemd user unit demo
|
|
After=network-online.target
|
|
Wants=network-online.target podman.socket
|
|
[Service]
|
|
ExecStart=/usr/bin/sleep infinity
|
|
`
|
|
|
|
const lingerSetup = `mkdir -p /home/[USER]/.config/systemd/user/default.target.wants
|
|
ln -fs /home/[USER]/.config/systemd/user/linger-example.service \
|
|
/home/[USER]/.config/systemd/user/default.target.wants/linger-example.service
|
|
`
|
|
|
|
const bindMountSystemService = `
|
|
[Unit]
|
|
Description=Bind mount for system podman sockets
|
|
After=podman.socket
|
|
|
|
[Service]
|
|
RemainAfterExit=true
|
|
Type=oneshot
|
|
# Ensure user services can register sockets as well
|
|
ExecStartPre=mkdir -p -m 777 /mnt/wsl/podman-sockets
|
|
ExecStartPre=mkdir -p -m 777 /mnt/wsl/podman-sockets/%[1]s
|
|
ExecStartPre=touch /mnt/wsl/podman-sockets/%[1]s/podman-root.sock
|
|
ExecStart=mount --bind %%t/podman/podman.sock /mnt/wsl/podman-sockets/%[1]s/podman-root.sock
|
|
ExecStop=umount /mnt/wsl/podman-sockets/%[1]s/podman-root.sock
|
|
`
|
|
|
|
const bindMountUserService = `
|
|
[Unit]
|
|
Description=Bind mount for user podman sockets
|
|
After=podman.socket
|
|
|
|
[Service]
|
|
RemainAfterExit=true
|
|
Type=oneshot
|
|
# Consistency with system service (supports racing)
|
|
ExecStartPre=mkdir -p -m 777 /mnt/wsl/podman-sockets
|
|
ExecStartPre=mkdir -p -m 777 /mnt/wsl/podman-sockets/%[1]s
|
|
ExecStartPre=touch /mnt/wsl/podman-sockets/%[1]s/podman-user.sock
|
|
# Relies on /etc/fstab entry for user mounting
|
|
ExecStart=mount /mnt/wsl/podman-sockets/%[1]s/podman-user.sock
|
|
ExecStop=umount /mnt/wsl/podman-sockets/%[1]s/podman-user.sock
|
|
`
|
|
|
|
const bindMountFsTab = `/run/user/1000/podman/podman.sock /mnt/wsl/podman-sockets/%s/podman-user.sock none noauto,user,bind,defaults 0 0
|
|
`
|
|
const (
|
|
defaultTargetWants = "default.target.wants"
|
|
userSystemdPath = "/home/%[1]s/.config/systemd/user"
|
|
sysSystemdPath = "/etc/systemd/system"
|
|
userSystemdWants = userSystemdPath + "/" + defaultTargetWants
|
|
sysSystemdWants = sysSystemdPath + "/" + defaultTargetWants
|
|
bindUnitFileName = "podman-mnt-bindings.service"
|
|
bindUserUnitPath = userSystemdPath + "/" + bindUnitFileName
|
|
bindUserUnitWant = userSystemdWants + "/" + bindUnitFileName
|
|
bindSysUnitPath = sysSystemdPath + "/" + bindUnitFileName
|
|
bindSysUnitWant = sysSystemdWants + "/" + bindUnitFileName
|
|
podmanSocketDropin = "podman.socket.d"
|
|
podmanSocketDropinPath = sysSystemdPath + "/" + podmanSocketDropin
|
|
)
|
|
|
|
const configBindServices = "mkdir -p " + userSystemdWants + " " + sysSystemdWants + " " + podmanSocketDropinPath + "\n" +
|
|
"ln -fs " + bindUserUnitPath + " " + bindUserUnitWant + "\n" +
|
|
"ln -fs " + bindSysUnitPath + " " + bindSysUnitWant + "\n"
|
|
|
|
const overrideSocketGroup = `
|
|
[Socket]
|
|
SocketMode=0660
|
|
SocketGroup=wheel
|
|
`
|
|
|
|
const wslInstallError = `Could not %s. See previous output for any potential failure details.
|
|
If you can not resolve the issue, and rerunning fails, try the "wsl --install" process
|
|
outlined in the following article:
|
|
|
|
http://docs.microsoft.com/en-us/windows/wsl/install
|
|
|
|
`
|
|
|
|
const wslOldVersion = `Automatic installation of WSL can not be performed on this version of Windows
|
|
Either update to Build 19041 (or later), or perform the manual installation steps
|
|
outlined in the following article:
|
|
|
|
http://docs.microsoft.com/en-us/windows/wsl/install\
|
|
|
|
`
|
|
|
|
const (
|
|
gvProxy = "gvproxy.exe"
|
|
winSSHProxy = "win-sshproxy.exe"
|
|
pipePrefix = "npipe:////./pipe/"
|
|
globalPipe = "docker_engine"
|
|
userModeDist = "podman-net-usermode"
|
|
rootfulSock = "/run/podman/podman.sock"
|
|
rootlessSock = "/run/user/1000/podman/podman.sock"
|
|
)
|