mirror of
https://github.com/containers/podman.git
synced 2025-05-17 15:18:43 +08:00
pod create --replace
Add a `--replace` flag to the `pod create` command. If another pod with the same name already exists, it will be replaced and removed. Adding this flag is motivated by #5485 to make running Podman in systemd units (or any other scripts/automation) more robust. In case of a crash, a pod may not be removed by a sytemd unit anymore. The `--replace` flag allows for supporting crashes. Note that the `--replace` flag does not require the `--name` flag to be set, so it can be set unconditionally in `podman generate systemd`. Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
@ -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"
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user