summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/podman/common/completion.go8
-rw-r--r--cmd/podman/containers/run.go6
-rw-r--r--cmd/podman/images/prune.go12
-rw-r--r--cmd/podman/machine/init.go99
-rw-r--r--cmd/podman/machine/machine.go32
-rw-r--r--cmd/podman/machine/machine_unsupported.go5
-rw-r--r--cmd/podman/machine/remove.go88
-rw-r--r--cmd/podman/machine/ssh.go70
-rw-r--r--cmd/podman/machine/start.go48
-rw-r--r--cmd/podman/machine/stop.go49
-rw-r--r--cmd/podman/main.go1
-rw-r--r--cmd/podman/system/prune.go32
12 files changed, 438 insertions, 12 deletions
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go
index bc106263c..6bed5e0c6 100644
--- a/cmd/podman/common/completion.go
+++ b/cmd/podman/common/completion.go
@@ -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
+}
diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go
index 83a5d7b8a..db7180ca9 100644
--- a/cmd/podman/containers/run.go
+++ b/cmd/podman/containers/run.go
@@ -17,6 +17,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
+ "golang.org/x/crypto/ssh/terminal"
)
var (
@@ -106,6 +107,11 @@ func run(cmd *cobra.Command, args []string) error {
return err
}
+ // TODO: Breaking change should be made fatal in next major Release
+ if cliVals.TTY && cliVals.Interactive && !terminal.IsTerminal(int(os.Stdin.Fd())) {
+ logrus.Warnf("The input device is not a TTY. The --tty and --interactive flags might not work properly")
+ }
+
if af := cliVals.Authfile; len(af) > 0 {
if _, err := os.Stat(af); err != nil {
return err
diff --git a/cmd/podman/images/prune.go b/cmd/podman/images/prune.go
index 78e107a97..8231e5c57 100644
--- a/cmd/podman/images/prune.go
+++ b/cmd/podman/images/prune.go
@@ -53,9 +53,7 @@ func init() {
func prune(cmd *cobra.Command, args []string) error {
if !force {
reader := bufio.NewReader(os.Stdin)
- fmt.Printf(`
-WARNING! This will remove all dangling images.
-Are you sure you want to continue? [y/N] `)
+ fmt.Printf("%s", createPruneWarningMessage(pruneOpts))
answer, err := reader.ReadString('\n')
if err != nil {
return err
@@ -72,3 +70,11 @@ Are you sure you want to continue? [y/N] `)
return utils.PrintImagePruneResults(results, false)
}
+
+func createPruneWarningMessage(pruneOpts entities.ImagePruneOptions) string {
+ question := "Are you sure you want to continue? [y/N] "
+ if pruneOpts.All {
+ return "WARNING! This will remove all images without at least one container associated to them.\n" + question
+ }
+ return "WARNING! This will remove all dangling images.\n" + question
+}
diff --git a/cmd/podman/machine/init.go b/cmd/podman/machine/init.go
new file mode 100644
index 000000000..900f67e2f
--- /dev/null
+++ b/cmd/podman/machine/init.go
@@ -0,0 +1,99 @@
+// +build amd64,linux amd64,darwin arm64,darwin
+
+package machine
+
+import (
+ "github.com/containers/common/pkg/completion"
+ "github.com/containers/podman/v3/cmd/podman/registry"
+ "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/spf13/cobra"
+)
+
+var (
+ initCmd = &cobra.Command{
+ Use: "init [options] [NAME]",
+ Short: "initialize a vm",
+ Long: "initialize a virtual machine for Podman to run on. Virtual machines are used to run Podman.",
+ RunE: initMachine,
+ Args: cobra.MaximumNArgs(1),
+ Example: `podman machine init myvm`,
+ ValidArgsFunction: completion.AutocompleteNone,
+ }
+)
+
+type InitCLIOptions struct {
+ CPUS uint64
+ Memory uint64
+ Devices []string
+ ImagePath string
+ IgnitionPath string
+ Name string
+}
+
+var (
+ initOpts = InitCLIOptions{}
+ defaultMachineName string = "podman-machine-default"
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: initCmd,
+ Parent: machineCmd,
+ })
+ flags := initCmd.Flags()
+
+ cpusFlagName := "cpus"
+ flags.Uint64Var(
+ &initOpts.CPUS,
+ cpusFlagName, 1,
+ "Number of CPUs. The default is 1.",
+ )
+ _ = initCmd.RegisterFlagCompletionFunc(cpusFlagName, completion.AutocompleteNone)
+
+ memoryFlagName := "memory"
+ flags.Uint64VarP(
+ &initOpts.Memory,
+ memoryFlagName, "m", 2048,
+ "Memory (in MB)",
+ )
+ _ = initCmd.RegisterFlagCompletionFunc(memoryFlagName, completion.AutocompleteNone)
+
+ ImagePathFlagName := "image-path"
+ flags.StringVar(&initOpts.ImagePath, ImagePathFlagName, "", "Path to qcow image")
+ _ = initCmd.RegisterFlagCompletionFunc(ImagePathFlagName, completion.AutocompleteDefault)
+
+ IgnitionPathFlagName := "ignition-path"
+ flags.StringVar(&initOpts.IgnitionPath, IgnitionPathFlagName, "", "Path to ignition file")
+ _ = initCmd.RegisterFlagCompletionFunc(IgnitionPathFlagName, completion.AutocompleteDefault)
+}
+
+// TODO should we allow for a users to append to the qemu cmdline?
+func initMachine(cmd *cobra.Command, args []string) error {
+ initOpts.Name = defaultMachineName
+ if len(args) > 0 {
+ initOpts.Name = args[0]
+ }
+ vmOpts := machine.InitOptions{
+ CPUS: initOpts.CPUS,
+ Memory: initOpts.Memory,
+ IgnitionPath: initOpts.IgnitionPath,
+ ImagePath: initOpts.ImagePath,
+ Name: initOpts.Name,
+ }
+ var (
+ vm machine.VM
+ vmType string
+ err error
+ )
+ switch vmType {
+ default: // qemu is the default
+ vm, err = qemu.NewMachine(vmOpts)
+ }
+ if err != nil {
+ return err
+ }
+ return vm.Init(vmOpts)
+}
diff --git a/cmd/podman/machine/machine.go b/cmd/podman/machine/machine.go
new file mode 100644
index 000000000..ed284ee10
--- /dev/null
+++ b/cmd/podman/machine/machine.go
@@ -0,0 +1,32 @@
+// +build amd64,linux amd64,darwin arm64,darwin
+
+package machine
+
+import (
+ "github.com/containers/podman/v3/cmd/podman/registry"
+ "github.com/containers/podman/v3/cmd/podman/validate"
+ "github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/spf13/cobra"
+)
+
+var (
+ noOp = func(cmd *cobra.Command, args []string) error {
+ return nil
+ }
+ // Command: podman _machine_
+ machineCmd = &cobra.Command{
+ Use: "machine",
+ Short: "Manage a virtual machine",
+ Long: "Manage a virtual machine. Virtual machines are used to run Podman.",
+ PersistentPreRunE: noOp,
+ PersistentPostRunE: noOp,
+ RunE: validate.SubCommandExists,
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: machineCmd,
+ })
+}
diff --git a/cmd/podman/machine/machine_unsupported.go b/cmd/podman/machine/machine_unsupported.go
new file mode 100644
index 000000000..cb1636419
--- /dev/null
+++ b/cmd/podman/machine/machine_unsupported.go
@@ -0,0 +1,5 @@
+// +build !amd64 arm64,linux amd64,windows
+
+package machine
+
+func init() {}
diff --git a/cmd/podman/machine/remove.go b/cmd/podman/machine/remove.go
new file mode 100644
index 000000000..f6ce9e326
--- /dev/null
+++ b/cmd/podman/machine/remove.go
@@ -0,0 +1,88 @@
+// +build amd64,linux amd64,darwin arm64,darwin
+
+package machine
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/containers/common/pkg/completion"
+ "github.com/containers/podman/v3/cmd/podman/registry"
+ "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/spf13/cobra"
+)
+
+var (
+ 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 remove myvm`,
+ ValidArgsFunction: completion.AutocompleteNone,
+ }
+)
+
+var (
+ destoryOptions machine.RemoveOptions
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: removeCmd,
+ Parent: machineCmd,
+ })
+
+ flags := removeCmd.Flags()
+ formatFlagName := "force"
+ 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")
+
+ ignitionFlagName := "save-ignition"
+ flags.BoolVar(&destoryOptions.SaveIgnition, ignitionFlagName, false, "Do not delete ignition file")
+
+ imageFlagName := "save-image"
+ flags.BoolVar(&destoryOptions.SaveImage, imageFlagName, false, "Do not delete the image file")
+}
+
+func remove(cmd *cobra.Command, args []string) error {
+ var (
+ err error
+ vm machine.VM
+ vmType string
+ )
+ switch vmType {
+ default:
+ vm, err = qemu.LoadVMByName(args[0])
+ }
+ if err != nil {
+ return err
+ }
+ confirmationMessage, doIt, err := vm.Remove(args[0], machine.RemoveOptions{})
+ if err != nil {
+ return err
+ }
+
+ if !destoryOptions.Force {
+ // Warn user
+ fmt.Println(confirmationMessage)
+ reader := bufio.NewReader(os.Stdin)
+ fmt.Print("Are you sure you want to continue? [y/N] ")
+ answer, err := reader.ReadString('\n')
+ if err != nil {
+ return err
+ }
+ if strings.ToLower(answer)[0] != 'y' {
+ return nil
+ }
+ }
+ return doIt()
+}
diff --git a/cmd/podman/machine/ssh.go b/cmd/podman/machine/ssh.go
new file mode 100644
index 000000000..a7111a195
--- /dev/null
+++ b/cmd/podman/machine/ssh.go
@@ -0,0 +1,70 @@
+// +build amd64,linux amd64,darwin arm64,darwin
+
+package machine
+
+import (
+ "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"
+ "github.com/containers/podman/v3/pkg/machine/qemu"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+)
+
+var (
+ sshCmd = &cobra.Command{
+ Use: "ssh [options] NAME [COMMAND [ARG ...]]",
+ Short: "SSH into a 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: common.AutocompleteMachineSSH,
+ }
+)
+
+var (
+ sshOpts machine.SSHOptions
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: sshCmd,
+ Parent: machineCmd,
+ })
+
+ flags := sshCmd.Flags()
+ executeFlagName := "execute"
+ flags.BoolVarP(&sshOpts.Execute, executeFlagName, "e", false, "Execute command from args")
+}
+
+func ssh(cmd *cobra.Command, args []string) error {
+ var (
+ err error
+ vm machine.VM
+ vmType string
+ )
+ sshOpts.Args = args[1:]
+
+ // Error if no execute but args given
+ if !sshOpts.Execute && len(sshOpts.Args) > 0 {
+ return errors.New("too many args: to execute commands via ssh, use -e flag")
+ }
+ // Error if execute but no args given
+ if sshOpts.Execute && len(sshOpts.Args) < 1 {
+ return errors.New("must proivde at least one command to execute")
+ }
+
+ switch vmType {
+ default:
+ vm, err = qemu.LoadVMByName(args[0])
+ }
+ if err != nil {
+ return errors.Wrapf(err, "vm %s not found", args[0])
+ }
+ return vm.SSH(args[0], sshOpts)
+}
diff --git a/cmd/podman/machine/start.go b/cmd/podman/machine/start.go
new file mode 100644
index 000000000..44ade2850
--- /dev/null
+++ b/cmd/podman/machine/start.go
@@ -0,0 +1,48 @@
+// +build amd64,linux amd64,darwin arm64,darwin
+
+package machine
+
+import (
+ "github.com/containers/common/pkg/completion"
+ "github.com/containers/podman/v3/cmd/podman/registry"
+ "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/spf13/cobra"
+)
+
+var (
+ startCmd = &cobra.Command{
+ Use: "start NAME",
+ Short: "Start an existing machine",
+ Long: "Start an existing machine ",
+ RunE: start,
+ Args: cobra.ExactArgs(1),
+ Example: `podman machine start myvm`,
+ ValidArgsFunction: completion.AutocompleteNone,
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: startCmd,
+ Parent: machineCmd,
+ })
+}
+
+func start(cmd *cobra.Command, args []string) error {
+ var (
+ err error
+ vm machine.VM
+ vmType string
+ )
+ switch vmType {
+ default:
+ vm, err = qemu.LoadVMByName(args[0])
+ }
+ if err != nil {
+ return err
+ }
+ return vm.Start(args[0], machine.StartOptions{})
+}
diff --git a/cmd/podman/machine/stop.go b/cmd/podman/machine/stop.go
new file mode 100644
index 000000000..35fd4ff95
--- /dev/null
+++ b/cmd/podman/machine/stop.go
@@ -0,0 +1,49 @@
+// +build amd64,linux amd64,darwin arm64,darwin
+
+package machine
+
+import (
+ "github.com/containers/common/pkg/completion"
+ "github.com/containers/podman/v3/cmd/podman/registry"
+ "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/spf13/cobra"
+)
+
+var (
+ stopCmd = &cobra.Command{
+ Use: "stop NAME",
+ Short: "Stop an existing machine",
+ Long: "Stop an existing machine ",
+ RunE: stop,
+ Args: cobra.ExactArgs(1),
+ Example: `podman machine stop myvm`,
+ ValidArgsFunction: completion.AutocompleteNone,
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: stopCmd,
+ Parent: machineCmd,
+ })
+}
+
+// TODO Name shouldnt be required, need to create a default vm
+func stop(cmd *cobra.Command, args []string) error {
+ var (
+ err error
+ vm machine.VM
+ vmType string
+ )
+ switch vmType {
+ default:
+ vm, err = qemu.LoadVMByName(args[0])
+ }
+ if err != nil {
+ return err
+ }
+ return vm.Stop(args[0], machine.StopOptions{})
+}
diff --git a/cmd/podman/main.go b/cmd/podman/main.go
index 561459c31..5219da26d 100644
--- a/cmd/podman/main.go
+++ b/cmd/podman/main.go
@@ -9,6 +9,7 @@ import (
_ "github.com/containers/podman/v3/cmd/podman/generate"
_ "github.com/containers/podman/v3/cmd/podman/healthcheck"
_ "github.com/containers/podman/v3/cmd/podman/images"
+ _ "github.com/containers/podman/v3/cmd/podman/machine"
_ "github.com/containers/podman/v3/cmd/podman/manifest"
_ "github.com/containers/podman/v3/cmd/podman/networks"
_ "github.com/containers/podman/v3/cmd/podman/play"
diff --git a/cmd/podman/system/prune.go b/cmd/podman/system/prune.go
index 136c15304..3020a541b 100644
--- a/cmd/podman/system/prune.go
+++ b/cmd/podman/system/prune.go
@@ -55,22 +55,17 @@ func init() {
func prune(cmd *cobra.Command, args []string) error {
var err error
-
// Prompt for confirmation if --force is not set
if !force {
reader := bufio.NewReader(os.Stdin)
volumeString := ""
if pruneOptions.Volume {
volumeString = `
- - all volumes not used by at least one container`
+ - all volumes not used by at least one container`
}
- fmt.Printf(`
-WARNING! This will remove:
- - all stopped containers%s
- - all stopped pods
- - all dangling images
- - all build cache
-Are you sure you want to continue? [y/N] `, volumeString)
+
+ fmt.Printf(createPruneWarningMessage(pruneOptions), volumeString, "Are you sure you want to continue? [y/N] ")
+
answer, err := reader.ReadString('\n')
if err != nil {
return err
@@ -115,3 +110,22 @@ Are you sure you want to continue? [y/N] `, volumeString)
fmt.Printf("Total reclaimed space: %s\n", units.HumanSize((float64)(response.ReclaimedSpace)))
return nil
}
+
+func createPruneWarningMessage(pruneOpts entities.SystemPruneOptions) string {
+ if pruneOpts.All {
+ return `WARNING! This will remove:
+ - all stopped containers
+ - all networks not used by at least one container%s
+ - all images without at least one container associated to them
+ - all build cache
+
+%s`
+ }
+ return `WARNING! This will remove:
+ - all stopped containers
+ - all networks not used by at least one container%s
+ - all dangling images
+ - all dangling build cache
+
+%s`
+}