Improvements for machine

clean up ci failures and add appropriate arch,os exclusion tags

Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
baude
2021-03-22 13:29:25 -05:00
parent e766113737
commit 4ab8a6f67e
24 changed files with 141 additions and 115 deletions

View File

@ -1092,3 +1092,11 @@ func AutocompleteVolumeFilters(cmd *cobra.Command, args []string, toComplete str
}
return completeKeyValues(toComplete, kv)
}
// AutocompleteMachineSSH - Autocomplete machine ssh command.
func AutocompleteMachineSSH(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) == 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
return nil, cobra.ShellCompDirectiveDefault
}

View File

@ -1,3 +1,5 @@
// +build amd64,linux amd64,darwin arm64,darwin
package machine
import (
@ -6,17 +8,16 @@ import (
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/machine"
"github.com/containers/podman/v3/pkg/machine/qemu"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
var (
createCmd = &cobra.Command{
Use: "create [options] NAME",
Use: "create [options] [NAME]",
Short: "Create a vm",
Long: "Create a virtual machine for Podman to run on. Virtual machines are used to run Podman on Macs. ",
Long: "Create a virtual machine for Podman to run on. Virtual machines are used to run Podman.",
RunE: create,
Args: cobra.NoArgs,
Args: cobra.MaximumNArgs(1),
Example: `podman machine create myvm`,
ValidArgsFunction: completion.AutocompleteNone,
}
@ -33,6 +34,7 @@ type CreateCLIOptions struct {
var (
createOpts = CreateCLIOptions{}
defaultMachineName string = "podman-machine-default"
)
func init() {
@ -59,14 +61,6 @@ func init() {
)
_ = createCmd.RegisterFlagCompletionFunc(memoryFlagName, completion.AutocompleteNone)
deviceFlagName := "name"
flags.StringVar(
&createOpts.Name,
deviceFlagName, "",
"set vm name",
)
_ = createCmd.RegisterFlagCompletionFunc(deviceFlagName, completion.AutocompleteDefault)
ImagePathFlagName := "image-path"
flags.StringVar(&createOpts.ImagePath, ImagePathFlagName, "", "Path to qcow image")
_ = createCmd.RegisterFlagCompletionFunc(ImagePathFlagName, completion.AutocompleteDefault)
@ -78,9 +72,9 @@ func init() {
// TODO should we allow for a users to append to the qemu cmdline?
func create(cmd *cobra.Command, args []string) error {
// TODO add ability to create default, not name required
if len(createOpts.Name) < 1 {
return errors.New("required --name not provided")
createOpts.Name = defaultMachineName
if len(args) > 0 {
createOpts.Name = args[0]
}
vmOpts := machine.CreateOptions{
CPUS: createOpts.CPUS,
@ -95,8 +89,6 @@ func create(cmd *cobra.Command, args []string) error {
err error
)
switch vmType {
case "foobar":
// do nothing
default: // qemu is the default
vm, err = qemu.NewMachine(vmOpts)
}

View File

@ -1,3 +1,5 @@
// +build amd64,linux amd64,darwin arm64,darwin
package machine
import (
@ -15,7 +17,7 @@ var (
machineCmd = &cobra.Command{
Use: "machine",
Short: "Manage a virtual machine",
Long: "Manage a virtual machine. Virtual machines are used to run Podman on Macs.",
Long: "Manage a virtual machine. Virtual machines are used to run Podman.",
PersistentPreRunE: noOp,
PersistentPostRunE: noOp,
RunE: validate.SubCommandExists,

View File

@ -0,0 +1,5 @@
// +build !amd64 arm64,linux amd64,windows
package machine
func init() {}

View File

@ -1,3 +1,5 @@
// +build amd64,linux amd64,darwin arm64,darwin
package machine
import (
@ -7,7 +9,6 @@ import (
"strings"
"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/machine"
@ -16,47 +17,43 @@ import (
)
var (
destroyCmd = &cobra.Command{
Use: "destroy [options] NAME",
Short: "Destroy an existing machine",
Long: "Destroy an existing machine ",
RunE: destroy,
removeCmd = &cobra.Command{
Use: "remove [options] NAME",
Short: "Remove an existing machine",
Long: "Remove an existing machine ",
RunE: remove,
Args: cobra.ExactArgs(1),
Example: `podman machine destroy myvm`,
Example: `podman machine remove myvm`,
ValidArgsFunction: completion.AutocompleteNone,
}
)
var (
destoryOptions machine.DestroyOptions
destoryOptions machine.RemoveOptions
)
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Command: destroyCmd,
Command: removeCmd,
Parent: machineCmd,
})
flags := destroyCmd.Flags()
flags := removeCmd.Flags()
formatFlagName := "force"
flags.BoolVar(&destoryOptions.Force, formatFlagName, false, "Do not prompt before destroying")
_ = destroyCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat)
flags.BoolVar(&destoryOptions.Force, formatFlagName, false, "Do not prompt before removeing")
keysFlagName := "save-keys"
flags.BoolVar(&destoryOptions.SaveKeys, keysFlagName, false, "Do not delete SSH keys")
_ = destroyCmd.RegisterFlagCompletionFunc(keysFlagName, common.AutocompleteJSONFormat)
ignitionFlagName := "save-ignition"
flags.BoolVar(&destoryOptions.SaveIgnition, ignitionFlagName, false, "Do not delete ignition file")
_ = destroyCmd.RegisterFlagCompletionFunc(ignitionFlagName, common.AutocompleteJSONFormat)
imageFlagName := "save-image"
flags.BoolVar(&destoryOptions.SaveImage, imageFlagName, false, "Do not delete the image file")
_ = destroyCmd.RegisterFlagCompletionFunc(imageFlagName, common.AutocompleteJSONFormat)
}
func destroy(cmd *cobra.Command, args []string) error {
func remove(cmd *cobra.Command, args []string) error {
var (
err error
vm machine.VM
@ -69,7 +66,7 @@ func destroy(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
confirmationMessage, doIt, err := vm.Destroy(args[0], machine.DestroyOptions{})
confirmationMessage, doIt, err := vm.Remove(args[0], machine.RemoveOptions{})
if err != nil {
return err
}

View File

@ -1,7 +1,9 @@
// +build amd64,linux amd64,darwin arm64,darwin
package machine
import (
"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/machine"
@ -14,13 +16,13 @@ var (
sshCmd = &cobra.Command{
Use: "ssh [options] NAME [COMMAND [ARG ...]]",
Short: "SSH into a virtual machine",
Long: "SSH into a podman-managed virtual machine ",
Long: "SSH into a virtual machine ",
RunE: ssh,
Args: cobra.MinimumNArgs(1),
Example: `podman machine ssh myvm
podman machine ssh -e myvm echo hello`,
ValidArgsFunction: completion.AutocompleteNone,
ValidArgsFunction: common.AutocompleteMachineSSH,
}
)
@ -38,7 +40,6 @@ func init() {
flags := sshCmd.Flags()
executeFlagName := "execute"
flags.BoolVarP(&sshOpts.Execute, executeFlagName, "e", false, "Execute command from args")
_ = sshCmd.RegisterFlagCompletionFunc(executeFlagName, completion.AutocompleteDefault)
}
func ssh(cmd *cobra.Command, args []string) error {

View File

@ -1,3 +1,5 @@
// +build amd64,linux amd64,darwin arm64,darwin
package machine
import (

View File

@ -1,3 +1,5 @@
// +build amd64,linux amd64,darwin arm64,darwin
package machine
import (

View File

@ -3,7 +3,7 @@ Machine
:doc:`create <markdown/podman-machine-create.1>` Create a new virtual machine
:doc:`destroy <markdown/podman-machine-destroy.1>` Destroy a virtual machine
:doc:`remove <markdown/podman-machine-remove.1>` Remove a virtual machine
:doc:`ssh <markdown/podman-machine-ssh.1>` SSH into a virtual machine
:doc:`start <markdown/podman-machine-start.1>` Start a virtual machine
:doc:`stop <markdown/podman-machine-stop.1>` Stop a virtual machine

View File

@ -4,7 +4,7 @@
podman\-machine\-create - Create a new virtual machine
## SYNOPSIS
**podman machine create** [*options*] *name*
**podman machine create** [*options*] [*name*]
## DESCRIPTION
@ -34,10 +34,6 @@ Fully qualified path of the uncompressed image file
Memory (in MB).
#### **--name**
Name to assign to the VM
#### **--help**
Print usage statement.

View File

@ -1,17 +1,17 @@
% podman-machine-destroy(1)
% podman-machine-remove(1)
## NAME
podman\-machine\-destroy - Destroy a virtual machine
podman\-machine\-remove - Remove a virtual machine
## SYNOPSIS
**podman machine destroy** [*options*] *name*
**podman machine remove** [*options*] *name*
## DESCRIPTION
Destroy a virtual machine and its related files. What is actually deleted
Remove a virtual machine and its related files. What is actually deleted
depends on the virtual machine type. For all virtual machines, the generated
SSH keys and the podman system connection are deleted. The ignition files
generated for that VM are also destroyed as is its image file on the filesystem.
generated for that VM are also removeed as is its image file on the filesystem.
Users get a display of what will be deleted and are required to confirm unless the option `--force`
is used.
@ -42,10 +42,10 @@ deleted.
## EXAMPLES
Destroy a VM named "test1"
Remove a VM named "test1"
```
$ podman machine destroy test1
$ podman machine remove test1
The following files will be deleted:

View File

@ -16,16 +16,26 @@ tied to the Linux kernel.
## OPTIONS
#### **--execute**, **-e**
Execute the given command on the VM
#### **--help**
Print usage statement.
## EXAMPLES
To get an interactive session with a VM called `myvm`:
```
$ podman machine ssh myvm
```
To run a command on a VM called `myvm`:
```
$ podman machine ssh -e myvm -- rpm -q podman
```
## SEE ALSO
podman-machine (1)

View File

@ -14,7 +14,7 @@ podman\-machine - Manage Podman's virtual machine
| Command | Man Page | Description |
| ------- | ------------------------------------------------------- | ----------------------------- |
| create | [podman-machine-create(1)](podman-machine-create.1.md) | Create a new virtual machine |
| destroy | [podman-machine-destroy(1)](podman-machine-destroy.1.md)| Destroy a virtual machine |
| remove | [podman-machine-destroy(1)](podman-machine-remove.1.md)| Remove a virtual machine |
| ssh | [podman-machine-ssh.1.md(1)](podman-machine-ssh.1.md) | SSH into a virtual machine |
| start | [podman-machine-start(1)](podman-machine-start.1.md) | Start a virtual machine |
| stop | [podman-machine-stop(1)](podman-machine-stop.1.md) | Stop a virtual machine |

View File

@ -22,21 +22,11 @@ import (
"golang.org/x/crypto/ssh/agent"
)
/*
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
DO NOT MERGE WITHOUT REVERTING THE HACK BELOW
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*/
var (
BasePath = &url.URL{
Scheme: "http",
Host: "d",
//Path: "/v" + version.APIVersion[version.Libpod][version.CurrentAPI].String() + "/libpod",
Path: "/v3.0.0/libpod",
Path: "/v" + version.APIVersion[version.Libpod][version.CurrentAPI].String() + "/libpod",
}
)

View File

@ -50,7 +50,7 @@ type StartOptions struct{}
type StopOptions struct{}
type DestroyOptions struct {
type RemoveOptions struct {
Force bool
SaveKeys bool
SaveImage bool
@ -59,7 +59,7 @@ type DestroyOptions struct {
type VM interface {
Create(opts CreateOptions) error
Destroy(name string, opts DestroyOptions) (string, func() error, error)
Remove(name string, opts RemoveOptions) (string, func() error, error)
SSH(name string, opts SSHOptions) error
Start(name string, opts StartOptions) error
Stop(name string, opts StopOptions) error
@ -70,20 +70,6 @@ type DistributionDownload interface {
Get() *Download
}
// TODO is this even needed?
type TestVM struct{}
func (vm *TestVM) Create(opts CreateOptions) error {
return nil
}
func (vm *TestVM) Start(name string, opts StartOptions) error {
return nil
}
func (vm *TestVM) Stop(name string, opts StopOptions) error {
return nil
}
func (rc RemoteConnectionType) MakeSSHURL(host, path, port, userName string) url.URL {
userInfo := url.User(userName)
uri := url.URL{
@ -96,7 +82,6 @@ func (rc RemoteConnectionType) MakeSSHURL(host, path, port, userName string) url
ForceQuery: false,
RawQuery: "",
Fragment: "",
RawFragment: "",
}
if len(port) > 0 {
uri.Host = net.JoinHostPort(uri.Hostname(), port)

View File

@ -11,10 +11,8 @@ import (
"strings"
"github.com/containers/storage/pkg/archive"
"github.com/sirupsen/logrus"
digest "github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus"
)
// These should eventually be moved into machine/qemu as

View File

@ -10,8 +10,9 @@ import (
"strconv"
"time"
"github.com/containers/podman/v3/utils"
"github.com/containers/podman/v3/pkg/machine"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/storage/pkg/homedir"
"github.com/digitalocean/go-qemu/qmp"
"github.com/pkg/errors"
@ -56,7 +57,7 @@ func NewMachine(opts machine.CreateOptions) (machine.VM, error) {
}
// Add a random port for ssh
port, err := specgen.GetRandomPort()
port, err := utils.GetRandomPort()
if err != nil {
return nil, err
}
@ -170,7 +171,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
attr := new(os.ProcAttr)
files := []*os.File{os.Stdin, os.Stdout, os.Stderr}
attr.Files = files
fmt.Print(v.CmdLine)
logrus.Debug(v.CmdLine)
_, err = os.StartProcess(v.CmdLine[0], v.CmdLine, attr)
return err
}
@ -211,22 +212,29 @@ func (v *MachineVM) Stop(name string, _ machine.StopOptions) error {
// NewQMPMonitor creates the monitor subsection of our vm
func NewQMPMonitor(network, name string, timeout time.Duration) (Monitor, error) {
rtDir, err := getDataDir()
rtDir, err := getSocketDir()
if err != nil {
return Monitor{}, err
}
rtDir = filepath.Join(rtDir, "podman")
if _, err := os.Stat(filepath.Join(rtDir)); os.IsNotExist(err) {
// TODO 0644 is fine on linux but macos is weird
if err := os.MkdirAll(rtDir, 0755); err != nil {
return Monitor{}, err
}
}
if timeout == 0 {
timeout = defaultQMPTimeout
}
monitor := Monitor{
Network: network,
Address: filepath.Join(rtDir, "podman", "qmp_"+name+".sock"),
Address: filepath.Join(rtDir, "qmp_"+name+".sock"),
Timeout: timeout,
}
return monitor, nil
}
func (v *MachineVM) Destroy(name string, opts machine.DestroyOptions) (string, func() error, error) {
func (v *MachineVM) Remove(name string, opts machine.RemoveOptions) (string, func() error, error) {
var (
files []string
)

View File

@ -0,0 +1,15 @@
package qemu
import (
"os"
"github.com/pkg/errors"
)
func getSocketDir() (string, error) {
tmpDir, ok := os.LookupEnv("TMPDIR")
if !ok {
return "", errors.New("unable to resolve TMPDIR")
}
return tmpDir, nil
}

View File

@ -0,0 +1,18 @@
package qemu
var (
QemuCommand = "qemu-system-x86_64"
)
func (v *MachineVM) addArchOptions() []string {
opts := []string{"-cpu", "host"}
return opts
}
func (v *MachineVM) prepare() error {
return nil
}
func (v *MachineVM) archRemovalFiles() []string {
return []string{}
}

View File

@ -31,10 +31,6 @@ func (v *MachineVM) archRemovalFiles() []string {
return []string{ovmDir}
}
func getDataDir() (string, error) {
return "/tmp", nil
}
func getOvmfDir(imagePath, vmName string) string {
return filepath.Join(filepath.Dir(imagePath), vmName+"_ovmf_vars.fd")
}

View File

@ -0,0 +1,7 @@
package qemu
import "github.com/containers/podman/v3/pkg/util"
func getSocketDir() (string, error) {
return util.GetRuntimeDir()
}

View File

@ -1,9 +1,5 @@
package qemu
import (
"github.com/containers/podman/v3/pkg/util"
)
var (
QemuCommand = "qemu-kvm"
)
@ -20,7 +16,3 @@ func (v *MachineVM) prepare() error {
func (v *MachineVM) archRemovalFiles() []string {
return []string{}
}
func getDataDir() (string, error) {
return util.GetRuntimeDir()
}

View File

@ -6,6 +6,8 @@ import (
"strconv"
"strings"
"github.com/containers/podman/v3/utils"
"github.com/containers/podman/v3/libpod/image"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/cri-o/ocicni/pkg/ocicni"
@ -218,7 +220,7 @@ func parsePortMapping(portMappings []specgen.PortMapping) ([]ocicni.PortMapping,
// Only get a random candidate for single entries or the start
// of a range. Otherwise we just increment the candidate.
if !tmp.isInRange || tmp.startOfRange {
candidate, err = specgen.GetRandomPort()
candidate, err = utils.GetRandomPort()
if err != nil {
return nil, nil, nil, errors.Wrapf(err, "error getting candidate host port for container port %d", p.ContainerPort)
}
@ -344,7 +346,7 @@ func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, img *imag
for hostPort == 0 && tries > 0 {
// We can't select a specific protocol, which is
// unfortunate for the UDP case.
candidate, err := specgen.GetRandomPort()
candidate, err := utils.GetRandomPort()
if err != nil {
return nil, err
}

View File

@ -1,4 +1,4 @@
package specgen
package utils
import (
"net"