mirror of
https://github.com/containers/podman
synced 2024-10-22 02:03:38 +00:00
Merge pull request #6553 from vrothberg/replace
--replace for containers and pods
This commit is contained in:
commit
10c6c806ea
|
@ -373,6 +373,11 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
|
|||
"read-only-tmpfs", true,
|
||||
"When running containers in read-only mode mount a read-write tmpfs on /run, /tmp and /var/tmp",
|
||||
)
|
||||
createFlags.BoolVar(
|
||||
&cf.Replace,
|
||||
"replace", false,
|
||||
`If a container with the same name exists, replace it`,
|
||||
)
|
||||
createFlags.StringVar(
|
||||
&cf.Restart,
|
||||
"restart", "",
|
||||
|
|
|
@ -76,6 +76,7 @@ type ContainerCLIOpts struct {
|
|||
ReadOnly bool
|
||||
ReadOnlyTmpFS bool
|
||||
Restart string
|
||||
Replace bool
|
||||
Rm bool
|
||||
RootFS bool
|
||||
SecurityOpt []string
|
||||
|
|
|
@ -122,6 +122,12 @@ func create(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if cliVals.Replace {
|
||||
if err := replaceContainer(cliVals.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
report, err := registry.ContainerEngine().ContainerCreate(registry.GetContext(), s)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -138,6 +144,17 @@ func create(cmd *cobra.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func replaceContainer(name string) error {
|
||||
if len(name) == 0 {
|
||||
return errors.New("cannot replace container without --name being set")
|
||||
}
|
||||
rmOptions := entities.RmOptions{
|
||||
Force: true, // force stop & removal
|
||||
Ignore: true, // ignore errors when a container doesn't exit
|
||||
}
|
||||
return removeContainers([]string{name}, rmOptions, false)
|
||||
}
|
||||
|
||||
func createInit(c *cobra.Command) error {
|
||||
if c.Flag("privileged").Changed && c.Flag("security-opt").Changed {
|
||||
logrus.Warn("setting security options with --privileged has no effect")
|
||||
|
|
|
@ -87,6 +87,14 @@ func init() {
|
|||
}
|
||||
|
||||
func rm(cmd *cobra.Command, args []string) error {
|
||||
return removeContainers(args, rmOptions, true)
|
||||
}
|
||||
|
||||
// removeContainers will remove the specified containers (names or IDs).
|
||||
// Allows for sharing removal logic across commands. If setExit is set,
|
||||
// removeContainers will set the exit code according to the `podman-rm` man
|
||||
// page.
|
||||
func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit bool) error {
|
||||
var (
|
||||
errs utils.OutputErrors
|
||||
)
|
||||
|
@ -96,9 +104,9 @@ func rm(cmd *cobra.Command, args []string) error {
|
|||
return errors.Errorf("--storage conflicts with --volumes, --all, --latest, --ignore and --cidfile")
|
||||
}
|
||||
}
|
||||
responses, err := registry.ContainerEngine().ContainerRm(context.Background(), args, rmOptions)
|
||||
responses, err := registry.ContainerEngine().ContainerRm(context.Background(), namesOrIDs, rmOptions)
|
||||
if err != nil {
|
||||
if len(args) < 2 {
|
||||
if setExit && len(namesOrIDs) < 2 {
|
||||
setExitCode(err)
|
||||
}
|
||||
return err
|
||||
|
@ -109,7 +117,9 @@ func rm(cmd *cobra.Command, args []string) error {
|
|||
if errors.Cause(err) == define.ErrWillDeadlock {
|
||||
logrus.Errorf("Potential deadlock detected - please run 'podman system renumber' to resolve")
|
||||
}
|
||||
setExitCode(r.Err)
|
||||
if setExit {
|
||||
setExitCode(r.Err)
|
||||
}
|
||||
errs = append(errs, r.Err)
|
||||
} else {
|
||||
fmt.Println(r.Id)
|
||||
|
|
|
@ -129,6 +129,12 @@ func run(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
}
|
||||
|
||||
if cliVals.Replace {
|
||||
if err := replaceContainer(cliVals.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// If -i is not set, clear stdin
|
||||
if !cliVals.Interactive {
|
||||
runOpts.InputStream = nil
|
||||
|
|
|
@ -39,6 +39,7 @@ var (
|
|||
createOptions entities.PodCreateOptions
|
||||
labels, labelFile []string
|
||||
podIDFile string
|
||||
replace bool
|
||||
share string
|
||||
)
|
||||
|
||||
|
@ -61,6 +62,7 @@ func init() {
|
|||
flags.StringVarP(&createOptions.Name, "name", "n", "", "Assign a name to the pod")
|
||||
flags.StringVarP(&createOptions.Hostname, "hostname", "", "", "Set a hostname to the pod")
|
||||
flags.StringVar(&podIDFile, "pod-id-file", "", "Write the pod ID to the file")
|
||||
flags.BoolVar(&replace, "replace", false, "If a pod with the same exists, replace it")
|
||||
flags.StringVar(&share, "share", specgen.DefaultKernelNamespaces, "A comma delimited list of kernel namespaces the pod will share")
|
||||
flags.SetNormalizeFunc(aliasNetworkFlag)
|
||||
}
|
||||
|
@ -147,6 +149,12 @@ func create(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
}
|
||||
|
||||
if replace {
|
||||
if err := replacePod(createOptions.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
response, err := registry.ContainerEngine().PodCreate(context.Background(), createOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -159,3 +167,14 @@ func create(cmd *cobra.Command, args []string) error {
|
|||
fmt.Println(response.Id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func replacePod(name string) error {
|
||||
if len(name) == 0 {
|
||||
return errors.New("cannot replace pod without --name being set")
|
||||
}
|
||||
rmOptions := entities.PodRmOptions{
|
||||
Force: true, // stop and remove pod
|
||||
Ignore: true, // ignore if pod doesn't exist
|
||||
}
|
||||
return removePods([]string{name}, rmOptions, false)
|
||||
}
|
||||
|
|
|
@ -58,24 +58,30 @@ func init() {
|
|||
}
|
||||
|
||||
func rm(cmd *cobra.Command, args []string) error {
|
||||
var (
|
||||
errs utils.OutputErrors
|
||||
)
|
||||
|
||||
ids, err := common.ReadPodIDFiles(rmOptions.PodIDFiles)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
args = append(args, ids...)
|
||||
return removePods(args, rmOptions.PodRmOptions, true)
|
||||
}
|
||||
|
||||
responses, err := registry.ContainerEngine().PodRm(context.Background(), args, rmOptions.PodRmOptions)
|
||||
// removePods removes the specified pods (names or IDs). Allows for sharing
|
||||
// pod-removal logic across commands.
|
||||
func removePods(namesOrIDs []string, rmOptions entities.PodRmOptions, printIDs bool) error {
|
||||
var errs utils.OutputErrors
|
||||
|
||||
responses, err := registry.ContainerEngine().PodRm(context.Background(), namesOrIDs, rmOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// in the cli, first we print out all the successful attempts
|
||||
for _, r := range responses {
|
||||
if r.Err == nil {
|
||||
fmt.Println(r.Id)
|
||||
if printIDs {
|
||||
fmt.Println(r.Id)
|
||||
}
|
||||
} else {
|
||||
errs = append(errs, r.Err)
|
||||
}
|
||||
|
|
|
@ -3118,6 +3118,7 @@ _podman_pod_create() {
|
|||
--help
|
||||
-h
|
||||
--infra
|
||||
--replace
|
||||
"
|
||||
_complete_ "$options_with_args" "$boolean_options"
|
||||
}
|
||||
|
|
|
@ -662,6 +662,10 @@ its root filesystem mounted as read only prohibiting any writes.
|
|||
|
||||
If container is running in --read-only mode, then mount a read-write tmpfs on /run, /tmp, and /var/tmp. The default is *true*
|
||||
|
||||
**--replace**=**true**|**false**
|
||||
|
||||
If another container with the same name already exists, replace and remove it. The default is **false**.
|
||||
|
||||
**--restart**=*policy*
|
||||
|
||||
Restart policy to follow when containers exit.
|
||||
|
|
|
@ -102,6 +102,10 @@ Use `podman port` to see the actual mapping: `podman port CONTAINER $CONTAINERPO
|
|||
|
||||
NOTE: This cannot be modified once the pod is created.
|
||||
|
||||
**--replace**=**true**|**false**
|
||||
|
||||
If another pod with the same name already exists, replace and remove it. The default is **false**.
|
||||
|
||||
**--share**=*namespace*
|
||||
|
||||
A comma delimited list of kernel namespaces to share. If none or "" is specified, no namespaces will be shared. The namespaces to choose from are ipc, net, pid, user, uts.
|
||||
|
|
|
@ -671,6 +671,10 @@ its root filesystem mounted as read only prohibiting any writes.
|
|||
|
||||
If container is running in **--read-only** mode, then mount a read-write tmpfs on _/run_, _/tmp_, and _/var/tmp_. The default is **true**.
|
||||
|
||||
**--replace**=**true**|**false**
|
||||
|
||||
If another container with the same name already exists, replace and remove it. The default is **false**.
|
||||
|
||||
**--restart**=*policy*
|
||||
|
||||
Restart policy to follow when containers exit.
|
||||
|
|
|
@ -207,24 +207,42 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
|
|||
info.CreateCommand = filterPodFlags(info.CreateCommand)
|
||||
}
|
||||
|
||||
// Enforce detaching
|
||||
//
|
||||
// since we use systemd `Type=forking` service
|
||||
// @see https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=
|
||||
// when we generated systemd service file with the --new param,
|
||||
// `ExecStart` will have `/usr/bin/podman run ...`
|
||||
// if `info.CreateCommand` has no `-d` or `--detach` param,
|
||||
// podman will run the container in default attached mode,
|
||||
// as a result, `systemd start` will wait the `podman run` command exit until failed with timeout error.
|
||||
// Presence check for certain flags/options.
|
||||
hasDetachParam := false
|
||||
hasNameParam := false
|
||||
hasReplaceParam := false
|
||||
for _, p := range info.CreateCommand[index:] {
|
||||
if p == "--detach" || p == "-d" {
|
||||
switch p {
|
||||
case "--detach", "-d":
|
||||
hasDetachParam = true
|
||||
case "--name":
|
||||
hasNameParam = true
|
||||
case "--replace":
|
||||
hasReplaceParam = true
|
||||
}
|
||||
}
|
||||
|
||||
if !hasDetachParam {
|
||||
// Enforce detaching
|
||||
//
|
||||
// since we use systemd `Type=forking` service @see
|
||||
// https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=
|
||||
// when we generated systemd service file with the
|
||||
// --new param, `ExecStart` will have `/usr/bin/podman
|
||||
// run ...` if `info.CreateCommand` has no `-d` or
|
||||
// `--detach` param, podman will run the container in
|
||||
// default attached mode, as a result, `systemd start`
|
||||
// will wait the `podman run` command exit until failed
|
||||
// with timeout error.
|
||||
startCommand = append(startCommand, "-d")
|
||||
}
|
||||
if hasNameParam && !hasReplaceParam {
|
||||
// Enforce --replace for named containers. This will
|
||||
// make systemd units more robuts as it allows them to
|
||||
// start after system crashes (see
|
||||
// github.com/containers/libpod/issues/5485).
|
||||
startCommand = append(startCommand, "--replace")
|
||||
}
|
||||
startCommand = append(startCommand, info.CreateCommand[index:]...)
|
||||
|
||||
info.ExecStartPre = "/usr/bin/rm -f {{.PIDFile}} {{.ContainerIDFile}}"
|
||||
|
|
|
@ -103,7 +103,7 @@ Type=forking
|
|||
[Install]
|
||||
WantedBy=multi-user.target default.target`
|
||||
|
||||
goodNameNew := `# jadda-jadda.service
|
||||
goodWithNameAndGeneric := `# jadda-jadda.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
[Unit]
|
||||
|
@ -116,7 +116,30 @@ After=network-online.target
|
|||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=always
|
||||
ExecStartPre=/usr/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
|
||||
ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
|
||||
ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d --replace --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
|
||||
ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
|
||||
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
|
||||
PIDFile=%t/jadda-jadda.pid
|
||||
KillMode=none
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target default.target`
|
||||
|
||||
goodWithExplicitShortDetachParam := `# jadda-jadda.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
[Unit]
|
||||
Description=Podman jadda-jadda.service
|
||||
Documentation=man:podman-generate-systemd(1)
|
||||
Wants=network.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=always
|
||||
ExecStartPre=/usr/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
|
||||
ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon --replace -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
|
||||
ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
|
||||
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
|
||||
PIDFile=%t/jadda-jadda.pid
|
||||
|
@ -139,7 +162,7 @@ After=network-online.target
|
|||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=always
|
||||
ExecStartPre=/usr/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
|
||||
ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon --pod-id-file /tmp/pod-foobar.pod-id-file -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
|
||||
ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon --pod-id-file /tmp/pod-foobar.pod-id-file --replace -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
|
||||
ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
|
||||
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
|
||||
PIDFile=%t/jadda-jadda.pid
|
||||
|
@ -148,6 +171,7 @@ Type=forking
|
|||
|
||||
[Install]
|
||||
WantedBy=multi-user.target default.target`
|
||||
|
||||
goodNameNewDetach := `# jadda-jadda.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
|
@ -161,7 +185,7 @@ After=network-online.target
|
|||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=always
|
||||
ExecStartPre=/usr/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
|
||||
ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon --detach --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
|
||||
ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon --replace --detach --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
|
||||
ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42
|
||||
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
|
||||
PIDFile=%t/jadda-jadda.pid
|
||||
|
@ -274,7 +298,7 @@ WantedBy=multi-user.target default.target`
|
|||
CreateCommand: []string{"I'll get stripped", "container", "run", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
|
||||
EnvVariable: EnvVariable,
|
||||
},
|
||||
goodNameNew,
|
||||
goodWithNameAndGeneric,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
|
@ -290,7 +314,7 @@ WantedBy=multi-user.target default.target`
|
|||
CreateCommand: []string{"I'll get stripped", "container", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"},
|
||||
EnvVariable: EnvVariable,
|
||||
},
|
||||
goodNameNew,
|
||||
goodWithExplicitShortDetachParam,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
|
|
|
@ -265,7 +265,7 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
|
|||
if podCreateIndex == 0 {
|
||||
return "", errors.Errorf("pod does not appear to be created via `podman pod create`: %v", info.CreateCommand)
|
||||
}
|
||||
podRootArgs = info.CreateCommand[1 : podCreateIndex-2]
|
||||
podRootArgs = info.CreateCommand[0 : podCreateIndex-2]
|
||||
podCreateArgs = filterPodFlags(info.CreateCommand[podCreateIndex+1:])
|
||||
}
|
||||
// We're hard-coding the first five arguments and append the
|
||||
|
@ -277,6 +277,21 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
|
|||
"--infra-conmon-pidfile", "{{.PIDFile}}",
|
||||
"--pod-id-file", "{{.PodIDFile}}"}...)
|
||||
|
||||
// Presence check for certain flags/options.
|
||||
hasNameParam := false
|
||||
hasReplaceParam := false
|
||||
for _, p := range podCreateArgs {
|
||||
switch p {
|
||||
case "--name":
|
||||
hasNameParam = true
|
||||
case "--replace":
|
||||
hasReplaceParam = true
|
||||
}
|
||||
}
|
||||
if hasNameParam && !hasReplaceParam {
|
||||
podCreateArgs = append(podCreateArgs, "--replace")
|
||||
}
|
||||
|
||||
startCommand = append(startCommand, podCreateArgs...)
|
||||
|
||||
info.ExecStartPre1 = "/usr/bin/rm -f {{.PIDFile}} {{.PodIDFile}}"
|
||||
|
|
|
@ -36,7 +36,7 @@ func TestValidateRestartPolicyPod(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreatePodSystemdUnit(t *testing.T) {
|
||||
podGoodName := `# pod-123abc.service
|
||||
podGood := `# pod-123abc.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
[Unit]
|
||||
|
@ -56,6 +56,32 @@ PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635
|
|||
KillMode=none
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target default.target`
|
||||
|
||||
podGoodNamedNew := `# pod-123abc.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
[Unit]
|
||||
Description=Podman pod-123abc.service
|
||||
Documentation=man:podman-generate-systemd(1)
|
||||
Wants=network.target
|
||||
After=network-online.target
|
||||
Requires=container-1.service container-2.service
|
||||
Before=container-1.service container-2.service
|
||||
|
||||
[Service]
|
||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=on-failure
|
||||
ExecStartPre=/usr/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id
|
||||
ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo --replace
|
||||
ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id
|
||||
ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10
|
||||
ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id
|
||||
PIDFile=%t/pod-123abc.pid
|
||||
KillMode=none
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target default.target`
|
||||
|
||||
|
@ -63,6 +89,7 @@ WantedBy=multi-user.target default.target`
|
|||
name string
|
||||
info podInfo
|
||||
want string
|
||||
new bool
|
||||
wantErr bool
|
||||
}{
|
||||
{"pod",
|
||||
|
@ -76,7 +103,24 @@ WantedBy=multi-user.target default.target`
|
|||
PodmanVersion: "CI",
|
||||
RequiredServices: []string{"container-1", "container-2"},
|
||||
},
|
||||
podGoodName,
|
||||
podGood,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{"pod --new",
|
||||
podInfo{
|
||||
Executable: "/usr/bin/podman",
|
||||
ServiceName: "pod-123abc",
|
||||
InfraNameOrID: "jadda-jadda-infra",
|
||||
RestartPolicy: "on-failure",
|
||||
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
|
||||
StopTimeout: 10,
|
||||
PodmanVersion: "CI",
|
||||
RequiredServices: []string{"container-1", "container-2"},
|
||||
CreateCommand: []string{"podman", "pod", "create", "--name", "foo"},
|
||||
},
|
||||
podGoodNamedNew,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
@ -86,6 +130,7 @@ WantedBy=multi-user.target default.target`
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
opts := entities.GenerateSystemdOptions{
|
||||
Files: false,
|
||||
New: test.new,
|
||||
}
|
||||
got, err := executePodTemplate(&test.info, opts)
|
||||
if (err != nil) != test.wantErr {
|
||||
|
|
|
@ -429,4 +429,19 @@ var _ = Describe("Podman create", func() {
|
|||
Expect(len(data)).To(Equal(1))
|
||||
Expect(data[0].HostConfig.NanoCpus).To(Equal(int64(nanoCPUs)))
|
||||
})
|
||||
|
||||
It("podman create --replace", func() {
|
||||
// Make sure we error out with --name.
|
||||
session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(125))
|
||||
|
||||
// Create and replace 5 times in a row the "same" container.
|
||||
ctrName := "testCtr"
|
||||
for i := 0; i < 5; i++ {
|
||||
session = podmanTest.Podman([]string{"create", "--replace", "--name", ctrName, ALPINE, "/bin/sh"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
@ -305,4 +305,19 @@ var _ = Describe("Podman pod create", func() {
|
|||
data := check.InspectPodToJSON()
|
||||
Expect(data.ID).To(Equal(string(id)))
|
||||
})
|
||||
|
||||
It("podman pod create --replace", func() {
|
||||
// Make sure we error out with --name.
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--replace", ALPINE, "/bin/sh"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(125))
|
||||
|
||||
// Create and replace 5 times in a row the "same" pod.
|
||||
podName := "testCtr"
|
||||
for i := 0; i < 5; i++ {
|
||||
session = podmanTest.Podman([]string{"pod", "create", "--replace", "--name", podName})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
@ -931,4 +931,19 @@ USER mail`
|
|||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
})
|
||||
|
||||
It("podman run --replace", func() {
|
||||
// Make sure we error out with --name.
|
||||
session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(125))
|
||||
|
||||
// Run and replace 5 times in a row the "same" container.
|
||||
ctrName := "testCtr"
|
||||
for i := 0; i < 5; i++ {
|
||||
session := podmanTest.Podman([]string{"run", "--detach", "--replace", "--name", ctrName, ALPINE, "/bin/sh"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue