Skip to content
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

Share podman sock bindings with other WSL distros #19705

Merged
merged 2 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 109 additions & 3 deletions pkg/machine/wsl/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,69 @@ Wants=network-online.target podman.socket
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 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is 777 realy correct? Seems way to open to me, but....

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it’s certainly an odd setup. So in this case /mnt/wsl (outside of our control is 777) since it’s a shaded space (sorta like /tmp) where all WSl distros cross (different Linux distributions, each running in a linux namespace). This subdir underneath just mirrors that permission scheme, and is also necessary since there is both a user systemd service and a root systemd service writing into the same directory.

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 proxyConfigSetup = `#!/bin/bash
Expand Down Expand Up @@ -553,9 +613,55 @@ func configureSystem(v *MachineVM, dist string) error {
return fmt.Errorf("could not create podman-machine file for guest OS: %w", err)
}

if err := configureBindMounts(dist, user); err != nil {
return err
}

return changeDistUserModeNetworking(dist, user, "", v.UserModeNetworking)
}

func configureBindMounts(dist string, user string) error {
if err := wslPipe(fmt.Sprintf(bindMountSystemService, dist), dist, "sh", "-c", "cat > /etc/systemd/system/podman-mnt-bindings.service"); err != nil {
return fmt.Errorf("could not create podman binding service file for guest OS: %w", err)
}

catUserService := "cat > " + getUserUnitPath(user)
if err := wslPipe(getBindMountUserService(dist), dist, "sh", "-c", catUserService); err != nil {
return fmt.Errorf("could not create podman binding user service file for guest OS: %w", err)
}

if err := wslPipe(getBindMountFsTab(dist), dist, "sh", "-c", "cat >> /etc/fstab"); err != nil {
return fmt.Errorf("could not create podman binding fstab entry for guest OS: %w", err)
}

if err := wslPipe(getConfigBindServicesScript(user), dist, "sh"); err != nil {
return fmt.Errorf("could not configure podman binding services for guest OS: %w", err)
}

catGroupDropin := fmt.Sprintf("cat > %s/%s", podmanSocketDropinPath, "10-group.conf")
if err := wslPipe(overrideSocketGroup, dist, "sh", "-c", catGroupDropin); err != nil {
return fmt.Errorf("could not configure podman socket group override: %w", err)
}

return nil
}

func getConfigBindServicesScript(user string) string {
return fmt.Sprintf(configBindServices, user)
}

func getBindMountUserService(dist string) string {
return fmt.Sprintf(bindMountUserService, dist)
}

func getUserUnitPath(user string) string {
return fmt.Sprintf(bindUserUnitPath, user)
}

func getBindMountFsTab(dist string) string {
return fmt.Sprintf(bindMountFsTab, dist)
}

func (v *MachineVM) setupPodmanDockerSock(dist string, rootful bool) error {
content := machine.GetPodmanDockerTmpConfig(1000, rootful, true)

Expand Down
8 changes: 4 additions & 4 deletions pkg/machine/wsl/usermodenet.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ func (v *MachineVM) launchUserModeNetDist(exeFile string) error {
}

func installUserModeDist(dist string, imagePath string) error {
if err := verifyWSLUserModeCompat(); err != nil {
return err
}

exists, err := isWSLExist(userModeDist)
if err != nil {
return err
Expand Down Expand Up @@ -315,10 +319,6 @@ func (v *MachineVM) obtainUserModeNetLock() (*fileLock, error) {
}

func changeDistUserModeNetworking(dist string, user string, image string, enable bool) error {
if err := verifyWSLUserModeCompat(); err != nil {
return err
}

// Only install if user-mode is being enabled and there was an image path passed
if enable && len(image) > 0 {
if err := installUserModeDist(dist, image); err != nil {
Expand Down