Merge pull request #7891 from rhatdan/rm

This PR allows users to remove external containers directly
This commit is contained in:
OpenShift Merge Robot
2020-10-09 10:55:15 -04:00
committed by GitHub
10 changed files with 40 additions and 35 deletions

View File

@ -57,13 +57,12 @@ func rmFlags(flags *pflag.FlagSet) {
flags.BoolVarP(&rmOptions.All, "all", "a", false, "Remove all containers")
flags.BoolVarP(&rmOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing")
flags.BoolVarP(&rmOptions.Force, "force", "f", false, "Force removal of a running or unusable container. The default is false")
flags.BoolVar(&rmOptions.Storage, "storage", false, "Remove container from storage library")
flags.BoolVarP(&rmOptions.Volumes, "volumes", "v", false, "Remove anonymous volumes associated with the container")
flags.StringArrayVarP(&rmOptions.CIDFiles, "cidfile", "", nil, "Read the container ID from the file")
if registry.IsRemote() {
_ = flags.MarkHidden("ignore")
_ = flags.MarkHidden("cidfile")
if !registry.IsRemote() {
// This option is deprecated, but needs to still exists for backwards compatibility
flags.Bool("storage", false, "Remove container from storage library")
_ = flags.MarkHidden("storage")
}
}
@ -97,12 +96,6 @@ func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit
var (
errs utils.OutputErrors
)
// Storage conflicts with --all/--latest/--volumes/--cidfile/--ignore
if rmOptions.Storage {
if rmOptions.All || rmOptions.Ignore || rmOptions.Latest || rmOptions.Volumes || rmOptions.CIDFiles != nil {
return errors.Errorf("--storage conflicts with --volumes, --all, --latest, --ignore and --cidfile")
}
}
responses, err := registry.ContainerEngine().ContainerRm(context.Background(), namesOrIDs, rmOptions)
if err != nil {
if setExit {

View File

@ -43,13 +43,6 @@ to run containers such as CRI-O, the last started container could be from either
The latest option is not supported on the remote client.
**--storage**
Remove external containers from the storage library.
This is only possible with containers that are not present in libpod can be seen by **podman ps --all --storage**).
It is used to remove external containers from **podman build** and **buildah**, and orphan containers which were only partially removed by **podman rm**.
The storage option conflicts with the **--all**, **--latest**, and **--volumes** options.
**--volumes**, **-v**
Remove anonymous volumes associated with the container. This does not include named volumes
@ -96,7 +89,7 @@ $ podman rm -f --latest
**125** The command fails for any other reason
## SEE ALSO
podman(1), podman-image-rm(1), podman-ps(1), podman-build(1)
podman(1), podman-image-rm(1), podman-ps(1), podman-build(1), buildah(1), cri-o(1)
## HISTORY
August 2017, Originally compiled by Ryan Cole <rycole@redhat.com>

View File

@ -131,7 +131,6 @@ type RmOptions struct {
Force bool
Ignore bool
Latest bool
Storage bool
Volumes bool
}

View File

@ -273,16 +273,6 @@ func (ic *ContainerEngine) ContainerRestart(ctx context.Context, namesOrIds []st
func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, options entities.RmOptions) ([]*entities.RmReport, error) {
reports := []*entities.RmReport{}
if options.Storage {
for _, ctr := range namesOrIds {
report := entities.RmReport{Id: ctr}
if err := ic.Libpod.RemoveStorageContainer(ctr, options.Force); err != nil {
report.Err = err
}
reports = append(reports, &report)
}
return reports, nil
}
names := namesOrIds
for _, cidFile := range options.CIDFiles {
@ -294,6 +284,22 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
names = append(names, id)
}
// Attempt to remove named containers directly from storage, if container is defined in libpod
// this will fail and code will fall through to removing the container from libpod.`
tmpNames := []string{}
for _, ctr := range names {
report := entities.RmReport{Id: ctr}
if err := ic.Libpod.RemoveStorageContainer(ctr, options.Force); err != nil {
// remove container names that we successfully deleted
tmpNames = append(tmpNames, ctr)
} else {
reports = append(reports, &report)
}
}
if len(tmpNames) < len(names) {
names = tmpNames
}
ctrs, err := getContainersByContext(options.All, options.Latest, names, ic.Libpod)
if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr) {
// Failed to get containers. If force is specified, get the containers ID
@ -302,7 +308,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
return nil, err
}
for _, ctr := range namesOrIds {
for _, ctr := range names {
logrus.Debugf("Evicting container %q", ctr)
report := entities.RmReport{Id: ctr}
id, err := ic.Libpod.EvictContainer(ctx, ctr, options.Volumes)

View File

@ -206,7 +206,7 @@ t POST containers/${cid_top}/stop "" 204
t DELETE containers/$cid 204
t DELETE containers/$cid_top 204
# test the apiv2 create, should't ignore the ENV and WORKDIR from the image
# test the apiv2 create, shouldn't ignore the ENV and WORKDIR from the image
t POST containers/create '"Image":"'$ENV_WORKDIR_IMG'","Env":["testKey1"]' 201 \
.Id~[0-9a-f]\\{64\\}
cid=$(jq -r '.Id' <<<"$output")

View File

@ -28,7 +28,7 @@ func removeConf(confPath string) {
// generateNetworkConfig generates a cni config with a random name
// it returns the network name and the filepath
func generateNetworkConfig(p *PodmanTestIntegration) (string, string) {
// generate a random name to preven conflicts with other tests
// generate a random name to prevent conflicts with other tests
name := "net" + stringid.GenerateNonCryptoID()
path := filepath.Join(p.CNIConfigDir, fmt.Sprintf("%s.conflist", name))
conf := fmt.Sprintf(`{

View File

@ -769,7 +769,7 @@ var _ = Describe("Podman generate kube", func() {
It("podman play kube test restartPolicy", func() {
// podName, set, expect
testSli := [][]string{
{"testPod1", "", "always"}, // Default eqaul to always
{"testPod1", "", "always"}, // Default equal to always
{"testPod2", "Always", "always"},
{"testPod3", "OnFailure", "on-failure"},
{"testPod4", "Never", "no"},

View File

@ -236,7 +236,6 @@ var _ = Describe("Podman rm", func() {
})
It("podman rm --ignore bogus container and a running container", func() {
session := podmanTest.RunTopContainer("test1")
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))

View File

@ -394,7 +394,7 @@ USER bin`
})
It("podman run sysctl test", func() {
SkipIfRootless("Network sysctls are not avalable root rootless")
SkipIfRootless("Network sysctls are not available root rootless")
session := podmanTest.Podman([]string{"run", "--rm", "--sysctl", "net.core.somaxconn=65535", ALPINE, "sysctl", "net.core.somaxconn"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))

View File

@ -33,6 +33,21 @@ load helpers
run_podman rm -f $cid
}
@test "podman rm container from storage" {
if is_remote; then
skip "only applicable for local podman"
fi
rand=$(random_string 30)
run_podman create --name $rand $IMAGE /bin/true
# Create a container that podman does not know about
run buildah from $IMAGE
cid="$output"
# rm should succeed
run_podman rm $rand $cid
}
# I'm sorry! This test takes 13 seconds. There's not much I can do about it,
# please know that I think it's justified: podman 1.5.0 had a strange bug
# in with exit status was not preserved on some code paths with 'rm -f'