aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorcdoern <cbdoer23@g.holycross.edu>2022-05-13 10:52:57 -0400
committercdoern <cdoern@redhat.com>2022-06-10 14:23:19 -0400
commit958759a71955860b01b17bd3bebf38f9dae1018e (patch)
tree34872e81fb126f854c7612ca39f11932ccd3f8bb /cmd
parent6a2c0e96011d36e5b459a010d472facd26c67389 (diff)
downloadpodman-958759a71955860b01b17bd3bebf38f9dae1018e.tar.gz
podman-958759a71955860b01b17bd3bebf38f9dae1018e.tar.bz2
podman-958759a71955860b01b17bd3bebf38f9dae1018e.zip
podman pod clone
implement podman pod clone, a command to create an exact copy of a pod while changing certain config elements current supported flags are: --name change the pod name --destroy remove the original pod --start run the new pod on creation and all infra-container related flags from podman pod create (namespaces etc) resolves #12843 Signed-off-by: cdoern <cdoern@redhat.com>
Diffstat (limited to 'cmd')
-rw-r--r--cmd/podman/common/completion.go6
-rw-r--r--cmd/podman/common/create.go31
-rw-r--r--cmd/podman/common/create_opts.go22
-rw-r--r--cmd/podman/containers/clone.go1
-rw-r--r--cmd/podman/containers/create.go1
-rw-r--r--cmd/podman/containers/run.go1
-rw-r--r--cmd/podman/pods/clone.go87
-rw-r--r--cmd/podman/pods/create.go1
8 files changed, 134 insertions, 16 deletions
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go
index 07dcc4e6a..aeb051001 100644
--- a/cmd/podman/common/completion.go
+++ b/cmd/podman/common/completion.go
@@ -1607,8 +1607,14 @@ func AutocompleteClone(cmd *cobra.Command, args []string, toComplete string) ([]
}
switch len(args) {
case 0:
+ if cmd.Parent().Name() == "pod" { // needs to be " pod " to exclude 'podman'
+ return getPods(cmd, toComplete, completeDefault)
+ }
return getContainers(cmd, toComplete, completeDefault)
case 2:
+ if cmd.Parent().Name() == "pod" {
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
return getImages(cmd, toComplete)
}
return nil, cobra.ShellCompDirectiveNoFileComp
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index f89035be3..40bb0df78 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -98,7 +98,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
cgroupsFlagName := "cgroups"
createFlags.StringVar(
&cf.CgroupsMode,
- cgroupsFlagName, cgroupConfig(),
+ cgroupsFlagName, cf.CgroupsMode,
`control container cgroup configuration ("enabled"|"disabled"|"no-conmon"|"split")`,
)
_ = cmd.RegisterFlagCompletionFunc(cgroupsFlagName, AutocompleteCgroupMode)
@@ -150,7 +150,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
envFlagName := "env"
createFlags.StringArrayP(
- envFlagName, "e", env(),
+ envFlagName, "e", Env(),
"Set environment variables in container",
)
_ = cmd.RegisterFlagCompletionFunc(envFlagName, completion.AutocompleteNone)
@@ -256,7 +256,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
imageVolumeFlagName := "image-volume"
createFlags.String(
- imageVolumeFlagName, containerConfig.Engine.ImageVolumeMode,
+ imageVolumeFlagName, cf.ImageVolume,
`Tells podman how to handle the builtin image volumes ("bind"|"tmpfs"|"ignore")`,
)
_ = cmd.RegisterFlagCompletionFunc(imageVolumeFlagName, AutocompleteImageVolume)
@@ -298,7 +298,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
logDriverFlagName := "log-driver"
createFlags.StringVar(
&cf.LogDriver,
- logDriverFlagName, LogDriver(),
+ logDriverFlagName, cf.LogDriver,
"Logging driver for the container",
)
_ = cmd.RegisterFlagCompletionFunc(logDriverFlagName, AutocompleteLogDriver)
@@ -389,7 +389,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
pullFlagName := "pull"
createFlags.StringVar(
&cf.Pull,
- pullFlagName, policy(),
+ pullFlagName, cf.Pull,
`Pull image before creating ("always"|"missing"|"never")`,
)
_ = cmd.RegisterFlagCompletionFunc(pullFlagName, AutocompletePullOption)
@@ -406,7 +406,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
createFlags.BoolVar(
&cf.ReadOnlyTmpFS,
- "read-only-tmpfs", true,
+ "read-only-tmpfs", cf.ReadOnlyTmpFS,
"When running containers in read-only mode mount a read-write tmpfs on /run, /tmp and /var/tmp",
)
requiresFlagName := "requires"
@@ -439,7 +439,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
sdnotifyFlagName := "sdnotify"
createFlags.StringVar(
&cf.SdNotifyMode,
- sdnotifyFlagName, define.SdNotifyModeContainer,
+ sdnotifyFlagName, cf.SdNotifyMode,
`control sd-notify behavior ("container"|"conmon"|"ignore")`,
)
_ = cmd.RegisterFlagCompletionFunc(sdnotifyFlagName, AutocompleteSDNotify)
@@ -470,7 +470,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
stopTimeoutFlagName := "stop-timeout"
createFlags.UintVar(
&cf.StopTimeout,
- stopTimeoutFlagName, containerConfig.Engine.StopTimeout,
+ stopTimeoutFlagName, cf.StopTimeout,
"Timeout (in seconds) that containers stopped by user command have to exit. If exceeded, the container will be forcibly stopped via SIGKILL.",
)
_ = cmd.RegisterFlagCompletionFunc(stopTimeoutFlagName, completion.AutocompleteNone)
@@ -478,7 +478,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
systemdFlagName := "systemd"
createFlags.StringVar(
&cf.Systemd,
- systemdFlagName, "true",
+ systemdFlagName, cf.Systemd,
`Run container in systemd mode ("true"|"false"|"always")`,
)
_ = cmd.RegisterFlagCompletionFunc(systemdFlagName, AutocompleteSystemdFlag)
@@ -522,7 +522,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
timezoneFlagName := "tz"
createFlags.StringVar(
&cf.Timezone,
- timezoneFlagName, containerConfig.TZ(),
+ timezoneFlagName, cf.Timezone,
"Set timezone in container",
)
_ = cmd.RegisterFlagCompletionFunc(timezoneFlagName, completion.AutocompleteNone) //TODO: add timezone completion
@@ -530,7 +530,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
umaskFlagName := "umask"
createFlags.StringVar(
&cf.Umask,
- umaskFlagName, containerConfig.Umask(),
+ umaskFlagName, cf.Umask,
"Set umask in container",
)
_ = cmd.RegisterFlagCompletionFunc(umaskFlagName, completion.AutocompleteNone)
@@ -538,7 +538,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
ulimitFlagName := "ulimit"
createFlags.StringSliceVar(
&cf.Ulimit,
- ulimitFlagName, ulimits(),
+ ulimitFlagName, cf.Ulimit,
"Ulimit options",
)
_ = cmd.RegisterFlagCompletionFunc(ulimitFlagName, completion.AutocompleteNone)
@@ -577,7 +577,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
seccompPolicyFlagName := "seccomp-policy"
createFlags.StringVar(
&cf.SeccompPolicy,
- seccompPolicyFlagName, "default",
+ seccompPolicyFlagName, cf.SeccompPolicy,
"Policy for selecting a seccomp profile (experimental)",
)
_ = cmd.RegisterFlagCompletionFunc(seccompPolicyFlagName, completion.AutocompleteDefault)
@@ -769,7 +769,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
volumeFlagName := "volume"
createFlags.StringArrayVarP(
&cf.Volume,
- volumeFlagName, "v", volumes(),
+ volumeFlagName, "v", cf.Volume,
volumeDesciption,
)
_ = cmd.RegisterFlagCompletionFunc(volumeFlagName, AutocompleteVolumeFlag)
@@ -890,12 +890,13 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
memorySwappinessFlagName := "memory-swappiness"
createFlags.Int64Var(
&cf.MemorySwappiness,
- memorySwappinessFlagName, -1,
+ memorySwappinessFlagName, cf.MemorySwappiness,
"Tune container memory swappiness (0 to 100, or -1 for system default)",
)
_ = cmd.RegisterFlagCompletionFunc(memorySwappinessFlagName, completion.AutocompleteNone)
}
// anyone can use these
+
cpusFlagName := "cpus"
createFlags.Float64Var(
&cf.CPUS,
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index ad535ff59..fb5af8f59 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -2,6 +2,8 @@ package common
import (
"github.com/containers/podman/v4/cmd/podman/registry"
+ "github.com/containers/podman/v4/libpod/define"
+ "github.com/containers/podman/v4/pkg/domain/entities"
)
func ulimits() []string {
@@ -25,7 +27,7 @@ func devices() []string {
return nil
}
-func env() []string {
+func Env() []string {
if !registry.IsRemote() {
return containerConfig.Env()
}
@@ -73,3 +75,21 @@ func LogDriver() string {
}
return ""
}
+
+// DefineCreateDefault is used to initialize ctr create options before flag initialization
+func DefineCreateDefaults(opts *entities.ContainerCreateOptions) {
+ opts.LogDriver = LogDriver()
+ opts.CgroupsMode = cgroupConfig()
+ opts.MemorySwappiness = -1
+ opts.ImageVolume = containerConfig.Engine.ImageVolumeMode
+ opts.Pull = policy()
+ opts.ReadOnlyTmpFS = true
+ opts.SdNotifyMode = define.SdNotifyModeContainer
+ opts.StopTimeout = containerConfig.Engine.StopTimeout
+ opts.Systemd = "true"
+ opts.Timezone = containerConfig.TZ()
+ opts.Umask = containerConfig.Umask()
+ opts.Ulimit = ulimits()
+ opts.SeccompPolicy = "default"
+ opts.Volume = volumes()
+}
diff --git a/cmd/podman/containers/clone.go b/cmd/podman/containers/clone.go
index 6912da1fc..2763adf3c 100644
--- a/cmd/podman/containers/clone.go
+++ b/cmd/podman/containers/clone.go
@@ -41,6 +41,7 @@ func cloneFlags(cmd *cobra.Command) {
forceFlagName := "force"
flags.BoolVarP(&ctrClone.Force, forceFlagName, "f", false, "force the existing container to be destroyed")
+ common.DefineCreateDefaults(&ctrClone.CreateOpts)
common.DefineCreateFlags(cmd, &ctrClone.CreateOpts, false, true)
}
func init() {
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 0a513c606..a214ae8aa 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -71,6 +71,7 @@ func createFlags(cmd *cobra.Command) {
)
flags.SetInterspersed(false)
+ common.DefineCreateDefaults(&cliVals)
common.DefineCreateFlags(cmd, &cliVals, false, false)
common.DefineNetFlags(cmd)
diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go
index a6c500afa..e49bdaee4 100644
--- a/cmd/podman/containers/run.go
+++ b/cmd/podman/containers/run.go
@@ -61,6 +61,7 @@ func runFlags(cmd *cobra.Command) {
flags := cmd.Flags()
flags.SetInterspersed(false)
+ common.DefineCreateDefaults(&cliVals)
common.DefineCreateFlags(cmd, &cliVals, false, false)
common.DefineNetFlags(cmd)
diff --git a/cmd/podman/pods/clone.go b/cmd/podman/pods/clone.go
new file mode 100644
index 000000000..d95d74b05
--- /dev/null
+++ b/cmd/podman/pods/clone.go
@@ -0,0 +1,87 @@
+package pods
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/containers/common/pkg/completion"
+ "github.com/containers/podman/v4/cmd/podman/common"
+ "github.com/containers/podman/v4/cmd/podman/registry"
+ "github.com/containers/podman/v4/libpod/define"
+ "github.com/containers/podman/v4/pkg/domain/entities"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+)
+
+var (
+ podCloneDescription = `Create an exact copy of a pod and the containers within it`
+
+ podCloneCommand = &cobra.Command{
+ Use: "clone [options] POD NAME",
+ Short: "Clone an existing pod",
+ Long: podCloneDescription,
+ RunE: clone,
+ Args: cobra.RangeArgs(1, 2),
+ ValidArgsFunction: common.AutocompleteClone,
+ Example: `podman pod clone pod_name new_name`,
+ }
+)
+
+var (
+ podClone entities.PodCloneOptions
+)
+
+func cloneFlags(cmd *cobra.Command) {
+ flags := cmd.Flags()
+
+ destroyFlagName := "destroy"
+ flags.BoolVar(&podClone.Destroy, destroyFlagName, false, "destroy the original pod")
+
+ startFlagName := "start"
+ flags.BoolVar(&podClone.Start, startFlagName, false, "start the new pod")
+
+ nameFlagName := "name"
+ flags.StringVarP(&podClone.CreateOpts.Name, nameFlagName, "n", "", "name the new pod")
+ _ = podCloneCommand.RegisterFlagCompletionFunc(nameFlagName, completion.AutocompleteNone)
+
+ common.DefineCreateDefaults(&podClone.InfraOptions)
+ common.DefineCreateFlags(cmd, &podClone.InfraOptions, true, false)
+ podClone.InfraOptions.MemorySwappiness = -1 // this is not implemented for pods yet, need to set -1 default manually
+
+ // need to fill an empty ctr create option for each container for sane defaults
+ // for now, these cannot be used. The flag names conflict too much
+ // this makes sense since this is a pod command not a container command
+ // TODO: add support for container specific arguments/flags
+ common.DefineCreateDefaults(&podClone.PerContainerOptions)
+}
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Command: podCloneCommand,
+ Parent: podCmd,
+ })
+
+ cloneFlags(podCloneCommand)
+}
+
+func clone(cmd *cobra.Command, args []string) error {
+ switch len(args) {
+ case 0:
+ return errors.Wrapf(define.ErrInvalidArg, "must specify at least 1 argument")
+ case 2:
+ podClone.CreateOpts.Name = args[1]
+ }
+
+ podClone.ID = args[0]
+ podClone.PerContainerOptions.IsClone = true
+ rep, err := registry.ContainerEngine().PodClone(context.Background(), podClone)
+ if err != nil {
+ if rep != nil {
+ fmt.Printf("pod %s created but error after creation\n", rep.Id)
+ }
+ return err
+ }
+
+ fmt.Println(rep.Id)
+
+ return nil
+}
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index e2f80bdbc..ca9d60174 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -64,6 +64,7 @@ func init() {
})
flags := createCommand.Flags()
flags.SetInterspersed(false)
+ common.DefineCreateDefaults(&infraOptions)
common.DefineCreateFlags(createCommand, &infraOptions, true, false)
common.DefineNetFlags(createCommand)