diff options
71 files changed, 1546 insertions, 596 deletions
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go index 7b7626040..16f193b03 100644 --- a/cmd/podman/common/create_opts.go +++ b/cmd/podman/common/create_opts.go @@ -347,7 +347,7 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c cliOpts.Volume = append(cliOpts.Volume, vol) // Extract the destination so we don't add duplicate mounts in // the volumes phase. - splitVol := strings.SplitN(vol, ":", 3) + splitVol := specgen.SplitVolumeString(vol) switch len(splitVol) { case 1: volDestinations[vol] = true diff --git a/cmd/podman/containers/utils.go b/cmd/podman/containers/utils.go deleted file mode 100644 index 0c09d3e40..000000000 --- a/cmd/podman/containers/utils.go +++ /dev/null @@ -1 +0,0 @@ -package containers diff --git a/cmd/podman/machine/inspect.go b/cmd/podman/machine/inspect.go index d43cabf6b..1884cf94d 100644 --- a/cmd/podman/machine/inspect.go +++ b/cmd/podman/machine/inspect.go @@ -59,7 +59,7 @@ func inspect(cmd *cobra.Command, args []string) error { errs = append(errs, err) continue } - state, err := vm.State() + state, err := vm.State(false) if err != nil { errs = append(errs, err) continue diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh index 1953c477e..5d6ba9921 100755 --- a/contrib/cirrus/runner.sh +++ b/contrib/cirrus/runner.sh @@ -121,7 +121,6 @@ function _run_bindings() { function _run_docker-py() { source .venv/docker-py/bin/activate - make binaries make run-docker-py-tests } @@ -374,8 +373,9 @@ dotest() { function _bail_if_test_can_be_skipped() { local head base diffs - # Cirrus sets these for PRs but not cron. In cron, we never want to skip. - for v in CIRRUS_CHANGE_IN_REPO DEST_BRANCH; do + # Cirrus sets these for PRs but not branches or cron. In cron and branches, + #we never want to skip. + for v in CIRRUS_CHANGE_IN_REPO CIRRUS_PR; do if [[ -z "${!v}" ]]; then msg "[ _cannot do selective skip: \$$v is undefined ]" return 0 diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index a7d0f7fa1..742289733 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -268,7 +268,7 @@ case "$TEST_FLAVOR" in ;; docker-py) remove_packaged_podman_files - make install PREFIX=/usr ETCDIR=/etc + make && make install PREFIX=/usr ETCDIR=/etc msg "Installing previously downloaded/cached packages" dnf install -y $PACKAGE_DOWNLOAD_DIR/python3*.rpm @@ -11,13 +11,13 @@ require ( github.com/container-orchestrated-devices/container-device-interface v0.4.0 github.com/containernetworking/cni v1.0.1 github.com/containernetworking/plugins v1.1.1 - github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057 - github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb + github.com/containers/buildah v1.25.2-0.20220423102655-8f2bb8876f3f + github.com/containers/common v0.47.5-0.20220425182415-4081e6be9356 github.com/containers/conmon v2.0.20+incompatible - github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c + github.com/containers/image/v5 v5.21.1-0.20220425080628-be085685e524 github.com/containers/ocicrypt v1.1.3 github.com/containers/psgo v1.7.2 - github.com/containers/storage v1.39.1-0.20220421071128-4899f8265d63 + github.com/containers/storage v1.39.1-0.20220422100603-8996869ae40b github.com/coreos/go-systemd/v22 v22.3.2 github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3 github.com/cyphar/filepath-securejoin v0.2.3 @@ -74,5 +74,3 @@ require ( gopkg.in/inf.v0 v0.9.1 gopkg.in/yaml.v2 v2.4.0 ) - -replace github.com/onsi/gomega => github.com/onsi/gomega v1.16.0 @@ -354,17 +354,17 @@ github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRD github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE= github.com/containernetworking/plugins v1.1.1 h1:+AGfFigZ5TiQH00vhR8qPeSatj53eNGz0C1d3wVYlHE= github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8= -github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057 h1:lKSxhMBpcHyyQrj2QJYzcm56uiSeibRdSL2KoppF6rg= -github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057/go.mod h1:iSoopbYRb6K4b5c3hXgXNkGTI/T085t2+XiGjceud94= -github.com/containers/common v0.47.5-0.20220331143923-5f14ec785c18/go.mod h1:Vr2Fn6EdzD6JNAbz8L8bTv3uWLv2p31Ih2O3EAK6Hyc= -github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb h1:TBrx1KcmWcesByqTb4Cq7F6bg7bDOjqCf6+6rbi8x4k= +github.com/containers/buildah v1.25.2-0.20220423102655-8f2bb8876f3f h1:a5Zjz9EXUDOelPdJKJiXBfDzQS1ynXL3rc16O93tcXo= +github.com/containers/buildah v1.25.2-0.20220423102655-8f2bb8876f3f/go.mod h1:fHTZF4uEZGIlR8oM0fhNvU0wYQOtDpuar8/PxTtdvR0= github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb/go.mod h1:r80nWTmJrG9EoLkuI6WfbWQDUNQVqkVuB8Oaj1VVjOA= +github.com/containers/common v0.47.5-0.20220425182415-4081e6be9356 h1:eJ1ghvyswTLRywF4YYEWrzZyOFEzlD1FUPLzJSz+wKo= +github.com/containers/common v0.47.5-0.20220425182415-4081e6be9356/go.mod h1:r80nWTmJrG9EoLkuI6WfbWQDUNQVqkVuB8Oaj1VVjOA= 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.19.2-0.20220224100137-1045fb70b094/go.mod h1:XoYK6kE0dpazFNcuS+a8lra+QfbC6s8tzv+cUuCrZpE= -github.com/containers/image/v5 v5.20.1-0.20220404163228-d03e80fc66b3/go.mod h1:2nEPM0WuinC/0ssPsMv5Iy8YaRueUUTmTp3C7bn5uro= -github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c h1:hshgYt6RAs4L0KhOEc2/qLF++2MryOfAXvTWmxYu4v4= github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c/go.mod h1:qpUuaiE2mON6xMA0PRO9GteyH9+KT+C6WygZzL5RhnE= +github.com/containers/image/v5 v5.21.1-0.20220425080628-be085685e524 h1:SEar3HX8b/tYE2m5fQ6fBMbwrTXLCzSBvxqODOfjp+E= +github.com/containers/image/v5 v5.21.1-0.20220425080628-be085685e524/go.mod h1:qpUuaiE2mON6xMA0PRO9GteyH9+KT+C6WygZzL5RhnE= github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a h1:spAGlqziZjCJL25C6F1zsQY05tfCKE9F5YwtEWWe6hU= github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= @@ -380,9 +380,8 @@ github.com/containers/storage v1.38.0/go.mod h1:lBzt28gAk5ADZuRtwdndRJyqX22vnRaX github.com/containers/storage v1.38.2/go.mod h1:INP0RPLHWBxx+pTsO5uiHlDUGHDFvWZPWprAbAlQWPQ= github.com/containers/storage v1.38.3-0.20220301151551-d06b0f81c0aa/go.mod h1:LkkL34WRi4dI4jt9Cp+ImdZi/P5i36glSHimT5CP5zM= github.com/containers/storage v1.39.0/go.mod h1:UAD0cKLouN4BOQRgZut/nMjrh/EnTCjSNPgp4ZuGWMs= -github.com/containers/storage v1.39.1-0.20220330193934-f3200eb5a5d9/go.mod h1:IMa2AfBI+Fxxk2hQqLTGhpJX6z2pZS1/I785QJeUwUY= -github.com/containers/storage v1.39.1-0.20220421071128-4899f8265d63 h1:57UXh6fThYqCUJ6iFwHnlFNoWSWlXylkW4H1VRs05mM= -github.com/containers/storage v1.39.1-0.20220421071128-4899f8265d63/go.mod h1:hFiHLMgNU0r3MiUpE97hEBaEKCN8fEIuEEBXoFC9eN0= +github.com/containers/storage v1.39.1-0.20220422100603-8996869ae40b h1:nGXmBAy71/Zjvi0K9fn8bvfZR15+IRxoxqGa0XPs774= +github.com/containers/storage v1.39.1-0.20220422100603-8996869ae40b/go.mod h1:hFiHLMgNU0r3MiUpE97hEBaEKCN8fEIuEEBXoFC9eN0= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -915,7 +914,6 @@ github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/magefile/mage v1.12.1/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -github.com/magefile/mage v1.13.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= @@ -1058,6 +1056,7 @@ github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2f github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -1071,8 +1070,19 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= +github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +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.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= 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= @@ -1314,7 +1324,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/sylabs/release-tools v0.1.0/go.mod h1:pqP/z/11/rYMQ0OM/Nn7TxGijw7KfZwW9UolD/J1TUo= github.com/sylabs/sif/v2 v2.3.2/go.mod h1:IrLX2pzmQ2O4qgv5iy3HdKJcBNYds9DTMd9Je8A9tX4= -github.com/sylabs/sif/v2 v2.4.2/go.mod h1:6gQvzNKRIqr4FS08XBfHpkpnxv9b7h58GLkSJ1zdK9A= github.com/sylabs/sif/v2 v2.6.0 h1:nrWbtSAavp4T6gETg/QgZXxs67qTpSNEgqs2H1y228w= github.com/sylabs/sif/v2 v2.6.0/go.mod h1:TiyBWsgWeh5yBeQFNuQnvROwswqK7YJT8JA1L53bsXQ= github.com/sylvia7788/contextcheck v1.0.4/go.mod h1:vuPKJMQ7MQ91ZTqfdyreNKwZjyUg6KO+IebVyQDedZQ= @@ -1576,10 +1585,12 @@ golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 3cfe19517..a312f5a0c 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -23,6 +23,7 @@ import ( "github.com/containers/common/libnetwork/etchosts" "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" + "github.com/containers/common/pkg/machine" "github.com/containers/common/pkg/netns" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/events" @@ -62,7 +63,7 @@ const ( // This is need because a HostIP of 127.0.0.1 would now allow the gvproxy forwarder to reach to open ports. // For machine the HostIP must only be used by gvproxy and never in the VM. func (c *Container) convertPortMappings() []types.PortMapping { - if !c.runtime.config.Engine.MachineEnabled || len(c.config.PortMappings) == 0 { + if !machine.IsGvProxyBased() || len(c.config.PortMappings) == 0 { return c.config.PortMappings } // if we run in a machine VM we have to ignore the host IP part diff --git a/libpod/networking_machine.go b/libpod/networking_machine.go index d2a6b7cfa..73089c474 100644 --- a/libpod/networking_machine.go +++ b/libpod/networking_machine.go @@ -14,6 +14,7 @@ import ( "time" "github.com/containers/common/libnetwork/types" + "github.com/containers/common/pkg/machine" "github.com/sirupsen/logrus" ) @@ -117,7 +118,7 @@ func annotateGvproxyResponseError(r io.Reader) error { // exposeMachinePorts exposes the ports for podman machine via gvproxy func (r *Runtime) exposeMachinePorts(ports []types.PortMapping) error { - if !r.config.Engine.MachineEnabled { + if !machine.IsGvProxyBased() { return nil } return requestMachinePorts(true, ports) @@ -125,7 +126,7 @@ func (r *Runtime) exposeMachinePorts(ports []types.PortMapping) error { // unexposeMachinePorts closes the ports for podman machine via gvproxy func (r *Runtime) unexposeMachinePorts(ports []types.PortMapping) error { - if !r.config.Engine.MachineEnabled { + if !machine.IsGvProxyBased() { return nil } return requestMachinePorts(false, ports) diff --git a/pkg/machine/config.go b/pkg/machine/config.go index 6c2fab0e5..1103933cd 100644 --- a/pkg/machine/config.go +++ b/pkg/machine/config.go @@ -121,7 +121,7 @@ type VM interface { Set(name string, opts SetOptions) error SSH(name string, opts SSHOptions) error Start(name string, opts StartOptions) error - State() (Status, error) + State(bypass bool) (Status, error) Stop(name string, opts StopOptions) error } diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go index fe47437e3..35a9a30cb 100644 --- a/pkg/machine/ignition.go +++ b/pkg/machine/ignition.go @@ -304,6 +304,8 @@ ExecStart=/usr/bin/sleep infinity containers := `[containers] netns="bridge" ` + // Set deprecated machine_enabled until podman package on fcos is + // current enough to no longer require it rootContainers := `[engine] machine_enabled=true ` @@ -392,7 +394,7 @@ Delegate=memory pids cpu io FileEmbedded1: FileEmbedded1{Mode: intToPtr(0644)}, }) - // Set machine_enabled to true to indicate we're in a VM + // Set deprecated machine_enabled to true to indicate we're in a VM files = append(files, File{ Node: Node{ Group: getNodeGrp("root"), @@ -408,6 +410,22 @@ Delegate=memory pids cpu io }, }) + // Set machine marker file to indicate podman is in a qemu based machine + files = append(files, File{ + Node: Node{ + Group: getNodeGrp("root"), + Path: "/etc/containers/podman-machine", + User: getNodeUsr("root"), + }, + FileEmbedded1: FileEmbedded1{ + Append: nil, + Contents: Resource{ + Source: encodeDataURLPtr("qemu\n"), + }, + Mode: intToPtr(0644), + }, + }) + // Issue #11489: make sure that we can inject a custom registries.conf // file on the system level to force a single search registry. // The remote client does not yet support prompting for short-name diff --git a/pkg/machine/qemu/config.go b/pkg/machine/qemu/config.go index 7340de604..9473eef6f 100644 --- a/pkg/machine/qemu/config.go +++ b/pkg/machine/qemu/config.go @@ -86,6 +86,12 @@ type MachineVM struct { ResourceConfig // SSHConfig for accessing the remote vm SSHConfig + // Starting tells us whether the machine is running or if we have just dialed it to start it + Starting bool + // Created contains the original created time instead of querying the file mod time + Created time.Time + // LastUp contains the last recorded uptime + LastUp time.Time } // ImageConfig describes the bootable image for the VM diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index 69a986102..969acb760 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -94,6 +94,8 @@ func (p *Provider) NewMachine(opts machine.InitOptions) (machine.VM, error) { vm.Memory = opts.Memory vm.DiskSize = opts.DiskSize + vm.Created = time.Now() + // Find the qemu executable cfg, err := config.Default() if err != nil { @@ -436,7 +438,7 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error { return nil } - state, err := v.State() + state, err := v.State(false) if err != nil { return err } @@ -477,6 +479,17 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error { wait = time.Millisecond * 500 ) + v.Starting = true + if err := v.writeConfig(); err != nil { + return fmt.Errorf("writing JSON file: %w", err) + } + defer func() error { + v.Starting = false + if err := v.writeConfig(); err != nil { + return fmt.Errorf("writing JSON file: %w", err) + } + return nil + }() if v.isIncompatible() { logrus.Errorf("machine %q is incompatible with this release of podman and needs to be recreated, starting for recovery only", v.Name) } @@ -498,6 +511,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error { return err } } + // If the qemusocketpath exists and the vm is off/down, we should rm // it before the dial as to avoid a segv if err := v.QMPMonitor.Address.Delete(); err != nil { @@ -589,14 +603,14 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error { return err } if len(v.Mounts) > 0 { - state, err := v.State() + state, err := v.State(true) if err != nil { return err } listening := v.isListening() for state != machine.Running || !listening { time.Sleep(100 * time.Millisecond) - state, err = v.State() + state, err = v.State(true) if err != nil { return err } @@ -638,7 +652,6 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error { } v.waitAPIAndPrintInfo(forwardState, forwardSock) - return nil } @@ -647,9 +660,10 @@ func (v *MachineVM) checkStatus(monitor *qmp.SocketMonitor) (machine.Status, err // {"return": {"status": "running", "singlestep": false, "running": true}} type statusDetails struct { - Status string `json:"status"` - Step bool `json:"singlestep"` - Running bool `json:"running"` + Status string `json:"status"` + Step bool `json:"singlestep"` + Running bool `json:"running"` + Starting bool `json:"starting"` } type statusResponse struct { Response statusDetails `json:"return"` @@ -735,6 +749,11 @@ func (v *MachineVM) Stop(_ string, _ machine.StopOptions) error { if p == nil && err != nil { return err } + + v.LastUp = time.Now() + if err := v.writeConfig(); err != nil { // keep track of last up + return err + } // Kill the process if err := p.Kill(); err != nil { return err @@ -756,7 +775,7 @@ func (v *MachineVM) Stop(_ string, _ machine.StopOptions) error { disconnected = true waitInternal := 250 * time.Millisecond for i := 0; i < 5; i++ { - state, err := v.State() + state, err := v.State(false) if err != nil { return err } @@ -808,7 +827,7 @@ func (v *MachineVM) Remove(_ string, opts machine.RemoveOptions) (string, func() ) // cannot remove a running vm unless --force is used - state, err := v.State() + state, err := v.State(false) if err != nil { return "", nil, err } @@ -874,12 +893,19 @@ func (v *MachineVM) Remove(_ string, opts machine.RemoveOptions) (string, func() }, nil } -func (v *MachineVM) State() (machine.Status, error) { +func (v *MachineVM) State(bypass bool) (machine.Status, error) { // Check if qmp socket path exists if _, err := os.Stat(v.QMPMonitor.Address.GetPath()); os.IsNotExist(err) { return "", nil } + err := v.update() + if err != nil { + return "", err + } // Check if we can dial it + if v.Starting && !bypass { + return "", nil + } monitor, err := qmp.NewSocketMonitor(v.QMPMonitor.Network, v.QMPMonitor.Address.GetPath(), v.QMPMonitor.Timeout) if err != nil { // FIXME: this error should probably be returned @@ -910,7 +936,7 @@ func (v *MachineVM) isListening() bool { // SSH opens an interactive SSH session to the vm specified. // Added ssh function to VM interface: pkg/machine/config/go : line 58 func (v *MachineVM) SSH(_ string, opts machine.SSHOptions) error { - state, err := v.State() + state, err := v.State(true) if err != nil { return err } @@ -1024,20 +1050,29 @@ func getVMInfos() ([]*machine.ListResponse, error) { listEntry.Port = vm.Port listEntry.RemoteUsername = vm.RemoteUsername listEntry.IdentityPath = vm.IdentityPath - fi, err := os.Stat(fullPath) - if err != nil { - return err + listEntry.CreatedAt = vm.Created + + if listEntry.CreatedAt.IsZero() { + listEntry.CreatedAt = time.Now() + vm.Created = time.Now() + if err := vm.writeConfig(); err != nil { + return err + } } - listEntry.CreatedAt = fi.ModTime() - fi, err = os.Stat(vm.getImageFile()) + state, err := vm.State(false) if err != nil { return err } - listEntry.LastUp = fi.ModTime() - state, err := vm.State() - if err != nil { - return err + + if !vm.LastUp.IsZero() { + listEntry.LastUp = vm.LastUp + } else { + listEntry.LastUp = vm.Created + vm.Created = time.Now() + if err := vm.writeConfig(); err != nil { + return err + } } if state == machine.Running { listEntry.Running = true diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go index dff7bfef9..f57dbd299 100644 --- a/pkg/machine/wsl/machine.go +++ b/pkg/machine/wsl/machine.go @@ -448,6 +448,10 @@ func configureSystem(v *MachineVM, dist string) error { return errors.Wrap(err, "could not create containers.conf for guest OS") } + if err := runCmdPassThrough("wsl", "-d", dist, "sh", "-c", "echo wsl > /etc/containers/podman-machine"); err != nil { + return errors.Wrap(err, "could not create podman-machine file for guest OS") + } + return nil } @@ -1024,7 +1028,7 @@ func (v *MachineVM) Stop(name string, _ machine.StopOptions) error { // TODO: We need to rename isRunning to State(); I do not have a // windows system to test this on. -func (v *MachineVM) State() (machine.Status, error) { +func (v *MachineVM) State(bypass bool) (machine.Status, error) { return "", define.ErrNotImplemented } diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index e4d89294e..5af9a978b 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -30,7 +30,7 @@ import ( ) /* -#cgo remoteclient CFLAGS: -Wall -Werror -DDISABLE_JOIN_SHORTCUT +#cgo remote CFLAGS: -Wall -Werror -DDISABLE_JOIN_SHORTCUT #include <stdlib.h> #include <sys/types.h> extern uid_t rootless_uid(); diff --git a/pkg/specgen/volumes.go b/pkg/specgen/volumes.go index eca8c0c35..b26666df3 100644 --- a/pkg/specgen/volumes.go +++ b/pkg/specgen/volumes.go @@ -65,7 +65,7 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na err error ) - splitVol := strings.Split(vol, ":") + splitVol := SplitVolumeString(vol) if len(splitVol) > 3 { return nil, nil, nil, errors.Wrapf(volumeFormatErr, vol) } @@ -93,7 +93,7 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na } } - if strings.HasPrefix(src, "/") || strings.HasPrefix(src, ".") { + if strings.HasPrefix(src, "/") || strings.HasPrefix(src, ".") || isHostWinPath(src) { // This is not a named volume overlayFlag := false chownFlag := false @@ -152,3 +152,26 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na return mounts, volumes, overlayVolumes, nil } + +// Splits a volume string, accounting for Win drive paths +// when running as a WSL linux guest or Windows client +func SplitVolumeString(vol string) []string { + parts := strings.Split(vol, ":") + if !shouldResolveWinPaths() { + return parts + } + + // Skip extended marker prefix if present + n := 0 + if strings.HasPrefix(vol, `\\?\`) { + n = 4 + } + + if hasWinDriveScheme(vol, n) { + first := parts[0] + ":" + parts[1] + parts = parts[1:] + parts[0] = first + } + + return parts +} diff --git a/pkg/specgen/winpath.go b/pkg/specgen/winpath.go new file mode 100644 index 000000000..f4249fab1 --- /dev/null +++ b/pkg/specgen/winpath.go @@ -0,0 +1,59 @@ +package specgen + +import ( + "fmt" + "strings" + "unicode" + + "github.com/pkg/errors" +) + +func isHostWinPath(path string) bool { + return shouldResolveWinPaths() && strings.HasPrefix(path, `\\`) || hasWinDriveScheme(path, 0) || winPathExists(path) +} + +func hasWinDriveScheme(path string, start int) bool { + if len(path) < start+2 || path[start+1] != ':' { + return false + } + + drive := rune(path[start]) + return drive < unicode.MaxASCII && unicode.IsLetter(drive) +} + +// Converts a Windows path to a WSL guest path if local env is a WSL linux guest or this is a Windows client. +func ConvertWinMountPath(path string) (string, error) { + if !shouldResolveWinPaths() { + return path, nil + } + + if strings.HasPrefix(path, "/") { + // Handle /[driveletter]/windows/path form (e.g. c:\Users\bar == /c/Users/bar) + if len(path) > 2 && path[2] == '/' && shouldResolveUnixWinVariant(path) { + drive := unicode.ToLower(rune(path[1])) + if unicode.IsLetter(drive) && drive <= unicode.MaxASCII { + return fmt.Sprintf("/mnt/%c/%s", drive, path[3:]), nil + } + } + + // unix path - pass through + return path, nil + } + + // Convert remote win client relative paths to absolute + path = resolveRelativeOnWindows(path) + + // Strip extended marker prefix if present + path = strings.TrimPrefix(path, `\\?\`) + + // Drive installed via wsl --mount + if strings.HasPrefix(path, `\\.\`) { + path = "/mnt/wsl/" + path[4:] + } else if len(path) > 1 && path[1] == ':' { + path = "/mnt/" + strings.ToLower(path[0:1]) + path[2:] + } else { + return path, errors.New("unsupported UNC path") + } + + return strings.ReplaceAll(path, `\`, "/"), nil +} diff --git a/pkg/specgen/winpath_linux.go b/pkg/specgen/winpath_linux.go new file mode 100644 index 000000000..f42ac7639 --- /dev/null +++ b/pkg/specgen/winpath_linux.go @@ -0,0 +1,24 @@ +package specgen + +import ( + "os" + + "github.com/containers/common/pkg/machine" +) + +func shouldResolveWinPaths() bool { + return machine.MachineHostType() == "wsl" +} + +func shouldResolveUnixWinVariant(path string) bool { + _, err := os.Stat(path) + return err != nil +} + +func resolveRelativeOnWindows(path string) string { + return path +} + +func winPathExists(path string) bool { + return false +} diff --git a/pkg/specgen/winpath_unsupported.go b/pkg/specgen/winpath_unsupported.go new file mode 100644 index 000000000..4cd008fdd --- /dev/null +++ b/pkg/specgen/winpath_unsupported.go @@ -0,0 +1,20 @@ +//go:build !linux && !windows +// +build !linux,!windows + +package specgen + +func shouldResolveWinPaths() bool { + return false +} + +func shouldResolveUnixWinVariant(path string) bool { + return false +} + +func resolveRelativeOnWindows(path string) string { + return path +} + +func winPathExists(path string) bool { + return false +} diff --git a/pkg/specgen/winpath_windows.go b/pkg/specgen/winpath_windows.go new file mode 100644 index 000000000..c6aad314a --- /dev/null +++ b/pkg/specgen/winpath_windows.go @@ -0,0 +1,30 @@ +package specgen + +import ( + "github.com/sirupsen/logrus" + "os" + "path/filepath" +) + +func shouldResolveUnixWinVariant(path string) bool { + return true +} + +func shouldResolveWinPaths() bool { + return true +} + +func resolveRelativeOnWindows(path string) string { + ret, err := filepath.Abs(path) + if err != nil { + logrus.Debugf("problem resolving possible relative path %q: %s", path, err.Error()) + return path + } + + return ret +} + +func winPathExists(path string) bool { + _, err := os.Stat(path) + return err == nil +} diff --git a/pkg/specgenutil/specgenutil_test.go b/pkg/specgenutil/specgenutil_test.go new file mode 100644 index 000000000..5867b0ae0 --- /dev/null +++ b/pkg/specgenutil/specgenutil_test.go @@ -0,0 +1,77 @@ +//go:build linux +// +build linux + +package specgenutil + +import ( + "testing" + + "github.com/containers/common/pkg/machine" + "github.com/containers/podman/v4/pkg/domain/entities" + "github.com/containers/podman/v4/pkg/specgen" + "github.com/stretchr/testify/assert" +) + +func TestWinPath(t *testing.T) { + const ( + fail = false + pass = true + ) + tests := []struct { + vol string + source string + dest string + isN bool + outcome bool + mach string + }{ + {`C:\Foo:/blah`, "/mnt/c/Foo", "/blah", false, pass, "wsl"}, + {`C:\Foo:/blah`, "/mnt/c/Foo", "/blah", false, fail, ""}, + {`\\?\C:\Foo:/blah`, "/mnt/c/Foo", "/blah", false, pass, "wsl"}, + {`/c/bar:/blah`, "/mnt/c/bar", "/blah", false, pass, "wsl"}, + {`/c/bar:/blah`, "/c/bar", "/blah", false, pass, ""}, + {`/test/this:/blah`, "/test/this", "/blah", false, pass, "wsl"}, + {`c:/bar/something:/other`, "/mnt/c/bar/something", "/other", false, pass, "wsl"}, + {`c:/foo:ro`, "c", "/foo", true, pass, ""}, + {`\\computer\loc:/dest`, "", "", false, fail, "wsl"}, + {`\\.\drive\loc:/target`, "/mnt/wsl/drive/loc", "/target", false, pass, "wsl"}, + } + + f := func(vol string, mach string) (*specgen.SpecGenerator, error) { + machine := machine.GetMachineMarker() + oldEnable, oldType := machine.Enabled, machine.Type + machine.Enabled, machine.Type = len(mach) > 0, mach + sg := specgen.NewSpecGenerator("nothing", false) + err := FillOutSpecGen(sg, &entities.ContainerCreateOptions{ + ImageVolume: "ignore", + Volume: []string{vol}}, []string{}, + ) + machine.Enabled, machine.Type = oldEnable, oldType + return sg, err + } + + for _, test := range tests { + msg := "Checking: " + test.vol + sg, err := f(test.vol, test.mach) + if test.outcome == fail { + assert.NotNil(t, err, msg) + continue + } + if !assert.Nil(t, err, msg) { + continue + } + if test.isN { + if !assert.Equal(t, 1, len(sg.Volumes), msg) { + continue + } + assert.Equal(t, test.source, sg.Volumes[0].Name, msg) + assert.Equal(t, test.dest, sg.Volumes[0].Dest, msg) + } else { + if !assert.Equal(t, 1, len(sg.Mounts), msg) { + continue + } + assert.Equal(t, test.source, sg.Mounts[0].Source, msg) + assert.Equal(t, test.dest, sg.Mounts[0].Destination, msg) + } + } +} diff --git a/pkg/specgenutil/volumes.go b/pkg/specgenutil/volumes.go index 95ce420f8..50d745380 100644 --- a/pkg/specgenutil/volumes.go +++ b/pkg/specgenutil/volumes.go @@ -3,7 +3,7 @@ package specgenutil import ( "encoding/csv" "fmt" - "path/filepath" + "path" "strings" "github.com/containers/common/pkg/parse" @@ -123,7 +123,7 @@ func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, addReadOnlyTmpfs bo finalMounts := make([]spec.Mount, 0, len(unifiedMounts)) for _, mount := range unifiedMounts { if mount.Type == define.TypeBind { - absSrc, err := filepath.Abs(mount.Source) + absSrc, err := specgen.ConvertWinMountPath(mount.Source) if err != nil { return nil, nil, nil, nil, errors.Wrapf(err, "error getting absolute path of %s", mount.Source) } @@ -334,7 +334,7 @@ func getBindMount(args []string) (spec.Mount, error) { if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil { return newMount, err } - newMount.Destination = filepath.Clean(kv[1]) + newMount.Destination = unixPathClean(kv[1]) setDest = true case "relabel": if setRelabel { @@ -456,7 +456,7 @@ func getTmpfsMount(args []string) (spec.Mount, error) { if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil { return newMount, err } - newMount.Destination = filepath.Clean(kv[1]) + newMount.Destination = unixPathClean(kv[1]) setDest = true case "U", "chown": if setOwnership { @@ -507,7 +507,7 @@ func getDevptsMount(args []string) (spec.Mount, error) { if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil { return newMount, err } - newMount.Destination = filepath.Clean(kv[1]) + newMount.Destination = unixPathClean(kv[1]) setDest = true default: return newMount, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0]) @@ -572,7 +572,7 @@ func getNamedVolume(args []string) (*specgen.NamedVolume, error) { if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil { return nil, err } - newVolume.Dest = filepath.Clean(kv[1]) + newVolume.Dest = unixPathClean(kv[1]) setDest = true case "U", "chown": if setOwnership { @@ -624,7 +624,7 @@ func getImageVolume(args []string) (*specgen.ImageVolume, error) { if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil { return nil, err } - newVolume.Destination = filepath.Clean(kv[1]) + newVolume.Destination = unixPathClean(kv[1]) case "rw", "readwrite": switch kv[1] { case "true": @@ -670,7 +670,7 @@ func getTmpfsMounts(tmpfsFlag []string) (map[string]spec.Mount, error) { } mount := spec.Mount{ - Destination: filepath.Clean(destPath), + Destination: unixPathClean(destPath), Type: define.TypeTmpfs, Options: options, Source: define.TypeTmpfs, @@ -700,3 +700,8 @@ func validChownFlag(flag string) (bool, error) { return true, nil } + +// Use path instead of filepath to preserve Unix style paths on Windows +func unixPathClean(p string) string { + return path.Clean(p) +} diff --git a/test/buildah-bud/apply-podman-deltas b/test/buildah-bud/apply-podman-deltas index b30c95d59..66e8687de 100755 --- a/test/buildah-bud/apply-podman-deltas +++ b/test/buildah-bud/apply-podman-deltas @@ -136,32 +136,17 @@ errmsg "no such file or directory" \ ############################################################################### # BEGIN tests that don't make sense under podman due to fundamental differences + # TODO -# Some of the podman tests in CI expects exit code 125, which might not be true -# since exit code from runtime is relayed as it is without any modification both -# in `buildah` and `podman`. Following behaviour is seen when PR https://github.com/containers/buildah/pull/3809 -# added a test here https://github.com/containers/buildah/blob/main/tests/bud.bats#L3183 -# which relays exit code from runtime as it is, in case of both `podman` and `buildah`. -# However apart from this test case no other test case was able to trigger this behavior -# hence marking this test as an anomaly. Since its debatable if we should override this -# returned error number or not hence adding a note here. -skip "podman CI expects all exit code to be 125 this test has anomaly behaviour" \ - "bud with --add-host" - -skip "podman CI expects all exit code to be 125 this test has anomaly behaviour" \ +# Normally, when buildah exits 1 on error, podman exits 125. +# These tests are the exception. They exit 1 under podman. +skip "these tests exit 1 under podman, not 125" \ + "bud with --add-host" \ "bud - invalid runtime flags test" skip "does not work under podman" \ "bud without any arguments should succeed" -skip "podman requires a directory, not a Dockerfile" \ - "bud with specified context should succeed if context contains existing Dockerfile" - -# ...or due to Ed's laziness -skip "Too much effort to spin up a local registry" \ - "bud with encrypted FROM image" \ - "bud --authfile" - # ...or due to a fundamental arg-parsing difference between buildah and podman # which we could and perhaps should fix in the buildah repo via: # - ... ${TESTSDIR}/bud/layers-squash/Dockerfile.hardlinks @@ -172,11 +157,6 @@ skip "FIXME FIXME FIXME: argument-order incompatible with podman" \ skip "FIXME FIXME FIXME: this passes on Ed's laptop, fails in CI??" \ "bud-multi-stage-nocache-nocommit" -# This will probably never work: buildah and podman have incompatible defaults -# Documented in https://github.com/containers/podman/issues/10412 -skip "buildah runs with --cgroup-manager=cgroupfs, podman with systemd" \ - "bud with --cgroup-parent" - ############################################################################### # BEGIN tests which are skipped because they make no sense under podman-remote @@ -200,6 +180,10 @@ skip_if_remote "volumes don't work with podman-remote" \ "buildah bud --volume" \ "buildah-bud-policy" +# Requires a local file outside context dir +skip_if_remote "local keyfile not sent to podman-remote" \ + "bud with encrypted FROM image" + # See podman #9890 for discussion skip_if_remote "--stdin option will not be implemented in podman-remote" \ "bud test no --stdin" diff --git a/test/buildah-bud/buildah-tests.diff b/test/buildah-bud/buildah-tests.diff index ca38b5a10..d8b7e177f 100644 --- a/test/buildah-bud/buildah-tests.diff +++ b/test/buildah-bud/buildah-tests.diff @@ -1,15 +1,15 @@ -From 1a5562929a85074a7498165191558f434bb30bf1 Mon Sep 17 00:00:00 2001 +From a2cf44e9b58955d682626e95b493450242fb8394 Mon Sep 17 00:00:00 2001 From: Ed Santiago <santiago@redhat.com> Date: Tue, 9 Feb 2021 17:28:05 -0700 Subject: [PATCH] tweaks for running buildah tests under podman Signed-off-by: Ed Santiago <santiago@redhat.com> --- - tests/helpers.bash | 73 +++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 69 insertions(+), 4 deletions(-) + tests/helpers.bash | 69 ++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/tests/helpers.bash b/tests/helpers.bash -index 2bb6b429..0dc98a85 100644 +index b5713550..34fcfa3a 100644 --- a/tests/helpers.bash +++ b/tests/helpers.bash @@ -43,6 +43,23 @@ EOF @@ -36,9 +36,9 @@ index 2bb6b429..0dc98a85 100644 } function starthttpd() { -@@ -85,6 +102,12 @@ function teardown_tests() { - stophttpd +@@ -86,6 +103,12 @@ function teardown_tests() { stop_git_daemon + stop_registry + if [[ -n "$PODMAN_SERVER_PID" ]]; then + kill $PODMAN_SERVER_PID @@ -49,22 +49,18 @@ index 2bb6b429..0dc98a85 100644 # Workaround for #1991 - buildah + overlayfs leaks mount points. # Many tests leave behind /var/tmp/.../root/overlay and sub-mounts; # let's find those and clean them up, otherwise 'rm -rf' fails. -@@ -157,7 +180,13 @@ function copy() { +@@ -178,6 +201,10 @@ function podman() { + command ${PODMAN_BINARY:-podman} ${PODMAN_REGISTRY_OPTS} ${ROOTDIR_OPTS} "$@" } - function podman() { -- command podman ${PODMAN_REGISTRY_OPTS} ${ROOTDIR_OPTS} "$@" -+ echo "# ... podman $*" >&3 -+ ${PODMAN_BINARY} ${PODMAN_REGISTRY_OPTS} ${ROOTDIR_OPTS} "$@" ++function podman-remote() { ++ command ${PODMAN_BINARY:-podman-remote} ${ROOTDIR_OPTS} "$@" +} + -+function podman-remote() { -+ echo "# ... podman-remote $*" >&3 -+ ${PODMAN_BINARY} ${ROOTDIR_OPTS} "$@" - } - # There are various scenarios where we would like to execute `tests` as rootless user, however certain commands like `buildah mount` -@@ -221,8 +250,35 @@ function run_buildah() { + # do not work in rootless session since a normal user cannot mount a filesystem unless they're in a user namespace along with its + # own mount namespace. In order to run such specific commands from a rootless session we must perform `buildah unshare`. +@@ -239,8 +266,35 @@ function run_buildah() { --retry) retry=3; shift;; # retry network flakes esac @@ -101,7 +97,7 @@ index 2bb6b429..0dc98a85 100644 # If session is rootless and `buildah mount` is invoked, perform unshare, # since normal user cannot mount a filesystem unless they're in a user namespace along with its own mount namespace. -@@ -236,8 +292,8 @@ function run_buildah() { +@@ -254,8 +308,8 @@ function run_buildah() { retry=$(( retry - 1 )) # stdout is only emitted upon error; this echo is to help a debugger @@ -112,7 +108,7 @@ index 2bb6b429..0dc98a85 100644 # without "quotes", multiple lines are glommed together into one if [ -n "$output" ]; then echo "$output" -@@ -545,6 +601,15 @@ function skip_if_no_docker() { +@@ -587,6 +641,15 @@ function skip_if_no_docker() { fi } @@ -129,5 +125,5 @@ index 2bb6b429..0dc98a85 100644 daemondir=${TESTDIR}/git-daemon mkdir -p ${daemondir}/repo -- -2.31.1 +2.35.1 diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 766f39964..6846a5677 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -462,7 +462,8 @@ func (p *PodmanTestIntegration) RunNginxWithHealthCheck(name string) (*PodmanSes if name != "" { podmanArgs = append(podmanArgs, "--name", name) } - podmanArgs = append(podmanArgs, "-dt", "-P", "--health-cmd", "curl http://localhost/", nginx) + // curl without -f exits 0 even if http code >= 400! + podmanArgs = append(podmanArgs, "-dt", "-P", "--health-cmd", "curl -f http://localhost/", nginx) session := p.Podman(podmanArgs) session.WaitWithDefaultTimeout() return session, session.OutputToString() diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go index 6373b949a..2b56502b0 100644 --- a/test/e2e/pod_infra_container_test.go +++ b/test/e2e/pod_infra_container_test.go @@ -119,11 +119,11 @@ var _ = Describe("Podman pod create", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - session = podmanTest.Podman([]string{"run", "--pod", podID, fedoraMinimal, "curl", "localhost:80"}) + session = podmanTest.Podman([]string{"run", "--pod", podID, fedoraMinimal, "curl", "-f", "localhost:80"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - session = podmanTest.Podman([]string{"run", fedoraMinimal, "curl", "localhost"}) + session = podmanTest.Podman([]string{"run", fedoraMinimal, "curl", "-f", "localhost"}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) }) @@ -219,7 +219,7 @@ var _ = Describe("Podman pod create", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - session = podmanTest.Podman([]string{"run", "--pod", podID, "--network", "bridge", nginx, "curl", "localhost"}) + session = podmanTest.Podman([]string{"run", "--pod", podID, "--network", "bridge", nginx, "curl", "-f", "localhost"}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) }) diff --git a/test/e2e/run_staticip_test.go b/test/e2e/run_staticip_test.go index b78a37495..7e61e7c5e 100644 --- a/test/e2e/run_staticip_test.go +++ b/test/e2e/run_staticip_test.go @@ -102,22 +102,33 @@ var _ = Describe("Podman run with --ip flag", func() { It("Podman run two containers with the same IP", func() { ip := GetRandomIPAddress() - result := podmanTest.Podman([]string{"run", "-dt", "--ip", ip, nginx}) + result := podmanTest.Podman([]string{"run", "-d", "--name", "nginx", "--ip", ip, nginx}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) - for i := 0; i < 10; i++ { - fmt.Println("Waiting for nginx", err) - time.Sleep(1 * time.Second) + + for retries := 20; retries > 0; retries-- { response, err := http.Get(fmt.Sprintf("http://%s", ip)) - if err != nil { - continue - } - if response.StatusCode == http.StatusOK { + if err == nil && response.StatusCode == http.StatusOK { break } + if retries == 1 { + logps := podmanTest.Podman([]string{"ps", "-a"}) + logps.WaitWithDefaultTimeout() + logps = podmanTest.Podman([]string{"logs", "nginx"}) + logps.WaitWithDefaultTimeout() + Fail("Timed out waiting for nginx container, see ps & log above.") + } + + if err != nil { + fmt.Printf("nginx not ready yet; error=%v; %d retries left...\n", err, retries) + } else { + fmt.Printf("nginx not ready yet; response=%v; %d retries left...\n", response.StatusCode, retries) + } + time.Sleep(1 * time.Second) } - result = podmanTest.Podman([]string{"run", "-ti", "--ip", ip, ALPINE, "ip", "addr"}) + result = podmanTest.Podman([]string{"run", "--ip", ip, ALPINE, "ip", "addr"}) result.WaitWithDefaultTimeout() Expect(result).To(ExitWithError()) + Expect(result.ErrorToString()).To(ContainSubstring(" address %s ", ip)) }) }) diff --git a/vendor/github.com/containers/buildah/Makefile b/vendor/github.com/containers/buildah/Makefile index 003d209ff..95ce322b8 100644 --- a/vendor/github.com/containers/buildah/Makefile +++ b/vendor/github.com/containers/buildah/Makefile @@ -37,7 +37,7 @@ LIBSECCOMP_COMMIT := release-2.3 EXTRA_LDFLAGS ?= BUILDAH_LDFLAGS := $(GO_LDFLAGS) '-X main.GitCommit=$(GIT_COMMIT) -X main.buildInfo=$(SOURCE_DATE_EPOCH) -X main.cniVersion=$(CNI_COMMIT) $(EXTRA_LDFLAGS)' -SOURCES=*.go imagebuildah/*.go bind/*.go chroot/*.go copier/*.go define/*.go docker/*.go manifests/*.go pkg/chrootuser/*.go pkg/cli/*.go pkg/completion/*.go pkg/formats/*.go pkg/overlay/*.go pkg/parse/*.go pkg/rusage/*.go pkg/sshagent/*.go pkg/umask/*.go pkg/util/*.go util/*.go +SOURCES=*.go imagebuildah/*.go bind/*.go chroot/*.go copier/*.go define/*.go docker/*.go internal/parse/*.go internal/source/*.go internal/util/*.go manifests/*.go pkg/chrootuser/*.go pkg/cli/*.go pkg/completion/*.go pkg/formats/*.go pkg/overlay/*.go pkg/parse/*.go pkg/rusage/*.go pkg/sshagent/*.go pkg/umask/*.go pkg/util/*.go util/*.go LINTFLAGS ?= diff --git a/vendor/github.com/containers/buildah/go.mod b/vendor/github.com/containers/buildah/go.mod index 6fb3653fd..f9023c3a8 100644 --- a/vendor/github.com/containers/buildah/go.mod +++ b/vendor/github.com/containers/buildah/go.mod @@ -1,14 +1,14 @@ module github.com/containers/buildah -go 1.13 +go 1.16 require ( github.com/containerd/containerd v1.6.2 github.com/containernetworking/cni v1.0.1 - github.com/containers/common v0.47.5-0.20220331143923-5f14ec785c18 - github.com/containers/image/v5 v5.20.1-0.20220404163228-d03e80fc66b3 + github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb + github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c github.com/containers/ocicrypt v1.1.3 - github.com/containers/storage v1.39.1-0.20220330193934-f3200eb5a5d9 + github.com/containers/storage v1.39.1-0.20220422100603-8996869ae40b github.com/docker/distribution v2.8.1+incompatible github.com/docker/docker v20.10.14+incompatible github.com/docker/go-units v0.4.0 @@ -37,7 +37,7 @@ require ( github.com/stretchr/testify v1.7.1 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 go.etcd.io/bbolt v1.3.6 - golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 + golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 diff --git a/vendor/github.com/containers/buildah/go.sum b/vendor/github.com/containers/buildah/go.sum index 86c79279a..6b306f33a 100644 --- a/vendor/github.com/containers/buildah/go.sum +++ b/vendor/github.com/containers/buildah/go.sum @@ -72,8 +72,9 @@ github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU= github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I= +github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= @@ -109,6 +110,7 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/ProtonMail/go-crypto v0.0.0-20210920160938-87db9fbc61c7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/ProtonMail/go-crypto v0.0.0-20220113124808-70ae35bab23f/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= +github.com/ProtonMail/go-crypto v0.0.0-20220407094043-a94812496cf5/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= @@ -279,8 +281,9 @@ github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+EL github.com/containerd/stargz-snapshotter/estargz v0.9.0/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0= github.com/containerd/stargz-snapshotter/estargz v0.11.0/go.mod h1:/KsZXsJRllMbTKFfG0miFQWViQKdI9+9aSXs+HN0+ac= github.com/containerd/stargz-snapshotter/estargz v0.11.1/go.mod h1:6VoPcf4M1wvnogWxqc4TqBWWErCS+R+ucnPZId2VbpQ= -github.com/containerd/stargz-snapshotter/estargz v0.11.3 h1:k2kN16Px6LYuv++qFqK+JTcYqc8bEVxzGpf8/gFBL5M= github.com/containerd/stargz-snapshotter/estargz v0.11.3/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0= +github.com/containerd/stargz-snapshotter/estargz v0.11.4 h1:LjrYUZpyOhiSaU7hHrdR82/RBoxfGWSaC0VeSSMXqnk= +github.com/containerd/stargz-snapshotter/estargz v0.11.4/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= @@ -306,11 +309,11 @@ github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRD github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE= github.com/containernetworking/plugins v1.1.1 h1:+AGfFigZ5TiQH00vhR8qPeSatj53eNGz0C1d3wVYlHE= github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8= -github.com/containers/common v0.47.5-0.20220331143923-5f14ec785c18 h1:Hp4ccfzcFpS2SAha0cfYcF6ofkaEFmgsuRSxBDK8W0Y= -github.com/containers/common v0.47.5-0.20220331143923-5f14ec785c18/go.mod h1:Vr2Fn6EdzD6JNAbz8L8bTv3uWLv2p31Ih2O3EAK6Hyc= +github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb h1:TBrx1KcmWcesByqTb4Cq7F6bg7bDOjqCf6+6rbi8x4k= +github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb/go.mod h1:r80nWTmJrG9EoLkuI6WfbWQDUNQVqkVuB8Oaj1VVjOA= github.com/containers/image/v5 v5.19.2-0.20220224100137-1045fb70b094/go.mod h1:XoYK6kE0dpazFNcuS+a8lra+QfbC6s8tzv+cUuCrZpE= -github.com/containers/image/v5 v5.20.1-0.20220404163228-d03e80fc66b3 h1:5oH8xNWulK0r7hfga9RsEZfh2JJXSn1UfSc6uPBgcP8= -github.com/containers/image/v5 v5.20.1-0.20220404163228-d03e80fc66b3/go.mod h1:2nEPM0WuinC/0ssPsMv5Iy8YaRueUUTmTp3C7bn5uro= +github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c h1:hshgYt6RAs4L0KhOEc2/qLF++2MryOfAXvTWmxYu4v4= +github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c/go.mod h1:qpUuaiE2mON6xMA0PRO9GteyH9+KT+C6WygZzL5RhnE= github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a h1:spAGlqziZjCJL25C6F1zsQY05tfCKE9F5YwtEWWe6hU= github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= @@ -323,8 +326,8 @@ github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c github.com/containers/storage v1.38.2/go.mod h1:INP0RPLHWBxx+pTsO5uiHlDUGHDFvWZPWprAbAlQWPQ= github.com/containers/storage v1.38.3-0.20220301151551-d06b0f81c0aa/go.mod h1:LkkL34WRi4dI4jt9Cp+ImdZi/P5i36glSHimT5CP5zM= github.com/containers/storage v1.39.0/go.mod h1:UAD0cKLouN4BOQRgZut/nMjrh/EnTCjSNPgp4ZuGWMs= -github.com/containers/storage v1.39.1-0.20220330193934-f3200eb5a5d9 h1:fA/2FemaDv+POCJgg+QGJm84gMEDBwL5H0lDeubDJoE= -github.com/containers/storage v1.39.1-0.20220330193934-f3200eb5a5d9/go.mod h1:IMa2AfBI+Fxxk2hQqLTGhpJX6z2pZS1/I785QJeUwUY= +github.com/containers/storage v1.39.1-0.20220422100603-8996869ae40b h1:nGXmBAy71/Zjvi0K9fn8bvfZR15+IRxoxqGa0XPs774= +github.com/containers/storage v1.39.1-0.20220422100603-8996869ae40b/go.mod h1:hFiHLMgNU0r3MiUpE97hEBaEKCN8fEIuEEBXoFC9eN0= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -336,11 +339,9 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= @@ -483,12 +484,10 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= -github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= @@ -726,7 +725,6 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/magefile/mage v1.12.1/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -github.com/magefile/mage v1.13.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= @@ -788,8 +786,9 @@ github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7s github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= -github.com/moby/sys/mountinfo v0.6.0 h1:gUDhXQx58YNrpHlK4nSL+7y2pxFZkUcXqzFDKWdC0Oo= github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/mountinfo v0.6.1 h1:+H/KnGEAGRpTrEAqNVQ2AM3SiwMgJUt/TXj+Z8cmCIc= +github.com/moby/sys/mountinfo v0.6.1/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= @@ -1024,8 +1023,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/sylabs/release-tools v0.1.0/go.mod h1:pqP/z/11/rYMQ0OM/Nn7TxGijw7KfZwW9UolD/J1TUo= github.com/sylabs/sif/v2 v2.3.2/go.mod h1:IrLX2pzmQ2O4qgv5iy3HdKJcBNYds9DTMd9Je8A9tX4= -github.com/sylabs/sif/v2 v2.4.2 h1:L4jcqeOF33JfSnH+8GJKC7/ooVpzpZ2K7wotGG4ZzqQ= -github.com/sylabs/sif/v2 v2.4.2/go.mod h1:6gQvzNKRIqr4FS08XBfHpkpnxv9b7h58GLkSJ1zdK9A= +github.com/sylabs/sif/v2 v2.6.0 h1:nrWbtSAavp4T6gETg/QgZXxs67qTpSNEgqs2H1y228w= +github.com/sylabs/sif/v2 v2.6.0/go.mod h1:TiyBWsgWeh5yBeQFNuQnvROwswqK7YJT8JA1L53bsXQ= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= @@ -1159,8 +1158,9 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= diff --git a/vendor/github.com/containers/buildah/internal/parse/parse.go b/vendor/github.com/containers/buildah/internal/parse/parse.go index 832b2b9ab..ec4638215 100644 --- a/vendor/github.com/containers/buildah/internal/parse/parse.go +++ b/vendor/github.com/containers/buildah/internal/parse/parse.go @@ -38,7 +38,7 @@ var ( errBadOptionArg = errors.New("must provide an argument for option") errBadVolDest = errors.New("must set volume destination") errBadVolSrc = errors.New("must set volume source") - errDuplicateDest = errors.Errorf("duplicate mount destination") + errDuplicateDest = errors.New("duplicate mount destination") ) // GetBindMount parses a single bind mount entry from the --mount flag. diff --git a/vendor/github.com/containers/buildah/pkg/parse/parse.go b/vendor/github.com/containers/buildah/pkg/parse/parse.go index e32280585..c5178636e 100644 --- a/vendor/github.com/containers/buildah/pkg/parse/parse.go +++ b/vendor/github.com/containers/buildah/pkg/parse/parse.go @@ -182,7 +182,7 @@ func parseSecurityOpts(securityOpts []string, commonOpts *define.CommonBuildOpti } con := strings.SplitN(opt, "=", 2) if len(con) != 2 { - return errors.Errorf("Invalid --security-opt name=value pair: %q", opt) + return errors.Errorf("invalid --security-opt name=value pair: %q", opt) } switch con[0] { @@ -193,7 +193,7 @@ func parseSecurityOpts(securityOpts []string, commonOpts *define.CommonBuildOpti case "seccomp": commonOpts.SeccompProfilePath = con[1] default: - return errors.Errorf("Invalid --security-opt 2: %q", opt) + return errors.Errorf("invalid --security-opt 2: %q", opt) } } diff --git a/vendor/github.com/containers/buildah/pull.go b/vendor/github.com/containers/buildah/pull.go index 3eddf5493..d203e6065 100644 --- a/vendor/github.com/containers/buildah/pull.go +++ b/vendor/github.com/containers/buildah/pull.go @@ -75,6 +75,14 @@ func Pull(ctx context.Context, imageName string, options PullOptions) (imageID s return "", err } + // Note: It is important to do this before we pull any images/create containers. + // The default backend detection logic needs an empty store to correctly detect + // that we can use netavark, if the store was not empty it will use CNI to not break existing installs. + _, err = getNetworkInterface(options.Store, "", "") + if err != nil { + return "", err + } + runtime, err := libimage.RuntimeFromStore(options.Store, &libimage.RuntimeOptions{SystemContext: options.SystemContext}) if err != nil { return "", err diff --git a/vendor/github.com/containers/buildah/run_linux.go b/vendor/github.com/containers/buildah/run_linux.go index 411a0f8cf..f52754c54 100644 --- a/vendor/github.com/containers/buildah/run_linux.go +++ b/vendor/github.com/containers/buildah/run_linux.go @@ -33,10 +33,10 @@ import ( "github.com/containers/buildah/pkg/parse" "github.com/containers/buildah/pkg/sshagent" "github.com/containers/buildah/util" + "github.com/containers/common/libnetwork/etchosts" "github.com/containers/common/libnetwork/network" nettypes "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/capabilities" - "github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/chown" "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/subscriptions" @@ -222,14 +222,24 @@ func (b *Builder) Run(command []string, options RunOptions) error { } rootIDPair := &idtools.IDPair{UID: int(rootUID), GID: int(rootGID)} - if !options.NoHosts && !contains(volumes, "/etc/hosts") { - hostFile, err := b.generateHosts(path, spec.Hostname, b.CommonBuildOpts.AddHost, rootIDPair) + hostFile := "" + if !options.NoHosts && !contains(volumes, config.DefaultHostsFile) && options.ConfigureNetwork != define.NetworkDisabled { + hostFile, err = b.generateHosts(path, rootIDPair, mountPoint) if err != nil { return err } - // Only bind /etc/hosts if there's a network - if options.ConfigureNetwork != define.NetworkDisabled { - bindFiles["/etc/hosts"] = hostFile + bindFiles[config.DefaultHostsFile] = hostFile + } + + // generate /etc/hostname if the user intentionally did not override + if !(contains(volumes, "/etc/hostname")) { + if _, ok := bindFiles["/etc/hostname"]; !ok { + hostFile, err := b.generateHostname(path, spec.Hostname, rootIDPair) + if err != nil { + return err + } + // Bind /etc/hostname + bindFiles["/etc/hostname"] = hostFile } } @@ -273,7 +283,7 @@ rootless=%d bindFiles["/run/.containerenv"] = containerenvPath } - runArtifacts, err := b.setupMounts(options.SystemContext, mountPoint, spec, path, options.Mounts, bindFiles, volumes, b.CommonBuildOpts.Volumes, b.CommonBuildOpts.ShmSize, namespaceOptions, options.Secrets, options.SSHSources, options.RunMounts, options.ContextDir, options.StageMountPoints) + runArtifacts, err := b.setupMounts(options.SystemContext, mountPoint, spec, path, options.Mounts, bindFiles, volumes, b.CommonBuildOpts.Volumes, options.Secrets, options.SSHSources, options.RunMounts, options.ContextDir, options.StageMountPoints) if err != nil { return errors.Wrapf(err, "error resolving mountpoints for container %q", b.ContainerID) } @@ -303,7 +313,8 @@ rootless=%d if options.NoPivot { moreCreateArgs = append(moreCreateArgs, "--no-pivot") } - err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, configureNetworks, moreCreateArgs, spec, mountPoint, path, define.Package+"-"+filepath.Base(path)) + err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, configureNetworks, moreCreateArgs, spec, + mountPoint, path, define.Package+"-"+filepath.Base(path), b.Container, hostFile) case IsolationChroot: err = chroot.RunUsingChroot(spec, path, homeDir, options.Stdin, options.Stdout, options.Stderr) case IsolationOCIRootless: @@ -311,10 +322,8 @@ rootless=%d if options.NoPivot { moreCreateArgs = append(moreCreateArgs, "--no-pivot") } - if err := setupRootlessSpecChanges(spec, path, b.CommonBuildOpts.ShmSize); err != nil { - return err - } - err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, configureNetworks, moreCreateArgs, spec, mountPoint, path, define.Package+"-"+filepath.Base(path)) + err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, configureNetworks, moreCreateArgs, spec, + mountPoint, path, define.Package+"-"+filepath.Base(path), b.Container, hostFile) default: err = errors.Errorf("don't know how to run this command") } @@ -431,7 +440,7 @@ func runSetupBuiltinVolumes(mountLabel, mountPoint, containerDir string, builtin return mounts, nil } -func (b *Builder) setupMounts(context *imagetypes.SystemContext, mountPoint string, spec *specs.Spec, bundlePath string, optionMounts []specs.Mount, bindFiles map[string]string, builtinVolumes, volumeMounts []string, shmSize string, namespaceOptions define.NamespaceOptions, secrets map[string]define.Secret, sshSources map[string]*sshagent.Source, runFileMounts []string, contextDir string, stageMountPoints map[string]internal.StageMountDetails) (*runMountArtifacts, error) { +func (b *Builder) setupMounts(context *imagetypes.SystemContext, mountPoint string, spec *specs.Spec, bundlePath string, optionMounts []specs.Mount, bindFiles map[string]string, builtinVolumes, volumeMounts []string, secrets map[string]define.Secret, sshSources map[string]*sshagent.Source, runFileMounts []string, contextDir string, stageMountPoints map[string]internal.StageMountDetails) (*runMountArtifacts, error) { // Start building a new list of mounts. var mounts []specs.Mount haveMount := func(destination string) bool { @@ -444,79 +453,9 @@ func (b *Builder) setupMounts(context *imagetypes.SystemContext, mountPoint stri return false } - ipc := namespaceOptions.Find(string(specs.IPCNamespace)) - hostIPC := ipc == nil || ipc.Host - net := namespaceOptions.Find(string(specs.NetworkNamespace)) - hostNetwork := net == nil || net.Host - user := namespaceOptions.Find(string(specs.UserNamespace)) - hostUser := (user == nil || user.Host) && !unshare.IsRootless() - - // Copy mounts from the generated list. - mountCgroups := true - specMounts := []specs.Mount{} - for _, specMount := range spec.Mounts { - // Override some of the mounts from the generated list if we're doing different things with namespaces. - if specMount.Destination == "/dev/shm" { - specMount.Options = []string{"nosuid", "noexec", "nodev", "mode=1777"} - if shmSize != "" { - specMount.Options = append(specMount.Options, "size="+shmSize) - } - if hostIPC && !hostUser { - if _, err := os.Stat("/dev/shm"); err != nil && os.IsNotExist(err) { - logrus.Debugf("/dev/shm is not present, not binding into container") - continue - } - specMount = specs.Mount{ - Source: "/dev/shm", - Type: "bind", - Destination: "/dev/shm", - Options: []string{bind.NoBindOption, "rbind", "nosuid", "noexec", "nodev"}, - } - } - } - if specMount.Destination == "/dev/mqueue" { - if hostIPC && !hostUser { - if _, err := os.Stat("/dev/mqueue"); err != nil && os.IsNotExist(err) { - logrus.Debugf("/dev/mqueue is not present, not binding into container") - continue - } - specMount = specs.Mount{ - Source: "/dev/mqueue", - Type: "bind", - Destination: "/dev/mqueue", - Options: []string{bind.NoBindOption, "rbind", "nosuid", "noexec", "nodev"}, - } - } - } - if specMount.Destination == "/sys" { - if hostNetwork && !hostUser { - mountCgroups = false - if _, err := os.Stat("/sys"); err != nil && os.IsNotExist(err) { - logrus.Debugf("/sys is not present, not binding into container") - continue - } - specMount = specs.Mount{ - Source: "/sys", - Type: "bind", - Destination: "/sys", - Options: []string{bind.NoBindOption, "rbind", "nosuid", "noexec", "nodev", "ro"}, - } - } - } - specMounts = append(specMounts, specMount) - } - - // Add a mount for the cgroups filesystem, unless we're already - // recursively bind mounting all of /sys, in which case we shouldn't - // bother with it. - sysfsMount := []specs.Mount{} - if mountCgroups { - sysfsMount = []specs.Mount{{ - Destination: "/sys/fs/cgroup", - Type: "cgroup", - Source: "cgroup", - Options: []string{bind.NoBindOption, "nosuid", "noexec", "nodev", "relatime", "ro"}, - }} + specMounts, err := setupSpecialMountSpecChanges(spec, b.CommonBuildOpts.ShmSize) + if err != nil { + return nil, err } // Get the list of files we need to bind into the container. @@ -568,7 +507,7 @@ func (b *Builder) setupMounts(context *imagetypes.SystemContext, mountPoint stri // everything other than these might have users content mountArtifacts.RunMountTargets = append(append(append(mountArtifacts.RunMountTargets, cleanableDestinationListFromMounts(bindFileMounts)...), cleanableDestinationListFromMounts(subscriptionMounts)...), cleanableDestinationListFromMounts(specMounts)...) - allMounts := util.SortMounts(append(append(append(append(append(append(volumes, builtins...), runMounts...), subscriptionMounts...), bindFileMounts...), specMounts...), sysfsMount...)) + allMounts := util.SortMounts(append(append(append(append(append(volumes, builtins...), runMounts...), subscriptionMounts...), bindFileMounts...), specMounts...)) // Add them all, in the preferred order, except where they conflict with something that was previously added. for _, mount := range allMounts { if haveMount(mount.Destination) { @@ -705,46 +644,58 @@ func (b *Builder) addResolvConf(rdir string, chownOpts *idtools.IDPair, dnsServe } // generateHosts creates a containers hosts file -func (b *Builder) generateHosts(rdir, hostname string, addHosts []string, chownOpts *idtools.IDPair) (string, error) { - hostPath := "/etc/hosts" - stat, err := os.Stat(hostPath) +func (b *Builder) generateHosts(rdir string, chownOpts *idtools.IDPair, imageRoot string) (string, error) { + conf, err := config.Default() if err != nil { return "", err } - hosts := bytes.NewBufferString("# Generated by Buildah\n") - orig, err := ioutil.ReadFile(hostPath) + path, err := etchosts.GetBaseHostFile(conf.Containers.BaseHostsFile, imageRoot) if err != nil { return "", err } - hosts.Write(orig) - for _, host := range addHosts { - // verify the host format - values := strings.SplitN(host, ":", 2) - if len(values) != 2 { - return "", errors.Errorf("unable to parse host entry %q: incorrect format", host) - } - if values[0] == "" { - return "", errors.Errorf("hostname in host entry %q is empty", host) - } - if values[1] == "" { - return "", errors.Errorf("IP address in host entry %q is empty", host) - } - hosts.Write([]byte(fmt.Sprintf("%s\t%s\n", values[1], values[0]))) + + targetfile := filepath.Join(rdir, "hosts") + if err := etchosts.New(&etchosts.Params{ + BaseFile: path, + ExtraHosts: b.CommonBuildOpts.AddHost, + HostContainersInternalIP: etchosts.GetHostContainersInternalIP(conf, nil, nil), + TargetFile: targetfile, + }); err != nil { + return "", err } - hosts.Write([]byte(fmt.Sprintf("127.0.0.1 %s %s\n", b.Container, hostname))) - hosts.Write([]byte(fmt.Sprintf("::1 %s %s\n", b.Container, hostname))) - if ip := util.LocalIP(); ip != "" { - hosts.Write([]byte(fmt.Sprintf("%s %s\n", ip, "host.containers.internal"))) + uid := 0 + gid := 0 + if chownOpts != nil { + uid = chownOpts.UID + gid = chownOpts.GID + } + if err = os.Chown(targetfile, uid, gid); err != nil { + return "", err } + if err := label.Relabel(targetfile, b.MountLabel, false); err != nil { + return "", err + } + + return targetfile, nil +} - cfile := filepath.Join(rdir, filepath.Base(hostPath)) - if err = ioutils.AtomicWriteFile(cfile, hosts.Bytes(), stat.Mode().Perm()); err != nil { - return "", errors.Wrapf(err, "error writing /etc/hosts into the container") +// generateHostname creates a containers /etc/hostname file +func (b *Builder) generateHostname(rdir, hostname string, chownOpts *idtools.IDPair) (string, error) { + var err error + hostnamePath := "/etc/hostname" + + var hostnameBuffer bytes.Buffer + hostnameBuffer.Write([]byte(fmt.Sprintf("%s\n", hostname))) + + cfile := filepath.Join(rdir, filepath.Base(hostnamePath)) + if err = ioutils.AtomicWriteFile(cfile, hostnameBuffer.Bytes(), 0644); err != nil { + return "", errors.Wrapf(err, "error writing /etc/hostname into the container") } - uid := int(stat.Sys().(*syscall.Stat_t).Uid) - gid := int(stat.Sys().(*syscall.Stat_t).Gid) + + uid := 0 + gid := 0 if chownOpts != nil { uid = chownOpts.UID gid = chownOpts.GID @@ -1179,11 +1130,10 @@ func setupRootlessNetwork(pid int) (teardown func(), err error) { }, nil } -func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, options RunOptions, configureNetworks []string, containerName string) (teardown func(), err error) { +func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, options RunOptions, configureNetworks []string, containerName string) (teardown func(), netStatus map[string]nettypes.StatusBlock, err error) { if isolation == IsolationOCIRootless { - if ns := options.NamespaceOptions.Find(string(specs.NetworkNamespace)); ns != nil && !ns.Host && ns.Path == "" { - return setupRootlessNetwork(pid) - } + teardown, err = setupRootlessNetwork(pid) + return teardown, nil, err } if len(configureNetworks) == 0 { @@ -1198,7 +1148,7 @@ func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, optio netns := fmt.Sprintf("/proc/%d/ns/net", pid) netFD, err := unix.Open(netns, unix.O_RDONLY, 0) if err != nil { - return nil, errors.Wrapf(err, "error opening network namespace") + return nil, nil, errors.Wrapf(err, "error opening network namespace") } mynetns := fmt.Sprintf("/proc/%d/fd/%d", unix.Getpid(), netFD) @@ -1214,9 +1164,9 @@ func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, optio ContainerName: containerName, Networks: networks, } - _, err = b.NetworkInterface.Setup(mynetns, nettypes.SetupOptions{NetworkOptions: opts}) + netStatus, err = b.NetworkInterface.Setup(mynetns, nettypes.SetupOptions{NetworkOptions: opts}) if err != nil { - return nil, err + return nil, nil, err } teardown = func() { @@ -1226,7 +1176,7 @@ func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, optio } } - return teardown, nil + return teardown, netStatus, nil } func setNonblock(logger *logrus.Logger, fd int, description string, nonblocking bool) (bool, error) { //nolint:interfacer @@ -2146,100 +2096,146 @@ func (b *Builder) configureEnvironment(g *generate.Generator, options RunOptions } } -func setupRootlessSpecChanges(spec *specs.Spec, bundleDir string, shmSize string) error { - emptyDir := filepath.Join(bundleDir, "empty") - if err := os.Mkdir(emptyDir, 0); err != nil { - return err +func addOrReplaceMount(moutns []specs.Mount, mount specs.Mount) []spec.Mount { + for i := range moutns { + if moutns[i].Destination == mount.Destination { + moutns[i] = mount + return moutns + } } + return append(moutns, mount) +} - // If the container has a network namespace, we can create a fresh /sys mount - for _, ns := range spec.Linux.Namespaces { - if ns.Type == specs.NetworkNamespace { - return nil +// setupSpecialMountSpecChanges creates special mounts for depending on the namespaces +// logic taken from podman and adapted for buildah +// https://github.com/containers/podman/blob/4ba71f955a944790edda6e007e6d074009d437a7/pkg/specgen/generate/oci.go#L178 +func setupSpecialMountSpecChanges(spec *spec.Spec, shmSize string) ([]specs.Mount, error) { + mounts := spec.Mounts + isRootless := unshare.IsRootless() + isNewUserns := false + isNetns := false + isPidns := false + isIpcns := false + + for _, namespace := range spec.Linux.Namespaces { + switch namespace.Type { + case specs.NetworkNamespace: + isNetns = true + case specs.UserNamespace: + isNewUserns = true + case specs.PIDNamespace: + isPidns = true + case specs.IPCNamespace: + isIpcns = true + } + } + + addCgroup := true + // mount sys when root and no userns or when both netns and userns are private + canMountSys := (!isRootless && !isNewUserns) || (isNetns && isNewUserns) + if !canMountSys { + addCgroup = false + sys := "/sys" + sysMnt := specs.Mount{ + Destination: sys, + Type: "bind", + Source: sys, + Options: []string{bind.NoBindOption, "rprivate", "nosuid", "noexec", "nodev", "ro", "rbind"}, } + mounts = addOrReplaceMount(mounts, sysMnt) } - // Replace /sys with a read-only bind mount. - mounts := []specs.Mount{ - { - Source: "/dev", - Destination: "/dev", - Type: "tmpfs", - Options: []string{"private", "strictatime", "noexec", "nosuid", "mode=755", "size=65536k"}, - }, - { - Source: "mqueue", - Destination: "/dev/mqueue", - Type: "mqueue", - Options: []string{"private", "nodev", "noexec", "nosuid"}, - }, - { - Source: "pts", + gid5Available := true + if isRootless { + _, gids, err := unshare.GetHostIDMappings("") + if err != nil { + return nil, err + } + gid5Available = checkIdsGreaterThan5(gids) + } + if gid5Available && len(spec.Linux.GIDMappings) > 0 { + gid5Available = checkIdsGreaterThan5(spec.Linux.GIDMappings) + } + if !gid5Available { + // If we have no GID mappings, the gid=5 default option would fail, so drop it. + devPts := specs.Mount{ Destination: "/dev/pts", Type: "devpts", - Options: []string{"private", "noexec", "nosuid", "newinstance", "ptmxmode=0666", "mode=0620"}, - }, - { - Source: "shm", - Destination: "/dev/shm", - Type: "tmpfs", - Options: []string{"private", "nodev", "noexec", "nosuid", "mode=1777", fmt.Sprintf("size=%s", shmSize)}, - }, - { - Source: "/proc", - Destination: "/proc", - Type: "proc", - Options: []string{"private", "nodev", "noexec", "nosuid"}, - }, - { - Source: "/sys", - Destination: "/sys", + Source: "devpts", + Options: []string{"rprivate", "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"}, + } + mounts = addOrReplaceMount(mounts, devPts) + } + + isUserns := isNewUserns || isRootless + + if isUserns && !isIpcns { + devMqueue := "/dev/mqueue" + devMqueueMnt := specs.Mount{ + Destination: devMqueue, Type: "bind", - Options: []string{bind.NoBindOption, "rbind", "private", "nodev", "noexec", "nosuid", "ro"}, - }, + Source: devMqueue, + Options: []string{bind.NoBindOption, "bind", "nosuid", "noexec", "nodev"}, + } + mounts = addOrReplaceMount(mounts, devMqueueMnt) + } + if isUserns && !isPidns { + proc := "/proc" + procMount := specs.Mount{ + Destination: proc, + Type: "bind", + Source: proc, + Options: []string{bind.NoBindOption, "rbind", "nosuid", "noexec", "nodev"}, + } + mounts = addOrReplaceMount(mounts, procMount) } - cgroup2, err := cgroups.IsCgroup2UnifiedMode() - if err != nil { - return err + if addCgroup { + cgroupMnt := specs.Mount{ + Destination: "/sys/fs/cgroup", + Type: "cgroup", + Source: "cgroup", + Options: []string{"rprivate", "nosuid", "noexec", "nodev", "relatime", "rw"}, + } + mounts = addOrReplaceMount(mounts, cgroupMnt) } - if cgroup2 { - hasCgroupNs := false - for _, ns := range spec.Linux.Namespaces { - if ns.Type == specs.CgroupNamespace { - hasCgroupNs = true - break + + // if userns and host ipc bind mount shm + if isUserns && !isIpcns { + // bind mount /dev/shm when it exists + if _, err := os.Stat("/dev/shm"); err == nil { + shmMount := specs.Mount{ + Source: "/dev/shm", + Type: "bind", + Destination: "/dev/shm", + Options: []string{bind.NoBindOption, "rbind", "nosuid", "noexec", "nodev"}, } + mounts = addOrReplaceMount(mounts, shmMount) } - if hasCgroupNs { - mounts = append(mounts, specs.Mount{ - Destination: "/sys/fs/cgroup", - Type: "cgroup", - Source: "cgroup", - Options: []string{"private", "rw"}, - }) - } - } else { - spec.Linux.Resources = nil - // Cover up /sys/fs/cgroup, if it exist in our source for /sys. - if _, err := os.Stat("/sys/fs/cgroup"); err == nil { - spec.Linux.MaskedPaths = append(spec.Linux.MaskedPaths, "/sys/fs/cgroup") + } else if shmSize != "" { + shmMount := specs.Mount{ + Source: "shm", + Destination: "/dev/shm", + Type: "tmpfs", + Options: []string{"private", "nodev", "noexec", "nosuid", "mode=1777", "size=" + shmSize}, } + mounts = addOrReplaceMount(mounts, shmMount) } - // Keep anything that isn't under /dev, /proc, or /sys. - for i := range spec.Mounts { - if spec.Mounts[i].Destination == "/dev" || strings.HasPrefix(spec.Mounts[i].Destination, "/dev/") || - spec.Mounts[i].Destination == "/proc" || strings.HasPrefix(spec.Mounts[i].Destination, "/proc/") || - spec.Mounts[i].Destination == "/sys" || strings.HasPrefix(spec.Mounts[i].Destination, "/sys/") { - continue + + return mounts, nil +} + +func checkIdsGreaterThan5(ids []spec.LinuxIDMapping) bool { + for _, r := range ids { + if r.ContainerID <= 5 && 5 < r.ContainerID+r.Size { + return true } - mounts = append(mounts, spec.Mounts[i]) } - spec.Mounts = mounts - return nil + return false } -func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options RunOptions, configureNetwork bool, configureNetworks, moreCreateArgs []string, spec *specs.Spec, rootPath, bundlePath, containerName string) (err error) { +func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options RunOptions, configureNetwork bool, configureNetworks, + moreCreateArgs []string, spec *specs.Spec, rootPath, bundlePath, containerName, buildContainerName, hostsFile string) (err error) { var confwg sync.WaitGroup config, conferr := json.Marshal(runUsingRuntimeSubprocOptions{ Options: options, @@ -2340,7 +2336,7 @@ func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options Run return errors.Wrapf(err, "error parsing pid %s as a number", string(pidValue)) } - teardown, err := b.runConfigureNetwork(pid, isolation, options, configureNetworks, containerName) + teardown, netstatus, err := b.runConfigureNetwork(pid, isolation, options, configureNetworks, containerName) if teardown != nil { defer teardown() } @@ -2348,6 +2344,22 @@ func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options Run return err } + // only add hosts if we manage the hosts file + if hostsFile != "" { + var entries etchosts.HostEntries + if netstatus != nil { + entries = etchosts.GetNetworkHostEntries(netstatus, spec.Hostname, buildContainerName) + } else { + // we have slirp4netns, default to slirp4netns ip since this is not configurable in buildah + entries = etchosts.HostEntries{{IP: "10.0.2.100", Names: []string{spec.Hostname, buildContainerName}}} + } + // make sure to sync this with (b *Builder) generateHosts() + err = etchosts.Add(hostsFile, entries) + if err != nil { + return err + } + } + logrus.Debug("network namespace successfully setup, send start message to child") _, err = containerStartW.file.Write([]byte{1}) if err != nil { @@ -2400,33 +2412,14 @@ func waitForSync(pipeR *os.File) error { func checkAndOverrideIsolationOptions(isolation define.Isolation, options *RunOptions) error { switch isolation { case IsolationOCIRootless: - if ns := options.NamespaceOptions.Find(string(specs.IPCNamespace)); ns == nil || ns.Host { - logrus.Debugf("Forcing use of an IPC namespace.") - } - options.NamespaceOptions.AddOrReplace(define.NamespaceOption{Name: string(specs.IPCNamespace)}) - _, err := exec.LookPath("slirp4netns") - hostNetworking := err != nil - networkNamespacePath := "" - if ns := options.NamespaceOptions.Find(string(specs.NetworkNamespace)); ns != nil { - hostNetworking = ns.Host - networkNamespacePath = ns.Path - if hostNetworking { - networkNamespacePath = "" - } - } - options.NamespaceOptions.AddOrReplace(define.NamespaceOption{ - Name: string(specs.NetworkNamespace), - Host: hostNetworking, - Path: networkNamespacePath, - }) - if ns := options.NamespaceOptions.Find(string(specs.PIDNamespace)); ns == nil || ns.Host { - logrus.Debugf("Forcing use of a PID namespace.") - } - options.NamespaceOptions.AddOrReplace(define.NamespaceOption{Name: string(specs.PIDNamespace), Host: false}) - if ns := options.NamespaceOptions.Find(string(specs.UserNamespace)); ns == nil || ns.Host { - logrus.Debugf("Forcing use of a user namespace.") + // only change the netns if the caller did not set it + if ns := options.NamespaceOptions.Find(string(specs.NetworkNamespace)); ns == nil { + if _, err := exec.LookPath("slirp4netns"); err != nil { + // if slirp4netns is not installed we have to use the hosts net namespace + options.NamespaceOptions.AddOrReplace(define.NamespaceOption{Name: string(specs.NetworkNamespace), Host: true}) + } } - options.NamespaceOptions.AddOrReplace(define.NamespaceOption{Name: string(specs.UserNamespace)}) + fallthrough case IsolationOCI: pidns := options.NamespaceOptions.Find(string(specs.PIDNamespace)) userns := options.NamespaceOptions.Find(string(specs.UserNamespace)) @@ -2447,25 +2440,12 @@ func DefaultNamespaceOptions() (define.NamespaceOptions, error) { options := define.NamespaceOptions{ {Name: string(specs.CgroupNamespace), Host: cfg.CgroupNS() == "host"}, {Name: string(specs.IPCNamespace), Host: cfg.IPCNS() == "host"}, - {Name: string(specs.MountNamespace), Host: true}, - {Name: string(specs.NetworkNamespace), Host: cfg.NetNS() == "host" || cfg.NetNS() == "container"}, + {Name: string(specs.MountNamespace), Host: false}, + {Name: string(specs.NetworkNamespace), Host: cfg.NetNS() == "host"}, {Name: string(specs.PIDNamespace), Host: cfg.PidNS() == "host"}, - {Name: string(specs.UserNamespace), Host: true}, + {Name: string(specs.UserNamespace), Host: cfg.Containers.UserNS == "host"}, {Name: string(specs.UTSNamespace), Host: cfg.UTSNS() == "host"}, } - g, err := generate.New("linux") - if err != nil { - return options, errors.Wrapf(err, "error generating new 'linux' runtime spec") - } - spec := g.Config - if spec.Linux != nil { - for _, ns := range spec.Linux.Namespaces { - options.AddOrReplace(define.NamespaceOption{ - Name: string(ns.Type), - Path: ns.Path, - }) - } - } return options, nil } diff --git a/vendor/github.com/containers/buildah/util/util.go b/vendor/github.com/containers/buildah/util/util.go index 13c602c00..33a8c5657 100644 --- a/vendor/github.com/containers/buildah/util/util.go +++ b/vendor/github.com/containers/buildah/util/util.go @@ -3,7 +3,6 @@ package util import ( "fmt" "io" - "net" "net/url" "os" "path/filepath" @@ -466,20 +465,3 @@ func VerifyTagName(imageSpec string) (types.ImageReference, error) { } return ref, nil } - -// LocalIP returns the non loopback local IP of the host -func LocalIP() string { - addrs, err := net.InterfaceAddrs() - if err != nil { - return "" - } - for _, address := range addrs { - // check the address type and if it is not a loopback the display it - if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To4() != nil { - return ipnet.IP.String() - } - } - } - return "" -} diff --git a/vendor/github.com/containers/common/libnetwork/etchosts/ip.go b/vendor/github.com/containers/common/libnetwork/etchosts/ip.go index 3d14b7147..2b8186e72 100644 --- a/vendor/github.com/containers/common/libnetwork/etchosts/ip.go +++ b/vendor/github.com/containers/common/libnetwork/etchosts/ip.go @@ -6,6 +6,7 @@ import ( "github.com/containers/common/libnetwork/types" "github.com/containers/common/libnetwork/util" "github.com/containers/common/pkg/config" + "github.com/containers/common/pkg/machine" "github.com/containers/storage/pkg/unshare" ) @@ -15,8 +16,8 @@ func GetHostContainersInternalIP(conf *config.Config, netStatus map[string]types switch conf.Containers.HostContainersInternalIP { case "": // if empty (default) we will automatically choose one below - // if machine we let the gvproxy dns server handle the dns name so do not add it - if conf.Engine.MachineEnabled { + // if machine using gvproxy we let the gvproxy dns server handle the dns name so do not add it + if machine.IsGvProxyBased() { return "" } case "none": diff --git a/vendor/github.com/containers/common/libnetwork/netavark/network.go b/vendor/github.com/containers/common/libnetwork/netavark/network.go index 9c8c4bfb4..8e7576a56 100644 --- a/vendor/github.com/containers/common/libnetwork/netavark/network.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/network.go @@ -27,7 +27,7 @@ type netavarkNetwork struct { // networkRunDir is where temporary files are stored, i.e.the ipam db, aardvark config etc networkRunDir string - // tells netavark whether this is rootless mode or rootfull, "true" or "false" + // tells netavark whether this is rootless mode or rootful, "true" or "false" networkRootless bool // netavarkBinary is the path to the netavark binary. diff --git a/vendor/github.com/containers/common/libnetwork/network/interface.go b/vendor/github.com/containers/common/libnetwork/network/interface.go index e452e6cd5..893bdea2e 100644 --- a/vendor/github.com/containers/common/libnetwork/network/interface.go +++ b/vendor/github.com/containers/common/libnetwork/network/interface.go @@ -14,6 +14,7 @@ import ( "github.com/containers/common/libnetwork/netavark" "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" + "github.com/containers/common/pkg/machine" "github.com/containers/storage" "github.com/containers/storage/pkg/homedir" "github.com/containers/storage/pkg/ioutils" @@ -173,7 +174,7 @@ func getCniInterface(conf *config.Config) (types.ContainerNetwork, error) { DefaultNetwork: conf.Network.DefaultNetwork, DefaultSubnet: conf.Network.DefaultSubnet, DefaultsubnetPools: conf.Network.DefaultSubnetPools, - IsMachine: conf.Engine.MachineEnabled, + IsMachine: machine.IsGvProxyBased(), }) } diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go index 319b8d153..d362495e3 100644 --- a/vendor/github.com/containers/common/pkg/config/config.go +++ b/vendor/github.com/containers/common/pkg/config/config.go @@ -312,6 +312,8 @@ type EngineConfig struct { LockType string `toml:"lock_type,omitempty"` // MachineEnabled indicates if Podman is running in a podman-machine VM + // + // This method is soft deprecated, use machine.IsPodmanMachine instead MachineEnabled bool `toml:"machine_enabled,omitempty"` // MultiImageArchive - if true, the container engine allows for storing diff --git a/vendor/github.com/containers/common/pkg/config/config_freebsd.go b/vendor/github.com/containers/common/pkg/config/config_freebsd.go new file mode 100644 index 000000000..85404a48d --- /dev/null +++ b/vendor/github.com/containers/common/pkg/config/config_freebsd.go @@ -0,0 +1,25 @@ +package config + +import ( + "os" +) + +// podman remote clients on freebsd cannot use unshare.isRootless() to determine the configuration file locations. +func customConfigFile() (string, error) { + if path, found := os.LookupEnv("CONTAINERS_CONF"); found { + return path, nil + } + return rootlessConfigPath() +} + +func ifRootlessConfigPath() (string, error) { + return rootlessConfigPath() +} + +var defaultHelperBinariesDir = []string{ + "/usr/local/bin", + "/usr/local/libexec/podman", + "/usr/local/lib/podman", + "/usr/local/libexec/podman", + "/usr/local/lib/podman", +} diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf index 429b254bc..2b250753e 100644 --- a/vendor/github.com/containers/common/pkg/config/containers.conf +++ b/vendor/github.com/containers/common/pkg/config/containers.conf @@ -455,12 +455,6 @@ default_sysctls = [ # #lock_type** = "shm" -# Indicates if Podman is running inside a VM via Podman Machine. -# Podman uses this value to do extra setup around networking from the -# container inside the VM to to host. -# -#machine_enabled = false - # MultiImageArchive - if true, the container engine allows for storing archives # (e.g., of the docker-archive transport) with multiple images. By default, # Podman creates single-image archives. @@ -572,9 +566,9 @@ default_sysctls = [ # URI to access the Podman service # Examples: # rootless "unix://run/user/$UID/podman/podman.sock" (Default) -# rootfull "unix://run/podman/podman.sock (Default) +# rootful "unix://run/podman/podman.sock (Default) # remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock -# remote rootfull ssh://root@10.10.1.136:22/run/podman/podman.sock +# remote rootful ssh://root@10.10.1.136:22/run/podman/podman.sock # # uri = "ssh://user@production.example.com/run/user/1001/podman/podman.sock" # Path to file containing ssh identity key diff --git a/vendor/github.com/containers/common/pkg/machine/machine.go b/vendor/github.com/containers/common/pkg/machine/machine.go new file mode 100644 index 000000000..465eeceaf --- /dev/null +++ b/vendor/github.com/containers/common/pkg/machine/machine.go @@ -0,0 +1,70 @@ +package machine + +import ( + "os" + "strings" + "sync" + + "github.com/containers/common/pkg/config" + "github.com/sirupsen/logrus" +) + +type MachineMarker struct { + Enabled bool + Type string +} + +const ( + markerFile = "/etc/containers/podman-machine" + Wsl = "wsl" + Qemu = "qemu" +) + +var ( + markerSync sync.Once + machineMarker *MachineMarker +) + +func loadMachineMarker(file string) { + var kind string + + // Support deprecated config value for compatibility + enabled := isLegacyConfigSet() + + if content, err := os.ReadFile(file); err == nil { + enabled = true + kind = strings.TrimSpace(string(content)) + } + + machineMarker = &MachineMarker{enabled, kind} +} + +func isLegacyConfigSet() bool { + config, err := config.Default() + if err != nil { + logrus.Warnf("could not obtain container configuration") + return false + } + + //nolint:staticcheck //lint:ignore SA1019 deprecated call + return config.Engine.MachineEnabled +} + +func IsPodmanMachine() bool { + return GetMachineMarker().Enabled +} + +func MachineHostType() string { + return GetMachineMarker().Type +} + +func IsGvProxyBased() bool { + return IsPodmanMachine() && MachineHostType() != Wsl +} + +func GetMachineMarker() *MachineMarker { + markerSync.Do(func() { + loadMachineMarker(markerFile) + }) + return machineMarker +} diff --git a/vendor/github.com/containers/image/v5/docker/docker_client.go b/vendor/github.com/containers/image/v5/docker/docker_client.go index d984db718..f537de72d 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_client.go +++ b/vendor/github.com/containers/image/v5/docker/docker_client.go @@ -1,7 +1,6 @@ package docker import ( - "bytes" "context" "crypto/tls" "encoding/json" @@ -653,7 +652,7 @@ func (c *dockerClient) getBearerTokenOAuth2(ctx context.Context, challenge chall params.Add("refresh_token", c.auth.IdentityToken) params.Add("client_id", "containers/image") - authReq.Body = io.NopCloser(bytes.NewBufferString(params.Encode())) + authReq.Body = io.NopCloser(strings.NewReader(params.Encode())) authReq.Header.Add("User-Agent", c.userAgent) authReq.Header.Add("Content-Type", "application/x-www-form-urlencoded") logrus.Debugf("%s %s", authReq.Method, authReq.URL.Redacted()) diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_src.go b/vendor/github.com/containers/image/v5/docker/docker_image_src.go index c8e176f90..085a3afcc 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image_src.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image_src.go @@ -610,8 +610,11 @@ func deleteImage(ctx context.Context, sys *types.SystemContext, ref dockerRefere return errors.Errorf("Failed to delete %v: %s (%v)", ref.ref, manifestBody, get.Status) } - digest := get.Header.Get("Docker-Content-Digest") - deletePath := fmt.Sprintf(manifestPath, reference.Path(ref.ref), digest) + manifestDigest, err := manifest.Digest(manifestBody) + if err != nil { + return fmt.Errorf("computing manifest digest: %w", err) + } + deletePath := fmt.Sprintf(manifestPath, reference.Path(ref.ref), manifestDigest) // When retrieving the digest from a registry >= 2.3 use the following header: // "Accept": "application/vnd.docker.distribution.manifest.v2+json" @@ -629,11 +632,6 @@ func deleteImage(ctx context.Context, sys *types.SystemContext, ref dockerRefere return errors.Errorf("Failed to delete %v: %s (%v)", deletePath, string(body), delete.Status) } - manifestDigest, err := manifest.Digest(manifestBody) - if err != nil { - return err - } - for i := 0; ; i++ { url := signatureStorageURL(c.signatureBase, manifestDigest, i) missing, err := c.deleteOneSignature(url) diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go index c911acb5c..550dc7d39 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go +++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go @@ -26,7 +26,6 @@ import ( "github.com/containers/storage/pkg/directory" "github.com/containers/storage/pkg/fsutils" "github.com/containers/storage/pkg/idtools" - "github.com/containers/storage/pkg/locker" "github.com/containers/storage/pkg/mount" "github.com/containers/storage/pkg/parsers" "github.com/containers/storage/pkg/system" @@ -119,7 +118,6 @@ type Driver struct { supportsDType bool supportsVolatile *bool usingMetacopy bool - locker *locker.Locker supportsIDMappedMounts *bool } @@ -422,7 +420,6 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error) supportsDType: supportsDType, usingMetacopy: usingMetacopy, supportsVolatile: supportsVolatile, - locker: locker.New(), options: *opts, } @@ -1175,9 +1172,6 @@ func (d *Driver) optsAppendMappings(opts string, uidMaps, gidMaps []idtools.IDMa // Remove cleans the directories that are created for this id. func (d *Driver) Remove(id string) error { - d.locker.Lock(id) - defer d.locker.Unlock(id) - dir := d.dir(id) lid, err := ioutil.ReadFile(path.Join(dir, "link")) if err == nil { @@ -1311,8 +1305,6 @@ func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr } func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountOpts) (_ string, retErr error) { - d.locker.Lock(id) - defer d.locker.Unlock(id) dir, inAdditionalStore := d.dir2(id) if _, err := os.Stat(dir); err != nil { return "", err @@ -1637,8 +1629,6 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO // Put unmounts the mount path created for the give id. func (d *Driver) Put(id string) error { - d.locker.Lock(id) - defer d.locker.Unlock(id) dir := d.dir(id) if _, err := os.Stat(dir); err != nil { return err diff --git a/vendor/github.com/onsi/gomega/.travis.yml b/vendor/github.com/onsi/gomega/.travis.yml deleted file mode 100644 index 6543dc553..000000000 --- a/vendor/github.com/onsi/gomega/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: go -arch: - - amd64 - - ppc64le - -go: - - gotip - - 1.16.x - - 1.15.x - -env: - - GO111MODULE=on - -install: skip - -script: - - go mod tidy && git diff --exit-code go.mod go.sum - - make test diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md index 18190e8b9..4375bbc64 100644 --- a/vendor/github.com/onsi/gomega/CHANGELOG.md +++ b/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -1,3 +1,53 @@ +## 1.19.0 + +## Features +- New [`HaveEach`](https://onsi.github.io/gomega/#haveeachelement-interface) matcher to ensure that each and every element in an `array`, `slice`, or `map` satisfies the passed in matcher. (#523) [9fc2ae2] (#524) [c8ba582] +- Users can now wrap the `Gomega` interface to implement custom behavior on each assertion. (#521) [1f2e714] +- [`ContainElement`](https://onsi.github.io/gomega/#containelementelement-interface) now accepts an additional pointer argument. Elements that satisfy the matcher are stored in the pointer enabling developers to easily add subsequent, more detailed, assertions against the matching element. (#527) [1a4e27f] + +## Fixes +- update RELEASING instructions to match ginkgo [0917cde] +- Bump github.com/onsi/ginkgo/v2 from 2.0.0 to 2.1.3 (#519) [49ab4b0] +- Fix CVE-2021-38561 (#534) [f1b4456] +- Fix max number of samples in experiments on non-64-bit systems. (#528) [1c84497] +- Remove dependency on ginkgo v1.16.4 (#530) [4dea8d5] +- Fix for Go 1.18 (#532) [56d2a29] +- Document precendence of timeouts (#533) [b607941] + +## 1.18.1 + +## Fixes +- Add pointer support to HaveField matcher (#495) [79e41a3] + +## 1.18.0 + +## Features +- Docs now live on the master branch in the docs folder which will make for easier PRs. The docs also use Ginkgo 2.0's new docs html/css/js. [2570272] +- New HaveValue matcher can handle actuals that are either values (in which case they are passed on unscathed) or pointers (in which case they are indirected). [Docs here.](https://onsi.github.io/gomega/#working-with-values) (#485) [bdc087c] +- Gmeasure has been declared GA [360db9d] + +## Fixes +- Gomega now uses ioutil for Go 1.15 and lower (#492) - official support is only for the most recent two major versions of Go but this will unblock users who need to stay on older unsupported versions of Go. [c29c1c0] + +## Maintenace +- Remove Travis workflow (#491) [72e6040] +- Upgrade to Ginkgo 2.0.0 GA [f383637] +- chore: fix description of HaveField matcher (#487) [2b4b2c0] +- use tools.go to ensure Ginkgo cli dependencies are included [f58a52b] +- remove dockerfile and simplify github actions to match ginkgo's actions [3f8160d] + +## 1.17.0 + +### Features +- Add HaveField matcher [3a26311] +- add Error() assertions on the final error value of multi-return values (#480) [2f96943] +- separate out offsets and timeouts (#478) [18a4723] +- fix transformation error reporting (#479) [e001fab] +- allow transform functions to report errors (#472) [bf93408] + +### Fixes +Stop using deprecated ioutil package (#467) [07f405d] + ## 1.16.0 ### Features diff --git a/vendor/github.com/onsi/gomega/Dockerfile b/vendor/github.com/onsi/gomega/Dockerfile deleted file mode 100644 index 11c7e63e7..000000000 --- a/vendor/github.com/onsi/gomega/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -FROM golang:1.15 diff --git a/vendor/github.com/onsi/gomega/Makefile b/vendor/github.com/onsi/gomega/Makefile deleted file mode 100644 index 1c6d107e1..000000000 --- a/vendor/github.com/onsi/gomega/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -###### Help ################################################################### - -.DEFAULT_GOAL = help - -.PHONY: help - -help: ## list Makefile targets - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' - -###### Targets ################################################################ - -test: version download fmt vet ginkgo ## Runs all build, static analysis, and test steps - -download: ## Download dependencies - go mod download - -vet: ## Run static code analysis - go vet ./... - -ginkgo: ## Run tests using Ginkgo - go run github.com/onsi/ginkgo/ginkgo -p -r --randomizeAllSpecs --failOnPending --randomizeSuites --race - -fmt: ## Checks that the code is formatted correcty - @@if [ -n "$$(gofmt -s -e -l -d .)" ]; then \ - echo "gofmt check failed: run 'gofmt -s -e -l -w .'"; \ - exit 1; \ - fi - -docker_test: ## Run tests in a container via docker-compose - docker-compose build test && docker-compose run --rm test make test - -version: ## Display the version of Go - @@go version diff --git a/vendor/github.com/onsi/gomega/RELEASING.md b/vendor/github.com/onsi/gomega/RELEASING.md index 998d64ee7..2d30d9992 100644 --- a/vendor/github.com/onsi/gomega/RELEASING.md +++ b/vendor/github.com/onsi/gomega/RELEASING.md @@ -7,6 +7,11 @@ A Gomega release is a tagged sha and a GitHub release. To cut a release: - New Features (minor version) - Fixes (fix version) - Maintenance (which in general should not be mentioned in `CHANGELOG.md` as they have no user impact) -2. Update GOMEGA_VERSION in `gomega_dsl.go` -3. Push a commit with the version number as the commit message (e.g. `v1.3.0`) -4. Create a new [GitHub release](https://help.github.com/articles/creating-releases/) with the version number as the tag (e.g. `v1.3.0`). List the key changes in the release notes. +1. Update GOMEGA_VERSION in `gomega_dsl.go` +1. Commit, push, and release: + ``` + git commit -m "vM.m.p" + git push + gh release create "vM.m.p" + git fetch --tags origin master + ```
\ No newline at end of file diff --git a/vendor/github.com/onsi/gomega/docker-compose.yaml b/vendor/github.com/onsi/gomega/docker-compose.yaml deleted file mode 100644 index f37496143..000000000 --- a/vendor/github.com/onsi/gomega/docker-compose.yaml +++ /dev/null @@ -1,10 +0,0 @@ -version: '3.0' - -services: - test: - build: - dockerfile: Dockerfile - context: . - working_dir: /app - volumes: - - ${PWD}:/app diff --git a/vendor/github.com/onsi/gomega/gexec/build.go b/vendor/github.com/onsi/gomega/gexec/build.go index 576fc8ee4..0ddb21076 100644 --- a/vendor/github.com/onsi/gomega/gexec/build.go +++ b/vendor/github.com/onsi/gomega/gexec/build.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "go/build" - "io/ioutil" "os" "os/exec" "path" @@ -14,6 +13,8 @@ import ( "runtime" "strings" "sync" + + "github.com/onsi/gomega/internal/gutil" ) var ( @@ -82,11 +83,11 @@ func CompileTest(packagePath string, args ...string) (compiledPath string, err e GetAndCompileTest is identical to CompileTest but `go get` the package before compiling tests. */ func GetAndCompileTest(packagePath string, args ...string) (compiledPath string, err error) { - if err := getForTest(build.Default.GOPATH, packagePath, nil); err != nil { + if err := getForTest(build.Default.GOPATH, packagePath, []string{"GO111MODULE=off"}); err != nil { return "", err } - return doCompileTest(build.Default.GOPATH, packagePath, nil, args...) + return doCompileTest(build.Default.GOPATH, packagePath, []string{"GO111MODULE=off"}, args...) } /* @@ -100,11 +101,11 @@ func CompileTestWithEnvironment(packagePath string, env []string, args ...string GetAndCompileTestWithEnvironment is identical to GetAndCompileTest but allows you to specify env vars to be set at build time. */ func GetAndCompileTestWithEnvironment(packagePath string, env []string, args ...string) (compiledPath string, err error) { - if err := getForTest(build.Default.GOPATH, packagePath, env); err != nil { + if err := getForTest(build.Default.GOPATH, packagePath, append(env, "GO111MODULE=off")); err != nil { return "", err } - return doCompileTest(build.Default.GOPATH, packagePath, env, args...) + return doCompileTest(build.Default.GOPATH, packagePath, append(env, "GO111MODULE=off"), args...) } /* @@ -118,11 +119,11 @@ func CompileTestIn(gopath string, packagePath string, args ...string) (compiledP GetAndCompileTestIn is identical to GetAndCompileTest but allows you to specify a custom $GOPATH (the first argument). */ func GetAndCompileTestIn(gopath string, packagePath string, args ...string) (compiledPath string, err error) { - if err := getForTest(gopath, packagePath, nil); err != nil { + if err := getForTest(gopath, packagePath, []string{"GO111MODULE=off"}); err != nil { return "", err } - return doCompileTest(gopath, packagePath, nil, args...) + return doCompileTest(gopath, packagePath, []string{"GO111MODULE=off"}, args...) } func isLocalPackage(packagePath string) bool { @@ -222,11 +223,11 @@ func temporaryDirectory() (string, error) { mu.Lock() defer mu.Unlock() if tmpDir == "" { - tmpDir, err = ioutil.TempDir("", "gexec_artifacts") + tmpDir, err = gutil.MkdirTemp("", "gexec_artifacts") if err != nil { return "", err } } - return ioutil.TempDir(tmpDir, "g") + return gutil.MkdirTemp(tmpDir, "g") } diff --git a/vendor/github.com/onsi/gomega/go.mod b/vendor/github.com/onsi/gomega/go.mod index 7fea4ac07..276ffb167 100644 --- a/vendor/github.com/onsi/gomega/go.mod +++ b/vendor/github.com/onsi/gomega/go.mod @@ -1,10 +1,16 @@ module github.com/onsi/gomega -go 1.16 +go 1.18 require ( github.com/golang/protobuf v1.5.2 - github.com/onsi/ginkgo v1.16.4 - golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 + github.com/onsi/ginkgo/v2 v2.1.3 + golang.org/x/net v0.0.0-20220225172249-27dd8689420f gopkg.in/yaml.v2 v2.4.0 ) + +require ( + golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect + golang.org/x/text v0.3.7 // indirect + google.golang.org/protobuf v1.26.0 // indirect +) diff --git a/vendor/github.com/onsi/gomega/go.sum b/vendor/github.com/onsi/gomega/go.sum index 56f1b44e2..256e91607 100644 --- a/vendor/github.com/onsi/gomega/go.sum +++ b/vendor/github.com/onsi/gomega/go.sum @@ -1,10 +1,10 @@ +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -21,41 +21,37 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -63,21 +59,22 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -95,9 +92,7 @@ google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/l google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go index 84775142c..dcb7e8879 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.16.0" +const GOMEGA_VERSION = "1.19.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(). @@ -52,7 +52,7 @@ var Default = Gomega(internal.NewGomega(internal.FetchDefaultDurationBundle())) // rich ecosystem of matchers without causing a test to fail. For example, to aggregate a series of potential failures // or for use in a non-test setting. func NewGomega(fail types.GomegaFailHandler) Gomega { - return internal.NewGomega(Default.(*internal.Gomega).DurationBundle).ConfigureWithFailHandler(fail) + return internal.NewGomega(internalGomega(Default).DurationBundle).ConfigureWithFailHandler(fail) } // WithT wraps a *testing.T and provides `Expect`, `Eventually`, and `Consistently` methods. This allows you to leverage @@ -69,6 +69,20 @@ type WithT = internal.Gomega // GomegaWithT is deprecated in favor of gomega.WithT, which does not stutter. type GomegaWithT = WithT +// inner is an interface that allows users to provide a wrapper around Default. The wrapper +// must implement the inner interface and return either the original Default or the result of +// a call to NewGomega(). +type inner interface { + Inner() Gomega +} + +func internalGomega(g Gomega) *internal.Gomega { + if v, ok := g.(inner); ok { + return v.Inner().(*internal.Gomega) + } + return g.(*internal.Gomega) +} + // NewWithT takes a *testing.T and returngs a `gomega.WithT` allowing you to use `Expect`, `Eventually`, and `Consistently` along with // Gomega's rich ecosystem of matchers in standard `testing` test suits. // @@ -79,7 +93,7 @@ type GomegaWithT = WithT // g.Expect(f.HasCow()).To(BeTrue(), "Farm should have cow") // } func NewWithT(t types.GomegaTestingT) *WithT { - return internal.NewGomega(Default.(*internal.Gomega).DurationBundle).ConfigureWithT(t) + return internal.NewGomega(internalGomega(Default).DurationBundle).ConfigureWithT(t) } // NewGomegaWithT is deprecated in favor of gomega.NewWithT, which does not stutter. @@ -88,20 +102,20 @@ var NewGomegaWithT = NewWithT // RegisterFailHandler connects Ginkgo to Gomega. When a matcher fails // the fail handler passed into RegisterFailHandler is called. func RegisterFailHandler(fail types.GomegaFailHandler) { - Default.(*internal.Gomega).ConfigureWithFailHandler(fail) + internalGomega(Default).ConfigureWithFailHandler(fail) } // RegisterFailHandlerWithT is deprecated and will be removed in a future release. // users should use RegisterFailHandler, or RegisterTestingT func RegisterFailHandlerWithT(_ types.GomegaTestingT, fail types.GomegaFailHandler) { fmt.Println("RegisterFailHandlerWithT is deprecated. Please use RegisterFailHandler or RegisterTestingT instead.") - Default.(*internal.Gomega).ConfigureWithFailHandler(fail) + internalGomega(Default).ConfigureWithFailHandler(fail) } // RegisterTestingT connects Gomega to Golang's XUnit style // Testing.T tests. It is now deprecated and you should use NewWithT() instead to get a fresh instance of Gomega for each test. func RegisterTestingT(t types.GomegaTestingT) { - Default.(*internal.Gomega).ConfigureWithT(t) + internalGomega(Default).ConfigureWithT(t) } // InterceptGomegaFailures runs a given callback and returns an array of @@ -112,13 +126,13 @@ func RegisterTestingT(t types.GomegaTestingT) { // This is most useful when testing custom matchers, but can also be used to check // on a value using a Gomega assertion without causing a test failure. func InterceptGomegaFailures(f func()) []string { - originalHandler := Default.(*internal.Gomega).Fail + originalHandler := internalGomega(Default).Fail failures := []string{} - Default.(*internal.Gomega).Fail = func(message string, callerSkip ...int) { + internalGomega(Default).Fail = func(message string, callerSkip ...int) { failures = append(failures, message) } defer func() { - Default.(*internal.Gomega).Fail = originalHandler + internalGomega(Default).Fail = originalHandler }() f() return failures @@ -131,14 +145,14 @@ func InterceptGomegaFailures(f func()) []string { // does not register a failure with the FailHandler registered via RegisterFailHandler - it is up // to the user to decide what to do with the returned error func InterceptGomegaFailure(f func()) (err error) { - originalHandler := Default.(*internal.Gomega).Fail - Default.(*internal.Gomega).Fail = func(message string, callerSkip ...int) { + originalHandler := internalGomega(Default).Fail + internalGomega(Default).Fail = func(message string, callerSkip ...int) { err = errors.New(message) panic("stop execution") } defer func() { - Default.(*internal.Gomega).Fail = originalHandler + internalGomega(Default).Fail = originalHandler if e := recover(); e != nil { if err == nil { panic(e) @@ -151,7 +165,7 @@ func InterceptGomegaFailure(f func()) (err error) { } func ensureDefaultGomegaIsConfigured() { - if !Default.(*internal.Gomega).IsConfigured() { + if !internalGomega(Default).IsConfigured() { panic(nilGomegaPanic) } } @@ -204,7 +218,8 @@ func Expect(actual interface{}, extra ...interface{}) Assertion { // ExpectWithOffset(1, "foo").To(Equal("foo")) // // Unlike `Expect` and `Ω`, `ExpectWithOffset` takes an additional integer argument -// that is used to modify the call-stack offset when computing line numbers. +// that is used to modify the call-stack offset when computing line numbers. It is +// the same as `Expect(...).WithOffset`. // // This is most useful in helper functions that make assertions. If you want Gomega's // error message to refer to the calling line in the test (as opposed to the line in the helper function) @@ -300,6 +315,9 @@ For example: }).Should(Succeed()) will rerun the function until all assertions pass. + +`Eventually` specifying a timeout interval (and an optional polling interval) are +the same as `Eventually(...).WithTimeout` or `Eventually(...).WithTimeout(...).WithPolling`. */ func Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() @@ -309,6 +327,12 @@ func Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion { // EventuallyWithOffset operates like Eventually but takes an additional // initial argument to indicate an offset in the call stack. This is useful when building helper // functions that contain matchers. To learn more, read about `ExpectWithOffset`. +// +// `EventuallyWithOffset` is the same as `Eventually(...).WithOffset`. +// +// `EventuallyWithOffset` specifying a timeout interval (and an optional polling interval) are +// the same as `Eventually(...).WithOffset(...).WithTimeout` or +// `Eventually(...).WithOffset(...).WithTimeout(...).WithPolling`. func EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() return Default.EventuallyWithOffset(offset, actual, intervals...) @@ -337,6 +361,9 @@ func Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion { // ConsistentlyWithOffset operates like Consistently but takes an additional // initial argument to indicate an offset in the call stack. This is useful when building helper // functions that contain matchers. To learn more, read about `ExpectWithOffset`. +// +// `ConsistentlyWithOffset` is the same as `Consistently(...).WithOffset` and +// optional `WithTimeout` and `WithPolling`. func ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() return Default.ConsistentlyWithOffset(offset, actual, intervals...) diff --git a/vendor/github.com/onsi/gomega/internal/assertion.go b/vendor/github.com/onsi/gomega/internal/assertion.go index 36b0e8345..b3c26889a 100644 --- a/vendor/github.com/onsi/gomega/internal/assertion.go +++ b/vendor/github.com/onsi/gomega/internal/assertion.go @@ -8,44 +8,64 @@ import ( ) type Assertion struct { - actualInput interface{} + actuals []interface{} // actual value plus all extra values + actualIndex int // value to pass to the matcher + vet vetinari // the vet to call before calling Gomega matcher offset int - extra []interface{} g *Gomega } +// ...obligatory discworld reference, as "vetineer" doesn't sound ... quite right. +type vetinari func(assertion *Assertion, optionalDescription ...interface{}) bool + func NewAssertion(actualInput interface{}, g *Gomega, offset int, extra ...interface{}) *Assertion { return &Assertion{ - actualInput: actualInput, + actuals: append([]interface{}{actualInput}, extra...), + actualIndex: 0, + vet: (*Assertion).vetActuals, offset: offset, - extra: extra, g: g, } } +func (assertion *Assertion) WithOffset(offset int) types.Assertion { + assertion.offset = offset + return assertion +} + +func (assertion *Assertion) Error() types.Assertion { + return &Assertion{ + actuals: assertion.actuals, + actualIndex: len(assertion.actuals) - 1, + vet: (*Assertion).vetError, + offset: assertion.offset, + g: assertion.g, + } +} + func (assertion *Assertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() - return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, true, optionalDescription...) + return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, true, optionalDescription...) } func (assertion *Assertion) ShouldNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() - return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...) + return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, false, optionalDescription...) } func (assertion *Assertion) To(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() - return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, true, optionalDescription...) + return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, true, optionalDescription...) } func (assertion *Assertion) ToNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() - return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...) + return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, false, optionalDescription...) } func (assertion *Assertion) NotTo(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() - return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...) + return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, false, optionalDescription...) } func (assertion *Assertion) buildDescription(optionalDescription ...interface{}) string { @@ -61,7 +81,8 @@ func (assertion *Assertion) buildDescription(optionalDescription ...interface{}) } func (assertion *Assertion) match(matcher types.GomegaMatcher, desiredMatch bool, optionalDescription ...interface{}) bool { - matches, err := matcher.Match(assertion.actualInput) + actualInput := assertion.actuals[assertion.actualIndex] + matches, err := matcher.Match(actualInput) assertion.g.THelper() if err != nil { description := assertion.buildDescription(optionalDescription...) @@ -71,9 +92,9 @@ func (assertion *Assertion) match(matcher types.GomegaMatcher, desiredMatch bool if matches != desiredMatch { var message string if desiredMatch { - message = matcher.FailureMessage(assertion.actualInput) + message = matcher.FailureMessage(actualInput) } else { - message = matcher.NegatedFailureMessage(assertion.actualInput) + message = matcher.NegatedFailureMessage(actualInput) } description := assertion.buildDescription(optionalDescription...) assertion.g.Fail(description+message, 2+assertion.offset) @@ -83,8 +104,11 @@ func (assertion *Assertion) match(matcher types.GomegaMatcher, desiredMatch bool return true } -func (assertion *Assertion) vetExtras(optionalDescription ...interface{}) bool { - success, message := vetExtras(assertion.extra) +// vetActuals vets the actual values, with the (optional) exception of a +// specific value, such as the first value in case non-error assertions, or the +// last value in case of Error()-based assertions. +func (assertion *Assertion) vetActuals(optionalDescription ...interface{}) bool { + success, message := vetActuals(assertion.actuals, assertion.actualIndex) if success { return true } @@ -95,12 +119,29 @@ func (assertion *Assertion) vetExtras(optionalDescription ...interface{}) bool { return false } -func vetExtras(extras []interface{}) (bool, string) { - for i, extra := range extras { - if extra != nil { - zeroValue := reflect.Zero(reflect.TypeOf(extra)).Interface() - if !reflect.DeepEqual(zeroValue, extra) { - message := fmt.Sprintf("Unexpected non-nil/non-zero extra argument at index %d:\n\t<%T>: %#v", i+1, extra, extra) +// vetError vets the actual values, except for the final error value, in case +// the final error value is non-zero. Otherwise, it doesn't vet the actual +// values, as these are allowed to take on any values unless there is a non-zero +// error value. +func (assertion *Assertion) vetError(optionalDescription ...interface{}) bool { + if err := assertion.actuals[assertion.actualIndex]; err != nil { + // Go error result idiom: all other actual values must be zero values. + return assertion.vetActuals(optionalDescription...) + } + return true +} + +// vetActuals vets a slice of actual values, optionally skipping a particular +// value slice element, such as the first or last value slice element. +func vetActuals(actuals []interface{}, skipIndex int) (bool, string) { + for i, actual := range actuals { + if i == skipIndex { + continue + } + if actual != nil { + zeroValue := reflect.Zero(reflect.TypeOf(actual)).Interface() + if !reflect.DeepEqual(zeroValue, actual) { + message := fmt.Sprintf("Unexpected non-nil/non-zero argument at index %d:\n\t<%T>: %#v", i, actual, actual) return false, message } } diff --git a/vendor/github.com/onsi/gomega/internal/async_assertion.go b/vendor/github.com/onsi/gomega/internal/async_assertion.go index ae20c14b8..99f4ebcfe 100644 --- a/vendor/github.com/onsi/gomega/internal/async_assertion.go +++ b/vendor/github.com/onsi/gomega/internal/async_assertion.go @@ -87,6 +87,21 @@ func NewAsyncAssertion(asyncType AsyncAssertionType, actualInput interface{}, g return out } +func (assertion *AsyncAssertion) WithOffset(offset int) types.AsyncAssertion { + assertion.offset = offset + return assertion +} + +func (assertion *AsyncAssertion) WithTimeout(interval time.Duration) types.AsyncAssertion { + assertion.timeoutInterval = interval + return assertion +} + +func (assertion *AsyncAssertion) WithPolling(interval time.Duration) types.AsyncAssertion { + assertion.pollingInterval = interval + return assertion +} + func (assertion *AsyncAssertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() return assertion.match(matcher, true, optionalDescription...) @@ -118,11 +133,11 @@ func (assertion *AsyncAssertion) pollActual() (interface{}, error) { if err != nil { return nil, err } - extras := []interface{}{} + extras := []interface{}{nil} for _, value := range values[1:] { extras = append(extras, value.Interface()) } - success, message := vetExtras(extras) + success, message := vetActuals(extras, 0) if !success { return nil, errors.New(message) } diff --git a/vendor/github.com/onsi/gomega/internal/gomega.go b/vendor/github.com/onsi/gomega/internal/gomega.go index f5b5c6b7a..d26a67485 100644 --- a/vendor/github.com/onsi/gomega/internal/gomega.go +++ b/vendor/github.com/onsi/gomega/internal/gomega.go @@ -39,12 +39,12 @@ func (g *Gomega) ConfigureWithT(t types.GomegaTestingT) *Gomega { return g } -func (g *Gomega) Ω(atual interface{}, extra ...interface{}) types.Assertion { - return g.ExpectWithOffset(0, atual, extra...) +func (g *Gomega) Ω(actual interface{}, extra ...interface{}) types.Assertion { + return g.ExpectWithOffset(0, actual, extra...) } -func (g *Gomega) Expect(atual interface{}, extra ...interface{}) types.Assertion { - return g.ExpectWithOffset(0, atual, extra...) +func (g *Gomega) Expect(actual interface{}, extra ...interface{}) types.Assertion { + return g.ExpectWithOffset(0, actual, extra...) } func (g *Gomega) ExpectWithOffset(offset int, actual interface{}, extra ...interface{}) types.Assertion { diff --git a/vendor/github.com/onsi/gomega/internal/gutil/post_ioutil.go b/vendor/github.com/onsi/gomega/internal/gutil/post_ioutil.go new file mode 100644 index 000000000..6864055a5 --- /dev/null +++ b/vendor/github.com/onsi/gomega/internal/gutil/post_ioutil.go @@ -0,0 +1,48 @@ +//go:build go1.16 +// +build go1.16 + +// Package gutil is a replacement for ioutil, which should not be used in new +// code as of Go 1.16. With Go 1.16 and higher, this implementation +// uses the ioutil replacement functions in "io" and "os" with some +// Gomega specifics. This means that we should not get deprecation warnings +// for ioutil when they are added. +package gutil + +import ( + "io" + "os" +) + +func NopCloser(r io.Reader) io.ReadCloser { + return io.NopCloser(r) +} + +func ReadAll(r io.Reader) ([]byte, error) { + return io.ReadAll(r) +} + +func ReadDir(dirname string) ([]string, error) { + entries, err := os.ReadDir(dirname) + if err != nil { + return nil, err + } + + var names []string + for _, entry := range entries { + names = append(names, entry.Name()) + } + + return names, nil +} + +func ReadFile(filename string) ([]byte, error) { + return os.ReadFile(filename) +} + +func MkdirTemp(dir, pattern string) (string, error) { + return os.MkdirTemp(dir, pattern) +} + +func WriteFile(filename string, data []byte) error { + return os.WriteFile(filename, data, 0644) +} diff --git a/vendor/github.com/onsi/gomega/internal/gutil/using_ioutil.go b/vendor/github.com/onsi/gomega/internal/gutil/using_ioutil.go new file mode 100644 index 000000000..5c0ce1ee3 --- /dev/null +++ b/vendor/github.com/onsi/gomega/internal/gutil/using_ioutil.go @@ -0,0 +1,47 @@ +//go:build !go1.16 +// +build !go1.16 + +// Package gutil is a replacement for ioutil, which should not be used in new +// code as of Go 1.16. With Go 1.15 and lower, this implementation +// uses the ioutil functions, meaning that although Gomega is not officially +// supported on these versions, it is still likely to work. +package gutil + +import ( + "io" + "io/ioutil" +) + +func NopCloser(r io.Reader) io.ReadCloser { + return ioutil.NopCloser(r) +} + +func ReadAll(r io.Reader) ([]byte, error) { + return ioutil.ReadAll(r) +} + +func ReadDir(dirname string) ([]string, error) { + files, err := ioutil.ReadDir(dirname) + if err != nil { + return nil, err + } + + var names []string + for _, file := range files { + names = append(names, file.Name()) + } + + return names, nil +} + +func ReadFile(filename string) ([]byte, error) { + return ioutil.ReadFile(filename) +} + +func MkdirTemp(dir, pattern string) (string, error) { + return ioutil.TempDir(dir, pattern) +} + +func WriteFile(filename string, data []byte) error { + return ioutil.WriteFile(filename, data, 0644) +} diff --git a/vendor/github.com/onsi/gomega/matchers.go b/vendor/github.com/onsi/gomega/matchers.go index 223f6ef53..b58dd67cb 100644 --- a/vendor/github.com/onsi/gomega/matchers.go +++ b/vendor/github.com/onsi/gomega/matchers.go @@ -256,16 +256,26 @@ func BeZero() types.GomegaMatcher { return &matchers.BeZeroMatcher{} } -//ContainElement succeeds if actual contains the passed in element. -//By default ContainElement() uses Equal() to perform the match, however a -//matcher can be passed in instead: +//ContainElement succeeds if actual contains the passed in element. By default +//ContainElement() uses Equal() to perform the match, however a matcher can be +//passed in instead: // Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubstring("Bar"))) // -//Actual must be an array, slice or map. -//For maps, ContainElement searches through the map's values. -func ContainElement(element interface{}) types.GomegaMatcher { +//Actual must be an array, slice or map. For maps, ContainElement searches +//through the map's values. +// +//If you want to have a copy of the matching element(s) found you can pass a +//pointer to a variable of the appropriate type. If the variable isn't a slice +//or map, then exactly one match will be expected and returned. If the variable +//is a slice or map, then at least one match is expected and all matches will be +//stored in the variable. +// +// var findings []string +// Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubString("Bar", &findings))) +func ContainElement(element interface{}, result ...interface{}) types.GomegaMatcher { return &matchers.ContainElementMatcher{ Element: element, + Result: result, } } @@ -320,6 +330,20 @@ func ContainElements(elements ...interface{}) types.GomegaMatcher { } } +//HaveEach succeeds if actual solely contains elements that match the passed in element. +//Please note that if actual is empty, HaveEach always will succeed. +//By default HaveEach() uses Equal() to perform the match, however a +//matcher can be passed in instead: +// Expect([]string{"Foo", "FooBar"}).Should(HaveEach(ContainSubstring("Foo"))) +// +//Actual must be an array, slice or map. +//For maps, HaveEach searches through the map's values. +func HaveEach(element interface{}) types.GomegaMatcher { + return &matchers.HaveEachMatcher{ + Element: element, + } +} + //HaveKey succeeds if actual is a map with the passed in key. //By default HaveKey uses Equal() to perform the match, however a //matcher can be passed in instead: @@ -342,6 +366,54 @@ func HaveKeyWithValue(key interface{}, value interface{}) types.GomegaMatcher { } } +//HaveField succeeds if actual is a struct and the value at the passed in field +//matches the passed in matcher. By default HaveField used Equal() to perform the match, +//however a matcher can be passed in in stead. +// +//The field must be a string that resolves to the name of a field in the struct. Structs can be traversed +//using the '.' delimiter. If the field ends with '()' a method named field is assumed to exist on the struct and is invoked. +//Such methods must take no arguments and return a single value: +// +// type Book struct { +// Title string +// Author Person +// } +// type Person struct { +// FirstName string +// LastName string +// DOB time.Time +// } +// Expect(book).To(HaveField("Title", "Les Miserables")) +// Expect(book).To(HaveField("Title", ContainSubstring("Les")) +// Expect(book).To(HaveField("Author.FirstName", Equal("Victor")) +// Expect(book).To(HaveField("Author.DOB.Year()", BeNumerically("<", 1900)) +func HaveField(field string, expected interface{}) types.GomegaMatcher { + return &matchers.HaveFieldMatcher{ + Field: field, + Expected: expected, + } +} + +// HaveValue applies the given matcher to the value of actual, optionally and +// repeatedly dereferencing pointers or taking the concrete value of interfaces. +// Thus, the matcher will always be applied to non-pointer and non-interface +// values only. HaveValue will fail with an error if a pointer or interface is +// nil. It will also fail for more than 31 pointer or interface dereferences to +// guard against mistakenly applying it to arbitrarily deep linked pointers. +// +// HaveValue differs from gstruct.PointTo in that it does not expect actual to +// be a pointer (as gstruct.PointTo does) but instead also accepts non-pointer +// and even interface values. +// +// actual := 42 +// Expect(actual).To(HaveValue(42)) +// Expect(&actual).To(HaveValue(42)) +func HaveValue(matcher types.GomegaMatcher) types.GomegaMatcher { + return &matchers.HaveValueMatcher{ + Matcher: matcher, + } +} + //BeNumerically performs numerical assertions in a type-agnostic way. //Actual and expected should be numbers, though the specific type of //number is irrelevant (float32, float64, uint8, etc...). @@ -485,10 +557,15 @@ func Not(matcher types.GomegaMatcher) types.GomegaMatcher { } //WithTransform applies the `transform` to the actual value and matches it against `matcher`. -//The given transform must be a function of one parameter that returns one value. +//The given transform must be either a function of one parameter that returns one value or a +// function of one parameter that returns two values, where the second value must be of the +// error type. // var plus1 = func(i int) int { return i + 1 } // Expect(1).To(WithTransform(plus1, Equal(2)) // +// var failingplus1 = func(i int) (int, error) { return 42, "this does not compute" } +// Expect(1).To(WithTransform(failingplus1, Equal(2))) +// //And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. func WithTransform(transform interface{}, matcher types.GomegaMatcher) types.GomegaMatcher { return matchers.NewWithTransformMatcher(transform, matcher) diff --git a/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go b/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go index 8d6c44c7a..3d45c9ebc 100644 --- a/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go @@ -3,6 +3,7 @@ package matchers import ( + "errors" "fmt" "reflect" @@ -11,6 +12,7 @@ import ( type ContainElementMatcher struct { Element interface{} + Result []interface{} } func (matcher *ContainElementMatcher) Match(actual interface{}) (success bool, err error) { @@ -18,6 +20,49 @@ func (matcher *ContainElementMatcher) Match(actual interface{}) (success bool, e return false, fmt.Errorf("ContainElement matcher expects an array/slice/map. Got:\n%s", format.Object(actual, 1)) } + var actualT reflect.Type + var result reflect.Value + switch l := len(matcher.Result); { + case l > 1: + return false, errors.New("ContainElement matcher expects at most a single optional pointer to store its findings at") + case l == 1: + if reflect.ValueOf(matcher.Result[0]).Kind() != reflect.Ptr { + return false, fmt.Errorf("ContainElement matcher expects a non-nil pointer to store its findings at. Got\n%s", + format.Object(matcher.Result[0], 1)) + } + actualT = reflect.TypeOf(actual) + resultReference := matcher.Result[0] + result = reflect.ValueOf(resultReference).Elem() // what ResultReference points to, to stash away our findings + switch result.Kind() { + case reflect.Array: + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + reflect.SliceOf(actualT.Elem()).String(), result.Type().String()) + case reflect.Slice: + if !isArrayOrSlice(actual) { + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + reflect.MapOf(actualT.Key(), actualT.Elem()).String(), result.Type().String()) + } + if !actualT.Elem().AssignableTo(result.Type().Elem()) { + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + actualT.String(), result.Type().String()) + } + case reflect.Map: + if !isMap(actual) { + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + actualT.String(), result.Type().String()) + } + if !actualT.AssignableTo(result.Type()) { + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + actualT.String(), result.Type().String()) + } + default: + if !actualT.Elem().AssignableTo(result.Type()) { + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + actualT.Elem().String(), result.Type().String()) + } + } + } + elemMatcher, elementIsMatcher := matcher.Element.(omegaMatcher) if !elementIsMatcher { elemMatcher = &EqualMatcher{Expected: matcher.Element} @@ -25,30 +70,99 @@ func (matcher *ContainElementMatcher) Match(actual interface{}) (success bool, e value := reflect.ValueOf(actual) var valueAt func(int) interface{} + + var getFindings func() reflect.Value + var foundAt func(int) + if isMap(actual) { keys := value.MapKeys() valueAt = func(i int) interface{} { return value.MapIndex(keys[i]).Interface() } + if result.Kind() != reflect.Invalid { + fm := reflect.MakeMap(actualT) + getFindings = func() reflect.Value { + return fm + } + foundAt = func(i int) { + fm.SetMapIndex(keys[i], value.MapIndex(keys[i])) + } + } } else { valueAt = func(i int) interface{} { return value.Index(i).Interface() } + if result.Kind() != reflect.Invalid { + var f reflect.Value + if result.Kind() == reflect.Slice { + f = reflect.MakeSlice(result.Type(), 0, 0) + } else { + f = reflect.MakeSlice(reflect.SliceOf(result.Type()), 0, 0) + } + getFindings = func() reflect.Value { + return f + } + foundAt = func(i int) { + f = reflect.Append(f, value.Index(i)) + } + } } var lastError error for i := 0; i < value.Len(); i++ { - success, err := elemMatcher.Match(valueAt(i)) + elem := valueAt(i) + success, err := elemMatcher.Match(elem) if err != nil { lastError = err continue } if success { - return true, nil + if result.Kind() == reflect.Invalid { + return true, nil + } + foundAt(i) } } - return false, lastError + // when the expectation isn't interested in the findings except for success + // or non-success, then we're done here and return the last matcher error + // seen, if any, as well as non-success. + if result.Kind() == reflect.Invalid { + return false, lastError + } + + // pick up any findings the test is interested in as it specified a non-nil + // result reference. However, the expection always is that there are at + // least one or multiple findings. So, if a result is expected, but we had + // no findings, then this is an error. + findings := getFindings() + if findings.Len() == 0 { + return false, lastError + } + + // there's just a single finding and the result is neither a slice nor a map + // (so it's a scalar): pick the one and only finding and return it in the + // place the reference points to. + if findings.Len() == 1 && !isArrayOrSlice(result.Interface()) && !isMap(result.Interface()) { + if isMap(actual) { + miter := findings.MapRange() + miter.Next() + result.Set(miter.Value()) + } else { + result.Set(findings.Index(0)) + } + return true, nil + } + + // at least one or even multiple findings and a the result references a + // slice or a map, so all we need to do is to store our findings where the + // reference points to. + if !findings.Type().AssignableTo(result.Type()) { + return false, fmt.Errorf("ContainElement cannot return multiple findings. Need *%s, got *%s", + findings.Type().String(), result.Type().String()) + } + result.Set(findings) + return true, nil } func (matcher *ContainElementMatcher) FailureMessage(actual interface{}) (message string) { diff --git a/vendor/github.com/onsi/gomega/matchers/have_each_matcher.go b/vendor/github.com/onsi/gomega/matchers/have_each_matcher.go new file mode 100644 index 000000000..025b6e1ac --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/have_each_matcher.go @@ -0,0 +1,65 @@ +package matchers + +import ( + "fmt" + "reflect" + + "github.com/onsi/gomega/format" +) + +type HaveEachMatcher struct { + Element interface{} +} + +func (matcher *HaveEachMatcher) Match(actual interface{}) (success bool, err error) { + if !isArrayOrSlice(actual) && !isMap(actual) { + return false, fmt.Errorf("HaveEach matcher expects an array/slice/map. Got:\n%s", + format.Object(actual, 1)) + } + + elemMatcher, elementIsMatcher := matcher.Element.(omegaMatcher) + if !elementIsMatcher { + elemMatcher = &EqualMatcher{Expected: matcher.Element} + } + + value := reflect.ValueOf(actual) + if value.Len() == 0 { + return false, fmt.Errorf("HaveEach matcher expects a non-empty array/slice/map. Got:\n%s", + format.Object(actual, 1)) + } + + var valueAt func(int) interface{} + if isMap(actual) { + keys := value.MapKeys() + valueAt = func(i int) interface{} { + return value.MapIndex(keys[i]).Interface() + } + } else { + valueAt = func(i int) interface{} { + return value.Index(i).Interface() + } + } + + // if there are no elements, then HaveEach will match. + for i := 0; i < value.Len(); i++ { + success, err := elemMatcher.Match(valueAt(i)) + if err != nil { + return false, err + } + if !success { + return false, nil + } + } + + return true, nil +} + +// FailureMessage returns a suitable failure message. +func (matcher *HaveEachMatcher) FailureMessage(actual interface{}) (message string) { + return format.Message(actual, "to contain element matching", matcher.Element) +} + +// NegatedFailureMessage returns a suitable negated failure message. +func (matcher *HaveEachMatcher) NegatedFailureMessage(actual interface{}) (message string) { + return format.Message(actual, "not to contain element matching", matcher.Element) +} diff --git a/vendor/github.com/onsi/gomega/matchers/have_field.go b/vendor/github.com/onsi/gomega/matchers/have_field.go new file mode 100644 index 000000000..e1fe934d5 --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/have_field.go @@ -0,0 +1,87 @@ +package matchers + +import ( + "fmt" + "reflect" + "strings" + + "github.com/onsi/gomega/format" +) + +func extractField(actual interface{}, field string) (interface{}, error) { + fields := strings.SplitN(field, ".", 2) + actualValue := reflect.ValueOf(actual) + + if actualValue.Kind() == reflect.Ptr { + actualValue = actualValue.Elem() + } + if actualValue == (reflect.Value{}) { + return nil, fmt.Errorf("HaveField encountered nil while dereferencing a pointer of type %T.", actual) + } + + if actualValue.Kind() != reflect.Struct { + return nil, fmt.Errorf("HaveField encountered:\n%s\nWhich is not a struct.", format.Object(actual, 1)) + } + + var extractedValue reflect.Value + + if strings.HasSuffix(fields[0], "()") { + extractedValue = actualValue.MethodByName(strings.TrimSuffix(fields[0], "()")) + if extractedValue == (reflect.Value{}) { + return nil, fmt.Errorf("HaveField could not find method named '%s' in struct of type %T.", fields[0], actual) + } + t := extractedValue.Type() + if t.NumIn() != 0 || t.NumOut() != 1 { + return nil, fmt.Errorf("HaveField found an invalid method named '%s' in struct of type %T.\nMethods must take no arguments and return exactly one value.", fields[0], actual) + } + extractedValue = extractedValue.Call([]reflect.Value{})[0] + } else { + extractedValue = actualValue.FieldByName(fields[0]) + if extractedValue == (reflect.Value{}) { + return nil, fmt.Errorf("HaveField could not find field named '%s' in struct:\n%s", fields[0], format.Object(actual, 1)) + } + } + + if len(fields) == 1 { + return extractedValue.Interface(), nil + } else { + return extractField(extractedValue.Interface(), fields[1]) + } +} + +type HaveFieldMatcher struct { + Field string + Expected interface{} + + extractedField interface{} + expectedMatcher omegaMatcher +} + +func (matcher *HaveFieldMatcher) Match(actual interface{}) (success bool, err error) { + matcher.extractedField, err = extractField(actual, matcher.Field) + if err != nil { + return false, err + } + + var isMatcher bool + matcher.expectedMatcher, isMatcher = matcher.Expected.(omegaMatcher) + if !isMatcher { + matcher.expectedMatcher = &EqualMatcher{Expected: matcher.Expected} + } + + return matcher.expectedMatcher.Match(matcher.extractedField) +} + +func (matcher *HaveFieldMatcher) FailureMessage(actual interface{}) (message string) { + message = fmt.Sprintf("Value for field '%s' failed to satisfy matcher.\n", matcher.Field) + message += matcher.expectedMatcher.FailureMessage(matcher.extractedField) + + return message +} + +func (matcher *HaveFieldMatcher) NegatedFailureMessage(actual interface{}) (message string) { + message = fmt.Sprintf("Value for field '%s' satisfied matcher, but should not have.\n", matcher.Field) + message += matcher.expectedMatcher.NegatedFailureMessage(matcher.extractedField) + + return message +} 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 66cbb254a..6a3dcdc35 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 @@ -2,11 +2,11 @@ package matchers import ( "fmt" - "io/ioutil" "net/http" "net/http/httptest" "github.com/onsi/gomega/format" + "github.com/onsi/gomega/internal/gutil" "github.com/onsi/gomega/types" ) @@ -81,7 +81,7 @@ func (matcher *HaveHTTPBodyMatcher) body(actual interface{}) ([]byte, error) { if a.Body != nil { defer a.Body.Close() var err error - matcher.cachedBody, err = ioutil.ReadAll(a.Body) + matcher.cachedBody, err = gutil.ReadAll(a.Body) if err != nil { return nil, fmt.Errorf("error reading response body: %w", err) } diff --git a/vendor/github.com/onsi/gomega/matchers/have_http_status_matcher.go b/vendor/github.com/onsi/gomega/matchers/have_http_status_matcher.go index 70f54899a..0f66e46ec 100644 --- a/vendor/github.com/onsi/gomega/matchers/have_http_status_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/have_http_status_matcher.go @@ -2,13 +2,13 @@ package matchers import ( "fmt" - "io/ioutil" "net/http" "net/http/httptest" "reflect" "strings" "github.com/onsi/gomega/format" + "github.com/onsi/gomega/internal/gutil" ) type HaveHTTPStatusMatcher struct { @@ -78,7 +78,7 @@ func formatHttpResponse(input interface{}) string { body := "<nil>" if resp.Body != nil { defer resp.Body.Close() - data, err := ioutil.ReadAll(resp.Body) + data, err := gutil.ReadAll(resp.Body) if err != nil { data = []byte("<error reading body>") } diff --git a/vendor/github.com/onsi/gomega/matchers/have_value.go b/vendor/github.com/onsi/gomega/matchers/have_value.go new file mode 100644 index 000000000..f67252835 --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/have_value.go @@ -0,0 +1,54 @@ +package matchers + +import ( + "errors" + "reflect" + + "github.com/onsi/gomega/format" + "github.com/onsi/gomega/types" +) + +const maxIndirections = 31 + +type HaveValueMatcher struct { + Matcher types.GomegaMatcher // the matcher to apply to the "resolved" actual value. + resolvedActual interface{} // the ("resolved") value. +} + +func (m *HaveValueMatcher) Match(actual interface{}) (bool, error) { + val := reflect.ValueOf(actual) + for allowedIndirs := maxIndirections; allowedIndirs > 0; allowedIndirs-- { + // return an error if value isn't valid. Please note that we cannot + // check for nil here, as we might not deal with a pointer or interface + // at this point. + if !val.IsValid() { + return false, errors.New(format.Message( + actual, "not to be <nil>")) + } + switch val.Kind() { + case reflect.Ptr, reflect.Interface: + // resolve pointers and interfaces to their values, then rinse and + // repeat. + if val.IsNil() { + return false, errors.New(format.Message( + actual, "not to be <nil>")) + } + val = val.Elem() + continue + default: + // forward the final value to the specified matcher. + m.resolvedActual = val.Interface() + return m.Matcher.Match(m.resolvedActual) + } + } + // too many indirections: extreme star gazing, indeed...? + return false, errors.New(format.Message(actual, "too many indirections")) +} + +func (m *HaveValueMatcher) FailureMessage(_ interface{}) (message string) { + return m.Matcher.FailureMessage(m.resolvedActual) +} + +func (m *HaveValueMatcher) NegatedFailureMessage(_ interface{}) (message string) { + return m.Matcher.NegatedFailureMessage(m.resolvedActual) +} diff --git a/vendor/github.com/onsi/gomega/matchers/with_transform.go b/vendor/github.com/onsi/gomega/matchers/with_transform.go index 8a06bd384..6f743b1b3 100644 --- a/vendor/github.com/onsi/gomega/matchers/with_transform.go +++ b/vendor/github.com/onsi/gomega/matchers/with_transform.go @@ -9,7 +9,7 @@ import ( type WithTransformMatcher struct { // input - Transform interface{} // must be a function of one parameter that returns one value + Transform interface{} // must be a function of one parameter that returns one value and an optional error Matcher types.GomegaMatcher // cached value @@ -19,6 +19,9 @@ type WithTransformMatcher struct { transformedValue interface{} } +// reflect.Type for error +var errorT = reflect.TypeOf((*error)(nil)).Elem() + func NewWithTransformMatcher(transform interface{}, matcher types.GomegaMatcher) *WithTransformMatcher { if transform == nil { panic("transform function cannot be nil") @@ -27,8 +30,10 @@ func NewWithTransformMatcher(transform interface{}, matcher types.GomegaMatcher) if txType.NumIn() != 1 { panic("transform function must have 1 argument") } - if txType.NumOut() != 1 { - panic("transform function must have 1 return value") + if numout := txType.NumOut(); numout != 1 { + if numout != 2 || !txType.Out(1).AssignableTo(errorT) { + panic("transform function must either have 1 return value, or 1 return value plus 1 error value") + } } return &WithTransformMatcher{ @@ -57,6 +62,11 @@ func (m *WithTransformMatcher) Match(actual interface{}) (bool, error) { // call the Transform function with `actual` fn := reflect.ValueOf(m.Transform) result := fn.Call([]reflect.Value{param}) + if len(result) == 2 { + if !result[1].IsNil() { + return false, fmt.Errorf("Transform function failed: %s", result[1].Interface().(error).Error()) + } + } m.transformedValue = result[0].Interface() // expect exactly one value return m.Matcher.Match(m.transformedValue) diff --git a/vendor/github.com/onsi/gomega/tools b/vendor/github.com/onsi/gomega/tools new file mode 100644 index 000000000..e4195cf36 --- /dev/null +++ b/vendor/github.com/onsi/gomega/tools @@ -0,0 +1,8 @@ +//go:build tools +// +build tools + +package main + +import ( + _ "github.com/onsi/ginkgo/v2/ginkgo" +) diff --git a/vendor/github.com/onsi/gomega/types/types.go b/vendor/github.com/onsi/gomega/types/types.go index c75fcb3cc..c315ef065 100644 --- a/vendor/github.com/onsi/gomega/types/types.go +++ b/vendor/github.com/onsi/gomega/types/types.go @@ -66,6 +66,10 @@ func MatchMayChangeInTheFuture(matcher GomegaMatcher, value interface{}) bool { type AsyncAssertion interface { Should(matcher GomegaMatcher, optionalDescription ...interface{}) bool ShouldNot(matcher GomegaMatcher, optionalDescription ...interface{}) bool + + WithOffset(offset int) AsyncAssertion + WithTimeout(interval time.Duration) AsyncAssertion + WithPolling(interval time.Duration) AsyncAssertion } // Assertions are returned by Ω and Expect and enable assertions against Gomega matchers @@ -76,4 +80,8 @@ type Assertion interface { To(matcher GomegaMatcher, optionalDescription ...interface{}) bool ToNot(matcher GomegaMatcher, optionalDescription ...interface{}) bool NotTo(matcher GomegaMatcher, optionalDescription ...interface{}) bool + + WithOffset(offset int) Assertion + + Error() Assertion } diff --git a/vendor/modules.txt b/vendor/modules.txt index b1e0e3a23..69e276940 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -87,7 +87,7 @@ github.com/containernetworking/cni/pkg/version # github.com/containernetworking/plugins v1.1.1 ## explicit github.com/containernetworking/plugins/pkg/ns -# github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057 +# github.com/containers/buildah v1.25.2-0.20220423102655-8f2bb8876f3f ## explicit github.com/containers/buildah github.com/containers/buildah/bind @@ -109,7 +109,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.47.5-0.20220421111103-112a47964ddb +# github.com/containers/common v0.47.5-0.20220425182415-4081e6be9356 ## explicit github.com/containers/common/libimage github.com/containers/common/libimage/manifests @@ -132,6 +132,7 @@ github.com/containers/common/pkg/config github.com/containers/common/pkg/download github.com/containers/common/pkg/filters github.com/containers/common/pkg/flag +github.com/containers/common/pkg/machine github.com/containers/common/pkg/manifests github.com/containers/common/pkg/netns github.com/containers/common/pkg/parse @@ -154,7 +155,7 @@ github.com/containers/common/version # github.com/containers/conmon v2.0.20+incompatible ## explicit github.com/containers/conmon/runner/config -# github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c +# github.com/containers/image/v5 v5.21.1-0.20220425080628-be085685e524 ## explicit github.com/containers/image/v5/copy github.com/containers/image/v5/directory @@ -234,7 +235,7 @@ github.com/containers/psgo/internal/dev github.com/containers/psgo/internal/host github.com/containers/psgo/internal/proc github.com/containers/psgo/internal/process -# github.com/containers/storage v1.39.1-0.20220421071128-4899f8265d63 +# github.com/containers/storage v1.39.1-0.20220422100603-8996869ae40b ## explicit github.com/containers/storage github.com/containers/storage/drivers @@ -531,7 +532,7 @@ github.com/onsi/ginkgo/reporters/stenographer github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty github.com/onsi/ginkgo/types -# github.com/onsi/gomega v1.19.0 => github.com/onsi/gomega v1.16.0 +# github.com/onsi/gomega v1.19.0 ## explicit github.com/onsi/gomega github.com/onsi/gomega/format @@ -540,6 +541,7 @@ github.com/onsi/gomega/gexec github.com/onsi/gomega/gstruct github.com/onsi/gomega/gstruct/errors github.com/onsi/gomega/internal +github.com/onsi/gomega/internal/gutil github.com/onsi/gomega/matchers github.com/onsi/gomega/matchers/support/goraph/bipartitegraph github.com/onsi/gomega/matchers/support/goraph/edge @@ -866,4 +868,3 @@ gopkg.in/yaml.v2 gopkg.in/yaml.v3 # sigs.k8s.io/yaml v1.3.0 sigs.k8s.io/yaml -# github.com/onsi/gomega => github.com/onsi/gomega v1.16.0 |