aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml4
-rw-r--r--cmd/podman/containers/start.go20
-rw-r--r--cmd/podman/images/rm.go1
-rw-r--r--contrib/cirrus/CIModes.md10
-rw-r--r--docs/source/markdown/podman-rmi.1.md3
-rwxr-xr-xhack/markdown-preprocess18
-rw-r--r--pkg/api/handlers/libpod/images.go3
-rw-r--r--pkg/bindings/images/types.go2
-rw-r--r--pkg/bindings/images/types_remove_options.go15
-rw-r--r--pkg/domain/entities/images.go2
-rw-r--r--pkg/domain/infra/abi/containers.go46
-rw-r--r--pkg/domain/infra/abi/images.go3
-rw-r--r--pkg/domain/infra/tunnel/containers.go31
-rw-r--r--pkg/domain/infra/tunnel/helpers.go11
-rw-r--r--pkg/domain/infra/tunnel/images.go2
-rw-r--r--pkg/machine/wsl/machine.go16
-rw-r--r--podman.spec.rpkg1
-rw-r--r--test/e2e/rmi_test.go78
-rw-r--r--test/e2e/start_test.go39
19 files changed, 210 insertions, 95 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 32771cb88..bf8dc5e25 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -308,6 +308,7 @@ bindings_task:
only_if: >-
$CIRRUS_PR != '' &&
$CIRRUS_CHANGE_TITLE !=~ '.*CI:DOCS.*' &&
+ $CIRRUS_CHANGE_TITLE !=~ '.*CI:COPR.*' &&
$CIRRUS_CHANGE_TITLE !=~ '.*CI:BUILD.*'
depends_on:
- build
@@ -483,6 +484,7 @@ docker-py_test_task:
only_if: &not_tag_branch_build_docs >-
$CIRRUS_PR != '' &&
$CIRRUS_CHANGE_TITLE !=~ '.*CI:DOCS.*' &&
+ $CIRRUS_CHANGE_TITLE !=~ '.*CI:COPR.*' &&
$CIRRUS_CHANGE_TITLE !=~ '.*CI:BUILD.*'
depends_on:
@@ -720,6 +722,7 @@ local_system_test_task: &local_system_test_task
only_if: &not_tag_build_docs_multiarch >-
$CIRRUS_TAG == '' &&
$CIRRUS_CHANGE_TITLE !=~ '.*CI:DOCS.*' &&
+ $CIRRUS_CHANGE_TITLE !=~ '.*CI:COPR.*' &&
$CIRRUS_CHANGE_TITLE !=~ '.*CI:BUILD.*' &&
$CIRRUS_CRON != 'multiarch'
depends_on:
@@ -1036,6 +1039,7 @@ artifacts_task:
# Docs: ./contrib/cirrus/CIModes.md
only_if: >-
$CIRRUS_CHANGE_TITLE !=~ '.*CI:DOCS.*' &&
+ $CIRRUS_CHANGE_TITLE !=~ '.*CI:COPR.*' &&
$CIRRUS_CRON != 'multiarch'
depends_on:
- success
diff --git a/cmd/podman/containers/start.go b/cmd/podman/containers/start.go
index cd4fa17b8..fc3488e0c 100644
--- a/cmd/podman/containers/start.go
+++ b/cmd/podman/containers/start.go
@@ -59,8 +59,10 @@ func startFlags(cmd *cobra.Command) {
flags.BoolVarP(&startOptions.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached")
flags.BoolVar(&startOptions.SigProxy, "sig-proxy", false, "Proxy received signals to the process (default true if attaching, false otherwise)")
- flags.StringSliceVarP(&filters, "filter", "f", []string{}, "Filter output based on conditions given")
- _ = cmd.RegisterFlagCompletionFunc("filter", common.AutocompletePsFilters)
+
+ filterFlagName := "filter"
+ flags.StringSliceVarP(&filters, filterFlagName, "f", []string{}, "Filter output based on conditions given")
+ _ = cmd.RegisterFlagCompletionFunc(filterFlagName, common.AutocompletePsFilters)
flags.BoolVar(&startOptions.All, "all", false, "Start all containers regardless of their state or configuration")
@@ -84,7 +86,7 @@ func init() {
}
func validateStart(cmd *cobra.Command, args []string) error {
- if len(args) == 0 && !startOptions.Latest && !startOptions.All {
+ if len(args) == 0 && !startOptions.Latest && !startOptions.All && len(filters) < 1 {
return errors.New("start requires at least one argument")
}
if startOptions.All && startOptions.Latest {
@@ -123,14 +125,12 @@ func start(cmd *cobra.Command, args []string) error {
}
containers := args
- if len(filters) > 0 {
- for _, f := range filters {
- split := strings.SplitN(f, "=", 2)
- if len(split) == 1 {
- return fmt.Errorf("invalid filter %q", f)
- }
- startOptions.Filters[split[0]] = append(startOptions.Filters[split[0]], split[1])
+ for _, f := range filters {
+ split := strings.SplitN(f, "=", 2)
+ if len(split) < 2 {
+ return fmt.Errorf("invalid filter %q", f)
}
+ startOptions.Filters[split[0]] = append(startOptions.Filters[split[0]], split[1])
}
responses, err := registry.ContainerEngine().ContainerStart(registry.GetContext(), containers, startOptions)
diff --git a/cmd/podman/images/rm.go b/cmd/podman/images/rm.go
index d3fd17440..4e4b001ad 100644
--- a/cmd/podman/images/rm.go
+++ b/cmd/podman/images/rm.go
@@ -61,6 +61,7 @@ func imageRemoveFlagSet(flags *pflag.FlagSet) {
flags.BoolVarP(&imageOpts.All, "all", "a", false, "Remove all images")
flags.BoolVarP(&imageOpts.Ignore, "ignore", "i", false, "Ignore errors if a specified image does not exist")
flags.BoolVarP(&imageOpts.Force, "force", "f", false, "Force Removal of the image")
+ flags.BoolVar(&imageOpts.NoPrune, "no-prune", false, "Do not remove dangling images")
}
func rm(cmd *cobra.Command, args []string) error {
diff --git a/contrib/cirrus/CIModes.md b/contrib/cirrus/CIModes.md
index c782ca64b..0b5a189a6 100644
--- a/contrib/cirrus/CIModes.md
+++ b/contrib/cirrus/CIModes.md
@@ -85,6 +85,16 @@ of this document, it's not possible to override the behavior of `$CIRRUS_PR`.
+ meta
+ success
+### Intended `[CI:COPR]` PR Tasks:
++ ext_svc_check
++ automation
++ *build*
++ validate
++ swagger
++ consistency
++ meta
++ success
+
### Intend `[CI:BUILD]` PR Tasks:
+ ext_svc_check
+ automation
diff --git a/docs/source/markdown/podman-rmi.1.md b/docs/source/markdown/podman-rmi.1.md
index 8d0e5e500..93658daaf 100644
--- a/docs/source/markdown/podman-rmi.1.md
+++ b/docs/source/markdown/podman-rmi.1.md
@@ -28,6 +28,9 @@ This option will cause podman to remove all containers that are using the image
If a specified image does not exist in the local storage, ignore it and do not throw an error.
+#### **--no-prune**
+
+This options will not remove dangling parents of specified image
Remove an image by its short ID
```
diff --git a/hack/markdown-preprocess b/hack/markdown-preprocess
index 6d2675cc4..4bc67a819 100755
--- a/hack/markdown-preprocess
+++ b/hack/markdown-preprocess
@@ -46,21 +46,19 @@ def process(infile):
if line.startswith('@@option '):
_, optionname = line.strip().split(" ")
optionfile = os.path.join("options", optionname + '.md')
- fh_out.write("[//]: # (BEGIN included file " + optionfile + ")\n")
+
+ # Comment intended to help someone viewing the .md file.
+ # Leading newline is important because if two lines are
+ # consecutive without a break, sphinx (but not go-md2man)
+ # treats them as one line and will unwantedly render the
+ # comment in its output.
+ fh_out.write("\n[//]: # (BEGIN included file " + optionfile + ")\n")
with open(optionfile, 'r') as fh_optfile:
for opt_line in fh_optfile:
opt_line = opt_line.replace('<POD-OR-CONTAINER>', pod_or_container)
opt_line = opt_line.replace('<SUBCOMMAND>', subcommand)
fh_out.write(opt_line)
-
- # Weird special case: options/image-volume.md ends in a
- # list, and in markdown lists are continued across lines,
- # so without an intervening blank line the '[//]' comment
- # becomes part of the final list entry.
- if opt_line.startswith('-'):
- fh_out.write("\n")
-
- fh_out.write("[//]: # (END included file " + optionfile + ")\n")
+ fh_out.write("\n[//]: # (END included file " + optionfile + ")\n")
else:
fh_out.write(line)
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 67943ecf1..bccaad932 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -547,6 +547,7 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) {
Ignore bool `schema:"ignore"`
LookupManifest bool `schema:"lookupManifest"`
Images []string `schema:"images"`
+ NoPrune bool `schema:"noprune"`
}{}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
@@ -554,7 +555,7 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) {
return
}
- opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force, Ignore: query.Ignore, LookupManifest: query.LookupManifest}
+ opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force, Ignore: query.Ignore, LookupManifest: query.LookupManifest, NoPrune: query.NoPrune}
imageEngine := abi.ImageEngine{Libpod: runtime}
rmReport, rmErrors := imageEngine.Remove(r.Context(), query.Images, opts)
strErrs := errorhandling.ErrorsToStrings(rmErrors)
diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go
index 0664afc1b..9783a8e18 100644
--- a/pkg/bindings/images/types.go
+++ b/pkg/bindings/images/types.go
@@ -15,6 +15,8 @@ type RemoveOptions struct {
Ignore *bool
// Confirms if given name is a manifest list and removes it, otherwise returns error.
LookupManifest *bool
+ // Does not remove dangling parent images
+ NoPrune *bool
}
//go:generate go run ../generator/generator.go DiffOptions
diff --git a/pkg/bindings/images/types_remove_options.go b/pkg/bindings/images/types_remove_options.go
index 559ebcfd5..8972ac93c 100644
--- a/pkg/bindings/images/types_remove_options.go
+++ b/pkg/bindings/images/types_remove_options.go
@@ -76,3 +76,18 @@ func (o *RemoveOptions) GetLookupManifest() bool {
}
return *o.LookupManifest
}
+
+// WithNoPrune set field NoPrune to given value
+func (o *RemoveOptions) WithNoPrune(value bool) *RemoveOptions {
+ o.NoPrune = &value
+ return o
+}
+
+// GetNoPrune returns value of field NoPrune
+func (o *RemoveOptions) GetNoPrune() bool {
+ if o.NoPrune == nil {
+ var z bool
+ return z
+ }
+ return *o.NoPrune
+}
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index dad2dc6cc..21c1372b9 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -94,6 +94,8 @@ type ImageRemoveOptions struct {
Ignore bool
// Confirms if given name is a manifest list and removes it, otherwise returns error.
LookupManifest bool
+ // NoPrune will not remove dangling images
+ NoPrune bool
}
// ImageRemoveReport is the response for removing one or more image(s) from storage
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index ed149a869..0df36ed64 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -40,6 +40,7 @@ import (
// is specified. It also returns a list of the corresponding input name used to lookup each container.
func getContainersAndInputByContext(all, latest bool, names []string, filters map[string][]string, runtime *libpod.Runtime) (ctrs []*libpod.Container, rawInput []string, err error) {
var ctr *libpod.Container
+ var filteredCtrs []*libpod.Container
ctrs = []*libpod.Container{}
filterFuncs := make([]libpod.ContainerFilter, 0, len(filters))
@@ -58,7 +59,17 @@ func getContainersAndInputByContext(all, latest bool, names []string, filters ma
}
rawInput = []string{}
for _, candidate := range ctrs {
- rawInput = append(rawInput, candidate.ID())
+ if len(names) > 0 {
+ for _, name := range names {
+ if candidate.ID() == name || candidate.Name() == name {
+ rawInput = append(rawInput, candidate.ID())
+ filteredCtrs = append(filteredCtrs, candidate)
+ }
+ }
+ ctrs = filteredCtrs
+ } else {
+ rawInput = append(rawInput, candidate.ID())
+ }
}
case all:
ctrs, err = runtime.GetAllContainers()
@@ -899,38 +910,7 @@ func (ic *ContainerEngine) ContainerExecDetached(ctx context.Context, nameOrID s
func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) {
reports := []*entities.ContainerStartReport{}
var exitCode = define.ExecErrorCodeGeneric
- containersNamesOrIds := namesOrIds
- all := options.All
- if len(options.Filters) > 0 {
- all = false
- filterFuncs := make([]libpod.ContainerFilter, 0, len(options.Filters))
- if len(options.Filters) > 0 {
- for k, v := range options.Filters {
- generatedFunc, err := dfilters.GenerateContainerFilterFuncs(k, v, ic.Libpod)
- if err != nil {
- return nil, err
- }
- filterFuncs = append(filterFuncs, generatedFunc)
- }
- }
- candidates, err := ic.Libpod.GetContainers(filterFuncs...)
- if err != nil {
- return nil, err
- }
- containersNamesOrIds = []string{}
- for _, candidate := range candidates {
- if options.All {
- containersNamesOrIds = append(containersNamesOrIds, candidate.ID())
- continue
- }
- for _, nameOrID := range namesOrIds {
- if nameOrID == candidate.ID() || nameOrID == candidate.Name() {
- containersNamesOrIds = append(containersNamesOrIds, nameOrID)
- }
- }
- }
- }
- ctrs, rawInputs, err := getContainersAndInputByContext(all, options.Latest, containersNamesOrIds, options.Filters, ic.Libpod)
+ ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, namesOrIds, options.Filters, ic.Libpod)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 94178a8e2..1f34cbd01 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -565,6 +565,7 @@ func (ir *ImageEngine) Remove(ctx context.Context, images []string, opts entitie
libimageOptions.Force = opts.Force
libimageOptions.Ignore = opts.Ignore
libimageOptions.LookupManifest = opts.LookupManifest
+ libimageOptions.NoPrune = opts.NoPrune
if !opts.All {
libimageOptions.Filters = append(libimageOptions.Filters, "intermediate=false")
}
@@ -581,7 +582,7 @@ func (ir *ImageEngine) Remove(ctx context.Context, images []string, opts entitie
rmErrors = libimageErrors
- return
+ return report, rmErrors
}
// Shutdown Libpod engine
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 225aee017..81fb6aef8 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -658,36 +658,7 @@ func logIfRmError(id string, err error, reports []*reports.RmReport) {
func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) {
reports := []*entities.ContainerStartReport{}
var exitCode = define.ExecErrorCodeGeneric
- containersNamesOrIds := namesOrIds
- all := options.All
- if len(options.Filters) > 0 {
- all = false
- containersNamesOrIds = []string{}
- opts := new(containers.ListOptions).WithFilters(options.Filters).WithAll(true)
- candidates, listErr := containers.List(ic.ClientCtx, opts)
- if listErr != nil {
- return nil, listErr
- }
- for _, candidate := range candidates {
- if options.All {
- containersNamesOrIds = append(containersNamesOrIds, candidate.ID)
- continue
- }
- for _, nameOrID := range namesOrIds {
- if nameOrID == candidate.ID {
- containersNamesOrIds = append(containersNamesOrIds, nameOrID)
- continue
- }
- for _, containerName := range candidate.Names {
- if containerName == nameOrID {
- containersNamesOrIds = append(containersNamesOrIds, nameOrID)
- continue
- }
- }
- }
- }
- }
- ctrs, err := getContainersByContext(ic.ClientCtx, all, false, containersNamesOrIds)
+ ctrs, namesOrIds, err := getContainersAndInputByContext(ic.ClientCtx, options.All, false, namesOrIds, options.Filters)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go
index a0b01dd71..90d558119 100644
--- a/pkg/domain/infra/tunnel/helpers.go
+++ b/pkg/domain/infra/tunnel/helpers.go
@@ -31,8 +31,17 @@ func getContainersAndInputByContext(contextWithConnection context.Context, all,
rawInputs := []string{}
switch {
case len(filters) > 0:
+ namesOrIDs = nil
for i := range allContainers {
- namesOrIDs = append(namesOrIDs, allContainers[i].ID)
+ if len(namesOrIDs) > 0 {
+ for _, name := range namesOrIDs {
+ if name == allContainers[i].ID {
+ namesOrIDs = append(namesOrIDs, allContainers[i].ID)
+ }
+ }
+ } else {
+ namesOrIDs = append(namesOrIDs, allContainers[i].ID)
+ }
}
case all:
for i := range allContainers {
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 4f79325fd..4fecefaa3 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -28,7 +28,7 @@ func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.Boo
}
func (ir *ImageEngine) Remove(ctx context.Context, imagesArg []string, opts entities.ImageRemoveOptions) (*entities.ImageRemoveReport, []error) {
- options := new(images.RemoveOptions).WithForce(opts.Force).WithIgnore(opts.Ignore).WithAll(opts.All).WithLookupManifest(opts.LookupManifest)
+ options := new(images.RemoveOptions).WithForce(opts.Force).WithIgnore(opts.Ignore).WithAll(opts.All).WithLookupManifest(opts.LookupManifest).WithNoPrune(opts.NoPrune)
return images.Remove(ir.ClientCtx, imagesArg, options)
}
diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go
index 9a57102f0..8f6ef7a43 100644
--- a/pkg/machine/wsl/machine.go
+++ b/pkg/machine/wsl/machine.go
@@ -364,14 +364,6 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
return false, err
}
- if err := v.writeConfig(); err != nil {
- return false, err
- }
-
- if err := setupConnections(v, opts, sshDir); err != nil {
- return false, err
- }
-
dist, err := provisionWSLDist(v)
if err != nil {
return false, err
@@ -393,6 +385,14 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
// Cycle so that user change goes into effect
_ = terminateDist(dist)
+ if err := v.writeConfig(); err != nil {
+ return false, err
+ }
+
+ if err := setupConnections(v, opts, sshDir); err != nil {
+ return false, err
+ }
+
return true, nil
}
diff --git a/podman.spec.rpkg b/podman.spec.rpkg
index 7068c9745..f27b31108 100644
--- a/podman.spec.rpkg
+++ b/podman.spec.rpkg
@@ -59,6 +59,7 @@ BuildRequires: go-rpm-macros
%endif
%if 0%{?rhel} <= 8
BuildRequires: pkgconfig(devmapper)
+BuildRequires: python3
%endif
BuildRequires: gpgme-devel
BuildRequires: libassuan-devel
diff --git a/test/e2e/rmi_test.go b/test/e2e/rmi_test.go
index d1a0cd6f5..f87f65c34 100644
--- a/test/e2e/rmi_test.go
+++ b/test/e2e/rmi_test.go
@@ -307,4 +307,82 @@ RUN touch %s`, CIRROS_IMAGE, imageName)
}
wg.Wait()
})
+
+ It("podman rmi --no-prune with dangling parents", func() {
+ podmanTest.AddImageToRWStore(ALPINE)
+ session := podmanTest.Podman([]string{"create", "--name", "c_test1", ALPINE, "true"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"commit", "-q", "c_test1", "test1"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"create", "--name", "c_test2", "test1", "true"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"commit", "-q", "c_test2", "test2"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ imageID2 := session.OutputToString()
+
+ session = podmanTest.Podman([]string{"create", "--name", "c_test3", "test2", "true"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"commit", "-q", "c_test3", "test3"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ imageID3 := session.OutputToString()
+
+ session = podmanTest.Podman([]string{"untag", "test2"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"untag", "test1"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"rmi", "-f", "--no-prune", "test3"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(ContainSubstring(imageID3))
+ Expect(session.OutputToString()).NotTo(ContainSubstring(imageID2))
+ })
+
+ It("podman rmi --no-prune with undangling parents", func() {
+ podmanTest.AddImageToRWStore(ALPINE)
+ session := podmanTest.Podman([]string{"create", "--name", "c_test1", ALPINE, "true"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"commit", "-q", "c_test1", "test1"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"create", "--name", "c_test2", "test1", "true"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"commit", "-q", "c_test2", "test2"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ imageID2 := session.OutputToString()
+
+ session = podmanTest.Podman([]string{"create", "--name", "c_test3", "test2", "true"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"commit", "-q", "c_test3", "test3"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ imageID3 := session.OutputToString()
+
+ session = podmanTest.Podman([]string{"rmi", "-f", "--no-prune", "test3"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(ContainSubstring(imageID3))
+ Expect(session.OutputToString()).NotTo(ContainSubstring(imageID2))
+ })
})
diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go
index 73af9d12c..736008ed3 100644
--- a/test/e2e/start_test.go
+++ b/test/e2e/start_test.go
@@ -1,6 +1,7 @@
package integration
import (
+ "fmt"
"io/ioutil"
"os"
"strconv"
@@ -231,4 +232,42 @@ var _ = Describe("Podman start", func() {
_, err = strconv.Atoi(containerPID) // Make sure it's a proper integer
Expect(err).To(BeNil())
})
+
+ It("podman start container --filter", func() {
+ session1 := podmanTest.Podman([]string{"container", "create", ALPINE})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ cid1 := session1.OutputToString()
+
+ session1 = podmanTest.Podman([]string{"container", "create", ALPINE})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ cid2 := session1.OutputToString()
+
+ session1 = podmanTest.Podman([]string{"container", "create", ALPINE})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ cid3 := session1.OutputToString()
+ shortCid3 := cid3[0:5]
+
+ session1 = podmanTest.Podman([]string{"start", cid1, "-f", "status=running"})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(HaveLen(0))
+
+ session1 = podmanTest.Podman([]string{"start", "--all", "--filter", fmt.Sprintf("id=%swrongid", shortCid3)})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(HaveLen(0))
+
+ session1 = podmanTest.Podman([]string{"start", "--all", "--filter", fmt.Sprintf("id=%s", shortCid3)})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(BeEquivalentTo(cid3))
+
+ session1 = podmanTest.Podman([]string{"start", "-f", fmt.Sprintf("id=%s", cid2)})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(BeEquivalentTo(cid2))
+ })
})