diff options
Diffstat (limited to 'pkg/machine/qemu/machine.go')
-rw-r--r-- | pkg/machine/qemu/machine.go | 119 |
1 files changed, 106 insertions, 13 deletions
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index fdb528a86..fd22f465b 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -10,6 +10,7 @@ import ( "os/exec" "path/filepath" "strconv" + "strings" "time" "github.com/containers/podman/v3/pkg/machine" @@ -36,12 +37,8 @@ func NewMachine(opts machine.InitOptions) (machine.VM, error) { if len(opts.Name) > 0 { vm.Name = opts.Name } - vm.IgnitionFilePath = opts.IgnitionPath - // If no ignitionfilepath was provided, use defaults - if len(vm.IgnitionFilePath) < 1 { - ignitionFile := filepath.Join(vmConfigDir, vm.Name+".ign") - vm.IgnitionFilePath = ignitionFile - } + ignitionFile := filepath.Join(vmConfigDir, vm.Name+".ign") + vm.IgnitionFilePath = ignitionFile // An image was specified if len(opts.ImagePath) > 0 { @@ -124,6 +121,9 @@ func LoadVMByName(name string) (machine.VM, error) { // Init writes the json configuration file to the filesystem for // other verbs (start, stop) func (v *MachineVM) Init(opts machine.InitOptions) error { + var ( + key string + ) sshDir := filepath.Join(homedir.Get(), ".ssh") // GetConfDir creates the directory so no need to check for // its existence @@ -163,9 +163,18 @@ func (v *MachineVM) Init(opts machine.InitOptions) error { // Add location of bootable image v.CmdLine = append(v.CmdLine, "-drive", "if=virtio,file="+v.ImagePath) // This kind of stinks but no other way around this r/n - uri := machine.SSHRemoteConnection.MakeSSHURL("localhost", "/run/user/1000/podman/podman.sock", strconv.Itoa(v.Port), v.RemoteUsername) - if err := machine.AddConnection(&uri, v.Name, filepath.Join(sshDir, v.Name), opts.IsDefault); err != nil { - return err + if len(opts.IgnitionPath) < 1 { + uri := machine.SSHRemoteConnection.MakeSSHURL("localhost", "/run/user/1000/podman/podman.sock", strconv.Itoa(v.Port), v.RemoteUsername) + if err := machine.AddConnection(&uri, v.Name, filepath.Join(sshDir, v.Name), opts.IsDefault); err != nil { + return err + } + + uriRoot := machine.SSHRemoteConnection.MakeSSHURL("localhost", "/run/podman/podman.sock", strconv.Itoa(v.Port), "root") + if err := machine.AddConnection(&uriRoot, v.Name+"-root", filepath.Join(sshDir, v.Name), opts.IsDefault); err != nil { + return err + } + } else { + fmt.Println("An ignition path was provided. No SSH connection was added to Podman") } // Write the JSON file b, err := json.MarshalIndent(v, "", " ") @@ -175,9 +184,14 @@ func (v *MachineVM) Init(opts machine.InitOptions) error { if err := ioutil.WriteFile(jsonFile, b, 0644); err != nil { return err } - key, err := machine.CreateSSHKeys(v.IdentityPath) - if err != nil { - return err + + // User has provided ignition file so keygen + // will be skipped. + if len(opts.IgnitionPath) < 1 { + key, err = machine.CreateSSHKeys(v.IdentityPath) + if err != nil { + return err + } } // Run arch specific things that need to be done if err := v.prepare(); err != nil { @@ -199,6 +213,15 @@ func (v *MachineVM) Init(opts machine.InitOptions) error { return errors.Errorf("error resizing image: %q", err) } } + // If the user provides an ignition file, we need to + // copy it into the conf dir + if len(opts.IgnitionPath) > 0 { + inputIgnition, err := ioutil.ReadFile(opts.IgnitionPath) + if err != nil { + return err + } + return ioutil.WriteFile(v.IgnitionFilePath, inputIgnition, 0644) + } // Write the ignition file ign := machine.DynamicIgnition{ Name: opts.Username, @@ -339,6 +362,10 @@ func (v *MachineVM) Remove(name string, opts machine.RemoveOptions) (string, fun if err := machine.RemoveConnection(v.Name); err != nil { logrus.Error(err) } + if err := machine.RemoveConnection(v.Name + "-root"); err != nil { + logrus.Error(err) + } + vmConfigDir, err := machine.GetConfDir(vmtype) if err != nil { return "", nil, err @@ -382,7 +409,7 @@ func (v *MachineVM) SSH(name string, opts machine.SSHOptions) error { port := strconv.Itoa(v.Port) args := []string{"-i", v.IdentityPath, "-p", port, sshDestination} - if opts.Execute { + if len(opts.Args) > 0 { args = append(args, opts.Args...) } else { fmt.Printf("Connecting to vm %s. To close connection, use `~.` or `exit`\n", v.Name) @@ -426,3 +453,69 @@ func getDiskSize(path string) (uint64, error) { } return tmpInfo.VirtualSize, nil } + +// List lists all vm's that use qemu virtualization +func List(_ machine.ListOptions) ([]*machine.ListResponse, error) { + return GetVMInfos() +} + +func GetVMInfos() ([]*machine.ListResponse, error) { + vmConfigDir, err := machine.GetConfDir(vmtype) + if err != nil { + return nil, err + } + + var listed []*machine.ListResponse + + if err = filepath.Walk(vmConfigDir, func(path string, info os.FileInfo, err error) error { + vm := new(MachineVM) + if strings.HasSuffix(info.Name(), ".json") { + fullPath := filepath.Join(vmConfigDir, info.Name()) + b, err := ioutil.ReadFile(fullPath) + if err != nil { + return err + } + err = json.Unmarshal(b, vm) + if err != nil { + return err + } + listEntry := new(machine.ListResponse) + + listEntry.Name = vm.Name + listEntry.VMType = "qemu" + fi, err := os.Stat(fullPath) + if err != nil { + return err + } + listEntry.CreatedAt = fi.ModTime() + + fi, err = os.Stat(vm.ImagePath) + if err != nil { + return err + } + listEntry.LastUp = fi.ModTime() + if vm.isRunning() { + listEntry.Running = true + } + + listed = append(listed, listEntry) + } + return nil + }); err != nil { + return nil, err + } + return listed, err +} + +func IsValidVMName(name string) (bool, error) { + infos, err := GetVMInfos() + if err != nil { + return false, err + } + for _, vm := range infos { + if vm.Name == name { + return true, nil + } + } + return false, nil +} |