mirror of
https://github.com/containers/podman.git
synced 2025-06-22 18:08:11 +08:00
Merge pull request #15060 from rhatdan/rm1
With --rm option remove container if podman run fails
This commit is contained in:
@ -1061,6 +1061,15 @@ func (ic *ContainerEngine) Diff(ctx context.Context, namesOrIDs []string, opts e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.ContainerRunOptions) (*entities.ContainerRunReport, error) {
|
func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.ContainerRunOptions) (*entities.ContainerRunReport, error) {
|
||||||
|
removeContainer := func(ctr *libpod.Container, force bool) error {
|
||||||
|
var timeout *uint
|
||||||
|
if err := ic.Libpod.RemoveContainer(ctx, ctr, force, true, timeout); err != nil {
|
||||||
|
logrus.Debugf("unable to remove container %s after failing to start and attach to it: %v", ctr.ID(), err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
warn, err := generate.CompleteSpec(ctx, ic.Libpod, opts.Spec)
|
warn, err := generate.CompleteSpec(ctx, ic.Libpod, opts.Spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1081,6 +1090,8 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
|
|
||||||
if opts.CIDFile != "" {
|
if opts.CIDFile != "" {
|
||||||
if err := util.CreateCidFile(opts.CIDFile, ctr.ID()); err != nil {
|
if err := util.CreateCidFile(opts.CIDFile, ctr.ID()); err != nil {
|
||||||
|
// If you fail to create CIDFile then remove the container
|
||||||
|
_ = removeContainer(ctr, true)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1098,6 +1109,11 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
if err := ctr.Start(ctx, true); err != nil {
|
if err := ctr.Start(ctx, true); err != nil {
|
||||||
// This means the command did not exist
|
// This means the command did not exist
|
||||||
report.ExitCode = define.ExitCode(err)
|
report.ExitCode = define.ExitCode(err)
|
||||||
|
if opts.Rm {
|
||||||
|
if rmErr := removeContainer(ctr, true); rmErr != nil && !errors.Is(rmErr, define.ErrNoSuchCtr) {
|
||||||
|
logrus.Errorf("Container %s failed to be removed", ctr.ID())
|
||||||
|
}
|
||||||
|
}
|
||||||
return &report, err
|
return &report, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1114,10 +1130,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
return &report, nil
|
return &report, nil
|
||||||
}
|
}
|
||||||
if opts.Rm {
|
if opts.Rm {
|
||||||
var timeout *uint
|
_ = removeContainer(ctr, true)
|
||||||
if deleteError := ic.Libpod.RemoveContainer(ctx, ctr, true, false, timeout); deleteError != nil {
|
|
||||||
logrus.Debugf("unable to remove container %s after failing to start and attach to it", ctr.ID())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if errors.Is(err, define.ErrWillDeadlock) {
|
if errors.Is(err, define.ErrWillDeadlock) {
|
||||||
logrus.Debugf("Deadlock error on %q: %v", ctr.ID(), err)
|
logrus.Debugf("Deadlock error on %q: %v", ctr.ID(), err)
|
||||||
@ -1129,8 +1142,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
}
|
}
|
||||||
report.ExitCode = ic.GetContainerExitCode(ctx, ctr)
|
report.ExitCode = ic.GetContainerExitCode(ctx, ctr)
|
||||||
if opts.Rm && !ctr.ShouldRestart(ctx) {
|
if opts.Rm && !ctr.ShouldRestart(ctx) {
|
||||||
var timeout *uint
|
if err := removeContainer(ctr, false); err != nil {
|
||||||
if err := ic.Libpod.RemoveContainer(ctx, ctr, false, true, timeout); err != nil {
|
|
||||||
if errors.Is(err, define.ErrNoSuchCtr) ||
|
if errors.Is(err, define.ErrNoSuchCtr) ||
|
||||||
errors.Is(err, define.ErrCtrRemoved) {
|
errors.Is(err, define.ErrCtrRemoved) {
|
||||||
logrus.Infof("Container %s was already removed, skipping --rm", ctr.ID())
|
logrus.Infof("Container %s was already removed, skipping --rm", ctr.ID())
|
||||||
|
@ -787,8 +787,17 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
for _, w := range con.Warnings {
|
for _, w := range con.Warnings {
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", w)
|
fmt.Fprintf(os.Stderr, "%s\n", w)
|
||||||
}
|
}
|
||||||
|
removeContainer := func(id string, force bool) error {
|
||||||
|
removeOptions := new(containers.RemoveOptions).WithVolumes(true).WithForce(force)
|
||||||
|
reports, err := containers.Remove(ic.ClientCtx, id, removeOptions)
|
||||||
|
logIfRmError(id, err, reports)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if opts.CIDFile != "" {
|
if opts.CIDFile != "" {
|
||||||
if err := util.CreateCidFile(opts.CIDFile, con.ID); err != nil {
|
if err := util.CreateCidFile(opts.CIDFile, con.ID); err != nil {
|
||||||
|
// If you fail to create CIDFile then remove the container
|
||||||
|
_ = removeContainer(con.ID, true)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -800,6 +809,11 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
err := containers.Start(ic.ClientCtx, con.ID, new(containers.StartOptions).WithRecursive(true))
|
err := containers.Start(ic.ClientCtx, con.ID, new(containers.StartOptions).WithRecursive(true))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
report.ExitCode = define.ExitCode(err)
|
report.ExitCode = define.ExitCode(err)
|
||||||
|
if opts.Rm {
|
||||||
|
if rmErr := removeContainer(con.ID, true); rmErr != nil && !errors.Is(rmErr, define.ErrNoSuchCtr) {
|
||||||
|
logrus.Errorf("Container %s failed to be removed", con.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &report, err
|
return &report, err
|
||||||
}
|
}
|
||||||
@ -812,10 +826,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
|
|
||||||
report.ExitCode = define.ExitCode(err)
|
report.ExitCode = define.ExitCode(err)
|
||||||
if opts.Rm {
|
if opts.Rm {
|
||||||
reports, rmErr := containers.Remove(ic.ClientCtx, con.ID, new(containers.RemoveOptions).WithForce(false).WithVolumes(true))
|
_ = removeContainer(con.ID, false)
|
||||||
if rmErr != nil || reports[0].Err != nil {
|
|
||||||
logrus.Debugf("unable to remove container %s after failing to start and attach to it", con.ID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return &report, err
|
return &report, err
|
||||||
}
|
}
|
||||||
@ -831,8 +842,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !shouldRestart {
|
if !shouldRestart {
|
||||||
reports, err := containers.Remove(ic.ClientCtx, con.ID, new(containers.RemoveOptions).WithForce(false).WithVolumes(true))
|
_ = removeContainer(con.ID, false)
|
||||||
logIfRmError(con.ID, err, reports)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -871,4 +871,20 @@ EOF
|
|||||||
run_podman container rm -fa
|
run_podman container rm -fa
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "podman run failed --rm " {
|
||||||
|
port=$(random_free_port)
|
||||||
|
|
||||||
|
# Run two containers with the same port bindings. The second must fail
|
||||||
|
run_podman run -p $port:80 --rm -d --name c_ok $IMAGE top
|
||||||
|
run_podman 126 run -p $port:80 -d --name c_fail_no_rm $IMAGE top
|
||||||
|
run_podman 126 run -p $port:80 --rm -d --name c_fail_with_rm $IMAGE top
|
||||||
|
# Prior to #15060, the third container would still show up in ps -a
|
||||||
|
run_podman ps -a --sort names --format '{{.Image}}--{{.Names}}'
|
||||||
|
is "$output" "$IMAGE--c_fail_no_rm
|
||||||
|
$IMAGE--c_ok" \
|
||||||
|
"podman ps -a shows running & failed containers, but not failed-with-rm"
|
||||||
|
|
||||||
|
run_podman container rm -f -t 0 c_ok c_fail_no_rm
|
||||||
|
}
|
||||||
|
|
||||||
# vim: filetype=sh
|
# vim: filetype=sh
|
||||||
|
Reference in New Issue
Block a user