summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/podman/common/completion.go2
-rw-r--r--cmd/podman/common/create.go17
-rw-r--r--cmd/podman/containers/create.go1
-rw-r--r--cmd/podman/containers/wait.go18
-rw-r--r--cmd/podman/machine/info.go182
-rw-r--r--cmd/podman/machine/list.go36
-rw-r--r--cmd/podman/machine/machine.go20
-rw-r--r--cmd/podman/networks/prune.go15
-rw-r--r--cmd/podman/pods/create.go1
-rw-r--r--cmd/podman/utils/utils.go8
10 files changed, 232 insertions, 68 deletions
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go
index ae30f2875..6e6c33f9b 100644
--- a/cmd/podman/common/completion.go
+++ b/cmd/podman/common/completion.go
@@ -966,7 +966,7 @@ func AutocompleteLogOpt(cmd *cobra.Command, args []string, toComplete string) ([
// AutocompletePullOption - Autocomplete pull options for create and run command.
// -> "always", "missing", "never"
func AutocompletePullOption(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
- pullOptions := []string{"always", "missing", "never"}
+ pullOptions := []string{"always", "missing", "never", "newer"}
return pullOptions, cobra.ShellCompDirectiveNoFileComp
}
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index f05549a8d..923d0517f 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -390,7 +390,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
createFlags.StringVar(
&cf.Pull,
pullFlagName, cf.Pull,
- `Pull image before creating ("always"|"missing"|"never")`,
+ `Pull image policy`,
)
_ = cmd.RegisterFlagCompletionFunc(pullFlagName, AutocompletePullOption)
@@ -544,13 +544,6 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(userFlagName, AutocompleteUserFlag)
- utsFlagName := "uts"
- createFlags.String(
- utsFlagName, "",
- "UTS namespace to use",
- )
- _ = cmd.RegisterFlagCompletionFunc(utsFlagName, AutocompleteNamespace)
-
mountFlagName := "mount"
createFlags.StringArrayVar(
&cf.Mount,
@@ -684,6 +677,14 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(usernsFlagName, AutocompleteUserNamespace)
+ utsFlagName := "uts"
+ createFlags.StringVar(
+ &cf.UTS,
+ utsFlagName, "",
+ "UTS namespace to use",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(utsFlagName, AutocompleteNamespace)
+
cgroupParentFlagName := "cgroup-parent"
createFlags.StringVar(
&cf.CgroupParent,
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 05a59ce7b..7d0f4d9ae 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -224,7 +224,6 @@ func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra
return vals, errors.New("--cpu-quota and --cpus cannot be set together")
}
vals.IPC = c.Flag("ipc").Value.String()
- vals.UTS = c.Flag("uts").Value.String()
vals.PID = c.Flag("pid").Value.String()
vals.CgroupNS = c.Flag("cgroupns").Value.String()
diff --git a/cmd/podman/containers/wait.go b/cmd/podman/containers/wait.go
index 5b8480781..be92a3cbe 100644
--- a/cmd/podman/containers/wait.go
+++ b/cmd/podman/containers/wait.go
@@ -41,9 +41,9 @@ var (
)
var (
- waitOptions = entities.WaitOptions{}
- waitCondition string
- waitInterval string
+ waitOptions = entities.WaitOptions{}
+ waitConditions []string
+ waitInterval string
)
func waitFlags(cmd *cobra.Command) {
@@ -54,7 +54,7 @@ func waitFlags(cmd *cobra.Command) {
_ = cmd.RegisterFlagCompletionFunc(intervalFlagName, completion.AutocompleteNone)
conditionFlagName := "condition"
- flags.StringVar(&waitCondition, conditionFlagName, "stopped", "Condition to wait on")
+ flags.StringSliceVar(&waitConditions, conditionFlagName, []string{}, "Condition to wait on")
_ = cmd.RegisterFlagCompletionFunc(conditionFlagName, common.AutocompleteWaitCondition)
}
@@ -92,11 +92,13 @@ func wait(cmd *cobra.Command, args []string) error {
return errors.New("--latest and containers cannot be used together")
}
- cond, err := define.StringToContainerStatus(waitCondition)
- if err != nil {
- return err
+ for _, condition := range waitConditions {
+ cond, err := define.StringToContainerStatus(condition)
+ if err != nil {
+ return err
+ }
+ waitOptions.Condition = append(waitOptions.Condition, cond)
}
- waitOptions.Condition = []define.ContainerStatus{cond}
responses, err := registry.ContainerEngine().ContainerWait(context.Background(), args, waitOptions)
if err != nil {
diff --git a/cmd/podman/machine/info.go b/cmd/podman/machine/info.go
new file mode 100644
index 000000000..9932027d8
--- /dev/null
+++ b/cmd/podman/machine/info.go
@@ -0,0 +1,182 @@
+//go:build amd64 || arm64
+// +build amd64 arm64
+
+package machine
+
+import (
+ "fmt"
+ "html/template"
+ "os"
+ "runtime"
+
+ "github.com/containers/common/pkg/completion"
+ "github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/report"
+ "github.com/containers/podman/v4/cmd/podman/common"
+ "github.com/containers/podman/v4/cmd/podman/registry"
+ "github.com/containers/podman/v4/cmd/podman/validate"
+ "github.com/containers/podman/v4/libpod/define"
+ "github.com/containers/podman/v4/pkg/machine"
+ "github.com/ghodss/yaml"
+ "github.com/spf13/cobra"
+)
+
+var infoDescription = `Display information pertaining to the machine host.`
+
+var (
+ infoCmd = &cobra.Command{
+ Use: "info [options]",
+ Short: "Display machine host info",
+ Long: infoDescription,
+ PersistentPreRunE: rootlessOnly,
+ RunE: info,
+ Args: validate.NoArgs,
+ ValidArgsFunction: completion.AutocompleteNone,
+ Example: `podman machine info`,
+ }
+)
+
+var (
+ inFormat string
+)
+
+// Info contains info on the machine host and version info
+type Info struct {
+ Host *HostInfo `json:"Host"`
+ Version define.Version `json:"Version"`
+}
+
+// HostInfo contains info on the machine host
+type HostInfo struct {
+ Arch string `json:"Arch"`
+ CurrentMachine string `json:"CurrentMachine"`
+ DefaultMachine string `json:"DefaultMachine"`
+ EventsDir string `json:"EventsDir"`
+ MachineConfigDir string `json:"MachineConfigDir"`
+ MachineImageDir string `json:"MachineImageDir"`
+ MachineState string `json:"MachineState"`
+ NumberOfMachines int `json:"NumberOfMachines"`
+ OS string `json:"OS"`
+ VMType string `json:"VMType"`
+}
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Command: infoCmd,
+ Parent: machineCmd,
+ })
+
+ flags := infoCmd.Flags()
+ formatFlagName := "format"
+ flags.StringVarP(&inFormat, formatFlagName, "f", "", "Change the output format to JSON or a Go template")
+ _ = infoCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&define.Info{}))
+}
+
+func info(cmd *cobra.Command, args []string) error {
+ info := Info{}
+ version, err := define.GetVersion()
+ if err != nil {
+ return fmt.Errorf("error getting version info %w", err)
+ }
+ info.Version = version
+
+ host, err := hostInfo()
+ if err != nil {
+ return err
+ }
+ info.Host = host
+
+ switch {
+ case report.IsJSON(inFormat):
+ b, err := json.MarshalIndent(info, "", " ")
+ if err != nil {
+ return err
+ }
+ fmt.Println(string(b))
+ case cmd.Flags().Changed("format"):
+ tmpl := template.New(cmd.Name()).Funcs(template.FuncMap(report.DefaultFuncs))
+ inFormat = report.NormalizeFormat(inFormat)
+ tmpl, err := tmpl.Parse(inFormat)
+ if err != nil {
+ return err
+ }
+ return tmpl.Execute(os.Stdout, info)
+ default:
+ b, err := yaml.Marshal(info)
+ if err != nil {
+ return err
+ }
+ fmt.Println(string(b))
+ }
+
+ return nil
+}
+
+func hostInfo() (*HostInfo, error) {
+ host := HostInfo{}
+
+ host.Arch = runtime.GOARCH
+ host.OS = runtime.GOOS
+
+ provider := GetSystemDefaultProvider()
+ var listOpts machine.ListOptions
+ listResponse, err := provider.List(listOpts)
+ if err != nil {
+ return nil, fmt.Errorf("failed to get machines %w", err)
+ }
+
+ host.NumberOfMachines = len(listResponse)
+
+ cfg, err := config.ReadCustomConfig()
+ if err != nil {
+ return nil, err
+ }
+
+ // Default state of machine is stopped
+ host.MachineState = "Stopped"
+ for _, vm := range listResponse {
+ // Set default machine if found
+ if vm.Name == cfg.Engine.ActiveService {
+ host.DefaultMachine = vm.Name
+ }
+ // If machine is running or starting, it is automatically the current machine
+ if vm.Running {
+ host.CurrentMachine = vm.Name
+ host.MachineState = "Running"
+ } else if vm.Starting {
+ host.CurrentMachine = vm.Name
+ host.MachineState = "Starting"
+ }
+ }
+ // If no machines are starting or running, set current machine to default machine
+ // If no default machines are found, do not report a default machine or a state
+ if host.CurrentMachine == "" {
+ if host.DefaultMachine == "" {
+ host.MachineState = ""
+ } else {
+ host.CurrentMachine = host.DefaultMachine
+ }
+ }
+
+ host.VMType = provider.VMType()
+
+ dataDir, err := machine.GetDataDir(host.VMType)
+ if err != nil {
+ return nil, fmt.Errorf("failed to get machine image dir")
+ }
+ host.MachineImageDir = dataDir
+
+ confDir, err := machine.GetConfDir(host.VMType)
+ if err != nil {
+ return nil, fmt.Errorf("failed to get machine config dir %w", err)
+ }
+ host.MachineConfigDir = confDir
+
+ eventsDir, err := eventSockDir()
+ if err != nil {
+ return nil, fmt.Errorf("failed to get events dir: %w", err)
+ }
+ host.EventsDir = eventsDir
+
+ return &host, nil
+}
diff --git a/cmd/podman/machine/list.go b/cmd/podman/machine/list.go
index b1e31566f..dd4a86697 100644
--- a/cmd/podman/machine/list.go
+++ b/cmd/podman/machine/list.go
@@ -16,6 +16,7 @@ import (
"github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/cmd/podman/validate"
+ "github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/machine"
"github.com/docker/go-units"
"github.com/spf13/cobra"
@@ -44,23 +45,6 @@ type listFlagType struct {
quiet bool
}
-type ListReporter struct {
- Name string
- Default bool
- Created string
- Running bool
- Starting bool
- LastUp string
- Stream string
- VMType string
- CPUs uint64
- Memory string
- DiskSize string
- Port int
- RemoteUsername string
- IdentityPath string
-}
-
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: lsCmd,
@@ -70,7 +54,7 @@ func init() {
flags := lsCmd.Flags()
formatFlagName := "format"
flags.StringVar(&listFlag.format, formatFlagName, "{{.Name}}\t{{.VMType}}\t{{.Created}}\t{{.LastUp}}\t{{.CPUs}}\t{{.Memory}}\t{{.DiskSize}}\n", "Format volume output using JSON or a Go template")
- _ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&ListReporter{}))
+ _ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.ListReporter{}))
flags.BoolVar(&listFlag.noHeading, "noheading", false, "Do not print headers")
flags.BoolVarP(&listFlag.quiet, "quiet", "q", false, "Show only machine names")
}
@@ -123,8 +107,8 @@ func list(cmd *cobra.Command, args []string) error {
return outputTemplate(cmd, machineReporter)
}
-func outputTemplate(cmd *cobra.Command, responses []*ListReporter) error {
- headers := report.Headers(ListReporter{}, map[string]string{
+func outputTemplate(cmd *cobra.Command, responses []*entities.ListReporter) error {
+ headers := report.Headers(entities.ListReporter{}, map[string]string{
"LastUp": "LAST UP",
"VmType": "VM TYPE",
"CPUs": "CPUS",
@@ -183,15 +167,15 @@ func streamName(imageStream string) string {
return imageStream
}
-func toMachineFormat(vms []*machine.ListResponse) ([]*ListReporter, error) {
+func toMachineFormat(vms []*machine.ListResponse) ([]*entities.ListReporter, error) {
cfg, err := config.ReadCustomConfig()
if err != nil {
return nil, err
}
- machineResponses := make([]*ListReporter, 0, len(vms))
+ machineResponses := make([]*entities.ListReporter, 0, len(vms))
for _, vm := range vms {
- response := new(ListReporter)
+ response := new(entities.ListReporter)
response.Default = vm.Name == cfg.Engine.ActiveService
response.Name = vm.Name
response.Running = vm.Running
@@ -211,15 +195,15 @@ func toMachineFormat(vms []*machine.ListResponse) ([]*ListReporter, error) {
return machineResponses, nil
}
-func toHumanFormat(vms []*machine.ListResponse) ([]*ListReporter, error) {
+func toHumanFormat(vms []*machine.ListResponse) ([]*entities.ListReporter, error) {
cfg, err := config.ReadCustomConfig()
if err != nil {
return nil, err
}
- humanResponses := make([]*ListReporter, 0, len(vms))
+ humanResponses := make([]*entities.ListReporter, 0, len(vms))
for _, vm := range vms {
- response := new(ListReporter)
+ response := new(entities.ListReporter)
if vm.Name == cfg.Engine.ActiveService {
response.Name = vm.Name + "*"
response.Default = true
diff --git a/cmd/podman/machine/machine.go b/cmd/podman/machine/machine.go
index 5a8a06b9d..0618337cc 100644
--- a/cmd/podman/machine/machine.go
+++ b/cmd/podman/machine/machine.go
@@ -101,12 +101,6 @@ func resolveEventSock() ([]string, error) {
return []string{sock}, nil
}
- xdg, err := util.GetRuntimeDir()
- if err != nil {
- logrus.Warnf("Failed to get runtime dir, machine events will not be published: %s", err)
- return nil, nil
- }
-
re := regexp.MustCompile(`machine_events.*\.sock`)
sockPaths := make([]string, 0)
fn := func(path string, info os.DirEntry, err error) error {
@@ -125,8 +119,12 @@ func resolveEventSock() ([]string, error) {
sockPaths = append(sockPaths, path)
return nil
}
+ sockDir, err := eventSockDir()
+ if err != nil {
+ logrus.Warnf("Failed to get runtime dir, machine events will not be published: %s", err)
+ }
- if err := filepath.WalkDir(filepath.Join(xdg, "podman"), fn); err != nil {
+ if err := filepath.WalkDir(sockDir, fn); err != nil {
if errors.Is(err, os.ErrNotExist) {
return nil, nil
}
@@ -135,6 +133,14 @@ func resolveEventSock() ([]string, error) {
return sockPaths, nil
}
+func eventSockDir() (string, error) {
+ xdg, err := util.GetRuntimeDir()
+ if err != nil {
+ return "", err
+ }
+ return filepath.Join(xdg, "podman"), nil
+}
+
func newMachineEvent(status events.Status, event events.Event) {
openEventSock.Do(initMachineEvents)
diff --git a/cmd/podman/networks/prune.go b/cmd/podman/networks/prune.go
index fa621ebac..ee5389aa7 100644
--- a/cmd/podman/networks/prune.go
+++ b/cmd/podman/networks/prune.go
@@ -52,10 +52,7 @@ func init() {
}
func networkPrune(cmd *cobra.Command, _ []string) error {
- var (
- errs utils.OutputErrors
- err error
- )
+ var err error
if !force {
reader := bufio.NewReader(os.Stdin)
fmt.Println("WARNING! This will remove all networks not used by at least one container.")
@@ -77,13 +74,5 @@ func networkPrune(cmd *cobra.Command, _ []string) error {
setExitCode(err)
return err
}
- for _, r := range responses {
- if r.Error == nil {
- fmt.Println(r.Name)
- } else {
- setExitCode(r.Error)
- errs = append(errs, r.Error)
- }
- }
- return errs.PrintErrors()
+ return utils.PrintNetworkPruneResults(responses, false)
}
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index 45ad2dfd0..aea8a7229 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -277,6 +277,7 @@ func create(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
+
podSpec.Volumes = podSpec.InfraContainerSpec.Volumes
podSpec.ImageVolumes = podSpec.InfraContainerSpec.ImageVolumes
podSpec.OverlayVolumes = podSpec.InfraContainerSpec.OverlayVolumes
diff --git a/cmd/podman/utils/utils.go b/cmd/podman/utils/utils.go
index 2ae123388..a265faf51 100644
--- a/cmd/podman/utils/utils.go
+++ b/cmd/podman/utils/utils.go
@@ -85,16 +85,16 @@ func PrintImagePruneResults(imagePruneReports []*reports.PruneReport, heading bo
return nil
}
-func PrintNetworkPruneResults(networkPruneReport []*reports.PruneReport, heading bool) error {
+func PrintNetworkPruneResults(networkPruneReport []*entities.NetworkPruneReport, heading bool) error {
var errs OutputErrors
if heading && len(networkPruneReport) > 0 {
fmt.Println("Deleted Networks")
}
for _, r := range networkPruneReport {
- if r.Err == nil {
- fmt.Println(r.Id)
+ if r.Error == nil {
+ fmt.Println(r.Name)
} else {
- errs = append(errs, r.Err)
+ errs = append(errs, r.Error)
}
}
return errs.PrintErrors()