diff options
-rw-r--r-- | .cirrus.yml | 10 | ||||
-rw-r--r-- | cmd/podman/containers/start.go | 20 | ||||
-rw-r--r-- | go.mod | 2 | ||||
-rw-r--r-- | go.sum | 4 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 46 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 31 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/helpers.go | 11 | ||||
-rw-r--r-- | test/e2e/start_test.go | 39 | ||||
-rw-r--r-- | test/system/010-images.bats | 6 | ||||
-rw-r--r-- | vendor/github.com/containers/common/libimage/image.go | 9 | ||||
-rw-r--r-- | vendor/github.com/containers/common/libimage/runtime.go | 3 | ||||
-rw-r--r-- | vendor/github.com/containers/common/version/version.go | 2 | ||||
-rw-r--r-- | vendor/modules.txt | 2 |
13 files changed, 96 insertions, 89 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 223fc5b53..32771cb88 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -415,9 +415,7 @@ alt_build_task: alias: alt_build # Don't create task for [CI:DOCS] or multiarch builds # Docs: ./contrib/cirrus/CIModes.md - only_if: ¬_docs_multiarch >- - $CIRRUS_CHANGE_TITLE !=~ '.*CI:DOCS.*' && - $CIRRUS_CRON != 'multiarch' + only_if: $CIRRUS_CRON != 'multiarch' depends_on: - build env: @@ -450,7 +448,7 @@ osx_alt_build_task: name: "OSX Cross" alias: osx_alt_build # Docs: ./contrib/cirrus/CIModes.md - only_if: *not_docs_multiarch + only_if: $CIRRUS_CRON != 'multiarch' depends_on: - build env: @@ -1036,7 +1034,9 @@ artifacts_task: name: "Artifacts" alias: artifacts # Docs: ./contrib/cirrus/CIModes.md - only_if: *not_docs_multiarch + only_if: >- + $CIRRUS_CHANGE_TITLE !=~ '.*CI:DOCS.*' && + $CIRRUS_CRON != 'multiarch' depends_on: - success # This task is a secondary/convenience for downstream consumers, don't 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) @@ -12,7 +12,7 @@ require ( github.com/containernetworking/cni v1.1.2 github.com/containernetworking/plugins v1.1.1 github.com/containers/buildah v1.26.1-0.20220716095526-d31d27c357ab - github.com/containers/common v0.49.1-0.20220729221035-246800047d46 + github.com/containers/common v0.49.2-0.20220804143628-dc97077782d5 github.com/containers/conmon v2.0.20+incompatible github.com/containers/image/v5 v5.22.0 github.com/containers/ocicrypt v1.1.5 @@ -395,8 +395,8 @@ github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19 github.com/containers/buildah v1.26.1-0.20220716095526-d31d27c357ab h1:NeI0DOkTf3Tn4OpdjMhMubAfTPs2oCO5jUY5wnpv4qk= github.com/containers/buildah v1.26.1-0.20220716095526-d31d27c357ab/go.mod h1:iVtQtU6a+pbETBqIzg0oAWW3gTR1ItrAihJpLFFppmA= github.com/containers/common v0.48.1-0.20220715075726-2ac10faca05a/go.mod h1:1dA7JPGoSi83kjf5H4NIrGANyLOULyvFqV1bwvYFEek= -github.com/containers/common v0.49.1-0.20220729221035-246800047d46 h1:BNNV+JlPYSmaa9rTapL9kh2JZrg7hmWwi/VrIY/KH1E= -github.com/containers/common v0.49.1-0.20220729221035-246800047d46/go.mod h1:ueM5hT0itKqCQvVJDs+EtjornAQtrHYxQJzP2gxeGIg= +github.com/containers/common v0.49.2-0.20220804143628-dc97077782d5 h1:bOdbfjiOvj5n51dyeo8LF3qAtvaiflS13q70Cx4NA40= +github.com/containers/common v0.49.2-0.20220804143628-dc97077782d5/go.mod h1:ueM5hT0itKqCQvVJDs+EtjornAQtrHYxQJzP2gxeGIg= github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg= github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I= github.com/containers/image/v5 v5.21.2-0.20220712113758-29aec5f7bbbf/go.mod h1:0+N0ZM9mgMmoZZc6uNcgnEsbX85Ne7b29cIW5lqWwVU= 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/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/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)) + }) }) diff --git a/test/system/010-images.bats b/test/system/010-images.bats index aa390f236..16ee681a3 100644 --- a/test/system/010-images.bats +++ b/test/system/010-images.bats @@ -259,8 +259,8 @@ Labels.created_at | 20[0-9-]\\\+T[0-9:]\\\+Z run_podman 2 rmi -a is "$output" "Error: 2 errors occurred: -.** image used by .*: image is in use by a container -.** image used by .*: image is in use by a container" +.** image used by .*: image is in use by a container: consider listing external containers and force-removing image +.** image used by .*: image is in use by a container: consider listing external containers and force-removing image" run_podman rmi -af is "$output" "Untagged: $IMAGE @@ -292,7 +292,7 @@ Deleted: $pauseID" "infra images gets removed as well" pauseID=$output run_podman 2 rmi $pauseImage - is "$output" "Error: image used by .* image is in use by a container" + is "$output" "Error: image used by .* image is in use by a container: consider listing external containers and force-removing image" run_podman rmi -f $pauseImage is "$output" "Untagged: $pauseImage diff --git a/vendor/github.com/containers/common/libimage/image.go b/vendor/github.com/containers/common/libimage/image.go index b1866fa9b..d1548eb23 100644 --- a/vendor/github.com/containers/common/libimage/image.go +++ b/vendor/github.com/containers/common/libimage/image.go @@ -470,6 +470,9 @@ func (i *Image) removeRecursive(ctx context.Context, rmMap map[string]*RemoveIma } if _, err := i.runtime.store.DeleteImage(i.ID(), true); handleError(err) != nil { + if errors.Is(err, storage.ErrImageUsedByContainer) { + err = fmt.Errorf("%w: consider listing external containers and force-removing image", err) + } return processedIDs, err } report.Untagged = append(report.Untagged, i.Names()...) @@ -478,6 +481,11 @@ func (i *Image) removeRecursive(ctx context.Context, rmMap map[string]*RemoveIma report.Removed = true } + // Do not delete any parents if NoPrune is true + if options.NoPrune { + return processedIDs, nil + } + // Check if can remove the parent image. if parent == nil { return processedIDs, nil @@ -495,7 +503,6 @@ func (i *Image) removeRecursive(ctx context.Context, rmMap map[string]*RemoveIma if !danglingParent { return processedIDs, nil } - // Recurse into removing the parent. return parent.removeRecursive(ctx, rmMap, processedIDs, "", options) } diff --git a/vendor/github.com/containers/common/libimage/runtime.go b/vendor/github.com/containers/common/libimage/runtime.go index 6030a179b..7cbf9c95e 100644 --- a/vendor/github.com/containers/common/libimage/runtime.go +++ b/vendor/github.com/containers/common/libimage/runtime.go @@ -608,6 +608,8 @@ type RemoveImagesOptions struct { // much space was freed. However, computing the size of an image is // comparatively expensive, so it is made optional. WithSize bool + // NoPrune will not remove dangling images + NoPrune bool } // RemoveImages removes images specified by names. If no names are specified, @@ -653,7 +655,6 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem toDelete := []string{} // Look up images in the local containers storage and fill out // toDelete and the deleteMap. - switch { case len(names) > 0: // prepare lookupOptions diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go index 7b44a84fc..34e9fe6ba 100644 --- a/vendor/github.com/containers/common/version/version.go +++ b/vendor/github.com/containers/common/version/version.go @@ -1,4 +1,4 @@ package version // Version is the version of the build. -const Version = "0.49.1-dev" +const Version = "0.49.2-dev" diff --git a/vendor/modules.txt b/vendor/modules.txt index 2a1beb611..1a13785eb 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -114,7 +114,7 @@ github.com/containers/buildah/pkg/rusage github.com/containers/buildah/pkg/sshagent github.com/containers/buildah/pkg/util github.com/containers/buildah/util -# github.com/containers/common v0.49.1-0.20220729221035-246800047d46 +# github.com/containers/common v0.49.2-0.20220804143628-dc97077782d5 ## explicit github.com/containers/common/libimage github.com/containers/common/libimage/define |