diff --git a/pkg/machine/wsl/stubber.go b/pkg/machine/wsl/stubber.go index 1794add35f..c3a5167606 100644 --- a/pkg/machine/wsl/stubber.go +++ b/pkg/machine/wsl/stubber.go @@ -105,6 +105,7 @@ func (w WSLStubber) MountVolumesToVM(_ *vmconfigs.MachineConfig, _ bool) error { return nil } +// ===================== CHANGED FUNCTION START ===================== func (w WSLStubber) Remove(mc *vmconfigs.MachineConfig) ([]string, func() error, error) { // Note: we could consider swapping the two conditionals // below if we wanted to hard error on the wsl unregister @@ -114,12 +115,26 @@ func (w WSLStubber) Remove(mc *vmconfigs.MachineConfig) ([]string, func() error, if err := runCmdPassThrough(cmd); err != nil { return err } + + // The podman-net-usermode WSL distribution is shared across all + // machines using --user-mode-networking, so it isn't removed + // automatically above. Clean it up here if this machine used it + // and no other configured machine still needs it. + // (see https://github.com/containers/podman/issues/29480) + if mc.WSLHypervisor != nil && mc.WSLHypervisor.UserModeNetworking { + if err := removeUserModeDistIfUnused(mc.Name); err != nil { + logrus.Warnf("could not clean up shared user-mode networking distribution: %v", err) + } + } + return nil } return []string{}, wslRemoveFunc, nil } +// ====================== CHANGED FUNCTION END ====================== + func (w WSLStubber) RemoveAndCleanMachines(_ *define.MachineDirs) error { return nil } diff --git a/pkg/machine/wsl/usermodenet.go b/pkg/machine/wsl/usermodenet.go index a46abbac18..10d31085b2 100644 --- a/pkg/machine/wsl/usermodenet.go +++ b/pkg/machine/wsl/usermodenet.go @@ -372,3 +372,32 @@ func appendDisableAutoResolve(dist string) error { return nil } + +func removeUserModeDistIfUnused(removedName string) error { + exists, err := isWSLExist(userModeDist) + if err != nil || !exists { + return err + } + + dirs, err := env.GetMachineDirs(vmtype) + if err != nil { + return err + } + + machines, err := vmconfigs.LoadMachinesInDir(dirs) + if err != nil { + return err + } + + for name, mc := range machines { + if name == removedName { + continue + } + if mc.WSLHypervisor != nil && mc.WSLHypervisor.UserModeNetworking { + return nil + } + } + + _ = terminateDist(userModeDist) + return unregisterDist(userModeDist) +}