github.com/containers/podman/v4@v4.9.4/pkg/machine/wsl/config.go (about) 1 //go:build windows 2 // +build windows 3 4 package wsl 5 6 import ( 7 "fmt" 8 "io/fs" 9 "path/filepath" 10 "strings" 11 "time" 12 13 "github.com/containers/podman/v4/pkg/machine" 14 "github.com/containers/podman/v4/pkg/machine/compression" 15 "github.com/containers/podman/v4/pkg/machine/define" 16 "github.com/containers/podman/v4/utils" 17 "github.com/sirupsen/logrus" 18 ) 19 20 type WSLVirtualization struct { 21 machine.Virtualization 22 } 23 24 func VirtualizationProvider() machine.VirtProvider { 25 return &WSLVirtualization{ 26 machine.NewVirtualization(define.None, compression.Xz, define.Tar, vmtype), 27 } 28 } 29 30 // NewMachine initializes an instance of a wsl machine 31 func (p *WSLVirtualization) NewMachine(opts machine.InitOptions) (machine.VM, error) { 32 vm := new(MachineVM) 33 if len(opts.USBs) > 0 { 34 return nil, fmt.Errorf("USB host passtrough not supported for WSL machines") 35 } 36 if len(opts.Name) > 0 { 37 vm.Name = opts.Name 38 } 39 configPath, err := getConfigPath(opts.Name) 40 if err != nil { 41 return vm, err 42 } 43 44 vm.ConfigPath = configPath 45 vm.ImagePath = opts.ImagePath 46 47 // WSL historically uses a different username; translate "core" fcos default to 48 // legacy "user" default 49 if opts.Username == "" || opts.Username == "core" { 50 vm.RemoteUsername = "user" 51 } else { 52 vm.RemoteUsername = opts.Username 53 } 54 55 vm.Created = time.Now() 56 57 // Default is false 58 if opts.UserModeNetworking != nil { 59 vm.UserModeNetworking = *opts.UserModeNetworking 60 } 61 62 // Add a random port for ssh 63 port, err := machine.AllocateMachinePort() 64 if err != nil { 65 return nil, err 66 } 67 vm.Port = port 68 69 return vm, nil 70 } 71 72 // LoadByName reads a json file that describes a known qemu vm 73 // and returns a vm instance 74 func (p *WSLVirtualization) LoadVMByName(name string) (machine.VM, error) { 75 configPath, err := getConfigPath(name) 76 if err != nil { 77 return nil, err 78 } 79 80 vm, err := readAndMigrate(configPath, name) 81 if err != nil { 82 return nil, err 83 } 84 85 lock, err := machine.GetLock(vm.Name, vmtype) 86 if err != nil { 87 return nil, err 88 } 89 vm.lock = lock 90 91 return vm, err 92 } 93 94 // List lists all vm's that use qemu virtualization 95 func (p *WSLVirtualization) List(_ machine.ListOptions) ([]*machine.ListResponse, error) { 96 return GetVMInfos() 97 } 98 99 func GetVMInfos() ([]*machine.ListResponse, error) { 100 vmConfigDir, err := machine.GetConfDir(vmtype) 101 if err != nil { 102 return nil, err 103 } 104 105 var listed []*machine.ListResponse 106 107 if err = filepath.WalkDir(vmConfigDir, func(path string, d fs.DirEntry, err error) error { 108 if strings.HasSuffix(d.Name(), ".json") { 109 path := filepath.Join(vmConfigDir, d.Name()) 110 vm, err := readAndMigrate(path, strings.TrimSuffix(d.Name(), ".json")) 111 if err != nil { 112 return err 113 } 114 listEntry := new(machine.ListResponse) 115 116 listEntry.Name = vm.Name 117 listEntry.Stream = vm.ImageStream 118 listEntry.VMType = "wsl" 119 listEntry.CPUs, _ = getCPUs(vm) 120 listEntry.Memory, _ = getMem(vm) 121 listEntry.DiskSize = getDiskSize(vm) 122 listEntry.RemoteUsername = vm.RemoteUsername 123 listEntry.Port = vm.Port 124 listEntry.IdentityPath = vm.IdentityPath 125 listEntry.Starting = false 126 listEntry.UserModeNetworking = vm.UserModeNetworking 127 128 running := vm.isRunning() 129 listEntry.CreatedAt, listEntry.LastUp, _ = vm.updateTimeStamps(running) 130 listEntry.Running = running 131 132 listed = append(listed, listEntry) 133 } 134 return nil 135 }); err != nil { 136 return nil, err 137 } 138 return listed, err 139 } 140 141 func (p *WSLVirtualization) IsValidVMName(name string) (bool, error) { 142 infos, err := GetVMInfos() 143 if err != nil { 144 return false, err 145 } 146 for _, vm := range infos { 147 if vm.Name == name { 148 return true, nil 149 } 150 } 151 return false, nil 152 } 153 154 func (p *WSLVirtualization) CheckExclusiveActiveVM() (bool, string, error) { 155 return false, "", nil 156 } 157 158 // RemoveAndCleanMachines removes all machine and cleans up any other files associated with podman machine 159 func (p *WSLVirtualization) RemoveAndCleanMachines() error { 160 var ( 161 vm machine.VM 162 listResponse []*machine.ListResponse 163 opts machine.ListOptions 164 destroyOptions machine.RemoveOptions 165 ) 166 destroyOptions.Force = true 167 var prevErr error 168 169 listResponse, err := p.List(opts) 170 if err != nil { 171 return err 172 } 173 174 for _, mach := range listResponse { 175 vm, err = p.LoadVMByName(mach.Name) 176 if err != nil { 177 if prevErr != nil { 178 logrus.Error(prevErr) 179 } 180 prevErr = err 181 } 182 _, remove, err := vm.Remove(mach.Name, destroyOptions) 183 if err != nil { 184 if prevErr != nil { 185 logrus.Error(prevErr) 186 } 187 prevErr = err 188 } else { 189 if err := remove(); err != nil { 190 if prevErr != nil { 191 logrus.Error(prevErr) 192 } 193 prevErr = err 194 } 195 } 196 } 197 198 // Clean leftover files in data dir 199 dataDir, err := machine.DataDirPrefix() 200 if err != nil { 201 if prevErr != nil { 202 logrus.Error(prevErr) 203 } 204 prevErr = err 205 } else { 206 err := utils.GuardedRemoveAll(dataDir) 207 if err != nil { 208 if prevErr != nil { 209 logrus.Error(prevErr) 210 } 211 prevErr = err 212 } 213 } 214 215 // Clean leftover files in conf dir 216 confDir, err := machine.ConfDirPrefix() 217 if err != nil { 218 if prevErr != nil { 219 logrus.Error(prevErr) 220 } 221 prevErr = err 222 } else { 223 err := utils.GuardedRemoveAll(confDir) 224 if err != nil { 225 if prevErr != nil { 226 logrus.Error(prevErr) 227 } 228 prevErr = err 229 } 230 } 231 return prevErr 232 } 233 234 func (p *WSLVirtualization) VMType() machine.VMType { 235 return vmtype 236 }