Fix broken podman images filters

The id, digest, and intermediate filters were broken
for podman images. Fix to match on substrings instead of
the whole string for id and digest. Add the intermediate value
correctly when set.

Signed-off-by: Urvashi Mohnani <umohnani@redhat.com>
This commit is contained in:
Urvashi Mohnani
2023-09-28 12:11:12 -04:00
parent 87dd939334
commit ba788c1bb8
17 changed files with 157 additions and 30 deletions

4
go.mod
View File

@ -13,7 +13,7 @@ require (
github.com/containernetworking/cni v1.1.2 github.com/containernetworking/cni v1.1.2
github.com/containernetworking/plugins v1.3.0 github.com/containernetworking/plugins v1.3.0
github.com/containers/buildah v1.32.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/conmon v2.0.20+incompatible
github.com/containers/gvisor-tap-vsock v0.7.1 github.com/containers/gvisor-tap-vsock v0.7.1
github.com/containers/image/v5 v5.28.0 github.com/containers/image/v5 v5.28.0
@ -45,7 +45,7 @@ require (
github.com/moby/term v0.5.0 github.com/moby/term v0.5.0
github.com/nxadm/tail v1.4.8 github.com/nxadm/tail v1.4.8
github.com/onsi/ginkgo/v2 v2.12.1 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/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.0-rc5 github.com/opencontainers/image-spec v1.1.0-rc5
github.com/opencontainers/runc v1.1.9 github.com/opencontainers/runc v1.1.9

8
go.sum
View File

@ -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/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 h1:uz5Rcf7lGeStj7iPTBgO4UdhQYZqMMzyt9suDf16k1k=
github.com/containers/buildah v1.32.0/go.mod h1:sN3rA3DbnqekNz3bNdkqWduuirYDuMs54LUCOZOomBE= 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.20230929120646-4fd26cf84f19 h1:aAs/BiCzeNndwOTt0tnE26D4B4wtztVxl/4h0bu86qY=
github.com/containers/common v0.56.1-0.20230927174306-9342cdd82aa6/go.mod h1:ABFEglmyt48WWWQv80kGhitfbVfR1Br35wk3gBQdrIk= 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 h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I= 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= 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.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= 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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.28.0 h1:i2rg/p9n/UqIDAMFUJ6qIUUMcsqOuUHgbpbu235Vr1c=
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= 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-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 v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=

View File

@ -7,6 +7,7 @@ import (
"github.com/containers/common/libimage" "github.com/containers/common/libimage"
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/domain/entities" "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) { 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, Filters: opts.Filter,
SetListData: true, SetListData: true,
} }
if !opts.All { if !opts.All && !util.StringInSlice("intermediate=true", listImagesOptions.Filters) {
// Filter intermediate images unless we want to list *all*. // Filter intermediate images unless we want to list *all*.
// NOTE: it's a positive filter, so `intermediate=false` means // NOTE: it's a positive filter, so `intermediate=false` means
// to display non-intermediate images. // to display non-intermediate images.

View File

@ -118,6 +118,32 @@ var _ = Describe("Podman images", func() {
Expect(session.OutputToStringArray()).To(HaveLen(2)) 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() { It("podman images filter reference", func() {
result := podmanTest.Podman([]string{"images", "-q", "-f", "reference=quay.io/libpod/*"}) result := podmanTest.Podman([]string{"images", "-q", "-f", "reference=quay.io/libpod/*"})
result.WaitWithDefaultTimeout() result.WaitWithDefaultTimeout()
@ -195,6 +221,18 @@ WORKDIR /test
Expect(result.OutputToStringArray()).Should(BeEmpty(), "dangling image output: %q", result.OutputToString()) 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() { It("podman pull by digest and list --all", func() {
// Prevent regressing on issue #7651: error parsing name that includes a digest // Prevent regressing on issue #7651: error parsing name that includes a digest
// component as if were a name that includes tag component. // component as if were a name that includes tag component.

View File

@ -11,7 +11,6 @@ import (
filtersPkg "github.com/containers/common/pkg/filters" filtersPkg "github.com/containers/common/pkg/filters"
"github.com/containers/common/pkg/timetype" "github.com/containers/common/pkg/timetype"
"github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/docker/reference"
"github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus" "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. // filterID creates an image-ID filter for matching the specified value.
func filterID(value string) filterFunc { func filterID(value string) filterFunc {
return func(img *Image) (bool, error) { 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. // filterDigest creates a digest filter for matching the specified value.
func filterDigest(value string) (filterFunc, error) { func filterDigest(value string) (filterFunc, error) {
d, err := digest.Parse(value) if !strings.HasPrefix(value, "sha256:") {
if err != nil { return nil, fmt.Errorf("invalid value %q for digest filter", value)
return nil, fmt.Errorf("invalid value %q for digest filter: %w", value, err)
} }
return func(img *Image) (bool, error) { return func(img *Image) (bool, error) {
return img.hasDigest(d), nil return img.containsDigestPrefix(value), nil
}, nil }, nil
} }

View File

@ -169,6 +169,17 @@ func (i *Image) hasDigest(wantedDigest digest.Digest) bool {
return false 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. // IsReadOnly returns whether the image is set read only.
func (i *Image) IsReadOnly() bool { func (i *Image) IsReadOnly() bool {
return i.storageImage.ReadOnly return i.storageImage.ReadOnly

View File

@ -440,6 +440,8 @@ func (m *ManifestList) Push(ctx context.Context, destination string, options *Ma
SignSigstorePrivateKeyPassphrase: options.SignSigstorePrivateKeyPassphrase, SignSigstorePrivateKeyPassphrase: options.SignSigstorePrivateKeyPassphrase,
RemoveSignatures: options.RemoveSignatures, RemoveSignatures: options.RemoveSignatures,
ManifestType: options.ManifestMIMEType, ManifestType: options.ManifestMIMEType,
MaxRetries: options.MaxRetries,
RetryDelay: options.RetryDelay,
ForceCompressionFormat: options.ForceCompressionFormat, ForceCompressionFormat: options.ForceCompressionFormat,
} }

View File

@ -6,8 +6,10 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"time"
"github.com/containers/common/pkg/manifests" "github.com/containers/common/pkg/manifests"
"github.com/containers/common/pkg/retry"
"github.com/containers/common/pkg/supplemented" "github.com/containers/common/pkg/supplemented"
cp "github.com/containers/image/v5/copy" cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/docker/reference"
@ -27,6 +29,10 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
const (
defaultMaxRetries = 3
)
const instancesData = "instances.json" const instancesData = "instances.json"
// LookupReferenceFunc return an image reference based on the specified one. // LookupReferenceFunc return an image reference based on the specified one.
@ -72,6 +78,11 @@ type PushOptions struct {
SourceFilter LookupReferenceFunc // filter the list source SourceFilter LookupReferenceFunc // filter the list source
AddCompression []string // add existing instances with requested compression algorithms to manifest list 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. 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, // 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, ForceCompressionFormat: options.ForceCompressionFormat,
} }
retryOptions := retry.Options{}
retryOptions.MaxRetry = defaultMaxRetries
if options.MaxRetries != nil {
retryOptions.MaxRetry = int(*options.MaxRetries)
}
if options.RetryDelay != nil {
retryOptions.Delay = *options.RetryDelay
}
// Copy whatever we were asked to copy. // Copy whatever we were asked to copy.
manifestBytes, err := cp.Image(ctx, policyContext, dest, src, copyOptions) var manifestDigest digest.Digest
if err != nil { f := func() error {
return nil, "", err 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
} }
manifestDigest, err := manifest.Digest(manifestBytes) err = retry.IfNecessary(ctx, f, &retryOptions)
if err != nil { return nil, manifestDigest, err
return nil, "", err
}
return nil, manifestDigest, nil
} }
func prepareAddWithCompression(variants []string) ([]cp.OptionCompressionVariant, error) { func prepareAddWithCompression(variants []string) ([]cp.OptionCompressionVariant, error) {

View File

@ -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 // 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) newNetwork.Options[types.NoDefaultRoute] = strconv.FormatBool(val)
case types.VRFOption:
if len(value) == 0 {
return nil, errors.New("invalid vrf name")
}
default: default:
return nil, fmt.Errorf("unsupported bridge network option %s", key) return nil, fmt.Errorf("unsupported bridge network option %s", key)
} }

View File

@ -43,6 +43,7 @@ const (
MetricOption = "metric" MetricOption = "metric"
NoDefaultRoute = "no_default_route" NoDefaultRoute = "no_default_route"
BclimOption = "bclim" BclimOption = "bclim"
VRFOption = "vrf"
) )
type NetworkBackend string type NetworkBackend string

View File

@ -67,7 +67,7 @@ func createPruneFilterFuncs(key string, filterValues []string) (types.FilterFunc
}, nil }, nil
case "label!": case "label!":
return func(net types.Network) bool { return func(net types.Network) bool {
return !filters.MatchLabelFilters(filterValues, net.Labels) return filters.MatchNegatedLabelFilters(filterValues, net.Labels)
}, nil }, nil
case "until": case "until":
until, err := filters.ComputeUntilTimestamp(filterValues) until, err := filters.ComputeUntilTimestamp(filterValues)

View File

@ -362,6 +362,35 @@ func addFIPSModeSubscription(mounts *[]rspec.Mount, containerRunDir, mountPoint,
} }
*mounts = append(*mounts, m) *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 return nil
} }

View File

@ -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 ## 1.27.10
### Fixes ### Fixes

View File

@ -22,7 +22,7 @@ import (
"github.com/onsi/gomega/types" "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. 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(). If you're using Ginkgo then you probably forgot to put your assertion in an It().

View File

@ -94,7 +94,7 @@ func Succeed() types.GomegaMatcher {
// //
// Expect(err).Should(MatchError("an error")) //asserts that err.Error() == "an error" // 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(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 // It is an error for err to be nil or an object that does not implement the
// Error interface // Error interface

View File

@ -11,8 +11,9 @@ import (
) )
type HaveHTTPBodyMatcher struct { type HaveHTTPBodyMatcher struct {
Expected interface{} Expected interface{}
cachedBody []byte cachedResponse interface{}
cachedBody []byte
} }
func (matcher *HaveHTTPBodyMatcher) Match(actual interface{}) (bool, error) { 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() // the Reader is closed and it is not readable again in FailureMessage()
// or NegatedFailureMessage() // or NegatedFailureMessage()
func (matcher *HaveHTTPBodyMatcher) body(actual interface{}) ([]byte, error) { func (matcher *HaveHTTPBodyMatcher) body(actual interface{}) ([]byte, error) {
if matcher.cachedBody != nil { if matcher.cachedResponse == actual && matcher.cachedBody != nil {
return matcher.cachedBody, nil return matcher.cachedBody, nil
} }
@ -91,8 +92,10 @@ func (matcher *HaveHTTPBodyMatcher) body(actual interface{}) ([]byte, error) {
switch a := actual.(type) { switch a := actual.(type) {
case *http.Response: case *http.Response:
matcher.cachedResponse = a
return body(a) return body(a)
case *httptest.ResponseRecorder: case *httptest.ResponseRecorder:
matcher.cachedResponse = a
return body(a.Result()) return body(a.Result())
default: default:
return nil, fmt.Errorf("HaveHTTPBody matcher expects *http.Response or *httptest.ResponseRecorder. Got:\n%s", format.Object(actual, 1)) return nil, fmt.Errorf("HaveHTTPBody matcher expects *http.Response or *httptest.ResponseRecorder. Got:\n%s", format.Object(actual, 1))

4
vendor/modules.txt vendored
View File

@ -164,7 +164,7 @@ github.com/containers/buildah/pkg/sshagent
github.com/containers/buildah/pkg/util github.com/containers/buildah/pkg/util
github.com/containers/buildah/pkg/volumes github.com/containers/buildah/pkg/volumes
github.com/containers/buildah/util 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 ## explicit; go 1.18
github.com/containers/common/libimage github.com/containers/common/libimage
github.com/containers/common/libimage/define 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/internal/testingtproxy
github.com/onsi/ginkgo/v2/reporters github.com/onsi/ginkgo/v2/reporters
github.com/onsi/ginkgo/v2/types github.com/onsi/ginkgo/v2/types
# github.com/onsi/gomega v1.27.10 # github.com/onsi/gomega v1.28.0
## explicit; go 1.18 ## explicit; go 1.18
github.com/onsi/gomega github.com/onsi/gomega
github.com/onsi/gomega/format github.com/onsi/gomega/format