diff --git a/go.mod b/go.mod index 00d9f0c730..48b3fedd85 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/containernetworking/cni v1.1.2 github.com/containernetworking/plugins v1.3.0 github.com/containers/buildah v1.32.0 - github.com/containers/common v0.56.1-0.20230927174306-9342cdd82aa6 + github.com/containers/common v0.56.1-0.20230929120646-4fd26cf84f19 github.com/containers/conmon v2.0.20+incompatible github.com/containers/gvisor-tap-vsock v0.7.1 github.com/containers/image/v5 v5.28.0 @@ -45,7 +45,7 @@ require ( github.com/moby/term v0.5.0 github.com/nxadm/tail v1.4.8 github.com/onsi/ginkgo/v2 v2.12.1 - github.com/onsi/gomega v1.27.10 + github.com/onsi/gomega v1.28.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0-rc5 github.com/opencontainers/runc v1.1.9 diff --git a/go.sum b/go.sum index 7fb0e215c1..870302d1de 100644 --- a/go.sum +++ b/go.sum @@ -249,8 +249,8 @@ github.com/containernetworking/plugins v1.3.0 h1:QVNXMT6XloyMUoO2wUOqWTC1hWFV62Q github.com/containernetworking/plugins v1.3.0/go.mod h1:Pc2wcedTQQCVuROOOaLBPPxrEXqqXBFt3cZ+/yVg6l0= github.com/containers/buildah v1.32.0 h1:uz5Rcf7lGeStj7iPTBgO4UdhQYZqMMzyt9suDf16k1k= github.com/containers/buildah v1.32.0/go.mod h1:sN3rA3DbnqekNz3bNdkqWduuirYDuMs54LUCOZOomBE= -github.com/containers/common v0.56.1-0.20230927174306-9342cdd82aa6 h1:yALmokSK/0EKa12wV4AkgLr7ObDIo5sySJohDhE2UIs= -github.com/containers/common v0.56.1-0.20230927174306-9342cdd82aa6/go.mod h1:ABFEglmyt48WWWQv80kGhitfbVfR1Br35wk3gBQdrIk= +github.com/containers/common v0.56.1-0.20230929120646-4fd26cf84f19 h1:aAs/BiCzeNndwOTt0tnE26D4B4wtztVxl/4h0bu86qY= +github.com/containers/common v0.56.1-0.20230929120646-4fd26cf84f19/go.mod h1:yV1LzHyQ4KH99zPS4NA0cfKdZKG3RHjozjsiT0GPsIg= 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/gvisor-tap-vsock v0.7.1 h1:+Rc+sOPplrkQb/BUXeN0ug8TxjgyrIqo/9P/eNS2A4c= @@ -807,8 +807,8 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/gomega v1.28.0 h1:i2rg/p9n/UqIDAMFUJ6qIUUMcsqOuUHgbpbu235Vr1c= +github.com/onsi/gomega v1.28.0/go.mod h1:A1H2JE76sI14WIP57LMKj7FVfCHx3g3BcZVjJG8bjX8= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= diff --git a/pkg/domain/infra/abi/images_list.go b/pkg/domain/infra/abi/images_list.go index b980dcc001..d70fca268b 100644 --- a/pkg/domain/infra/abi/images_list.go +++ b/pkg/domain/infra/abi/images_list.go @@ -7,6 +7,7 @@ import ( "github.com/containers/common/libimage" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/domain/entities" + "github.com/containers/podman/v4/pkg/util" ) func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ([]*entities.ImageSummary, error) { @@ -14,7 +15,7 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) Filters: opts.Filter, SetListData: true, } - if !opts.All { + if !opts.All && !util.StringInSlice("intermediate=true", listImagesOptions.Filters) { // Filter intermediate images unless we want to list *all*. // NOTE: it's a positive filter, so `intermediate=false` means // to display non-intermediate images. diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go index 971c48df6f..563715c8d1 100644 --- a/test/e2e/images_test.go +++ b/test/e2e/images_test.go @@ -118,6 +118,32 @@ var _ = Describe("Podman images", func() { Expect(session.OutputToStringArray()).To(HaveLen(2)) }) + It("podman images filter by image ID", func() { + session := podmanTest.Podman([]string{"inspect", ALPINE, "--format", "{{.ID}}"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(ExitCleanly()) + Expect(session.OutputToStringArray()).To(HaveLen(1)) + imgID := session.OutputToString() + + session = podmanTest.Podman([]string{"images", "--noheading", "--filter", "id=" + imgID[:5]}) + session.WaitWithDefaultTimeout() + Expect(session).Should(ExitCleanly()) + Expect(session.OutputToStringArray()).To(HaveLen(1)) + }) + + It("podman images filter by image digest", func() { + session := podmanTest.Podman([]string{"inspect", ALPINE, "--format", "{{.Digest}}"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(ExitCleanly()) + Expect(session.OutputToStringArray()).To(HaveLen(1)) + imgDigest := session.OutputToString() + + session = podmanTest.Podman([]string{"images", "--noheading", "--filter", "digest=" + imgDigest[:10]}) + session.WaitWithDefaultTimeout() + Expect(session).Should(ExitCleanly()) + Expect(session.OutputToStringArray()).To(HaveLen(1)) + }) + It("podman images filter reference", func() { result := podmanTest.Podman([]string{"images", "-q", "-f", "reference=quay.io/libpod/*"}) result.WaitWithDefaultTimeout() @@ -195,6 +221,18 @@ WORKDIR /test Expect(result.OutputToStringArray()).Should(BeEmpty(), "dangling image output: %q", result.OutputToString()) }) + It("podman images filter intermediate", func() { + dockerfile := `FROM quay.io/libpod/alpine:latest + RUN touch /tmp/test.txt + RUN touch /tmp/test-2.txt +` + podmanTest.BuildImage(dockerfile, "foobar.com/test-build", "true") + result := podmanTest.Podman([]string{"images", "--noheading", "--filter", "intermediate=true"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(ExitCleanly()) + Expect(result.OutputToStringArray()).To(HaveLen(1)) + }) + It("podman pull by digest and list --all", func() { // Prevent regressing on issue #7651: error parsing name that includes a digest // component as if were a name that includes tag component. diff --git a/vendor/github.com/containers/common/libimage/filters.go b/vendor/github.com/containers/common/libimage/filters.go index fdde5e8326..88dfef9dca 100644 --- a/vendor/github.com/containers/common/libimage/filters.go +++ b/vendor/github.com/containers/common/libimage/filters.go @@ -11,7 +11,6 @@ import ( filtersPkg "github.com/containers/common/pkg/filters" "github.com/containers/common/pkg/timetype" "github.com/containers/image/v5/docker/reference" - "github.com/opencontainers/go-digest" "github.com/sirupsen/logrus" ) @@ -394,18 +393,17 @@ func filterDangling(ctx context.Context, value bool, tree *layerTree) filterFunc // filterID creates an image-ID filter for matching the specified value. func filterID(value string) filterFunc { return func(img *Image) (bool, error) { - return img.ID() == value, nil + return strings.HasPrefix(img.ID(), value), nil } } // filterDigest creates a digest filter for matching the specified value. func filterDigest(value string) (filterFunc, error) { - d, err := digest.Parse(value) - if err != nil { - return nil, fmt.Errorf("invalid value %q for digest filter: %w", value, err) + if !strings.HasPrefix(value, "sha256:") { + return nil, fmt.Errorf("invalid value %q for digest filter", value) } return func(img *Image) (bool, error) { - return img.hasDigest(d), nil + return img.containsDigestPrefix(value), nil }, nil } diff --git a/vendor/github.com/containers/common/libimage/image.go b/vendor/github.com/containers/common/libimage/image.go index 640968fd0e..e4198a792c 100644 --- a/vendor/github.com/containers/common/libimage/image.go +++ b/vendor/github.com/containers/common/libimage/image.go @@ -169,6 +169,17 @@ func (i *Image) hasDigest(wantedDigest digest.Digest) bool { return false } +// containsDigestPrefix returns whether the specified value matches any digest of the +// image. It checks for the prefix and not a full match. +func (i *Image) containsDigestPrefix(wantedDigestPrefix string) bool { + for _, d := range i.Digests() { + if strings.HasPrefix(d.String(), wantedDigestPrefix) { + return true + } + } + return false +} + // IsReadOnly returns whether the image is set read only. func (i *Image) IsReadOnly() bool { return i.storageImage.ReadOnly diff --git a/vendor/github.com/containers/common/libimage/manifest_list.go b/vendor/github.com/containers/common/libimage/manifest_list.go index 839892366b..6fed12d741 100644 --- a/vendor/github.com/containers/common/libimage/manifest_list.go +++ b/vendor/github.com/containers/common/libimage/manifest_list.go @@ -440,6 +440,8 @@ func (m *ManifestList) Push(ctx context.Context, destination string, options *Ma SignSigstorePrivateKeyPassphrase: options.SignSigstorePrivateKeyPassphrase, RemoveSignatures: options.RemoveSignatures, ManifestType: options.ManifestMIMEType, + MaxRetries: options.MaxRetries, + RetryDelay: options.RetryDelay, ForceCompressionFormat: options.ForceCompressionFormat, } diff --git a/vendor/github.com/containers/common/libimage/manifests/manifests.go b/vendor/github.com/containers/common/libimage/manifests/manifests.go index f3fb5b6aea..d28ac87bba 100644 --- a/vendor/github.com/containers/common/libimage/manifests/manifests.go +++ b/vendor/github.com/containers/common/libimage/manifests/manifests.go @@ -6,8 +6,10 @@ import ( "errors" "fmt" "io" + "time" "github.com/containers/common/pkg/manifests" + "github.com/containers/common/pkg/retry" "github.com/containers/common/pkg/supplemented" cp "github.com/containers/image/v5/copy" "github.com/containers/image/v5/docker/reference" @@ -27,6 +29,10 @@ import ( "github.com/sirupsen/logrus" ) +const ( + defaultMaxRetries = 3 +) + const instancesData = "instances.json" // LookupReferenceFunc return an image reference based on the specified one. @@ -72,6 +78,11 @@ type PushOptions struct { SourceFilter LookupReferenceFunc // filter the list source AddCompression []string // add existing instances with requested compression algorithms to manifest list ForceCompressionFormat bool // force push with requested compression ignoring the blobs which can be reused. + // Maximum number of retries with exponential backoff when facing + // transient network errors. Default 3. + MaxRetries *uint + // RetryDelay used for the exponential back off of MaxRetries. + RetryDelay *time.Duration } // Create creates a new list containing information about the specified image, @@ -262,16 +273,31 @@ func (l *list) Push(ctx context.Context, dest types.ImageReference, options Push ForceCompressionFormat: options.ForceCompressionFormat, } - // Copy whatever we were asked to copy. - manifestBytes, err := cp.Image(ctx, policyContext, dest, src, copyOptions) - if err != nil { - return nil, "", err + retryOptions := retry.Options{} + retryOptions.MaxRetry = defaultMaxRetries + if options.MaxRetries != nil { + retryOptions.MaxRetry = int(*options.MaxRetries) } - manifestDigest, err := manifest.Digest(manifestBytes) - if err != nil { - return nil, "", err + if options.RetryDelay != nil { + retryOptions.Delay = *options.RetryDelay + } + + // Copy whatever we were asked to copy. + var manifestDigest digest.Digest + f := func() error { + opts := copyOptions + var manifestBytes []byte + var digest digest.Digest + var err error + if manifestBytes, err = cp.Image(ctx, policyContext, dest, src, opts); err == nil { + if digest, err = manifest.Digest(manifestBytes); err == nil { + manifestDigest = digest + } + } + return err } - return nil, manifestDigest, nil + err = retry.IfNecessary(ctx, f, &retryOptions) + return nil, manifestDigest, err } func prepareAddWithCompression(variants []string) ([]cp.OptionCompressionVariant, error) { diff --git a/vendor/github.com/containers/common/libnetwork/netavark/config.go b/vendor/github.com/containers/common/libnetwork/netavark/config.go index 45b49bf22b..de7af9575c 100644 --- a/vendor/github.com/containers/common/libnetwork/netavark/config.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/config.go @@ -204,7 +204,10 @@ func (n *netavarkNetwork) networkCreate(newNetwork *types.Network, defaultNet bo } // rust only support "true" or "false" while go can parse 1 and 0 as well so we need to change it newNetwork.Options[types.NoDefaultRoute] = strconv.FormatBool(val) - + case types.VRFOption: + if len(value) == 0 { + return nil, errors.New("invalid vrf name") + } default: return nil, fmt.Errorf("unsupported bridge network option %s", key) } diff --git a/vendor/github.com/containers/common/libnetwork/types/const.go b/vendor/github.com/containers/common/libnetwork/types/const.go index 83103ef6ef..a916182007 100644 --- a/vendor/github.com/containers/common/libnetwork/types/const.go +++ b/vendor/github.com/containers/common/libnetwork/types/const.go @@ -43,6 +43,7 @@ const ( MetricOption = "metric" NoDefaultRoute = "no_default_route" BclimOption = "bclim" + VRFOption = "vrf" ) type NetworkBackend string diff --git a/vendor/github.com/containers/common/libnetwork/util/filters.go b/vendor/github.com/containers/common/libnetwork/util/filters.go index b348b33a35..70f90918c7 100644 --- a/vendor/github.com/containers/common/libnetwork/util/filters.go +++ b/vendor/github.com/containers/common/libnetwork/util/filters.go @@ -67,7 +67,7 @@ func createPruneFilterFuncs(key string, filterValues []string) (types.FilterFunc }, nil case "label!": return func(net types.Network) bool { - return !filters.MatchLabelFilters(filterValues, net.Labels) + return filters.MatchNegatedLabelFilters(filterValues, net.Labels) }, nil case "until": until, err := filters.ComputeUntilTimestamp(filterValues) diff --git a/vendor/github.com/containers/common/pkg/subscriptions/subscriptions.go b/vendor/github.com/containers/common/pkg/subscriptions/subscriptions.go index a2924737ec..6ba2154a77 100644 --- a/vendor/github.com/containers/common/pkg/subscriptions/subscriptions.go +++ b/vendor/github.com/containers/common/pkg/subscriptions/subscriptions.go @@ -362,6 +362,35 @@ func addFIPSModeSubscription(mounts *[]rspec.Mount, containerRunDir, mountPoint, } *mounts = append(*mounts, m) } + + // Make sure we set the config to FIPS so that the container does not overwrite + // /etc/crypto-policies/back-ends when crypto-policies-scripts is reinstalled. + cryptoPoliciesConfigFile := filepath.Join(containerRunDir, "fips-config") + file, err := os.Create(cryptoPoliciesConfigFile) + if err != nil { + return fmt.Errorf("creating fips config file in container for FIPS mode: %w", err) + } + defer file.Close() + if _, err := file.WriteString("FIPS\n"); err != nil { + return fmt.Errorf("writing fips config file in container for FIPS mode: %w", err) + } + if err = label.Relabel(cryptoPoliciesConfigFile, mountLabel, false); err != nil { + return fmt.Errorf("applying correct labels on fips-config file: %w", err) + } + if err := file.Chown(uid, gid); err != nil { + return fmt.Errorf("chown fips-config file: %w", err) + } + + policyConfig := "/etc/crypto-policies/config" + if !mountExists(*mounts, policyConfig) { + m := rspec.Mount{ + Source: cryptoPoliciesConfigFile, + Destination: policyConfig, + Type: "bind", + Options: []string{"bind", "rprivate"}, + } + *mounts = append(*mounts, m) + } return nil } diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md index 1526497b9f..fbb12a157f 100644 --- a/vendor/github.com/onsi/gomega/CHANGELOG.md +++ b/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -1,3 +1,18 @@ +## 1.28.0 + +### Features +- Add VerifyHost handler to ghttp (#698) [0b03b36] + +### Fixes +- Read Body for Newer Responses in HaveHTTPBodyMatcher (#686) [18d6673] + +### Maintenance +- Bump github.com/onsi/ginkgo/v2 from 2.11.0 to 2.12.0 (#693) [55a33f3] +- Typo in matchers.go (#691) [de68e8f] +- Bump commonmarker from 0.23.9 to 0.23.10 in /docs (#690) [ab17f5e] +- chore: update test matrix for Go 1.21 (#689) [5069017] +- Bump golang.org/x/net from 0.12.0 to 0.14.0 (#688) [babe25f] + ## 1.27.10 ### Fixes diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go index 1fd1803acf..675a17840e 100644 --- a/vendor/github.com/onsi/gomega/gomega_dsl.go +++ b/vendor/github.com/onsi/gomega/gomega_dsl.go @@ -22,7 +22,7 @@ import ( "github.com/onsi/gomega/types" ) -const GOMEGA_VERSION = "1.27.10" +const GOMEGA_VERSION = "1.28.0" const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler. If you're using Ginkgo then you probably forgot to put your assertion in an It(). diff --git a/vendor/github.com/onsi/gomega/matchers.go b/vendor/github.com/onsi/gomega/matchers.go index bdaf62b56b..4c13ad0a7b 100644 --- a/vendor/github.com/onsi/gomega/matchers.go +++ b/vendor/github.com/onsi/gomega/matchers.go @@ -94,7 +94,7 @@ func Succeed() types.GomegaMatcher { // // Expect(err).Should(MatchError("an error")) //asserts that err.Error() == "an error" // Expect(err).Should(MatchError(SomeError)) //asserts that err == SomeError (via reflect.DeepEqual) -// Expect(err).Should(MatchError(ContainSubstring("sprocket not found"))) // asserts that edrr.Error() contains substring "sprocket not found" +// Expect(err).Should(MatchError(ContainSubstring("sprocket not found"))) // asserts that err.Error() contains substring "sprocket not found" // // It is an error for err to be nil or an object that does not implement the // Error interface diff --git a/vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go b/vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go index 6a3dcdc353..d14d9e5fc6 100644 --- a/vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go @@ -11,8 +11,9 @@ import ( ) type HaveHTTPBodyMatcher struct { - Expected interface{} - cachedBody []byte + Expected interface{} + cachedResponse interface{} + cachedBody []byte } func (matcher *HaveHTTPBodyMatcher) Match(actual interface{}) (bool, error) { @@ -73,7 +74,7 @@ func (matcher *HaveHTTPBodyMatcher) NegatedFailureMessage(actual interface{}) (m // the Reader is closed and it is not readable again in FailureMessage() // or NegatedFailureMessage() func (matcher *HaveHTTPBodyMatcher) body(actual interface{}) ([]byte, error) { - if matcher.cachedBody != nil { + if matcher.cachedResponse == actual && matcher.cachedBody != nil { return matcher.cachedBody, nil } @@ -91,8 +92,10 @@ func (matcher *HaveHTTPBodyMatcher) body(actual interface{}) ([]byte, error) { switch a := actual.(type) { case *http.Response: + matcher.cachedResponse = a return body(a) case *httptest.ResponseRecorder: + matcher.cachedResponse = a return body(a.Result()) default: return nil, fmt.Errorf("HaveHTTPBody matcher expects *http.Response or *httptest.ResponseRecorder. Got:\n%s", format.Object(actual, 1)) diff --git a/vendor/modules.txt b/vendor/modules.txt index ffef349b11..824508a93c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -164,7 +164,7 @@ github.com/containers/buildah/pkg/sshagent github.com/containers/buildah/pkg/util github.com/containers/buildah/pkg/volumes github.com/containers/buildah/util -# github.com/containers/common v0.56.1-0.20230927174306-9342cdd82aa6 +# github.com/containers/common v0.56.1-0.20230929120646-4fd26cf84f19 ## explicit; go 1.18 github.com/containers/common/libimage github.com/containers/common/libimage/define @@ -797,7 +797,7 @@ github.com/onsi/ginkgo/v2/internal/parallel_support github.com/onsi/ginkgo/v2/internal/testingtproxy github.com/onsi/ginkgo/v2/reporters github.com/onsi/ginkgo/v2/types -# github.com/onsi/gomega v1.27.10 +# github.com/onsi/gomega v1.28.0 ## explicit; go 1.18 github.com/onsi/gomega github.com/onsi/gomega/format