mirror of
https://github.com/containers/podman.git
synced 2025-06-22 18:08:11 +08:00
podman kube play --replace should force removal of pods and containers
Fixes: https://github.com/containers/podman/issues/20025 Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
@ -25,6 +25,7 @@ func KubePlay(w http.ResponseWriter, r *http.Request) {
|
||||
Network []string `schema:"network"`
|
||||
NoHosts bool `schema:"noHosts"`
|
||||
NoTrunc bool `schema:"noTrunc"`
|
||||
Replace bool `schema:"replace"`
|
||||
PublishPorts []string `schema:"publishPorts"`
|
||||
ServiceContainer bool `schema:"serviceContainer"`
|
||||
Start bool `schema:"start"`
|
||||
@ -97,6 +98,7 @@ func KubePlay(w http.ResponseWriter, r *http.Request) {
|
||||
Password: password,
|
||||
PublishPorts: query.PublishPorts,
|
||||
Quiet: true,
|
||||
Replace: query.Replace,
|
||||
ServiceContainer: query.ServiceContainer,
|
||||
StaticIPs: staticIPs,
|
||||
StaticMACs: staticMACs,
|
||||
|
@ -17,31 +17,53 @@ func (s *APIServer) registerKubeHandlers(r *mux.Router) error {
|
||||
// description: Create and run pods based on a Kubernetes YAML file (pod or service kind).
|
||||
// parameters:
|
||||
// - in: query
|
||||
// name: logDriver
|
||||
// type: string
|
||||
// description: Logging driver for the containers in the pod.
|
||||
// - in: query
|
||||
// name: logOptions
|
||||
// type: array
|
||||
// description: logging driver options
|
||||
// items:
|
||||
// type: string
|
||||
// - in: query
|
||||
// name: network
|
||||
// type: array
|
||||
// description: USe the network mode or specify an array of networks.
|
||||
// items:
|
||||
// type: string
|
||||
// - in: query
|
||||
// name: tlsVerify
|
||||
// name: noHosts
|
||||
// type: boolean
|
||||
// default: true
|
||||
// description: Require HTTPS and verify signatures when contacting registries.
|
||||
// default: false
|
||||
// description: do not setup /etc/hosts file in container
|
||||
// - in: query
|
||||
// name: logDriver
|
||||
// name: noTrunc
|
||||
// type: boolean
|
||||
// default: false
|
||||
// description: use annotations that are not truncated to the Kubernetes maximum length of 63 characters
|
||||
// - in: query
|
||||
// name: publishPorts
|
||||
// type: array
|
||||
// description: publish a container's port, or a range of ports, to the host
|
||||
// items:
|
||||
// type: string
|
||||
// description: Logging driver for the containers in the pod.
|
||||
// - in: query
|
||||
// name: start
|
||||
// name: replace
|
||||
// type: boolean
|
||||
// default: true
|
||||
// description: Start the pod after creating it.
|
||||
// default: false
|
||||
// description: replace existing pods and containers
|
||||
// - in: query
|
||||
// name: serviceContainer
|
||||
// type: boolean
|
||||
// default: false
|
||||
// description: Starts a service container before all pods.
|
||||
// - in: query
|
||||
// name: start
|
||||
// type: boolean
|
||||
// default: true
|
||||
// description: Start the pod after creating it.
|
||||
// - in: query
|
||||
// name: staticIPs
|
||||
// type: array
|
||||
// description: Static IPs used for the pods.
|
||||
@ -54,19 +76,19 @@ func (s *APIServer) registerKubeHandlers(r *mux.Router) error {
|
||||
// items:
|
||||
// type: string
|
||||
// - in: query
|
||||
// name: wait
|
||||
// name: tlsVerify
|
||||
// type: boolean
|
||||
// default: false
|
||||
// description: Clean up all objects created when a SIGTERM is received or pods exit.
|
||||
// - in: query
|
||||
// name: noTrunc
|
||||
// type: boolean
|
||||
// default: false
|
||||
// description: use annotations that are not truncated to the Kubernetes maximum length of 63 characters
|
||||
// default: true
|
||||
// description: Require HTTPS and verify signatures when contacting registries.
|
||||
// - in: query
|
||||
// name: userns
|
||||
// type: string
|
||||
// description: Set the user namespace mode for the pods.
|
||||
// - in: query
|
||||
// name: wait
|
||||
// type: boolean
|
||||
// default: false
|
||||
// description: Clean up all objects created when a SIGTERM is received or pods exit.
|
||||
// - in: body
|
||||
// name: request
|
||||
// description: Kubernetes YAML file.
|
||||
|
@ -42,6 +42,8 @@ type PlayOptions struct {
|
||||
LogDriver *string
|
||||
// LogOptions for the container. For example: journald
|
||||
LogOptions *[]string
|
||||
// Replace - replace existing pods and containers
|
||||
Replace *bool
|
||||
// Start - don't start the pod if false
|
||||
Start *bool
|
||||
// NoTrunc - use annotations that were not truncated to the
|
||||
|
@ -258,6 +258,21 @@ func (o *PlayOptions) GetLogOptions() []string {
|
||||
return *o.LogOptions
|
||||
}
|
||||
|
||||
// WithReplace set field Replace to given value
|
||||
func (o *PlayOptions) WithReplace(value bool) *PlayOptions {
|
||||
o.Replace = &value
|
||||
return o
|
||||
}
|
||||
|
||||
// GetReplace returns value of field Replace
|
||||
func (o *PlayOptions) GetReplace() bool {
|
||||
if o.Replace == nil {
|
||||
var z bool
|
||||
return z
|
||||
}
|
||||
return *o.Replace
|
||||
}
|
||||
|
||||
// WithStart set field Start to given value
|
||||
func (o *PlayOptions) WithStart(value bool) *PlayOptions {
|
||||
o.Start = &value
|
||||
|
@ -109,6 +109,12 @@ func (ic *ContainerEngine) createServiceContainer(ctx context.Context, name stri
|
||||
// via the `sdNotifyAnnotation` annotation in the K8s YAML.
|
||||
opts = append(opts, libpod.WithSdNotifyMode(define.SdNotifyModeIgnore))
|
||||
|
||||
if options.Replace {
|
||||
if _, err := ic.ContainerRm(ctx, []string{spec.Name}, entities.RmOptions{Force: true, Ignore: true}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new libpod container based on the spec.
|
||||
ctr, err := ic.Libpod.NewContainer(ctx, runtimeSpec, spec, false, opts...)
|
||||
if err != nil {
|
||||
@ -813,6 +819,12 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
|
||||
return nil, nil, err
|
||||
}
|
||||
opts = append(opts, libpod.WithSdNotifyMode(define.SdNotifyModeIgnore))
|
||||
if options.Replace {
|
||||
if _, err := ic.ContainerRm(ctx, []string{spec.Name}, entities.RmOptions{Force: true, Ignore: true}); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
ctr, err := generate.ExecuteCreate(ctx, ic.Libpod, rtSpec, spec, false, opts...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@ -913,6 +925,12 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
|
||||
opts = append(opts, libpod.WithSdNotifySocket(proxy.SocketPath()))
|
||||
}
|
||||
|
||||
if options.Replace {
|
||||
if _, err := ic.ContainerRm(ctx, []string{spec.Name}, entities.RmOptions{Force: true, Ignore: true}); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
ctr, err := generate.ExecuteCreate(ctx, ic.Libpod, rtSpec, spec, false, opts...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@ -1516,7 +1534,7 @@ func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, body io.Reader, opt
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reports.RmReport, err = ic.PodRm(ctx, podNames, entities.PodRmOptions{Ignore: true})
|
||||
reports.RmReport, err = ic.PodRm(ctx, podNames, entities.PodRmOptions{Ignore: true, Force: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, opts en
|
||||
options := new(kube.PlayOptions).WithAuthfile(opts.Authfile).WithUsername(opts.Username).WithPassword(opts.Password)
|
||||
options.WithCertDir(opts.CertDir).WithQuiet(opts.Quiet).WithSignaturePolicy(opts.SignaturePolicy).WithConfigMaps(opts.ConfigMaps)
|
||||
options.WithLogDriver(opts.LogDriver).WithNetwork(opts.Networks).WithSeccompProfileRoot(opts.SeccompProfileRoot)
|
||||
options.WithStaticIPs(opts.StaticIPs).WithStaticMACs(opts.StaticMACs).WithWait(opts.Wait).WithServiceContainer(opts.ServiceContainer)
|
||||
options.WithStaticIPs(opts.StaticIPs).WithStaticMACs(opts.StaticMACs).WithWait(opts.Wait).WithServiceContainer(opts.ServiceContainer).WithReplace(opts.Replace)
|
||||
if len(opts.LogOptions) > 0 {
|
||||
options.WithLogOptions(opts.LogOptions)
|
||||
}
|
||||
|
@ -411,6 +411,27 @@ _EOF
|
||||
run_podman rmi -f userimage:latest
|
||||
}
|
||||
|
||||
# Ocassionaly a remnant storage container is left behind which causes
|
||||
# podman play kube --replace to fail. This tests created a conflicting
|
||||
# storage container name using buildah to make sure --replace, still
|
||||
# functions proplery by removing the storage container.
|
||||
@test "podman kube play --replace external storage" {
|
||||
TESTDIR=$PODMAN_TMPDIR/testdir
|
||||
mkdir -p $TESTDIR
|
||||
echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
|
||||
run_podman play kube $PODMAN_TMPDIR/test.yaml
|
||||
# Force removal of container
|
||||
run_podman rm --force -t0 test_pod-test
|
||||
# Create external container using buildah with same name
|
||||
buildah from --name test_pod-test $IMAGE
|
||||
# --replace deletes the buildah container and replace it with new one
|
||||
run_podman play kube --replace $PODMAN_TMPDIR/test.yaml
|
||||
|
||||
run_podman stop -a -t 0
|
||||
run_podman pod rm -t 0 -f test_pod
|
||||
run_podman rmi -f userimage:latest
|
||||
}
|
||||
|
||||
@test "podman kube --annotation" {
|
||||
TESTDIR=$PODMAN_TMPDIR/testdir
|
||||
RANDOMSTRING=$(random_string 15)
|
||||
|
Reference in New Issue
Block a user