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  }