diff options
403 files changed, 13004 insertions, 6339 deletions
diff --git a/.github/workflows/check_cirrus_cron.yml b/.github/workflows/check_cirrus_cron.yml index d869576fd..65c483c96 100644 --- a/.github/workflows/check_cirrus_cron.yml +++ b/.github/workflows/check_cirrus_cron.yml @@ -6,10 +6,12 @@ name: check_cirrus_cron on: - # Note: This only applies to the master branch. + # Note: This only applies to the main branch. schedule: - # Assume cirrus cron jobs runs at least once per day - - cron: '59 23 * * *' + # N/B: This should correspond to a period slightly after + # the last job finishes running. See job defs. at: + # https://cirrus-ci.com/settings/repository/6707778565701632 + - cron: '59 23 * * 1-5' # Debug: Allow triggering job manually in github-actions WebUI workflow_dispatch: {} @@ -30,7 +32,6 @@ jobs: steps: - uses: actions/checkout@v2 with: - ref: master persist-credentials: false - name: Get failed cron names and Build IDs diff --git a/.github/workflows/multi-arch-build.yaml b/.github/workflows/multi-arch-build.yaml index 9bd98078b..f364cd6c6 100644 --- a/.github/workflows/multi-arch-build.yaml +++ b/.github/workflows/multi-arch-build.yaml @@ -1,6 +1,6 @@ --- -# Please see contrib/podmanimage/README.md for details on the intentions +# Please see contrib/<reponame>image/README.md for details on the intentions # of this workflow. # # BIG FAT WARNING: This workflow is duplicated across containers/skopeo, @@ -11,7 +11,7 @@ name: build multi-arch images on: - # Upstream podman tends to be very active, with many merges per day. + # Upstream tends to be very active, with many merges per day. # Only run this daily via cron schedule, or manually, not by branch push. schedule: - cron: '0 8 * * *' @@ -20,19 +20,23 @@ on: jobs: multi: - name: multi-arch Podman build + name: multi-arch image build env: - PODMAN_QUAY_REGISTRY: quay.io/podman + REPONAME: podman # No easy way to parse this out of $GITHUB_REPOSITORY + # Server/namespace value used to format FQIN + REPONAME_QUAY_REGISTRY: quay.io/podman CONTAINERS_QUAY_REGISTRY: quay.io/containers # list of architectures for build PLATFORMS: linux/amd64,linux/s390x,linux/ppc64le,linux/arm64 + # Command to execute in container to obtain project version number + VERSION_CMD: "podman --version" # build several images (upstream, testing, stable) in parallel strategy: # By default, failure of one matrix item cancels all others fail-fast: false matrix: - # Builds are located under contrib/podmanimage/<source> directory + # Builds are located under contrib/<reponame>image/<source> directory source: - upstream - testing @@ -57,14 +61,14 @@ jobs: driver-opts: network=host install: true - - name: Build and locally push Podman + - name: Build and locally push image uses: docker/build-push-action@v2 with: - context: contrib/podmanimage/${{ matrix.source }} - file: ./contrib/podmanimage/${{ matrix.source }}/Dockerfile + context: contrib/${{ env.REPONAME }}image/${{ matrix.source }} + file: ./contrib/${{ env.REPONAME }}image/${{ matrix.source }}/Dockerfile platforms: ${{ env.PLATFORMS }} push: true - tags: localhost:5000/podman/${{ matrix.source }} + tags: localhost:5000/${{ env.REPONAME }}/${{ matrix.source }} # Simple verification that stable images work, and # also grab version number use in forming the FQIN. @@ -73,41 +77,41 @@ jobs: id: sniff_test run: | podman pull --tls-verify=false \ - localhost:5000/podman/${{ matrix.source }} - VERSION_OUTPUT="$(podman run \ - localhost:5000/podman/${{ matrix.source }} \ - podman --storage-driver=vfs version)" + localhost:5000/$REPONAME/${{ matrix.source }} + VERSION_OUTPUT=$(podman run \ + localhost:5000/$REPONAME/${{ matrix.source }} \ + $VERSION_CMD) echo "$VERSION_OUTPUT" - VERSION=$(grep -Em1 '^Version: ' <<<"$VERSION_OUTPUT" | awk '{print $2}') + VERSION=$(awk -r -e "/^${REPONAME} version /"'{print $3}' <<<"$VERSION_OUTPUT") test -n "$VERSION" - echo "::set-output name=version::${VERSION}" + echo "::set-output name=version::$VERSION" - - name: Generate podman reg. image FQIN(s) - id: podman_reg + - name: Generate image FQIN(s) to push + id: gen_fqin run: | if [[ "${{ matrix.source }}" == 'stable' ]]; then - # The `podman version` in image just built + # The command version in image just built VERSION='v${{ steps.sniff_test.outputs.version }}' # workaround vim syntax-highlight bug: ' # Image tags previously pushed to quay ALLTAGS=$(skopeo list-tags \ - docker://$PODMAN_QUAY_REGISTRY/stable | \ + docker://$REPONAME_QUAY_REGISTRY/stable | \ jq -r '.Tags[]') - # New version? Push quay.io/podman/stable:vX.X.X and :latest + # New version? Push quay.io/$REPONAME/stable:vX.X.X and :latest if ! fgrep -qx "$VERSION" <<<"$ALLTAGS"; then # Assume version-tag is also the most up to date (i.e. "latest") - FQIN="$PODMAN_QUAY_REGISTRY/stable:$VERSION,$PODMAN_QUAY_REGISTRY/stable:latest" + FQIN="$REPONAME_QUAY_REGISTRY/stable:$VERSION,$REPONAME_QUAY_REGISTRY/stable:latest" else # Not a new version-tagged image # Assume other contents changed, so this is the "new" latest. - FQIN="$PODMAN_QUAY_REGISTRY/stable:latest" + FQIN="$REPONAME_QUAY_REGISTRY/stable:latest" fi elif [[ "${{ matrix.source }}" == 'testing' ]]; then # Assume some contents changed, always push latest testing. - FQIN="$PODMAN_QUAY_REGISTRY/testing:latest" + FQIN="$REPONAME_QUAY_REGISTRY/testing:latest" elif [[ "${{ matrix.source }}" == 'upstream' ]]; then # Assume some contents changed, always push latest upstream. - FQIN="$PODMAN_QUAY_REGISTRY/upstream:latest" + FQIN="$REPONAME_QUAY_REGISTRY/upstream:latest" else echo "::error::Unknown matrix item '${{ matrix.source }}'" exit 1 @@ -126,14 +130,14 @@ jobs: VERSION='v${{ steps.sniff_test.outputs.version }}' # workaround vim syntax-highlight bug: ' ALLTAGS=$(skopeo list-tags \ - docker://$CONTAINERS_QUAY_REGISTRY/podman | \ + docker://$CONTAINERS_QUAY_REGISTRY/$REPONAME | \ jq -r '.Tags[]') - # New version? Push quay.io/containers/podman:vX.X.X and latest + # New version? Push quay.io/containers/$REPONAME:vX.X.X and latest if ! fgrep -qx "$VERSION" <<<"$ALLTAGS"; then - FQIN="$CONTAINERS_QUAY_REGISTRY/podman:$VERSION,$CONTAINERS_QUAY_REGISTRY/podman:latest" + FQIN="$CONTAINERS_QUAY_REGISTRY/$REPONAME:$VERSION,$CONTAINERS_QUAY_REGISTRY/$REPONAME:latest" else # Not a new version-tagged image, only update latest. - FQIN="$CONTAINERS_QUAY_REGISTRY/podman:latest" + FQIN="$CONTAINERS_QUAY_REGISTRY/$REPONAME:latest" fi echo "::warning::Pushing $FQIN" echo "::set-output name=fqin::${FQIN}" @@ -153,40 +157,39 @@ jobs: DELIMITER EOF - # Separate steps to login and push for podman and containers quay - # repositories are required, because 2 sets of credentials are used and `docker - # login` as well as `podman login` do not support having 2 different - # credential sets for 1 registry. - # At the same time reuse of non-shell steps is not supported by Github Actions - # via anchors or composite actions + # Separate steps to login and push for $REPONAME_QUAY_REGISTRY and + # $CONTAINERS_QUAY_REGISTRY are required, because 2 sets of credentials + # are used and namespaced within the registry. At the same time, reuse + # of non-shell steps is not supported by Github Actions nor are YAML + # anchors/aliases, nor composite actions. - # Push to 'podman' Quay repo for stable, testing. and upstream - - name: Login to 'podman' Quay registry + # Push to $REPONAME_QUAY_REGISTRY for stable, testing. and upstream + - name: Login to ${{ env.REPONAME_QUAY_REGISTRY }} uses: docker/login-action@v1 - if: steps.podman_reg.outputs.push == 'true' + if: steps.gen_fqin.outputs.push == 'true' with: - registry: ${{ env.PODMAN_QUAY_REGISTRY }} + registry: ${{ env.REPONAME_QUAY_REGISTRY }} # N/B: Secrets are not passed to workflows that are triggered # by a pull request from a fork - username: ${{ secrets.PODMAN_QUAY_USERNAME }} - password: ${{ secrets.PODMAN_QUAY_PASSWORD }} + username: ${{ secrets.REPONAME_QUAY_USERNAME }} + password: ${{ secrets.REPONAME_QUAY_PASSWORD }} - - name: Push images to 'podman' Quay + - name: Push images to ${{ steps.gen_fqin.outputs.fqin }} uses: docker/build-push-action@v2 - if: steps.podman_reg.outputs.push == 'true' + if: steps.gen_fqin.outputs.push == 'true' with: - cache-from: type=registry,ref=localhost:5000/podman/${{ matrix.source }} + cache-from: type=registry,ref=localhost:5000/${{ env.REPONAME }}/${{ matrix.source }} cache-to: type=inline - context: contrib/podmanimage/${{ matrix.source }} - file: ./contrib/podmanimage/${{ matrix.source }}/Dockerfile + context: contrib/${{ env.REPONAME }}image/${{ matrix.source }} + file: ./contrib/${{ env.REPONAME }}image/${{ matrix.source }}/Dockerfile platforms: ${{ env.PLATFORMS }} push: true - tags: ${{ steps.podman_reg.outputs.fqin }} + tags: ${{ steps.gen_fqin.outputs.fqin }} labels: | ${{ env.LABELS }} - # Push to 'containers' Quay repo only stable podman - - name: Login to 'containers' Quay registry + # Push to $CONTAINERS_QUAY_REGISTRY only stable + - name: Login to ${{ env.CONTAINERS_QUAY_REGISTRY }} if: steps.containers_reg.outputs.push == 'true' uses: docker/login-action@v1 with: @@ -194,14 +197,14 @@ jobs: username: ${{ secrets.CONTAINERS_QUAY_USERNAME }} password: ${{ secrets.CONTAINERS_QUAY_PASSWORD }} - - name: Push images to 'containers' Quay + - name: Push images to ${{ steps.containers_reg.outputs.fqin }} if: steps.containers_reg.outputs.push == 'true' uses: docker/build-push-action@v2 with: - cache-from: type=registry,ref=localhost:5000/podman/${{ matrix.source }} + cache-from: type=registry,ref=localhost:5000/${{ env.REPONAME }}/${{ matrix.source }} cache-to: type=inline - context: contrib/podmanimage/${{ matrix.source }} - file: ./contrib/podmanimage/${{ matrix.source }}/Dockerfile + context: contrib/${{ env.REPONAME }}image/${{ matrix.source }} + file: ./contrib/${{ env.REPONAME }}image/${{ matrix.source }}/Dockerfile platforms: ${{ env.PLATFORMS }} push: true tags: ${{ steps.containers_reg.outputs.fqin }} @@ -261,7 +261,7 @@ codespell: codespell -S bin,vendor,.git,go.sum,changelog.txt,.cirrus.yml,"RELEASE_NOTES.md,*.xz,*.gz,*.tar,*.tgz,bin2img,*ico,*.png,*.1,*.5,copyimg,*.orig,apidoc.go" -L uint,iff,od,seeked,splitted,marge,ERRO,hist,ether -w .PHONY: validate -validate: gofmt lint .gitvalidation validate.completions man-page-check swagger-check tests-included +validate: gofmt lint .gitvalidation validate.completions man-page-check swagger-check tests-included tests-expect-exit .PHONY: build-all-new-commits build-all-new-commits: @@ -605,6 +605,16 @@ test-binaries: test/checkseccomp/checkseccomp test/goecho/goecho install.cataton tests-included: contrib/cirrus/pr-should-include-tests +.PHONY: tests-expect-exit +tests-expect-exit: + @if egrep 'Expect.*ExitCode' test/e2e/*.go | egrep -v ', ".*"\)'; then \ + echo "^^^ Unhelpful use of Expect(ExitCode())"; \ + echo " Please use '.Should(Exit(...))' pattern instead."; \ + echo " If that's not possible, please add an annotation (description) to your assertion:"; \ + echo " Expect(...).To(..., \"Friendly explanation of this check\")"; \ + exit 1; \ + fi + ### ### Release/Packaging targets ### @@ -5,7 +5,7 @@ Podman (the POD MANager) is a tool for managing containers and images, volumes mounted into those containers, and pods made from groups of containers. Podman is based on libpod, a library for container lifecycle management that is also contained in this repository. The libpod library provides APIs for managing containers, pods, container images, and volumes. -* [Latest Version: 3.2.0](https://github.com/containers/podman/releases/latest) +* [Latest Version: 3.2.3](https://github.com/containers/podman/releases/latest) * Latest Remote client for Windows * Latest Remote client for macOS * Latest Static Remote client for Linux diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index c6efff5dd..ba323e6a0 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,74 @@ # Release Notes +## 3.2.3 +### Security +- This release addresses CVE-2021-3602, an issue with the `podman build` command with the `--isolation chroot` flag that results in environment variables from the host leaking into build containers. + +### Bugfixes +- Fixed a bug where events related to images could occur before the relevant operation had completed (e.g. an image pull event could be written before the pull was finished) ([#10812](https://github.com/containers/podman/issues/10812)). +- Fixed a bug where `podman save` would refuse to save images with an architecture different from that of the host ([#10835](https://github.com/containers/podman/issues/10835)). +- Fixed a bug where the `podman import` command did not correctly handle images without tags ([#10854](https://github.com/containers/podman/issues/10854)). +- Fixed a bug where Podman's journald events backend would fail and prevent Podman from running when run on a host with systemd as PID1 but in an environment (e.g. a container) without systemd ([#10863](https://github.com/containers/podman/issues/10863)). +- Fixed a bug where containers using rootless CNI networking would fail to start when the `dnsname` CNI plugin was in use and the host system's `/etc/resolv.conf` was a symlink ([#10855](https://github.com/containers/podman/issues/10855) and [#10929](https://github.com/containers/podman/issues/10929)). +- Fixed a bug where containers using rootless CNI networking could fail to start due to a race in rootless CNI initialization ([#10930](https://github.com/containers/podman/issues/10930)). + +### Misc +- Updated Buildah to v1.21.3 +- Updated the containers/common library to v0.38.16 + +## 3.2.2 +### Changes +- Podman's handling of the Architecture field of images has been relaxed. Since 3.2.0, Podman required that the architecture of the image match the architecture of the system to run containers based on an image, but images often incorrectly report architecture, causing Podman to reject valid images ([#10648](https://github.com/containers/podman/issues/10648) and [#10682](https://github.com/containers/podman/issues/10682)). +- Podman no longer uses inotify to monitor for changes to CNI configurations. This removes potential issues where Podman cannot be run because a user has exhausted their available inotify sessions ([#10686](https://github.com/containers/podman/issues/10686)). + +### Bugfixes +- Fixed a bug where the `podman cp` would, when given a directory as its source and a target that existed and was a file, copy the contents of the directory into the parent directory of the file; this now results in an error. +- Fixed a bug where the `podman logs` command would, when following a running container's logs, not include the last line of output from the container when it exited when the `k8s-file` driver was in use ([#10675](https://github.com/containers/podman/issues/10675)). +- Fixed a bug where Podman would fail to run containers if `systemd-resolved` was incorrectly detected as the system's DNS server ([#10733](https://github.com/containers/podman/issues/10733)). +- Fixed a bug where the `podman exec -t` command would only resize the exec session's TTY after the session started, leading to a race condition where the terminal would initially not have a size set ([#10560](https://github.com/containers/podman/issues/10560)). +- Fixed a bug where Podman containers using the `slirp4netns` network mode would add an incorrect entry to `/etc/hosts` pointing the container's hostname to the wrong IP address. +- Fixed a bug where Podman would create volumes specified by images with incorrect permissions ([#10188](https://github.com/containers/podman/issues/10188) and [#10606](https://github.com/containers/podman/issues/10606)). +- Fixed a bug where Podman would not respect the `uid` and `gid` options to `podman volume create -o` ([#10620](https://github.com/containers/podman/issues/10620)). +- Fixed a bug where the `podman run` command could panic when parsing the system's cgroup configuration ([#10666](https://github.com/containers/podman/issues/10666)). +- Fixed a bug where the remote Podman client's `podman build -f - ...` command did not read a Containerfile from STDIN ([#10621](https://github.com/containers/podman/issues/10621)). +- Fixed a bug where the `podman container restore --import` command would fail to restore checkpoints created from privileged containers ([#10615](https://github.com/containers/podman/issues/10615)). +- Fixed a bug where Podman was not respecting the `TMPDIR` environment variable when pulling images ([#10698](https://github.com/containers/podman/issues/10698)). +- Fixed a bug where a number of Podman commands did not properly support using Go templates as an argument to the `--format` option. + +### API +- Fixed a bug where the Compat Inspect endpoint for Containers did not include information on container healthchecks ([#10457](https://github.com/containers/podman/issues/10457)). +- Fixed a bug where the Libpod and Compat Build endpoints for Images did not properly handle the `devices` query parameter ([#10614](https://github.com/containers/podman/issues/10614)). + +### Misc +- Fixed a bug where the Makefile's `make podman-remote-static` target to build a statically-linked `podman-remote` binary was instead producing dynamic binaries ([#10656](https://github.com/containers/podman/issues/10656)). +- Updated the containers/common library to v0.38.11 + +## 3.2.1 +### Changes +- Podman now allows corrupt images (e.g. from restarting the system during an image pull) to be replaced by a `podman pull` of the same image (instead of requiring they be removed first, then re-pulled). + +### Bugfixes +- Fixed a bug where Podman would fail to start containers if a Seccomp profile was not available at `/usr/share/containers/seccomp.json` ([#10556](https://github.com/containers/podman/issues/10556)). +- Fixed a bug where the `podman machine start` command failed on OS X machines with the AMD64 architecture and certain QEMU versions ([#10555](https://github.com/containers/podman/issues/10555)). +- Fixed a bug where Podman would always use the slow path for joining the rootless user namespace. +- Fixed a bug where the `podman stats` command would fail on Cgroups v1 systems when run on a container running systemd ([#10602](https://github.com/containers/podman/issues/10602)). +- Fixed a bug where pre-checkpoint support for `podman container checkpoint` did not function correctly. +- Fixed a bug where the remote Podman client's `podman build` command did not properly handle the `-f` option ([#9871](https://github.com/containers/podman/issues/9871)). +- Fixed a bug where the remote Podman client's `podman run` command would sometimes not resize the container's terminal before execution began ([#9859](https://github.com/containers/podman/issues/9859)). +- Fixed a bug where the `--filter` option to the `podman image prune` command was nonfunctional. +- Fixed a bug where the `podman logs -f` command would exit before all output for a container was printed when the `k8s-file` log driver was in use ([#10596](https://github.com/containers/podman/issues/10596)). +- Fixed a bug where Podman would not correctly detect that systemd-resolved was in use on the host and adjust DNS servers in the container appropriately under some circumstances ([#10570](https://github.com/containers/podman/issues/10570)). +- Fixed a bug where the `podman network connect` and `podman network disconnect` commands acted improperly when containers were in the Created state, marking the changes as done but not actually performing them. + +### API +- Fixed a bug where the Compat and Libpod Prune endpoints for Networks returned null, instead of an empty array, when nothing was pruned. +- Fixed a bug where the Create API for Images would continue to pull images even if a client closed the connection mid-pull ([#7558](https://github.com/containers/podman/issues/7558)). +- Fixed a bug where the Events API did not include some information (including labels) when sending events. +- Fixed a bug where the Events API would, when streaming was not requested, send at most one event ([#10529](https://github.com/containers/podman/issues/10529)). + +### Misc +- Updated the containers/common library to v0.38.9 + ## 3.2.0 ### Features - Docker Compose is now supported with rootless Podman ([#9169](https://github.com/containers/podman/issues/9169)). diff --git a/cmd/podman/auto-update.go b/cmd/podman/auto-update.go index 99226790f..9622088d5 100644 --- a/cmd/podman/auto-update.go +++ b/cmd/podman/auto-update.go @@ -1,10 +1,15 @@ package main import ( + "encoding/json" "fmt" + "os" + "strings" "github.com/containers/common/pkg/auth" "github.com/containers/common/pkg/completion" + "github.com/containers/common/pkg/report" + "github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/errorhandling" @@ -12,8 +17,13 @@ import ( "github.com/spf13/cobra" ) +type cliAutoUpdateOptions struct { + entities.AutoUpdateOptions + format string +} + var ( - autoUpdateOptions = entities.AutoUpdateOptions{} + autoUpdateOptions = cliAutoUpdateOptions{} autoUpdateDescription = `Auto update containers according to their auto-update policy. Auto-update policies are specified with the "io.containers.autoupdate" label. @@ -42,6 +52,11 @@ func init() { authfileFlagName := "authfile" flags.StringVar(&autoUpdateOptions.Authfile, authfileFlagName, auth.GetDefaultAuthFile(), "Path to the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") _ = autoUpdateCommand.RegisterFlagCompletionFunc(authfileFlagName, completion.AutocompleteDefault) + + flags.BoolVar(&autoUpdateOptions.DryRun, "dry-run", false, "Check for pending updates") + + flags.StringVar(&autoUpdateOptions.format, "format", "", "Change the output format to JSON or a Go template") + _ = autoUpdateCommand.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(autoUpdateOutput{})) } func autoUpdate(cmd *cobra.Command, args []string) error { @@ -49,11 +64,83 @@ func autoUpdate(cmd *cobra.Command, args []string) error { // Backwards compat. System tests expect this error string. return errors.Errorf("`%s` takes no arguments", cmd.CommandPath()) } - report, failures := registry.ContainerEngine().AutoUpdate(registry.GetContext(), autoUpdateOptions) - if report != nil { - for _, unit := range report.Units { - fmt.Println(unit) - } + + allReports, failures := registry.ContainerEngine().AutoUpdate(registry.GetContext(), autoUpdateOptions.AutoUpdateOptions) + if allReports == nil { + return errorhandling.JoinErrors(failures) + } + + if err := writeTemplate(allReports, autoUpdateOptions.format); err != nil { + failures = append(failures, err) } + return errorhandling.JoinErrors(failures) } + +type autoUpdateOutput struct { + Unit string + Container string + ContainerName string + ContainerID string + Image string + Policy string + Updated string +} + +func reportsToOutput(allReports []*entities.AutoUpdateReport) []autoUpdateOutput { + output := make([]autoUpdateOutput, len(allReports)) + for i, r := range allReports { + output[i] = autoUpdateOutput{ + Unit: r.SystemdUnit, + Container: fmt.Sprintf("%s (%s)", r.ContainerID[:12], r.ContainerName), + ContainerName: r.ContainerName, + ContainerID: r.ContainerID, + Image: r.ImageName, + Policy: r.Policy, + Updated: r.Updated, + } + } + return output +} + +func writeTemplate(allReports []*entities.AutoUpdateReport, inputFormat string) error { + var format string + var printHeader bool + + output := reportsToOutput(allReports) + switch inputFormat { + case "": + rows := []string{"{{.Unit}}", "{{.Container}}", "{{.Image}}", "{{.Policy}}", "{{.Updated}}"} + format = "{{range . }}" + strings.Join(rows, "\t") + "\n{{end -}}" + printHeader = true + case "json": + prettyJSON, err := json.MarshalIndent(output, "", " ") + if err != nil { + return err + } + fmt.Println(string(prettyJSON)) + return nil + default: + format = "{{range . }}" + inputFormat + "\n{{end -}}" + } + + tmpl, err := report.NewTemplate("auto-update").Parse(format) + if err != nil { + return err + } + + w, err := report.NewWriterDefault(os.Stdout) + if err != nil { + return err + } + defer w.Flush() + + if printHeader { + headers := report.Headers(autoUpdateOutput{}, nil) + if err := tmpl.Execute(w, headers); err != nil { + return err + } + } + + return tmpl.Execute(w, output) +} diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go index 177d094aa..08b2f6235 100644 --- a/cmd/podman/common/completion.go +++ b/cmd/podman/common/completion.go @@ -46,7 +46,9 @@ func setupContainerEngine(cmd *cobra.Command) (entities.ContainerEngine, error) return nil, err } if !registry.IsRemote() && rootless.IsRootless() { - err := containerEngine.SetupRootless(registry.Context(), cmd) + _, noMoveProcess := cmd.Annotations[registry.NoMoveProcess] + + err := containerEngine.SetupRootless(registry.Context(), noMoveProcess) if err != nil { return nil, err } diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go index 64d1956eb..96414add4 100644 --- a/cmd/podman/common/create.go +++ b/cmd/podman/common/create.go @@ -655,15 +655,6 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) { ) _ = cmd.RegisterFlagCompletionFunc(stopTimeoutFlagName, completion.AutocompleteNone) - storageOptFlagName := "storage-opt" - createFlags.StringSliceVar( - &cf.StorageOpt, - storageOptFlagName, []string{}, - "Storage driver options per container", - ) - //FIXME: What should we suggest here? The flag is not in the man page. - _ = cmd.RegisterFlagCompletionFunc(storageOptFlagName, completion.AutocompleteNone) - subgidnameFlagName := "subgidname" createFlags.StringVar( &cf.SubUIDName, diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go index 149869237..42f515ace 100644 --- a/cmd/podman/common/specgen.go +++ b/cmd/podman/common/specgen.go @@ -565,6 +565,14 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string s.Devices = append(s.Devices, specs.LinuxDevice{Path: dev}) } + for _, rule := range c.DeviceCGroupRule { + dev, err := parseLinuxResourcesDeviceAccess(rule) + if err != nil { + return err + } + s.DeviceCGroupRule = append(s.DeviceCGroupRule, dev) + } + s.Init = c.Init s.InitPath = c.InitPath s.Stdin = c.Interactive @@ -899,3 +907,58 @@ func parseSecrets(secrets []string) ([]specgen.Secret, map[string]string, error) } return mount, envs, nil } + +var cgroupDeviceType = map[string]bool{ + "a": true, // all + "b": true, // block device + "c": true, // character device +} + +var cgroupDeviceAccess = map[string]bool{ + "r": true, //read + "w": true, //write + "m": true, //mknod +} + +// parseLinuxResourcesDeviceAccess parses the raw string passed with the --device-access-add flag +func parseLinuxResourcesDeviceAccess(device string) (specs.LinuxDeviceCgroup, error) { + var devType, access string + var major, minor *int64 + + value := strings.Split(device, " ") + if len(value) != 3 { + return specs.LinuxDeviceCgroup{}, fmt.Errorf("invalid device cgroup rule requires type, major:Minor, and access rules: %q", device) + } + + devType = value[0] + if !cgroupDeviceType[devType] { + return specs.LinuxDeviceCgroup{}, fmt.Errorf("invalid device type in device-access-add: %s", devType) + } + + number := strings.SplitN(value[1], ":", 2) + i, err := strconv.ParseInt(number[0], 10, 64) + if err != nil { + return specs.LinuxDeviceCgroup{}, err + } + major = &i + if len(number) == 2 && number[1] != "*" { + i, err := strconv.ParseInt(number[1], 10, 64) + if err != nil { + return specs.LinuxDeviceCgroup{}, err + } + minor = &i + } + access = value[2] + for _, c := range strings.Split(access, "") { + if !cgroupDeviceAccess[c] { + return specs.LinuxDeviceCgroup{}, fmt.Errorf("invalid device access in device-access-add: %s", c) + } + } + return specs.LinuxDeviceCgroup{ + Allow: true, + Type: devType, + Major: major, + Minor: minor, + Access: access, + }, nil +} diff --git a/cmd/podman/containers/cp.go b/cmd/podman/containers/cp.go index c1f1e27f5..7b5846a35 100644 --- a/cmd/podman/containers/cp.go +++ b/cmd/podman/containers/cp.go @@ -82,7 +82,9 @@ func cp(cmd *cobra.Command, args []string) error { return err } - if len(sourceContainerStr) > 0 { + if len(sourceContainerStr) > 0 && len(destContainerStr) > 0 { + return copyContainerToContainer(sourceContainerStr, sourcePath, destContainerStr, destPath) + } else if len(sourceContainerStr) > 0 { return copyFromContainer(sourceContainerStr, sourcePath, destPath) } @@ -115,6 +117,84 @@ func doCopy(funcA func() error, funcB func() error) error { return errorhandling.JoinErrors(copyErrors) } +func copyContainerToContainer(sourceContainer string, sourcePath string, destContainer string, destPath string) error { + if err := containerMustExist(sourceContainer); err != nil { + return err + } + + if err := containerMustExist(destContainer); err != nil { + return err + } + + sourceContainerInfo, err := registry.ContainerEngine().ContainerStat(registry.GetContext(), sourceContainer, sourcePath) + if err != nil { + return errors.Wrapf(err, "%q could not be found on container %s", sourcePath, sourceContainer) + } + + destContainerBaseName, destContainerInfo, destResolvedToParentDir, err := resolvePathOnDestinationContainer(destContainer, destPath, false) + if err != nil { + return err + } + + if sourceContainerInfo.IsDir && !destContainerInfo.IsDir { + return errors.New("destination must be a directory when copying a directory") + } + + sourceContainerTarget := sourceContainerInfo.LinkTarget + destContainerTarget := destContainerInfo.LinkTarget + if !destContainerInfo.IsDir { + destContainerTarget = filepath.Dir(destPath) + } + + // If we copy a directory via the "." notation and the container path + // does not exist, we need to make sure that the destination on the + // container gets created; otherwise the contents of the source + // directory will be written to the destination's parent directory. + // + // Hence, whenever "." is the source and the destination does not + // exist, we copy the source's parent and let the copier package create + // the destination via the Rename option. + if destResolvedToParentDir && sourceContainerInfo.IsDir && strings.HasSuffix(sourcePath, ".") { + sourceContainerTarget = filepath.Dir(sourceContainerTarget) + } + + reader, writer := io.Pipe() + + sourceContainerCopy := func() error { + defer writer.Close() + copyFunc, err := registry.ContainerEngine().ContainerCopyToArchive(registry.GetContext(), sourceContainer, sourceContainerTarget, writer) + if err != nil { + return err + } + if err := copyFunc(); err != nil { + return errors.Wrap(err, "error copying from container") + } + return nil + } + + destContainerCopy := func() error { + defer reader.Close() + + copyOptions := entities.CopyOptions{Chown: chown} + if (!sourceContainerInfo.IsDir && !destContainerInfo.IsDir) || destResolvedToParentDir { + // If we're having a file-to-file copy, make sure to + // rename accordingly. + copyOptions.Rename = map[string]string{filepath.Base(sourceContainerTarget): destContainerBaseName} + } + + copyFunc, err := registry.ContainerEngine().ContainerCopyFromArchive(registry.GetContext(), destContainer, destContainerTarget, reader, copyOptions) + if err != nil { + return err + } + if err := copyFunc(); err != nil { + return errors.Wrap(err, "error copying to container") + } + return nil + } + + return doCopy(sourceContainerCopy, destContainerCopy) +} + // copyFromContainer copies from the containerPath on the container to hostPath. func copyFromContainer(container string, containerPath string, hostPath string) error { if err := containerMustExist(container); err != nil { @@ -133,6 +213,7 @@ func copyFromContainer(container string, containerPath string, hostPath string) } var hostBaseName string + var resolvedToHostParentDir bool hostInfo, hostInfoErr := copy.ResolveHostPath(hostPath) if hostInfoErr != nil { if strings.HasSuffix(hostPath, "/") { @@ -148,6 +229,7 @@ func copyFromContainer(container string, containerPath string, hostPath string) // it'll be created while copying. Hence, we use it as the // base path. hostBaseName = filepath.Base(hostPath) + resolvedToHostParentDir = true } else { // If the specified path exists on the host, we must use its // base path as it may have changed due to symlink evaluations. @@ -175,7 +257,7 @@ func copyFromContainer(container string, containerPath string, hostPath string) // we copy the source's parent and let the copier package create the // destination via the Rename option. containerTarget := containerInfo.LinkTarget - if hostInfoErr != nil && containerInfo.IsDir && strings.HasSuffix(containerTarget, ".") { + if resolvedToHostParentDir && containerInfo.IsDir && strings.HasSuffix(containerTarget, ".") { containerTarget = filepath.Dir(containerTarget) } @@ -216,7 +298,7 @@ func copyFromContainer(container string, containerPath string, hostPath string) ChownFiles: &idPair, IgnoreDevices: true, } - if (!containerInfo.IsDir && !hostInfo.IsDir) || hostInfoErr != nil { + if (!containerInfo.IsDir && !hostInfo.IsDir) || resolvedToHostParentDir { // If we're having a file-to-file copy, make sure to // rename accordingly. putOptions.Rename = map[string]string{filepath.Base(containerTarget): hostBaseName} @@ -263,42 +345,9 @@ func copyToContainer(container string, containerPath string, hostPath string) er return errors.Wrapf(err, "%q could not be found on the host", hostPath) } - // If the path on the container does not exist. We need to make sure - // that it's parent directory exists. The destination may be created - // while copying. - var containerBaseName string - containerInfo, containerInfoErr := registry.ContainerEngine().ContainerStat(registry.GetContext(), container, containerPath) - if containerInfoErr != nil { - if strings.HasSuffix(containerPath, "/") { - return errors.Wrapf(containerInfoErr, "%q could not be found on container %s", containerPath, container) - } - if isStdin { - return errors.New("destination must be a directory when copying from stdin") - } - // NOTE: containerInfo may actually be set. That happens when - // the container path is a symlink into nirvana. In that case, - // we must use the symlinked path instead. - path := containerPath - if containerInfo != nil { - containerBaseName = filepath.Base(containerInfo.LinkTarget) - path = containerInfo.LinkTarget - } else { - containerBaseName = filepath.Base(containerPath) - } - - parentDir, err := containerParentDir(container, path) - if err != nil { - return errors.Wrapf(err, "could not determine parent dir of %q on container %s", path, container) - } - containerInfo, err = registry.ContainerEngine().ContainerStat(registry.GetContext(), container, parentDir) - if err != nil { - return errors.Wrapf(err, "%q could not be found on container %s", containerPath, container) - } - } else { - // If the specified path exists on the container, we must use - // its base path as it may have changed due to symlink - // evaluations. - containerBaseName = filepath.Base(containerInfo.LinkTarget) + containerBaseName, containerInfo, containerResolvedToParentDir, err := resolvePathOnDestinationContainer(container, containerPath, isStdin) + if err != nil { + return err } // If we copy a directory via the "." notation and the container path @@ -310,7 +359,7 @@ func copyToContainer(container string, containerPath string, hostPath string) er // exist, we copy the source's parent and let the copier package create // the destination via the Rename option. hostTarget := hostInfo.LinkTarget - if containerInfoErr != nil && hostInfo.IsDir && strings.HasSuffix(hostTarget, ".") { + if containerResolvedToParentDir && hostInfo.IsDir && strings.HasSuffix(hostTarget, ".") { hostTarget = filepath.Dir(hostTarget) } @@ -362,7 +411,7 @@ func copyToContainer(container string, containerPath string, hostPath string) er // copy the base directory. KeepDirectoryNames: hostInfo.IsDir && filepath.Base(hostTarget) != ".", } - if (!hostInfo.IsDir && !containerInfo.IsDir) || containerInfoErr != nil { + if (!hostInfo.IsDir && !containerInfo.IsDir) || containerResolvedToParentDir { // If we're having a file-to-file copy, make sure to // rename accordingly. getOptions.Rename = map[string]string{filepath.Base(hostTarget): containerBaseName} @@ -393,6 +442,52 @@ func copyToContainer(container string, containerPath string, hostPath string) er return doCopy(hostCopy, containerCopy) } +// resolvePathOnDestinationContainer resolves the specified path on the +// container. If the path does not exist, it attempts to use the parent +// directory. +func resolvePathOnDestinationContainer(container string, containerPath string, isStdin bool) (baseName string, containerInfo *entities.ContainerStatReport, resolvedToParentDir bool, err error) { + containerInfo, err = registry.ContainerEngine().ContainerStat(registry.GetContext(), container, containerPath) + if err == nil { + baseName = filepath.Base(containerInfo.LinkTarget) + return + } + + if strings.HasSuffix(containerPath, "/") { + err = errors.Wrapf(err, "%q could not be found on container %s", containerPath, container) + return + } + if isStdin { + err = errors.New("destination must be a directory when copying from stdin") + return + } + + // NOTE: containerInfo may actually be set. That happens when + // the container path is a symlink into nirvana. In that case, + // we must use the symlinked path instead. + path := containerPath + if containerInfo != nil { + baseName = filepath.Base(containerInfo.LinkTarget) + path = containerInfo.LinkTarget + } else { + baseName = filepath.Base(containerPath) + } + + parentDir, err := containerParentDir(container, path) + if err != nil { + err = errors.Wrapf(err, "could not determine parent dir of %q on container %s", path, container) + return + } + + containerInfo, err = registry.ContainerEngine().ContainerStat(registry.GetContext(), container, parentDir) + if err != nil { + err = errors.Wrapf(err, "%q could not be found on container %s", containerPath, container) + return + } + + resolvedToParentDir = true + return baseName, containerInfo, resolvedToParentDir, nil +} + // containerParentDir returns the parent directory of the specified path on the // container. If the path is relative, it will be resolved relative to the // container's working directory (or "/" if the work dir isn't set). diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go index 1e11c53d5..c63c074f7 100644 --- a/cmd/podman/containers/create.go +++ b/cmd/podman/containers/create.go @@ -146,6 +146,8 @@ func replaceContainer(name string) error { } func createInit(c *cobra.Command) error { + cliVals.StorageOpt = registry.PodmanConfig().StorageOpts + if c.Flag("shm-size").Changed { cliVals.ShmSize = c.Flag("shm-size").Value.String() } @@ -293,6 +295,7 @@ func createPodIfNecessary(s *specgen.SpecGenerator, netOpts *entities.NetOptions Hostname: s.ContainerBasicConfig.Hostname, Cpus: cliVals.CPUS, CpusetCpus: cliVals.CPUSetCPUs, + Pid: cliVals.PID, } // Unset config values we passed to the pod to prevent them being used twice for the container and pod. s.ContainerBasicConfig.Hostname = "" diff --git a/cmd/podman/containers/logs.go b/cmd/podman/containers/logs.go index 0d745291e..00a8d4b52 100644 --- a/cmd/podman/containers/logs.go +++ b/cmd/podman/containers/logs.go @@ -19,6 +19,8 @@ type logsOptionsWrapper struct { entities.ContainerLogsOptions SinceRaw string + + UntilRaw string } var ( @@ -101,6 +103,10 @@ func logsFlags(cmd *cobra.Command) { flags.StringVar(&logsOptions.SinceRaw, sinceFlagName, "", "Show logs since TIMESTAMP") _ = cmd.RegisterFlagCompletionFunc(sinceFlagName, completion.AutocompleteNone) + untilFlagName := "until" + flags.StringVar(&logsOptions.UntilRaw, untilFlagName, "", "Show logs until TIMESTAMP") + _ = cmd.RegisterFlagCompletionFunc(untilFlagName, completion.AutocompleteNone) + tailFlagName := "tail" flags.Int64Var(&logsOptions.Tail, tailFlagName, -1, "Output the specified number of LINES at the end of the logs. Defaults to -1, which prints all lines") _ = cmd.RegisterFlagCompletionFunc(tailFlagName, completion.AutocompleteNone) @@ -120,6 +126,14 @@ func logs(_ *cobra.Command, args []string) error { } logsOptions.Since = since } + if logsOptions.UntilRaw != "" { + // parse time, error out if something is wrong + until, err := util.ParseInputTime(logsOptions.UntilRaw) + if err != nil { + return errors.Wrapf(err, "error parsing --until %q", logsOptions.UntilRaw) + } + logsOptions.Until = until + } logsOptions.StdoutWriter = os.Stdout logsOptions.StderrWriter = os.Stderr return registry.ContainerEngine().ContainerLogs(registry.GetContext(), args, logsOptions.ContainerLogsOptions) diff --git a/cmd/podman/containers/restore.go b/cmd/podman/containers/restore.go index b908ea493..3b6f74efa 100644 --- a/cmd/podman/containers/restore.go +++ b/cmd/podman/containers/restore.go @@ -71,6 +71,9 @@ func init() { ) _ = restoreCommand.RegisterFlagCompletionFunc("publish", completion.AutocompleteNone) + flags.StringVar(&restoreOptions.Pod, "pod", "", "Restore container into existing Pod (only works with --import)") + _ = restoreCommand.RegisterFlagCompletionFunc("pod", common.AutocompletePodsRunning) + validate.AddLatestFlag(restoreCommand, &restoreOptions.Latest) } @@ -91,6 +94,9 @@ func restore(cmd *cobra.Command, args []string) error { if restoreOptions.Import == "" && restoreOptions.Name != "" { return errors.Errorf("--name can only be used with --import") } + if restoreOptions.Import == "" && restoreOptions.Pod != "" { + return errors.Errorf("--pod can only be used with --import") + } if restoreOptions.Name != "" && restoreOptions.TCPEstablished { return errors.Errorf("--tcp-established cannot be used with --name") } diff --git a/cmd/podman/images/import.go b/cmd/podman/images/import.go index bed2d4105..bc80417cc 100644 --- a/cmd/podman/images/import.go +++ b/cmd/podman/images/import.go @@ -3,6 +3,9 @@ package images import ( "context" "fmt" + "io" + "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -97,6 +100,22 @@ func importCon(cmd *cobra.Command, args []string) error { default: return errors.Errorf("too many arguments. Usage TARBALL [REFERENCE]") } + + if source == "-" { + outFile, err := ioutil.TempFile("", "podman") + if err != nil { + return errors.Errorf("error creating file %v", err) + } + defer os.Remove(outFile.Name()) + defer outFile.Close() + + _, err = io.Copy(outFile, os.Stdin) + if err != nil { + return errors.Errorf("error copying file %v", err) + } + source = outFile.Name() + } + errFileName := parse.ValidateFileName(source) errURL := parse.ValidURL(source) if errURL == nil { diff --git a/cmd/podman/manifest/create.go b/cmd/podman/manifest/create.go index 9f7d74d14..95c9f89b0 100644 --- a/cmd/podman/manifest/create.go +++ b/cmd/podman/manifest/create.go @@ -13,15 +13,16 @@ import ( var ( manifestCreateOpts = entities.ManifestCreateOptions{} createCmd = &cobra.Command{ - Use: "create [options] LIST [IMAGE]", + Use: "create [options] LIST [IMAGE...]", Short: "Create manifest list or image index", Long: "Creates manifest lists or image indexes.", RunE: create, ValidArgsFunction: common.AutocompleteImages, Example: `podman manifest create mylist:v1.11 podman manifest create mylist:v1.11 arch-specific-image-to-add + podman manifest create mylist:v1.11 arch-specific-image-to-add another-arch-specific-image-to-add podman manifest create --all mylist:v1.11 transport:tagged-image-to-add`, - Args: cobra.RangeArgs(1, 2), + Args: cobra.MinimumNArgs(1), } ) diff --git a/cmd/podman/parse/net.go b/cmd/podman/parse/net.go index f93c4ab1e..870690db3 100644 --- a/cmd/podman/parse/net.go +++ b/cmd/podman/parse/net.go @@ -180,9 +180,12 @@ func ValidateFileName(filename string) error { // ValidURL checks a string urlStr is a url or not func ValidURL(urlStr string) error { - _, err := url.ParseRequestURI(urlStr) + url, err := url.ParseRequestURI(urlStr) if err != nil { - return errors.Wrapf(err, "invalid url path: %q", urlStr) + return errors.Wrapf(err, "invalid url %q", urlStr) + } + if url.Scheme == "" { + return errors.Errorf("invalid url %q: missing scheme", urlStr) } return nil } diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go index 03e3ffaa0..abc47164b 100644 --- a/cmd/podman/pods/create.go +++ b/cmd/podman/pods/create.go @@ -86,6 +86,10 @@ func init() { flags.String(infraCommandFlagName, containerConfig.Engine.InfraCommand, "The command to run on the infra container when the pod is started") _ = createCommand.RegisterFlagCompletionFunc(infraCommandFlagName, completion.AutocompleteNone) + infraNameFlagName := "infra-name" + flags.StringVarP(&createOptions.InfraName, infraNameFlagName, "", "", "The name used as infra container name") + _ = createCommand.RegisterFlagCompletionFunc(infraNameFlagName, completion.AutocompleteNone) + labelFileFlagName := "label-file" flags.StringSliceVar(&labelFile, labelFileFlagName, []string{}, "Read in a line delimited file of labels") _ = createCommand.RegisterFlagCompletionFunc(labelFileFlagName, completion.AutocompleteDefault) @@ -102,6 +106,10 @@ func init() { flags.StringVarP(&createOptions.Hostname, hostnameFlagName, "", "", "Set a hostname to the pod") _ = createCommand.RegisterFlagCompletionFunc(hostnameFlagName, completion.AutocompleteNone) + pidFlagName := "pid" + flags.StringVar(&createOptions.Pid, pidFlagName, "", "PID namespace to use") + _ = createCommand.RegisterFlagCompletionFunc(pidFlagName, common.AutocompleteNamespace) + podIDFileFlagName := "pod-id-file" flags.StringVar(&podIDFile, podIDFileFlagName, "", "Write the pod ID to the file") _ = createCommand.RegisterFlagCompletionFunc(podIDFileFlagName, completion.AutocompleteDefault) @@ -144,6 +152,9 @@ func create(cmd *cobra.Command, args []string) error { return errors.New("cannot set infra-image without an infra container") } createOptions.InfraImage = "" + if createOptions.InfraName != "" { + return errors.New("cannot set infra-name without an infra container") + } if cmd.Flag("share").Changed && share != "none" && share != "" { return fmt.Errorf("cannot set share(%s) namespaces without an infra container", cmd.Flag("share").Value) @@ -179,6 +190,8 @@ func create(cmd *cobra.Command, args []string) error { defer errorhandling.SyncQuiet(podIDFD) } + createOptions.Pid = cmd.Flag("pid").Value.String() + createOptions.Net, err = common.NetFlagsToNetOptions(cmd, createOptions.Infra) if err != nil { return err diff --git a/cmd/podman/pods/ps.go b/cmd/podman/pods/ps.go index 3e5ab86f4..14e3e2ea9 100644 --- a/cmd/podman/pods/ps.go +++ b/cmd/podman/pods/ps.go @@ -124,6 +124,11 @@ func pods(cmd *cobra.Command, _ []string) error { "NumberOfContainers": "# OF CONTAINERS", "Created": "CREATED", "InfraID": "INFRA ID", + "ContainerIds": "IDS", + "ContainerNames": "NAMES", + "ContainerStatuses": "STATUS", + "Cgroup": "CGROUP", + "Namespace": "NAMESPACES", }) renderHeaders := true row := podPsFormat() diff --git a/cmd/podman/registry/config.go b/cmd/podman/registry/config.go index 25139a3de..b512ba341 100644 --- a/cmd/podman/registry/config.go +++ b/cmd/podman/registry/config.go @@ -15,6 +15,9 @@ import ( ) const ( + // NoMoveProcess used as cobra.Annotation when command doesn't need Podman to be moved to a separate cgroup + NoMoveProcess = "NoMoveProcess" + // ParentNSRequired used as cobra.Annotation when command requires root access ParentNSRequired = "ParentNSRequired" diff --git a/cmd/podman/root.go b/cmd/podman/root.go index 9e5d2a236..dc4ebb952 100644 --- a/cmd/podman/root.go +++ b/cmd/podman/root.go @@ -208,7 +208,8 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { // 3) command doesn't require Parent Namespace _, found := cmd.Annotations[registry.ParentNSRequired] if !registry.IsRemote() && rootless.IsRootless() && !found { - err := registry.ContainerEngine().SetupRootless(registry.Context(), cmd) + _, noMoveProcess := cmd.Annotations[registry.NoMoveProcess] + err := registry.ContainerEngine().SetupRootless(registry.Context(), noMoveProcess) if err != nil { return err } @@ -342,10 +343,6 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) { pFlags.StringVar(&opts.StorageDriver, storageDriverFlagName, "", "Select which storage driver is used to manage storage of images and containers (default is overlay)") _ = cmd.RegisterFlagCompletionFunc(storageDriverFlagName, completion.AutocompleteNone) //TODO: what can we recommend here? - storageOptFlagName := "storage-opt" - pFlags.StringArrayVar(&opts.StorageOpts, storageOptFlagName, []string{}, "Used to pass an option to the storage driver") - _ = cmd.RegisterFlagCompletionFunc(storageOptFlagName, completion.AutocompleteNone) - tmpdirFlagName := "tmpdir" pFlags.StringVar(&opts.Engine.TmpDir, tmpdirFlagName, "", "Path to the tmp directory for libpod state content.\n\nNote: use the environment variable 'TMPDIR' to change the temporary storage location for container images, '/var/tmp'.\n") _ = cmd.RegisterFlagCompletionFunc(tmpdirFlagName, completion.AutocompleteDefault) @@ -365,6 +362,10 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) { } } } + storageOptFlagName := "storage-opt" + pFlags.StringArrayVar(&opts.StorageOpts, storageOptFlagName, []string{}, "Used to pass an option to the storage driver") + _ = cmd.RegisterFlagCompletionFunc(storageOptFlagName, completion.AutocompleteNone) + // Override default --help information of `--help` global flag var dummyHelp bool pFlags.BoolVar(&dummyHelp, "help", false, "Help for podman") diff --git a/cmd/podman/system/migrate.go b/cmd/podman/system/migrate.go index 9940cd063..b9dc272d7 100644 --- a/cmd/podman/system/migrate.go +++ b/cmd/podman/system/migrate.go @@ -22,7 +22,10 @@ var ( ` migrateCommand = &cobra.Command{ - Annotations: map[string]string{registry.EngineMode: registry.ABIMode}, + Annotations: map[string]string{ + registry.EngineMode: registry.ABIMode, + registry.NoMoveProcess: registry.NoMoveProcess, + }, Use: "migrate [options]", Args: validate.NoArgs, Short: "Migrate containers", diff --git a/contrib/podmanimage/stable/Dockerfile b/contrib/podmanimage/stable/Dockerfile index 2f86dd4ae..f980d15ed 100644 --- a/contrib/podmanimage/stable/Dockerfile +++ b/contrib/podmanimage/stable/Dockerfile @@ -11,7 +11,7 @@ FROM registry.fedoraproject.org/fedora:latest # Don't include container-selinux and remove # directories used by yum that are just taking # up space. -RUN dnf -y update; yum -y reinstall shadow-utils; \ +RUN dnf -y update; rpm --restore shadow-utils 2>/dev/null; \ yum -y install podman fuse-overlayfs --exclude container-selinux; \ rm -rf /var/cache /var/log/dnf* /var/log/yum.* diff --git a/contrib/podmanimage/testing/Dockerfile b/contrib/podmanimage/testing/Dockerfile index 63b31252f..58b11a20b 100644 --- a/contrib/podmanimage/testing/Dockerfile +++ b/contrib/podmanimage/testing/Dockerfile @@ -13,7 +13,7 @@ FROM registry.fedoraproject.org/fedora:latest # Don't include container-selinux and remove # directories used by yum that are just taking # up space. -RUN yum -y update; yum -y reinstall shadow-utils; yum -y install podman fuse-overlayfs --exclude container-selinux --enablerepo updates-testing; rm -rf /var/cache /var/log/dnf* /var/log/yum.* +RUN yum -y update; rpm --restore shadow-utils 2>/dev/null; yum -y install podman fuse-overlayfs --exclude container-selinux --enablerepo updates-testing; rm -rf /var/cache /var/log/dnf* /var/log/yum.* RUN useradd podman; \ echo podman:10000:5000 > /etc/subuid; \ diff --git a/contrib/podmanimage/upstream/Dockerfile b/contrib/podmanimage/upstream/Dockerfile index 922eee748..baad49e08 100644 --- a/contrib/podmanimage/upstream/Dockerfile +++ b/contrib/podmanimage/upstream/Dockerfile @@ -17,7 +17,7 @@ ENV GOPATH=/root/podman # to the container. # Finally remove the podman directory and a few other packages # that are needed for building but not running Podman -RUN yum -y update; yum -y reinstall shadow-utils; yum -y install --exclude container-selinux \ +RUN yum -y update; rpm --restore shadow-utils 2>/dev/null; yum -y install --exclude container-selinux \ --enablerepo=updates-testing \ btrfs-progs-devel \ containernetworking-cni \ diff --git a/contrib/systemd/auto-update/podman-auto-update.service b/contrib/systemd/auto-update/podman-auto-update.service index 9376db225..dc5fac8cf 100644 --- a/contrib/systemd/auto-update/podman-auto-update.service +++ b/contrib/systemd/auto-update/podman-auto-update.service @@ -1,7 +1,7 @@ [Unit] Description=Podman auto-update service Documentation=man:podman-auto-update(1) -Wants=network.target +Wants=network-online.target After=network-online.target [Service] diff --git a/contrib/systemd/auto-update/podman-auto-update.timer b/contrib/systemd/auto-update/podman-auto-update.timer index 3e50ffa9b..50be391d3 100644 --- a/contrib/systemd/auto-update/podman-auto-update.timer +++ b/contrib/systemd/auto-update/podman-auto-update.timer @@ -3,6 +3,7 @@ Description=Podman auto-update timer [Timer] OnCalendar=daily +RandomizedDelaySec=900 Persistent=true [Install] diff --git a/docs/source/includes.rst b/docs/source/includes.rst index 6e04d77f4..8d5f18e4d 100644 --- a/docs/source/includes.rst +++ b/docs/source/includes.rst @@ -16,4 +16,4 @@ .. _podman run: http://docs.podman.io/en/latest/markdown/podman-run.1.html .. _podman build: http://docs.podman.io/en/latest/markdown/podman-build.1.html .. _podman push: http://docs.podman.io/en/latest/markdown/podman-push.1.html -.. image:: https://github.com/containers/podman/blob/main/logo/podman-logo.png?raw=true +.. image:: https://raw.githubusercontent.com/containers/podman/main/logo/podman-logo.png diff --git a/docs/source/markdown/podman-auto-update.1.md b/docs/source/markdown/podman-auto-update.1.md index 24b910470..106b9b00a 100644 --- a/docs/source/markdown/podman-auto-update.1.md +++ b/docs/source/markdown/podman-auto-update.1.md @@ -41,6 +41,27 @@ If the authorization state is not found there, `$HOME/.docker/config.json` is ch Note: There is also the option to override the default path of the authentication file by setting the `REGISTRY_AUTH_FILE` environment variable. This can be done with **export REGISTRY_AUTH_FILE=_path_**. +#### **--dry-run**=*true|false* + +Check for the availability of new images but do not perform any pull operation or restart any service or container. +The `UPDATED` field indicates the availability of a new image with "pending". + +#### **--format**=*format* + +Change the default output format. This can be of a supported type like 'json' or a Go template. +Valid placeholders for the Go template are listed below: + +| **Placeholder** | **Description** | +| --------------- | -------------------------------------- | +| .Unit | Name of the systemd unit | +| .ContainerName | Name of the container | +| .ContainerID | ID of the container | +| .Container | ID and name of the container | +| .Image | Name of the image | +| .Policy | Auto-update policy of the container | +| .Updated | Update status: true,false,failed | + + ## EXAMPLES Autoupdate with registry policy @@ -48,26 +69,31 @@ Autoupdate with registry policy ### Start a container $ podman run --label "io.containers.autoupdate=registry" \ --label "io.containers.autoupdate.authfile=/some/authfile.json" \ - -d busybox:latest top + -d --name=test registry.fedoraproject.org/fedora:latest sleep infinity bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d ### Generate a systemd unit for this container $ podman generate systemd --new --files bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d -/home/user/containers/libpod/container-bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d.service +/home/user/container-bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d.service ### Load the new systemd unit and start it -$ mv ./container-bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d.service ~/.config/systemd/user +$ mv ./container-bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d.service ~/.config/systemd/user/container-test.service $ systemctl --user daemon-reload ### If the previously created containers or pods are using shared resources, such as ports, make sure to remove them before starting the generated systemd units. $ podman stop bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d $ podman rm bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d -$ systemctl --user start container-bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d.service +$ systemctl --user start container-test.service -### Auto-update the container +### Check if a newer image is available +$ podman auto-update --dry-run --format "{{.Image}} {{.Updated}}" +registry.fedoraproject.org/fedora:latest pending + +### Autoupdate the services $ podman auto-update -container-bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9d.service +UNIT CONTAINER IMAGE POLICY UPDATED +container-test.service 08fd34e533fd (test) registry.fedoraproject.org/fedora:latest registry false ``` Autoupdate with local policy @@ -80,7 +106,7 @@ be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338 ### Generate a systemd unit for this container $ podman generate systemd --new --files be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338 -/home/user/containers/libpod/container-be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338.service +/home/user/container-be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338.service ### Load the new systemd unit and start it $ mv ./container-be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338.service ~/.config/systemd/user @@ -102,7 +128,7 @@ $ podman commit --change CMD=/bin/bash inspiring_galileo busybox:latest ### Auto-update the container $ podman auto-update -container-be0889fd06f252a2e5141b37072c6bada68563026cb2b2649f53394d87ccc338.service +[...] ``` ## SEE ALSO diff --git a/docs/source/markdown/podman-container-restore.1.md b/docs/source/markdown/podman-container-restore.1.md index 36eb650e5..856008cc0 100644 --- a/docs/source/markdown/podman-container-restore.1.md +++ b/docs/source/markdown/podman-container-restore.1.md @@ -93,6 +93,15 @@ be used once and the restored *container* will have another IP address. This als that **--name, -n** cannot be used in combination with **--tcp-established**.\ *IMPORTANT: This OPTION is only available in combination with **--import, -i**.* +#### **--pod**=*name* + +Restore a container into the pod *name*. The destination pod for this restore +has to have the same namespaces shared as the pod this container was checkpointed +from (see **[podman pod create --share](podman-pod-create.1.md#--share)**). +*IMPORTANT: This OPTION is only available in combination with **--import, -i**.* + +This option requires at least CRIU 3.16. + #### **--publish**, **-p**=*port* Replaces the ports that the *container* publishes, as configured during the @@ -128,7 +137,7 @@ $ podman run --rm -p 2345:80 -d webserver ``` ## SEE ALSO -**[podman(1)](podman.1.md)**, **[podman-container-checkpoint(1)](podman-container-checkpoint.1.md)**, **[podman-run(1)](podman-run.1.md)** +**[podman(1)](podman.1.md)**, **[podman-container-checkpoint(1)](podman-container-checkpoint.1.md)**, **[podman-run(1)](podman-run.1.md)**, **[podman-pod-create(1)](podman-pod-create.1.md)** ## HISTORY September 2018, Originally compiled by Adrian Reber <areber@redhat.com> diff --git a/docs/source/markdown/podman-container-runlabel.1.md b/docs/source/markdown/podman-container-runlabel.1.md index e343a12fe..ec67a2687 100644 --- a/docs/source/markdown/podman-container-runlabel.1.md +++ b/docs/source/markdown/podman-container-runlabel.1.md @@ -1,76 +1,58 @@ % podman-container-runlabel(1) ## NAME -podman-container-runlabel - Executes a command as described by a container image label +podman-container-runlabel - Executes a command as described by a container-image label ## SYNOPSIS **podman container runlabel** [*options*] *label* *image* [*arg...*] ## DESCRIPTION -**podman container runlabel** reads the provided `LABEL` field in the container -IMAGE and executes the provided value for the label as a command. If this field does not -exist, `podman container runlabel` will just exit. +**podman container runlabel** reads the specified `label` of the `image` and executes it as command on the host. If the label does not exist, Podman will exit with an error. Additional arguments will be appended to the command. -If the container image has a LABEL INSTALL instruction like the following: +Historically, container images describe the contents (e.g., layers) and how a container runtime (e.g., crun(1) or runc(1)) should execute the container. For instance, an image may set the environment and the command in its configuration. However, a container image cannot directly specify how a container engine such as Podman should execute it. For instance, an image configuration does not include information about log drivers, namespaces or which capabilities it needs to run correctly. -`LABEL INSTALL /usr/bin/podman run -t -i --rm \${OPT1} --privileged -v /:/host --net=host --ipc=host --pid=host -e HOST=/host -e NAME=\${NAME} -e IMAGE=\${IMAGE} -e CONFDIR=/etc/\${NAME} -e LOGDIR=/var/log/\${NAME} -e DATADIR=/var/lib/\${NAME} \${IMAGE} \${OPT2} /bin/install.sh \${OPT3}` +`podman container runlabel` addresses the limitation of container images in a simple yet efficient way. Podman will read the contents of the label and interpret it as a command that will be executed on the host. This way an image can describe exactly how it should be executed by Podman. For instance, a label with the content `/usr/bin/podman run -d --pid=host --privileged \${IMAGE}` instructs the image to be executed in a detached, privileged container that is using the PID namespace of the host. This lifts the self-description of a container image from "what" to "how". -`podman container runlabel` will set the following environment variables for use in the command: +Please note that the `runlabel` command is intended to be run in trusted environments exclusively. Using the command on untrusted images is not recommended. -If the container image does not have the desired label, an error message will be displayed along with a non-zero -return code. If the image is not found in local storage, Podman will attempt to pull it first. +## VARIABLES -**LABEL** -The label name specified via the command. +The contents of a label may refer to the following variables which will be substituted while processing the label. **IMAGE** -Image name specified via the command. +The name of the image. When executing `podman container runlabel label fedora` the `IMAGE` variable will be replaced with `fedora`. Valid formats are `IMAGE`, `$IMAGE`, `${IMAGE}` and `=IMAGE`. -**SUDO_UID** -The `SUDO_UID` environment variable. This is useful with the podman -`-u` option for user space tools. If the environment variable is -not available, the value of `/proc/self/loginuid` is used. +**NAME** +As specified by the `--name` option. The format is identical to the one of the IMAGE attribute. -**SUDO_GID** -The `SUDO_GID` environment variable. This is useful with the podman -`-u` option for user space tools. If the environment variable is -not available, the default GID of the value for `SUDO_UID` is used. -If this value is not available, the value of `/proc/self/loginuid` -is used. - -Any additional arguments will be appended to the command. +**PWD** +Will be replaced with the current working directory. ## OPTIONS #### **--authfile**=*path* -Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`. -If the authorization state is not found there, $HOME/.docker/config.json is checked, which is set using `docker login`. +Path of the containers-auth.json(5) file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`. If the authorization state is not found there, $HOME/.docker/config.json is checked, which is set using `docker login`. -Note: You can also override the default path of the authentication file by setting the REGISTRY\_AUTH\_FILE -environment variable. `export REGISTRY_AUTH_FILE=path` +Note: You can also override the default path of the authentication file by setting the REGISTRY\_AUTH\_FILE environment variable. `export REGISTRY_AUTH_FILE=path` #### **--display** -Display the label's value of the image having populated its environment variables. -The runlabel command will not execute if --display is specified. +Display the label's value of the image having populated its environment variables. The runlabel command will not execute if --display is specified. #### **--cert-dir**=*path* -Use certificates at *path* (\*.crt, \*.cert, \*.key) to connect to the registry. -Please refer to containers-certs.d(5) for details. (This option is not available with the remote Podman client) +Use certificates at *path* (\*.crt, \*.cert, \*.key) to connect to the registry. Please refer to containers-certs.d(5) for details. (This option is not available with the remote Podman client) #### **--creds**=*[username[:password]]* -The [username[:password]] to use to authenticate with the registry if required. -If one or both values are not supplied, a command line prompt will appear and the -value can be entered. The password is entered without echo. +The [username[:password]] to use to authenticate with the registry if required. If one or both values are not supplied, a command line prompt will appear and the value can be entered. The password is entered without echo. #### **--help**, **-h** Print usage statement #### **--name**, **-n**=*name* -Use this name for creating content for the container. NAME will default to the IMAGENAME if it is not specified. +Use this name for creating content for the container. If not specified, name defaults to the name of the image. #### **--quiet**, **-q** @@ -78,34 +60,33 @@ Suppress output information when pulling images #### **--replace** -If a container exists of the default or given name, as needed it will be stopped, deleted and a new container will be -created from this image. +If a container exists of the default or given name, as needed it will be stopped, deleted and a new container will be created from this image. #### **--tls-verify** -Require HTTPS and verify certificates when contacting registries (default: true). If explicitly set to true, -then TLS verification will be used. If set to false, then TLS verification will not be used. If not specified, -TLS verification will be used unless the target registry is listed as an insecure registry in registries.conf. +Require HTTPS and verify certificates when contacting registries (default: true). If explicitly set to true, then TLS verification will be used. If set to false, then TLS verification will not be used. If not specified, TLS verification will be used unless the target registry is listed as an insecure registry in containers-registries.conf(5). ## EXAMPLES -Execute the run label of an image called foobar. +Execute the `run` label of an image called foobar. ``` -$ sudo podman container runlabel run foobar +$ podman container runlabel run foobar ``` -Execute the install label of an image called foobar with additional arguments. +Execute the `install` label of an image called foobar with additional arguments. ``` -$ sudo podman container runlabel install foobar apples oranges +$ podman container runlabel install foobar apples oranges ``` -Display the command that would be executed by runlabel. +Display the contents of the `run` label of image foobar. ``` -$ sudo podman container runlabel --display run foobar +$ podman container runlabel --display run foobar ``` ## SEE ALSO -podman(1), containers-certs.d(5) +podman(1), crun(1), runc(1), containers-auth.json(5), containers-certs.d(5), containers-registries.conf(5) ## HISTORY +August 2021, Refinements by Valentin Rothberg (rothberg at redhat dot com) + September 2018, Originally compiled by Brent Baude (bbaude at redhat dot com) diff --git a/docs/source/markdown/podman-container.1.md b/docs/source/markdown/podman-container.1.md index e69c5a170..3cc90d9ec 100644 --- a/docs/source/markdown/podman-container.1.md +++ b/docs/source/markdown/podman-container.1.md @@ -38,7 +38,7 @@ The container command allows you to manage containers | restore | [podman-container-restore(1)](podman-container-restore.1.md) | Restores one or more containers from a checkpoint. | | rm | [podman-rm(1)](podman-rm.1.md) | Remove one or more containers. | | run | [podman-run(1)](podman-run.1.md) | Run a command in a container. | -| runlabel | [podman-container-runlabel(1)](podman-container-runlabel.1.md) | Executes a command as described by a container image label. | +| runlabel | [podman-container-runlabel(1)](podman-container-runlabel.1.md) | Executes a command as described by a container-image label. | | start | [podman-start(1)](podman-start.1.md) | Starts one or more containers. | | stats | [podman-stats(1)](podman-stats.1.md) | Display a live stream of one or more container's resource usage statistics. | | stop | [podman-stop(1)](podman-stop.1.md) | Stop one or more running containers. | diff --git a/docs/source/markdown/podman-cp.1.md b/docs/source/markdown/podman-cp.1.md index 43ee4cdff..79edf26ed 100644 --- a/docs/source/markdown/podman-cp.1.md +++ b/docs/source/markdown/podman-cp.1.md @@ -9,111 +9,121 @@ podman\-cp - Copy files/folders between a container and the local filesystem **podman container cp** [*options*] [*container*:]*src_path* [*container*:]*dest_path* ## DESCRIPTION -Copy the contents of **src_path** to the **dest_path**. You can copy from the container's filesystem to the local machine or the reverse, from the local filesystem to the container. -If `-` is specified for either the SRC_PATH or DEST_PATH, you can also stream a tar archive from STDIN or to STDOUT. +**podman cp** allows copying the contents of **src_path** to the **dest_path**. Files can be copied from a container to the local machine and vice versa or between two containers. +If `-` is specified for either the `SRC_PATH` or `DEST_PATH`, one can also stream a tar archive from `STDIN` or to `STDOUT`. -The CONTAINER can be a running or stopped container. The **src_path** or **dest_path** can be a file or directory. +The containers can be either running or stopped and the *src_path* or *dest_path* can be a file or directory. -The **podman cp** command assumes container paths are relative to the container's root directory (i.e., `/`). - -This means supplying the initial forward slash is optional; - -The command sees **compassionate_darwin:/tmp/foo/myfile.txt** and **compassionate_darwin:tmp/foo/myfile.txt** as identical. +*IMPORTANT: The **podman cp** command assumes container paths are relative to the container's root directory (`/`), which means supplying the initial forward slash is optional and therefore sees `compassionate_darwin:/tmp/foo/myfile.txt` and `compassionate_darwin:tmp/foo/myfile.txt` as identical.* Local machine paths can be an absolute or relative value. The command interprets a local machine's relative paths as relative to the current working directory where **podman cp** is run. -Assuming a path separator of /, a first argument of **src_path** and second argument of **dest_path**, the behavior is as follows: +Assuming a path separator of `/`, a first argument of **src_path** and second argument of **dest_path**, the behavior is as follows: -**src_path** specifies a file +**src_path** specifies a file: - **dest_path** does not exist - - the file is saved to a file created at **dest_path** (note that parent directory must exist) + - the file is saved to a file created at **dest_path** (note that parent directory must exist). - **dest_path** exists and is a file - - the destination is overwritten with the source file's contents + - the destination is overwritten with the source file's contents. - **dest_path** exists and is a directory - - the file is copied into this directory using the base name from **src_path** + - the file is copied into this directory using the base name from **src_path**. -**src_path** specifies a directory +**src_path** specifies a directory: - **dest_path** does not exist - - **dest_path** is created as a directory and the contents of the source directory are copied into this directory + - **dest_path** is created as a directory and the contents of the source directory are copied into this directory. - **dest_path** exists and is a file - - Error condition: cannot copy a directory to a file + - Error condition: cannot copy a directory to a file. - **dest_path** exists and is a directory - **src_path** ends with `/` - - the source directory is copied into this directory + - the source directory is copied into this directory. - **src_path** ends with `/.` (i.e., slash followed by dot) - - the content of the source directory is copied into this directory + - the content of the source directory is copied into this directory. The command requires **src_path** and **dest_path** to exist according to the above rules. If **src_path** is local and is a symbolic link, the symbolic target, is copied by default. -A colon (:) is used as a delimiter between CONTAINER and its path. - -You can also use : when specifying paths to a **src_path** or **dest_path** on a local machine, for example, `file:name.txt`. +A *colon* ( : ) is used as a delimiter between a container and its path, it can also be used when specifying paths to a **src_path** or **dest_path** on a local machine, for example, `file:name.txt`. -If you use a : in a local machine path, you must be explicit with a relative or absolute path, for example: - `/path/to/file:name.txt` or `./file:name.txt` +*IMPORTANT: while using a *colon* ( : ) in a local machine path, one must be explicit with a relative or absolute path, for example: `/path/to/file:name.txt` or `./file:name.txt`* -Using `-` as the *src_path* streams the contents of STDIN as a tar archive. The command extracts the content of the tar to the *DEST_PATH* in the container. In this case, *dest_path* must specify a directory. Using `-` as the *dest_path* streams the contents of the resource (can be a directory) as a tar archive to STDOUT. +Using `-` as the **src_path** streams the contents of `STDIN` as a tar archive. The command extracts the content of the tar to the `DEST_PATH` in the container. In this case, **dest_path** must specify a directory. Using `-` as the **dest_path** streams the contents of the resource (can be a directory) as a tar archive to `STDOUT`. Note that `podman cp` ignores permission errors when copying from a running rootless container. The TTY devices inside a rootless container are owned by the host's root user and hence cannot be read inside the container's user namespace. ## OPTIONS -#### **--archive**, **-a** +#### **--archive**, **-a**=**true** | *false* Archive mode (copy all uid/gid information). -When set to true, files copied to a container will have changed ownership to the primary uid/gid of the container. +When set to true, files copied to a container will have changed ownership to the primary UID/GID of the container. When set to false, maintain uid/gid from archive sources instead of changing them to the primary uid/gid of the destination container. -The default is *true*. +The default is **true**. ## ALTERNATIVES -Podman has much stronger capabilities than just `podman cp` to achieve copy files between host and container. +Podman has much stronger capabilities than just `podman cp` to achieve copying files between the host and containers. -Using standard podman-mount and podman-umount takes advantage of the entire linux tool chain, rather -then just cp. +Using standard **[podman-mount(1)](podman-mount.1.md)** and **[podman-unmount(1)](podman-unmount.1.md)** takes advantage of the entire linux tool chain, rather than just cp. -If a user wants to copy contents out of a container or into a container, they can execute a few simple commands. +copying contents out of a container or into a container, can be achieved with a few simple commands. For example: -You can copy from the container's file system to the local machine or the reverse, from the local filesystem to the container. - -If you want to copy the /etc/foobar directory out of a container and onto /tmp on the host, you could execute the following commands: +To copy the `/etc/foobar` directory out of a container and onto `/tmp` on the host, the following commands can be executed: mnt=$(podman mount CONTAINERID) cp -R ${mnt}/etc/foobar /tmp podman umount CONTAINERID -If you want to untar a tar ball into a container, you can execute these commands: +To untar a tar ball into a container, following commands can be executed: mnt=$(podman mount CONTAINERID) tar xf content.tgz -C ${mnt} podman umount CONTAINERID -One last example, if you want to install a package into a container that -does not have dnf installed, you could execute something like: +To install a package into a container that +does not have dnf installed, following commands can be executed: mnt=$(podman mount CONTAINERID) dnf install --installroot=${mnt} httpd chroot ${mnt} rm -rf /var/log/dnf /var/cache/dnf podman umount CONTAINERID -This shows that using `podman mount` and `podman umount` you can use all of the +By using `podman mount` and `podman unmount`, one can use all of the standard linux tools for moving files into and out of containers, not just the cp command. -## EXAMPLE +## EXAMPLES + +- Copy a file from host to a container. + ``` + podman cp /myapp/app.conf containerID:/myapp/app.conf + ``` -podman cp /myapp/app.conf containerID:/myapp/app.conf +- Copy a file from a container to a directory on another container. + ``` + podman cp containerID1:/myfile.txt containerID2:/tmp + ``` -podman cp /home/myuser/myfiles.tar containerID:/tmp +- Copy a directory on a container to a directory on the host. + ``` + podman cp containerID:/myapp/ /myapp/ + ``` -podman cp containerID:/myapp/ /myapp/ +- Copy the contents of a directory on a container to a directory on the host. + ``` + podman cp containerID:/home/myuser/. /home/myuser/ + ``` -podman cp containerID:/home/myuser/. /home/myuser/ +- Copy a directory on a container into a directory on another. + ``` + podman cp containerA:/myapp containerB:/yourapp + ``` -podman cp - containerID:/myfiles.tar.gz < myfiles.tar.gz +- Stream a tar archive from `STDIN` to a container. + ``` + podman cp - containerID:/myfiles.tar.gz < myfiles.tar.gz + ``` ## SEE ALSO -podman(1), podman-mount(1), podman-umount(1) +**[podman(1)](podman.1.md)**, **[podman-mount(1)](podman-mount.1.md)**, **[podman-unmount(1)](podman-unmount.1.md)** diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md index f56b363e0..7f9cf0e75 100644 --- a/docs/source/markdown/podman-create.1.md +++ b/docs/source/markdown/podman-create.1.md @@ -181,6 +181,8 @@ Limit the CPU real-time period in microseconds Limit the container's Real Time CPU usage. This flag tell the kernel to restrict the container's Real Time CPU usage to the period you specify. +This flag is not supported on cgroups V2 systems. + #### **--cpu-rt-runtime**=*microseconds* Limit the CPU real-time runtime in microseconds @@ -190,6 +192,8 @@ Period of 1,000,000us and Runtime of 950,000us means that this container could c The sum of all runtimes across containers cannot exceed the amount allotted to the parent cgroup. +This flag is not supported on cgroups V2 systems. + #### **--cpu-shares**=*shares* CPU shares (relative weight) @@ -479,6 +483,8 @@ is not limited. If you specify a limit, it may be rounded up to a multiple of the operating system's page size and the value can be very large, millions of trillions. +This flag is not supported on cgroups V2 systems. + #### **--label**, **-l**=*label* Add metadata to a container (e.g., --label com.example.key=value) @@ -561,6 +567,8 @@ unit, `b` is used. Set LIMIT to `-1` to enable unlimited swap. Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. +This flag is not supported on cgroups V2 systems. + #### **--mount**=*type=TYPE,TYPE-SPECIFIC-OPTION[,...]* Attach a filesystem mount to the container @@ -858,7 +866,7 @@ Secrets and its storage are managed using the `podman secret` command. Secret Options - `type=mount|env` : How the secret will be exposed to the container. Default mount. -- `target=target` : Target of secret. Defauts to secret name. +- `target=target` : Target of secret. Defaults to secret name. - `uid=0` : UID of secret. Defaults to 0. Mount secret type only. - `gid=0` : GID of secret. Defaults to 0. Mount secret type only. - `mode=0` : Mode of secret. Defaults to 0444. Mount secret type only. @@ -1086,14 +1094,28 @@ Set the user namespace mode for the container. It defaults to the **PODMAN_USERN Valid _mode_ values are: -- **auto[:**_OPTIONS,..._**]**: automatically create a namespace. It is possible to specify these options to `auto`: - - **gidmapping=**_HOST_GID:CONTAINER_GID:SIZE_: to force a GID mapping to be present in the user namespace. - - **size=**_SIZE_: to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will estimate a size for the user namespace. - - **uidmapping=**_HOST_UID:CONTAINER_UID:SIZE_: to force a UID mapping to be present in the user namespace. -- **container:**_id_: join the user namespace of the specified container. -- **host**: run in the user namespace of the caller. The processes running in the container will have the same privileges on the host as any other process launched by the calling user (default). +**auto**[:_OPTIONS,..._]: automatically create a unique user namespace. + +The `--userns=auto` flag, requires that the user name `containers` and a range of subordinate user ids that the Podman container is allowed to use be specified in the /etc/subuid and /etc/subgid files. + +Example: `containers:2147483647:2147483648`. + +Podman allocates unique ranges of UIDs and GIDs from the `containers` subpordinate user ids. The size of the ranges is based on the number of UIDs required in the image. The number of UIDs and GIDs can be overridden with the `size` option. The `auto` options currently does not work in rootless mode + + Valid `auto`options: + + - *gidmapping*=_HOST_GID:CONTAINER_GID:SIZE_: to force a GID mapping to be present in the user namespace. + - *size*=_SIZE_: to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will estimate a size for the user namespace. + - *uidmapping*=_HOST_UID:CONTAINER_UID:SIZE_: to force a UID mapping to be present in the user namespace. + +**container:**_id_: join the user namespace of the specified container. + +**host**: run in the user namespace of the caller. The processes running in the container will have the same privileges on the host as any other process launched by the calling user (default). + - **keep-id**: creates a user namespace where the current rootless user's UID:GID are mapped to the same values in the container. This option is ignored for containers created by the root user. + - **ns:**_namespace_: run the container in the given existing user namespace. + - **private**: create a new namespace for the container. This option is incompatible with **--gidmap**, **--uidmap**, **--subuidname** and **--subgidname**. @@ -1353,6 +1375,12 @@ the uids and gids from the host. $ podman create --uidmap 0:30000:7000 --gidmap 0:30000:7000 fedora echo hello ``` +### Setting automatic user namespace separated containers + +``` +# podman create --userns=auto:size=65536 ubi8-init +``` + ### Configure timezone in a container ``` diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md index 28c455b78..357120381 100644 --- a/docs/source/markdown/podman-generate-systemd.1.md +++ b/docs/source/markdown/podman-generate-systemd.1.md @@ -73,7 +73,7 @@ $ podman generate systemd --restart-policy=always -t 1 nginx [Unit] Description=Podman container-de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/container/storage @@ -102,7 +102,7 @@ $ sudo podman generate systemd --new --files --name bb310a0780ae [Unit] Description=Podman container-busy_moser.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/container/storage @@ -144,7 +144,7 @@ Description=Podman pod-systemd-pod.service Documentation=man:podman-generate-systemd(1) Requires=container-amazing_chandrasekhar.service container-jolly_shtern.service Before=container-amazing_chandrasekhar.service container-jolly_shtern.service -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/container/storage diff --git a/docs/source/markdown/podman-images.1.md b/docs/source/markdown/podman-images.1.md index 23cce450a..02385daec 100644 --- a/docs/source/markdown/podman-images.1.md +++ b/docs/source/markdown/podman-images.1.md @@ -36,7 +36,7 @@ Filter output based on conditions provided Filter on images created before the given IMAGE (name or tag). **dangling=true|false** - Show dangling images. Dangling images are a file system layer that was used in a previous build of an image and is no longer referenced by any active images. They are denoted with the `<none>` tag, consume disk space and serve no active purpose. + Show dangling images. Dangling images are a file system layer that was used in a previous build of an image and is no longer referenced by any image. They are denoted with the `<none>` tag, consume disk space and serve no active purpose. **label** Filter by images labels key and/or value. diff --git a/docs/source/markdown/podman-logs.1.md b/docs/source/markdown/podman-logs.1.md index 8f1301102..6b3ef79d7 100644 --- a/docs/source/markdown/podman-logs.1.md +++ b/docs/source/markdown/podman-logs.1.md @@ -39,6 +39,14 @@ strings (e.g. 10m, 1h30m) computed relative to the client machine's time. Suppor time stamps include RFC3339Nano, RFC3339, 2006-01-02T15:04:05, 2006-01-02T15:04:05.999999999, 2006-01-02Z07:00, and 2006-01-02. +#### **--until**=*TIMESTAMP* + +Show logs until TIMESTAMP. The --until option can be Unix timestamps, date formatted timestamps, or Go duration +strings (e.g. 10m, 1h30m) computed relative to the client machine's time. Supported formats for date formatted +time stamps include RFC3339Nano, RFC3339, 2006-01-02T15:04:05, 2006-01-02T15:04:05.999999999, 2006-01-02Z07:00, +and 2006-01-02. + + #### **--tail**=*LINES* Output the specified number of LINES at the end of the logs. LINES must be an integer. Defaults to -1, @@ -74,6 +82,17 @@ podman logs --tail 2 b3f2436bdb97 # Server initialized ``` +To view all containers logs: +``` +podman logs -t --since 0 myserver + +1:M 07 Aug 14:10:09.055 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted. +1:M 07 Aug 14:10:09.055 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'. +1:M 07 Aug 14:10:09.056 * Running mode=standalone, port=6379. +1:M 07 Aug 14:10:09.056 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. +1:M 07 Aug 14:10:09.056 # Server initialized +``` + To view a containers logs since a certain time: ``` podman logs -t --since 2017-08-07T10:10:09.055837383-04:00 myserver @@ -93,6 +112,16 @@ podman logs --since 10m myserver # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'. ``` +To view a container's logs until 30 minutes ago: +``` +podman logs --until 30m myserver + +AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.0.2.100. Set the 'ServerName' directive globally to suppress this message +AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.0.2.100. Set the 'ServerName' directive globally to suppress this message +[Tue Jul 20 13:18:14.223727 2021] [mpm_event:notice] [pid 1:tid 140021067187328] AH00489: Apache/2.4.48 (Unix) configured -- resuming normal operations +[Tue Jul 20 13:18:14.223819 2021] [core:notice] [pid 1:tid 140021067187328] AH00094: Command line: 'httpd -D FOREGROUND' +``` + ## SEE ALSO podman(1), podman-run(1), podman-container-rm(1) diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md index 653b0f6f1..441995cb6 100644 --- a/docs/source/markdown/podman-pod-create.1.md +++ b/docs/source/markdown/podman-pod-create.1.md @@ -75,6 +75,10 @@ The command that will be run to start the infra container. Default: "/pause". The image that will be created for the infra container. Default: "k8s.gcr.io/pause:3.1". +#### **--infra-name**=*name* + +The name that will be used for the pod's infra container. + #### **--ip**=*ipaddr* Set a static IP for the pod's shared network. @@ -120,6 +124,14 @@ Add a DNS alias for the container. When the container is joined to a CNI network Disable creation of /etc/hosts for the pod. +#### **--pid**=*pid* + +Set the PID mode for the pod. The default is to create a private PID namespace for the pod. Requires the PID namespace to be shared via --share. + + host: use the host’s PID namespace for the pod + ns: join the specified PID namespace + private: create a new namespace for the pod (default) + #### **--pod-id-file**=*path* Write the pod ID to the file. diff --git a/docs/source/markdown/podman-pod-ps.1.md b/docs/source/markdown/podman-pod-ps.1.md index c1f5fd5e3..156adccaa 100644 --- a/docs/source/markdown/podman-pod-ps.1.md +++ b/docs/source/markdown/podman-pod-ps.1.md @@ -12,7 +12,9 @@ By default it lists: * pod id * pod name + * the time the pod was created * number of containers attached to pod + * container id of the pod infra container * status of pod as defined by the following table | **Status** | **Description** | @@ -28,15 +30,15 @@ By default it lists: #### **--ctr-names** -Includes the container names in the container info field +Display the container names #### **--ctr-ids** -Includes the container IDs in the container info field +Display the container IDs #### **--ctr-status** -Includes the container statuses in the container info field +Display the container statuses #### **--latest**, **-l** @@ -111,62 +113,55 @@ Print usage statement ``` $ podman pod ps -POD ID NAME STATUS NUMBER OF CONTAINERS -00dfd6fa02c0 jolly_goldstine Running 1 -f4df8692e116 nifty_torvalds Created 2 +POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS +00dfd6fa02c0 jolly_goldstine Running 31 hours ago ba465ab0a3a4 1 +f4df8692e116 nifty_torvalds Created 10 minutes ago 331693bff40a 2 ``` ``` $ podman pod ps --ctr-names -POD ID NAME STATUS CONTAINER INFO -00dfd6fa02c0 jolly_goldstine Running [ loving_archimedes ] -f4df8692e116 nifty_torvalds Created [ thirsty_hawking ] [ wizardly_golick ] +POD ID NAME STATUS CREATED INFRA ID NAMES +00dfd6fa02c0 jolly_goldstine Running 31 hours ago ba465ab0a3a4 loving_archimedes +f4df8692e116 nifty_torvalds Created 10 minutes ago 331693bff40a thirsty_hawking,wizardly_golick ``` ``` $ podman pod ps --ctr-status --ctr-names --ctr-ids -POD ID NAME STATUS CONTAINER INFO -00dfd6fa02c0 jolly_goldstine Running [ ba465ab0a3a4 loving_archimedes Running ] -f4df8692e116 nifty_torvalds Created [ 331693bff40a thirsty_hawking Created ] [ 8e428daeb89e wizardly_golick Created ] +POD ID NAME STATUS CREATED INFRA ID IDS NAMES STATUS +00dfd6fa02c0 jolly_goldstine Running 31 hours ago ba465ab0a3a4 ba465ab0a3a4 loving_archimedes running +f4df8692e116 nifty_torvalds Created 10 minutes ago 331693bff40a 331693bff40a,8e428daeb89e thirsty_hawking,wizardly_golick configured,configured ``` ``` -$ podman pod ps --format "{{.ID}} {{.ContainerInfo}} {{.Cgroup}}" --ctr-names -00dfd6fa02c0 [ loving_archimedes ] /libpod_parent -f4df8692e116 [ thirsty_hawking ] [ wizardly_golick ] /libpod_parent -``` - -``` -$ podman pod ps --cgroup -POD ID NAME STATUS NUMBER OF CONTAINERS CGROUP USE POD CGROUP -00dfd6fa02c0 jolly_goldstine Running 1 /libpod_parent true -f4df8692e116 nifty_torvalds Created 2 /libpod_parent true +$ podman pod ps --format "{{.ID}} {{.ContainerNames}} {{.Cgroup}}" +00dfd6fa02c0 loving_archimedes /libpod_parent +f4df8692e116 thirsty_hawking,wizardly_golick /libpod_parent ``` ``` $ podman pod ps --sort id --filter ctr-number=2 -POD ID NAME STATUS NUMBER OF CONTAINERS -f4df8692e116 nifty_torvalds Created 2 +POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS +f4df8692e116 nifty_torvalds Created 10 minutes ago 331693bff40a 2 ``` ``` $ podman pod ps --ctr-ids -POD ID NAME STATUS CONTAINER INFO -00dfd6fa02c0 jolly_goldstine Running [ ba465ab0a3a4 ] -f4df8692e116 nifty_torvalds Created [ 331693bff40a ] [ 8e428daeb89e ] +POD ID NAME STATUS CREATED INFRA ID IDS +00dfd6fa02c0 jolly_goldstine Running 31 hours ago ba465ab0a3a4 ba465ab0a3a4 +f4df8692e116 nifty_torvalds Created 10 minutes ago 331693bff40a 331693bff40a,8e428daeb89e ``` ``` $ podman pod ps --no-trunc --ctr-ids -POD ID NAME STATUS CONTAINER INFO -00dfd6fa02c0a2daaedfdf8fcecd06f22ad114d46d167d71777224735f701866 jolly_goldstine Running [ ba465ab0a3a4e15e3539a1e79c32d1213a02b0989371e274f98e0f1ae9de7050 ] -f4df8692e116a3e6d1d62572644ed36ca475d933808cc3c93435c45aa139314b nifty_torvalds Created [ 331693bff40a0ef2f05a3aba73ce49e3243108911927fff04d1f7fc44dda8022 ] [ 8e428daeb89e69b71e7916a13accfb87d122889442b5c05c2d99cf94a3230e9d ] +POD ID NAME STATUS CREATED INFRA ID IDS +00dfd6fa02c0a2daaedfdf8fcecd06f22ad114d46d167d71777224735f701866 jolly_goldstine Running 31 hours ago ba465ab0a3a4e15e3539a1e79c32d1213a02b0989371e274f98e0f1ae9de7050 ba465ab0a3a4e15e3539a1e79c32d1213a02b0989371e274f98e0f1ae9de7050 +f4df8692e116a3e6d1d62572644ed36ca475d933808cc3c93435c45aa139314b nifty_torvalds Created 10 minutes ago 331693bff40a926b6d52b184e116afd15497610c378d5d4c42945dd6e33b75b0 331693bff40a926b6d52b184e116afd15497610c378d5d4c42945dd6e33b75b0,8e428daeb89e69b71e7916a13accfb87d122889442b5c05c2d99cf94a3230e9d ``` ``` $ podman pod ps --ctr-names -POD ID NAME STATUS CONTAINER INFO -314f4da82d74 hi Created [ jovial_jackson ] [ hopeful_archimedes ] [ vibrant_ptolemy ] [ heuristic_jennings ] [ keen_raman ] [ hopeful_newton ] [ mystifying_bose ] [ silly_lalande ] [ serene_lichterman ] ... +POD ID NAME STATUS CREATED INFRA ID NAMES +314f4da82d74 hi Created 17 hours ago a9f2d2165675 jovial_jackson,hopeful_archimedes,vibrant_ptolemy,heuristic_jennings,keen_raman,hopeful_newton,mystifying_bose,silly_lalande,serene_lichterman ... ``` ## pod ps diff --git a/docs/source/markdown/podman-pull.1.md b/docs/source/markdown/podman-pull.1.md index 10661e16e..189464d17 100644 --- a/docs/source/markdown/podman-pull.1.md +++ b/docs/source/markdown/podman-pull.1.md @@ -182,7 +182,7 @@ Storing signatures d6e46aa2470df1d32034c6707c8041158b652f38d2a9ae3d7ad7e7532d22ebe0 ``` -Pull an image by specifiying an authentication file. +Pull an image by specifying an authentication file. ``` $ podman pull --authfile temp-auths/myauths.json docker://docker.io/umohnani/finaltest Trying to pull docker.io/umohnani/finaltest:latest...Getting image source signatures diff --git a/docs/source/markdown/podman-rmi.1.md b/docs/source/markdown/podman-rmi.1.md index 1f62d6133..e34b1964b 100644 --- a/docs/source/markdown/podman-rmi.1.md +++ b/docs/source/markdown/podman-rmi.1.md @@ -10,7 +10,7 @@ podman\-rmi - Removes one or more locally stored images ## DESCRIPTION Removes one or more locally stored images. -Passing an argument _image_ deletes it, along with any of its dangling (untagged) parent images. +Passing an argument _image_ deletes it, along with any of its dangling parent images. A dangling image is an image without a tag and without being referenced by another image. ## OPTIONS diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index 1c3efa0c3..f08561904 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -199,6 +199,8 @@ Limit the CPU real-time period in microseconds. Limit the container's Real Time CPU usage. This flag tell the kernel to restrict the container's Real Time CPU usage to the period you specify. +This flag is not supported on cgroups V2 systems. + #### **--cpu-rt-runtime**=*microseconds* Limit the CPU real-time runtime in microseconds. @@ -208,6 +210,8 @@ Period of 1,000,000us and Runtime of 950,000us means that this container could c The sum of all runtimes across containers cannot exceed the amount allotted to the parent cgroup. +This flag is not supported on cgroups V2 systems. + #### **--cpu-shares**=*shares* CPU shares (relative weight). @@ -518,6 +522,8 @@ is not limited. If you specify a limit, it may be rounded up to a multiple of the operating system's page size and the value can be very large, millions of trillions. +This flag is not supported on cgroups V2 systems. + #### **--label**, **-l**=*key*=*value* Add metadata to a container. @@ -595,6 +601,8 @@ Set _number_ to **-1** to enable unlimited swap. Tune a container's memory swappiness behavior. Accepts an integer between *0* and *100*. +This flag is not supported on cgroups V2 systems. + #### **--mount**=*type=TYPE,TYPE-SPECIFIC-OPTION[,...]* Attach a filesystem mount to the container @@ -908,7 +916,7 @@ Secrets and its storage are managed using the `podman secret` command. Secret Options - `type=mount|env` : How the secret will be exposed to the container. Default mount. -- `target=target` : Target of secret. Defauts to secret name. +- `target=target` : Target of secret. Defaults to secret name. - `uid=0` : UID of secret. Defaults to 0. Mount secret type only. - `gid=0` : GID of secret. Defaults to 0. Mount secret type only. - `mode=0` : Mode of secret. Defaults to 0444. Mount secret type only. @@ -1159,14 +1167,28 @@ Set the user namespace mode for the container. It defaults to the **PODMAN_USERN Valid _mode_ values are: -- **auto[:**_OPTIONS,..._**]**: automatically create a namespace. It is possible to specify these options to `auto`: - - **gidmapping=**_HOST_GID:CONTAINER_GID:SIZE_: to force a GID mapping to be present in the user namespace. - - **size=**_SIZE_: to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will estimate a size for the user namespace. - - **uidmapping=**_HOST_UID:CONTAINER_UID:SIZE_: to force a UID mapping to be present in the user namespace. -- **container:**_id_: join the user namespace of the specified container. -- **host**: run in the user namespace of the caller. The processes running in the container will have the same privileges on the host as any other process launched by the calling user (default). +**auto**[:_OPTIONS,..._]: automatically create a unique user namespace. + +The `--userns=auto` flag, requires that the user name `containers` and a range of subordinate user ids that the Podman container is allowed to use be specified in the /etc/subuid and /etc/subgid files. + +Example: `containers:2147483647:2147483648`. + +Podman allocates unique ranges of UIDs and GIDs from the `containers` subpordinate user ids. The size of the ranges is based on the number of UIDs required in the image. The number of UIDs and GIDs can be overridden with the `size` option. The `auto` options currently does not work in rootless mode + + Valid `auto`options: + + - *gidmapping*=_HOST_GID:CONTAINER_GID:SIZE_: to force a GID mapping to be present in the user namespace. + - *size*=_SIZE_: to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will estimate a size for the user namespace. + - *uidmapping*=_HOST_UID:CONTAINER_UID:SIZE_: to force a UID mapping to be present in the user namespace. + +**container:**_id_: join the user namespace of the specified container. + +**host**: run in the user namespace of the caller. The processes running in the container will have the same privileges on the host as any other process launched by the calling user (default). + - **keep-id**: creates a user namespace where the current rootless user's UID:GID are mapped to the same values in the container. This option is ignored for containers created by the root user. + - **ns:**_namespace_: run the container in the given existing user namespace. + - **private**: create a new namespace for the container. This option is incompatible with **--gidmap**, **--uidmap**, **--subuidname** and **--subgidname**. @@ -1676,6 +1698,15 @@ $ echo "asdf" | podman run --rm -i --entrypoint /bin/cat someimage asdf ``` +### Setting automatic user namespace separated containers + +``` +# podman run --userns=auto:size=65536 ubi8-micro cat /proc/self/uid_map +0 2147483647 65536 +# podman run --userns=auto:size=65536 ubi8-micro cat /proc/self/uid_map +0 2147549183 65536 +``` + ### Setting Namespaced Kernel Parameters (Sysctls) The **--sysctl** sets namespaced kernel parameters (sysctls) in the diff --git a/docs/source/markdown/podman-volume-ls.1.md b/docs/source/markdown/podman-volume-ls.1.md index 489057446..b562aff61 100644 --- a/docs/source/markdown/podman-volume-ls.1.md +++ b/docs/source/markdown/podman-volume-ls.1.md @@ -24,6 +24,7 @@ Volumes can be filtered by the following attributes: - name - opt - scope +- until #### **--format**=*format* diff --git a/docs/source/markdown/podman-volume-prune.1.md b/docs/source/markdown/podman-volume-prune.1.md index 9477cb5d5..b9599c200 100644 --- a/docs/source/markdown/podman-volume-prune.1.md +++ b/docs/source/markdown/podman-volume-prune.1.md @@ -23,12 +23,8 @@ Do not prompt for confirmation. Filter volumes to be pruned. Volumes can be filtered by the following attributes: -- dangling -- driver - label -- name -- opt -- scope +- until #### **--help** diff --git a/docs/tutorials/basic_networking.md b/docs/tutorials/basic_networking.md index 850bf6681..e47661ddf 100644 --- a/docs/tutorials/basic_networking.md +++ b/docs/tutorials/basic_networking.md @@ -237,7 +237,7 @@ port like 8080. $ podman run -dt --name webserver -p 8080:80 quay.io/libpod/banner 17ea33ccd7f55ff45766b3ec596b990a5f2ba66eb9159cb89748a85dc3cebfe0 ``` -Because rootfull containers cannot communicate with each other directly with TCP/IP +Because rootless containers cannot communicate with each other directly with TCP/IP via IP addresses, the host and the port mapping are used. To do so, the IP address of the host (interface) must be known. ``` @@ -7,17 +7,17 @@ require ( github.com/blang/semver v3.5.1+incompatible github.com/buger/goterm v0.0.0-20181115115552-c206103e1f37 github.com/checkpoint-restore/checkpointctl v0.0.0-20210301084134-a2024f5584e7 - github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b + github.com/checkpoint-restore/go-criu/v5 v5.1.0 github.com/container-orchestrated-devices/container-device-interface v0.0.0-20210325223243-f99e8b6c10b9 github.com/containernetworking/cni v0.8.1 github.com/containernetworking/plugins v0.9.1 - github.com/containers/buildah v1.21.1-0.20210628174543-eadb10a12336 - github.com/containers/common v0.40.2-0.20210702074932-9d34b37ba77e + github.com/containers/buildah v1.21.1-0.20210721171232-54cafea4c933 + github.com/containers/common v0.41.1-0.20210721172332-291287e9d060 github.com/containers/conmon v2.0.20+incompatible - github.com/containers/image/v5 v5.13.2 + github.com/containers/image/v5 v5.14.0 github.com/containers/ocicrypt v1.1.2 github.com/containers/psgo v1.5.2 - github.com/containers/storage v1.32.5 + github.com/containers/storage v1.33.0 github.com/coreos/go-systemd/v22 v22.3.2 github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3 github.com/cri-o/ocicni v0.2.1-0.20210621164014-d0acc7862283 @@ -33,7 +33,7 @@ require ( github.com/ghodss/yaml v1.0.0 github.com/godbus/dbus/v5 v5.0.4 github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf - github.com/google/uuid v1.2.0 + github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.8.0 github.com/gorilla/schema v1.2.0 github.com/hashicorp/go-multierror v1.1.1 @@ -46,7 +46,7 @@ require ( github.com/onsi/gomega v1.14.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 - github.com/opencontainers/runc v1.0.0 + github.com/opencontainers/runc v1.0.1 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 github.com/opencontainers/runtime-tools v0.9.0 github.com/opencontainers/selinux v1.8.2 @@ -64,8 +64,8 @@ require ( go.etcd.io/bbolt v1.3.6 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20210603125802-9665404d3644 + golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b - k8s.io/api v0.21.2 - k8s.io/apimachinery v0.21.2 + k8s.io/api v0.21.3 + k8s.io/apimachinery v0.21.3 ) @@ -73,8 +73,9 @@ github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg3 github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= -github.com/Microsoft/hcsshim v0.8.17 h1:yFHH5bghP9ij5Y34PPaMOE8g//oXZ0uJQeMENVo2zcI= github.com/Microsoft/hcsshim v0.8.17/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= +github.com/Microsoft/hcsshim v0.8.20 h1:ZTwcx3NS8n07kPf/JZ1qwU6vnjhVPMUWlXBF8r9UxrE= +github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -127,11 +128,11 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/checkpointctl v0.0.0-20210301084134-a2024f5584e7 h1:ZmSAEFFtv3mepC4/Ze6E/hi6vGZlhRvywqp1l+w+qqw= github.com/checkpoint-restore/checkpointctl v0.0.0-20210301084134-a2024f5584e7/go.mod h1:Kp3ezoDVdhfYxZUtgs4OL8sVvgOLz3txk0sbQD0opvw= -github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b h1:T4nWG1TXIxeor8mAu5bFguPJgSIGhZqv/f0z55KCrJM= -github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b/go.mod h1:TrMrLQfeENAPYPRsJuq3jsqdlRh3lvi6trTZJG8+tho= github.com/checkpoint-restore/go-criu/v4 v4.0.2/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= +github.com/checkpoint-restore/go-criu/v5 v5.1.0 h1:BkVH17kcwgmKMnFArsvLrxuBbMwfvPNYRB7mfJ0lzyI= +github.com/checkpoint-restore/go-criu/v5 v5.1.0/go.mod h1:iaS8bb7p6zKJanp1Qe8mpl7+bnkYBR500psJR6mwma0= github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= @@ -145,6 +146,7 @@ github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.6.1/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -237,15 +239,16 @@ github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHV github.com/containernetworking/plugins v0.8.7/go.mod h1:R7lXeZaBzpfqapcAbHRW8/CYwm0dHzbz0XEjofx0uB0= github.com/containernetworking/plugins v0.9.1 h1:FD1tADPls2EEi3flPc2OegIY1M9pUa9r2Quag7HMLV8= github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= -github.com/containers/buildah v1.21.1-0.20210628174543-eadb10a12336 h1:LAjAsDE6sxZnDoSzE384o/cRuTGGn1OMjkd9YIPT2bg= -github.com/containers/buildah v1.21.1-0.20210628174543-eadb10a12336/go.mod h1:HZ2k0W/EREpNxr+AnRZQzjjBdhXLItp9yuzwAaVa6zM= -github.com/containers/common v0.40.1/go.mod h1:X4F+6vmeAWKMMTNHlOBwOnkf5TQAkQACcuNsKjfcodw= -github.com/containers/common v0.40.2-0.20210702074932-9d34b37ba77e h1:ubkW5+D74+JrEL6qFmdAQpZ2L1jdGrRYPpkgKdV2YEw= -github.com/containers/common v0.40.2-0.20210702074932-9d34b37ba77e/go.mod h1:dbz5oauwVA4I/9HMe7YQUt6LWUmrYQlwQH9LQ35bm/U= +github.com/containers/buildah v1.21.1-0.20210721171232-54cafea4c933 h1:jqO3hDypBoKM5be+fVcqGHOpX2fOiQy2DFEeb/VKpsk= +github.com/containers/buildah v1.21.1-0.20210721171232-54cafea4c933/go.mod h1:9gspFNeUJxIK72n1IMIKIHmtcePEZQsv0tjo+1LqkCo= +github.com/containers/common v0.41.1-0.20210721112610-c95d2f794edf/go.mod h1:Ba5YVNCnyX6xDtg1JqEHa2EMVMW5UbHmIyEqsEwpeGE= +github.com/containers/common v0.41.1-0.20210721172332-291287e9d060 h1:HgGff2MeEKfYoKp2WQFl9xdsgP7KV8rr/1JZRIuPXmg= +github.com/containers/common v0.41.1-0.20210721172332-291287e9d060/go.mod h1:Ba5YVNCnyX6xDtg1JqEHa2EMVMW5UbHmIyEqsEwpeGE= 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.13.2 h1:AgYunV/9d2fRkrmo23wH2MkqeHolFd6oQCkK+1PpuFA= github.com/containers/image/v5 v5.13.2/go.mod h1:GkWursKDlDcUIT7L7vZf70tADvZCk/Ga0wgS0MuF0ag= +github.com/containers/image/v5 v5.14.0 h1:ORaFZ/NwFjkSunMhxg9I8fQod8pgXkrYNiZzit/VqOE= +github.com/containers/image/v5 v5.14.0/go.mod h1:SxiBKOcKuT+4yTjD0AskjO+UwFvNcVOJ9qlAw1HNSPU= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= @@ -257,8 +260,9 @@ github.com/containers/psgo v1.5.2 h1:3aoozst/GIwsrr/5jnFy3FrJay98uujPCu9lTuSZ/Cw github.com/containers/psgo v1.5.2/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzPUWfawVU= github.com/containers/storage v1.23.5/go.mod h1:ha26Q6ngehFNhf3AWoXldvAvwI4jFe3ETQAf/CeZPyM= github.com/containers/storage v1.32.2/go.mod h1:YIBxxjfXZTi04Ah49sh1uSGfmT1V89+I5i3deRobzQo= -github.com/containers/storage v1.32.5 h1:DXgmyA+oOs7YAzKkEqgC5O8l2UuDGJcwEFbdt49qiak= -github.com/containers/storage v1.32.5/go.mod h1:8/DVVDqniaUlUV0D0q7cEnXK6Bs2uU3FPqNZVPumwEs= +github.com/containers/storage v1.32.6/go.mod h1:mdB+b89p+jU8zpzLTVXA0gWMmIo0WrkfGMh1R8O2IQw= +github.com/containers/storage v1.33.0 h1:sTk1Mfz3uSNg7cxeaDb0Ld8/UV+8pZEOQjvysjJuzX8= +github.com/containers/storage v1.33.0/go.mod h1:FUZPF4nJijX8ixdhByZJXf02cvbyLi6dyDwXdIe8QVY= 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= @@ -480,8 +484,9 @@ github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIE github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= @@ -694,7 +699,6 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= -github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= 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/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= @@ -705,7 +709,6 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= -github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/onsi/gomega v1.14.0 h1:ep6kpPVwmr/nTbklSx2nrLNSIO62DoYAhnPNIMhK8gI= github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -726,8 +729,9 @@ github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rm github.com/opencontainers/runc v1.0.0-rc91/go.mod h1:3Sm6Dt7OT8z88EbdQqqcRN2oCT54jbi72tT/HqgflT8= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= github.com/opencontainers/runc v1.0.0-rc95/go.mod h1:z+bZxa/+Tz/FmYVWkhUajJdzFeOqjc5vrqskhVyHGUM= -github.com/opencontainers/runc v1.0.0 h1:QOhAQAYUlKeofuyeKdR6ITvOnXLPbEAjPMjz9wCUXcU= github.com/opencontainers/runc v1.0.0/go.mod h1:MU2S3KEB2ZExnhnAQYbwjdYV6HwKtDlNbA2Z2OeNDeA= +github.com/opencontainers/runc v1.0.1 h1:G18PGckGdAm3yVQRWDVQ1rLSLntiniKJ0cNRT2Tm5gs= +github.com/opencontainers/runc v1.0.1/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -841,8 +845,6 @@ github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKv github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/cobra v1.2.0/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= @@ -896,8 +898,9 @@ github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02 github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g= github.com/vbauerster/mpb/v6 v6.0.4 h1:h6J5zM/2wimP5Hj00unQuV8qbo5EPcj6wbkCqgj7KcY= github.com/vbauerster/mpb/v6 v6.0.4/go.mod h1:a/+JT57gqh6Du0Ay5jSR+uBMfXGdlR7VQlGP52fJxLM= -github.com/vbauerster/mpb/v7 v7.0.2 h1:eN6AD/ytv1nqCO7Dm8MO0/pGMKmMyH/WMnTJhAUuc/w= github.com/vbauerster/mpb/v7 v7.0.2/go.mod h1:Mnq3gESXJ9eQhccbGZDggJ1faTCrmaA4iN57fUloRGE= +github.com/vbauerster/mpb/v7 v7.0.3 h1:NfX0pHWhlDTev15M/C3qmSTM1EiIjcS+/d6qS6H4FnI= +github.com/vbauerster/mpb/v7 v7.0.3/go.mod h1:NXGsfPGx6G2JssqvEcULtDqUrxuuYs4llpv8W6ZUpzk= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852 h1:cPXZWzzG0NllBLdjWoD1nDfaqu98YMv+OneaKc8sPOA= @@ -1177,8 +1180,9 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201113234701-d7a72108b828/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1427,13 +1431,13 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= -k8s.io/api v0.21.2 h1:vz7DqmRsXTCSa6pNxXwQ1IYeAZgdIsua+DZU+o+SX3Y= -k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU= +k8s.io/api v0.21.3 h1:cblWILbLO8ar+Fj6xdDGr603HRsf8Wu9E9rngJeprZQ= +k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= -k8s.io/apimachinery v0.21.2 h1:vezUc/BHqWlQDnZ+XkrpXSmnANSLbpnlpwo0Lhk0gpc= -k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM= +k8s.io/apimachinery v0.21.3 h1:3Ju4nvjCngxxMYby0BimUk+pQHPOQp3eCGChk5kfVII= +k8s.io/apimachinery v0.21.3/go.mod h1:H/IM+5vH9kZRNJ4l3x/fXP/5bOPJaVP/guptnZPeCFI= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= @@ -1465,8 +1469,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyz sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= -sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= +sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/libpod/container_api.go b/libpod/container_api.go index 390bba7bb..637f5b686 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -780,6 +780,16 @@ type ContainerCheckpointOptions struct { // Compression tells the API which compression to use for // the exported checkpoint archive. Compression archive.Compression + // If Pod is set the container should be restored into the + // given Pod. If Pod is empty it is a restore without a Pod. + // Restoring a non Pod container into a Pod or a Pod container + // without a Pod is theoretically possible, but will + // probably not work if a PID namespace is shared. + // A shared PID namespace means that a Pod container has PID 1 + // in the infrastructure container, but without the infrastructure + // container no PID 1 will be in the namespace and that is not + // possible. + Pod string } // Checkpoint checkpoints a container @@ -811,7 +821,11 @@ func (c *Container) Checkpoint(ctx context.Context, options ContainerCheckpointO // Restore restores a container func (c *Container) Restore(ctx context.Context, options ContainerCheckpointOptions) error { - logrus.Debugf("Trying to restore container %s", c.ID()) + if options.Pod == "" { + logrus.Debugf("Trying to restore container %s", c.ID()) + } else { + logrus.Debugf("Trying to restore container %s into pod %s", c.ID(), options.Pod) + } if !c.batched { c.lock.Lock() defer c.lock.Unlock() @@ -840,7 +854,7 @@ func (c *Container) ShouldRestart(ctx context.Context) bool { // CopyFromArchive copies the contents from the specified tarStream to path // *inside* the container. -func (c *Container) CopyFromArchive(ctx context.Context, containerPath string, chown bool, tarStream io.Reader) (func() error, error) { +func (c *Container) CopyFromArchive(ctx context.Context, containerPath string, chown bool, rename map[string]string, tarStream io.Reader) (func() error, error) { if !c.batched { c.lock.Lock() defer c.lock.Unlock() @@ -850,7 +864,7 @@ func (c *Container) CopyFromArchive(ctx context.Context, containerPath string, c } } - return c.copyFromArchive(ctx, containerPath, chown, tarStream) + return c.copyFromArchive(ctx, containerPath, chown, rename, tarStream) } // CopyToArchive copies the contents from the specified path *inside* the diff --git a/libpod/container_copy_linux.go b/libpod/container_copy_linux.go index 01e7ecacb..a35824289 100644 --- a/libpod/container_copy_linux.go +++ b/libpod/container_copy_linux.go @@ -23,7 +23,7 @@ import ( "golang.org/x/sys/unix" ) -func (c *Container) copyFromArchive(ctx context.Context, path string, chown bool, reader io.Reader) (func() error, error) { +func (c *Container) copyFromArchive(ctx context.Context, path string, chown bool, rename map[string]string, reader io.Reader) (func() error, error) { var ( mountPoint string resolvedRoot string @@ -89,6 +89,7 @@ func (c *Container) copyFromArchive(ctx context.Context, path string, chown bool GIDMap: c.config.IDMappings.GIDMap, ChownDirs: idPair, ChownFiles: idPair, + Rename: rename, } return c.joinMountAndExec(ctx, diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 2555f15ec..e7694227a 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -420,7 +420,6 @@ func (c *Container) setupStorage(ctx context.Context) error { if c.config.Rootfs == "" && (c.config.RootfsImageID == "" || c.config.RootfsImageName == "") { return errors.Wrapf(define.ErrInvalidArg, "must provide image ID and image name to use an image") } - options := storage.ContainerOptions{ IDMappingOptions: storage.IDMappingOptions{ HostUIDMapping: true, diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 850af235f..bff64aa95 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -901,8 +901,27 @@ func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr } func (c *Container) exportCheckpoint(options ContainerCheckpointOptions) error { - if len(c.Dependencies()) > 0 { - return errors.Errorf("Cannot export checkpoints of containers with dependencies") + if len(c.Dependencies()) == 1 { + // Check if the dependency is an infra container. If it is we can checkpoint + // the container out of the Pod. + if c.config.Pod == "" { + return errors.Errorf("cannot export checkpoints of containers with dependencies") + } + + pod, err := c.runtime.state.Pod(c.config.Pod) + if err != nil { + return errors.Wrapf(err, "container %s is in pod %s, but pod cannot be retrieved", c.ID(), c.config.Pod) + } + infraID, err := pod.InfraContainerID() + if err != nil { + return errors.Wrapf(err, "cannot retrieve infra container ID for pod %s", c.config.Pod) + } + if c.Dependencies()[0] != infraID { + return errors.Errorf("cannot export checkpoints of containers with dependencies") + } + } + if len(c.Dependencies()) > 1 { + return errors.Errorf("cannot export checkpoints of containers with dependencies") } logrus.Debugf("Exporting checkpoint image of container %q to %q", c.ID(), options.TargetFile) @@ -1021,9 +1040,9 @@ func (c *Container) exportCheckpoint(options ContainerCheckpointOptions) error { return nil } -func (c *Container) checkpointRestoreSupported() error { - if !criu.CheckForCriu() { - return errors.Errorf("checkpoint/restore requires at least CRIU %d", criu.MinCriuVersion) +func (c *Container) checkpointRestoreSupported(version int) error { + if !criu.CheckForCriu(version) { + return errors.Errorf("checkpoint/restore requires at least CRIU %d", version) } if !c.ociRuntime.SupportsCheckpoint() { return errors.Errorf("configured runtime does not support checkpoint/restore") @@ -1032,7 +1051,7 @@ func (c *Container) checkpointRestoreSupported() error { } func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointOptions) error { - if err := c.checkpointRestoreSupported(); err != nil { + if err := c.checkpointRestoreSupported(criu.MinCriuVersion); err != nil { return err } @@ -1136,10 +1155,20 @@ func (c *Container) importPreCheckpoint(input string) error { } func (c *Container) restore(ctx context.Context, options ContainerCheckpointOptions) (retErr error) { - if err := c.checkpointRestoreSupported(); err != nil { + minCriuVersion := func() int { + if options.Pod == "" { + return criu.MinCriuVersion + } + return criu.PodCriuVersion + }() + if err := c.checkpointRestoreSupported(minCriuVersion); err != nil { return err } + if options.Pod != "" && !crutils.CRRuntimeSupportsPodCheckpointRestore(c.ociRuntime.Path()) { + return errors.Errorf("runtime %s does not support pod restore", c.ociRuntime.Path()) + } + if !c.ensureState(define.ContainerStateConfigured, define.ContainerStateExited) { return errors.Wrapf(define.ErrCtrStateInvalid, "container %s is running or paused, cannot restore", c.ID()) } @@ -1247,6 +1276,83 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti } } + if options.Pod != "" { + // Running in a Pod means that we have to change all namespace settings to + // the ones from the infrastructure container. + pod, err := c.runtime.LookupPod(options.Pod) + if err != nil { + return errors.Wrapf(err, "pod %q cannot be retrieved", options.Pod) + } + + infraContainer, err := pod.InfraContainer() + if err != nil { + return errors.Wrapf(err, "cannot retrieved infra container from pod %q", options.Pod) + } + + infraContainer.lock.Lock() + if err := infraContainer.syncContainer(); err != nil { + infraContainer.lock.Unlock() + return errors.Wrapf(err, "Error syncing infrastructure container %s status", infraContainer.ID()) + } + if infraContainer.state.State != define.ContainerStateRunning { + if err := infraContainer.initAndStart(ctx); err != nil { + infraContainer.lock.Unlock() + return errors.Wrapf(err, "Error starting infrastructure container %s status", infraContainer.ID()) + } + } + infraContainer.lock.Unlock() + + if c.config.IPCNsCtr != "" { + nsPath, err := infraContainer.namespacePath(IPCNS) + if err != nil { + return errors.Wrapf(err, "cannot retrieve IPC namespace path for Pod %q", options.Pod) + } + if err := g.AddOrReplaceLinuxNamespace(string(spec.IPCNamespace), nsPath); err != nil { + return err + } + } + + if c.config.NetNsCtr != "" { + nsPath, err := infraContainer.namespacePath(NetNS) + if err != nil { + return errors.Wrapf(err, "cannot retrieve network namespace path for Pod %q", options.Pod) + } + if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), nsPath); err != nil { + return err + } + } + + if c.config.PIDNsCtr != "" { + nsPath, err := infraContainer.namespacePath(PIDNS) + if err != nil { + return errors.Wrapf(err, "cannot retrieve PID namespace path for Pod %q", options.Pod) + } + if err := g.AddOrReplaceLinuxNamespace(string(spec.PIDNamespace), nsPath); err != nil { + return err + } + } + + if c.config.UTSNsCtr != "" { + nsPath, err := infraContainer.namespacePath(UTSNS) + if err != nil { + return errors.Wrapf(err, "cannot retrieve UTS namespace path for Pod %q", options.Pod) + } + if err := g.AddOrReplaceLinuxNamespace(string(spec.UTSNamespace), nsPath); err != nil { + return err + } + } + + if c.config.CgroupNsCtr != "" { + nsPath, err := infraContainer.namespacePath(CgroupNS) + if err != nil { + return errors.Wrapf(err, "cannot retrieve Cgroup namespace path for Pod %q", options.Pod) + } + if err := g.AddOrReplaceLinuxNamespace(string(spec.CgroupNamespace), nsPath); err != nil { + return err + } + } + } + if err := c.makeBindMounts(); err != nil { return err } @@ -2490,6 +2596,11 @@ func (c *Container) fixVolumePermissions(v *ContainerNamedVolume) error { // https://github.com/containers/podman/issues/10188 st, err := os.Lstat(filepath.Join(c.state.Mountpoint, v.Dest)) if err == nil { + if stat, ok := st.Sys().(*syscall.Stat_t); ok { + if err := os.Lchown(mountPoint, int(stat.Uid), int(stat.Gid)); err != nil { + return err + } + } if err := os.Chmod(mountPoint, st.Mode()|0111); err != nil { return err } diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go index 9f9dd3b0d..d4afaa52a 100644 --- a/libpod/container_log_linux.go +++ b/libpod/container_log_linux.go @@ -97,8 +97,6 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption } }() - beforeTimeStamp := true - afterTimeStamp := false // needed for options.Since tailQueue := []*logs.LogLine{} // needed for options.Tail doTail := options.Tail > 0 for { @@ -150,21 +148,10 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption return } - if !afterTimeStamp { - entryTime := time.Unix(0, int64(entry.RealtimeTimestamp)*int64(time.Microsecond)) - if entryTime.Before(options.Since) { - continue - } - afterTimeStamp = true - } - if beforeTimeStamp { - entryTime := time.Unix(0, int64(entry.RealtimeTimestamp)*int64(time.Microsecond)) - if entryTime.Before(options.Until) || !options.Until.IsZero() { - continue - } - beforeTimeStamp = false + entryTime := time.Unix(0, int64(entry.RealtimeTimestamp)*int64(time.Microsecond)) + if (entryTime.Before(options.Since) && !options.Since.IsZero()) || (entryTime.After(options.Until) && !options.Until.IsZero()) { + continue } - // If we're reading an event and the container exited/died, // then we're done and can return. event, ok := entry.Fields["PODMAN_EVENT"] diff --git a/libpod/define/pod_inspect.go b/libpod/define/pod_inspect.go index 67f075b3c..a17304875 100644 --- a/libpod/define/pod_inspect.go +++ b/libpod/define/pod_inspect.go @@ -103,6 +103,8 @@ type InspectPodInfraConfig struct { CPUQuota int64 `json:"cpu_quota,omitempty"` // CPUSetCPUs contains linux specific CPU data for the container CPUSetCPUs string `json:"cpuset_cpus,omitempty"` + // Pid is the PID namespace mode of the pod's infra container + PidNS string `json:"pid_ns,omitempty"` } // InspectPodContainerInfo contains information on a container in a pod. diff --git a/libpod/diff.go b/libpod/diff.go index 5bd162e7b..cdd5e79cb 100644 --- a/libpod/diff.go +++ b/libpod/diff.go @@ -1,7 +1,6 @@ package libpod import ( - "github.com/containers/common/libimage" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/layers" "github.com/containers/storage/pkg/archive" @@ -53,7 +52,7 @@ func (r *Runtime) GetDiff(from, to string, diffType define.DiffType) ([]archive. func (r *Runtime) getLayerID(id string, diffType define.DiffType) (string, error) { var lastErr error if diffType&define.DiffImage == define.DiffImage { - toImage, _, err := r.libimageRuntime.LookupImage(id, &libimage.LookupImageOptions{IgnorePlatform: true}) + toImage, _, err := r.libimageRuntime.LookupImage(id, nil) if err == nil { return toImage.TopLayer(), nil } diff --git a/libpod/network/network.go b/libpod/network/network.go index ed4e6388a..805988432 100644 --- a/libpod/network/network.go +++ b/libpod/network/network.go @@ -111,8 +111,10 @@ func allocatorToIPNets(networks []*allocator.Net) []*net.IPNet { if len(network.IPAM.Ranges) > 0 { // this is the new IPAM range style // append each subnet from ipam the rangeset - for _, r := range network.IPAM.Ranges[0] { - nets = append(nets, newIPNetFromSubnet(r.Subnet)) + for _, allocatorRange := range network.IPAM.Ranges { + for _, r := range allocatorRange { + nets = append(nets, newIPNetFromSubnet(r.Subnet)) + } } } else { // looks like the old, deprecated style diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 48b0c495c..0f3e03e06 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -108,7 +108,7 @@ func (r *Runtime) getPodNetwork(id, name, nsPath string, networks []string, port type RootlessCNI struct { ns ns.NetNS dir string - lock lockfile.Locker + Lock lockfile.Locker } // getPath will join the given path to the rootless cni dir @@ -177,6 +177,21 @@ func (r *RootlessCNI) Do(toRun func() error) error { if err != nil { return err } + logrus.Debugf("The actual path of /etc/resolv.conf on the host is %q", resolvePath) + // When /etc/resolv.conf on the host is a symlink to /run/systemd/resolve/stub-resolv.conf, + // we have to mount an empty filesystem on /run/systemd/resolve in the child namespace, + // so as to isolate the directory from the host mount namespace. + // + // Otherwise our bind-mount for /run/systemd/resolve/stub-resolv.conf is unmounted + // when systemd-resolved unlinks and recreates /run/systemd/resolve/stub-resolv.conf on the host. + // see: https://github.com/containers/podman/issues/10929 + if strings.HasPrefix(resolvePath, "/run/systemd/resolve/") { + rsr := r.getPath("/run/systemd/resolve") + err = unix.Mount("", rsr, "tmpfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, "") + if err != nil { + return errors.Wrapf(err, "failed to mount tmpfs on %q for rootless cni", rsr) + } + } if strings.HasPrefix(resolvePath, "/run/") { resolvePath = r.getPath(resolvePath) err = os.MkdirAll(filepath.Dir(resolvePath), 0700) @@ -234,16 +249,17 @@ func (r *RootlessCNI) Do(toRun func() error) error { return err } -// Cleanup the rootless cni namespace if needed -// check if we have running containers with the bridge network mode +// Cleanup the rootless cni namespace if needed. +// It checks if we have running containers with the bridge network mode. +// Cleanup() will try to lock RootlessCNI, therefore you have to call it with an unlocked func (r *RootlessCNI) Cleanup(runtime *Runtime) error { _, err := os.Stat(r.dir) if os.IsNotExist(err) { // the directory does not exists no need for cleanup return nil } - r.lock.Lock() - defer r.lock.Unlock() + r.Lock.Lock() + defer r.Lock.Unlock() running := func(c *Container) bool { // we cannot use c.state() because it will try to lock the container // using c.state.State directly should be good enough for this use case @@ -301,205 +317,216 @@ func (r *RootlessCNI) Cleanup(runtime *Runtime) error { // GetRootlessCNINetNs returns the rootless cni object. If create is set to true // the rootless cni namespace will be created if it does not exists already. +// If called as root it returns always nil. +// On success the returned RootlessCNI lock is locked and must be unlocked by the caller. func (r *Runtime) GetRootlessCNINetNs(new bool) (*RootlessCNI, error) { + if !rootless.IsRootless() { + return nil, nil + } var rootlessCNINS *RootlessCNI - if rootless.IsRootless() { - runDir, err := util.GetRuntimeDir() - if err != nil { - return nil, err + runDir, err := util.GetRuntimeDir() + if err != nil { + return nil, err + } + + lfile := filepath.Join(runDir, "rootless-cni.lock") + lock, err := lockfile.GetLockfile(lfile) + if err != nil { + return nil, errors.Wrap(err, "failed to get rootless-cni lockfile") + } + lock.Lock() + defer func() { + // In case of an error (early exit) rootlessCNINS will be nil. + // Make sure to unlock otherwise we could deadlock. + if rootlessCNINS == nil { + lock.Unlock() } - cniDir := filepath.Join(runDir, "rootless-cni") - err = os.MkdirAll(cniDir, 0700) + }() + + cniDir := filepath.Join(runDir, "rootless-cni") + err = os.MkdirAll(cniDir, 0700) + if err != nil { + return nil, errors.Wrap(err, "could not create rootless-cni directory") + } + + nsDir, err := netns.GetNSRunDir() + if err != nil { + return nil, err + } + path := filepath.Join(nsDir, rootlessCNINSName) + ns, err := ns.GetNS(path) + if err != nil { + if !new { + // return a error if we could not get the namespace and should no create one + return nil, errors.Wrap(err, "error getting rootless cni network namespace") + } + // create a new namespace + logrus.Debug("creating rootless cni network namespace") + ns, err = netns.NewNSWithName(rootlessCNINSName) if err != nil { - return nil, errors.Wrap(err, "could not create rootless-cni directory") + return nil, errors.Wrap(err, "error creating rootless cni network namespace") + } + // setup slirp4netns here + path := r.config.Engine.NetworkCmdPath + if path == "" { + var err error + path, err = exec.LookPath("slirp4netns") + if err != nil { + return nil, err + } } - lfile := filepath.Join(cniDir, "rootless-cni.lck") - lock, err := lockfile.GetLockfile(lfile) + syncR, syncW, err := os.Pipe() if err != nil { - return nil, errors.Wrap(err, "failed to get rootless-cni lockfile") + return nil, errors.Wrapf(err, "failed to open pipe") } - lock.Lock() - defer lock.Unlock() + defer errorhandling.CloseQuiet(syncR) + defer errorhandling.CloseQuiet(syncW) - nsDir, err := netns.GetNSRunDir() + netOptions, err := parseSlirp4netnsNetworkOptions(r, nil) if err != nil { return nil, err } - path := filepath.Join(nsDir, rootlessCNINSName) - ns, err := ns.GetNS(path) + slirpFeatures, err := checkSlirpFlags(path) if err != nil { - if new { - // create a new namespace - logrus.Debug("creating rootless cni network namespace") - ns, err = netns.NewNSWithName(rootlessCNINSName) - if err != nil { - return nil, errors.Wrap(err, "error creating rootless cni network namespace") - } - // setup slirp4netns here - path := r.config.Engine.NetworkCmdPath - if path == "" { - var err error - path, err = exec.LookPath("slirp4netns") - if err != nil { - return nil, err - } - } - - syncR, syncW, err := os.Pipe() - if err != nil { - return nil, errors.Wrapf(err, "failed to open pipe") - } - defer errorhandling.CloseQuiet(syncR) - defer errorhandling.CloseQuiet(syncW) - - netOptions, err := parseSlirp4netnsNetworkOptions(r, nil) - if err != nil { - return nil, err - } - slirpFeatures, err := checkSlirpFlags(path) - if err != nil { - return nil, errors.Wrapf(err, "error checking slirp4netns binary %s: %q", path, err) - } - cmdArgs, err := createBasicSlirp4netnsCmdArgs(netOptions, slirpFeatures) - if err != nil { - return nil, err - } - // Note we do not use --exit-fd, we kill this process by pid - cmdArgs = append(cmdArgs, "-c", "-r", "3") - cmdArgs = append(cmdArgs, "--netns-type=path", ns.Path(), "tap0") - - cmd := exec.Command(path, cmdArgs...) - logrus.Debugf("slirp4netns command: %s", strings.Join(cmd.Args, " ")) - cmd.SysProcAttr = &syscall.SysProcAttr{ - Setpgid: true, - } - - // workaround for https://github.com/rootless-containers/slirp4netns/pull/153 - if !netOptions.noPivotRoot && slirpFeatures.HasEnableSandbox { - cmd.SysProcAttr.Cloneflags = syscall.CLONE_NEWNS - cmd.SysProcAttr.Unshareflags = syscall.CLONE_NEWNS - } - - // Leak one end of the pipe in slirp4netns - cmd.ExtraFiles = append(cmd.ExtraFiles, syncW) + return nil, errors.Wrapf(err, "error checking slirp4netns binary %s: %q", path, err) + } + cmdArgs, err := createBasicSlirp4netnsCmdArgs(netOptions, slirpFeatures) + if err != nil { + return nil, err + } + // Note we do not use --exit-fd, we kill this process by pid + cmdArgs = append(cmdArgs, "-c", "-r", "3") + cmdArgs = append(cmdArgs, "--netns-type=path", ns.Path(), "tap0") + + cmd := exec.Command(path, cmdArgs...) + logrus.Debugf("slirp4netns command: %s", strings.Join(cmd.Args, " ")) + cmd.SysProcAttr = &syscall.SysProcAttr{ + Setpgid: true, + } - logPath := filepath.Join(r.config.Engine.TmpDir, "slirp4netns-rootless-cni.log") - logFile, err := os.Create(logPath) - if err != nil { - return nil, errors.Wrapf(err, "failed to open slirp4netns log file %s", logPath) - } - defer logFile.Close() - // Unlink immediately the file so we won't need to worry about cleaning it up later. - // It is still accessible through the open fd logFile. - if err := os.Remove(logPath); err != nil { - return nil, errors.Wrapf(err, "delete file %s", logPath) - } - cmd.Stdout = logFile - cmd.Stderr = logFile - if err := cmd.Start(); err != nil { - return nil, errors.Wrapf(err, "failed to start slirp4netns process") - } - // create pid file for the slirp4netns process - // this is need to kill the process in the cleanup - pid := strconv.Itoa(cmd.Process.Pid) - err = ioutil.WriteFile(filepath.Join(cniDir, "rootless-cni-slirp4netns.pid"), []byte(pid), 0700) - if err != nil { - errors.Wrap(err, "unable to write rootless-cni slirp4netns pid file") - } + // workaround for https://github.com/rootless-containers/slirp4netns/pull/153 + if !netOptions.noPivotRoot && slirpFeatures.HasEnableSandbox { + cmd.SysProcAttr.Cloneflags = syscall.CLONE_NEWNS + cmd.SysProcAttr.Unshareflags = syscall.CLONE_NEWNS + } - defer func() { - if err := cmd.Process.Release(); err != nil { - logrus.Errorf("unable to release command process: %q", err) - } - }() + // Leak one end of the pipe in slirp4netns + cmd.ExtraFiles = append(cmd.ExtraFiles, syncW) - if err := waitForSync(syncR, cmd, logFile, 1*time.Second); err != nil { - return nil, err - } + logPath := filepath.Join(r.config.Engine.TmpDir, "slirp4netns-rootless-cni.log") + logFile, err := os.Create(logPath) + if err != nil { + return nil, errors.Wrapf(err, "failed to open slirp4netns log file %s", logPath) + } + defer logFile.Close() + // Unlink immediately the file so we won't need to worry about cleaning it up later. + // It is still accessible through the open fd logFile. + if err := os.Remove(logPath); err != nil { + return nil, errors.Wrapf(err, "delete file %s", logPath) + } + cmd.Stdout = logFile + cmd.Stderr = logFile + if err := cmd.Start(); err != nil { + return nil, errors.Wrapf(err, "failed to start slirp4netns process") + } + // create pid file for the slirp4netns process + // this is need to kill the process in the cleanup + pid := strconv.Itoa(cmd.Process.Pid) + err = ioutil.WriteFile(filepath.Join(cniDir, "rootless-cni-slirp4netns.pid"), []byte(pid), 0700) + if err != nil { + errors.Wrap(err, "unable to write rootless-cni slirp4netns pid file") + } - // build a new resolv.conf file which uses the slirp4netns dns server address - resolveIP, err := GetSlirp4netnsDNS(nil) - if err != nil { - return nil, errors.Wrap(err, "failed to determine default slirp4netns DNS address") - } + defer func() { + if err := cmd.Process.Release(); err != nil { + logrus.Errorf("unable to release command process: %q", err) + } + }() - if netOptions.cidr != "" { - _, cidr, err := net.ParseCIDR(netOptions.cidr) - if err != nil { - return nil, errors.Wrap(err, "failed to parse slirp4netns cidr") - } - resolveIP, err = GetSlirp4netnsDNS(cidr) - if err != nil { - return nil, errors.Wrapf(err, "failed to determine slirp4netns DNS address from cidr: %s", cidr.String()) - } - } - conf, err := resolvconf.Get() - if err != nil { - return nil, err - } - conf, err = resolvconf.FilterResolvDNS(conf.Content, netOptions.enableIPv6, true) - if err != nil { - return nil, err - } - searchDomains := resolvconf.GetSearchDomains(conf.Content) - dnsOptions := resolvconf.GetOptions(conf.Content) - nameServers := resolvconf.GetNameservers(conf.Content) + if err := waitForSync(syncR, cmd, logFile, 1*time.Second); err != nil { + return nil, err + } - _, err = resolvconf.Build(filepath.Join(cniDir, "resolv.conf"), append([]string{resolveIP.String()}, nameServers...), searchDomains, dnsOptions) - if err != nil { - return nil, errors.Wrap(err, "failed to create rootless cni resolv.conf") - } + // build a new resolv.conf file which uses the slirp4netns dns server address + resolveIP, err := GetSlirp4netnsDNS(nil) + if err != nil { + return nil, errors.Wrap(err, "failed to determine default slirp4netns DNS address") + } - // create cni directories to store files - // they will be bind mounted to the correct location in a extra mount ns - err = os.MkdirAll(filepath.Join(cniDir, strings.TrimPrefix(persistentCNIDir, "/")), 0700) - if err != nil { - return nil, errors.Wrap(err, "could not create rootless-cni var directory") - } - runDir := filepath.Join(cniDir, "run") - err = os.MkdirAll(runDir, 0700) - if err != nil { - return nil, errors.Wrap(err, "could not create rootless-cni run directory") - } - // relabel the new run directory to the iptables /run label - // this is important, otherwise the iptables command will fail - err = label.Relabel(runDir, "system_u:object_r:iptables_var_run_t:s0", false) - if err != nil { - return nil, errors.Wrap(err, "could not create relabel rootless-cni run directory") - } - // create systemd run directory - err = os.MkdirAll(filepath.Join(runDir, "systemd"), 0700) - if err != nil { - return nil, errors.Wrap(err, "could not create rootless-cni systemd directory") - } - // create the directory for the netns files at the same location - // relative to the rootless-cni location - err = os.MkdirAll(filepath.Join(cniDir, nsDir), 0700) - if err != nil { - return nil, errors.Wrap(err, "could not create rootless-cni netns directory") - } - } else { - // return a error if we could not get the namespace and should no create one - return nil, errors.Wrap(err, "error getting rootless cni network namespace") + if netOptions.cidr != "" { + _, cidr, err := net.ParseCIDR(netOptions.cidr) + if err != nil { + return nil, errors.Wrap(err, "failed to parse slirp4netns cidr") + } + resolveIP, err = GetSlirp4netnsDNS(cidr) + if err != nil { + return nil, errors.Wrapf(err, "failed to determine slirp4netns DNS address from cidr: %s", cidr.String()) } } + conf, err := resolvconf.Get() + if err != nil { + return nil, err + } + conf, err = resolvconf.FilterResolvDNS(conf.Content, netOptions.enableIPv6, true) + if err != nil { + return nil, err + } + searchDomains := resolvconf.GetSearchDomains(conf.Content) + dnsOptions := resolvconf.GetOptions(conf.Content) + nameServers := resolvconf.GetNameservers(conf.Content) - // The CNI plugins need access to iptables in $PATH. As it turns out debian doesn't put - // /usr/sbin in $PATH for rootless users. This will break rootless cni completely. - // We might break existing users and we cannot expect everyone to change their $PATH so - // lets add /usr/sbin to $PATH ourselves. - path = os.Getenv("PATH") - if !strings.Contains(path, "/usr/sbin") { - path = path + ":/usr/sbin" - os.Setenv("PATH", path) + _, err = resolvconf.Build(filepath.Join(cniDir, "resolv.conf"), append([]string{resolveIP.String()}, nameServers...), searchDomains, dnsOptions) + if err != nil { + return nil, errors.Wrap(err, "failed to create rootless cni resolv.conf") } - rootlessCNINS = &RootlessCNI{ - ns: ns, - dir: cniDir, - lock: lock, + // create cni directories to store files + // they will be bind mounted to the correct location in a extra mount ns + err = os.MkdirAll(filepath.Join(cniDir, strings.TrimPrefix(persistentCNIDir, "/")), 0700) + if err != nil { + return nil, errors.Wrap(err, "could not create rootless-cni var directory") + } + runDir := filepath.Join(cniDir, "run") + err = os.MkdirAll(runDir, 0700) + if err != nil { + return nil, errors.Wrap(err, "could not create rootless-cni run directory") + } + // relabel the new run directory to the iptables /run label + // this is important, otherwise the iptables command will fail + err = label.Relabel(runDir, "system_u:object_r:iptables_var_run_t:s0", false) + if err != nil { + return nil, errors.Wrap(err, "could not create relabel rootless-cni run directory") + } + // create systemd run directory + err = os.MkdirAll(filepath.Join(runDir, "systemd"), 0700) + if err != nil { + return nil, errors.Wrap(err, "could not create rootless-cni systemd directory") } + // create the directory for the netns files at the same location + // relative to the rootless-cni location + err = os.MkdirAll(filepath.Join(cniDir, nsDir), 0700) + if err != nil { + return nil, errors.Wrap(err, "could not create rootless-cni netns directory") + } + } + + // The CNI plugins need access to iptables in $PATH. As it turns out debian doesn't put + // /usr/sbin in $PATH for rootless users. This will break rootless cni completely. + // We might break existing users and we cannot expect everyone to change their $PATH so + // lets add /usr/sbin to $PATH ourselves. + path = os.Getenv("PATH") + if !strings.Contains(path, "/usr/sbin") { + path = path + ":/usr/sbin" + os.Setenv("PATH", path) + } + + // Important set rootlessCNINS as last step. + // Do not return any errors after this. + rootlessCNINS = &RootlessCNI{ + ns: ns, + dir: cniDir, + Lock: lock, } return rootlessCNINS, nil } @@ -548,9 +575,8 @@ func (r *Runtime) setUpOCICNIPod(podNetwork ocicni.PodNetwork) ([]ocicni.NetResu // rootlessCNINS is nil if we are root if rootlessCNINS != nil { // execute the cni setup in the rootless net ns - rootlessCNINS.lock.Lock() err = rootlessCNINS.Do(setUpPod) - rootlessCNINS.lock.Unlock() + rootlessCNINS.Lock.Unlock() } else { err = setUpPod() } @@ -762,9 +788,8 @@ func (r *Runtime) teardownOCICNIPod(podNetwork ocicni.PodNetwork) error { // rootlessCNINS is nil if we are root if rootlessCNINS != nil { // execute the cni setup in the rootless net ns - rootlessCNINS.lock.Lock() err = rootlessCNINS.Do(tearDownPod) - rootlessCNINS.lock.Unlock() + rootlessCNINS.Lock.Unlock() if err == nil { err = rootlessCNINS.Cleanup(r) } diff --git a/libpod/oci_conmon_exec_linux.go b/libpod/oci_conmon_exec_linux.go index 09d3d1833..05a4e19b0 100644 --- a/libpod/oci_conmon_exec_linux.go +++ b/libpod/oci_conmon_exec_linux.go @@ -610,6 +610,9 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp _, err := utils.CopyDetachable(conn, httpBuf, detachKeys) logrus.Debugf("STDIN copy completed") stdinChan <- err + if connErr := conn.CloseWrite(); connErr != nil { + logrus.Errorf("Unable to close conn: %v", connErr) + } }() } diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index 2914bd1a1..846d3815a 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -1064,6 +1064,30 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co if restoreOptions.TCPEstablished { args = append(args, "--runtime-opt", "--tcp-established") } + if restoreOptions.Pod != "" { + mountLabel := ctr.config.MountLabel + processLabel := ctr.config.ProcessLabel + if mountLabel != "" { + args = append( + args, + "--runtime-opt", + fmt.Sprintf( + "--lsm-mount-context=%s", + mountLabel, + ), + ) + } + if processLabel != "" { + args = append( + args, + "--runtime-opt", + fmt.Sprintf( + "--lsm-profile=selinux:%s", + processLabel, + ), + ) + } + } } logrus.WithFields(logrus.Fields{ diff --git a/libpod/options.go b/libpod/options.go index b12153512..17a36008d 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -16,6 +16,7 @@ import ( "github.com/containers/podman/v3/libpod/events" "github.com/containers/podman/v3/pkg/namespaces" "github.com/containers/podman/v3/pkg/rootless" + "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/util" "github.com/containers/storage" "github.com/containers/storage/pkg/idtools" @@ -458,6 +459,19 @@ func WithDefaultInfraCommand(cmd string) RuntimeOption { } } +// WithDefaultInfraName sets the infra container name for a single pod. +func WithDefaultInfraName(name string) RuntimeOption { + return func(rt *Runtime) error { + if rt.valid { + return define.ErrRuntimeFinalized + } + + rt.config.Engine.InfraImage = name + + return nil + } +} + // WithRenumber instructs libpod to perform a lock renumbering while // initializing. This will handle migrations from early versions of libpod with // file locks to newer versions with SHM locking, as well as changes in the @@ -1786,6 +1800,19 @@ func WithInfraCommand(cmd []string) PodCreateOption { } } +// WithInfraName sets the infra container name for a single pod. +func WithInfraName(name string) PodCreateOption { + return func(pod *Pod) error { + if pod.valid { + return define.ErrPodFinalized + } + + pod.config.InfraContainer.InfraName = name + + return nil + } +} + // WithPodName sets the name of the pod. func WithPodName(name string) PodCreateOption { return func(pod *Pod) error { @@ -2397,3 +2424,22 @@ func WithPodCPUSetCPUs(inp string) PodCreateOption { return nil } } + +func WithPodPidNS(inp specgen.Namespace) PodCreateOption { + return func(p *Pod) error { + if p.valid { + return define.ErrPodFinalized + } + if p.config.UsePodPID { + switch inp.NSMode { + case "container": + return errors.Wrap(define.ErrInvalidArg, "Cannot take container in a different NS as an argument") + case "host": + p.config.UsePodPID = false + } + p.config.InfraContainer.PidNS = inp + } + + return nil + } +} diff --git a/libpod/pod.go b/libpod/pod.go index d7a9b15d9..62f5c9e5b 100644 --- a/libpod/pod.go +++ b/libpod/pod.go @@ -7,6 +7,7 @@ import ( "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/lock" + "github.com/containers/podman/v3/pkg/specgen" "github.com/cri-o/ocicni/pkg/ocicni" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -97,6 +98,7 @@ type InfraContainerConfig struct { HasInfraContainer bool `json:"makeInfraContainer"` NoNetwork bool `json:"noNetwork,omitempty"` HostNetwork bool `json:"infraHostNetwork,omitempty"` + PidNS specgen.Namespace `json:"infraPid,omitempty"` PortBindings []ocicni.PortMapping `json:"infraPortBindings"` StaticIP net.IP `json:"staticIP,omitempty"` StaticMAC net.HardwareAddr `json:"staticMAC,omitempty"` @@ -110,6 +112,7 @@ type InfraContainerConfig struct { ExitCommand []string `json:"exitCommand,omitempty"` InfraImage string `json:"infraImage,omitempty"` InfraCommand []string `json:"infraCommand,omitempty"` + InfraName string `json:"infraName,omitempty"` Slirp4netns bool `json:"slirp4netns,omitempty"` NetworkOptions map[string][]string `json:"network_options,omitempty"` ResourceLimits *specs.LinuxResources `json:"resource_limits,omitempty"` @@ -170,6 +173,11 @@ func (p *Pod) CPUQuota() int64 { return 0 } +// PidMode returns the PID mode given by the user ex: pod, private... +func (p *Pod) PidMode() string { + return string(p.config.InfraContainer.PidNS.NSMode) +} + // Labels returns the pod's labels func (p *Pod) Labels() map[string]string { labels := make(map[string]string) diff --git a/libpod/pod_api.go b/libpod/pod_api.go index d8f5d15f8..1ab012a8b 100644 --- a/libpod/pod_api.go +++ b/libpod/pod_api.go @@ -541,6 +541,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) { infraConfig.CPUPeriod = p.CPUPeriod() infraConfig.CPUQuota = p.CPUQuota() infraConfig.CPUSetCPUs = p.ResourceLim().CPU.Cpus + infraConfig.PidNS = p.PidMode() if len(p.config.InfraContainer.DNSServer) > 0 { infraConfig.DNSServer = make([]string, 0, len(p.config.InfraContainer.DNSServer)) diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 6c69d1b72..ce4c5d758 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -47,6 +47,32 @@ func (r *Runtime) NewContainer(ctx context.Context, rSpec *spec.Spec, options .. return r.newContainer(ctx, rSpec, options...) } +func (r *Runtime) PrepareVolumeOnCreateContainer(ctx context.Context, ctr *Container) error { + // Copy the content from the underlying image into the newly created + // volume if configured to do so. + if !r.config.Containers.PrepareVolumeOnCreate { + return nil + } + + defer func() { + if err := ctr.cleanupStorage(); err != nil { + logrus.Errorf("error cleaning up container storage %s: %v", ctr.ID(), err) + } + }() + + mountPoint, err := ctr.mountStorage() + if err == nil { + // Finish up mountStorage + ctr.state.Mounted = true + ctr.state.Mountpoint = mountPoint + if err = ctr.save(); err != nil { + logrus.Errorf("Error saving container %s state: %v", ctr.ID(), err) + } + } + + return err +} + // RestoreContainer re-creates a container from an imported checkpoint func (r *Runtime) RestoreContainer(ctx context.Context, rSpec *spec.Spec, config *ContainerConfig) (*Container, error) { r.lock.Lock() diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go index 6b002f65a..d4f861118 100644 --- a/libpod/runtime_pod_infra_linux.go +++ b/libpod/runtime_pod_infra_linux.go @@ -145,6 +145,18 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm if len(p.config.InfraContainer.ExitCommand) > 0 { options = append(options, WithExitCommand(p.config.InfraContainer.ExitCommand)) } + + if p.config.UsePodPID && p.config.InfraContainer.PidNS.NSMode != "host" { + g.AddOrReplaceLinuxNamespace(string(spec.LinuxNamespaceType("pid")), p.config.InfraContainer.PidNS.Value) + } else if p.config.InfraContainer.PidNS.NSMode == "host" { + newNS := []spec.LinuxNamespace{} + for _, entry := range g.Config.Linux.Namespaces { + if entry.Type != spec.LinuxNamespaceType("pid") { + newNS = append(newNS, entry) + } + } + g.Config.Linux.Namespaces = newNS + } } g.SetRootReadonly(true) g.SetProcessArgs(infraCtrCommand) @@ -189,7 +201,11 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm g.AddLinuxSysctl(sysctlKey, sysctlVal) } - containerName := p.ID()[:IDTruncLength] + "-infra" + containerName := p.config.InfraContainer.InfraName + if containerName == "" { + containerName = p.ID()[:IDTruncLength] + "-infra" + } + logrus.Infof("Infra container name %s", containerName) options = append(options, r.WithPod(p)) options = append(options, WithRootFSFromImage(imgID, imgName, rawImageName)) options = append(options, WithName(containerName)) diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go index 4ede23cac..fce3f38a7 100644 --- a/libpod/runtime_pod_linux.go +++ b/libpod/runtime_pod_linux.go @@ -116,6 +116,7 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po if pod.config.UsePodCgroup { logrus.Debugf("Got pod cgroup as %s", pod.state.CgroupPath) } + if !pod.HasInfraContainer() && pod.SharesNamespaces() { return nil, errors.Errorf("Pods must have an infra container to share namespaces") } diff --git a/nix/default-arm64.nix b/nix/default-arm64.nix index d29f75520..8868788ae 100644 --- a/nix/default-arm64.nix +++ b/nix/default-arm64.nix @@ -30,8 +30,10 @@ let "--enable-confdir=/etc" "--enable-usbdropdir=/var/lib/pcsc/drivers" "--disable-libsystemd" + "--disable-libudev" + "--disable-libusb" ]; - buildInputs = [ pkgs.python3 pkgs.udev pkgs.dbus pkgs.systemd ]; + buildInputs = [ pkgs.python3 pkgs.dbus ]; }); systemd = (static pkg.systemd).overrideAttrs (x: { outputs = [ "out" "dev" ]; @@ -69,6 +71,7 @@ let export LDFLAGS='-s -w -static-libgcc -static' export EXTRA_LDFLAGS='-s -w -linkmode external -extldflags "-static -lm"' export BUILDTAGS='static netgo osusergo exclude_graphdriver_btrfs exclude_graphdriver_devicemapper seccomp apparmor selinux' + export CGO_ENABLED=1 ''; buildPhase = '' patchShebangs . diff --git a/nix/default.nix b/nix/default.nix index f6194e3d9..4d15532c2 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -27,9 +27,11 @@ let configureFlags = [ "--enable-confdir=/etc" "--enable-usbdropdir=/var/lib/pcsc/drivers" - "--with-systemdsystemunitdir=${placeholder "bin"}/lib/systemd/system" + "--disable-libsystemd" + "--disable-libudev" + "--disable-libusb" ]; - buildInputs = [ pkgs.python3 pkgs.udev pkgs.dbus pkgs.systemd ]; + buildInputs = [ pkgs.python3 pkgs.dbus ]; }); systemd = (static pkg.systemd).overrideAttrs (x: { outputs = [ "out" "dev" ]; @@ -67,6 +69,7 @@ let export LDFLAGS='-s -w -static-libgcc -static' export EXTRA_LDFLAGS='-s -w -linkmode external -extldflags "-static -lm"' export BUILDTAGS='static netgo osusergo exclude_graphdriver_btrfs exclude_graphdriver_devicemapper seccomp apparmor selinux' + export CGO_ENABLED=1 ''; buildPhase = '' patchShebangs . diff --git a/nix/nixpkgs.json b/nix/nixpkgs.json index a9771eade..efcfe202e 100644 --- a/nix/nixpkgs.json +++ b/nix/nixpkgs.json @@ -1,9 +1,9 @@ { "url": "https://github.com/nixos/nixpkgs", - "rev": "60cce7e5e1fdf62421ef6d4184ee399b46209366", - "date": "2021-06-09T01:18:50-04:00", - "path": "/nix/store/fixgn194626rb7gf99l9jaqm0hbqn2ix-nixpkgs", - "sha256": "100xrb925cana1kfd0c7gwkjjalq891vfgr0rn1gl9j8gp3l3gx6", + "rev": "2a96414d7e350160a33ed0978449c9ff5b5a6eb3", + "date": "2021-07-13T18:21:47+02:00", + "path": "/nix/store/2ai9q8ac6vxb2rrngdz82y8jxnk15cvm-nixpkgs", + "sha256": "1dzrfqdjq3yq5jjskiqflzy58l2xx6059gay9p1k07zrlm1wigy5", "fetchSubmodules": false, "deepClone": false, "leaveDotGit": false diff --git a/pkg/api/handlers/compat/containers_archive.go b/pkg/api/handlers/compat/containers_archive.go index a9d74e5f4..541f702e7 100644 --- a/pkg/api/handlers/compat/containers_archive.go +++ b/pkg/api/handlers/compat/containers_archive.go @@ -1,6 +1,7 @@ package compat import ( + "encoding/json" "fmt" "net/http" "os" @@ -93,8 +94,9 @@ func handleHeadAndGet(w http.ResponseWriter, r *http.Request, decoder *schema.De func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder, runtime *libpod.Runtime) { query := struct { - Path string `schema:"path"` - Chown bool `schema:"copyUIDGID"` + Path string `schema:"path"` + Chown bool `schema:"copyUIDGID"` + Rename string `schema:"rename"` // TODO handle params below NoOverwriteDirNonDir bool `schema:"noOverwriteDirNonDir"` }{ @@ -107,10 +109,19 @@ func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder, return } + var rename map[string]string + if query.Rename != "" { + if err := json.Unmarshal([]byte(query.Rename), &rename); err != nil { + utils.Error(w, "Bad Request.", http.StatusBadRequest, errors.Wrap(err, "couldn't decode the query")) + return + } + } + containerName := utils.GetName(r) containerEngine := abi.ContainerEngine{Libpod: runtime} - copyFunc, err := containerEngine.ContainerCopyFromArchive(r.Context(), containerName, query.Path, r.Body, entities.CopyOptions{Chown: query.Chown}) + copyOptions := entities.CopyOptions{Chown: query.Chown, Rename: rename} + copyFunc, err := containerEngine.ContainerCopyFromArchive(r.Context(), containerName, query.Path, r.Body, copyOptions) if errors.Cause(err) == define.ErrNoSuchCtr || os.IsNotExist(err) { // 404 is returned for an absent container and path. The // clients must deal with it accordingly. diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index 7baa1145a..6f8fb21f0 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -266,41 +266,26 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { } defer auth.RemoveAuthfile(authfile) - platformSpecs := strings.Split(query.Platform, "/") // split query into its parts - - addOS := true // default assume true due to structure of if/else below - addArch := false - addVariant := false - - if len(platformSpecs) > 1 { // if we have two arguments then we have os and arch - addArch = true - if len(platformSpecs) > 2 { // if we have 3 arguments then we have os arch and variant - addVariant = true - } - } else if len(platformSpecs) == 0 { - addOS = false - } - pullOptions := &libimage.PullOptions{} pullOptions.AuthFilePath = authfile if authConf != nil { pullOptions.Username = authConf.Username pullOptions.Password = authConf.Password pullOptions.IdentityToken = authConf.IdentityToken - if addOS { // if the len is not 0 - pullOptions.OS = platformSpecs[0] - if addArch { - pullOptions.Architecture = platformSpecs[1] - } - if addVariant { - pullOptions.Variant = platformSpecs[2] - } - } } pullOptions.Writer = os.Stderr // allows for debugging on the server - progress := make(chan types.ProgressProperties) + // Handle the platform. + platformSpecs := strings.Split(query.Platform, "/") + pullOptions.OS = platformSpecs[0] // may be empty + if len(platformSpecs) > 1 { + pullOptions.Architecture = platformSpecs[1] + if len(platformSpecs) > 2 { + pullOptions.Variant = platformSpecs[2] + } + } + progress := make(chan types.ProgressProperties) pullOptions.Progress = progress pullResChan := make(chan pullResult) diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index 64805b7fa..2c98a5361 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -393,16 +393,16 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { defer auth.RemoveAuthfile(authfile) // Channels all mux'ed in select{} below to follow API build protocol - stdout := channel.NewWriter(make(chan []byte, 1)) + stdout := channel.NewWriter(make(chan []byte)) defer stdout.Close() - auxout := channel.NewWriter(make(chan []byte, 1)) + auxout := channel.NewWriter(make(chan []byte)) defer auxout.Close() - stderr := channel.NewWriter(make(chan []byte, 1)) + stderr := channel.NewWriter(make(chan []byte)) defer stderr.Close() - reporter := channel.NewWriter(make(chan []byte, 1)) + reporter := channel.NewWriter(make(chan []byte)) defer reporter.Close() runtime := r.Context().Value("runtime").(*libpod.Runtime) @@ -529,7 +529,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { enc := json.NewEncoder(body) enc.SetEscapeHTML(true) -loop: + for { m := struct { Stream string `json:"stream,omitempty"` @@ -543,13 +543,13 @@ loop: stderr.Write([]byte(err.Error())) } flush() - case e := <-auxout.Chan(): + case e := <-reporter.Chan(): m.Stream = string(e) if err := enc.Encode(m); err != nil { stderr.Write([]byte(err.Error())) } flush() - case e := <-reporter.Chan(): + case e := <-auxout.Chan(): m.Stream = string(e) if err := enc.Encode(m); err != nil { stderr.Write([]byte(err.Error())) @@ -561,8 +561,8 @@ loop: logrus.Warnf("Failed to json encode error %v", err) } flush() + return case <-runCtx.Done(): - flush() if success { if !utils.IsLibpodRequest(r) { m.Stream = fmt.Sprintf("Successfully built %12.12s\n", imageID) @@ -579,7 +579,8 @@ loop: } } } - break loop + flush() + return case <-r.Context().Done(): cancel() logrus.Infof("Client disconnect reported for build %q / %q.", registry, query.Dockerfile) diff --git a/pkg/api/handlers/compat/images_history.go b/pkg/api/handlers/compat/images_history.go index ea596890f..54c893f47 100644 --- a/pkg/api/handlers/compat/images_history.go +++ b/pkg/api/handlers/compat/images_history.go @@ -3,7 +3,6 @@ package compat import ( "net/http" - "github.com/containers/common/libimage" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/pkg/api/handlers" "github.com/containers/podman/v3/pkg/api/handlers/utils" @@ -14,8 +13,7 @@ func HistoryImage(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) name := utils.GetName(r) - lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true} - newImage, _, err := runtime.LibimageRuntime().LookupImage(name, lookupOptions) + newImage, _, err := runtime.LibimageRuntime().LookupImage(name, nil) if err != nil { utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "failed to find image %s", name)) return diff --git a/pkg/api/handlers/compat/images_tag.go b/pkg/api/handlers/compat/images_tag.go index 8d256f4fa..199ad0488 100644 --- a/pkg/api/handlers/compat/images_tag.go +++ b/pkg/api/handlers/compat/images_tag.go @@ -4,7 +4,6 @@ import ( "fmt" "net/http" - "github.com/containers/common/libimage" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/pkg/api/handlers/utils" "github.com/pkg/errors" @@ -16,8 +15,7 @@ func TagImage(w http.ResponseWriter, r *http.Request) { // /v1.xx/images/(name)/tag name := utils.GetName(r) - lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true} - newImage, _, err := runtime.LibimageRuntime().LookupImage(name, lookupOptions) + newImage, _, err := runtime.LibimageRuntime().LookupImage(name, nil) if err != nil { utils.ImageNotFound(w, name, errors.Wrapf(err, "failed to find image %s", name)) return diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go index 4e1f31404..b990a916b 100644 --- a/pkg/api/handlers/compat/networks.go +++ b/pkg/api/handlers/compat/networks.go @@ -25,6 +25,12 @@ import ( "github.com/sirupsen/logrus" ) +type pluginInterface struct { + PluginType string `json:"type"` + IPAM network.IPAMConfig `json:"ipam"` + IsGW bool `json:"isGateway"` +} + func InspectNetwork(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) @@ -103,12 +109,12 @@ func getNetworkResourceByNameOrID(nameOrID string, runtime *libpod.Runtime, filt } } - // No Bridge plugin means we bail - bridge, err := genericPluginsToBridge(conf.Plugins, network.DefaultNetworkDriver) + plugin, err := getPlugin(conf.Plugins) if err != nil { return nil, err } - for _, outer := range bridge.IPAM.Ranges { + + for _, outer := range plugin.IPAM.Ranges { for _, n := range outer { ipamConfig := dockerNetwork.IPAMConfig{ Subnet: n.Subnet, @@ -140,19 +146,26 @@ func getNetworkResourceByNameOrID(nameOrID string, runtime *libpod.Runtime, filt labels = map[string]string{} } + isInternal := false + dockerDriver := plugin.PluginType + if plugin.PluginType == network.DefaultNetworkDriver { + isInternal = !plugin.IsGW + dockerDriver = "default" + } + report := types.NetworkResource{ Name: conf.Name, ID: networkid.GetNetworkID(conf.Name), Created: time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec)), // nolint: unconvert Scope: "local", - Driver: network.DefaultNetworkDriver, + Driver: plugin.PluginType, EnableIPv6: false, IPAM: dockerNetwork.IPAM{ - Driver: "default", + Driver: dockerDriver, Options: map[string]string{}, Config: ipamConfigs, }, - Internal: !bridge.IsGW, + Internal: isInternal, Attachable: false, Ingress: false, ConfigFrom: dockerNetwork.ConfigReference{}, @@ -166,23 +179,19 @@ func getNetworkResourceByNameOrID(nameOrID string, runtime *libpod.Runtime, filt return &report, nil } -func genericPluginsToBridge(plugins []*libcni.NetworkConfig, pluginType string) (network.HostLocalBridge, error) { - var bridge network.HostLocalBridge - generic, err := findPluginByName(plugins, pluginType) - if err != nil { - return bridge, err - } - err = json.Unmarshal(generic, &bridge) - return bridge, err -} +func getPlugin(plugins []*libcni.NetworkConfig) (pluginInterface, error) { + var plugin pluginInterface -func findPluginByName(plugins []*libcni.NetworkConfig, pluginType string) ([]byte, error) { for _, p := range plugins { - if pluginType == p.Network.Type { - return p.Bytes, nil + for _, pluginType := range network.SupportedNetworkDrivers { + if pluginType == p.Network.Type { + err := json.Unmarshal(p.Bytes, &plugin) + return plugin, err + } } } - return nil, errors.New("unable to find bridge plugin") + + return plugin, errors.New("unable to find supported plugin") } func ListNetworks(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/api/handlers/libpod/containers_create.go b/pkg/api/handlers/libpod/containers_create.go index b92588346..65951861b 100644 --- a/pkg/api/handlers/libpod/containers_create.go +++ b/pkg/api/handlers/libpod/containers_create.go @@ -22,6 +22,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) return } + warn, err := generate.CompleteSpec(r.Context(), runtime, &sg) if err != nil { utils.InternalServerError(w, err) diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index fc6ab4b4c..d759f4824 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -11,7 +11,6 @@ import ( "strings" "github.com/containers/buildah" - "github.com/containers/common/libimage" "github.com/containers/common/pkg/filters" "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/types" @@ -215,8 +214,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) { } name := utils.GetName(r) - lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true} - if _, _, err := runtime.LibimageRuntime().LookupImage(name, lookupOptions); err != nil { + if _, _, err := runtime.LibimageRuntime().LookupImage(name, nil); err != nil { utils.ImageNotFound(w, name, err) return } diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go index 59f948567..af5878798 100644 --- a/pkg/api/handlers/types.go +++ b/pkg/api/handlers/types.go @@ -133,6 +133,7 @@ type PodCreateConfig struct { Infra bool `json:"infra"` InfraCommand string `json:"infra-command"` InfraImage string `json:"infra-image"` + InfraName string `json:"infra-name"` Labels []string `json:"labels"` Publish []string `json:"publish"` Share string `json:"share"` @@ -175,6 +176,11 @@ func ImageToImageSummary(l *libimage.Image) (*entities.ImageSummary, error) { } containerCount := len(containers) + isDangling, err := l.IsDangling(context.TODO()) + if err != nil { + return nil, errors.Wrapf(err, "failed to check if image %s is dangling", l.ID()) + } + is := entities.ImageSummary{ ID: l.ID(), ParentId: imageData.Parent, @@ -187,7 +193,7 @@ func ImageToImageSummary(l *libimage.Image) (*entities.ImageSummary, error) { Labels: imageData.Labels, Containers: containerCount, ReadOnly: l.IsReadOnly(), - Dangling: l.IsDangling(), + Dangling: isDangling, Names: l.Names(), Digest: string(imageData.Digest), ConfigDigest: "", // TODO: libpod/image didn't set it but libimage should diff --git a/pkg/api/handlers/utils/images.go b/pkg/api/handlers/utils/images.go index 2a1908d63..1e8edb6dd 100644 --- a/pkg/api/handlers/utils/images.go +++ b/pkg/api/handlers/utils/images.go @@ -88,8 +88,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) ([]*libimage.Image, error func GetImage(r *http.Request, name string) (*libimage.Image, error) { runtime := r.Context().Value("runtime").(*libpod.Runtime) - lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true} - image, _, err := runtime.LibimageRuntime().LookupImage(name, lookupOptions) + image, _, err := runtime.LibimageRuntime().LookupImage(name, nil) if err != nil { return nil, err } diff --git a/pkg/api/server/docs.go b/pkg/api/server/docs.go index e72b78221..bf15afbf9 100644 --- a/pkg/api/server/docs.go +++ b/pkg/api/server/docs.go @@ -42,7 +42,7 @@ // // InfoExtensions: // x-logo: -// - url: https://raw.githubusercontent.com/containers/libpod/master/logo/podman-logo.png +// - url: https://raw.githubusercontent.com/containers/libpod/main/logo/podman-logo.png // - altText: "Podman logo" // // Produces: diff --git a/pkg/api/server/register_archive.go b/pkg/api/server/register_archive.go index ee7449fbb..82d72ee6a 100644 --- a/pkg/api/server/register_archive.go +++ b/pkg/api/server/register_archive.go @@ -151,6 +151,10 @@ func (s *APIServer) registerArchiveHandlers(r *mux.Router) error { // type: string // description: Path to a directory in the container to extract // required: true + // - in: query + // name: rename + // type: string + // description: JSON encoded map[string]string to translate paths // responses: // 200: // description: no error diff --git a/pkg/api/server/register_volumes.go b/pkg/api/server/register_volumes.go index d58bf0662..fb02cffcf 100644 --- a/pkg/api/server/register_volumes.go +++ b/pkg/api/server/register_volumes.go @@ -68,6 +68,7 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { // - label=<key> or label=<key>:<value> Matches volumes based on the presence of a label alone or a label and a value. // - name=<volume-name> Matches all of volume name. // - opt=<driver-option> Matches a storage driver options + // - `until=<timestamp>` List volumes created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time. // responses: // '200': // "$ref": "#/responses/VolumeList" @@ -166,6 +167,7 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { // - driver=<volume-driver-name> Matches volumes based on their driver. // - label=<key> or label=<key>:<value> Matches volumes based on the presence of a label alone or a label and a value. // - name=<volume-name> Matches all of volume name. + // - `until=<timestamp>` List volumes created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time. // // Note: // The boolean `dangling` filter is not yet implemented for this endpoint. diff --git a/pkg/autoupdate/autoupdate.go b/pkg/autoupdate/autoupdate.go index 0a13e7e74..c51e2cd03 100644 --- a/pkg/autoupdate/autoupdate.go +++ b/pkg/autoupdate/autoupdate.go @@ -9,12 +9,13 @@ import ( "github.com/containers/common/pkg/config" "github.com/containers/image/v5/docker" "github.com/containers/image/v5/docker/reference" - "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/transports/alltransports" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" + "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/systemd" systemdDefine "github.com/containers/podman/v3/pkg/systemd/define" + "github.com/coreos/go-systemd/v22/dbus" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -74,12 +75,6 @@ func LookupPolicy(s string) (Policy, error) { return "", errors.Errorf("invalid auto-update policy %q: valid policies are %+q", s, keys) } -// Options include parameters for auto updates. -type Options struct { - // Authfile to use when contacting registries. - Authfile string -} - // ValidateImageReference checks if the specified imageName is a fully-qualified // image reference to the docker transport (without digest). Such a reference // includes a domain, name and tag (e.g., quay.io/podman/stable:latest). The @@ -119,7 +114,7 @@ func ValidateImageReference(imageName string) error { // // It returns a slice of successfully restarted systemd units and a slice of // errors encountered during auto update. -func AutoUpdate(runtime *libpod.Runtime, options Options) ([]string, []error) { +func AutoUpdate(ctx context.Context, runtime *libpod.Runtime, options entities.AutoUpdateOptions) ([]*entities.AutoUpdateReport, []error) { // Create a map from `image ID -> []*Container`. containerMap, errs := imageContainersMap(runtime) if len(containerMap) == 0 { @@ -130,7 +125,7 @@ func AutoUpdate(runtime *libpod.Runtime, options Options) ([]string, []error) { listOptions := &libimage.ListImagesOptions{ Filters: []string{"readonly=false"}, } - imagesSlice, err := runtime.LibimageRuntime().ListImages(context.Background(), nil, listOptions) + imagesSlice, err := runtime.LibimageRuntime().ListImages(ctx, nil, listOptions) if err != nil { return nil, []error{err} } @@ -147,8 +142,8 @@ func AutoUpdate(runtime *libpod.Runtime, options Options) ([]string, []error) { } defer conn.Close() - // Update images. - containersToRestart := []*libpod.Container{} + // Update all images/container according to their auto-update policy. + var allReports []*entities.AutoUpdateReport updatedRawImages := make(map[string]bool) for imageID, policyMapper := range containerMap { image, exists := imageMap[imageID] @@ -156,76 +151,149 @@ func AutoUpdate(runtime *libpod.Runtime, options Options) ([]string, []error) { errs = append(errs, errors.Errorf("container image ID %q not found in local storage", imageID)) return nil, errs } - // Now we have to check if the image of any containers must be updated. - // Note that the image ID is NOT enough for this check as a given image - // may have multiple tags. - for _, registryCtr := range policyMapper[PolicyRegistryImage] { - cid := registryCtr.ID() - rawImageName := registryCtr.RawImageName() - if rawImageName == "" { - errs = append(errs, errors.Errorf("error registry auto-updating container %q: raw-image name is empty", cid)) - } - readAuthenticationPath(registryCtr, options) - needsUpdate, err := newerRemoteImageAvailable(runtime, image, rawImageName, options) + + for _, ctr := range policyMapper[PolicyRegistryImage] { + report, err := autoUpdateRegistry(ctx, image, ctr, updatedRawImages, &options, conn, runtime) if err != nil { - errs = append(errs, errors.Wrapf(err, "error registry auto-updating container %q: image check for %q failed", cid, rawImageName)) - continue + errs = append(errs, err) } - - if needsUpdate { - logrus.Infof("Auto-updating container %q using registry image %q", cid, rawImageName) - if _, updated := updatedRawImages[rawImageName]; !updated { - _, err = updateImage(runtime, rawImageName, options) - if err != nil { - errs = append(errs, errors.Wrapf(err, "error registry auto-updating container %q: image update for %q failed", cid, rawImageName)) - continue - } - updatedRawImages[rawImageName] = true - } - containersToRestart = append(containersToRestart, registryCtr) + if report != nil { + allReports = append(allReports, report) } } - for _, localCtr := range policyMapper[PolicyLocalImage] { - cid := localCtr.ID() - rawImageName := localCtr.RawImageName() - if rawImageName == "" { - errs = append(errs, errors.Errorf("error locally auto-updating container %q: raw-image name is empty", cid)) - } - // This avoids restarting containers unnecessarily. - needsUpdate, err := newerLocalImageAvailable(runtime, image, rawImageName) + for _, ctr := range policyMapper[PolicyLocalImage] { + report, err := autoUpdateLocally(ctx, image, ctr, &options, conn, runtime) if err != nil { - errs = append(errs, errors.Wrapf(err, "error locally auto-updating container %q: image check for %q failed", cid, rawImageName)) - continue + errs = append(errs, err) } - - if needsUpdate { - logrus.Infof("Auto-updating container %q using local image %q", cid, rawImageName) - containersToRestart = append(containersToRestart, localCtr) + if report != nil { + allReports = append(allReports, report) } } } - // Restart containers. - updatedUnits := []string{} - for _, ctr := range containersToRestart { - labels := ctr.Labels() - unit, exists := labels[systemdDefine.EnvVariable] - if !exists { - // Shouldn't happen but let's be sure of it. - errs = append(errs, errors.Errorf("error auto-updating container %q: no %s label found", ctr.ID(), systemdDefine.EnvVariable)) - continue - } - _, err := conn.RestartUnit(unit, "replace", nil) - if err != nil { - errs = append(errs, errors.Wrapf(err, "error auto-updating container %q: restarting systemd unit %q failed", ctr.ID(), unit)) - continue + return allReports, errs +} + +// autoUpdateRegistry updates the image/container according to the "registry" policy. +func autoUpdateRegistry(ctx context.Context, image *libimage.Image, ctr *libpod.Container, updatedRawImages map[string]bool, options *entities.AutoUpdateOptions, conn *dbus.Conn, runtime *libpod.Runtime) (*entities.AutoUpdateReport, error) { + cid := ctr.ID() + rawImageName := ctr.RawImageName() + if rawImageName == "" { + return nil, errors.Errorf("error registry auto-updating container %q: raw-image name is empty", cid) + } + + labels := ctr.Labels() + unit, exists := labels[systemdDefine.EnvVariable] + if !exists { + return nil, errors.Errorf("error auto-updating container %q: no %s label found", ctr.ID(), systemdDefine.EnvVariable) + } + + report := &entities.AutoUpdateReport{ + ContainerID: cid, + ContainerName: ctr.Name(), + ImageName: rawImageName, + Policy: PolicyRegistryImage, + SystemdUnit: unit, + Updated: "failed", + } + + if _, updated := updatedRawImages[rawImageName]; updated { + logrus.Infof("Auto-updating container %q using registry image %q", cid, rawImageName) + if err := restartSystemdUnit(ctr, unit, conn); err != nil { + return report, err } - logrus.Infof("Successfully restarted systemd unit %q", unit) - updatedUnits = append(updatedUnits, unit) + report.Updated = "true" + return report, nil + } + + authfile := getAuthfilePath(ctr, options) + needsUpdate, err := newerRemoteImageAvailable(ctx, runtime, image, rawImageName, authfile) + if err != nil { + return report, errors.Wrapf(err, "error registry auto-updating container %q: image check for %q failed", cid, rawImageName) + } + + if !needsUpdate { + report.Updated = "false" + return report, nil + } + + if options.DryRun { + report.Updated = "pending" + return report, nil + } + + if _, err := updateImage(ctx, runtime, rawImageName, options); err != nil { + return report, errors.Wrapf(err, "error registry auto-updating container %q: image update for %q failed", cid, rawImageName) + } + updatedRawImages[rawImageName] = true + + logrus.Infof("Auto-updating container %q using registry image %q", cid, rawImageName) + if err := restartSystemdUnit(ctr, unit, conn); err != nil { + return report, err } - return updatedUnits, errs + report.Updated = "true" + return report, nil +} + +// autoUpdateRegistry updates the image/container according to the "local" policy. +func autoUpdateLocally(ctx context.Context, image *libimage.Image, ctr *libpod.Container, options *entities.AutoUpdateOptions, conn *dbus.Conn, runtime *libpod.Runtime) (*entities.AutoUpdateReport, error) { + cid := ctr.ID() + rawImageName := ctr.RawImageName() + if rawImageName == "" { + return nil, errors.Errorf("error locally auto-updating container %q: raw-image name is empty", cid) + } + + labels := ctr.Labels() + unit, exists := labels[systemdDefine.EnvVariable] + if !exists { + return nil, errors.Errorf("error auto-updating container %q: no %s label found", ctr.ID(), systemdDefine.EnvVariable) + } + + report := &entities.AutoUpdateReport{ + ContainerID: cid, + ContainerName: ctr.Name(), + ImageName: rawImageName, + Policy: PolicyLocalImage, + SystemdUnit: unit, + Updated: "failed", + } + + needsUpdate, err := newerLocalImageAvailable(runtime, image, rawImageName) + if err != nil { + return report, errors.Wrapf(err, "error locally auto-updating container %q: image check for %q failed", cid, rawImageName) + } + + if !needsUpdate { + report.Updated = "false" + return report, nil + } + + if options.DryRun { + report.Updated = "pending" + return report, nil + } + + logrus.Infof("Auto-updating container %q using local image %q", cid, rawImageName) + if err := restartSystemdUnit(ctr, unit, conn); err != nil { + return report, err + } + + report.Updated = "true" + return report, nil +} + +// restartSystemdUnit restarts the systemd unit the container is running in. +func restartSystemdUnit(ctr *libpod.Container, unit string, conn *dbus.Conn) error { + _, err := conn.RestartUnit(unit, "replace", nil) + if err != nil { + return errors.Wrapf(err, "error auto-updating container %q: restarting systemd unit %q failed", ctr.ID(), unit) + } + + logrus.Infof("Successfully restarted systemd unit %q of container %q", unit, ctr.ID()) + return nil } // imageContainersMap generates a map[image ID] -> [containers using the image] @@ -280,52 +348,25 @@ func imageContainersMap(runtime *libpod.Runtime) (map[string]policyMapper, []err return containerMap, errors } -// readAuthenticationPath reads a container's labels and reads authentication path into options -func readAuthenticationPath(ctr *libpod.Container, options Options) { +// getAuthfilePath returns an authfile path, if set. The authfile label in the +// container, if set, as precedence over the one set in the options. +func getAuthfilePath(ctr *libpod.Container, options *entities.AutoUpdateOptions) string { labels := ctr.Labels() authFilePath, exists := labels[AuthfileLabel] if exists { - options.Authfile = authFilePath + return authFilePath } + return options.Authfile } // newerRemoteImageAvailable returns true if there corresponding image on the remote // registry is newer. -func newerRemoteImageAvailable(runtime *libpod.Runtime, img *libimage.Image, origName string, options Options) (bool, error) { +func newerRemoteImageAvailable(ctx context.Context, runtime *libpod.Runtime, img *libimage.Image, origName string, authfile string) (bool, error) { remoteRef, err := docker.ParseReference("//" + origName) if err != nil { return false, err } - - data, err := img.Inspect(context.Background(), false) - if err != nil { - return false, err - } - - sys := runtime.SystemContext() - sys.AuthFilePath = options.Authfile - - // We need to account for the arch that the image uses. It seems - // common on ARM to tweak this option to pull the correct image. See - // github.com/containers/podman/issues/6613. - sys.ArchitectureChoice = data.Architecture - - remoteImg, err := remoteRef.NewImage(context.Background(), sys) - if err != nil { - return false, err - } - - rawManifest, _, err := remoteImg.Manifest(context.Background()) - if err != nil { - return false, err - } - - remoteDigest, err := manifest.Digest(rawManifest) - if err != nil { - return false, err - } - - return img.Digest().String() != remoteDigest.String(), nil + return img.HasDifferentDigest(ctx, remoteRef) } // newerLocalImageAvailable returns true if the container and local image have different digests @@ -334,21 +375,16 @@ func newerLocalImageAvailable(runtime *libpod.Runtime, img *libimage.Image, rawI if err != nil { return false, err } - - localDigest := localImg.Digest().String() - - ctrDigest := img.Digest().String() - - return localDigest != ctrDigest, nil + return localImg.Digest().String() != img.Digest().String(), nil } // updateImage pulls the specified image. -func updateImage(runtime *libpod.Runtime, name string, options Options) (*libimage.Image, error) { +func updateImage(ctx context.Context, runtime *libpod.Runtime, name string, options *entities.AutoUpdateOptions) (*libimage.Image, error) { pullOptions := &libimage.PullOptions{} pullOptions.AuthFilePath = options.Authfile pullOptions.Writer = os.Stderr - pulledImages, err := runtime.LibimageRuntime().Pull(context.Background(), name, config.PullPolicyAlways, pullOptions) + pulledImages, err := runtime.LibimageRuntime().Pull(ctx, name, config.PullPolicyAlways, pullOptions) if err != nil { return nil, err } diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go index fd93c5ac7..62b1655ac 100644 --- a/pkg/bindings/connection.go +++ b/pkg/bindings/connection.go @@ -327,7 +327,7 @@ func (c *Connection) DoRequest(httpBody io.Reader, httpMethod, endpoint string, uri := fmt.Sprintf("http://d/v%d.%d.%d/libpod"+endpoint, params...) logrus.Debugf("DoRequest Method: %s URI: %v", httpMethod, uri) - req, err := http.NewRequest(httpMethod, uri, httpBody) + req, err := http.NewRequestWithContext(context.WithValue(context.Background(), clientKey, c), httpMethod, uri, httpBody) if err != nil { return nil, err } @@ -337,7 +337,6 @@ func (c *Connection) DoRequest(httpBody io.Reader, httpMethod, endpoint string, for key, val := range header { req.Header.Set(key, val) } - req = req.WithContext(context.WithValue(context.Background(), clientKey, c)) // Give the Do three chances in the case of a comm/service hiccup for i := 0; i < 3; i++ { response, err = c.Client.Do(req) // nolint diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go index cc12c8ab7..01c14d350 100644 --- a/pkg/bindings/containers/attach.go +++ b/pkg/bindings/containers/attach.go @@ -25,6 +25,12 @@ import ( "golang.org/x/crypto/ssh/terminal" ) +// The CloseWriter interface is used to determine whether we can do a one-sided +// close of a hijacked connection. +type CloseWriter interface { + CloseWrite() error +} + // Attach attaches to a running container func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Writer, stderr io.Writer, attachReady chan bool, options *AttachOptions) error { if options == nil { @@ -161,6 +167,12 @@ func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Wri logrus.Error("failed to write input to service: " + err.Error()) } stdinChan <- err + + if closeWrite, ok := socket.(CloseWriter); ok { + if err := closeWrite.CloseWrite(); err != nil { + logrus.Warnf("Failed to close STDIN for writing: %v", err) + } + } }() } @@ -485,6 +497,13 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar if err != nil { logrus.Error("failed to write input to service: " + err.Error()) } + + if closeWrite, ok := socket.(CloseWriter); ok { + logrus.Debugf("Closing STDIN") + if err := closeWrite.CloseWrite(); err != nil { + logrus.Warnf("Failed to close STDIN for writing: %v", err) + } + } }() } diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go index 1058c7a48..cf088441f 100644 --- a/pkg/bindings/containers/types.go +++ b/pkg/bindings/containers/types.go @@ -62,6 +62,7 @@ type RestoreOptions struct { Keep *bool Name *string TCPEstablished *bool + Pod *string } //go:generate go run ../generator/generator.go CreateOptions @@ -263,4 +264,6 @@ type CopyOptions struct { // If used with CopyFromArchive and set to true it will change ownership of files from the source tar archive // to the primary uid/gid of the target container. Chown *bool `schema:"copyUIDGID"` + // Map to translate path names. + Rename map[string]string } diff --git a/pkg/bindings/containers/types_copy_options.go b/pkg/bindings/containers/types_copy_options.go index 12ad085fd..0624b450e 100644 --- a/pkg/bindings/containers/types_copy_options.go +++ b/pkg/bindings/containers/types_copy_options.go @@ -35,3 +35,19 @@ func (o *CopyOptions) GetChown() bool { } return *o.Chown } + +// WithRename +func (o *CopyOptions) WithRename(value map[string]string) *CopyOptions { + v := value + o.Rename = v + return o +} + +// GetRename +func (o *CopyOptions) GetRename() map[string]string { + var rename map[string]string + if o.Rename == nil { + return rename + } + return o.Rename +} diff --git a/pkg/bindings/containers/types_restore_options.go b/pkg/bindings/containers/types_restore_options.go index ea6c810a2..820a7696f 100644 --- a/pkg/bindings/containers/types_restore_options.go +++ b/pkg/bindings/containers/types_restore_options.go @@ -131,3 +131,19 @@ func (o *RestoreOptions) GetTCPEstablished() bool { } return *o.TCPEstablished } + +// WithPod +func (o *RestoreOptions) WithPod(value string) *RestoreOptions { + v := &value + o.Pod = v + return o +} + +// GetPod +func (o *RestoreOptions) GetPod() string { + var pod string + if o.Pod == nil { + return pod + } + return *o.Pod +} diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go index 95d9d4df7..a35f461a7 100644 --- a/pkg/bindings/images/build.go +++ b/pkg/bindings/images/build.go @@ -301,6 +301,8 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO tarContent := []string{options.ContextDirectory} newContainerFiles := []string{} + + dontexcludes := []string{"!Dockerfile", "!Containerfile", "!.dockerignore", "!.containerignore"} for _, c := range containerFiles { if c == "/dev/stdin" { content, err := ioutil.ReadAll(os.Stdin) @@ -328,6 +330,7 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO // Do NOT add to tarfile if strings.HasPrefix(containerfile, contextDir+string(filepath.Separator)) { containerfile = strings.TrimPrefix(containerfile, contextDir+string(filepath.Separator)) + dontexcludes = append(dontexcludes, "!"+containerfile) } else { // If Containerfile does not exists assume it is in context directory, do Not add to tarfile if _, err := os.Lstat(containerfile); err != nil { @@ -349,8 +352,7 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO } params.Set("dockerfile", string(cFileJSON)) } - - tarfile, err := nTar(excludes, tarContent...) + tarfile, err := nTar(append(excludes, dontexcludes...), tarContent...) if err != nil { logrus.Errorf("cannot tar container entries %v error: %v", tarContent, err) return nil, err @@ -389,42 +391,50 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO dec := json.NewDecoder(body) var id string - var mErr error for { var s struct { Stream string `json:"stream,omitempty"` Error string `json:"error,omitempty"` } - if err := dec.Decode(&s); err != nil { - if errors.Is(err, io.EOF) { - if mErr == nil && id == "" { - mErr = errors.New("stream dropped, unexpected failure") - } - break - } - s.Error = err.Error() + "\n" - } select { + // FIXME(vrothberg): it seems we always hit the EOF case below, + // even when the server quit but it seems desirable to + // distinguish a proper build from a transient EOF. case <-response.Request.Context().Done(): - return &entities.BuildReport{ID: id}, mErr + return &entities.BuildReport{ID: id}, nil default: // non-blocking select } + if err := dec.Decode(&s); err != nil { + if errors.Is(err, io.ErrUnexpectedEOF) { + return nil, errors.Wrap(err, "server probably quit") + } + // EOF means the stream is over in which case we need + // to have read the id. + if errors.Is(err, io.EOF) && id != "" { + break + } + return &entities.BuildReport{ID: id}, errors.Wrap(err, "decoding stream") + } + switch { case s.Stream != "": - stdout.Write([]byte(s.Stream)) - if iidRegex.Match([]byte(s.Stream)) { + raw := []byte(s.Stream) + stdout.Write(raw) + if iidRegex.Match(raw) { id = strings.TrimSuffix(s.Stream, "\n") } case s.Error != "": - mErr = errors.New(s.Error) + // If there's an error, return directly. The stream + // will be closed on return. + return &entities.BuildReport{ID: id}, errors.New(s.Error) default: return &entities.BuildReport{ID: id}, errors.New("failed to parse build results stream, unexpected input") } } - return &entities.BuildReport{ID: id}, mErr + return &entities.BuildReport{ID: id}, nil } func nTar(excludes []string, sources ...string) (io.ReadCloser, error) { @@ -548,9 +558,13 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) { } func parseDockerignore(root string) ([]string, error) { - ignore, err := ioutil.ReadFile(filepath.Join(root, ".dockerignore")) - if err != nil && !os.IsNotExist(err) { - return nil, errors.Wrapf(err, "error reading .dockerignore: '%s'", root) + ignore, err := ioutil.ReadFile(filepath.Join(root, ".containerignore")) + if err != nil { + var dockerIgnoreErr error + ignore, dockerIgnoreErr = ioutil.ReadFile(filepath.Join(root, ".dockerignore")) + if dockerIgnoreErr != nil && !os.IsNotExist(dockerIgnoreErr) { + return nil, errors.Wrapf(err, "error reading .containerignore: '%s'", root) + } } rawexcludes := strings.Split(string(ignore), "\n") excludes := make([]string, 0, len(rawexcludes)) diff --git a/pkg/checkpoint/checkpoint_restore.go b/pkg/checkpoint/checkpoint_restore.go index 0d45cab5f..9fdf04933 100644 --- a/pkg/checkpoint/checkpoint_restore.go +++ b/pkg/checkpoint/checkpoint_restore.go @@ -9,6 +9,9 @@ import ( "github.com/containers/common/libimage" "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/libpod" + ann "github.com/containers/podman/v3/pkg/annotations" + "github.com/containers/podman/v3/pkg/checkpoint/crutils" + "github.com/containers/podman/v3/pkg/criu" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/errorhandling" "github.com/containers/podman/v3/pkg/specgen/generate" @@ -68,6 +71,14 @@ func CRImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, restoreOpt return nil, err } + if ctrConfig.Pod != "" && restoreOptions.Pod == "" { + return nil, errors.New("cannot restore pod container without --pod") + } + + if ctrConfig.Pod == "" && restoreOptions.Pod != "" { + return nil, errors.New("cannot restore non pod container into pod") + } + // This should not happen as checkpoints with these options are not exported. if len(ctrConfig.Dependencies) > 0 { return nil, errors.Errorf("Cannot import checkpoints of containers with dependencies") @@ -96,6 +107,91 @@ func CRImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, restoreOpt newName = true } + if restoreOptions.Pod != "" { + // Restoring into a Pod requires much newer versions of CRIU + if !criu.CheckForCriu(criu.PodCriuVersion) { + return nil, errors.Errorf("restoring containers into pods requires at least CRIU %d", criu.PodCriuVersion) + } + // The runtime also has to support it + if !crutils.CRRuntimeSupportsPodCheckpointRestore(runtime.GetOCIRuntimePath()) { + return nil, errors.Errorf("runtime %s does not support pod restore", runtime.GetOCIRuntimePath()) + } + // Restoring into an existing Pod + ctrConfig.Pod = restoreOptions.Pod + + // According to podman pod create a pod can share the following namespaces: + // cgroup, ipc, net, pid, uts + // Let's make sure we a restoring into a pod with the same shared namespaces. + pod, err := runtime.LookupPod(ctrConfig.Pod) + if err != nil { + return nil, errors.Wrapf(err, "pod %q cannot be retrieved", ctrConfig.Pod) + } + + infraContainer, err := pod.InfraContainer() + if err != nil { + return nil, errors.Wrapf(err, "cannot retrieve infra container from pod %q", ctrConfig.Pod) + } + + // If a namespaces was shared (!= "") it needs to be set to the new infrastructure container + // If the infrastructure container does not share the same namespaces as the to be restored + // container we abort. + if ctrConfig.IPCNsCtr != "" { + if !pod.SharesIPC() { + return nil, errors.Errorf("pod %s does not share the IPC namespace", ctrConfig.Pod) + } + ctrConfig.IPCNsCtr = infraContainer.ID() + } + + if ctrConfig.NetNsCtr != "" { + if !pod.SharesNet() { + return nil, errors.Errorf("pod %s does not share the network namespace", ctrConfig.Pod) + } + ctrConfig.NetNsCtr = infraContainer.ID() + } + + if ctrConfig.PIDNsCtr != "" { + if !pod.SharesPID() { + return nil, errors.Errorf("pod %s does not share the PID namespace", ctrConfig.Pod) + } + ctrConfig.PIDNsCtr = infraContainer.ID() + } + + if ctrConfig.UTSNsCtr != "" { + if !pod.SharesUTS() { + return nil, errors.Errorf("pod %s does not share the UTS namespace", ctrConfig.Pod) + } + ctrConfig.UTSNsCtr = infraContainer.ID() + } + + if ctrConfig.CgroupNsCtr != "" { + if !pod.SharesCgroup() { + return nil, errors.Errorf("pod %s does not share the cgroup namespace", ctrConfig.Pod) + } + ctrConfig.CgroupNsCtr = infraContainer.ID() + } + + // Change SELinux labels to infrastructure container labels + ctrConfig.MountLabel = infraContainer.MountLabel() + ctrConfig.ProcessLabel = infraContainer.ProcessLabel() + + // Fix parent cgroup + cgroupPath, err := pod.CgroupPath() + if err != nil { + return nil, errors.Wrapf(err, "cannot retrieve cgroup path from pod %q", ctrConfig.Pod) + } + ctrConfig.CgroupParent = cgroupPath + + oldPodID := dumpSpec.Annotations[ann.SandboxID] + // Fix up SandboxID in the annotations + dumpSpec.Annotations[ann.SandboxID] = ctrConfig.Pod + // Fix up CreateCommand + for i, c := range ctrConfig.CreateCommand { + if c == oldPodID { + ctrConfig.CreateCommand[i] = ctrConfig.Pod + } + } + } + if len(restoreOptions.PublishPorts) > 0 { ports, _, _, err := generate.ParsePortMapping(restoreOptions.PublishPorts) if err != nil { diff --git a/pkg/checkpoint/crutils/checkpoint_restore_utils.go b/pkg/checkpoint/crutils/checkpoint_restore_utils.go index 53ff55865..3b77368bb 100644 --- a/pkg/checkpoint/crutils/checkpoint_restore_utils.go +++ b/pkg/checkpoint/crutils/checkpoint_restore_utils.go @@ -1,6 +1,7 @@ package crutils import ( + "bytes" "io" "os" "os/exec" @@ -189,3 +190,13 @@ func CRRuntimeSupportsCheckpointRestore(runtimePath string) bool { } return false } + +// CRRuntimeSupportsCheckpointRestore tests if the runtime at 'runtimePath' +// supports restoring into existing Pods. The runtime needs to support +// the CRIU option --lsm-mount-context and the existence of this is checked +// by this function. In addition it is necessary to at least have CRIU 3.16. +func CRRuntimeSupportsPodCheckpointRestore(runtimePath string) bool { + cmd := exec.Command(runtimePath, "restore", "--lsm-mount-context") + out, _ := cmd.CombinedOutput() + return bytes.Contains(out, []byte("flag needs an argument")) +} diff --git a/pkg/copy/parse.go b/pkg/copy/parse.go index 39e0e1547..93edec5fa 100644 --- a/pkg/copy/parse.go +++ b/pkg/copy/parse.go @@ -18,18 +18,6 @@ func ParseSourceAndDestination(source, destination string) (string, string, stri sourceContainer, sourcePath := parseUserInput(source) destContainer, destPath := parseUserInput(destination) - numContainers := 0 - if len(sourceContainer) > 0 { - numContainers++ - } - if len(destContainer) > 0 { - numContainers++ - } - - if numContainers != 1 { - return "", "", "", "", errors.Errorf("invalid arguments %q, %q: exactly 1 container expected but %d specified", source, destination, numContainers) - } - if len(sourcePath) == 0 || len(destPath) == 0 { return "", "", "", "", errors.Errorf("invalid arguments %q, %q: you must specify paths", source, destination) } diff --git a/pkg/criu/criu.go b/pkg/criu/criu.go index f4cce238a..2a6805979 100644 --- a/pkg/criu/criu.go +++ b/pkg/criu/criu.go @@ -1,17 +1,21 @@ package criu import ( - "github.com/checkpoint-restore/go-criu" + "github.com/checkpoint-restore/go-criu/v5" ) // MinCriuVersion for Podman at least CRIU 3.11 is required const MinCriuVersion = 31100 +// PodCriuVersion is the version of CRIU needed for +// checkpointing and restoring containers out of and into Pods. +const PodCriuVersion = 31600 + // CheckForCriu uses CRIU's go bindings to check if the CRIU // binary exists and if it at least the version Podman needs. -func CheckForCriu() bool { +func CheckForCriu(version int) bool { c := criu.MakeCriu() - result, err := c.IsCriuAtLeast(MinCriuVersion) + result, err := c.IsCriuAtLeast(version) if err != nil { return false } diff --git a/pkg/domain/entities/auto-update.go b/pkg/domain/entities/auto-update.go index c51158816..eed617bf8 100644 --- a/pkg/domain/entities/auto-update.go +++ b/pkg/domain/entities/auto-update.go @@ -4,10 +4,25 @@ package entities type AutoUpdateOptions struct { // Authfile to use when contacting registries. Authfile string + // Only check for but do not perform any update. If an update is + // pending, it will be indicated in the Updated field of + // AutoUpdateReport. + DryRun bool } // AutoUpdateReport contains the results from running auto-update. type AutoUpdateReport struct { - // Units - the restarted systemd units during auto-update. - Units []string + // ID of the container *before* an update. + ContainerID string + // Name of the container *before* an update. + ContainerName string + // Name of the image. + ImageName string + // The configured auto-update policy. + Policy string + // SystemdUnit running a container configured for auto updates. + SystemdUnit string + // Indicates the update status: true, false, failed, pending (see + // DryRun). + Updated string } diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index 302b35a47..564921c52 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -165,6 +165,8 @@ type CopyOptions struct { // it will change ownership of files from the source tar archive // to the primary uid/gid of the destination container. Chown bool + // Map to translate path names. + Rename map[string]string } type CommitReport struct { @@ -207,6 +209,7 @@ type RestoreOptions struct { TCPEstablished bool ImportPrevious string PublishPorts []specgen.PortMapping + Pod string } type RestoreReport struct { @@ -242,6 +245,8 @@ type ContainerLogsOptions struct { Names bool // Show logs since this timestamp. Since time.Time + // Show logs until this timestamp. + Until time.Time // Number of lines to display at the end of the output. Tail int64 // Show timestamps in the logs. diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go index 28e5160db..d573e4704 100644 --- a/pkg/domain/entities/engine_container.go +++ b/pkg/domain/entities/engine_container.go @@ -8,13 +8,12 @@ import ( "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/pkg/domain/entities/reports" "github.com/containers/podman/v3/pkg/specgen" - "github.com/spf13/cobra" ) type ContainerCopyFunc func() error type ContainerEngine interface { - AutoUpdate(ctx context.Context, options AutoUpdateOptions) (*AutoUpdateReport, []error) + AutoUpdate(ctx context.Context, options AutoUpdateOptions) ([]*AutoUpdateReport, []error) Config(ctx context.Context) (*config.Config, error) ContainerAttach(ctx context.Context, nameOrID string, options AttachOptions) error ContainerCheckpoint(ctx context.Context, namesOrIds []string, options CheckpointOptions) ([]*CheckpointReport, error) @@ -82,7 +81,7 @@ type ContainerEngine interface { PodStop(ctx context.Context, namesOrIds []string, options PodStopOptions) ([]*PodStopReport, error) PodTop(ctx context.Context, options PodTopOptions) (*StringSliceReport, error) PodUnpause(ctx context.Context, namesOrIds []string, options PodunpauseOptions) ([]*PodUnpauseReport, error) - SetupRootless(ctx context.Context, cmd *cobra.Command) error + SetupRootless(ctx context.Context, noMoveProcess bool) error SecretCreate(ctx context.Context, name string, reader io.Reader, options SecretCreateOptions) (*SecretCreateReport, error) SecretInspect(ctx context.Context, nameOrIDs []string) ([]*SecretInfoReport, []error, error) SecretList(ctx context.Context) ([]*SecretInfoReport, error) diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go index 35f940bca..68e335f8d 100644 --- a/pkg/domain/entities/pods.go +++ b/pkg/domain/entities/pods.go @@ -112,12 +112,14 @@ type PodCreateOptions struct { Hostname string Infra bool InfraImage string + InfraName string InfraCommand string InfraConmonPidFile string Labels map[string]string Name string Net *NetOptions Share []string + Pid string Cpus float64 CpusetCpus string } @@ -146,6 +148,18 @@ func (p *PodCreateOptions) CPULimits() *specs.LinuxCPU { return cpu } +func setNamespaces(p *PodCreateOptions) ([4]specgen.Namespace, error) { + allNS := [4]specgen.Namespace{} + if p.Pid != "" { + pid, err := specgen.ParseNamespace(p.Pid) + if err != nil { + return [4]specgen.Namespace{}, err + } + allNS[0] = pid + } + return allNS, nil +} + func (p *PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) error { // Basic Config s.Name = p.Name @@ -159,6 +173,7 @@ func (p *PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) error { s.InfraConmonPidFile = p.InfraConmonPidFile } s.InfraImage = p.InfraImage + s.InfraName = p.InfraName s.SharedNamespaces = p.Share s.PodCreateCommand = p.CreateCommand @@ -178,6 +193,14 @@ func (p *PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) error { s.NoManageHosts = p.Net.NoHosts s.HostAdd = p.Net.AddHosts + namespaces, err := setNamespaces(p) + if err != nil { + return err + } + if !namespaces[0].IsDefault() { + s.Pid = namespaces[0] + } + // Cgroup s.CgroupParent = p.CGroupParent diff --git a/pkg/domain/filters/volumes.go b/pkg/domain/filters/volumes.go index df23c31c0..d55c44ef5 100644 --- a/pkg/domain/filters/volumes.go +++ b/pkg/domain/filters/volumes.go @@ -51,6 +51,12 @@ func GenerateVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, error) { } return false }) + case "until": + f, err := createUntilFilterVolumeFunction(val) + if err != nil { + return nil, err + } + vf = append(vf, f) case "dangling": danglingVal := val invert := false @@ -93,16 +99,11 @@ func GeneratePruneVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, erro return util.MatchLabelFilters([]string{filterVal}, v.Labels()) }) case "until": - until, err := util.ComputeUntilTimestamp([]string{filterVal}) + f, err := createUntilFilterVolumeFunction(filterVal) if err != nil { return nil, err } - vf = append(vf, func(v *libpod.Volume) bool { - if !until.IsZero() && v.CreatedTime().Before(until) { - return true - } - return false - }) + vf = append(vf, f) default: return nil, errors.Errorf("%q is an invalid volume filter", filter) } @@ -110,3 +111,16 @@ func GeneratePruneVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, erro } return vf, nil } + +func createUntilFilterVolumeFunction(filter string) (libpod.VolumeFilter, error) { + until, err := util.ComputeUntilTimestamp([]string{filter}) + if err != nil { + return nil, err + } + return func(v *libpod.Volume) bool { + if !until.IsZero() && v.CreatedTime().Before(until) { + return true + } + return false + }, nil +} diff --git a/pkg/domain/infra/abi/archive.go b/pkg/domain/infra/abi/archive.go index 1a5bb6dc4..b60baa935 100644 --- a/pkg/domain/infra/abi/archive.go +++ b/pkg/domain/infra/abi/archive.go @@ -12,7 +12,7 @@ func (ic *ContainerEngine) ContainerCopyFromArchive(ctx context.Context, nameOrI if err != nil { return nil, err } - return container.CopyFromArchive(ctx, containerPath, options.Chown, reader) + return container.CopyFromArchive(ctx, containerPath, options.Chown, options.Rename, reader) } func (ic *ContainerEngine) ContainerCopyToArchive(ctx context.Context, nameOrID string, containerPath string, writer io.Writer) (entities.ContainerCopyFunc, error) { diff --git a/pkg/domain/infra/abi/auto-update.go b/pkg/domain/infra/abi/auto-update.go index c9d7f2130..b98ee1cb2 100644 --- a/pkg/domain/infra/abi/auto-update.go +++ b/pkg/domain/infra/abi/auto-update.go @@ -7,11 +7,6 @@ import ( "github.com/containers/podman/v3/pkg/domain/entities" ) -func (ic *ContainerEngine) AutoUpdate(ctx context.Context, options entities.AutoUpdateOptions) (*entities.AutoUpdateReport, []error) { - // Convert the entities options to the autoupdate ones. We can't use - // them in the entities package as low-level packages must not leak - // into the remote client. - autoOpts := autoupdate.Options{Authfile: options.Authfile} - units, failures := autoupdate.AutoUpdate(ic.Libpod, autoOpts) - return &entities.AutoUpdateReport{Units: units}, failures +func (ic *ContainerEngine) AutoUpdate(ctx context.Context, options entities.AutoUpdateOptions) ([]*entities.AutoUpdateReport, []error) { + return autoupdate.AutoUpdate(ctx, ic.Libpod, options) } diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 2c5300ccb..2003879b8 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -261,6 +261,24 @@ func (ic *ContainerEngine) ContainerRestart(ctx context.Context, namesOrIds []st return reports, nil } +func (ic *ContainerEngine) removeContainer(ctx context.Context, ctr *libpod.Container, options entities.RmOptions) error { + err := ic.Libpod.RemoveContainer(ctx, ctr, options.Force, options.Volumes) + if err == nil { + return nil + } + logrus.Debugf("Failed to remove container %s: %s", ctr.ID(), err.Error()) + switch errors.Cause(err) { + case define.ErrNoSuchCtr: + if options.Ignore { + logrus.Debugf("Ignoring error (--allow-missing): %v", err) + return nil + } + case define.ErrCtrRemoved: + return nil + } + return err +} + func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, options entities.RmOptions) ([]*entities.RmReport, error) { reports := []*entities.RmReport{} @@ -318,21 +336,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, } errMap, err := parallelctr.ContainerOp(ctx, ctrs, func(c *libpod.Container) error { - err := ic.Libpod.RemoveContainer(ctx, c, options.Force, options.Volumes) - if err == nil { - return nil - } - logrus.Debugf("Failed to remove container %s: %s", c.ID(), err.Error()) - switch errors.Cause(err) { - case define.ErrNoSuchCtr: - if options.Ignore { - logrus.Debugf("Ignoring error (--allow-missing): %v", err) - return nil - } - case define.ErrCtrRemoved: - return nil - } - return err + return ic.removeContainer(ctx, c, options) }) if err != nil { return nil, err @@ -525,6 +529,7 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st IgnoreStaticIP: options.IgnoreStaticIP, IgnoreStaticMAC: options.IgnoreStaticMAC, ImportPrevious: options.ImportPrevious, + Pod: options.Pod, } filterFuncs := []libpod.ContainerFilter{ @@ -614,7 +619,7 @@ func makeExecConfig(options entities.ExecOptions, rt *libpod.Runtime) (*libpod.E return nil, errors.Wrapf(err, "error retrieving Libpod configuration to build exec exit command") } // TODO: Add some ability to toggle syslog - exitCommandArgs, err := generate.CreateExitCommandArgs(storageConfig, runtimeConfig, false, true, true) + exitCommandArgs, err := generate.CreateExitCommandArgs(storageConfig, runtimeConfig, false, false, true) if err != nil { return nil, errors.Wrapf(err, "error constructing exit command for exec session") } @@ -791,6 +796,11 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri Err: err, ExitCode: exitCode, }) + if ctr.AutoRemove() { + if err := ic.removeContainer(ctx, ctr, entities.RmOptions{}); err != nil { + logrus.Errorf("Error removing container %s: %v", ctr.ID(), err) + } + } return reports, errors.Wrapf(err, "unable to start container %s", ctr.ID()) } @@ -827,9 +837,6 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri ExitCode: 125, } if err := ctr.Start(ctx, true); err != nil { - // if lastError != nil { - // fmt.Fprintln(os.Stderr, lastError) - // } report.Err = err if errors.Cause(err) == define.ErrWillDeadlock { report.Err = errors.Wrapf(err, "please run 'podman system renumber' to resolve deadlocks") @@ -838,6 +845,11 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri } report.Err = errors.Wrapf(err, "unable to start container %q", ctr.ID()) reports = append(reports, report) + if ctr.AutoRemove() { + if err := ic.removeContainer(ctx, ctr, entities.RmOptions{}); err != nil { + logrus.Errorf("Error removing container %s: %v", ctr.ID(), err) + } + } continue } report.ExitCode = 0 @@ -987,6 +999,7 @@ func (ic *ContainerEngine) ContainerLogs(ctx context.Context, containers []strin Details: options.Details, Follow: options.Follow, Since: options.Since, + Until: options.Until, Tail: options.Tail, Timestamps: options.Timestamps, UseName: options.Names, diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 6d1acb590..e8739615d 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -89,7 +89,7 @@ func toDomainHistoryLayer(layer *libimage.ImageHistory) entities.ImageHistoryLay } func (ir *ImageEngine) History(ctx context.Context, nameOrID string, opts entities.ImageHistoryOptions) (*entities.ImageHistoryReport, error) { - image, _, err := ir.Libpod.LibimageRuntime().LookupImage(nameOrID, &libimage.LookupImageOptions{IgnorePlatform: true}) + image, _, err := ir.Libpod.LibimageRuntime().LookupImage(nameOrID, nil) if err != nil { return nil, err } @@ -245,7 +245,7 @@ func (ir *ImageEngine) Inspect(ctx context.Context, namesOrIDs []string, opts en reports := []*entities.ImageInspectReport{} errs := []error{} for _, i := range namesOrIDs { - img, _, err := ir.Libpod.LibimageRuntime().LookupImage(i, &libimage.LookupImageOptions{IgnorePlatform: true}) + img, _, err := ir.Libpod.LibimageRuntime().LookupImage(i, nil) if err != nil { // This is probably a no such image, treat as nonfatal. errs = append(errs, err) @@ -321,7 +321,7 @@ func (ir *ImageEngine) Push(ctx context.Context, source string, destination stri } func (ir *ImageEngine) Tag(ctx context.Context, nameOrID string, tags []string, options entities.ImageTagOptions) error { - image, _, err := ir.Libpod.LibimageRuntime().LookupImage(nameOrID, &libimage.LookupImageOptions{IgnorePlatform: true}) + image, _, err := ir.Libpod.LibimageRuntime().LookupImage(nameOrID, nil) if err != nil { return err } @@ -334,7 +334,7 @@ func (ir *ImageEngine) Tag(ctx context.Context, nameOrID string, tags []string, } func (ir *ImageEngine) Untag(ctx context.Context, nameOrID string, tags []string, options entities.ImageUntagOptions) error { - image, _, err := ir.Libpod.LibimageRuntime().LookupImage(nameOrID, &libimage.LookupImageOptions{IgnorePlatform: true}) + image, _, err := ir.Libpod.LibimageRuntime().LookupImage(nameOrID, nil) if err != nil { return err } @@ -454,7 +454,7 @@ func (ir *ImageEngine) Build(ctx context.Context, containerFiles []string, opts } func (ir *ImageEngine) Tree(ctx context.Context, nameOrID string, opts entities.ImageTreeOptions) (*entities.ImageTreeReport, error) { - image, _, err := ir.Libpod.LibimageRuntime().LookupImage(nameOrID, &libimage.LookupImageOptions{IgnorePlatform: true}) + image, _, err := ir.Libpod.LibimageRuntime().LookupImage(nameOrID, nil) if err != nil { return nil, err } diff --git a/pkg/domain/infra/abi/images_list.go b/pkg/domain/infra/abi/images_list.go index b0e947991..2ec4ad244 100644 --- a/pkg/domain/infra/abi/images_list.go +++ b/pkg/domain/infra/abi/images_list.go @@ -30,12 +30,16 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) for j, d := range img.Digests() { digests[j] = string(d) } + isDangling, err := img.IsDangling(ctx) + if err != nil { + return nil, errors.Wrapf(err, "error checking if image %q is dangling", img.ID()) + } e := entities.ImageSummary{ ID: img.ID(), // ConfigDigest: string(img.ConfigDigest), Created: img.Created().Unix(), - Dangling: img.IsDangling(), + Dangling: isDangling, Digest: string(img.Digest()), RepoDigests: digests, History: img.NamesHistory(), diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go index e905036be..666bc997d 100644 --- a/pkg/domain/infra/abi/manifest.go +++ b/pkg/domain/infra/abi/manifest.go @@ -47,7 +47,7 @@ func (ir *ImageEngine) ManifestCreate(ctx context.Context, names []string, image // ManifestExists checks if a manifest list with the given name exists in local storage func (ir *ImageEngine) ManifestExists(ctx context.Context, name string) (*entities.BoolReport, error) { - image, _, err := ir.Libpod.LibimageRuntime().LookupImage(name, &libimage.LookupImageOptions{IgnorePlatform: true}) + _, err := ir.Libpod.LibimageRuntime().LookupManifestList(name) if err != nil { if errors.Cause(err) == storage.ErrImageUnknown { return &entities.BoolReport{Value: false}, nil @@ -55,11 +55,7 @@ func (ir *ImageEngine) ManifestExists(ctx context.Context, name string) (*entiti return nil, err } - isManifestList, err := image.IsManifestList(ctx) - if err != nil { - return nil, err - } - return &entities.BoolReport{Value: isManifestList}, nil + return &entities.BoolReport{Value: true}, nil } // ManifestInspect returns the content of a manifest list or image @@ -341,6 +337,7 @@ func (ir *ImageEngine) ManifestPush(ctx context.Context, name, destination strin pushOptions.ManifestMIMEType = manifestType pushOptions.RemoveSignatures = opts.RemoveSignatures pushOptions.SignBy = opts.SignBy + pushOptions.InsecureSkipTLSVerify = opts.SkipTLSVerify if opts.All { pushOptions.ImageListSelection = cp.CopyAllImages diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index 4782f0d01..d257bad18 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -277,7 +277,10 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY // registry on localhost. pullPolicy := config.PullPolicyNewer if len(container.ImagePullPolicy) > 0 { - pullPolicy, err = config.ParsePullPolicy(string(container.ImagePullPolicy)) + // Make sure to lower the strings since K8s pull policy + // may be capitalized (see bugzilla.redhat.com/show_bug.cgi?id=1985905). + rawPolicy := string(container.ImagePullPolicy) + pullPolicy, err = config.ParsePullPolicy(strings.ToLower(rawPolicy)) if err != nil { return nil, err } diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go index ebe59e871..bc98edd06 100644 --- a/pkg/domain/infra/abi/system.go +++ b/pkg/domain/infra/abi/system.go @@ -24,7 +24,6 @@ import ( "github.com/containers/storage/pkg/unshare" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -57,7 +56,7 @@ func (ic *ContainerEngine) Info(ctx context.Context) (*define.Info, error) { return info, err } -func (ic *ContainerEngine) SetupRootless(_ context.Context, cmd *cobra.Command) error { +func (ic *ContainerEngine) SetupRootless(_ context.Context, noMoveProcess bool) error { // do it only after podman has already re-execed and running with uid==0. hasCapSysAdmin, err := unshare.HasCapSysAdmin() if err != nil { @@ -104,6 +103,9 @@ func (ic *ContainerEngine) SetupRootless(_ context.Context, cmd *cobra.Command) if became { os.Exit(ret) } + if noMoveProcess { + return nil + } // if there is no pid file, try to join existing containers, and create a pause process. ctrs, err := ic.Libpod.GetRunningContainers() @@ -118,9 +120,10 @@ func (ic *ContainerEngine) SetupRootless(_ context.Context, cmd *cobra.Command) } became, ret, err = rootless.TryJoinFromFilePaths(pausePidPath, true, paths) + if err := movePauseProcessToScope(ic.Libpod); err != nil { - conf, err := ic.Config(context.Background()) - if err != nil { + conf, err2 := ic.Config(context.Background()) + if err2 != nil { return err } if conf.Engine.CgroupManager == config.SystemdCgroupsManager { @@ -148,7 +151,6 @@ func movePauseProcessToScope(r *libpod.Runtime) error { if err != nil { return errors.Wrapf(err, "could not get pause process pid file path") } - data, err := ioutil.ReadFile(pausePidPath) if err != nil { return errors.Wrapf(err, "cannot read pause pid file") @@ -403,6 +405,8 @@ func (ic *ContainerEngine) Unshare(ctx context.Context, args []string, options e if err != nil { return err } + // make sure to unlock, unshare can run for a long time + rootlesscni.Lock.Unlock() defer rootlesscni.Cleanup(ic.Libpod) return rootlesscni.Do(unshare) } diff --git a/pkg/domain/infra/runtime_abi.go b/pkg/domain/infra/runtime_abi.go index ca201b5ae..177e9cff4 100644 --- a/pkg/domain/infra/runtime_abi.go +++ b/pkg/domain/infra/runtime_abi.go @@ -33,6 +33,7 @@ func NewImageEngine(facts *entities.PodmanConfig) (entities.ImageEngine, error) r, err := NewLibpodImageRuntime(facts.FlagSet, facts) return r, err case entities.TunnelMode: + // TODO: look at me! ctx, err := bindings.NewConnectionWithIdentity(context.Background(), facts.URI, facts.Identity) return &tunnel.ImageEngine{ClientCtx: ctx}, err } diff --git a/pkg/domain/infra/tunnel/auto-update.go b/pkg/domain/infra/tunnel/auto-update.go index 41165cc74..038c60537 100644 --- a/pkg/domain/infra/tunnel/auto-update.go +++ b/pkg/domain/infra/tunnel/auto-update.go @@ -7,6 +7,6 @@ import ( "github.com/pkg/errors" ) -func (ic *ContainerEngine) AutoUpdate(ctx context.Context, options entities.AutoUpdateOptions) (*entities.AutoUpdateReport, []error) { +func (ic *ContainerEngine) AutoUpdate(ctx context.Context, options entities.AutoUpdateOptions) ([]*entities.AutoUpdateReport, []error) { return nil, []error{errors.New("not implemented")} } diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 56315f46f..58f9c5fb0 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -369,10 +369,11 @@ func (ic *ContainerEngine) ContainerCreate(ctx context.Context, s *specgen.SpecG func (ic *ContainerEngine) ContainerLogs(_ context.Context, nameOrIDs []string, opts entities.ContainerLogsOptions) error { since := opts.Since.Format(time.RFC3339) + until := opts.Until.Format(time.RFC3339) tail := strconv.FormatInt(opts.Tail, 10) stdout := opts.StdoutWriter != nil stderr := opts.StderrWriter != nil - options := new(containers.LogOptions).WithFollow(opts.Follow).WithSince(since).WithStderr(stderr) + options := new(containers.LogOptions).WithFollow(opts.Follow).WithSince(since).WithUntil(until).WithStderr(stderr) options.WithStdout(stdout).WithTail(tail) var err error @@ -541,6 +542,17 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri return nil, err } removeOptions := new(containers.RemoveOptions).WithVolumes(true).WithForce(false) + removeContainer := func(id string) { + if err := containers.Remove(ic.ClientCtx, id, removeOptions); err != nil { + if errorhandling.Contains(err, define.ErrNoSuchCtr) || + errorhandling.Contains(err, define.ErrCtrRemoved) { + logrus.Debugf("Container %s does not exist: %v", id, err) + } else { + logrus.Errorf("Error removing container %s: %v", id, err) + } + } + } + // There can only be one container if attach was used for i, ctr := range ctrs { name := ctr.ID @@ -568,6 +580,9 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri } if err != nil { + if ctr.AutoRemove { + removeContainer(ctr.ID) + } report.ExitCode = define.ExitCode(report.Err) report.Err = err reports = append(reports, &report) @@ -582,16 +597,10 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri logrus.Errorf("Failed to check if %s should restart: %v", ctr.ID, err) return } + logrus.Errorf("Should restart: %v", shouldRestart) - if !shouldRestart { - if err := containers.Remove(ic.ClientCtx, ctr.ID, removeOptions); err != nil { - if errorhandling.Contains(err, define.ErrNoSuchCtr) || - errorhandling.Contains(err, define.ErrCtrRemoved) { - logrus.Debugf("Container %s does not exist: %v", ctr.ID, err) - } else { - logrus.Errorf("Error removing container %s: %v", ctr.ID, err) - } - } + if !shouldRestart && ctr.AutoRemove { + removeContainer(ctr.ID) } }() } @@ -844,7 +853,8 @@ func (ic *ContainerEngine) ContainerPort(ctx context.Context, nameOrID string, o } func (ic *ContainerEngine) ContainerCopyFromArchive(ctx context.Context, nameOrID, path string, reader io.Reader, options entities.CopyOptions) (entities.ContainerCopyFunc, error) { - return containers.CopyFromArchiveWithOptions(ic.ClientCtx, nameOrID, path, reader, new(containers.CopyOptions).WithChown(options.Chown)) + copyOptions := new(containers.CopyOptions).WithChown(options.Chown).WithRename(options.Rename) + return containers.CopyFromArchiveWithOptions(ic.ClientCtx, nameOrID, path, reader, copyOptions) } func (ic *ContainerEngine) ContainerCopyToArchive(ctx context.Context, nameOrID string, path string, writer io.Writer) (entities.ContainerCopyFunc, error) { diff --git a/pkg/domain/infra/tunnel/system.go b/pkg/domain/infra/tunnel/system.go index 7400d3771..6b43cf038 100644 --- a/pkg/domain/infra/tunnel/system.go +++ b/pkg/domain/infra/tunnel/system.go @@ -7,14 +7,13 @@ import ( "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/pkg/bindings/system" "github.com/containers/podman/v3/pkg/domain/entities" - "github.com/spf13/cobra" ) func (ic *ContainerEngine) Info(ctx context.Context) (*define.Info, error) { return system.Info(ic.ClientCtx, nil) } -func (ic *ContainerEngine) SetupRootless(_ context.Context, cmd *cobra.Command) error { +func (ic *ContainerEngine) SetupRootless(_ context.Context, noMoveProcess bool) error { panic(errors.New("rootless engine mode is not supported when tunneling")) } diff --git a/pkg/ps/ps.go b/pkg/ps/ps.go index ef79973d6..54079baa1 100644 --- a/pkg/ps/ps.go +++ b/pkg/ps/ps.go @@ -9,7 +9,6 @@ import ( "strings" "time" - "github.com/containers/common/libimage" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/pkg/domain/entities" @@ -272,8 +271,7 @@ func ListStorageContainer(rt *libpod.Runtime, ctr storage.Container) (entities.L imageName := "" if ctr.ImageID != "" { - lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true} - image, _, err := rt.LibimageRuntime().LookupImage(ctr.ImageID, lookupOptions) + image, _, err := rt.LibimageRuntime().LookupImage(ctr.ImageID, nil) if err != nil { return ps, err } diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index f76eab0e3..9ef56acb4 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -14,11 +14,13 @@ import ( "os/user" "runtime" "strconv" + "strings" "sync" "unsafe" "github.com/containers/podman/v3/pkg/errorhandling" "github.com/containers/storage/pkg/idtools" + pmount "github.com/containers/storage/pkg/mount" "github.com/containers/storage/pkg/unshare" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -235,6 +237,24 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo return false, 0, nil } + if mounts, err := pmount.GetMounts(); err == nil { + for _, m := range mounts { + if m.Mountpoint == "/" { + isShared := false + for _, o := range strings.Split(m.Optional, ",") { + if strings.HasPrefix(o, "shared:") { + isShared = true + break + } + } + if !isShared { + logrus.Warningf("%q is not a shared mount, this could cause issues or missing mounts with rootless containers", m.Mountpoint) + } + break + } + } + } + cPausePid := C.CString(pausePid) defer C.free(unsafe.Pointer(cPausePid)) diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go index ca92f558d..1f6d00eb7 100644 --- a/pkg/specgen/generate/container.go +++ b/pkg/specgen/generate/container.go @@ -26,8 +26,7 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat var inspectData *libimage.ImageData var err error if s.Image != "" { - lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true} - newImage, _, err = r.LibimageRuntime().LookupImage(s.Image, lookupOptions) + newImage, _, err = r.LibimageRuntime().LookupImage(s.Image, nil) if err != nil { return nil, err } diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go index e2901f0b6..4e3a86ae4 100644 --- a/pkg/specgen/generate/container_create.go +++ b/pkg/specgen/generate/container_create.go @@ -92,8 +92,7 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener options = append(options, libpod.WithRootFS(s.Rootfs)) } else { var resolvedImageName string - lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true} - newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, lookupOptions) + newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, nil) if err != nil { return nil, err } @@ -154,7 +153,15 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener if err != nil { return nil, err } - return rt.NewContainer(ctx, runtimeSpec, options...) + + ctr, err := rt.NewContainer(ctx, runtimeSpec, options...) + if err != nil { + return ctr, err + } + + // Copy the content from the underlying image into the newly created + // volume if configured to do so. + return ctr, rt.PrepareVolumeOnCreateContainer(ctx, ctr) } func extractCDIDevices(s *specgen.SpecGenerator) []libpod.CtrCreateOption { diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index fb563f935..fb7eb99a2 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -6,10 +6,12 @@ import ( "fmt" "net" "strings" + "time" "github.com/containers/common/libimage" "github.com/containers/common/pkg/parse" "github.com/containers/common/pkg/secrets" + "github.com/containers/image/v5/manifest" ann "github.com/containers/podman/v3/pkg/annotations" "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/specgen/generate" @@ -129,6 +131,10 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener } setupSecurityContext(s, opts.Container) + err := setupLivenessProbe(s, opts.Container, opts.RestartPolicy) + if err != nil { + return nil, errors.Wrap(err, "Failed to configure livenessProbe") + } // Since we prefix the container name with pod name to work-around the uniqueness requirement, // the seccomp profile should reference the actual container name from the YAML @@ -270,10 +276,11 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener return nil, err } + volume.MountPath = dest switch volumeSource.Type { case KubeVolumeTypeBindMount: mount := spec.Mount{ - Destination: dest, + Destination: volume.MountPath, Source: volumeSource.Source, Type: "bind", Options: options, @@ -281,7 +288,7 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener s.Mounts = append(s.Mounts, mount) case KubeVolumeTypeNamed: namedVolume := specgen.NamedVolume{ - Dest: dest, + Dest: volume.MountPath, Name: volumeSource.Source, Options: options, } @@ -324,12 +331,105 @@ func parseMountPath(mountPath string, readOnly bool) (string, []string, error) { options = strings.Split(splitVol[1], ",") } if err := parse.ValidateVolumeCtrDir(dest); err != nil { - return "", options, errors.Wrapf(err, "error in parsing MountPath") + return "", options, errors.Wrapf(err, "parsing MountPath") } if readOnly { options = append(options, "ro") } - return dest, options, nil + opts, err := parse.ValidateVolumeOpts(options) + if err != nil { + return "", opts, errors.Wrapf(err, "parsing MountOptions") + } + return dest, opts, nil +} + +func setupLivenessProbe(s *specgen.SpecGenerator, containerYAML v1.Container, restartPolicy string) error { + var err error + if containerYAML.LivenessProbe == nil { + return nil + } + emptyHandler := v1.Handler{} + if containerYAML.LivenessProbe.Handler != emptyHandler { + var commandString string + failureCmd := "exit 1" + probe := containerYAML.LivenessProbe + probeHandler := probe.Handler + + // append `exit 1` to `cmd` so healthcheck can be marked as `unhealthy`. + // append `kill 1` to `cmd` if appropriate restart policy is configured. + if restartPolicy == "always" || restartPolicy == "onfailure" { + // container will be restarted so we can kill init. + failureCmd = "kill 1" + } + + // configure healthcheck on the basis of Handler Actions. + if probeHandler.Exec != nil { + execString := strings.Join(probeHandler.Exec.Command, " ") + commandString = fmt.Sprintf("%s || %s", execString, failureCmd) + } else if probeHandler.HTTPGet != nil { + commandString = fmt.Sprintf("curl %s://%s:%d/%s || %s", probeHandler.HTTPGet.Scheme, probeHandler.HTTPGet.Host, probeHandler.HTTPGet.Port.IntValue(), probeHandler.HTTPGet.Path, failureCmd) + } else if probeHandler.TCPSocket != nil { + commandString = fmt.Sprintf("nc -z -v %s %d || %s", probeHandler.TCPSocket.Host, probeHandler.TCPSocket.Port.IntValue(), failureCmd) + } + s.HealthConfig, err = makeHealthCheck(commandString, probe.PeriodSeconds, probe.FailureThreshold, probe.TimeoutSeconds, probe.InitialDelaySeconds) + if err != nil { + return err + } + return nil + } + return nil +} + +func makeHealthCheck(inCmd string, interval int32, retries int32, timeout int32, startPeriod int32) (*manifest.Schema2HealthConfig, error) { + // Every healthcheck requires a command + if len(inCmd) == 0 { + return nil, errors.New("Must define a healthcheck command for all healthchecks") + } + + // first try to parse option value as JSON array of strings... + cmd := []string{} + + if inCmd == "none" { + cmd = []string{"NONE"} + } else { + err := json.Unmarshal([]byte(inCmd), &cmd) + if err != nil { + // ...otherwise pass it to "/bin/sh -c" inside the container + cmd = []string{"CMD-SHELL"} + cmd = append(cmd, strings.Split(inCmd, " ")...) + } + } + hc := manifest.Schema2HealthConfig{ + Test: cmd, + } + + if interval < 1 { + //kubernetes interval defaults to 10 sec and cannot be less than 1 + interval = 10 + } + hc.Interval = (time.Duration(interval) * time.Second) + if retries < 1 { + //kubernetes retries defaults to 3 + retries = 3 + } + hc.Retries = int(retries) + if timeout < 1 { + //kubernetes timeout defaults to 1 + timeout = 1 + } + timeoutDuration := (time.Duration(timeout) * time.Second) + if timeoutDuration < time.Duration(1) { + return nil, errors.New("healthcheck-timeout must be at least 1 second") + } + hc.Timeout = timeoutDuration + + startPeriodDuration := (time.Duration(startPeriod) * time.Second) + if startPeriodDuration < time.Duration(0) { + return nil, errors.New("healthcheck-start-period must be 0 seconds or greater") + } + hc.StartPeriod = startPeriodDuration + + return &hc, nil } func setupSecurityContext(s *specgen.SpecGenerator, containerYAML v1.Container) { diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go index bf8d44ed6..6e310d8a6 100644 --- a/pkg/specgen/generate/oci.go +++ b/pkg/specgen/generate/oci.go @@ -321,6 +321,10 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt } } + for _, dev := range s.DeviceCGroupRule { + g.AddLinuxResourcesDevice(true, dev.Type, dev.Major, dev.Minor, dev.Access) + } + BlockAccessToKernelFilesystems(s.Privileged, s.PidNS.IsHost(), s.Mask, s.Unmask, &g) for name, val := range s.Env { diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go index 023ebb41e..aab29499e 100644 --- a/pkg/specgen/generate/pod_create.go +++ b/pkg/specgen/generate/pod_create.go @@ -98,10 +98,18 @@ func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime) ([]libpod options = append(options, libpod.WithInfraImage(p.InfraImage)) } + if len(p.InfraName) > 0 { + options = append(options, libpod.WithInfraName(p.InfraName)) + } + if len(p.InfraCommand) > 0 { options = append(options, libpod.WithInfraCommand(p.InfraCommand)) } + if !p.Pid.IsDefault() { + options = append(options, libpod.WithPodPidNS(p.Pid)) + } + switch p.NetNS.NSMode { case specgen.Default, "": if p.NoInfra { diff --git a/pkg/specgen/pod_validate.go b/pkg/specgen/pod_validate.go index c746bcd1a..bca7b6dbe 100644 --- a/pkg/specgen/pod_validate.go +++ b/pkg/specgen/pod_validate.go @@ -36,6 +36,9 @@ func (p *PodSpecGenerator) Validate() error { if len(p.InfraImage) > 0 { return exclusivePodOptions("NoInfra", "InfraImage") } + if len(p.InfraName) > 0 { + return exclusivePodOptions("NoInfra", "InfraName") + } if len(p.SharedNamespaces) > 0 { return exclusivePodOptions("NoInfra", "SharedNamespaces") } diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go index 000a787ea..02237afe9 100644 --- a/pkg/specgen/podspecgen.go +++ b/pkg/specgen/podspecgen.go @@ -43,6 +43,12 @@ type PodBasicConfig struct { // Conflicts with NoInfra=true. // Optional. InfraImage string `json:"infra_image,omitempty"` + // InfraName is the name that will be used for the infra container. + // If not set, the default set in the Libpod configuration file will be + // used. + // Conflicts with NoInfra=true. + // Optional. + InfraName string `json:"infra_name,omitempty"` // SharedNamespaces instructs the pod to share a set of namespaces. // Shared namespaces will be joined (by default) by every container // which joins the pod. @@ -57,6 +63,10 @@ type PodBasicConfig struct { // (e.g. `podman generate systemd --new`). // Optional. PodCreateCommand []string `json:"pod_create_command,omitempty"` + // Pid sets the process id namespace of the pod + // Optional (defaults to private if unset). This sets the PID namespace of the infra container + // This configuration will then be shared with the entire pod if PID namespace sharing is enabled via --share + Pid Namespace `json:"pid,omitempty:"` } // PodNetworkConfig contains networking configuration for a pod. diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go index c5cc726d7..7eec48a55 100644 --- a/pkg/specgen/specgen.go +++ b/pkg/specgen/specgen.go @@ -239,6 +239,9 @@ type ContainerStorageConfig struct { // Devices are devices that will be added to the container. // Optional. Devices []spec.LinuxDevice `json:"devices,omitempty"` + // DeviceCGroupRule are device cgroup rules that allow containers + // to use additional types of devices. + DeviceCGroupRule []spec.LinuxDeviceCgroup `json:"device_cgroup_rule,omitempty"` // IpcNS is the container's IPC namespace. // Default is private. // Conflicts with ShmSize if not set to private. diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go index e183125a7..349805980 100644 --- a/pkg/systemd/generate/common.go +++ b/pkg/systemd/generate/common.go @@ -34,7 +34,7 @@ const headerTemplate = `# {{{{.ServiceName}}}}.service [Unit] Description=Podman {{{{.ServiceName}}}}.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor={{{{.RunRoot}}}} ` diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go index 12a8f3004..1d24cc4a9 100644 --- a/pkg/systemd/generate/containers_test.go +++ b/pkg/systemd/generate/containers_test.go @@ -46,7 +46,7 @@ func TestCreateContainerSystemdUnit(t *testing.T) { [Unit] Description=Podman container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -72,7 +72,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman container-foobar.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -96,7 +96,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman container-foobar.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage BindsTo=a.service b.service c.service pod.service @@ -122,7 +122,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -144,7 +144,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -166,7 +166,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -188,7 +188,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -210,7 +210,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -233,7 +233,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -259,7 +259,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -281,7 +281,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -303,7 +303,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -325,7 +325,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -347,7 +347,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -369,7 +369,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -391,7 +391,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage @@ -413,7 +413,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman jadda-jadda.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go index a11e1e11e..4b8a9ffd5 100644 --- a/pkg/systemd/generate/pods_test.go +++ b/pkg/systemd/generate/pods_test.go @@ -45,7 +45,7 @@ func TestCreatePodSystemdUnit(t *testing.T) { [Unit] Description=Podman pod-123abc.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage Requires=container-1.service container-2.service @@ -73,7 +73,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman pod-123abc.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage Requires=container-1.service container-2.service @@ -101,7 +101,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman pod-123abc.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage Requires=container-1.service container-2.service @@ -129,7 +129,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman pod-123abc.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage Requires=container-1.service container-2.service @@ -157,7 +157,7 @@ WantedBy=multi-user.target default.target [Unit] Description=Podman pod-123abc.service Documentation=man:podman-generate-systemd(1) -Wants=network.target +Wants=network-online.target After=network-online.target RequiresMountsFor=/var/run/containers/storage Requires=container-1.service container-2.service diff --git a/test/README.md b/test/README.md index d7710cc95..769bdbfd7 100644 --- a/test/README.md +++ b/test/README.md @@ -84,7 +84,7 @@ file itself. Consider the following actual test: It("podman inspect bogus pod", func() { session := podmanTest.Podman([]string{"pod", "inspect", "foobar"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) ``` diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at index 9e464dbc7..195b11ff0 100644 --- a/test/apiv2/10-images.at +++ b/test/apiv2/10-images.at @@ -45,6 +45,11 @@ t POST "images/create?fromImage=alpine" 200 .error~null .status~".*Download comp t POST "images/create?fromImage=alpine&tag=latest" 200 +# 10977 - handle platform parameter correctly +t POST "images/create?fromImage=alpine&platform=linux/arm64" 200 +t GET "images/alpine/json" 200 \ + .Architecture=arm64 + # Make sure that new images are pulled old_iid=$(podman image inspect --format "{{.ID}}" docker.io/library/alpine:latest) podman rmi -f docker.io/library/alpine:latest diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at index ef51757c9..c5b2f5ec1 100644 --- a/test/apiv2/20-containers.at +++ b/test/apiv2/20-containers.at @@ -211,15 +211,11 @@ t GET containers/$cid/json 200 \ t POST containers/create Image=$IMAGE Entrypoint='["top"]' 201 \ .Id~[0-9a-f]\\{64\\} cid_top=$(jq -r '.Id' <<<"$output") -network_expect="{}" -if root; then - network_expect='.podman.NetworkID=podman' -fi t GET containers/${cid_top}/json 200 \ .Config.Entrypoint[0]="top" \ .Config.Cmd='[]' \ - .Path="top" - .NetworkSettings.Networks="$network_expect" + .Path="top" \ + .NetworkSettings.Networks.podman.NetworkID=podman t POST containers/${cid_top}/start 204 # make sure the container is running t GET containers/${cid_top}/json 200 \ diff --git a/test/apiv2/30-volumes.at b/test/apiv2/30-volumes.at index 5feceea7b..fd1542293 100644 --- a/test/apiv2/30-volumes.at +++ b/test/apiv2/30-volumes.at @@ -13,13 +13,14 @@ t POST libpod/volumes/create name=foo1 201 \ .CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \ .Labels={} \ .Options={} +# TODO(mwhahaha): there might be a bug here since options is null and not {} t POST volumes/create 201 \ - .Name~[0-9a-f]\\{64\\} + .Name~[0-9a-f]\\{64\\} \ .Driver=local \ - .Mountpoint=$volumepath/~[0-9a-f]\\{64\\}/_data \ + .Mountpoint~$volumepath/[0-9a-f]\\{64\\}/_data \ .CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \ .Labels={} \ - .Options={} + .Options=null t POST libpod/volumes/create 201 t POST libpod/volumes/create \ Name=foo2 \ @@ -173,6 +174,8 @@ t POST libpod/volumes/create \ # with date way back in the past, volume should not be deleted (compat api) t POST volumes/prune?filters='{"until":["500000"]}' 200 t GET libpod/volumes/json?filters='{"label":["testuntilcompat"]}' 200 length=1 +t GET libpod/volumes/json?filters='{"until":["500000"]}' 200 length=0 +t GET libpod/volumes/json?filters='{"until":["5000000000"]}' 200 length=1 # with date far in the future, volume should be deleted (compat api) t POST volumes/prune?filters='{"until":["5000000000"]}' 200 diff --git a/test/apiv2/35-networks.at b/test/apiv2/35-networks.at index 59947faac..7a36b605f 100644 --- a/test/apiv2/35-networks.at +++ b/test/apiv2/35-networks.at @@ -142,4 +142,18 @@ t GET networks?filters='{"label":["zaq"]}' 200 length=1 t POST networks/prune?filters='{"until":["5000000000"]}' 200 t GET networks?filters='{"label":["zaq"]}' 200 length=0 +# test macvlan network response +podman network create --driver macvlan macvlan1 + +# libpod api inspect the macvlan network +t GET libpod/networks/macvlan1/json 200 .name="macvlan1" + +# compat api inspect the macvlan network +t GET networks/macvlan1 200 .Name="macvlan1" + +# clean the macvlan network +t DELETE libpod/networks/macvlan1 200 \ + .[0].Name~macvlan1 \ + .[0].Err=null + # vim: filetype=sh diff --git a/test/apiv2/test-apiv2 b/test/apiv2/test-apiv2 index 9f6bf257f..26619ae03 100755 --- a/test/apiv2/test-apiv2 +++ b/test/apiv2/test-apiv2 @@ -442,10 +442,10 @@ function random_string() { function wait_for_port() { local host=$1 # Probably "localhost" local port=$2 # Numeric port - local timeout=${3:-5} # Optional; default to 5 seconds + local _timeout=${3:-5} # Optional; default to 5 seconds # Wait - while [ $timeout -gt 0 ]; do + while [ $_timeout -gt 0 ]; do { exec 3<> /dev/tcp/$host/$port; } &>/dev/null && return sleep 1 _timeout=$(( $_timeout - 1 )) diff --git a/test/buildah-bud/apply-podman-deltas b/test/buildah-bud/apply-podman-deltas index 0bf9f298d..41c84257f 100755 --- a/test/buildah-bud/apply-podman-deltas +++ b/test/buildah-bud/apply-podman-deltas @@ -155,6 +155,10 @@ skip "FIXME FIXME FIXME we'll figure these out later" \ skip "FIXME FIXME FIXME podman save/load has been fixed (but not yet used in Buildah CI)" \ "bud with --layers and --no-cache flags" +# see https://github.com/containers/podman/pull/10829 +skip "FIXME FIXME FIXME - requires updated CI images (#10829)" \ + "bud with --runtime and --runtime-flag" + ############################################################################### # BEGIN tests which are skipped due to actual podman bugs. diff --git a/test/e2e/attach_test.go b/test/e2e/attach_test.go index 146ff27a5..5843462f2 100644 --- a/test/e2e/attach_test.go +++ b/test/e2e/attach_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman attach", func() { @@ -36,48 +37,48 @@ var _ = Describe("Podman attach", func() { It("podman attach to bogus container", func() { session := podmanTest.Podman([]string{"attach", "foobar"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman attach to non-running container", func() { session := podmanTest.Podman([]string{"create", "--name", "test1", "-i", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) results := podmanTest.Podman([]string{"attach", "test1"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(125)) + Expect(results).Should(Exit(125)) }) It("podman container attach to non-running container", func() { session := podmanTest.Podman([]string{"container", "create", "--name", "test1", "-i", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) results := podmanTest.Podman([]string{"container", "attach", "test1"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(125)) + Expect(results).Should(Exit(125)) }) It("podman attach to multiple containers", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainer("test2") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) results := podmanTest.Podman([]string{"attach", "test1", "test2"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(125)) + Expect(results).Should(Exit(125)) }) It("podman attach to a running container", func() { session := podmanTest.Podman([]string{"run", "-d", "--name", "test", ALPINE, "/bin/sh", "-c", "while true; do echo test; sleep 1; done"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) results := podmanTest.Podman([]string{"attach", "test"}) time.Sleep(2 * time.Second) @@ -88,11 +89,11 @@ var _ = Describe("Podman attach", func() { It("podman attach to the latest container", func() { session := podmanTest.Podman([]string{"run", "-d", "--name", "test1", ALPINE, "/bin/sh", "-c", "while true; do echo test1; sleep 1; done"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "-d", "--name", "test2", ALPINE, "/bin/sh", "-c", "while true; do echo test2; sleep 1; done"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := "-l" if IsRemote() { @@ -108,7 +109,7 @@ var _ = Describe("Podman attach", func() { It("podman attach to a container with --sig-proxy set to false", func() { session := podmanTest.Podman([]string{"run", "-d", "--name", "test", ALPINE, "/bin/sh", "-c", "while true; do echo test; sleep 1; done"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) results := podmanTest.Podman([]string{"attach", "--sig-proxy=false", "test"}) time.Sleep(2 * time.Second) diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go index abaacdd5e..aca2b831b 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -12,6 +12,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman build", func() { @@ -42,7 +43,7 @@ var _ = Describe("Podman build", func() { podmanTest.AddImageToRWStore(ALPINE) session := podmanTest.Podman([]string{"build", "--pull-never", "build/basicalpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) iid := session.OutputToStringArray()[len(session.OutputToStringArray())-1] @@ -55,14 +56,14 @@ var _ = Describe("Podman build", func() { session = podmanTest.Podman([]string{"rmi", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman build with logfile", func() { logfile := filepath.Join(podmanTest.TempDir, "logfile") session := podmanTest.Podman([]string{"build", "--pull-never", "--tag", "test", "--logfile", logfile, "build/basicalpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Verify that OS and Arch are being set inspect := podmanTest.Podman([]string{"inspect", "test"}) @@ -77,7 +78,7 @@ var _ = Describe("Podman build", func() { session = podmanTest.Podman([]string{"rmi", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) // If the context directory is pointing at a file and not a directory, @@ -85,7 +86,7 @@ var _ = Describe("Podman build", func() { It("podman build context directory a file", func() { session := podmanTest.Podman([]string{"build", "--pull-never", "build/context_dir_a_file"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) // Check that builds with different values for the squash options @@ -93,47 +94,47 @@ var _ = Describe("Podman build", func() { It("podman build basic alpine with squash", func() { session := podmanTest.Podman([]string{"build", "--pull-never", "-f", "build/squash/Dockerfile.squash-a", "-t", "test-squash-a:latest", "build/squash"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.RootFS.Layers}}", "test-squash-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Check for two layers Expect(len(strings.Fields(session.OutputToString()))).To(Equal(2)) session = podmanTest.Podman([]string{"build", "--pull-never", "-f", "build/squash/Dockerfile.squash-b", "--squash", "-t", "test-squash-b:latest", "build/squash"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.RootFS.Layers}}", "test-squash-b"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Check for three layers Expect(len(strings.Fields(session.OutputToString()))).To(Equal(3)) session = podmanTest.Podman([]string{"build", "--pull-never", "-f", "build/squash/Dockerfile.squash-c", "--squash", "-t", "test-squash-c:latest", "build/squash"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.RootFS.Layers}}", "test-squash-c"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Check for two layers Expect(len(strings.Fields(session.OutputToString()))).To(Equal(2)) session = podmanTest.Podman([]string{"build", "--pull-never", "-f", "build/squash/Dockerfile.squash-c", "--squash-all", "-t", "test-squash-d:latest", "build/squash"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.RootFS.Layers}}", "test-squash-d"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Check for one layers Expect(len(strings.Fields(session.OutputToString()))).To(Equal(1)) session = podmanTest.Podman([]string{"rm", "-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman build Containerfile locations", func() { @@ -168,7 +169,7 @@ var _ = Describe("Podman build", func() { session.WaitWithDefaultTimeout() // Then - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(strings.Fields(session.OutputToString())). To(ContainElement("scratch")) }) @@ -188,7 +189,7 @@ var _ = Describe("Podman build", func() { session := podmanTest.Podman([]string{"build", "--pull-never", "build/basicalpine", "--iidfile", targetFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) id, _ := ioutil.ReadFile(targetFile) // Verify that id is correct @@ -204,11 +205,11 @@ var _ = Describe("Podman build", func() { "build", "--pull-never", "-f", "build/basicalpine/Containerfile.path", "-t", "test-path", }) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "test-path", "printenv", "PATH"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) stdoutLines := session.OutputToStringArray() Expect(stdoutLines[0]).Should(Equal(path)) }) @@ -228,7 +229,7 @@ RUN printenv http_proxy`, ALPINE) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "--http-proxy", "--file", dockerfilePath, podmanTest.TempDir}) session.Wait(120) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString("1.2.3.4") Expect(ok).To(BeTrue()) os.Unsetenv("http_proxy") @@ -237,7 +238,7 @@ RUN printenv http_proxy`, ALPINE) It("podman build and check identity", func() { session := podmanTest.Podman([]string{"build", "--pull-never", "-f", "build/basicalpine/Containerfile.path", "--no-cache", "-t", "test", "build/basicalpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Verify that OS and Arch are being set inspect := podmanTest.Podman([]string{"image", "inspect", "--format", "{{ index .Config.Labels }}", "test"}) @@ -282,7 +283,7 @@ RUN find /test`, ALPINE) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "-f", "Containerfile", targetSubPath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString("/test/dummy") Expect(ok).To(BeTrue()) }) @@ -324,7 +325,7 @@ RUN find /test`, ALPINE) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "-f", "subdir/Containerfile", "."}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman remote test .dockerignore", func() { @@ -388,7 +389,7 @@ subdir**` session := podmanTest.Podman([]string{"build", "-t", "test", "."}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString("/testfilter/dummy1") Expect(ok).NotTo(BeTrue()) ok, _ = session.GrepString("/testfilter/dummy2") @@ -448,7 +449,7 @@ RUN [[ -L /test/dummy-symlink ]] && echo SYMLNKOK || echo SYMLNKERR`, ALPINE) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", targetSubPath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString("/test/dummy") Expect(ok).To(BeTrue()) ok, _ = session.GrepString("/test/emptyDir") @@ -481,7 +482,7 @@ RUN grep CapEff /proc/self/status` session.WaitWithDefaultTimeout() // Then - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(strings.Fields(session.OutputToString())). To(ContainElement(ALPINE)) Expect(strings.Fields(session.OutputToString())). @@ -507,7 +508,7 @@ RUN grep CapEff /proc/self/status` }) session.WaitWithDefaultTimeout() // Then - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // When session = podmanTest.Podman([]string{ @@ -515,7 +516,7 @@ RUN grep CapEff /proc/self/status` }) session.WaitWithDefaultTimeout() // Then - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // When session = podmanTest.Podman([]string{ @@ -523,7 +524,7 @@ RUN grep CapEff /proc/self/status` }) session.WaitWithDefaultTimeout() // Then - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // When session = podmanTest.Podman([]string{ @@ -531,7 +532,7 @@ RUN grep CapEff /proc/self/status` }) session.WaitWithDefaultTimeout() // Then - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman build --timestamp flag", func() { @@ -543,7 +544,7 @@ RUN echo hello`, ALPINE) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--timestamp", "0", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"image", "inspect", "--format", "{{ .Created }}", "test"}) inspect.WaitWithDefaultTimeout() @@ -561,7 +562,7 @@ RUN echo hello`, ALPINE) session := podmanTest.Podman([]string{"build", "--log-rusage", "--pull-never", targetPath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("(system)")) Expect(session.OutputToString()).To(ContainSubstring("(user)")) Expect(session.OutputToString()).To(ContainSubstring("(elapsed)")) @@ -574,7 +575,7 @@ RUN echo hello`, ALPINE) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--arch", "foo", "--os", "bar", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"image", "inspect", "--format", "{{ .Architecture }}", "test"}) inspect.WaitWithDefaultTimeout() @@ -593,7 +594,7 @@ RUN echo hello`, ALPINE) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--os", "windows", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"image", "inspect", "--format", "{{ .Architecture }}", "test"}) inspect.WaitWithDefaultTimeout() @@ -616,11 +617,11 @@ RUN ls /dev/fuse`, ALPINE) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) session = podmanTest.Podman([]string{"build", "--pull-never", "--device", "/dev/fuse", "-t", "test", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman build device rename test", func() { @@ -632,10 +633,10 @@ RUN ls /dev/test1`, ALPINE) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) session = podmanTest.Podman([]string{"build", "--pull-never", "--device", "/dev/zero:/dev/test1", "-t", "test", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) }) diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index 70a1d09ed..1c9a8dc6f 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -1,15 +1,18 @@ package integration import ( + "fmt" "net" "os" "os/exec" "strings" + "github.com/containers/podman/v3/pkg/checkpoint/crutils" "github.com/containers/podman/v3/pkg/criu" . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) func getRunString(input []string) []string { @@ -45,7 +48,7 @@ var _ = Describe("Podman checkpoint", func() { Skip("OCI runtime does not support checkpoint/restore") } - if !criu.CheckForCriu() { + if !criu.CheckForCriu(criu.MinCriuVersion) { Skip("CRIU is missing or too old.") } // Only Fedora 29 and newer has a new enough selinux-policy and @@ -80,20 +83,20 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"container", "checkpoint", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) result = podmanTest.Podman([]string{"container", "restore", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) }) @@ -102,19 +105,19 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{"--name", "test_name", ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"container", "checkpoint", "test_name"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) result = podmanTest.Podman([]string{"container", "restore", "test_name"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) }) @@ -123,36 +126,36 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"container", "checkpoint", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) result = podmanTest.Podman([]string{"pause", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) result = podmanTest.Podman([]string{"container", "restore", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) result = podmanTest.Podman([]string{"rm", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(2)) + Expect(result).Should(Exit(2)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) result = podmanTest.Podman([]string{"rm", "-f", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -161,36 +164,36 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{"--name", "first", ALPINE, "top"}) session1 := podmanTest.Podman(localRunString) session1.WaitWithDefaultTimeout() - Expect(session1.ExitCode()).To(Equal(0)) + Expect(session1).Should(Exit(0)) localRunString = getRunString([]string{"--name", "second", ALPINE, "top"}) session2 := podmanTest.Podman(localRunString) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) result := podmanTest.Podman([]string{"container", "checkpoint", "-l"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) ps := podmanTest.Podman([]string{"ps", "-q", "--no-trunc"}) ps.WaitWithDefaultTimeout() - Expect(ps.ExitCode()).To(Equal(0)) + Expect(ps).Should(Exit(0)) Expect(ps.LineInOutputContains(session1.OutputToString())).To(BeTrue()) Expect(ps.LineInOutputContains(session2.OutputToString())).To(BeFalse()) result = podmanTest.Podman([]string{"container", "restore", "-l"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) Expect(podmanTest.GetContainerStatus()).To(Not(ContainSubstring("Exited"))) result = podmanTest.Podman([]string{"rm", "-fa"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -198,36 +201,36 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{"--name", "first", ALPINE, "top"}) session1 := podmanTest.Podman(localRunString) session1.WaitWithDefaultTimeout() - Expect(session1.ExitCode()).To(Equal(0)) + Expect(session1).Should(Exit(0)) localRunString = getRunString([]string{"--name", "second", ALPINE, "top"}) session2 := podmanTest.Podman(localRunString) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) result := podmanTest.Podman([]string{"container", "checkpoint", "-a"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) ps := podmanTest.Podman([]string{"ps", "-q", "--no-trunc"}) ps.WaitWithDefaultTimeout() - Expect(ps.ExitCode()).To(Equal(0)) + Expect(ps).Should(Exit(0)) Expect(ps.LineInOutputContains(session1.OutputToString())).To(BeFalse()) Expect(ps.LineInOutputContains(session2.OutputToString())).To(BeFalse()) result = podmanTest.Podman([]string{"container", "restore", "-a"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) Expect(podmanTest.GetContainerStatus()).To(Not(ContainSubstring("Exited"))) result = podmanTest.Podman([]string{"rm", "-fa"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -237,11 +240,11 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{redis}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) IP := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.IPAddress}}"}) IP.WaitWithDefaultTimeout() - Expect(IP.ExitCode()).To(Equal(0)) + Expect(IP).Should(Exit(0)) // Open a network connection to the redis server conn, err := net.Dial("tcp", IP.OutputToString()+":6379") @@ -252,7 +255,7 @@ var _ = Describe("Podman checkpoint", func() { result := podmanTest.Podman([]string{"container", "checkpoint", "-l"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -260,7 +263,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "--tcp-established"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) @@ -268,7 +271,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "-l"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) @@ -276,13 +279,13 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "-l", "--tcp-established"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) result = podmanTest.Podman([]string{"rm", "-fa"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) conn.Close() @@ -292,14 +295,14 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() // Checkpoint container, but leave it running result := podmanTest.Podman([]string{"container", "checkpoint", "--leave-running", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) // Make sure it is still running Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -308,7 +311,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "stop", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) @@ -316,13 +319,13 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) result = podmanTest.Podman([]string{"rm", "-fa"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -330,20 +333,20 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{"--name", "test_name", ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) IPBefore := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.IPAddress}}"}) IPBefore.WaitWithDefaultTimeout() - Expect(IPBefore.ExitCode()).To(Equal(0)) + Expect(IPBefore).Should(Exit(0)) MACBefore := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.MacAddress}}"}) MACBefore.WaitWithDefaultTimeout() - Expect(MACBefore.ExitCode()).To(Equal(0)) + Expect(MACBefore).Should(Exit(0)) result := podmanTest.Podman([]string{"container", "checkpoint", "test_name"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) @@ -352,11 +355,11 @@ var _ = Describe("Podman checkpoint", func() { IPAfter := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.IPAddress}}"}) IPAfter.WaitWithDefaultTimeout() - Expect(IPAfter.ExitCode()).To(Equal(0)) + Expect(IPAfter).Should(Exit(0)) MACAfter := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.MacAddress}}"}) MACAfter.WaitWithDefaultTimeout() - Expect(MACAfter.ExitCode()).To(Equal(0)) + Expect(MACAfter).Should(Exit(0)) // Check that IP address did not change between checkpointing and restoring Expect(IPBefore.OutputToString()).To(Equal(IPAfter.OutputToString())) @@ -364,13 +367,13 @@ var _ = Describe("Podman checkpoint", func() { // Check that MAC address did not change between checkpointing and restoring Expect(MACBefore.OutputToString()).To(Equal(MACAfter.OutputToString())) - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) result = podmanTest.Podman([]string{"rm", "-fa"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -380,7 +383,7 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{"--rm", ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) cid := session.OutputToString() fileName := "/tmp/checkpoint-" + cid + ".tar.gz" @@ -390,7 +393,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -405,20 +408,20 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "-i", fileName, "-n", "restore_again", "--ignore-static-ip"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) result = podmanTest.Podman([]string{"rm", "-fa"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -431,7 +434,7 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{"--rm", ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) cid := session.OutputToString() fileName := "/tmp/checkpoint-" + cid + ".tar" @@ -442,7 +445,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -450,7 +453,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -460,7 +463,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -468,7 +471,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -478,7 +481,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -486,7 +489,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -496,7 +499,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -504,7 +507,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -512,13 +515,13 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName, "-c", "non-existing"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) result = podmanTest.Podman([]string{"rm", "-fa"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -531,7 +534,7 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{"--rm", ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) cid := session.OutputToString() fileName := "/tmp/checkpoint-" + cid + ".tar.gz" @@ -539,15 +542,15 @@ var _ = Describe("Podman checkpoint", func() { // Change the container's root file-system result := podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "rm /etc/motd"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"diff", "-l"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring("C /etc")) Expect(result.OutputToString()).To(ContainSubstring("A /test.output")) Expect(result.OutputToString()).To(ContainSubstring("D /etc/motd")) @@ -557,7 +560,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -565,7 +568,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -573,12 +576,12 @@ var _ = Describe("Podman checkpoint", func() { // Verify the changes to the container's root file-system result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring("test" + cid + "test")) result = podmanTest.Podman([]string{"diff", "-l"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring("C /etc")) Expect(result.OutputToString()).To(ContainSubstring("A /test.output")) Expect(result.OutputToString()).To(ContainSubstring("D /etc/motd")) @@ -592,7 +595,7 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{"--rm", ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) cid := session.OutputToString() fileName := "/tmp/checkpoint-" + cid + ".tar.gz" @@ -600,13 +603,13 @@ var _ = Describe("Podman checkpoint", func() { // Change the container's root file-system result := podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) // Checkpoint the container result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -614,7 +617,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "--ignore-rootfs", "-i", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -622,7 +625,7 @@ var _ = Describe("Podman checkpoint", func() { // Verify the changes to the container's root file-system result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(1)) + Expect(result).Should(Exit(1)) Expect(result.ErrorToString()).To(ContainSubstring("cat: can't open '/test.output': No such file or directory")) // Remove exported checkpoint @@ -633,7 +636,7 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{"--rm", ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) cid := session.OutputToString() fileName := "/tmp/checkpoint-" + cid + ".tar.gz" @@ -641,13 +644,13 @@ var _ = Describe("Podman checkpoint", func() { // Change the container's root file-system result := podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) // Checkpoint the container result = podmanTest.Podman([]string{"container", "checkpoint", "--ignore-rootfs", "-l", "-e", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -655,7 +658,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -663,7 +666,7 @@ var _ = Describe("Podman checkpoint", func() { // Verify the changes to the container's root file-system result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(1)) + Expect(result).Should(Exit(1)) Expect(result.ErrorToString()).To(ContainSubstring("cat: can't open '/test.output': No such file or directory")) // Remove exported checkpoint @@ -675,7 +678,7 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{"--rm", ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) cid := session.OutputToString() fileName := "/tmp/checkpoint-" + cid + ".tar.gz" @@ -684,7 +687,7 @@ var _ = Describe("Podman checkpoint", func() { result := podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -692,7 +695,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -700,11 +703,11 @@ var _ = Describe("Podman checkpoint", func() { // Exec in the container result = podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo " + cid + " > /test.output"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(cid)) // Remove exported checkpoint @@ -733,20 +736,20 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) result = podmanTest.Podman([]string{"rm", "-fa"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -759,7 +762,7 @@ var _ = Describe("Podman checkpoint", func() { "build", "-f", "build/basicalpine/Containerfile.volume", "-t", "test-cr-volume", }) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Start the container localRunString := getRunString([]string{ @@ -771,7 +774,7 @@ var _ = Describe("Podman checkpoint", func() { }) session = podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) cid := session.OutputToString() @@ -781,28 +784,28 @@ var _ = Describe("Podman checkpoint", func() { "exec", "-l", "/bin/sh", "-c", "echo " + cid + " > /volume0/test.output", }) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) // Add file in volume1 result = podmanTest.Podman([]string{ "exec", "-l", "/bin/sh", "-c", "echo " + cid + " > /volume1/test.output", }) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) // Add file in volume2 result = podmanTest.Podman([]string{ "exec", "-l", "/bin/sh", "-c", "echo " + cid + " > /volume2/test.output", }) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) checkpointFileName := "/tmp/checkpoint-" + cid + ".tar.gz" // Checkpoint the container result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", checkpointFileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -817,12 +820,12 @@ var _ = Describe("Podman checkpoint", func() { // Remove named volume session = podmanTest.Podman([]string{"volume", "rm", "my-test-vol"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Restoring container result = podmanTest.Podman([]string{"container", "restore", "-i", checkpointFileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -830,19 +833,19 @@ var _ = Describe("Podman checkpoint", func() { // Validate volume0 content result = podmanTest.Podman([]string{"exec", "-l", "cat", "/volume0/test.output"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(cid)) // Validate volume1 content result = podmanTest.Podman([]string{"exec", "-l", "cat", "/volume1/test.output"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(cid)) // Validate volume2 content result = podmanTest.Podman([]string{"exec", "-l", "cat", "/volume2/test.output"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(cid)) // Remove exported checkpoint @@ -856,27 +859,27 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"container", "checkpoint", "-P", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) result = podmanTest.Podman([]string{"container", "checkpoint", "--with-previous", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) result = podmanTest.Podman([]string{"container", "restore", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) }) @@ -888,7 +891,7 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{ALPINE, "top"}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() preCheckpointFileName := "/tmp/pre-checkpoint-" + cid + ".tar.gz" checkpointFileName := "/tmp/checkpoint-" + cid + ".tar.gz" @@ -896,26 +899,26 @@ var _ = Describe("Podman checkpoint", func() { result := podmanTest.Podman([]string{"container", "checkpoint", "-P", "-e", preCheckpointFileName, cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) result = podmanTest.Podman([]string{"container", "checkpoint", "--with-previous", "-e", checkpointFileName, cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) result = podmanTest.Podman([]string{"rm", "-f", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) result = podmanTest.Podman([]string{"container", "restore", "-i", checkpointFileName, "--import-previous", preCheckpointFileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -927,7 +930,7 @@ var _ = Describe("Podman checkpoint", func() { localRunString := getRunString([]string{"-p", "1234:6379", "--rm", redis}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() fileName := "/tmp/checkpoint-" + cid + ".tar.gz" @@ -944,7 +947,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -952,7 +955,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "-p", "1235:6379", "-i", fileName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) @@ -969,11 +972,171 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"rm", "-fa"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) // Remove exported checkpoint os.Remove(fileName) }) + + namespaceCombination := []string{ + "cgroup,ipc,net,uts,pid", + "cgroup,ipc,net,uts", + "cgroup,ipc,net", + "cgroup,ipc", + "ipc,net,uts,pid", + "ipc,net,uts", + "ipc,net", + "net,uts,pid", + "net,uts", + "uts,pid", + } + for _, share := range namespaceCombination { + testName := fmt.Sprintf( + "podman checkpoint and restore container out of and into pod (%s)", + share, + ) + It(testName, func() { + if !criu.CheckForCriu(criu.PodCriuVersion) { + Skip("CRIU is missing or too old.") + } + if !crutils.CRRuntimeSupportsPodCheckpointRestore(podmanTest.OCIRuntime) { + Skip("runtime does not support pod restore") + } + // Create a pod + session := podmanTest.Podman([]string{ + "pod", + "create", + "--share", + share, + }) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + podID := session.OutputToString() + + session = podmanTest.Podman([]string{ + "run", + "-d", + "--rm", + "--pod", + podID, + ALPINE, + "top", + }) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + cid := session.OutputToString() + + fileName := "/tmp/checkpoint-" + cid + ".tar.gz" + + // Checkpoint the container + result := podmanTest.Podman([]string{ + "container", + "checkpoint", + "-e", + fileName, + cid, + }) + result.WaitWithDefaultTimeout() + + // As the container has been started with '--rm' it will be completely + // cleaned up after checkpointing. + Expect(result).To(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + Expect(podmanTest.NumberOfContainers()).To(Equal(1)) + + // Remove the pod and create a new pod + result = podmanTest.Podman([]string{ + "pod", + "rm", + podID, + }) + result.WaitWithDefaultTimeout() + Expect(result).To(Exit(0)) + + // First create a pod with different shared namespaces. + // Restore should fail + + wrongShare := share[:strings.LastIndex(share, ",")] + + session = podmanTest.Podman([]string{ + "pod", + "create", + "--share", + wrongShare, + }) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + podID = session.OutputToString() + + // Restore container with different port mapping + result = podmanTest.Podman([]string{ + "container", + "restore", + "--pod", + podID, + "-i", + fileName, + }) + result.WaitWithDefaultTimeout() + Expect(result).To(Exit(125)) + Expect(result.ErrorToString()).To(ContainSubstring("does not share the")) + + // Remove the pod and create a new pod + result = podmanTest.Podman([]string{ + "pod", + "rm", + podID, + }) + result.WaitWithDefaultTimeout() + Expect(result).To(Exit(0)) + + session = podmanTest.Podman([]string{ + "pod", + "create", + "--share", + share, + }) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + podID = session.OutputToString() + + // Restore container with different port mapping + result = podmanTest.Podman([]string{ + "container", + "restore", + "--pod", + podID, + "-i", + fileName, + }) + result.WaitWithDefaultTimeout() + + Expect(result).To(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) + + result = podmanTest.Podman([]string{ + "rm", + "-f", + result.OutputToString(), + }) + result.WaitWithDefaultTimeout() + Expect(result).To(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + Expect(podmanTest.NumberOfContainers()).To(Equal(1)) + + result = podmanTest.Podman([]string{ + "pod", + "rm", + "-fa", + }) + result.WaitWithDefaultTimeout() + Expect(result).To(Exit(0)) + + // Remove exported checkpoint + os.Remove(fileName) + }) + } }) diff --git a/test/e2e/commit_test.go b/test/e2e/commit_test.go index 70a66124a..0a368b10f 100644 --- a/test/e2e/commit_test.go +++ b/test/e2e/commit_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman commit", func() { @@ -41,7 +42,7 @@ var _ = Describe("Podman commit", func() { session := podmanTest.Podman([]string{"commit", "test1", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"}) check.WaitWithDefaultTimeout() @@ -56,7 +57,7 @@ var _ = Describe("Podman commit", func() { session := podmanTest.Podman([]string{"commit", "test1", "a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"inspect", "localhost/a:latest"}) check.WaitWithDefaultTimeout() @@ -71,7 +72,7 @@ var _ = Describe("Podman commit", func() { session := podmanTest.Podman([]string{"container", "commit", "test1", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"image", "inspect", "foobar.com/test1-image:latest"}) check.WaitWithDefaultTimeout() @@ -86,7 +87,7 @@ var _ = Describe("Podman commit", func() { session := podmanTest.Podman([]string{"commit", "-f", "docker", "--message", "testing-commit", "test1", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"}) check.WaitWithDefaultTimeout() @@ -101,7 +102,7 @@ var _ = Describe("Podman commit", func() { session := podmanTest.Podman([]string{"commit", "--author", "snoopy", "test1", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"}) check.WaitWithDefaultTimeout() @@ -112,12 +113,12 @@ var _ = Describe("Podman commit", func() { It("podman commit container with change flag", func() { test := podmanTest.Podman([]string{"run", "--name", "test1", "-d", ALPINE, "ls"}) test.WaitWithDefaultTimeout() - Expect(test.ExitCode()).To(Equal(0)) + Expect(test).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) session := podmanTest.Podman([]string{"commit", "--change", "LABEL=image=blue", "test1", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"}) check.WaitWithDefaultTimeout() @@ -135,12 +136,12 @@ var _ = Describe("Podman commit", func() { It("podman commit container with change flag and JSON entrypoint with =", func() { test := podmanTest.Podman([]string{"run", "--name", "test1", "-d", ALPINE, "ls"}) test.WaitWithDefaultTimeout() - Expect(test.ExitCode()).To(Equal(0)) + Expect(test).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) session := podmanTest.Podman([]string{"commit", "--change", `ENTRYPOINT ["foo", "bar=baz"]`, "test1", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"}) check.WaitWithDefaultTimeout() @@ -154,25 +155,25 @@ var _ = Describe("Podman commit", func() { It("podman commit container with change CMD flag", func() { test := podmanTest.Podman([]string{"run", "--name", "test1", "-d", ALPINE, "ls"}) test.WaitWithDefaultTimeout() - Expect(test.ExitCode()).To(Equal(0)) + Expect(test).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) session := podmanTest.Podman([]string{"commit", "--change", "CMD a b c", "test1", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.Config.Cmd}}", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("sh -c a b c")) session = podmanTest.Podman([]string{"commit", "--change", "CMD=[\"a\",\"b\",\"c\"]", "test1", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.Config.Cmd}}", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(ContainSubstring("sh -c"))) }) @@ -183,25 +184,25 @@ var _ = Describe("Podman commit", func() { session := podmanTest.Podman([]string{"commit", "--pause=false", "test1", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) }) It("podman commit with volumes mounts and no include-volumes", func() { s := podmanTest.Podman([]string{"run", "--name", "test1", "-v", "/tmp:/foo", "alpine", "date"}) s.WaitWithDefaultTimeout() - Expect(s.ExitCode()).To(Equal(0)) + Expect(s).Should(Exit(0)) c := podmanTest.Podman([]string{"commit", "test1", "newimage"}) c.WaitWithDefaultTimeout() - Expect(c.ExitCode()).To(Equal(0)) + Expect(c).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "newimage"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) image := inspect.InspectImageJSON() _, ok := image[0].Config.Volumes["/foo"] Expect(ok).To(BeFalse()) @@ -213,36 +214,36 @@ var _ = Describe("Podman commit", func() { SkipIfRemote("--testing Remote Volumes") s := podmanTest.Podman([]string{"run", "--name", "test1", "-v", "/tmp:/foo", "alpine", "date"}) s.WaitWithDefaultTimeout() - Expect(s.ExitCode()).To(Equal(0)) + Expect(s).Should(Exit(0)) c := podmanTest.Podman([]string{"commit", "--include-volumes", "test1", "newimage"}) c.WaitWithDefaultTimeout() - Expect(c.ExitCode()).To(Equal(0)) + Expect(c).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "newimage"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) image := inspect.InspectImageJSON() _, ok := image[0].Config.Volumes["/foo"] Expect(ok).To(BeTrue()) r := podmanTest.Podman([]string{"run", "newimage"}) r.WaitWithDefaultTimeout() - Expect(r.ExitCode()).To(Equal(0)) + Expect(r).Should(Exit(0)) }) It("podman commit container check env variables", func() { s := podmanTest.Podman([]string{"run", "--name", "test1", "-e", "TEST=1=1-01=9.01", "-it", "alpine", "true"}) s.WaitWithDefaultTimeout() - Expect(s.ExitCode()).To(Equal(0)) + Expect(s).Should(Exit(0)) c := podmanTest.Podman([]string{"commit", "test1", "newimage"}) c.WaitWithDefaultTimeout() - Expect(c.ExitCode()).To(Equal(0)) + Expect(c).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "newimage"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) image := inspect.InspectImageJSON() envMap := make(map[string]bool) @@ -271,7 +272,7 @@ var _ = Describe("Podman commit", func() { session := podmanTest.Podman([]string{"commit", "test1", "foobar.com/test1-image:latest", "--iidfile", targetFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) id, _ := ioutil.ReadFile(targetFile) check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"}) @@ -288,20 +289,20 @@ var _ = Describe("Podman commit", func() { session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(secretsString)) session = podmanTest.Podman([]string{"commit", "secr", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "foobar.com/test1-image:latest", "cat", "/run/secrets/mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) @@ -313,16 +314,16 @@ var _ = Describe("Podman commit", func() { session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env", "--name", "secr", ALPINE, "printenv", "mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(secretsString)) session = podmanTest.Podman([]string{"commit", "secr", "foobar.com/test1-image:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "foobar.com/test1-image:latest", "printenv", "mysecret"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 1aeeca4cb..2e48e1763 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -321,11 +321,11 @@ func (p *PodmanTestIntegration) createArtifact(image string) { if _, err := os.Stat(destName); os.IsNotExist(err) { pull := p.PodmanNoCache([]string{"pull", image}) pull.Wait(440) - Expect(pull.ExitCode()).To(Equal(0)) + Expect(pull).Should(Exit(0)) save := p.PodmanNoCache([]string{"save", "-o", destName, image}) save.Wait(90) - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) fmt.Printf("\n") } else { fmt.Printf(" already exists.\n") @@ -811,7 +811,7 @@ func generateNetworkConfig(p *PodmanTestIntegration) (string, string) { func (p *PodmanTestIntegration) removeCNINetwork(name string) { session := p.Podman([]string{"network", "rm", "-f", name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeNumerically("<=", 1)) + Expect(session.ExitCode()).To(BeNumerically("<=", 1), "Exit code must be 0 or 1") } func (p *PodmanSessionIntegration) jq(jqCommand string) (string, error) { diff --git a/test/e2e/container_create_volume_test.go b/test/e2e/container_create_volume_test.go new file mode 100644 index 000000000..001698239 --- /dev/null +++ b/test/e2e/container_create_volume_test.go @@ -0,0 +1,127 @@ +package integration + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + + . "github.com/containers/podman/v3/test/utils" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" +) + +func buildDataVolumeImage(pTest *PodmanTestIntegration, image, data, dest string) { + // Create a dummy file for data volume + dummyFile := filepath.Join(pTest.TempDir, data) + err := ioutil.WriteFile(dummyFile, []byte(data), 0644) + Expect(err).To(BeNil()) + + // Create a data volume container image but no CMD binary in it + containerFile := fmt.Sprintf(`FROM scratch +CMD doesnotexist.sh +ADD %s %s/ +VOLUME %s/`, data, dest, dest) + pTest.BuildImage(containerFile, image, "false") +} + +func createContainersConfFile(pTest *PodmanTestIntegration) { + configPath := filepath.Join(pTest.TempDir, "containers.conf") + containersConf := []byte(fmt.Sprintf("[containers]\nprepare_volume_on_create = true\n")) + err := ioutil.WriteFile(configPath, containersConf, os.ModePerm) + Expect(err).To(BeNil()) + + // Set custom containers.conf file + os.Setenv("CONTAINERS_CONF", configPath) + if IsRemote() { + pTest.RestartRemoteService() + } +} + +func checkDataVolumeContainer(pTest *PodmanTestIntegration, image, cont, dest, data string) { + create := pTest.Podman([]string{"create", "--name", cont, image}) + create.WaitWithDefaultTimeout() + Expect(create).Should(Exit(0)) + + inspect := pTest.InspectContainer(cont) + Expect(len(inspect)).To(Equal(1)) + Expect(len(inspect[0].Mounts)).To(Equal(1)) + Expect(inspect[0].Mounts[0].Destination).To(Equal(dest)) + + mntName, mntSource := inspect[0].Mounts[0].Name, inspect[0].Mounts[0].Source + + volList := pTest.Podman([]string{"volume", "list", "--quiet"}) + volList.WaitWithDefaultTimeout() + Expect(volList).Should(Exit(0)) + Expect(len(volList.OutputToStringArray())).To(Equal(1)) + Expect(volList.OutputToStringArray()[0]).To(Equal(mntName)) + + // Check the mount source directory + files, err := ioutil.ReadDir(mntSource) + Expect(err).To(BeNil()) + + if data == "" { + Expect(len(files)).To(Equal(0)) + } else { + Expect(len(files)).To(Equal(1)) + Expect(files[0].Name()).To(Equal(data)) + } +} + +var _ = Describe("Podman create data volume", func() { + var ( + tempdir string + err error + podmanTest *PodmanTestIntegration + ) + + BeforeEach(func() { + tempdir, err = CreateTempDirInTempDir() + if err != nil { + os.Exit(1) + } + podmanTest = PodmanTestCreate(tempdir) + podmanTest.Setup() + podmanTest.SeedImages() + }) + + AfterEach(func() { + podmanTest.Cleanup() + f := CurrentGinkgoTestDescription() + processTestResult(f) + os.Unsetenv("CONTAINERS_CONF") + }) + + It("podman create with volume data copy turned off", func() { + imgName, volData, volDest := "dataimg", "dummy", "/test" + + buildDataVolumeImage(podmanTest, imgName, volData, volDest) + + // Create a container with the default containers.conf and + // check that the volume is not copied from the image. + checkDataVolumeContainer(podmanTest, imgName, "ctr-nocopy", volDest, "") + }) + + It("podman create with volume data copy turned on", func() { + imgName, volData, volDest := "dataimg", "dummy", "/test" + + buildDataVolumeImage(podmanTest, imgName, volData, volDest) + + // Create a container with the custom containers.conf and + // check that the volume is copied from the image. + createContainersConfFile(podmanTest) + + checkDataVolumeContainer(podmanTest, imgName, "ctr-copy", volDest, volData) + }) + + It("podman run with volume data copy turned on", func() { + // Create a container with the custom containers.conf and + // check that the container is run successfully + createContainersConfFile(podmanTest) + + session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "echo"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + }) +}) diff --git a/test/e2e/container_inspect_test.go b/test/e2e/container_inspect_test.go index 840f13e3d..9a95a275a 100644 --- a/test/e2e/container_inspect_test.go +++ b/test/e2e/container_inspect_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman container inspect", func() { @@ -36,7 +37,7 @@ var _ = Describe("Podman container inspect", func() { const testContainer = "container-inspect-test-1" setup := podmanTest.RunTopContainer(testContainer) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) data := podmanTest.InspectContainer(testContainer) Expect(data[0].Config.Annotations[annotations.ContainerManager]). diff --git a/test/e2e/containers_conf_test.go b/test/e2e/containers_conf_test.go index 054454798..3349b8be3 100644 --- a/test/e2e/containers_conf_test.go +++ b/test/e2e/containers_conf_test.go @@ -11,6 +11,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run", func() { @@ -47,12 +48,12 @@ var _ = Describe("Podman run", func() { //containers.conf is set to "nofile=500:500" session := podmanTest.Podman([]string{"run", "--rm", fedoraMinimal, "ulimit", "-n"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("500")) session = podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=2048:2048", fedoraMinimal, "ulimit", "-n"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("2048")) }) @@ -60,7 +61,7 @@ var _ = Describe("Podman run", func() { //containers.conf default env includes foo session := podmanTest.Podman([]string{"run", ALPINE, "printenv"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("foo=bar")) }) @@ -68,7 +69,7 @@ var _ = Describe("Podman run", func() { //containers.conf devices includes notone session := podmanTest.Podman([]string{"run", "--device", "/dev/null:/dev/bar", ALPINE, "ls", "/dev"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("bar")) Expect(session.OutputToString()).To(ContainSubstring("notone")) }) @@ -77,7 +78,7 @@ var _ = Describe("Podman run", func() { //containers.conf default sets shm-size=201k, which ends up as 200k session := podmanTest.Podman([]string{"run", ALPINE, "grep", "shm", "/proc/self/mounts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("size=200k")) }) @@ -85,7 +86,7 @@ var _ = Describe("Podman run", func() { SkipIfRootlessCgroupsV1("Not supported for rootless + CGroupsV1") cap := podmanTest.Podman([]string{"run", ALPINE, "grep", "CapEff", "/proc/self/status"}) cap.WaitWithDefaultTimeout() - Expect(cap.ExitCode()).To(Equal(0)) + Expect(cap).Should(Exit(0)) os.Setenv("CONTAINERS_CONF", "config/containers-ns.conf") if IsRemote() { @@ -93,7 +94,7 @@ var _ = Describe("Podman run", func() { } session := podmanTest.Podman([]string{"run", BB, "grep", "CapEff", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).ToNot(Equal(cap.OutputToString())) }) @@ -102,7 +103,7 @@ var _ = Describe("Podman run", func() { setup.WaitWithDefaultTimeout() result := podmanTest.Podman([]string{"top", "test1", "capeff"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring("SYS_CHROOT")) Expect(result.OutputToString()).To(ContainSubstring("NET_RAW")) }) @@ -116,7 +117,7 @@ var _ = Describe("Podman run", func() { setup.WaitWithDefaultTimeout() result := podmanTest.Podman([]string{"container", "top", "test1", "capeff"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).ToNot(ContainSubstring("SYS_CHROOT")) Expect(result.OutputToString()).ToNot(ContainSubstring("NET_RAW")) }) @@ -130,7 +131,7 @@ var _ = Describe("Podman run", func() { //containers.conf default ipcns to default to host session := podmanTest.Podman([]string{"run", ALPINE, "ls", "-l", nspath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) fields := strings.Split(session.OutputToString(), " ") ctrNS := strings.TrimSuffix(fields[len(fields)-1], "\n") @@ -175,12 +176,12 @@ var _ = Describe("Podman run", func() { } logc := podmanTest.Podman([]string{"run", "-d", ALPINE, "sh", "-c", "echo podman; sleep 0.1; echo podman; sleep 0.1; echo podman"}) logc.WaitWithDefaultTimeout() - Expect(logc.ExitCode()).To(Equal(0)) + Expect(logc).Should(Exit(0)) cid := logc.OutputToString() wait := podmanTest.Podman([]string{"wait", cid}) wait.WaitWithDefaultTimeout() - Expect(wait.ExitCode()).To(Equal(0)) + Expect(wait).Should(Exit(0)) cmd := exec.Command("journalctl", "--no-pager", "-o", "json", "--output-fields=CONTAINER_TAG", fmt.Sprintf("CONTAINER_ID_FULL=%s", cid)) out, err := cmd.CombinedOutput() @@ -202,55 +203,55 @@ var _ = Describe("Podman run", func() { } result := podmanTest.Podman([]string{"run", ALPINE, "ls", tempdir}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman run containers.conf sysctl test", func() { //containers.conf is set to "net.ipv4.ping_group_range=0 1000" session := podmanTest.Podman([]string{"run", "--rm", fedoraMinimal, "cat", "/proc/sys/net/ipv4/ping_group_range"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("1000")) // Ignore containers.conf setting if --net=host session = podmanTest.Podman([]string{"run", "--rm", "--net", "host", fedoraMinimal, "cat", "/proc/sys/net/ipv4/ping_group_range"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).ToNot((ContainSubstring("1000"))) }) It("podman run containers.conf search domain", func() { session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session.LineInOutputStartsWith("search foobar.com") }) It("podman run add dns server", func() { session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session.LineInOutputStartsWith("server 1.2.3.4") }) It("podman run add dns option", func() { session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session.LineInOutputStartsWith("options debug") }) It("podman run containers.conf remove all search domain", func() { session := podmanTest.Podman([]string{"run", "--dns-search=.", ALPINE, "cat", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputStartsWith("search")).To(BeFalse()) }) It("podman run use containers.conf search domain", func() { session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputStartsWith("search")).To(BeTrue()) Expect(session.OutputToString()).To(ContainSubstring("foobar.com")) @@ -262,7 +263,7 @@ var _ = Describe("Podman run", func() { //containers.conf timezone set to Pacific/Honolulu session := podmanTest.Podman([]string{"run", ALPINE, "date", "+'%H %Z'"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("HST")) }) @@ -274,14 +275,14 @@ var _ = Describe("Podman run", func() { session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("0002")) }) It("podman set network cmd options slirp options to allow host loopback", func() { session := podmanTest.Podman([]string{"run", "--network", "slirp4netns", ALPINE, "ping", "-c1", "10.0.2.2"}) session.Wait(30) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman-remote test localcontainers.conf versus remote containers.conf", func() { @@ -294,13 +295,13 @@ var _ = Describe("Podman run", func() { // env session := podmanTest.Podman([]string{"run", ALPINE, "printenv", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("bar")) // dns-search, server, options session = podmanTest.Podman([]string{"run", ALPINE, "cat", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputStartsWith("search")).To(BeTrue()) Expect(session.OutputToString()).To(ContainSubstring("foobar.com")) Expect(session.OutputToString()).To(ContainSubstring("1.2.3.4")) @@ -309,32 +310,32 @@ var _ = Describe("Podman run", func() { // sysctls session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "cat", "/proc/sys/net/ipv4/ping_group_range"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("1000")) // shm-size session = podmanTest.Podman([]string{"run", ALPINE, "grep", "shm", "/proc/self/mounts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("size=200k")) // ulimits session = podmanTest.Podman([]string{"run", "--rm", fedoraMinimal, "ulimit", "-n"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("500")) // Configuration that comes from remote client // Timezone session = podmanTest.Podman([]string{"run", ALPINE, "date", "+'%H %Z'"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Or(ContainSubstring("EST"), ContainSubstring("EDT"))) // Umask session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("0022")) }) @@ -342,7 +343,7 @@ var _ = Describe("Podman run", func() { //containers.conf is set to "run.oci.keep_original_groups=1" session := podmanTest.Podman([]string{"create", "--rm", "--name", "test", fedoraMinimal}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "--format", "{{ .Config.Annotations }}", "test"}) inspect.WaitWithDefaultTimeout() @@ -357,18 +358,18 @@ var _ = Describe("Podman run", func() { session = podmanTest.Podman([]string{"run", "-dt", "--add-host", "test1:127.0.0.1", "--no-hosts=false", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run with no-hosts=true /etc/hosts does not include hostname", func() { session := podmanTest.Podman([]string{"run", "--rm", "--name", "test", ALPINE, "cat", "/etc/hosts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(ContainSubstring("test"))) session = podmanTest.Podman([]string{"run", "--rm", "--name", "test", "--no-hosts=false", ALPINE, "cat", "/etc/hosts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("test")) }) @@ -387,7 +388,7 @@ var _ = Describe("Podman run", func() { session := podmanTest.Podman([]string{"info", "--format", "{{.Host.Security.SECCOMPProfilePath}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(profile)) }) }) diff --git a/test/e2e/cp_test.go b/test/e2e/cp_test.go index be4901833..360b8c7fc 100644 --- a/test/e2e/cp_test.go +++ b/test/e2e/cp_test.go @@ -10,6 +10,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) // NOTE: Only smoke tests. The system tests (i.e., "./test/system/*") take @@ -55,7 +56,7 @@ var _ = Describe("Podman cp", func() { // Create a container. NOTE that container mustn't be running for copying. session := podmanTest.Podman([]string{"create", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) name := session.OutputToString() // Copy TO the container. @@ -68,7 +69,7 @@ var _ = Describe("Podman cp", func() { // The file will now be created (and written to). session = podmanTest.Podman([]string{"cp", srcFile.Name(), name + ":foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Copy FROM the container. @@ -79,11 +80,11 @@ var _ = Describe("Podman cp", func() { session = podmanTest.Podman([]string{"cp", name + ":foo", destFile.Name()}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Now make sure the content matches. roundtripContent, err := ioutil.ReadFile(destFile.Name()) @@ -106,17 +107,17 @@ var _ = Describe("Podman cp", func() { // Create a container. NOTE that container mustn't be running for copying. session := podmanTest.Podman([]string{"create", "--pid=host", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) name := session.OutputToString() session = podmanTest.Podman([]string{"start", name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // The file will now be created (and written to). session = podmanTest.Podman([]string{"cp", srcFile.Name(), name + ":foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Copy FROM the container. @@ -127,7 +128,7 @@ var _ = Describe("Podman cp", func() { session = podmanTest.Podman([]string{"cp", name + ":foo", destFile.Name()}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Now make sure the content matches. roundtripContent, err := ioutil.ReadFile(destFile.Name()) @@ -150,25 +151,25 @@ var _ = Describe("Podman cp", func() { session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) name := session.OutputToString() session = podmanTest.Podman([]string{"exec", name, "ln", "-s", "/tmp", "/test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"cp", "--pause=false", srcFile.Name(), name + ":/test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", name, "cat", "/tmp/" + filepath.Base(srcFile.Name())}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(string(originalContent))) session = podmanTest.Podman([]string{"exec", name, "cat", "/test/" + filepath.Base(srcFile.Name())}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(string(originalContent))) }) @@ -188,21 +189,21 @@ var _ = Describe("Podman cp", func() { Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"volume", "create", "data"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "-v", "data:/data", "--name", "container1", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"cp", srcFile.Name(), "container1" + ":/data/file.txt"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Now get the volume's mount point, read the file and make // sure the contents match. session = podmanTest.Podman([]string{"volume", "inspect", "data", "--format", "{{.Mountpoint}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) volumeMountPoint := session.OutputToString() copiedContent, err := ioutil.ReadFile(filepath.Join(volumeMountPoint, "file.txt")) @@ -221,19 +222,19 @@ var _ = Describe("Podman cp", func() { setup := podmanTest.RunTopContainer("testctr") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "testctr", "adduser", "-S", "testuser"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "-u", "testuser", "testctr", "touch", "/tmp/testfile"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"cp", "--pause=false", "testctr:/tmp/testfile", srcFile.Name()}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // owner of the file copied to local machine is not testuser u, err := user.Current() @@ -245,12 +246,12 @@ var _ = Describe("Podman cp", func() { session = podmanTest.Podman([]string{"cp", "--pause=false", srcFile.Name(), "testctr:testfile2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // owner of the file copied to a container is the root user session = podmanTest.Podman([]string{"exec", "-it", "testctr", "ls", "-l", "testfile2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("root")) }) @@ -259,18 +260,18 @@ var _ = Describe("Podman cp", func() { container := "copyroottohost" session := podmanTest.RunTopContainer(container) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", container, "touch", "/dummy.txt"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) tmpDir, err := ioutil.TempDir("", "") Expect(err).To(BeNil()) session = podmanTest.Podman([]string{"cp", container + ":/", tmpDir}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cmd := exec.Command("ls", "-la", tmpDir) output, err := cmd.Output() diff --git a/test/e2e/create_staticip_test.go b/test/e2e/create_staticip_test.go index 2cf552274..205855fd6 100644 --- a/test/e2e/create_staticip_test.go +++ b/test/e2e/create_staticip_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman create with --ip flag", func() { @@ -52,7 +53,7 @@ var _ = Describe("Podman create with --ip flag", func() { SkipIfRootless("--ip not supported without network in rootless mode") result := podmanTest.Podman([]string{"create", "--name", "test", "--ip", "203.0.113.124", ALPINE, "ls"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"start", "test"}) result.WaitWithDefaultTimeout() @@ -67,17 +68,17 @@ var _ = Describe("Podman create with --ip flag", func() { result.WaitWithDefaultTimeout() // Rootless static ip assignment without network should error if rootless.IsRootless() { - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) } else { - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"start", "test"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"logs", "test"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(ip + "/16")) } }) @@ -87,19 +88,19 @@ var _ = Describe("Podman create with --ip flag", func() { ip := GetRandomIPAddress() result := podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test1", "--ip", ip, ALPINE, "sleep", "999"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test2", "--ip", ip, ALPINE, "ip", "addr"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"start", "test1"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) // race prevention: wait until IP address is assigned for i := 0; i < 5; i++ { result = podmanTest.Podman([]string{"inspect", "--format", "{{.NetworkSettings.IPAddress}}", "test1"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) if result.OutputToString() != "" { break } diff --git a/test/e2e/create_staticmac_test.go b/test/e2e/create_staticmac_test.go index 1df93553d..7cb638e47 100644 --- a/test/e2e/create_staticmac_test.go +++ b/test/e2e/create_staticmac_test.go @@ -8,6 +8,7 @@ import ( "github.com/containers/storage/pkg/stringid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run with --mac-address flag", func() { @@ -40,9 +41,9 @@ var _ = Describe("Podman run with --mac-address flag", func() { result := podmanTest.Podman([]string{"run", "--mac-address", "92:d0:c6:0a:29:34", ALPINE, "ip", "addr"}) result.WaitWithDefaultTimeout() if rootless.IsRootless() { - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) } else { - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring("92:d0:c6:0a:29:34")) } }) @@ -52,11 +53,11 @@ var _ = Describe("Podman run with --mac-address flag", func() { session := podmanTest.Podman([]string{"network", "create", net}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"run", "--network", net, "--mac-address", "92:d0:c6:00:29:34", ALPINE, "ip", "addr"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring("92:d0:c6:00:29:34")) }) }) diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index e4db6b845..975596dee 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -12,6 +12,7 @@ import ( "github.com/containers/storage/pkg/stringid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman create", func() { @@ -42,7 +43,7 @@ var _ = Describe("Podman create", func() { session := podmanTest.Podman([]string{"create", "--name", "local_image_test", ALPINE, "ls"}) session.WaitWithDefaultTimeout() cid := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) check := podmanTest.Podman([]string{"inspect", "local_image_test"}) @@ -54,39 +55,39 @@ var _ = Describe("Podman create", func() { It("podman create container based on a remote image", func() { session := podmanTest.Podman([]string{"create", BB_GLIBC, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) }) It("podman container create container based on a remote image", func() { session := podmanTest.Podman([]string{"container", "create", BB_GLIBC, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) }) It("podman create using short options", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) }) It("podman create using existing name", func() { session := podmanTest.Podman([]string{"create", "--name=foo", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) session = podmanTest.Podman([]string{"create", "--name=foo", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman create adds annotation", func() { session := podmanTest.Podman([]string{"create", "--annotation", "HELLO=WORLD", "--name", "annotate_test", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) check := podmanTest.Podman([]string{"inspect", "annotate_test"}) @@ -100,24 +101,24 @@ var _ = Describe("Podman create", func() { It("podman create --entrypoint command", func() { session := podmanTest.Podman([]string{"create", "--name", "entrypoint_test", "--entrypoint", "/bin/foobar", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) result := podmanTest.Podman([]string{"inspect", "entrypoint_test", "--format", "{{.Config.Entrypoint}}"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal("/bin/foobar")) }) It("podman create --entrypoint \"\"", func() { session := podmanTest.Podman([]string{"create", "--entrypoint", "", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) result := podmanTest.Podman([]string{"inspect", session.OutputToString(), "--format", "{{.Config.Entrypoint}}"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal("")) }) @@ -125,12 +126,12 @@ var _ = Describe("Podman create", func() { jsonString := `[ "/bin/foo", "-c"]` session := podmanTest.Podman([]string{"create", "--name", "entrypoint_json", "--entrypoint", jsonString, ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) result := podmanTest.Podman([]string{"inspect", "entrypoint_json", "--format", "{{.Config.Entrypoint}}"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal("/bin/foo -c")) }) @@ -144,15 +145,15 @@ var _ = Describe("Podman create", func() { session := podmanTest.Podman([]string{"create", "--name", "test", "--mount", "type=bind,src=" + vol1 + ",target=/myvol1,z", "--mount", "type=bind,src=" + vol2 + ",target=/myvol2,z", ALPINE, "touch", "/myvol2/foo.txt"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"logs", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).ToNot(ContainSubstring("cannot touch")) }) @@ -167,35 +168,35 @@ var _ = Describe("Podman create", func() { os.Mkdir(mountPath, 0755) session := podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"logs", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("/create/test rw")) session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test_ro", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test,ro", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "test_ro"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"logs", "test_ro"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("/create/test ro")) session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test_shared", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test,shared", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "test_shared"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"logs", "test_shared"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, matches := session.GrepString("/create/test") Expect(found).Should(BeTrue()) Expect(matches[0]).To(ContainSubstring("rw")) @@ -205,20 +206,20 @@ var _ = Describe("Podman create", func() { os.Mkdir(mountPath, 0755) session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test_tmpfs", "--mount", "type=tmpfs,target=/create/test", ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "test_tmpfs"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"logs", "test_tmpfs"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("/create/test rw,nosuid,nodev,relatime - tmpfs")) }) It("podman create --pod automatically", func() { session := podmanTest.Podman([]string{"create", "--pod", "new:foobar", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"pod", "ps", "--no-trunc"}) check.WaitWithDefaultTimeout() @@ -231,7 +232,7 @@ var _ = Describe("Podman create", func() { // if used together. session := podmanTest.Podman([]string{"create", "--pod", "foo", "--pod-id-file", "bar", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) tmpDir, err := ioutil.TempDir("", "") Expect(err).To(BeNil()) @@ -244,11 +245,11 @@ var _ = Describe("Podman create", func() { // Now, let's create a pod with --pod-id-file. session = podmanTest.Podman([]string{"pod", "create", "--pod-id-file", podIDFile, "--name", podName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "inspect", podName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) podData := session.InspectPodToJSON() @@ -256,7 +257,7 @@ var _ = Describe("Podman create", func() { // some checks to make sure it's working as expected. session = podmanTest.Podman([]string{"create", "--pod-id-file", podIDFile, "--name", ctrName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ctrJSON := podmanTest.InspectContainer(ctrName) Expect(podData.ID).To(Equal(ctrJSON[0].Pod)) // Make sure the container's pod matches the pod's ID @@ -266,7 +267,7 @@ var _ = Describe("Podman create", func() { name := "test101" create := podmanTest.Podman([]string{"create", "--name", name, redis}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) ctrJSON := podmanTest.InspectContainer(name) Expect(len(ctrJSON)).To(Equal(1)) @@ -282,62 +283,62 @@ var _ = Describe("Podman create", func() { session = podmanTest.Podman([]string{"create", "--pull", "always", "--name=foo", "testimage:00000000"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman create using image list by tag", func() { session := podmanTest.Podman([]string{"create", "--pull=always", "--arch=arm64", "--name=foo", ALPINELISTTAG}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.Image}}", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64ID)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.ImageName}}", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG)) }) It("podman create using image list by digest", func() { session := podmanTest.Podman([]string{"create", "--pull=always", "--arch=arm64", "--name=foo", ALPINELISTDIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.Image}}", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64ID)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.ImageName}}", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST)) }) It("podman create using image list instance by digest", func() { session := podmanTest.Podman([]string{"create", "--pull=always", "--arch=arm64", "--name=foo", ALPINEARM64DIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.Image}}", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64ID)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.ImageName}}", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) }) It("podman create using cross-arch image list instance by digest", func() { session := podmanTest.Podman([]string{"create", "--pull=always", "--arch=arm64", "--name=foo", ALPINEARM64DIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.Image}}", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64ID)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.ImageName}}", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) }) @@ -351,11 +352,11 @@ var _ = Describe("Podman create", func() { SkipIfRemote("SigPolicy not handled by remote") session := podmanTest.Podman([]string{"create", "--pull=always", "--signature-policy", "/no/such/file", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"create", "--pull=always", "--signature-policy", "/etc/containers/policy.json", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman create with unset label", func() { @@ -363,7 +364,7 @@ var _ = Describe("Podman create", func() { ctrName := "testctr" session := podmanTest.Podman([]string{"create", "--label", "TESTKEY1=", "--label", "TESTKEY2", "--name", ctrName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() @@ -381,7 +382,7 @@ var _ = Describe("Podman create", func() { ctrName := "testctr" session := podmanTest.Podman([]string{"create", "--label", "TESTKEY1=value1", "--label", "TESTKEY2=bar", "--name", ctrName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() @@ -400,7 +401,7 @@ var _ = Describe("Podman create", func() { ctrName := "testctr" session := podmanTest.Podman([]string{"create", "-t", "--restart", "on-failure:5", "--name", ctrName, ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() @@ -413,7 +414,7 @@ var _ = Describe("Podman create", func() { It("podman create with --restart-policy=always:5 fails", func() { session := podmanTest.Podman([]string{"create", "-t", "--restart", "always:5", ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("podman create with --restart-policy unless-stopped", func() { @@ -421,7 +422,7 @@ var _ = Describe("Podman create", func() { unlessStopped := "unless-stopped" session := podmanTest.Podman([]string{"create", "-t", "--restart", unlessStopped, "--name", ctrName, ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() @@ -435,7 +436,7 @@ var _ = Describe("Podman create", func() { ctrName := "testCtr" session := podmanTest.Podman([]string{"create", "-t", "-m", fmt.Sprintf("%db", numMem), "--name", ctrName, ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() @@ -450,7 +451,7 @@ var _ = Describe("Podman create", func() { ctrName := "testCtr" session := podmanTest.Podman([]string{"create", "-t", "--cpus", fmt.Sprintf("%d", numCpus), "--name", ctrName, ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() @@ -463,14 +464,14 @@ var _ = Describe("Podman create", func() { // Make sure we error out with --name. session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) // Create and replace 5 times in a row the "same" container. ctrName := "testCtr" for i := 0; i < 5; i++ { session = podmanTest.Podman([]string{"create", "--replace", "--name", ctrName, ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) } }) @@ -478,7 +479,7 @@ var _ = Describe("Podman create", func() { ctrName := "testCtr" session := podmanTest.Podman([]string{"create", "--name", ctrName, ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() @@ -490,11 +491,11 @@ var _ = Describe("Podman create", func() { It("podman create --tz", func() { session := podmanTest.Podman([]string{"create", "--tz", "foo", "--name", "bad", ALPINE, "date"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"create", "--tz", "America", "--name", "dir", ALPINE, "date"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"create", "--tz", "Pacific/Honolulu", "--name", "zone", ALPINE, "date"}) session.WaitWithDefaultTimeout() @@ -552,7 +553,7 @@ var _ = Describe("Podman create", func() { session = podmanTest.Podman([]string{"create", "--umask", "9999", "--name", "bad", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) Expect(session.ErrorToString()).To(ContainSubstring("Invalid umask")) }) @@ -561,11 +562,11 @@ var _ = Describe("Podman create", func() { name := "createwithstaticip" pod := podmanTest.RunTopContainerInPod("", "new:"+name) pod.WaitWithDefaultTimeout() - Expect(pod.ExitCode()).To(BeZero()) + Expect(pod).Should(Exit(0)) session := podmanTest.Podman([]string{"create", "--pod", name, "--ip", "192.168.1.2", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).ToNot(BeZero()) + Expect(session).Should(ExitWithError()) }) It("create container in pod with mac should fail", func() { @@ -573,112 +574,112 @@ var _ = Describe("Podman create", func() { name := "createwithstaticmac" pod := podmanTest.RunTopContainerInPod("", "new:"+name) pod.WaitWithDefaultTimeout() - Expect(pod.ExitCode()).To(BeZero()) + Expect(pod).Should(Exit(0)) session := podmanTest.Podman([]string{"create", "--pod", name, "--mac-address", "52:54:00:6d:2f:82", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).ToNot(BeZero()) + Expect(session).Should(ExitWithError()) }) It("create container in pod with network should not fail", func() { name := "createwithnetwork" pod := podmanTest.RunTopContainerInPod("", "new:"+name) pod.WaitWithDefaultTimeout() - Expect(pod.ExitCode()).To(BeZero()) + Expect(pod).Should(Exit(0)) netName := "pod" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) session = podmanTest.Podman([]string{"create", "--pod", name, "--network", netName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) }) It("create container in pod with ports should fail", func() { name := "createwithports" pod := podmanTest.RunTopContainerInPod("", "new:"+name) pod.WaitWithDefaultTimeout() - Expect(pod.ExitCode()).To(BeZero()) + Expect(pod).Should(Exit(0)) session := podmanTest.Podman([]string{"create", "--pod", name, "-p", "8080:80", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).ToNot(BeZero()) + Expect(session).Should(ExitWithError()) }) It("create container in pod ppublish ports should fail", func() { name := "createwithpublishports" pod := podmanTest.RunTopContainerInPod("", "new:"+name) pod.WaitWithDefaultTimeout() - Expect(pod.ExitCode()).To(BeZero()) + Expect(pod).Should(Exit(0)) session := podmanTest.Podman([]string{"create", "--pod", name, "-P", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).ToNot(BeZero()) + Expect(session).Should(ExitWithError()) }) It("create use local store image if input image contains a manifest list", func() { session := podmanTest.Podman([]string{"pull", BB}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "create", "mylist"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "add", "--all", "mylist", BB}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "mylist"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) }) It("podman create -d should fail, can not detach create containers", func() { session := podmanTest.Podman([]string{"create", "-d", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) Expect(session.ErrorToString()).To(ContainSubstring("unknown shorthand flag")) session = podmanTest.Podman([]string{"create", "--detach", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) Expect(session.ErrorToString()).To(ContainSubstring("unknown flag")) session = podmanTest.Podman([]string{"create", "--detach-keys", "ctrl-x", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) Expect(session.ErrorToString()).To(ContainSubstring("unknown flag")) }) It("podman create --platform", func() { session := podmanTest.Podman([]string{"create", "--platform=linux/bogus", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) expectedError := "no image found in manifest list for architecture bogus" Expect(session.ErrorToString()).To(ContainSubstring(expectedError)) session = podmanTest.Podman([]string{"create", "--platform=linux/arm64", "--os", "windows", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) expectedError = "--platform option can not be specified with --arch or --os" Expect(session.ErrorToString()).To(ContainSubstring(expectedError)) session = podmanTest.Podman([]string{"create", "-q", "--platform=linux/arm64", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) setup := podmanTest.Podman([]string{"container", "inspect", session.OutputToString()}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) data := setup.InspectContainerToJSON() setup = podmanTest.Podman([]string{"image", "inspect", data[0].Image}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) idata := setup.InspectImageJSON() // returns []inspect.ImageData Expect(len(idata)).To(Equal(1)) diff --git a/test/e2e/diff_test.go b/test/e2e/diff_test.go index cf955772b..65ec0d1de 100644 --- a/test/e2e/diff_test.go +++ b/test/e2e/diff_test.go @@ -9,6 +9,7 @@ import ( "github.com/containers/storage/pkg/stringid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman diff", func() { @@ -38,27 +39,27 @@ var _ = Describe("Podman diff", func() { It("podman diff of image", func() { session := podmanTest.Podman([]string{"diff", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 0)) }) It("podman diff bogus image", func() { session := podmanTest.Podman([]string{"diff", "1234"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman diff image with json output", func() { session := podmanTest.Podman([]string{"diff", "--format=json", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) }) It("podman diff container and committed image", func() { session := podmanTest.Podman([]string{"run", "--name=diff-test", ALPINE, "touch", "/tmp/diff-test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"diff", "diff-test"}) session.WaitWithDefaultTimeout() containerDiff := session.OutputToStringArray() @@ -67,7 +68,7 @@ var _ = Describe("Podman diff", func() { Expect(session.LineInOutputContains("A /tmp/diff-test")).To(BeTrue()) session = podmanTest.Podman([]string{"commit", "diff-test", "diff-test-img"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"diff", "diff-test-img"}) session.WaitWithDefaultTimeout() imageDiff := session.OutputToStringArray() @@ -78,7 +79,7 @@ var _ = Describe("Podman diff", func() { It("podman diff latest container", func() { session := podmanTest.Podman([]string{"run", "--name", "diff-test", ALPINE, "touch", "/tmp/diff-test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if !IsRemote() { session = podmanTest.Podman([]string{"diff", "-l"}) } else { @@ -89,7 +90,7 @@ var _ = Describe("Podman diff", func() { sort.Strings(containerDiff) Expect(session.LineInOutputContains("C /tmp")).To(BeTrue()) Expect(session.LineInOutputContains("A /tmp/diff-test")).To(BeTrue()) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman image diff", func() { @@ -118,13 +119,13 @@ RUN echo test session := podmanTest.Podman([]string{"image", "diff", image}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically("==", 1)) Expect(session.OutputToString()).To(Equal("A " + file3)) session = podmanTest.Podman([]string{"image", "diff", image, baseImage}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically("==", 4)) Expect(session.LineInOutputContains("A " + file1)).To(BeTrue()) Expect(session.LineInOutputContains("A " + file2)).To(BeTrue()) @@ -134,20 +135,20 @@ RUN echo test It("podman image diff of single image", func() { session := podmanTest.Podman([]string{"image", "diff", BB}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 0)) }) It("podman image diff bogus image", func() { session := podmanTest.Podman([]string{"image", "diff", "1234", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman image diff of the same image", func() { session := podmanTest.Podman([]string{"image", "diff", ALPINE, ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically("==", 0)) }) @@ -165,25 +166,25 @@ RUN touch %s`, ALPINE, imagefile) session := podmanTest.Podman([]string{"run", "--name", name, ALPINE, "touch", confile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // podman diff prefers image over container when they have the same name session = podmanTest.Podman([]string{"diff", name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically("==", 2)) Expect(session.OutputToString()).To(ContainSubstring(imagefile)) session = podmanTest.Podman([]string{"image", "diff", name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically("==", 2)) Expect(session.OutputToString()).To(ContainSubstring(imagefile)) // container diff has to show the container session = podmanTest.Podman([]string{"container", "diff", name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically("==", 2)) Expect(session.OutputToString()).To(ContainSubstring(confile)) }) diff --git a/test/e2e/events_test.go b/test/e2e/events_test.go index cc7c4d996..e2a169383 100644 --- a/test/e2e/events_test.go +++ b/test/e2e/events_test.go @@ -52,7 +52,7 @@ var _ = Describe("Podman events", func() { Expect(ec).To(Equal(0)) result := podmanTest.Podman([]string{"events", "--stream=false"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(BeZero()) + Expect(result).Should(Exit(0)) }) It("podman events with an event filter", func() { @@ -61,7 +61,7 @@ var _ = Describe("Podman events", func() { Expect(ec).To(Equal(0)) result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=start"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray()) >= 1) }) @@ -75,7 +75,7 @@ var _ = Describe("Podman events", func() { time.Sleep(5 * time.Second) result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=start", "--filter", fmt.Sprintf("container=%s", cid)}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(Equal(1)) Expect(!strings.Contains(result.OutputToString(), cid2)) }) @@ -86,7 +86,7 @@ var _ = Describe("Podman events", func() { Expect(ec).To(Equal(0)) result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "type=pod", "--filter", fmt.Sprintf("container=%s", cid)}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(Equal(0)) }) @@ -96,11 +96,11 @@ var _ = Describe("Podman events", func() { setup.WaitWithDefaultTimeout() stop := podmanTest.Podman([]string{"pod", "stop", "foobarpod"}) stop.WaitWithDefaultTimeout() - Expect(stop.ExitCode()).To(Equal(0)) - Expect(setup.ExitCode()).To(Equal(0)) + Expect(stop).Should(Exit(0)) + Expect(setup).Should(Exit(0)) result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "type=pod", "--filter", "pod=foobarpod"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) fmt.Println(result.OutputToStringArray()) Expect(len(result.OutputToStringArray()) >= 2) }) @@ -111,7 +111,7 @@ var _ = Describe("Podman events", func() { Expect(ec).To(Equal(0)) result := podmanTest.Podman([]string{"events", "--stream=false", "--since", "1m"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(BeZero()) + Expect(result).Should(Exit(0)) }) It("podman events --until", func() { @@ -120,7 +120,7 @@ var _ = Describe("Podman events", func() { Expect(ec).To(Equal(0)) result := podmanTest.Podman([]string{"events", "--stream=false", "--until", "1h"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(BeZero()) + Expect(result).Should(Exit(0)) }) It("podman events format", func() { @@ -157,7 +157,7 @@ var _ = Describe("Podman events", func() { name3 := stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"create", "--name", name1, ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) var wg sync.WaitGroup wg.Add(1) @@ -169,17 +169,17 @@ var _ = Describe("Podman events", func() { time.Sleep(time.Second * 2) session = podmanTest.Podman([]string{"create", "--name", name2, ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "--name", name3, ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }() // unix timestamp in 10 seconds until := time.Now().Add(time.Second * 10).Unix() result := podmanTest.Podman([]string{"events", "--since", "30s", "--until", fmt.Sprint(until)}) result.Wait(11) - Expect(result.ExitCode()).To(BeZero()) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(name1)) Expect(result.OutputToString()).To(ContainSubstring(name2)) Expect(result.OutputToString()).To(ContainSubstring(name3)) diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go index e6f63a391..02680e739 100644 --- a/test/e2e/exec_test.go +++ b/test/e2e/exec_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman exec", func() { @@ -37,61 +38,61 @@ var _ = Describe("Podman exec", func() { It("podman exec into bogus container", func() { session := podmanTest.Podman([]string{"exec", "foobar", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman exec without command", func() { session := podmanTest.Podman([]string{"exec", "foobar"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman exec simple command", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "test1", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman container exec simple command", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"container", "exec", "test1", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman exec simple command using latest", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid := "-l" if IsRemote() { cid = "test1" } session := podmanTest.Podman([]string{"exec", cid, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman exec environment test", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "--env", "FOO=BAR", "test1", "printenv", "FOO"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("BAR")) session = podmanTest.Podman([]string{"exec", "--env", "PATH=/bin", "test1", "printenv", "PATH"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("/bin")) }) @@ -99,12 +100,12 @@ var _ = Describe("Podman exec", func() { // remote doesn't properly interpret os.Setenv setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) os.Setenv("FOO", "BAR") session := podmanTest.Podman([]string{"exec", "--env", "FOO", "test1", "printenv", "FOO"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("BAR")) os.Unsetenv("FOO") }) @@ -112,11 +113,11 @@ var _ = Describe("Podman exec", func() { It("podman exec exit code", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "test1", "sh", "-c", "exit 100"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(100)) + Expect(session).Should(Exit(100)) }) It("podman exec in keep-id container drops privileges", func() { @@ -124,63 +125,63 @@ var _ = Describe("Podman exec", func() { ctrName := "testctr1" testCtr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "--userns=keep-id", ALPINE, "top"}) testCtr.WaitWithDefaultTimeout() - Expect(testCtr.ExitCode()).To(Equal(0)) + Expect(testCtr).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", ctrName, "grep", "CapEff", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) }) It("podman exec --privileged", func() { session := podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) bndPerms := session.OutputToString() session = podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) effPerms := session.OutputToString() setup := podmanTest.RunTopContainer("test-privileged") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(effPerms)) session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) }) It("podman exec --privileged", func() { session := podmanTest.Podman([]string{"run", "--privileged", "--user=bin", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) bndPerms := session.OutputToString() session = podmanTest.Podman([]string{"run", "--privileged", "--user=bin", "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) effPerms := session.OutputToString() setup := podmanTest.RunTopContainer("test-privileged") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(effPerms)) session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) }) @@ -188,52 +189,52 @@ var _ = Describe("Podman exec", func() { It("podman exec --privileged", func() { session := podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) bndPerms := session.OutputToString() setup := podmanTest.RunTopContainer("test-privileged") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("00000000")) session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) }) It("podman exec --privileged container not running as root", func() { session := podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) bndPerms := session.OutputToString() setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--user=bin"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("00000000")) session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("00000000")) session = podmanTest.Podman([]string{"exec", "--privileged", "--user=root", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) }) @@ -241,26 +242,26 @@ var _ = Describe("Podman exec", func() { capAdd := "--cap-add=net_bind_service" session := podmanTest.Podman([]string{"run", "--user=bin", capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) bndPerms := session.OutputToString() session = podmanTest.Podman([]string{"run", "--user=bin", capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) effPerms := session.OutputToString() setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--user=bin", capAdd}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(effPerms)) }) @@ -269,111 +270,111 @@ var _ = Describe("Podman exec", func() { capDrop := "--cap-drop=all" session := podmanTest.Podman([]string{"run", "--user=bin", capDrop, capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) bndPerms := session.OutputToString() session = podmanTest.Podman([]string{"run", "--user=bin", capDrop, capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) effPerms := session.OutputToString() setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--user=bin", capDrop, capAdd}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapInh /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(effPerms)) session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(effPerms)) session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapPrm /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(effPerms)) session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapAmb /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(effPerms)) }) It("podman exec --privileged with user", func() { session := podmanTest.Podman([]string{"run", "--privileged", "--user=bin", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) bindPerms := session.OutputToString() setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--privileged", "--user=bin"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(bindPerms)) session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) }) It("podman exec terminal doesn't hang", func() { setup := podmanTest.Podman([]string{"run", "-dti", "--name", "test1", fedoraMinimal, "sleep", "+Inf"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) for i := 0; i < 5; i++ { session := podmanTest.Podman([]string{"exec", "-ti", "test1", "true"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) } }) It("podman exec pseudo-terminal sanity check", func() { setup := podmanTest.Podman([]string{"run", "--detach", "--name", "test1", fedoraMinimal, "sleep", "+Inf"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "--interactive", "--tty", "test1", "/usr/bin/stty", "--all"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(" onlcr")) }) It("podman exec simple command with user", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "--user", "root", "test1", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman exec with user only in container", func() { testUser := "test123" setup := podmanTest.Podman([]string{"run", "--name", "test1", "-d", fedoraMinimal, "sleep", "60"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "test1", "useradd", testUser}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session2 := podmanTest.Podman([]string{"exec", "--user", testUser, "test1", "whoami"}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) Expect(session2.OutputToString()).To(Equal(testUser)) }) @@ -381,41 +382,41 @@ var _ = Describe("Podman exec", func() { testUser := "guest" setup := podmanTest.Podman([]string{"run", "--user", testUser, "-d", ALPINE, "top"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) ctrID := setup.OutputToString() session := podmanTest.Podman([]string{"exec", ctrID, "whoami"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(testUser)) overrideUser := "root" session = podmanTest.Podman([]string{"exec", "--user", overrideUser, ctrID, "whoami"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(overrideUser)) }) It("podman exec simple working directory test", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "--workdir", "/tmp", "test1", "pwd"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("/tmp")) session = podmanTest.Podman([]string{"exec", "-w", "/tmp", "test1", "pwd"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("/tmp")) }) It("podman exec missing working directory test", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "--workdir", "/missing", "test1", "pwd"}) session.WaitWithDefaultTimeout() @@ -429,27 +430,27 @@ var _ = Describe("Podman exec", func() { It("podman exec cannot be invoked", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "test1", "/etc"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(126)) + Expect(session).Should(Exit(126)) }) It("podman exec command not found", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "test1", "notthere"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(127)) + Expect(session).Should(Exit(127)) }) It("podman exec preserve fds sanity check", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) devNull, err := os.Open("/dev/null") Expect(err).To(BeNil()) @@ -459,7 +460,7 @@ var _ = Describe("Podman exec", func() { } session := podmanTest.PodmanExtraFiles([]string{"exec", "--preserve-fds", "1", "test1", "ls"}, files) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman exec preserves --group-add groups", func() { @@ -468,21 +469,21 @@ var _ = Describe("Podman exec", func() { ctrName1 := "ctr1" ctr1 := podmanTest.Podman([]string{"run", "-ti", "--name", ctrName1, fedoraMinimal, "groupadd", "-g", gid, groupName}) ctr1.WaitWithDefaultTimeout() - Expect(ctr1.ExitCode()).To(Equal(0)) + Expect(ctr1).Should(Exit(0)) imgName := "img1" commit := podmanTest.Podman([]string{"commit", ctrName1, imgName}) commit.WaitWithDefaultTimeout() - Expect(commit.ExitCode()).To(Equal(0)) + Expect(commit).Should(Exit(0)) ctrName2 := "ctr2" ctr2 := podmanTest.Podman([]string{"run", "-d", "--name", ctrName2, "--group-add", groupName, imgName, "sleep", "300"}) ctr2.WaitWithDefaultTimeout() - Expect(ctr2.ExitCode()).To(Equal(0)) + Expect(ctr2).Should(Exit(0)) exec := podmanTest.Podman([]string{"exec", "-ti", ctrName2, "id"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(Equal(0)) + Expect(exec).Should(Exit(0)) Expect(exec.OutputToString()).To(ContainSubstring(fmt.Sprintf("%s(%s)", gid, groupName))) }) @@ -497,11 +498,11 @@ RUN useradd -u 1000 auser`, fedoraMinimal) ctrName := "testctr" ctr := podmanTest.Podman([]string{"run", "-t", "-i", "-d", "--name", ctrName, "--user", "auser:first", "--group-add", "second", imgName, "sleep", "300"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(Equal(0)) + Expect(ctr).Should(Exit(0)) exec := podmanTest.Podman([]string{"exec", "-t", ctrName, "id"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(Equal(0)) + Expect(exec).Should(Exit(0)) output := exec.OutputToString() Expect(output).To(ContainSubstring("4000(first)")) Expect(output).To(ContainSubstring("4001(second)")) @@ -510,18 +511,18 @@ RUN useradd -u 1000 auser`, fedoraMinimal) // Kill the container just so the test does not take 15 seconds to stop. kill := podmanTest.Podman([]string{"kill", ctrName}) kill.WaitWithDefaultTimeout() - Expect(kill.ExitCode()).To(Equal(0)) + Expect(kill).Should(Exit(0)) }) It("podman exec --detach", func() { ctrName := "testctr" ctr := podmanTest.Podman([]string{"run", "-t", "-i", "-d", "--name", ctrName, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(Equal(0)) + Expect(ctr).Should(Exit(0)) exec1 := podmanTest.Podman([]string{"exec", "-t", "-i", "-d", ctrName, "top"}) exec1.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(Equal(0)) + Expect(ctr).Should(Exit(0)) data := podmanTest.InspectContainer(ctrName) Expect(len(data)).To(Equal(1)) @@ -530,13 +531,13 @@ RUN useradd -u 1000 auser`, fedoraMinimal) exec2 := podmanTest.Podman([]string{"exec", "-t", "-i", ctrName, "ps", "-a"}) exec2.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(Equal(0)) + Expect(ctr).Should(Exit(0)) Expect(strings.Count(exec2.OutputToString(), "top")).To(Equal(2)) // Ensure that stop with a running detached exec session is // clean. stop := podmanTest.Podman([]string{"stop", ctrName}) stop.WaitWithDefaultTimeout() - Expect(stop.ExitCode()).To(Equal(0)) + Expect(stop).Should(Exit(0)) }) }) diff --git a/test/e2e/exists_test.go b/test/e2e/exists_test.go index f0a55dd94..260b6d5f2 100644 --- a/test/e2e/exists_test.go +++ b/test/e2e/exists_test.go @@ -50,7 +50,7 @@ var _ = Describe("Podman image|container exists", func() { It("podman container exists in local storage by name", func() { setup := podmanTest.RunTopContainer("foobar") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"container", "exists", "foobar"}) session.WaitWithDefaultTimeout() @@ -69,7 +69,7 @@ var _ = Describe("Podman image|container exists", func() { It("podman container exists in local storage by short container ID", func() { setup := podmanTest.RunTopContainer("") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid := setup.OutputToString()[0:12] session := podmanTest.Podman([]string{"container", "exists", cid}) diff --git a/test/e2e/export_test.go b/test/e2e/export_test.go index 61aebb5f2..a9dd09d8e 100644 --- a/test/e2e/export_test.go +++ b/test/e2e/export_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman export", func() { @@ -40,7 +41,7 @@ var _ = Describe("Podman export", func() { outfile := filepath.Join(podmanTest.TempDir, "container.tar") result := podmanTest.Podman([]string{"export", "-o", outfile, cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) _, err := os.Stat(outfile) Expect(err).To(BeNil()) @@ -55,7 +56,7 @@ var _ = Describe("Podman export", func() { outfile := filepath.Join(podmanTest.TempDir, "container.tar") result := podmanTest.Podman([]string{"container", "export", "-o", outfile, cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) _, err := os.Stat(outfile) Expect(err).To(BeNil()) diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go index 4c0fc6db0..8996bf6a0 100644 --- a/test/e2e/generate_kube_test.go +++ b/test/e2e/generate_kube_test.go @@ -11,6 +11,7 @@ import ( "github.com/ghodss/yaml" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" v1 "k8s.io/api/core/v1" ) @@ -53,11 +54,11 @@ var _ = Describe("Podman generate kube", func() { It("podman generate kube on container", func() { session := podmanTest.RunTopContainer("top") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "top"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -74,11 +75,11 @@ var _ = Describe("Podman generate kube", func() { It("podman generate service kube on container with --security-opt level", func() { session := podmanTest.Podman([]string{"create", "--name", "test", "--security-opt", "label=level:s0:c100,c200", "alpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "test"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -89,11 +90,11 @@ var _ = Describe("Podman generate kube", func() { It("podman generate service kube on container with --security-opt disable", func() { session := podmanTest.Podman([]string{"create", "--name", "test-disable", "--security-opt", "label=disable", "alpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "test-disable"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err = yaml.Unmarshal(kube.Out.Contents(), pod) @@ -104,11 +105,11 @@ var _ = Describe("Podman generate kube", func() { It("podman generate service kube on container with --security-opt type", func() { session := podmanTest.Podman([]string{"create", "--name", "test", "--security-opt", "label=type:foo_bar_t", "alpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "test"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err = yaml.Unmarshal(kube.Out.Contents(), pod) @@ -119,11 +120,11 @@ var _ = Describe("Podman generate kube", func() { It("podman generate service kube on container", func() { session := podmanTest.RunTopContainer("top") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "-s", "top"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) // TODO - test generated YAML - service produces multiple // structs. @@ -138,11 +139,11 @@ var _ = Describe("Podman generate kube", func() { session := podmanTest.RunTopContainerInPod("topcontainer", "toppod") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "toppod"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -159,15 +160,15 @@ var _ = Describe("Podman generate kube", func() { It("podman generate kube multiple pods", func() { pod1 := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:pod1", ALPINE, "top"}) pod1.WaitWithDefaultTimeout() - Expect(pod1.ExitCode()).To(Equal(0)) + Expect(pod1).Should(Exit(0)) pod2 := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:pod2", ALPINE, "top"}) pod2.WaitWithDefaultTimeout() - Expect(pod2.ExitCode()).To(Equal(0)) + Expect(pod2).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "pod1", "pod2"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) Expect(string(kube.Out.Contents())).To(ContainSubstring(`name: pod1`)) Expect(string(kube.Out.Contents())).To(ContainSubstring(`name: pod2`)) @@ -176,15 +177,15 @@ var _ = Describe("Podman generate kube", func() { It("podman generate kube on pod with host network", func() { podSession := podmanTest.Podman([]string{"pod", "create", "--name", "testHostNetwork", "--network", "host"}) podSession.WaitWithDefaultTimeout() - Expect(podSession.ExitCode()).To(Equal(0)) + Expect(podSession).Should(Exit(0)) session := podmanTest.Podman([]string{"create", "--name", "topcontainer", "--pod", "testHostNetwork", "--network", "host", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "testHostNetwork"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -195,11 +196,11 @@ var _ = Describe("Podman generate kube", func() { It("podman generate kube on container with host network", func() { session := podmanTest.RunTopContainerWithArgs("topcontainer", []string{"--network", "host"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "topcontainer"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -215,21 +216,21 @@ var _ = Describe("Podman generate kube", func() { "--add-host", "test2.podman.io" + ":" + testIP, }) podSession.WaitWithDefaultTimeout() - Expect(podSession.ExitCode()).To(Equal(0)) + Expect(podSession).Should(Exit(0)) ctr1Name := "ctr1" ctr1Session := podmanTest.Podman([]string{"create", "--name", ctr1Name, "--pod", podName, ALPINE, "top"}) ctr1Session.WaitWithDefaultTimeout() - Expect(ctr1Session.ExitCode()).To(Equal(0)) + Expect(ctr1Session).Should(Exit(0)) ctr2Name := "ctr2" ctr2Session := podmanTest.Podman([]string{"create", "--name", ctr2Name, "--pod", podName, ALPINE, "top"}) ctr2Session.WaitWithDefaultTimeout() - Expect(ctr2Session.ExitCode()).To(Equal(0)) + Expect(ctr2Session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", podName}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -245,11 +246,11 @@ var _ = Describe("Podman generate kube", func() { session := podmanTest.RunTopContainerInPod("topcontainer", "toppod") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "-s", "toppod"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) // TODO: How do we test unmarshal with a service? We have two // structs that need to be unmarshalled... @@ -270,17 +271,17 @@ var _ = Describe("Podman generate kube", func() { podName := v[0] podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName}) podSession.WaitWithDefaultTimeout() - Expect(podSession.ExitCode()).To(Equal(0)) + Expect(podSession).Should(Exit(0)) ctrName := "ctr" + strconv.Itoa(k) ctr1Session := podmanTest.Podman([]string{"create", "--name", ctrName, "--pod", podName, "--restart", v[1], ALPINE, "top"}) ctr1Session.WaitWithDefaultTimeout() - Expect(ctr1Session.ExitCode()).To(Equal(0)) + Expect(ctr1Session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", podName}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -294,16 +295,16 @@ var _ = Describe("Podman generate kube", func() { podName := "testMemoryLimit" podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName}) podSession.WaitWithDefaultTimeout() - Expect(podSession.ExitCode()).To(Equal(0)) + Expect(podSession).Should(Exit(0)) ctr1Name := "ctr1" ctr1Session := podmanTest.Podman([]string{"create", "--name", ctr1Name, "--pod", podName, "--memory", "10Mi", ALPINE, "top"}) ctr1Session.WaitWithDefaultTimeout() - Expect(ctr1Session.ExitCode()).To(Equal(0)) + Expect(ctr1Session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", podName}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -319,23 +320,23 @@ var _ = Describe("Podman generate kube", func() { podName := "testCpuLimit" podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName}) podSession.WaitWithDefaultTimeout() - Expect(podSession.ExitCode()).To(Equal(0)) + Expect(podSession).Should(Exit(0)) ctr1Name := "ctr1" ctr1Session := podmanTest.Podman([]string{"create", "--name", ctr1Name, "--pod", podName, "--cpus", "0.5", ALPINE, "top"}) ctr1Session.WaitWithDefaultTimeout() - Expect(ctr1Session.ExitCode()).To(Equal(0)) + Expect(ctr1Session).Should(Exit(0)) ctr2Name := "ctr2" ctr2Session := podmanTest.Podman([]string{"create", "--name", ctr2Name, "--pod", podName, "--cpu-period", "100000", "--cpu-quota", "50000", ALPINE, "top"}) ctr2Session.WaitWithDefaultTimeout() - Expect(ctr2Session.ExitCode()).To(Equal(0)) + Expect(ctr2Session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", podName}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -351,21 +352,21 @@ var _ = Describe("Podman generate kube", func() { podName := "test" podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName, "-p", "4000:4000", "-p", "5000:5000"}) podSession.WaitWithDefaultTimeout() - Expect(podSession.ExitCode()).To(Equal(0)) + Expect(podSession).Should(Exit(0)) ctr1Name := "ctr1" ctr1Session := podmanTest.Podman([]string{"create", "--name", ctr1Name, "--pod", podName, ALPINE, "top"}) ctr1Session.WaitWithDefaultTimeout() - Expect(ctr1Session.ExitCode()).To(Equal(0)) + Expect(ctr1Session).Should(Exit(0)) ctr2Name := "ctr2" ctr2Session := podmanTest.Podman([]string{"create", "--name", ctr2Name, "--pod", podName, ALPINE, "top"}) ctr2Session.WaitWithDefaultTimeout() - Expect(ctr2Session.ExitCode()).To(Equal(0)) + Expect(ctr2Session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", podName}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -397,33 +398,33 @@ var _ = Describe("Podman generate kube", func() { session := podmanTest.Podman([]string{"create", "--pod", podName, "--name", "test1", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session2 := podmanTest.Podman([]string{"create", "--pod", podName, "--name", "test2", ALPINE, "top"}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml") kube := podmanTest.Podman([]string{"generate", "kube", "-f", outputFile, podName}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) session3 := podmanTest.Podman([]string{"pod", "rm", "-af"}) session3.WaitWithDefaultTimeout() - Expect(session3.ExitCode()).To(Equal(0)) + Expect(session3).Should(Exit(0)) session4 := podmanTest.Podman([]string{"play", "kube", outputFile}) session4.WaitWithDefaultTimeout() - Expect(session4.ExitCode()).To(Equal(0)) + Expect(session4).Should(Exit(0)) session5 := podmanTest.Podman([]string{"pod", "ps"}) session5.WaitWithDefaultTimeout() - Expect(session5.ExitCode()).To(Equal(0)) + Expect(session5).Should(Exit(0)) Expect(session5.OutputToString()).To(ContainSubstring(podName)) session6 := podmanTest.Podman([]string{"ps", "-a"}) session6.WaitWithDefaultTimeout() - Expect(session6.ExitCode()).To(Equal(0)) + Expect(session6).Should(Exit(0)) psOut := session6.OutputToString() Expect(psOut).To(ContainSubstring("test1")) Expect(psOut).To(ContainSubstring("test2")) @@ -436,31 +437,31 @@ var _ = Describe("Podman generate kube", func() { session := podmanTest.Podman([]string{"create", "--pod", podName, "--name", "test1", "--user", "100:200", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "--format", "{{.Config.User}}", "test1"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring("100:200")) outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml") kube := podmanTest.Podman([]string{"generate", "kube", "-f", outputFile, podName}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "rm", "-af"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podmanTest.AddImageToRWStore(ALPINE) session = podmanTest.Podman([]string{"play", "kube", outputFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // container name in pod is <podName>-<ctrName> inspect1 := podmanTest.Podman([]string{"inspect", "--format", "{{.Config.User}}", "toppod-test1"}) inspect1.WaitWithDefaultTimeout() - Expect(inspect1.ExitCode()).To(Equal(0)) + Expect(inspect1).Should(Exit(0)) Expect(inspect1.OutputToString()).To(ContainSubstring(inspect.OutputToString())) }) @@ -475,24 +476,24 @@ var _ = Describe("Podman generate kube", func() { session1 := podmanTest.Podman([]string{"run", "-d", "--pod", "new:test1", "--name", ctrName, "-v", vol1 + ":/volume/:z", "alpine", "top"}) session1.WaitWithDefaultTimeout() - Expect(session1.ExitCode()).To(Equal(0)) + Expect(session1).Should(Exit(0)) outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml") kube := podmanTest.Podman([]string{"generate", "kube", "test1", "-f", outputFile}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) rm := podmanTest.Podman([]string{"pod", "rm", "-f", "test1"}) rm.WaitWithDefaultTimeout() - Expect(rm.ExitCode()).To(Equal(0)) + Expect(rm).Should(Exit(0)) play := podmanTest.Podman([]string{"play", "kube", outputFile}) play.WaitWithDefaultTimeout() - Expect(play.ExitCode()).To(Equal(0)) + Expect(play).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrNameInKubePod}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(vol1)) }) @@ -505,11 +506,11 @@ var _ = Describe("Podman generate kube", func() { "-v", "/root:/volume2/", "alpine", "top"}) session1.WaitWithDefaultTimeout() - Expect(session1.ExitCode()).To(Equal(0)) + Expect(session1).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "mount-root-conflict"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -528,24 +529,24 @@ var _ = Describe("Podman generate kube", func() { session := podmanTest.Podman([]string{"run", "-d", "--pod", "new:test1", "--name", ctrName, "-v", vol + ":/volume/:z", "alpine", "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml") kube := podmanTest.Podman([]string{"generate", "kube", "test1", "-f", outputFile}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) rm := podmanTest.Podman([]string{"pod", "rm", "-f", "test1"}) rm.WaitWithDefaultTimeout() - Expect(rm.ExitCode()).To(Equal(0)) + Expect(rm).Should(Exit(0)) play := podmanTest.Podman([]string{"play", "kube", outputFile}) play.WaitWithDefaultTimeout() - Expect(play.ExitCode()).To(Equal(0)) + Expect(play).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrNameInKubePod}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(vol)) }) @@ -553,95 +554,95 @@ var _ = Describe("Podman generate kube", func() { podName := "test" podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--share", "pid"}) podSession.WaitWithDefaultTimeout() - Expect(podSession.ExitCode()).To(Equal(0)) + Expect(podSession).Should(Exit(0)) session := podmanTest.Podman([]string{"create", "--pod", podName, "--name", "test1", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml") kube := podmanTest.Podman([]string{"generate", "kube", podName, "-f", outputFile}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) rm := podmanTest.Podman([]string{"pod", "rm", "-f", podName}) rm.WaitWithDefaultTimeout() - Expect(rm.ExitCode()).To(Equal(0)) + Expect(rm).Should(Exit(0)) play := podmanTest.Podman([]string{"play", "kube", outputFile}) play.WaitWithDefaultTimeout() - Expect(play.ExitCode()).To(Equal(0)) + Expect(play).Should(Exit(0)) inspect := podmanTest.Podman([]string{"pod", "inspect", podName}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`"pid"`)) }) It("podman generate kube with pods and containers", func() { pod1 := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:pod1", ALPINE, "top"}) pod1.WaitWithDefaultTimeout() - Expect(pod1.ExitCode()).To(Equal(0)) + Expect(pod1).Should(Exit(0)) pod2 := podmanTest.Podman([]string{"run", "-dt", "--name", "top", ALPINE, "top"}) pod2.WaitWithDefaultTimeout() - Expect(pod2.ExitCode()).To(Equal(0)) + Expect(pod2).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "pod1", "top"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) }) It("podman generate kube with containers in a pod should fail", func() { pod1 := podmanTest.Podman([]string{"pod", "create", "--name", "pod1"}) pod1.WaitWithDefaultTimeout() - Expect(pod1.ExitCode()).To(Equal(0)) + Expect(pod1).Should(Exit(0)) con := podmanTest.Podman([]string{"run", "-dt", "--pod", "pod1", "--name", "top", ALPINE, "top"}) con.WaitWithDefaultTimeout() - Expect(con.ExitCode()).To(Equal(0)) + Expect(con).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "top"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).ToNot(Equal(0)) + Expect(kube).To(ExitWithError()) }) It("podman generate kube with multiple containers", func() { con1 := podmanTest.Podman([]string{"run", "-dt", "--name", "con1", ALPINE, "top"}) con1.WaitWithDefaultTimeout() - Expect(con1.ExitCode()).To(Equal(0)) + Expect(con1).Should(Exit(0)) con2 := podmanTest.Podman([]string{"run", "-dt", "--name", "con2", ALPINE, "top"}) con2.WaitWithDefaultTimeout() - Expect(con2.ExitCode()).To(Equal(0)) + Expect(con2).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "con1", "con2"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) }) It("podman generate kube with containers in pods should fail", func() { pod1 := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:pod1", "--name", "top1", ALPINE, "top"}) pod1.WaitWithDefaultTimeout() - Expect(pod1.ExitCode()).To(Equal(0)) + Expect(pod1).Should(Exit(0)) pod2 := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:pod2", "--name", "top2", ALPINE, "top"}) pod2.WaitWithDefaultTimeout() - Expect(pod2.ExitCode()).To(Equal(0)) + Expect(pod2).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "top1", "top2"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).ToNot(Equal(0)) + Expect(kube).To(ExitWithError()) }) It("podman generate kube on a container with dns options", func() { top := podmanTest.Podman([]string{"run", "-dt", "--name", "top", "--dns", "8.8.8.8", "--dns-search", "foobar.com", "--dns-opt", "color:blue", ALPINE, "top"}) top.WaitWithDefaultTimeout() - Expect(top.ExitCode()).To(BeZero()) + Expect(top).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "top"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -657,15 +658,15 @@ var _ = Describe("Podman generate kube", func() { It("podman generate kube multiple container dns servers and options are cumulative", func() { top1 := podmanTest.Podman([]string{"run", "-dt", "--name", "top1", "--dns", "8.8.8.8", "--dns-search", "foobar.com", ALPINE, "top"}) top1.WaitWithDefaultTimeout() - Expect(top1.ExitCode()).To(BeZero()) + Expect(top1).Should(Exit(0)) top2 := podmanTest.Podman([]string{"run", "-dt", "--name", "top2", "--dns", "8.7.7.7", "--dns-search", "homer.com", ALPINE, "top"}) top2.WaitWithDefaultTimeout() - Expect(top2.ExitCode()).To(BeZero()) + Expect(top2).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "top1", "top2"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -680,11 +681,11 @@ var _ = Describe("Podman generate kube", func() { It("podman generate kube on a pod with dns options", func() { top := podmanTest.Podman([]string{"run", "--pod", "new:pod1", "-dt", "--name", "top", "--dns", "8.8.8.8", "--dns-search", "foobar.com", "--dns-opt", "color:blue", ALPINE, "top"}) top.WaitWithDefaultTimeout() - Expect(top.ExitCode()).To(BeZero()) + Expect(top).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "pod1"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -700,11 +701,11 @@ var _ = Describe("Podman generate kube", func() { It("podman generate kube - set entrypoint as command", func() { session := podmanTest.Podman([]string{"create", "--pod", "new:testpod", "--entrypoint", "/bin/sleep", ALPINE, "10s"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "testpod"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) // Now make sure that the container's command is set to the // entrypoint and it's arguments to "10s". @@ -733,15 +734,15 @@ ENTRYPOINT /bin/sleep` image := "generatekube:test" session := podmanTest.Podman([]string{"build", "--pull-never", "-f", containerfilePath, "-t", image}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "--pod", "new:testpod", image, "10s"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "testpod"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) // Now make sure that the container's command is set to the // entrypoint and it's arguments to "10s". @@ -759,11 +760,11 @@ ENTRYPOINT /bin/sleep` It("podman generate kube - --privileged container", func() { session := podmanTest.Podman([]string{"create", "--pod", "new:testpod", "--privileged", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "testpod"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) // Now make sure that the capabilities aren't set. pod := new(v1.Pod) @@ -779,16 +780,16 @@ ENTRYPOINT /bin/sleep` kube = podmanTest.Podman([]string{"generate", "kube", "testpod", "-f", kubeFile}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) // Remove the pod so play can recreate it. kube = podmanTest.Podman([]string{"pod", "rm", "-f", "testpod"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) kube = podmanTest.Podman([]string{"play", "kube", kubeFile}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) }) It("podman generate kube based on user in container", func() { @@ -806,15 +807,15 @@ USER test1` image := "generatekube:test" session := podmanTest.Podman([]string{"build", "--pull-never", "-f", containerfilePath, "-t", image}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "--pod", "new:testpod", image, "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "testpod"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err = yaml.Unmarshal(kube.Out.Contents(), pod) @@ -827,11 +828,11 @@ USER test1` session := podmanTest.Podman([]string{"volume", "create", vol}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", vol}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pvc := new(v1.PersistentVolumeClaim) err := yaml.Unmarshal(kube.Out.Contents(), pvc) @@ -849,11 +850,11 @@ USER test1` session := podmanTest.Podman([]string{"volume", "create", "--opt", "device=" + volDevice, "--opt", "type=" + volType, "--opt", "o=" + volOpts, vol}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", vol}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pvc := new(v1.PersistentVolumeClaim) err := yaml.Unmarshal(kube.Out.Contents(), pvc) @@ -877,11 +878,11 @@ USER test1` It("podman generate kube on container with auto update labels", func() { top := podmanTest.Podman([]string{"run", "-dt", "--name", "top", "--label", "io.containers.autoupdate=local", ALPINE, "top"}) top.WaitWithDefaultTimeout() - Expect(top.ExitCode()).To(Equal(0)) + Expect(top).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "top"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) @@ -895,19 +896,19 @@ USER test1` It("podman generate kube on pod with auto update labels in all containers", func() { pod1 := podmanTest.Podman([]string{"pod", "create", "--name", "pod1"}) pod1.WaitWithDefaultTimeout() - Expect(pod1.ExitCode()).To(Equal(0)) + Expect(pod1).Should(Exit(0)) top1 := podmanTest.Podman([]string{"run", "-dt", "--name", "top1", "--pod", "pod1", "--label", "io.containers.autoupdate=registry", "--label", "io.containers.autoupdate.authfile=/some/authfile.json", ALPINE, "top"}) top1.WaitWithDefaultTimeout() - Expect(top1.ExitCode()).To(Equal(0)) + Expect(top1).Should(Exit(0)) top2 := podmanTest.Podman([]string{"run", "-dt", "--name", "top2", "--pod", "pod1", "--label", "io.containers.autoupdate=registry", "--label", "io.containers.autoupdate.authfile=/some/authfile.json", ALPINE, "top"}) top2.WaitWithDefaultTimeout() - Expect(top2.ExitCode()).To(Equal(0)) + Expect(top2).Should(Exit(0)) kube := podmanTest.Podman([]string{"generate", "kube", "pod1"}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) pod := new(v1.Pod) err := yaml.Unmarshal(kube.Out.Contents(), pod) diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go index e03d6899e..121f09a11 100644 --- a/test/e2e/generate_systemd_test.go +++ b/test/e2e/generate_systemd_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman generate systemd", func() { @@ -54,7 +55,7 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd bad restart-policy value", func() { session := podmanTest.Podman([]string{"create", "--name", "foobar", "alpine", "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"generate", "systemd", "--restart-policy", "bogus", "foobar"}) session.WaitWithDefaultTimeout() @@ -65,11 +66,11 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd with --no-header=true", func() { session := podmanTest.Podman([]string{"create", "--name", "foobar", "alpine", "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"generate", "systemd", "foobar", "--no-header=true"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).NotTo(ContainSubstring("autogenerated by")) }) @@ -77,11 +78,11 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd with --no-header", func() { session := podmanTest.Podman([]string{"create", "--name", "foobar", "alpine", "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"generate", "systemd", "foobar", "--no-header"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).NotTo(ContainSubstring("autogenerated by")) }) @@ -89,11 +90,11 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd with --no-header=false", func() { session := podmanTest.Podman([]string{"create", "--name", "foobar", "alpine", "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"generate", "systemd", "foobar", "--no-header=false"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("autogenerated by")) }) @@ -101,11 +102,11 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd good timeout value", func() { session := podmanTest.Podman([]string{"create", "--name", "foobar", "alpine", "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"generate", "systemd", "--time", "1234", "foobar"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("TimeoutStopSec=1294")) Expect(session.OutputToString()).To(ContainSubstring(" stop -t 1234 ")) }) @@ -113,11 +114,11 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd", func() { n := podmanTest.Podman([]string{"run", "--name", "nginx", "-dt", nginx}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "nginx"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // The podman commands in the unit should not contain the root flags Expect(session.OutputToString()).ToNot(ContainSubstring(" --runroot")) @@ -126,11 +127,11 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd --files --name", func() { n := podmanTest.Podman([]string{"run", "--name", "nginx", "-dt", nginx}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--files", "--name", "nginx"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) for _, file := range session.OutputToStringArray() { os.Remove(file) @@ -141,30 +142,30 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd with timeout", func() { n := podmanTest.Podman([]string{"run", "--name", "nginx", "-dt", nginx}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--time", "5", "nginx"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("podman stop -t 5")) }) It("podman generate systemd pod --name", func() { n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-1", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-2", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--time", "42", "--name", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Grepping the output (in addition to unit tests) Expect(session.OutputToString()).To(ContainSubstring("# pod-foo.service")) @@ -185,15 +186,15 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd pod --name --files", func() { n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-1", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--name", "--files", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) for _, file := range session.OutputToStringArray() { os.Remove(file) @@ -206,11 +207,11 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd --new --name foo", func() { n := podmanTest.Podman([]string{"create", "--name", "foo", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "-t", "42", "--name", "--new", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Grepping the output (in addition to unit tests) Expect(session.OutputToString()).To(ContainSubstring("# container-foo.service")) @@ -224,11 +225,11 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd --new --name=foo", func() { n := podmanTest.Podman([]string{"create", "--name=foo", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "-t", "42", "--name", "--new", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Grepping the output (in addition to unit tests) Expect(session.OutputToString()).To(ContainSubstring("# container-foo.service")) @@ -238,11 +239,11 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd --new without explicit detaching param", func() { n := podmanTest.Podman([]string{"create", "--name", "foo", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--time", "42", "--name", "--new", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Grepping the output (in addition to unit tests) Expect(session.OutputToString()).To(ContainSubstring(" -d ")) @@ -251,11 +252,11 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd --new with explicit detaching param in middle", func() { n := podmanTest.Podman([]string{"create", "--name", "foo", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--time", "42", "--name", "--new", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Grepping the output (in addition to unit tests) Expect(session.OutputToString()).To(ContainSubstring("--name foo alpine top")) @@ -264,44 +265,44 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd --new pod", func() { n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--time", "42", "--name", "--new", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(" pod create ")) }) It("podman generate systemd --new=false pod", func() { n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--time", "42", "--name", "--new=false", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).NotTo(ContainSubstring(" pod create ")) }) It("podman generate systemd --new=true pod", func() { n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--time", "42", "--name", "--new=true", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(" pod create ")) }) It("podman generate systemd --container-prefix con", func() { n := podmanTest.Podman([]string{"create", "--name", "foo", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--name", "--container-prefix", "con", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Grepping the output (in addition to unit tests) Expect(session.OutputToString()).To(ContainSubstring("# con-foo.service")) @@ -311,11 +312,11 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd --separator _", func() { n := podmanTest.Podman([]string{"create", "--name", "foo", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--name", "--separator", "_", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Grepping the output (in addition to unit tests) Expect(session.OutputToString()).To(ContainSubstring("# container_foo.service")) @@ -324,19 +325,19 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd pod --pod-prefix p", func() { n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-1", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-2", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--pod-prefix", "p", "--name", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Grepping the output (in addition to unit tests) Expect(session.OutputToString()).To(ContainSubstring("# p-foo.service")) @@ -348,19 +349,19 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd pod --pod-prefix p --container-prefix con --separator _ change all prefixes/separator", func() { n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-1", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-2", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--container-prefix", "con", "--pod-prefix", "p", "--separator", "_", "--name", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Grepping the output (in addition to unit tests) Expect(session.OutputToString()).To(ContainSubstring("# p_foo.service")) @@ -378,19 +379,19 @@ var _ = Describe("Podman generate systemd", func() { n := podmanTest.Podman([]string{"pod", "create", "--pod-id-file", tmpFile, "--name", "foo"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-1", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-2", "alpine", "top"}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--new", "--name", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Grepping the output (in addition to unit tests) Expect(session.OutputToString()).To(ContainSubstring("# pod-foo.service")) @@ -405,11 +406,11 @@ var _ = Describe("Podman generate systemd", func() { It("podman generate systemd --format json", func() { n := podmanTest.Podman([]string{"create", "--name", "foo", ALPINE}) n.WaitWithDefaultTimeout() - Expect(n.ExitCode()).To(Equal(0)) + Expect(n).Should(Exit(0)) session := podmanTest.Podman([]string{"generate", "systemd", "--format", "json", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) }) @@ -417,20 +418,20 @@ var _ = Describe("Podman generate systemd", func() { // Regression test for #9034 session := podmanTest.Podman([]string{"create", "--name", "foo", "--log-driver=journald", "--log-opt=tag={{.Name}}", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"generate", "systemd", "--new", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(" --log-opt=tag={{.Name}} ")) session = podmanTest.Podman([]string{"pod", "create", "--name", "pod", "--label", "key={{someval}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"generate", "systemd", "--new", "pod"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(" --label key={{someval}}")) }) }) diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go index bea22ea85..535783dbd 100644 --- a/test/e2e/healthcheck_run_test.go +++ b/test/e2e/healthcheck_run_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman healthcheck run", func() { @@ -44,26 +45,26 @@ var _ = Describe("Podman healthcheck run", func() { It("podman disable healthcheck with --no-healthcheck on valid container", func() { session := podmanTest.Podman([]string{"run", "-dt", "--no-healthcheck", "--name", "hc", healthcheck}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(125)) + Expect(hc).Should(Exit(125)) }) It("podman disable healthcheck with --health-cmd=none on valid container", func() { session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "none", "--name", "hc", healthcheck}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(125)) + Expect(hc).Should(Exit(125)) }) It("podman healthcheck on valid container", func() { Skip("Extremely consistent flake - re-enable on debugging") session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", healthcheck}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) exitCode := 999 @@ -83,37 +84,37 @@ var _ = Describe("Podman healthcheck run", func() { It("podman healthcheck that should fail", func() { session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "quay.io/libpod/badhealthcheck:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(1)) + Expect(hc).Should(Exit(1)) }) It("podman healthcheck on stopped container", func() { session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", healthcheck, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(125)) + Expect(hc).Should(Exit(125)) }) It("podman healthcheck on container without healthcheck", func() { session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(125)) + Expect(hc).Should(Exit(125)) }) It("podman healthcheck should be starting", func() { session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-retries", "2", "--health-cmd", "ls /foo || exit 1", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.InspectContainer("hc") Expect(inspect[0].State.Healthcheck.Status).To(Equal("starting")) }) @@ -121,19 +122,19 @@ var _ = Describe("Podman healthcheck run", func() { It("podman healthcheck failed checks in start-period should not change status", func() { session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-start-period", "2m", "--health-retries", "2", "--health-cmd", "ls /foo || exit 1", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(1)) + Expect(hc).Should(Exit(1)) hc = podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(1)) + Expect(hc).Should(Exit(1)) hc = podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(1)) + Expect(hc).Should(Exit(1)) inspect := podmanTest.InspectContainer("hc") Expect(inspect[0].State.Healthcheck.Status).To(Equal("starting")) @@ -142,18 +143,18 @@ var _ = Describe("Podman healthcheck run", func() { It("podman healthcheck failed checks must reach retries before unhealthy ", func() { session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-retries", "2", "--health-cmd", "ls /foo || exit 1", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(1)) + Expect(hc).Should(Exit(1)) inspect := podmanTest.InspectContainer("hc") Expect(inspect[0].State.Healthcheck.Status).To(Equal("starting")) hc = podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(1)) + Expect(hc).Should(Exit(1)) inspect = podmanTest.InspectContainer("hc") Expect(inspect[0].State.Healthcheck.Status).To(Equal("unhealthy")) @@ -163,11 +164,11 @@ var _ = Describe("Podman healthcheck run", func() { It("podman healthcheck good check results in healthy even in start-period", func() { session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-start-period", "2m", "--health-retries", "2", "--health-cmd", "ls || exit 1", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(0)) + Expect(hc).Should(Exit(0)) inspect := podmanTest.InspectContainer("hc") Expect(inspect[0].State.Healthcheck.Status).To(Equal("healthy")) @@ -186,29 +187,29 @@ var _ = Describe("Podman healthcheck run", func() { It("podman healthcheck single healthy result changes failed to healthy", func() { session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-retries", "2", "--health-cmd", "ls /foo || exit 1", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(1)) + Expect(hc).Should(Exit(1)) inspect := podmanTest.InspectContainer("hc") Expect(inspect[0].State.Healthcheck.Status).To(Equal("starting")) hc = podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(1)) + Expect(hc).Should(Exit(1)) inspect = podmanTest.InspectContainer("hc") Expect(inspect[0].State.Healthcheck.Status).To(Equal("unhealthy")) foo := podmanTest.Podman([]string{"exec", "hc", "touch", "/foo"}) foo.WaitWithDefaultTimeout() - Expect(foo.ExitCode()).To(BeZero()) + Expect(foo).Should(Exit(0)) hc = podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() - Expect(hc.ExitCode()).To(Equal(0)) + Expect(hc).Should(Exit(0)) inspect = podmanTest.InspectContainer("hc") Expect(inspect[0].State.Healthcheck.Status).To(Equal("healthy")) diff --git a/test/e2e/history_test.go b/test/e2e/history_test.go index e2cf62d9a..0f0f6d38a 100644 --- a/test/e2e/history_test.go +++ b/test/e2e/history_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman history", func() { @@ -35,40 +36,40 @@ var _ = Describe("Podman history", func() { It("podman history output flag", func() { session := podmanTest.Podman([]string{"history", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 0)) }) It("podman history with GO template", func() { session := podmanTest.Podman([]string{"history", "--format", "{{.ID}} {{.Created}}", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 0)) }) It("podman history with human flag", func() { session := podmanTest.Podman([]string{"history", "--human=false", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 0)) }) It("podman history with quiet flag", func() { session := podmanTest.Podman([]string{"history", "-qH", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 0)) }) It("podman history with no-trunc flag", func() { session := podmanTest.Podman([]string{"history", "--no-trunc", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 0)) session = podmanTest.Podman([]string{"history", "--no-trunc", "--format", "{{.ID}}", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) lines := session.OutputToStringArray() Expect(len(lines)).To(BeNumerically(">", 0)) // the image id must be 64 chars long @@ -76,7 +77,7 @@ var _ = Describe("Podman history", func() { session = podmanTest.Podman([]string{"history", "--no-trunc", "--format", "{{.CreatedBy}}", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) lines = session.OutputToStringArray() Expect(len(lines)).To(BeNumerically(">", 0)) Expect(session.OutputToString()).ToNot(ContainSubstring("...")) @@ -87,7 +88,7 @@ var _ = Describe("Podman history", func() { It("podman history with json flag", func() { session := podmanTest.Podman([]string{"history", "--format=json", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) }) }) diff --git a/test/e2e/image_sign_test.go b/test/e2e/image_sign_test.go index 704a78685..6b87c9edd 100644 --- a/test/e2e/image_sign_test.go +++ b/test/e2e/image_sign_test.go @@ -9,6 +9,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman image sign", func() { @@ -55,7 +56,7 @@ var _ = Describe("Podman image sign", func() { Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"image", "sign", "--directory", sigDir, "--sign-by", "foo@bar.com", "docker://library/alpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, err = os.Stat(filepath.Join(sigDir, "library")) Expect(err).To(BeNil()) }) @@ -69,7 +70,7 @@ var _ = Describe("Podman image sign", func() { Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"image", "sign", "--all", "--directory", sigDir, "--sign-by", "foo@bar.com", "docker://library/alpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) fInfos, err := ioutil.ReadDir(filepath.Join(sigDir, "library")) Expect(err).To(BeNil()) Expect(len(fInfos) > 1).To(BeTrue()) diff --git a/test/e2e/import_test.go b/test/e2e/import_test.go index 1f1b23bd0..519a7290c 100644 --- a/test/e2e/import_test.go +++ b/test/e2e/import_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman import", func() { @@ -41,15 +42,15 @@ var _ = Describe("Podman import", func() { export := podmanTest.Podman([]string{"export", "-o", outfile, cid}) export.WaitWithDefaultTimeout() - Expect(export.ExitCode()).To(Equal(0)) + Expect(export).Should(Exit(0)) importImage := podmanTest.Podman([]string{"import", outfile, "foobar.com/imported-image:latest"}) importImage.WaitWithDefaultTimeout() - Expect(importImage.ExitCode()).To(Equal(0)) + Expect(importImage).Should(Exit(0)) results := podmanTest.Podman([]string{"inspect", "--type", "image", "foobar.com/imported-image:latest"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) }) It("podman import without reference", func() { @@ -59,16 +60,16 @@ var _ = Describe("Podman import", func() { export := podmanTest.Podman([]string{"export", "-o", outfile, cid}) export.WaitWithDefaultTimeout() - Expect(export.ExitCode()).To(Equal(0)) + Expect(export).Should(Exit(0)) importImage := podmanTest.Podman([]string{"import", outfile}) importImage.WaitWithDefaultTimeout() - Expect(importImage.ExitCode()).To(Equal(0)) + Expect(importImage).Should(Exit(0)) // tag the image which proves it is in R/W storage tag := podmanTest.Podman([]string{"tag", importImage.OutputToString(), "foo"}) tag.WaitWithDefaultTimeout() - Expect(tag.ExitCode()).To(BeZero()) + Expect(tag).Should(Exit(0)) }) It("podman import with message flag", func() { @@ -78,15 +79,15 @@ var _ = Describe("Podman import", func() { export := podmanTest.Podman([]string{"export", "-o", outfile, cid}) export.WaitWithDefaultTimeout() - Expect(export.ExitCode()).To(Equal(0)) + Expect(export).Should(Exit(0)) importImage := podmanTest.Podman([]string{"import", "--message", "importing container test message", outfile, "imported-image"}) importImage.WaitWithDefaultTimeout() - Expect(importImage.ExitCode()).To(Equal(0)) + Expect(importImage).Should(Exit(0)) results := podmanTest.Podman([]string{"history", "imported-image", "--format", "{{.Comment}}"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) Expect(results.LineInOutputStartsWith("importing container test message")).To(BeTrue()) }) @@ -97,15 +98,15 @@ var _ = Describe("Podman import", func() { export := podmanTest.Podman([]string{"export", "-o", outfile, cid}) export.WaitWithDefaultTimeout() - Expect(export.ExitCode()).To(Equal(0)) + Expect(export).Should(Exit(0)) importImage := podmanTest.Podman([]string{"import", "--change", "CMD=/bin/bash", outfile, "imported-image"}) importImage.WaitWithDefaultTimeout() - Expect(importImage.ExitCode()).To(Equal(0)) + Expect(importImage).Should(Exit(0)) results := podmanTest.Podman([]string{"inspect", "imported-image"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) imageData := results.InspectImageJSON() Expect(imageData[0].Config.Cmd[0]).To(Equal("/bin/sh")) Expect(imageData[0].Config.Cmd[1]).To(Equal("-c")) @@ -119,15 +120,15 @@ var _ = Describe("Podman import", func() { export := podmanTest.Podman([]string{"export", "-o", outfile, cid}) export.WaitWithDefaultTimeout() - Expect(export.ExitCode()).To(Equal(0)) + Expect(export).Should(Exit(0)) importImage := podmanTest.Podman([]string{"import", "--change", "CMD /bin/sh", outfile, "imported-image"}) importImage.WaitWithDefaultTimeout() - Expect(importImage.ExitCode()).To(Equal(0)) + Expect(importImage).Should(Exit(0)) results := podmanTest.Podman([]string{"inspect", "imported-image"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) imageData := results.InspectImageJSON() Expect(imageData[0].Config.Cmd[0]).To(Equal("/bin/sh")) Expect(imageData[0].Config.Cmd[1]).To(Equal("-c")) @@ -141,15 +142,15 @@ var _ = Describe("Podman import", func() { export := podmanTest.Podman([]string{"export", "-o", outfile, cid}) export.WaitWithDefaultTimeout() - Expect(export.ExitCode()).To(Equal(0)) + Expect(export).Should(Exit(0)) importImage := podmanTest.Podman([]string{"import", "--change", "CMD [\"/bin/bash\"]", outfile, "imported-image"}) importImage.WaitWithDefaultTimeout() - Expect(importImage.ExitCode()).To(Equal(0)) + Expect(importImage).Should(Exit(0)) results := podmanTest.Podman([]string{"inspect", "imported-image"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) imageData := results.InspectImageJSON() Expect(imageData[0].Config.Cmd[0]).To(Equal("/bin/bash")) }) @@ -161,14 +162,14 @@ var _ = Describe("Podman import", func() { export := podmanTest.Podman([]string{"export", "-o", outfile, cid}) export.WaitWithDefaultTimeout() - Expect(export.ExitCode()).To(Equal(0)) + Expect(export).Should(Exit(0)) importImage := podmanTest.Podman([]string{"import", "--signature-policy", "/no/such/file", outfile}) importImage.WaitWithDefaultTimeout() - Expect(importImage.ExitCode()).To(Not(Equal(0))) + Expect(importImage).To(ExitWithError()) result := podmanTest.Podman([]string{"import", "--signature-policy", "/etc/containers/policy.json", outfile}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) }) diff --git a/test/e2e/info_test.go b/test/e2e/info_test.go index 83d185be1..8ac538dd2 100644 --- a/test/e2e/info_test.go +++ b/test/e2e/info_test.go @@ -67,13 +67,13 @@ var _ = Describe("Podman Info", func() { It("podman info --format GO template", func() { session := podmanTest.Podman([]string{"info", "--format", "{{.Store.GraphRoot}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman info --format GO template", func() { session := podmanTest.Podman([]string{"info", "--format", "{{.Registries}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("registry")) }) @@ -113,13 +113,13 @@ var _ = Describe("Podman Info", func() { It("podman info check RemoteSocket", func() { session := podmanTest.Podman([]string{"info", "--format", "{{.Host.RemoteSocket.Path}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(MatchRegexp("/run/.*podman.*sock")) if IsRemote() { session = podmanTest.Podman([]string{"info", "--format", "{{.Host.RemoteSocket.Exists}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("true")) } }) diff --git a/test/e2e/init_test.go b/test/e2e/init_test.go index d283e1f9a..788b67154 100644 --- a/test/e2e/init_test.go +++ b/test/e2e/init_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman init", func() { @@ -35,26 +36,26 @@ var _ = Describe("Podman init", func() { It("podman init bogus container", func() { session := podmanTest.Podman([]string{"start", "123456"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman init with no arguments", func() { session := podmanTest.Podman([]string{"start"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman init single container by ID", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() init := podmanTest.Podman([]string{"init", cid}) init.WaitWithDefaultTimeout() - Expect(init.ExitCode()).To(Equal(0)) + Expect(init).Should(Exit(0)) result := podmanTest.Podman([]string{"inspect", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() Expect(conData[0].State.Status).To(Equal("created")) }) @@ -63,13 +64,13 @@ var _ = Describe("Podman init", func() { name := "test1" session := podmanTest.Podman([]string{"create", "--name", name, ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) init := podmanTest.Podman([]string{"init", name}) init.WaitWithDefaultTimeout() - Expect(init.ExitCode()).To(Equal(0)) + Expect(init).Should(Exit(0)) result := podmanTest.Podman([]string{"inspect", name}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() Expect(conData[0].State.Status).To(Equal("created")) }) @@ -78,13 +79,13 @@ var _ = Describe("Podman init", func() { SkipIfRemote("--latest flag n/a") session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) init := podmanTest.Podman([]string{"init", "--latest"}) init.WaitWithDefaultTimeout() - Expect(init.ExitCode()).To(Equal(0)) + Expect(init).Should(Exit(0)) result := podmanTest.Podman([]string{"inspect", "--latest"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() Expect(conData[0].State.Status).To(Equal("created")) }) @@ -92,29 +93,29 @@ var _ = Describe("Podman init", func() { It("podman init all three containers, one running", func() { session := podmanTest.Podman([]string{"create", "--name", "test1", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session2 := podmanTest.Podman([]string{"create", "--name", "test2", ALPINE, "ls"}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) session3 := podmanTest.Podman([]string{"run", "--name", "test3", "-d", ALPINE, "top"}) session3.WaitWithDefaultTimeout() - Expect(session3.ExitCode()).To(Equal(0)) + Expect(session3).Should(Exit(0)) init := podmanTest.Podman([]string{"init", "--all"}) init.WaitWithDefaultTimeout() - Expect(init.ExitCode()).To(Equal(0)) + Expect(init).Should(Exit(0)) result := podmanTest.Podman([]string{"inspect", "test1"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() Expect(conData[0].State.Status).To(Equal("created")) result2 := podmanTest.Podman([]string{"inspect", "test2"}) result2.WaitWithDefaultTimeout() - Expect(result2.ExitCode()).To(Equal(0)) + Expect(result2).Should(Exit(0)) conData2 := result2.InspectContainerToJSON() Expect(conData2[0].State.Status).To(Equal("created")) result3 := podmanTest.Podman([]string{"inspect", "test3"}) result3.WaitWithDefaultTimeout() - Expect(result3.ExitCode()).To(Equal(0)) + Expect(result3).Should(Exit(0)) conData3 := result3.InspectContainerToJSON() Expect(conData3[0].State.Status).To(Equal("running")) }) @@ -122,9 +123,9 @@ var _ = Describe("Podman init", func() { It("podman init running container errors", func() { session := podmanTest.Podman([]string{"run", "--name", "init_test", "-d", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) init := podmanTest.Podman([]string{"init", "init_test"}) init.WaitWithDefaultTimeout() - Expect(init.ExitCode()).To(Equal(125)) + Expect(init).Should(Exit(125)) }) }) diff --git a/test/e2e/inspect_test.go b/test/e2e/inspect_test.go index ba018b5ad..89859e74f 100644 --- a/test/e2e/inspect_test.go +++ b/test/e2e/inspect_test.go @@ -38,7 +38,7 @@ var _ = Describe("Podman inspect", func() { It("podman inspect alpine image", func() { session := podmanTest.Podman([]string{"inspect", "--format=json", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) imageData := session.InspectImageJSON() Expect(imageData[0].RepoTags[0]).To(Equal("quay.io/libpod/alpine:latest")) @@ -53,18 +53,18 @@ var _ = Describe("Podman inspect", func() { It("podman inspect with GO format", func() { session := podmanTest.Podman([]string{"inspect", "--format", "{{.ID}}", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"images", "-q", "--no-trunc", ALPINE}) result.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(strings.Contains(result.OutputToString(), session.OutputToString())) }) It("podman inspect specified type", func() { session := podmanTest.Podman([]string{"inspect", "--type", "image", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman inspect container with GO format for ConmonPidFile", func() { @@ -73,7 +73,7 @@ var _ = Describe("Podman inspect", func() { session = podmanTest.Podman([]string{"inspect", "--format", "{{.ConmonPidFile}}", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman inspect container with size", func() { @@ -82,7 +82,7 @@ var _ = Describe("Podman inspect", func() { result := podmanTest.Podman([]string{"inspect", "--size", "sizetest"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() Expect(conData[0].SizeRootFs).To(BeNumerically(">", 0)) Expect(*conData[0].SizeRw).To(BeNumerically(">=", 0)) @@ -95,7 +95,7 @@ var _ = Describe("Podman inspect", func() { result := podmanTest.Podman([]string{"inspect", "--format={{.ID}}", cid, ALPINE}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(Equal(2)) }) @@ -106,12 +106,12 @@ var _ = Describe("Podman inspect", func() { result := podmanTest.Podman([]string{"inspect", "--format={{.ImageID}}", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(Equal(1)) result = podmanTest.Podman([]string{"inspect", "--format={{.Image}}", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(Equal(1)) }) @@ -122,7 +122,7 @@ var _ = Describe("Podman inspect", func() { result := podmanTest.Podman([]string{"inspect", "--format={{.Config.CreateCommand}}", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(Equal(1)) }) @@ -130,33 +130,33 @@ var _ = Describe("Podman inspect", func() { SkipIfRemote("--latest flag n/a") result := podmanTest.Podman([]string{"inspect", "-l", "1234foobar"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) }) It("podman inspect with mount filters", func() { ctrSession := podmanTest.Podman([]string{"create", "--name", "test", "-v", "/tmp:/test1", ALPINE, "top"}) ctrSession.WaitWithDefaultTimeout() - Expect(ctrSession.ExitCode()).To(Equal(0)) + Expect(ctrSession).Should(Exit(0)) inspectSource := podmanTest.Podman([]string{"inspect", "test", "--format", "{{(index .Mounts 0).Source}}"}) inspectSource.WaitWithDefaultTimeout() - Expect(inspectSource.ExitCode()).To(Equal(0)) + Expect(inspectSource).Should(Exit(0)) Expect(inspectSource.OutputToString()).To(Equal("/tmp")) inspectSrc := podmanTest.Podman([]string{"inspect", "test", "--format", "{{(index .Mounts 0).Src}}"}) inspectSrc.WaitWithDefaultTimeout() - Expect(inspectSrc.ExitCode()).To(Equal(0)) + Expect(inspectSrc).Should(Exit(0)) Expect(inspectSrc.OutputToString()).To(Equal("/tmp")) inspectDestination := podmanTest.Podman([]string{"inspect", "test", "--format", "{{(index .Mounts 0).Destination}}"}) inspectDestination.WaitWithDefaultTimeout() - Expect(inspectDestination.ExitCode()).To(Equal(0)) + Expect(inspectDestination).Should(Exit(0)) Expect(inspectDestination.OutputToString()).To(Equal("/test1")) inspectDst := podmanTest.Podman([]string{"inspect", "test", "--format", "{{(index .Mounts 0).Dst}}"}) inspectDst.WaitWithDefaultTimeout() - Expect(inspectDst.ExitCode()).To(Equal(0)) + Expect(inspectDst).Should(Exit(0)) Expect(inspectDst.OutputToString()).To(Equal("/test1")) }) @@ -175,23 +175,23 @@ var _ = Describe("Podman inspect", func() { session := podmanTest.Podman([]string{"inspect", "--latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("podman [image,container] inspect on image", func() { baseInspect := podmanTest.Podman([]string{"inspect", ALPINE}) baseInspect.WaitWithDefaultTimeout() - Expect(baseInspect.ExitCode()).To(Equal(0)) + Expect(baseInspect).Should(Exit(0)) baseJSON := baseInspect.InspectImageJSON() Expect(len(baseJSON)).To(Equal(1)) ctrInspect := podmanTest.Podman([]string{"container", "inspect", ALPINE}) ctrInspect.WaitWithDefaultTimeout() - Expect(ctrInspect.ExitCode()).To(Not(Equal(0))) + Expect(ctrInspect).To(ExitWithError()) imageInspect := podmanTest.Podman([]string{"image", "inspect", ALPINE}) imageInspect.WaitWithDefaultTimeout() - Expect(imageInspect.ExitCode()).To(Equal(0)) + Expect(imageInspect).Should(Exit(0)) imageJSON := imageInspect.InspectImageJSON() Expect(len(imageJSON)).To(Equal(1)) @@ -202,23 +202,23 @@ var _ = Describe("Podman inspect", func() { ctrName := "testCtr" create := podmanTest.Podman([]string{"create", "--name", ctrName, ALPINE, "sh"}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) baseInspect := podmanTest.Podman([]string{"inspect", ctrName}) baseInspect.WaitWithDefaultTimeout() - Expect(baseInspect.ExitCode()).To(Equal(0)) + Expect(baseInspect).Should(Exit(0)) baseJSON := baseInspect.InspectContainerToJSON() Expect(len(baseJSON)).To(Equal(1)) ctrInspect := podmanTest.Podman([]string{"container", "inspect", ctrName}) ctrInspect.WaitWithDefaultTimeout() - Expect(ctrInspect.ExitCode()).To(Equal(0)) + Expect(ctrInspect).Should(Exit(0)) ctrJSON := ctrInspect.InspectContainerToJSON() Expect(len(ctrJSON)).To(Equal(1)) imageInspect := podmanTest.Podman([]string{"image", "inspect", ctrName}) imageInspect.WaitWithDefaultTimeout() - Expect(imageInspect.ExitCode()).To(Not(Equal(0))) + Expect(imageInspect).To(ExitWithError()) Expect(baseJSON[0].ID).To(Equal(ctrJSON[0].ID)) }) @@ -226,7 +226,7 @@ var _ = Describe("Podman inspect", func() { It("podman inspect always produces a valid array", func() { baseInspect := podmanTest.Podman([]string{"inspect", "doesNotExist"}) baseInspect.WaitWithDefaultTimeout() - Expect(baseInspect.ExitCode()).To(Not(Equal(0))) + Expect(baseInspect).To(ExitWithError()) emptyJSON := baseInspect.InspectContainerToJSON() Expect(len(emptyJSON)).To(Equal(0)) }) @@ -235,11 +235,11 @@ var _ = Describe("Podman inspect", func() { ctrName := "testCtr" create := podmanTest.Podman([]string{"create", "--name", ctrName, ALPINE, "sh"}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) baseInspect := podmanTest.Podman([]string{"inspect", ctrName, "doesNotExist"}) baseInspect.WaitWithDefaultTimeout() - Expect(baseInspect.ExitCode()).To(Not(Equal(0))) + Expect(baseInspect).To(ExitWithError()) baseJSON := baseInspect.InspectContainerToJSON() Expect(len(baseJSON)).To(Equal(1)) Expect(baseJSON[0].Name).To(Equal(ctrName)) @@ -250,15 +250,15 @@ var _ = Describe("Podman inspect", func() { ctrName := "testcontainer" create := podmanTest.Podman([]string{"create", "--name", ctrName, ALPINE, "sh"}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) tag := podmanTest.Podman([]string{"tag", ALPINE, ctrName + ":latest"}) tag.WaitWithDefaultTimeout() - Expect(tag.ExitCode()).To(Equal(0)) + Expect(tag).Should(Exit(0)) baseInspect := podmanTest.Podman([]string{"inspect", ctrName}) baseInspect.WaitWithDefaultTimeout() - Expect(baseInspect.ExitCode()).To(Equal(0)) + Expect(baseInspect).Should(Exit(0)) baseJSON := baseInspect.InspectContainerToJSON() Expect(len(baseJSON)).To(Equal(1)) Expect(baseJSON[0].Name).To(Equal(ctrName)) @@ -278,11 +278,11 @@ var _ = Describe("Podman inspect", func() { ALPINE, "sh"}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) baseInspect := podmanTest.Podman([]string{"inspect", ctrName}) baseInspect.WaitWithDefaultTimeout() - Expect(baseInspect.ExitCode()).To(Equal(0)) + Expect(baseInspect).Should(Exit(0)) baseJSON := baseInspect.InspectContainerToJSON() Expect(len(baseJSON)).To(Equal(1)) Expect(baseJSON[0].HostConfig.SecurityOpt).To(Equal([]string{"label=type:spc_t,label=level:s0", "seccomp=unconfined"})) @@ -292,11 +292,11 @@ var _ = Describe("Podman inspect", func() { podName := "testpod" create := podmanTest.Podman([]string{"pod", "create", "--name", podName}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", podName}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.IsJSONOutputValid()).To(BeTrue()) podData := inspect.InspectPodArrToJSON() Expect(podData[0].Name).To(Equal(podName)) @@ -306,11 +306,11 @@ var _ = Describe("Podman inspect", func() { podName := "testpod" create := podmanTest.Podman([]string{"pod", "create", "--name", podName}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "--type", "pod", podName}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.IsJSONOutputValid()).To(BeTrue()) podData := inspect.InspectPodArrToJSON() Expect(podData[0].Name).To(Equal(podName)) @@ -321,11 +321,11 @@ var _ = Describe("Podman inspect", func() { podName := "testpod" create := podmanTest.Podman([]string{"pod", "create", "--name", podName}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "--type", "pod", "--latest"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.IsJSONOutputValid()).To(BeTrue()) podData := inspect.InspectPodArrToJSON() Expect(podData[0].Name).To(Equal(podName)) @@ -335,18 +335,18 @@ var _ = Describe("Podman inspect", func() { podName := "testpod" pod := podmanTest.Podman([]string{"pod", "create", "--name", podName}) pod.WaitWithDefaultTimeout() - Expect(pod.ExitCode()).To(Equal(0)) + Expect(pod).Should(Exit(0)) inspect1 := podmanTest.Podman([]string{"inspect", "--type", "pod", podName}) inspect1.WaitWithDefaultTimeout() - Expect(inspect1.ExitCode()).To(Equal(0)) + Expect(inspect1).Should(Exit(0)) Expect(inspect1.IsJSONOutputValid()).To(BeTrue()) podData := inspect1.InspectPodArrToJSON() infra := podData[0].Containers[0].Name inspect := podmanTest.Podman([]string{"inspect", "--latest"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.IsJSONOutputValid()).To(BeTrue()) containerData := inspect.InspectContainerToJSON() Expect(containerData[0].Name).To(Equal(infra)) @@ -358,7 +358,7 @@ var _ = Describe("Podman inspect", func() { session := podmanTest.Podman([]string{"inspect", name, "--format", "{{.cniVersion}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("0.3.0")).To(BeTrue()) }) @@ -366,11 +366,11 @@ var _ = Describe("Podman inspect", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol"}) session.WaitWithDefaultTimeout() volName := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"inspect", volName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) }) @@ -378,18 +378,18 @@ var _ = Describe("Podman inspect", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol"}) session.WaitWithDefaultTimeout() volName := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"inspect", "--format", "{{.Name}}", volName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(volName)) }) It("podman inspect --type container on a pod should fail", func() { podName := "testpod" create := podmanTest.Podman([]string{"pod", "create", "--name", podName}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "--type", "container", podName}) inspect.WaitWithDefaultTimeout() @@ -400,7 +400,7 @@ var _ = Describe("Podman inspect", func() { ctrName := "testctr" create := podmanTest.Podman([]string{"create", "--name", ctrName, ALPINE}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "--type", "network", ctrName}) inspect.WaitWithDefaultTimeout() @@ -411,7 +411,7 @@ var _ = Describe("Podman inspect", func() { ctrName := "testctr" create := podmanTest.Podman([]string{"create", "--name", ctrName, ALPINE}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "--type", "pod", ctrName}) inspect.WaitWithDefaultTimeout() @@ -422,7 +422,7 @@ var _ = Describe("Podman inspect", func() { ctrName := "testctr" create := podmanTest.Podman([]string{"create", "--name", ctrName, ALPINE}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "--type", "volume", ctrName}) inspect.WaitWithDefaultTimeout() @@ -448,7 +448,7 @@ var _ = Describe("Podman inspect", func() { ctrName := "testctr" session := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) inspect := podmanTest.InspectContainer(ctrName) Expect(len(inspect)).To(Equal(1)) @@ -460,7 +460,7 @@ var _ = Describe("Podman inspect", func() { ctrName := "testctr" session := podmanTest.Podman([]string{"create", "--name", ctrName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) inspect := podmanTest.InspectContainer(ctrName) Expect(len(inspect)).To(Equal(1)) @@ -471,11 +471,11 @@ var _ = Describe("Podman inspect", func() { ctrName := "testctr" session := podmanTest.Podman([]string{"run", "-d", "--ulimit", "core=-1:-1", "--name", ctrName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) data := inspect.InspectContainerToJSON() ulimits := data[0].HostConfig.Ulimits @@ -495,11 +495,11 @@ var _ = Describe("Podman inspect", func() { ctrName := "testCtr" session := podmanTest.Podman([]string{"run", "-d", "--cap-drop", "CAP_AUDIT_WRITE", "--cap-drop", "CAP_MKNOD", "--cap-drop", "CAP_NET_RAW", "--name", ctrName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) data := inspect.InspectContainerToJSON() Expect(len(data)).To(Equal(1)) @@ -516,6 +516,6 @@ var _ = Describe("Podman inspect", func() { session = podmanTest.Podman([]string{"inspect", "--format", "{{.PidFile}}", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) }) diff --git a/test/e2e/kill_test.go b/test/e2e/kill_test.go index a9f21fa70..266146bd2 100644 --- a/test/e2e/kill_test.go +++ b/test/e2e/kill_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman kill", func() { @@ -41,25 +42,25 @@ var _ = Describe("Podman kill", func() { It("podman container kill a running container by id", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"container", "kill", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) It("podman container kill a running container by short id", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"container", "kill", cid[:5]}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal(cid[:5])) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -67,55 +68,55 @@ var _ = Describe("Podman kill", func() { It("podman kill a running container by id", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"kill", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) It("podman kill a running container by id with TERM", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"kill", "-s", "9", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) It("podman kill a running container by name", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"kill", "-s", "9", "test1"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) It("podman kill a running container by id with a bogus signal", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"kill", "-s", "foobar", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) }) It("podman kill latest container", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := "-l" if IsRemote() { @@ -123,7 +124,7 @@ var _ = Describe("Podman kill", func() { } result := podmanTest.Podman([]string{"kill", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -135,16 +136,16 @@ var _ = Describe("Podman kill", func() { session := podmanTest.Podman([]string{"run", "-dt", "--cidfile", tmpFile, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToStringArray()[0] kill := podmanTest.Podman([]string{"kill", "--cidfile", tmpFile}) kill.WaitWithDefaultTimeout() - Expect(kill.ExitCode()).To(BeZero()) + Expect(kill).Should(Exit(0)) wait := podmanTest.Podman([]string{"wait", "--condition", "exited", cid}) wait.WaitWithDefaultTimeout() - Expect(wait.ExitCode()).To(BeZero()) + Expect(wait).Should(Exit(0)) }) It("podman kill multiple --cidfile", func() { @@ -160,40 +161,40 @@ var _ = Describe("Podman kill", func() { session := podmanTest.Podman([]string{"run", "-dt", "--cidfile", tmpFile1, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid1 := session.OutputToStringArray()[0] session2 := podmanTest.Podman([]string{"run", "-dt", "--cidfile", tmpFile2, ALPINE, "top"}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) cid2 := session2.OutputToStringArray()[0] kill := podmanTest.Podman([]string{"kill", "--cidfile", tmpFile1, "--cidfile", tmpFile2}) kill.WaitWithDefaultTimeout() - Expect(kill.ExitCode()).To(BeZero()) + Expect(kill).Should(Exit(0)) wait := podmanTest.Podman([]string{"wait", "--condition", "exited", cid1}) wait.WaitWithDefaultTimeout() - Expect(wait.ExitCode()).To(BeZero()) + Expect(wait).Should(Exit(0)) wait = podmanTest.Podman([]string{"wait", "--condition", "exited", cid2}) wait.WaitWithDefaultTimeout() - Expect(wait.ExitCode()).To(BeZero()) + Expect(wait).Should(Exit(0)) }) It("podman stop --all", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) session = podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) session = podmanTest.Podman([]string{"kill", "--all"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) }) diff --git a/test/e2e/load_test.go b/test/e2e/load_test.go index 3bd75a8f2..a3ee1814a 100644 --- a/test/e2e/load_test.go +++ b/test/e2e/load_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman load", func() { @@ -43,15 +44,15 @@ var _ = Describe("Podman load", func() { save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) rmi := podmanTest.Podman([]string{"rmi", ALPINE}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(Equal(0)) + Expect(rmi).Should(Exit(0)) result := podmanTest.Podman([]string{"load", "-i", outfile}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman load compressed tar file", func() { @@ -59,19 +60,19 @@ var _ = Describe("Podman load", func() { save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) compress := SystemExec("gzip", []string{outfile}) - Expect(compress.ExitCode()).To(Equal(0)) + Expect(compress).Should(Exit(0)) outfile = outfile + ".gz" rmi := podmanTest.Podman([]string{"rmi", ALPINE}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(Equal(0)) + Expect(rmi).Should(Exit(0)) result := podmanTest.Podman([]string{"load", "-i", outfile}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman load oci-archive image", func() { @@ -79,15 +80,15 @@ var _ = Describe("Podman load", func() { save := podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-archive", ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) rmi := podmanTest.Podman([]string{"rmi", ALPINE}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(Equal(0)) + Expect(rmi).Should(Exit(0)) result := podmanTest.Podman([]string{"load", "-i", outfile}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman load oci-archive with signature", func() { @@ -95,15 +96,15 @@ var _ = Describe("Podman load", func() { save := podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-archive", ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) rmi := podmanTest.Podman([]string{"rmi", ALPINE}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(Equal(0)) + Expect(rmi).Should(Exit(0)) result := podmanTest.Podman([]string{"load", "--signature-policy", "/etc/containers/policy.json", "-i", outfile}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman load with quiet flag", func() { @@ -111,15 +112,15 @@ var _ = Describe("Podman load", func() { save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) rmi := podmanTest.Podman([]string{"rmi", ALPINE}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(Equal(0)) + Expect(rmi).Should(Exit(0)) result := podmanTest.Podman([]string{"load", "-q", "-i", outfile}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman load directory", func() { @@ -128,15 +129,15 @@ var _ = Describe("Podman load", func() { save := podmanTest.Podman([]string{"save", "--format", "oci-dir", "-o", outdir, ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) rmi := podmanTest.Podman([]string{"rmi", ALPINE}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(Equal(0)) + Expect(rmi).Should(Exit(0)) result := podmanTest.Podman([]string{"load", "-i", outdir}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman-remote load directory", func() { @@ -148,7 +149,7 @@ var _ = Describe("Podman load", func() { result := podmanTest.Podman([]string{"load", "-i", podmanTest.TempDir}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) errMsg := fmt.Sprintf("remote client supports archives only but %q is a directory", podmanTest.TempDir) found, _ := result.ErrorGrepString(errMsg) @@ -170,45 +171,45 @@ var _ = Describe("Podman load", func() { pull := podmanTest.Podman([]string{"pull", alpVersion}) pull.WaitWithDefaultTimeout() - Expect(pull.ExitCode()).To(Equal(0)) + Expect(pull).Should(Exit(0)) save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINE, alpVersion}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) rmi := podmanTest.Podman([]string{"rmi", ALPINE, alpVersion}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(Equal(0)) + Expect(rmi).Should(Exit(0)) result := podmanTest.Podman([]string{"load", "-i", outfile}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ALPINE}) inspect.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) inspect = podmanTest.Podman([]string{"inspect", alpVersion}) inspect.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman load localhost registry from scratch", func() { outfile := filepath.Join(podmanTest.TempDir, "load_test.tar.gz") setup := podmanTest.Podman([]string{"tag", ALPINE, "hello:world"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) setup = podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-archive", "hello:world"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) setup = podmanTest.Podman([]string{"rmi", "hello:world"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) load := podmanTest.Podman([]string{"load", "-i", outfile}) load.WaitWithDefaultTimeout() - Expect(load.ExitCode()).To(Equal(0)) + Expect(load).Should(Exit(0)) result := podmanTest.Podman([]string{"images", "hello:world"}) result.WaitWithDefaultTimeout() @@ -221,19 +222,19 @@ var _ = Describe("Podman load", func() { setup := podmanTest.Podman([]string{"tag", ALPINE, "hello"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) setup = podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-archive", "hello"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) setup = podmanTest.Podman([]string{"rmi", "hello"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) load := podmanTest.Podman([]string{"load", "-i", outfile}) load.WaitWithDefaultTimeout() - Expect(load.ExitCode()).To(Equal(0)) + Expect(load).Should(Exit(0)) result := podmanTest.Podman([]string{"images", "hello:latest"}) result.WaitWithDefaultTimeout() @@ -247,19 +248,19 @@ var _ = Describe("Podman load", func() { setup := podmanTest.Podman([]string{"tag", ALPINE, "hello:world"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) setup = podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-dir", "hello:world"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) setup = podmanTest.Podman([]string{"rmi", "hello:world"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) load := podmanTest.Podman([]string{"load", "-i", outfile}) load.WaitWithDefaultTimeout() - Expect(load.ExitCode()).To(Equal(0)) + Expect(load).Should(Exit(0)) result := podmanTest.Podman([]string{"images", "load:latest"}) result.WaitWithDefaultTimeout() @@ -272,23 +273,23 @@ var _ = Describe("Podman load", func() { save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) session := SystemExec("xz", []string{outfile}) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) rmi := podmanTest.Podman([]string{"rmi", ALPINE}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(Equal(0)) + Expect(rmi).Should(Exit(0)) result := podmanTest.Podman([]string{"load", "-i", outfile + ".xz"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman load multi-image archive", func() { result := podmanTest.Podman([]string{"load", "-i", "./testdata/docker-two-images.tar.xz"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.LineInOutputContains("example.com/empty:latest")).To(BeTrue()) Expect(result.LineInOutputContains("example.com/empty/but:different")).To(BeTrue()) }) diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go index 6269bb92b..6088d991f 100644 --- a/test/e2e/login_logout_test.go +++ b/test/e2e/login_logout_test.go @@ -13,6 +13,7 @@ import ( . "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/config" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman login and logout", func() { @@ -54,7 +55,7 @@ var _ = Describe("Podman login and logout", func() { session := podmanTest.Podman([]string{"run", "--entrypoint", "htpasswd", "registry:2.6", "-Bbn", "podmantest", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) f, _ := os.Create(filepath.Join(authPath, "htpasswd")) defer f.Close() @@ -83,7 +84,7 @@ var _ = Describe("Podman login and logout", func() { "-v", strings.Join([]string{certPath, "/certs"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt", "-e", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key", "registry:2.6"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) { Skip("Cannot start docker registry.") @@ -99,15 +100,15 @@ var _ = Describe("Podman login and logout", func() { It("podman login and logout", func() { session := podmanTest.Podman([]string{"login", "-u", "podmantest", "-p", "test", server}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"push", ALPINE, testImg}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"logout", server}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"push", ALPINE, testImg}) session.WaitWithDefaultTimeout() @@ -137,18 +138,18 @@ var _ = Describe("Podman login and logout", func() { session := podmanTest.Podman([]string{"login", "-u", "podmantest", "-p", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"logout"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman login and logout with flag --authfile", func() { authFile := filepath.Join(podmanTest.TempDir, "auth.json") session := podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", "--authfile", authFile, server}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) authInfo, _ := ioutil.ReadFile(authFile) var info map[string]interface{} @@ -158,20 +159,20 @@ var _ = Describe("Podman login and logout", func() { // push should fail with nonexistent authfile session = podmanTest.Podman([]string{"push", "--authfile", "/tmp/nonexistent", ALPINE, testImg}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"push", "--authfile", authFile, ALPINE, testImg}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--authfile", authFile, testImg}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // logout should fail with nonexistent authfile session = podmanTest.Podman([]string{"logout", "--authfile", "/tmp/nonexistent", server}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"logout", "--authfile", authFile, server}) }) @@ -179,15 +180,15 @@ var _ = Describe("Podman login and logout", func() { It("podman login and logout with --tls-verify", func() { session := podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", "--tls-verify=false", server}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"push", ALPINE, testImg}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"logout", server}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman login and logout with --cert-dir", func() { certDir := filepath.Join(podmanTest.TempDir, "certs") @@ -198,15 +199,15 @@ var _ = Describe("Podman login and logout", func() { session := podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", "--cert-dir", certDir, server}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"push", "--cert-dir", certDir, ALPINE, testImg}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"logout", server}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman login and logout with multi registry", func() { certDir := filepath.Join(os.Getenv("HOME"), ".config/containers/certs.d", "localhost:9001") @@ -225,7 +226,7 @@ var _ = Describe("Podman login and logout", func() { "-v", strings.Join([]string{certPath, "/certs"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt", "-e", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key", "registry:2.6"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry1", "listening on", 20, 1) { Skip("Cannot start docker registry.") @@ -233,11 +234,11 @@ var _ = Describe("Podman login and logout", func() { session = podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", server}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"push", ALPINE, testImg}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"push", ALPINE, "localhost:9001/test-alpine"}) session.WaitWithDefaultTimeout() @@ -245,19 +246,19 @@ var _ = Describe("Podman login and logout", func() { session = podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", "localhost:9001"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"push", ALPINE, testImg}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"push", ALPINE, "localhost:9001/test-alpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"logout", server}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"push", ALPINE, testImg}) session.WaitWithDefaultTimeout() @@ -265,15 +266,15 @@ var _ = Describe("Podman login and logout", func() { session = podmanTest.Podman([]string{"push", ALPINE, "localhost:9001/test-alpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"login", "--username", "podmantest", "--password", "test", "localhost:9001"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"logout", "-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"push", ALPINE, testImg}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go index b576fa072..0a973b802 100644 --- a/test/e2e/logs_test.go +++ b/test/e2e/logs_test.go @@ -5,6 +5,7 @@ import ( "os" "os/exec" "strings" + "time" . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" @@ -135,6 +136,34 @@ var _ = Describe("Podman logs", func() { Expect(len(results.OutputToStringArray())).To(Equal(3)) }) + It("until duration 10m: "+log, func() { + logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) + logc.WaitWithDefaultTimeout() + Expect(logc).To(Exit(0)) + cid := logc.OutputToString() + + results := podmanTest.Podman([]string{"logs", "--until", "10m", cid}) + results.WaitWithDefaultTimeout() + Expect(results).To(Exit(0)) + Expect(len(results.OutputToStringArray())).To(Equal(0)) + }) + + It("until time NOW: "+log, func() { + + logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) + logc.WaitWithDefaultTimeout() + Expect(logc).To(Exit(0)) + cid := logc.OutputToString() + + now := time.Now() + now = now.Add(time.Minute * 1) + nowS := now.Format(time.RFC3339) + results := podmanTest.Podman([]string{"logs", "--until", nowS, cid}) + results.WaitWithDefaultTimeout() + Expect(results).To(Exit(0)) + Expect(len(results.OutputToStringArray())).To(Equal(3)) + }) + It("latest and container name should fail: "+log, func() { results := podmanTest.Podman([]string{"logs", "-l", "foobar"}) results.WaitWithDefaultTimeout() @@ -145,12 +174,12 @@ var _ = Describe("Podman logs", func() { SkipIfRemote("FIXME: podman-remote logs does not support showing two containers at the same time") log1 := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) log1.WaitWithDefaultTimeout() - Expect(log1.ExitCode()).To(Equal(0)) + Expect(log1).Should(Exit(0)) cid1 := log1.OutputToString() log2 := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) log2.WaitWithDefaultTimeout() - Expect(log2.ExitCode()).To(Equal(0)) + Expect(log2).Should(Exit(0)) cid2 := log2.OutputToString() results := podmanTest.Podman([]string{"logs", cid1, cid2}) diff --git a/test/e2e/manifest_test.go b/test/e2e/manifest_test.go index b2dc4f734..95f90d4c1 100644 --- a/test/e2e/manifest_test.go +++ b/test/e2e/manifest_test.go @@ -47,13 +47,19 @@ var _ = Describe("Podman manifest", func() { It("podman manifest create", func() { session := podmanTest.Podman([]string{"manifest", "create", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) + }) + + It("podman manifest create", func() { + session := podmanTest.Podman([]string{"manifest", "create", "foo", imageList}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) }) It("podman manifest inspect", func() { session := podmanTest.Podman([]string{"manifest", "inspect", BB}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "inspect", "quay.io/libpod/busybox"}) session.WaitWithDefaultTimeout() @@ -68,35 +74,35 @@ var _ = Describe("Podman manifest", func() { It("podman manifest add", func() { session := podmanTest.Podman([]string{"manifest", "create", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "add", "--arch=arm64", "foo", imageListInstance}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman manifest add one", func() { session := podmanTest.Podman([]string{"manifest", "create", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "add", "--arch=arm64", "foo", imageListInstance}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(imageListARM64InstanceDigest)) }) It("podman manifest add --all", func() { session := podmanTest.Podman([]string{"manifest", "create", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "add", "--all", "foo", imageList}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(imageListAMD64InstanceDigest)) Expect(session.OutputToString()).To(ContainSubstring(imageListARMInstanceDigest)) Expect(session.OutputToString()).To(ContainSubstring(imageListARM64InstanceDigest)) @@ -107,13 +113,13 @@ var _ = Describe("Podman manifest", func() { It("podman manifest add --os", func() { session := podmanTest.Podman([]string{"manifest", "create", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "add", "--os", "bar", "foo", imageList}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(`"os": "bar"`)) }) @@ -121,36 +127,36 @@ var _ = Describe("Podman manifest", func() { SkipIfRemote("Not supporting annotate on remote connections") session := podmanTest.Podman([]string{"manifest", "create", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "add", "foo", imageListInstance}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "annotate", "--arch", "bar", "foo", imageListARM64InstanceDigest}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(`"architecture": "bar"`)) }) It("podman manifest remove", func() { session := podmanTest.Podman([]string{"manifest", "create", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "add", "--all", "foo", imageList}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(imageListARM64InstanceDigest)) session = podmanTest.Podman([]string{"manifest", "remove", "foo", imageListARM64InstanceDigest}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(imageListAMD64InstanceDigest)) Expect(session.OutputToString()).To(ContainSubstring(imageListARMInstanceDigest)) Expect(session.OutputToString()).To(ContainSubstring(imageListPPC64LEInstanceDigest)) @@ -161,27 +167,27 @@ var _ = Describe("Podman manifest", func() { It("podman manifest remove not-found", func() { session := podmanTest.Podman([]string{"manifest", "create", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "add", "foo", imageList}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "remove", "foo", "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"manifest", "rm", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman manifest push", func() { SkipIfRemote("manifest push to dir not supported in remote mode") session := podmanTest.Podman([]string{"manifest", "create", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "add", "--all", "foo", imageList}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) dest := filepath.Join(podmanTest.TempDir, "pushed") err := os.MkdirAll(dest, os.ModePerm) Expect(err).To(BeNil()) @@ -190,12 +196,12 @@ var _ = Describe("Podman manifest", func() { }() session = podmanTest.Podman([]string{"manifest", "push", "--all", "foo", "dir:" + dest}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) files, err := filepath.Glob(dest + string(os.PathSeparator) + "*") Expect(err).To(BeNil()) check := SystemExec("sha256sum", files) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) prefix := "sha256:" Expect(check.OutputToString()).To(ContainSubstring(strings.TrimPrefix(imageListAMD64InstanceDigest, prefix))) Expect(check.OutputToString()).To(ContainSubstring(strings.TrimPrefix(imageListARMInstanceDigest, prefix))) @@ -208,10 +214,10 @@ var _ = Describe("Podman manifest", func() { SkipIfRemote("manifest push to dir not supported in remote mode") session := podmanTest.Podman([]string{"manifest", "create", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "add", "--all", "foo", imageList}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) dest := filepath.Join(podmanTest.TempDir, "pushed") err := os.MkdirAll(dest, os.ModePerm) Expect(err).To(BeNil()) @@ -220,12 +226,12 @@ var _ = Describe("Podman manifest", func() { }() session = podmanTest.Podman([]string{"push", "foo", "dir:" + dest}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) files, err := filepath.Glob(dest + string(os.PathSeparator) + "*") Expect(err).To(BeNil()) check := SystemExec("sha256sum", files) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) prefix := "sha256:" Expect(check.OutputToString()).To(ContainSubstring(strings.TrimPrefix(imageListAMD64InstanceDigest, prefix))) Expect(check.OutputToString()).To(ContainSubstring(strings.TrimPrefix(imageListARMInstanceDigest, prefix))) @@ -238,10 +244,10 @@ var _ = Describe("Podman manifest", func() { SkipIfRemote("remote does not support --rm") session := podmanTest.Podman([]string{"manifest", "create", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "add", "foo", imageList}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) dest := filepath.Join(podmanTest.TempDir, "pushed") err := os.MkdirAll(dest, os.ModePerm) Expect(err).To(BeNil()) @@ -250,28 +256,28 @@ var _ = Describe("Podman manifest", func() { }() session = podmanTest.Podman([]string{"manifest", "push", "--purge", "foo", "dir:" + dest}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"manifest", "rm", "foo1", "foo2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("podman manifest exists", func() { manifestList := "manifest-list" session := podmanTest.Podman([]string{"manifest", "create", manifestList}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "exists", manifestList}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"manifest", "exists", "no-manifest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) }) }) diff --git a/test/e2e/mount_rootless_test.go b/test/e2e/mount_rootless_test.go index 502bdef4e..b66826b31 100644 --- a/test/e2e/mount_rootless_test.go +++ b/test/e2e/mount_rootless_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman mount", func() { @@ -37,31 +38,31 @@ var _ = Describe("Podman mount", func() { It("podman mount", func() { setup := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid := setup.OutputToString() mount := podmanTest.Podman([]string{"mount", cid}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).ToNot(Equal(0)) + Expect(mount).To(ExitWithError()) Expect(mount.ErrorToString()).To(ContainSubstring("podman unshare")) }) It("podman unshare podman mount", func() { setup := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid := setup.OutputToString() session := podmanTest.Podman([]string{"unshare", PODMAN_BINARY, "mount", cid}) session.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) }) It("podman image mount", func() { podmanTest.AddImageToRWStore(ALPINE) mount := podmanTest.Podman([]string{"image", "mount", ALPINE}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).ToNot(Equal(0)) + Expect(mount).To(ExitWithError()) Expect(mount.ErrorToString()).To(ContainSubstring("podman unshare")) }) @@ -69,10 +70,10 @@ var _ = Describe("Podman mount", func() { podmanTest.AddImageToRWStore(ALPINE) setup := podmanTest.Podman([]string{"pull", ALPINE}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"unshare", PODMAN_BINARY, "image", "mount", ALPINE}) session.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) }) }) diff --git a/test/e2e/mount_test.go b/test/e2e/mount_test.go index ee77f2984..141d1a386 100644 --- a/test/e2e/mount_test.go +++ b/test/e2e/mount_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman mount", func() { @@ -37,175 +38,175 @@ var _ = Describe("Podman mount", func() { It("podman mount", func() { setup := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid := setup.OutputToString() mount := podmanTest.Podman([]string{"mount", cid}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) umount := podmanTest.Podman([]string{"umount", cid}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) }) It("podman container mount", func() { setup := podmanTest.Podman([]string{"container", "create", ALPINE, "ls"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid := setup.OutputToString() mount := podmanTest.Podman([]string{"container", "mount", cid}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) umount := podmanTest.Podman([]string{"container", "umount", cid}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) }) It("podman mount with json format", func() { setup := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid := setup.OutputToString() mount := podmanTest.Podman([]string{"mount", cid}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) j := podmanTest.Podman([]string{"mount", "--format=json"}) j.WaitWithDefaultTimeout() - Expect(j.ExitCode()).To(Equal(0)) + Expect(j).Should(Exit(0)) Expect(j.IsJSONOutputValid()).To(BeTrue()) j = podmanTest.Podman([]string{"mount", "--format='{{.foobar}}'"}) j.WaitWithDefaultTimeout() - Expect(j.ExitCode()).ToNot(Equal(0)) + Expect(j).To(ExitWithError()) Expect(j.ErrorToString()).To(ContainSubstring("unknown --format")) umount := podmanTest.Podman([]string{"umount", cid}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) }) It("podman mount many", func() { setup1 := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup1.WaitWithDefaultTimeout() - Expect(setup1.ExitCode()).To(Equal(0)) + Expect(setup1).Should(Exit(0)) cid1 := setup1.OutputToString() setup2 := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup2.WaitWithDefaultTimeout() - Expect(setup2.ExitCode()).To(Equal(0)) + Expect(setup2).Should(Exit(0)) cid2 := setup2.OutputToString() setup3 := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup3.WaitWithDefaultTimeout() - Expect(setup3.ExitCode()).To(Equal(0)) + Expect(setup3).Should(Exit(0)) cid3 := setup3.OutputToString() mount1 := podmanTest.Podman([]string{"mount", cid1, cid2, cid3}) mount1.WaitWithDefaultTimeout() - Expect(mount1.ExitCode()).To(Equal(0)) + Expect(mount1).Should(Exit(0)) umount := podmanTest.Podman([]string{"umount", cid1, cid2, cid3}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) }) It("podman umount many", func() { setup1 := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup1.WaitWithDefaultTimeout() - Expect(setup1.ExitCode()).To(Equal(0)) + Expect(setup1).Should(Exit(0)) cid1 := setup1.OutputToString() setup2 := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup2.WaitWithDefaultTimeout() - Expect(setup2.ExitCode()).To(Equal(0)) + Expect(setup2).Should(Exit(0)) cid2 := setup2.OutputToString() mount1 := podmanTest.Podman([]string{"mount", cid1}) mount1.WaitWithDefaultTimeout() - Expect(mount1.ExitCode()).To(Equal(0)) + Expect(mount1).Should(Exit(0)) mount2 := podmanTest.Podman([]string{"mount", cid2}) mount2.WaitWithDefaultTimeout() - Expect(mount2.ExitCode()).To(Equal(0)) + Expect(mount2).Should(Exit(0)) umount := podmanTest.Podman([]string{"umount", cid1, cid2}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) }) It("podman umount all", func() { setup1 := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup1.WaitWithDefaultTimeout() - Expect(setup1.ExitCode()).To(Equal(0)) + Expect(setup1).Should(Exit(0)) cid1 := setup1.OutputToString() setup2 := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup2.WaitWithDefaultTimeout() - Expect(setup2.ExitCode()).To(Equal(0)) + Expect(setup2).Should(Exit(0)) cid2 := setup2.OutputToString() mount1 := podmanTest.Podman([]string{"mount", cid1}) mount1.WaitWithDefaultTimeout() - Expect(mount1.ExitCode()).To(Equal(0)) + Expect(mount1).Should(Exit(0)) mount2 := podmanTest.Podman([]string{"mount", cid2}) mount2.WaitWithDefaultTimeout() - Expect(mount2.ExitCode()).To(Equal(0)) + Expect(mount2).Should(Exit(0)) umount := podmanTest.Podman([]string{"umount", "--all"}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) }) It("podman list mounted container", func() { setup := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid := setup.OutputToString() lmount := podmanTest.Podman([]string{"mount", "--notruncate"}) lmount.WaitWithDefaultTimeout() - Expect(lmount.ExitCode()).To(Equal(0)) + Expect(lmount).Should(Exit(0)) Expect(lmount.OutputToString()).To(Equal("")) mount := podmanTest.Podman([]string{"mount", cid}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) lmount = podmanTest.Podman([]string{"mount", "--notruncate"}) lmount.WaitWithDefaultTimeout() - Expect(lmount.ExitCode()).To(Equal(0)) + Expect(lmount).Should(Exit(0)) Expect(lmount.OutputToString()).To(ContainSubstring(cid)) umount := podmanTest.Podman([]string{"umount", cid}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) }) It("podman list running container", func() { setup := podmanTest.Podman([]string{"run", "-dt", ALPINE, "top"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid := setup.OutputToString() lmount := podmanTest.Podman([]string{"mount", "--notruncate"}) lmount.WaitWithDefaultTimeout() - Expect(lmount.ExitCode()).To(Equal(0)) + Expect(lmount).Should(Exit(0)) Expect(lmount.OutputToString()).To(ContainSubstring(cid)) stop := podmanTest.Podman([]string{"stop", cid}) stop.WaitWithDefaultTimeout() - Expect(stop.ExitCode()).To(Equal(0)) + Expect(stop).Should(Exit(0)) lmount = podmanTest.Podman([]string{"mount", "--notruncate"}) lmount.WaitWithDefaultTimeout() - Expect(lmount.ExitCode()).To(Equal(0)) + Expect(lmount).Should(Exit(0)) Expect(lmount.OutputToString()).To(Equal("")) }) @@ -213,42 +214,42 @@ var _ = Describe("Podman mount", func() { setup := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid1 := setup.OutputToString() setup = podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid2 := setup.OutputToString() setup = podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid3 := setup.OutputToString() lmount := podmanTest.Podman([]string{"mount", "--notruncate"}) lmount.WaitWithDefaultTimeout() - Expect(lmount.ExitCode()).To(Equal(0)) + Expect(lmount).Should(Exit(0)) Expect(lmount.OutputToString()).To(Equal("")) mount := podmanTest.Podman([]string{"mount", cid1, cid3}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) lmount = podmanTest.Podman([]string{"mount", "--notruncate"}) lmount.WaitWithDefaultTimeout() - Expect(lmount.ExitCode()).To(Equal(0)) + Expect(lmount).Should(Exit(0)) Expect(lmount.OutputToString()).To(ContainSubstring(cid1)) Expect(lmount.OutputToString()).ToNot(ContainSubstring(cid2)) Expect(lmount.OutputToString()).To(ContainSubstring(cid3)) umount := podmanTest.Podman([]string{"umount", cid1, cid3}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) lmount = podmanTest.Podman([]string{"mount", "--notruncate"}) lmount.WaitWithDefaultTimeout() - Expect(lmount.ExitCode()).To(Equal(0)) + Expect(lmount).Should(Exit(0)) Expect(lmount.OutputToString()).To(Equal("")) }) @@ -257,95 +258,95 @@ var _ = Describe("Podman mount", func() { setup := podmanTest.Podman([]string{"create", ALPINE, "ls"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) cid := setup.OutputToString() lmount := podmanTest.Podman([]string{"mount", "--notruncate"}) lmount.WaitWithDefaultTimeout() - Expect(lmount.ExitCode()).To(Equal(0)) + Expect(lmount).Should(Exit(0)) Expect(lmount.OutputToString()).To(Equal("")) mount := podmanTest.Podman([]string{"mount", cid}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) lmount = podmanTest.Podman([]string{"mount", "--notruncate"}) lmount.WaitWithDefaultTimeout() - Expect(lmount.ExitCode()).To(Equal(0)) + Expect(lmount).Should(Exit(0)) Expect(lmount.OutputToString()).To(ContainSubstring(cid)) umount := podmanTest.Podman([]string{"umount", cid}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) }) It("podman image mount", func() { images := podmanTest.Podman([]string{"images"}) images.WaitWithDefaultTimeout() - Expect(images.ExitCode()).To(Equal(0)) + Expect(images).Should(Exit(0)) mount := podmanTest.Podman([]string{"image", "mount", ALPINE}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) umount := podmanTest.Podman([]string{"image", "umount", ALPINE}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) mount = podmanTest.Podman([]string{"image", "mount"}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) Expect(mount.OutputToString()).To(Equal("")) // Mount multiple times mount = podmanTest.Podman([]string{"image", "mount", ALPINE}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) mount = podmanTest.Podman([]string{"image", "mount", ALPINE}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) // Unmount once mount = podmanTest.Podman([]string{"image", "mount", ALPINE}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) mount = podmanTest.Podman([]string{"image", "mount"}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) Expect(mount.OutputToString()).To(ContainSubstring(ALPINE)) mount = podmanTest.Podman([]string{"image", "umount", "--all"}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) }) It("podman mount with json format", func() { podmanTest.AddImageToRWStore(fedoraMinimal) mount := podmanTest.Podman([]string{"image", "mount", fedoraMinimal}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) j := podmanTest.Podman([]string{"image", "mount", "--format=json"}) j.WaitWithDefaultTimeout() - Expect(j.ExitCode()).To(Equal(0)) + Expect(j).Should(Exit(0)) Expect(j.IsJSONOutputValid()).To(BeTrue()) umount := podmanTest.Podman([]string{"image", "umount", fedoraMinimal}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) }) It("podman umount --all", func() { podmanTest.AddImageToRWStore(fedoraMinimal) mount := podmanTest.Podman([]string{"image", "mount", fedoraMinimal}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) umount := podmanTest.Podman([]string{"image", "umount", "--all"}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) Expect(len(umount.OutputToStringArray())).To(Equal(1)) }) @@ -356,66 +357,66 @@ var _ = Describe("Podman mount", func() { mount1 := podmanTest.Podman([]string{"image", "mount", fedoraMinimal, ALPINE, "busybox"}) mount1.WaitWithDefaultTimeout() - Expect(mount1.ExitCode()).To(Equal(0)) + Expect(mount1).Should(Exit(0)) umount := podmanTest.Podman([]string{"image", "umount", fedoraMinimal, ALPINE}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) mount := podmanTest.Podman([]string{"image", "mount"}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) Expect(mount.OutputToString()).To(ContainSubstring("busybox")) mount1 = podmanTest.Podman([]string{"image", "unmount", "busybox"}) mount1.WaitWithDefaultTimeout() - Expect(mount1.ExitCode()).To(Equal(0)) + Expect(mount1).Should(Exit(0)) mount = podmanTest.Podman([]string{"image", "mount"}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) Expect(mount.OutputToString()).To(Equal("")) mount1 = podmanTest.Podman([]string{"image", "mount", fedoraMinimal, ALPINE, "busybox"}) mount1.WaitWithDefaultTimeout() - Expect(mount1.ExitCode()).To(Equal(0)) + Expect(mount1).Should(Exit(0)) mount = podmanTest.Podman([]string{"image", "mount"}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) Expect(mount.OutputToString()).To(ContainSubstring(fedoraMinimal)) Expect(mount.OutputToString()).To(ContainSubstring(ALPINE)) umount = podmanTest.Podman([]string{"image", "umount", "--all"}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) mount = podmanTest.Podman([]string{"image", "mount"}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) Expect(mount.OutputToString()).To(Equal("")) umount = podmanTest.Podman([]string{"image", "umount", fedoraMinimal, ALPINE}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) mount1 = podmanTest.Podman([]string{"image", "mount", "--all"}) mount1.WaitWithDefaultTimeout() - Expect(mount1.ExitCode()).To(Equal(0)) + Expect(mount1).Should(Exit(0)) mount = podmanTest.Podman([]string{"image", "mount"}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) Expect(mount.OutputToString()).To(ContainSubstring(fedoraMinimal)) Expect(mount.OutputToString()).To(ContainSubstring(ALPINE)) umount = podmanTest.Podman([]string{"image", "umount", "--all"}) umount.WaitWithDefaultTimeout() - Expect(umount.ExitCode()).To(Equal(0)) + Expect(umount).Should(Exit(0)) mount = podmanTest.Podman([]string{"image", "mount"}) mount.WaitWithDefaultTimeout() - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) Expect(mount.OutputToString()).To(Equal("")) }) }) diff --git a/test/e2e/namespace_test.go b/test/e2e/namespace_test.go index 0c451d6cd..43edee1a5 100644 --- a/test/e2e/namespace_test.go +++ b/test/e2e/namespace_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman namespaces", func() { @@ -37,15 +38,15 @@ var _ = Describe("Podman namespaces", func() { podman1.WaitWithDefaultTimeout() if IsRemote() { // --namespace flag not supported in podman remote - Expect(podman1.ExitCode()).To(Equal(125)) + Expect(podman1).Should(Exit(125)) Expect(podman1.ErrorToString()).To(ContainSubstring("unknown flag: --namespace")) return } - Expect(podman1.ExitCode()).To(Equal(0)) + Expect(podman1).Should(Exit(0)) podman2 := podmanTest.Podman([]string{"--namespace", "test2", "ps", "-aq"}) podman2.WaitWithDefaultTimeout() - Expect(podman2.ExitCode()).To(Equal(0)) + Expect(podman2).Should(Exit(0)) output := podman2.OutputToStringArray() numCtrs := 0 for _, outputLine := range output { diff --git a/test/e2e/network_connect_disconnect_test.go b/test/e2e/network_connect_disconnect_test.go index c82aacbe4..b1f3607ab 100644 --- a/test/e2e/network_connect_disconnect_test.go +++ b/test/e2e/network_connect_disconnect_test.go @@ -7,6 +7,7 @@ import ( "github.com/containers/storage/pkg/stringid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman network connect and disconnect", func() { @@ -35,19 +36,19 @@ var _ = Describe("Podman network connect and disconnect", func() { It("bad network name in disconnect should result in error", func() { dis := podmanTest.Podman([]string{"network", "disconnect", "foobar", "test"}) dis.WaitWithDefaultTimeout() - Expect(dis.ExitCode()).ToNot(BeZero()) + Expect(dis).Should(ExitWithError()) }) It("bad container name in network disconnect should result in error", func() { netName := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) dis := podmanTest.Podman([]string{"network", "disconnect", netName, "foobar"}) dis.WaitWithDefaultTimeout() - Expect(dis.ExitCode()).ToNot(BeZero()) + Expect(dis).Should(ExitWithError()) }) It("network disconnect with net mode slirp4netns should result in error", func() { @@ -55,17 +56,17 @@ var _ = Describe("Podman network connect and disconnect", func() { netName := "slirp" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) session = podmanTest.Podman([]string{"create", "--name", "test", "--network", "slirp4netns", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) con := podmanTest.Podman([]string{"network", "disconnect", netName, "test"}) con.WaitWithDefaultTimeout() - Expect(con.ExitCode()).ToNot(BeZero()) + Expect(con).Should(ExitWithError()) Expect(con.ErrorToString()).To(ContainSubstring(`"slirp4netns" is not supported: invalid network mode`)) }) @@ -73,47 +74,47 @@ var _ = Describe("Podman network connect and disconnect", func() { netName := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netName, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(BeZero()) + Expect(ctr).Should(Exit(0)) exec := podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(BeZero()) + Expect(exec).Should(Exit(0)) dis := podmanTest.Podman([]string{"network", "disconnect", netName, "test"}) dis.WaitWithDefaultTimeout() - Expect(dis.ExitCode()).To(BeZero()) + Expect(dis).Should(Exit(0)) inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal("0")) exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).ToNot(BeZero()) + Expect(exec).Should(ExitWithError()) }) It("bad network name in connect should result in error", func() { dis := podmanTest.Podman([]string{"network", "connect", "foobar", "test"}) dis.WaitWithDefaultTimeout() - Expect(dis.ExitCode()).ToNot(BeZero()) + Expect(dis).Should(ExitWithError()) }) It("bad container name in network connect should result in error", func() { netName := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) dis := podmanTest.Podman([]string{"network", "connect", netName, "foobar"}) dis.WaitWithDefaultTimeout() - Expect(dis.ExitCode()).ToNot(BeZero()) + Expect(dis).Should(ExitWithError()) }) It("network connect with net mode slirp4netns should result in error", func() { @@ -121,17 +122,17 @@ var _ = Describe("Podman network connect and disconnect", func() { netName := "slirp" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) session = podmanTest.Podman([]string{"create", "--name", "test", "--network", "slirp4netns", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) con := podmanTest.Podman([]string{"network", "connect", netName, "test"}) con.WaitWithDefaultTimeout() - Expect(con.ExitCode()).ToNot(BeZero()) + Expect(con).Should(ExitWithError()) Expect(con.ErrorToString()).To(ContainSubstring(`"slirp4netns" is not supported: invalid network mode`)) }) @@ -139,16 +140,16 @@ var _ = Describe("Podman network connect and disconnect", func() { netName := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) ctr := podmanTest.Podman([]string{"create", "--name", "test", "--network", netName, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(BeZero()) + Expect(ctr).Should(Exit(0)) con := podmanTest.Podman([]string{"network", "connect", netName, "test"}) con.WaitWithDefaultTimeout() - Expect(con.ExitCode()).ToNot(BeZero()) + Expect(con).Should(ExitWithError()) }) It("podman network connect", func() { @@ -156,41 +157,41 @@ var _ = Describe("Podman network connect and disconnect", func() { netName := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netName, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(BeZero()) + Expect(ctr).Should(Exit(0)) exec := podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(BeZero()) + Expect(exec).Should(Exit(0)) // Create a second network newNetName := "aliasTest" + stringid.GenerateNonCryptoID() session = podmanTest.Podman([]string{"network", "create", newNetName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(newNetName) connect := podmanTest.Podman([]string{"network", "connect", newNetName, "test"}) connect.WaitWithDefaultTimeout() - Expect(connect.ExitCode()).To(BeZero()) + Expect(connect).Should(Exit(0)) inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal("2")) exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth1"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(BeZero()) + Expect(exec).Should(Exit(0)) // make sure no logrus errors are shown https://github.com/containers/podman/issues/9602 rm := podmanTest.Podman([]string{"rm", "-f", "test"}) rm.WaitWithDefaultTimeout() - Expect(rm.ExitCode()).To(BeZero()) + Expect(rm).Should(Exit(0)) Expect(rm.ErrorToString()).To(Equal("")) }) @@ -199,39 +200,39 @@ var _ = Describe("Podman network connect and disconnect", func() { netName1 := "connect1" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName1) netName2 := "connect2" + stringid.GenerateNonCryptoID() session = podmanTest.Podman([]string{"network", "create", netName2}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName2) ctr := podmanTest.Podman([]string{"create", "--name", "test", "--network", netName1, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(BeZero()) + Expect(ctr).Should(Exit(0)) dis := podmanTest.Podman([]string{"network", "connect", netName2, "test"}) dis.WaitWithDefaultTimeout() - Expect(dis.ExitCode()).To(BeZero()) + Expect(dis).Should(Exit(0)) inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal("2")) start := podmanTest.Podman([]string{"start", "test"}) start.WaitWithDefaultTimeout() - Expect(start.ExitCode()).To(BeZero()) + Expect(start).Should(Exit(0)) exec := podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(BeZero()) + Expect(exec).Should(Exit(0)) exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth1"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(BeZero()) + Expect(exec).Should(Exit(0)) }) It("podman network connect and run with network ID", func() { @@ -240,86 +241,86 @@ var _ = Describe("Podman network connect and disconnect", func() { netName := "ID" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) netID := session.OutputToString() ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netID, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(BeZero()) + Expect(ctr).Should(Exit(0)) exec := podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(BeZero()) + Expect(exec).Should(Exit(0)) // Create a second network newNetName := "ID2" + stringid.GenerateNonCryptoID() session = podmanTest.Podman([]string{"network", "create", newNetName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(newNetName) session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + newNetName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) newNetID := session.OutputToString() connect := podmanTest.Podman([]string{"network", "connect", newNetID, "test"}) connect.WaitWithDefaultTimeout() - Expect(connect.ExitCode()).To(BeZero()) + Expect(connect).Should(Exit(0)) inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{.NetworkSettings.Networks}}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(netName)) Expect(inspect.OutputToString()).To(ContainSubstring(newNetName)) exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth1"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(BeZero()) + Expect(exec).Should(Exit(0)) }) It("podman network disconnect when not running", func() { netName1 := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName1) netName2 := "aliasTest" + stringid.GenerateNonCryptoID() session2 := podmanTest.Podman([]string{"network", "create", netName2}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(BeZero()) + Expect(session2).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName2) ctr := podmanTest.Podman([]string{"create", "--name", "test", "--network", netName1 + "," + netName2, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(BeZero()) + Expect(ctr).Should(Exit(0)) dis := podmanTest.Podman([]string{"network", "disconnect", netName1, "test"}) dis.WaitWithDefaultTimeout() - Expect(dis.ExitCode()).To(BeZero()) + Expect(dis).Should(Exit(0)) inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal("1")) start := podmanTest.Podman([]string{"start", "test"}) start.WaitWithDefaultTimeout() - Expect(start.ExitCode()).To(BeZero()) + Expect(start).Should(Exit(0)) exec := podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(BeZero()) + Expect(exec).Should(Exit(0)) exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth1"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).ToNot(BeZero()) + Expect(exec).Should(ExitWithError()) }) It("podman network disconnect and run with network ID", func() { @@ -328,33 +329,33 @@ var _ = Describe("Podman network connect and disconnect", func() { netName := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) netID := session.OutputToString() ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netID, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(BeZero()) + Expect(ctr).Should(Exit(0)) exec := podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(BeZero()) + Expect(exec).Should(Exit(0)) dis := podmanTest.Podman([]string{"network", "disconnect", netID, "test"}) dis.WaitWithDefaultTimeout() - Expect(dis.ExitCode()).To(BeZero()) + Expect(dis).Should(Exit(0)) inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal("0")) exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).ToNot(BeZero()) + Expect(exec).Should(ExitWithError()) }) }) diff --git a/test/e2e/network_create_test.go b/test/e2e/network_create_test.go index ef3be8e22..fb4a144fa 100644 --- a/test/e2e/network_create_test.go +++ b/test/e2e/network_create_test.go @@ -13,6 +13,7 @@ import ( "github.com/containers/storage/pkg/stringid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" "github.com/pkg/errors" ) @@ -89,7 +90,7 @@ var _ = Describe("Podman network create", func() { nc := podmanTest.Podman([]string{"network", "create"}) nc.WaitWithDefaultTimeout() - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) fileContent, err := ioutil.ReadFile(nc.OutputToString()) Expect(err).To(BeNil()) @@ -121,7 +122,7 @@ var _ = Describe("Podman network create", func() { nc := podmanTest.Podman([]string{"network", "create", netName}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName) - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) inspect := podmanTest.Podman([]string{"network", "inspect", netName}) inspect.WaitWithDefaultTimeout() @@ -141,7 +142,7 @@ var _ = Describe("Podman network create", func() { nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", netName}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName) - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) // Inspect the network configuration inspect := podmanTest.Podman([]string{"network", "inspect", netName}) @@ -184,7 +185,7 @@ var _ = Describe("Podman network create", func() { nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:1:2:3:4::/64", netName}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName) - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) // Inspect the network configuration inspect := podmanTest.Podman([]string{"network", "inspect", netName}) @@ -225,7 +226,7 @@ var _ = Describe("Podman network create", func() { nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:3:2:1::/64", "--ipv6", netName}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName) - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) // Inspect the network configuration inspect := podmanTest.Podman([]string{"network", "inspect", netName}) @@ -243,10 +244,59 @@ var _ = Describe("Podman network create", func() { Expect(bridgePlugin.IPAM.Routes[0].Dest).To(Equal("::/0")) Expect(bridgePlugin.IPAM.Routes[1].Dest).To(Equal("0.0.0.0/0")) + Expect(bridgePlugin.IPAM.Ranges).To(HaveLen(2)) + Expect(bridgePlugin.IPAM.Ranges[0]).To(HaveLen(1)) + Expect(bridgePlugin.IPAM.Ranges[0][0].Subnet).ToNot(BeEmpty()) + Expect(bridgePlugin.IPAM.Ranges[1]).To(HaveLen(1)) + Expect(bridgePlugin.IPAM.Ranges[1][0].Subnet).ToNot(BeEmpty()) + + _, subnet11, err := net.ParseCIDR(bridgePlugin.IPAM.Ranges[0][0].Subnet) + Expect(err).To(BeNil()) + _, subnet12, err := net.ParseCIDR(bridgePlugin.IPAM.Ranges[1][0].Subnet) + Expect(err).To(BeNil()) + // Once a container executes a new network, the nic will be created. We should clean those up // best we can defer removeNetworkDevice(bridgePlugin.BrName) + // create a second network to check the auto assigned ipv4 subnet does not overlap + // https://github.com/containers/podman/issues/11032 + netName2 := "dual-" + stringid.GenerateNonCryptoID() + nc = podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:6:3:2:1::/64", "--ipv6", netName2}) + nc.WaitWithDefaultTimeout() + defer podmanTest.removeCNINetwork(netName2) + Expect(nc).Should(Exit(0)) + + // Inspect the network configuration + inspect = podmanTest.Podman([]string{"network", "inspect", netName2}) + inspect.WaitWithDefaultTimeout() + + // JSON the network configuration into something usable + err = json.Unmarshal([]byte(inspect.OutputToString()), &results) + Expect(err).To(BeNil()) + result = results[0] + Expect(result["name"]).To(Equal(netName2)) + + // JSON the bridge info + bridgePlugin, err = genericPluginsToBridge(result["plugins"], "bridge") + Expect(err).To(BeNil()) + Expect(bridgePlugin.IPAM.Routes[0].Dest).To(Equal("::/0")) + Expect(bridgePlugin.IPAM.Routes[1].Dest).To(Equal("0.0.0.0/0")) + Expect(bridgePlugin.IPAM.Ranges).To(HaveLen(2)) + Expect(bridgePlugin.IPAM.Ranges[0]).To(HaveLen(1)) + Expect(bridgePlugin.IPAM.Ranges[0][0].Subnet).ToNot(BeEmpty()) + Expect(bridgePlugin.IPAM.Ranges[1]).To(HaveLen(1)) + Expect(bridgePlugin.IPAM.Ranges[1][0].Subnet).ToNot(BeEmpty()) + + _, subnet21, err := net.ParseCIDR(bridgePlugin.IPAM.Ranges[0][0].Subnet) + Expect(err).To(BeNil()) + _, subnet22, err := net.ParseCIDR(bridgePlugin.IPAM.Ranges[1][0].Subnet) + Expect(err).To(BeNil()) + + // check that the subnets do not overlap + Expect(subnet11.Contains(subnet21.IP)).To(BeFalse()) + Expect(subnet12.Contains(subnet22.IP)).To(BeFalse()) + try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", netName, ALPINE, "sh", "-c", "ip addr show eth0 | grep global | awk ' /inet6 / {print $2}'"}) try.WaitWithDefaultTimeout() @@ -299,7 +349,7 @@ var _ = Describe("Podman network create", func() { nc := podmanTest.Podman([]string{"network", "create", netName}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName) - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) ncFail := podmanTest.Podman([]string{"network", "create", netName}) ncFail.WaitWithDefaultTimeout() @@ -311,7 +361,7 @@ var _ = Describe("Podman network create", func() { nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.13.0/24", netName1}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName1) - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) netName2 := "sub2-" + stringid.GenerateNonCryptoID() ncFail := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.13.0/24", netName2}) @@ -326,7 +376,7 @@ var _ = Describe("Podman network create", func() { nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:4:4:4::/64", "--ipv6", netName1}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName1) - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) netName2 := "subipv62-" + stringid.GenerateNonCryptoID() ncFail := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:4:4:4::/64", "--ipv6", netName2}) @@ -346,11 +396,11 @@ var _ = Describe("Podman network create", func() { nc := podmanTest.Podman([]string{"network", "create", "--opt", "mtu=9000", net}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) nc = podmanTest.Podman([]string{"network", "inspect", net}) nc.WaitWithDefaultTimeout() - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) Expect(nc.OutputToString()).To(ContainSubstring(`"mtu": 9000,`)) }) @@ -359,11 +409,11 @@ var _ = Describe("Podman network create", func() { nc := podmanTest.Podman([]string{"network", "create", "--opt", "vlan=9", net}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) nc = podmanTest.Podman([]string{"network", "inspect", net}) nc.WaitWithDefaultTimeout() - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) Expect(nc.OutputToString()).To(ContainSubstring(`"vlan": 9`)) }) @@ -380,7 +430,7 @@ var _ = Describe("Podman network create", func() { nc := podmanTest.Podman([]string{"network", "create", "--internal", net}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) // Not performing this check on remote tests because it is a logrus error which does // not come back via stderr on the remote client. if !IsRemote() { @@ -388,7 +438,7 @@ var _ = Describe("Podman network create", func() { } nc = podmanTest.Podman([]string{"network", "inspect", net}) nc.WaitWithDefaultTimeout() - Expect(nc.ExitCode()).To(BeZero()) + Expect(nc).Should(Exit(0)) Expect(nc.OutputToString()).ToNot(ContainSubstring("dnsname")) }) diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go index a7e61932e..1959ed555 100644 --- a/test/e2e/network_test.go +++ b/test/e2e/network_test.go @@ -11,6 +11,7 @@ import ( "github.com/containers/storage/pkg/stringid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman network", func() { @@ -42,7 +43,7 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains(name)).To(BeTrue()) }) @@ -52,7 +53,7 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "ls", "--quiet"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains(name)).To(BeTrue()) }) @@ -62,7 +63,7 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "ls", "--filter", "plugin=bridge"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains(name)).To(BeTrue()) }) @@ -72,7 +73,7 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "ls", "--filter", "plugin=bridge", "--filter", "name=" + name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(name)) }) @@ -85,7 +86,7 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "ls", "--filter", "name=" + name1, "--filter", "name=" + name2}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(name1)) Expect(session.OutputToString()).To(ContainSubstring(name2)) }) @@ -97,23 +98,23 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "create", "--label", label1, net1}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net1) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) net2 := "labelnet" + stringid.GenerateNonCryptoID() session = podmanTest.Podman([]string{"network", "create", "--label", label1, "--label", label2, net2}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net2) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"network", "ls", "--filter", "label=" + label1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(net1)) Expect(session.OutputToString()).To(ContainSubstring(net2)) session = podmanTest.Podman([]string{"network", "ls", "--filter", "label=" + label1, "--filter", "label=" + label2}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).ToNot(ContainSubstring(net1)) Expect(session.OutputToString()).To(ContainSubstring(net2)) }) @@ -123,7 +124,7 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "create", net}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"network", "ls", "--filter", "namr=ab"}) session.WaitWithDefaultTimeout() @@ -137,7 +138,7 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "ls", "--filter", "plugin=test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains(name)).To(BeFalse()) }) @@ -148,45 +149,45 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "create", net}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) // Tests Default Table Output session = podmanTest.Podman([]string{"network", "ls", "--filter", "id=" + netID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) expectedTable := "NETWORK ID NAME VERSION PLUGINS" Expect(session.OutputToString()).To(ContainSubstring(expectedTable)) session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}} {{.ID}}", "--filter", "id=" + netID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(net + " " + netID[:12])) session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}} {{.ID}}", "--filter", "id=" + netID[10:50], "--no-trunc"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(net + " " + netID)) session = podmanTest.Podman([]string{"network", "inspect", netID[:40]}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(net)) session = podmanTest.Podman([]string{"network", "inspect", netID[1:]}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).ToNot(BeZero()) + Expect(session).Should(ExitWithError()) Expect(session.ErrorToString()).To(ContainSubstring("no such network")) session = podmanTest.Podman([]string{"network", "rm", netID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) }) rm_func := func(rm string) { It(fmt.Sprintf("podman network %s no args", rm), func() { session := podmanTest.Podman([]string{"network", rm}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).ToNot(BeZero()) + Expect(session).Should(ExitWithError()) }) @@ -196,16 +197,16 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "ls", "--quiet"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains(name)).To(BeTrue()) rm := podmanTest.Podman([]string{"network", rm, name}) rm.WaitWithDefaultTimeout() - Expect(rm.ExitCode()).To(BeZero()) + Expect(rm).Should(Exit(0)) results := podmanTest.Podman([]string{"network", "ls", "--quiet"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) Expect(results.LineInOutputContains(name)).To(BeFalse()) }) } @@ -216,7 +217,7 @@ var _ = Describe("Podman network", func() { It("podman network inspect no args", func() { session := podmanTest.Podman([]string{"network", "inspect"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).ToNot(BeZero()) + Expect(session).Should(ExitWithError()) }) It("podman network inspect", func() { @@ -230,7 +231,7 @@ var _ = Describe("Podman network", func() { } session := podmanTest.Podman(append([]string{"network", "inspect"}, expectedNetworks...)) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) }) @@ -240,7 +241,7 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "inspect", name, "--format", "{{.cniVersion}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("0.3.0")).To(BeTrue()) }) @@ -249,16 +250,16 @@ var _ = Describe("Podman network", func() { network := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.50.0/24", netName}) network.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName) - Expect(network.ExitCode()).To(BeZero()) + Expect(network).Should(Exit(0)) ctrName := "testCtr" container := podmanTest.Podman([]string{"run", "-dt", "--network", netName, "--name", ctrName, ALPINE, "top"}) container.WaitWithDefaultTimeout() - Expect(container.ExitCode()).To(BeZero()) + Expect(container).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) conData := inspect.InspectContainerToJSON() Expect(len(conData)).To(Equal(1)) Expect(len(conData[0].NetworkSettings.Networks)).To(Equal(1)) @@ -271,7 +272,7 @@ var _ = Describe("Podman network", func() { // Necessary to ensure the CNI network is removed cleanly rmAll := podmanTest.Podman([]string{"rm", "-f", ctrName}) rmAll.WaitWithDefaultTimeout() - Expect(rmAll.ExitCode()).To(BeZero()) + Expect(rmAll).Should(Exit(0)) }) It("podman inspect container two CNI networks (container not running)", func() { @@ -279,22 +280,22 @@ var _ = Describe("Podman network", func() { network1 := podmanTest.Podman([]string{"network", "create", netName1}) network1.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName1) - Expect(network1.ExitCode()).To(BeZero()) + Expect(network1).Should(Exit(0)) netName2 := "net2-" + stringid.GenerateNonCryptoID() network2 := podmanTest.Podman([]string{"network", "create", netName2}) network2.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName2) - Expect(network2.ExitCode()).To(BeZero()) + Expect(network2).Should(Exit(0)) ctrName := "testCtr" container := podmanTest.Podman([]string{"create", "--network", fmt.Sprintf("%s,%s", netName1, netName2), "--name", ctrName, ALPINE, "top"}) container.WaitWithDefaultTimeout() - Expect(container.ExitCode()).To(BeZero()) + Expect(container).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) conData := inspect.InspectContainerToJSON() Expect(len(conData)).To(Equal(1)) Expect(len(conData[0].NetworkSettings.Networks)).To(Equal(2)) @@ -308,7 +309,7 @@ var _ = Describe("Podman network", func() { // Necessary to ensure the CNI network is removed cleanly rmAll := podmanTest.Podman([]string{"rm", "-f", ctrName}) rmAll.WaitWithDefaultTimeout() - Expect(rmAll.ExitCode()).To(BeZero()) + Expect(rmAll).Should(Exit(0)) }) It("podman inspect container two CNI networks", func() { @@ -316,22 +317,22 @@ var _ = Describe("Podman network", func() { network1 := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.51.0/25", netName1}) network1.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName1) - Expect(network1.ExitCode()).To(BeZero()) + Expect(network1).Should(Exit(0)) netName2 := "net2-" + stringid.GenerateNonCryptoID() network2 := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.51.128/26", netName2}) network2.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName2) - Expect(network2.ExitCode()).To(BeZero()) + Expect(network2).Should(Exit(0)) ctrName := "testCtr" container := podmanTest.Podman([]string{"run", "-dt", "--network", fmt.Sprintf("%s,%s", netName1, netName2), "--name", ctrName, ALPINE, "top"}) container.WaitWithDefaultTimeout() - Expect(container.ExitCode()).To(BeZero()) + Expect(container).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) conData := inspect.InspectContainerToJSON() Expect(len(conData)).To(Equal(1)) Expect(len(conData[0].NetworkSettings.Networks)).To(Equal(2)) @@ -349,7 +350,7 @@ var _ = Describe("Podman network", func() { // Necessary to ensure the CNI network is removed cleanly rmAll := podmanTest.Podman([]string{"rm", "-f", ctrName}) rmAll.WaitWithDefaultTimeout() - Expect(rmAll.ExitCode()).To(BeZero()) + Expect(rmAll).Should(Exit(0)) }) It("podman network remove after disconnect when container initially created with the network", func() { @@ -360,25 +361,25 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "create", network}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--name", container, "--network", network, "-d", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"network", "disconnect", network, container}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"network", "rm", network}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman network remove bogus", func() { session := podmanTest.Podman([]string{"network", "rm", "bogus"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) }) It("podman network remove --force with pod", func() { @@ -386,34 +387,34 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "create", "--network", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"create", "--pod", podID, ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"network", "rm", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(2)) + Expect(session).Should(Exit(2)) session = podmanTest.Podman([]string{"network", "rm", "--force", netName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) // check if pod is deleted session = podmanTest.Podman([]string{"pod", "exists", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) // check if net is deleted session = podmanTest.Podman([]string{"network", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(ContainSubstring(netName))) }) @@ -422,17 +423,17 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "create", netName1}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName1) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) netName2 := "net2-" + stringid.GenerateNonCryptoID() session = podmanTest.Podman([]string{"network", "create", netName2}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName2) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"network", "rm", netName1, netName2}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) lines := session.OutputToStringArray() Expect(lines[0]).To(Equal(netName1)) Expect(lines[1]).To(Equal(netName2)) @@ -444,7 +445,7 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(netName) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) interval := time.Duration(250 * time.Millisecond) for i := 0; i < 6; i++ { @@ -460,7 +461,7 @@ var _ = Describe("Podman network", func() { top := podmanTest.Podman([]string{"run", "-dt", "--name=web", "--network=" + netName, "--network-alias=web1", "--network-alias=web2", nginx}) top.WaitWithDefaultTimeout() - Expect(top.ExitCode()).To(BeZero()) + Expect(top).Should(Exit(0)) interval = time.Duration(250 * time.Millisecond) // Wait for the nginx service to be running for i := 0; i < 6; i++ { @@ -480,12 +481,12 @@ var _ = Describe("Podman network", func() { // Test against the first alias c2 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web1"}) c2.WaitWithDefaultTimeout() - Expect(c2.ExitCode()).To(BeZero()) + Expect(c2).Should(Exit(0)) // Test against the second alias c3 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web2"}) c3.WaitWithDefaultTimeout() - Expect(c3.ExitCode()).To(BeZero()) + Expect(c3).Should(Exit(0)) }) It("podman network create/remove macvlan", func() { @@ -493,11 +494,11 @@ var _ = Describe("Podman network", func() { nc := podmanTest.Podman([]string{"network", "create", "--macvlan", "lo", net}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(nc.ExitCode()).To(Equal(0)) + Expect(nc).Should(Exit(0)) nc = podmanTest.Podman([]string{"network", "rm", net}) nc.WaitWithDefaultTimeout() - Expect(nc.ExitCode()).To(Equal(0)) + Expect(nc).Should(Exit(0)) }) It("podman network create/remove macvlan as driver (-d) no device name", func() { @@ -505,11 +506,11 @@ var _ = Describe("Podman network", func() { nc := podmanTest.Podman([]string{"network", "create", "-d", "macvlan", net}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(nc.ExitCode()).To(Equal(0)) + Expect(nc).Should(Exit(0)) inspect := podmanTest.Podman([]string{"network", "inspect", net}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) out, err := inspect.jq(".[0].plugins[0].master") Expect(err).To(BeNil()) @@ -517,7 +518,7 @@ var _ = Describe("Podman network", func() { nc = podmanTest.Podman([]string{"network", "rm", net}) nc.WaitWithDefaultTimeout() - Expect(nc.ExitCode()).To(Equal(0)) + Expect(nc).Should(Exit(0)) }) It("podman network create/remove macvlan as driver (-d) with device name", func() { @@ -525,11 +526,11 @@ var _ = Describe("Podman network", func() { nc := podmanTest.Podman([]string{"network", "create", "-d", "macvlan", "-o", "parent=lo", net}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(nc.ExitCode()).To(Equal(0)) + Expect(nc).Should(Exit(0)) inspect := podmanTest.Podman([]string{"network", "inspect", net}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) out, err := inspect.jq(".[0].plugins[0].master") Expect(err).To(BeNil()) @@ -541,7 +542,7 @@ var _ = Describe("Podman network", func() { nc = podmanTest.Podman([]string{"network", "rm", net}) nc.WaitWithDefaultTimeout() - Expect(nc.ExitCode()).To(Equal(0)) + Expect(nc).Should(Exit(0)) }) It("podman network exists", func() { @@ -549,15 +550,15 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"network", "create", net}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"network", "exists", net}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"network", "exists", stringid.GenerateNonCryptoID()}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) }) It("podman network create macvlan with network info and options", func() { @@ -565,11 +566,11 @@ var _ = Describe("Podman network", func() { nc := podmanTest.Podman([]string{"network", "create", "-d", "macvlan", "-o", "parent=lo", "-o", "mtu=1500", "--gateway", "192.168.1.254", "--subnet", "192.168.1.0/24", net}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(nc.ExitCode()).To(Equal(0)) + Expect(nc).Should(Exit(0)) inspect := podmanTest.Podman([]string{"network", "inspect", net}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(BeZero()) + Expect(inspect).Should(Exit(0)) mtu, err := inspect.jq(".[0].plugins[0].mtu") Expect(err).To(BeNil()) @@ -601,7 +602,7 @@ var _ = Describe("Podman network", func() { nc = podmanTest.Podman([]string{"network", "rm", net}) nc.WaitWithDefaultTimeout() - Expect(nc.ExitCode()).To(Equal(0)) + Expect(nc).Should(Exit(0)) }) It("podman network prune --filter", func() { @@ -610,11 +611,11 @@ var _ = Describe("Podman network", func() { nc := podmanTest.Podman([]string{"network", "create", net1}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net1) - Expect(nc.ExitCode()).To(Equal(0)) + Expect(nc).Should(Exit(0)) list := podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"}) list.WaitWithDefaultTimeout() - Expect(list.ExitCode()).To(BeZero()) + Expect(list).Should(Exit(0)) Expect(StringInSlice(net1, list.OutputToStringArray())).To(BeTrue()) if !isRootless() { @@ -624,11 +625,11 @@ var _ = Describe("Podman network", func() { // -f needed only to skip y/n question prune := podmanTest.Podman([]string{"network", "prune", "-f", "--filter", "until=50"}) prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(BeZero()) + Expect(prune).Should(Exit(0)) listAgain := podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"}) listAgain.WaitWithDefaultTimeout() - Expect(listAgain.ExitCode()).To(BeZero()) + Expect(listAgain).Should(Exit(0)) Expect(StringInSlice(net1, listAgain.OutputToStringArray())).To(BeTrue()) if !isRootless() { @@ -638,11 +639,11 @@ var _ = Describe("Podman network", func() { // -f needed only to skip y/n question prune = podmanTest.Podman([]string{"network", "prune", "-f", "--filter", "until=5000000000000"}) prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(BeZero()) + Expect(prune).Should(Exit(0)) listAgain = podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"}) listAgain.WaitWithDefaultTimeout() - Expect(listAgain.ExitCode()).To(BeZero()) + Expect(listAgain).Should(Exit(0)) Expect(StringInSlice(net1, listAgain.OutputToStringArray())).To(BeFalse()) if !isRootless() { @@ -662,16 +663,16 @@ var _ = Describe("Podman network", func() { nc := podmanTest.Podman([]string{"network", "create", net1}) nc.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net1) - Expect(nc.ExitCode()).To(Equal(0)) + Expect(nc).Should(Exit(0)) nc2 := podmanTest.Podman([]string{"network", "create", net2}) nc2.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net2) - Expect(nc2.ExitCode()).To(Equal(0)) + Expect(nc2).Should(Exit(0)) list := podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"}) list.WaitWithDefaultTimeout() - Expect(list.ExitCode()).To(BeZero()) + Expect(list).Should(Exit(0)) Expect(StringInSlice(net1, list.OutputToStringArray())).To(BeTrue()) Expect(StringInSlice(net2, list.OutputToStringArray())).To(BeTrue()) @@ -681,15 +682,15 @@ var _ = Describe("Podman network", func() { session := podmanTest.Podman([]string{"run", "-dt", "--net", net2, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) prune := podmanTest.Podman([]string{"network", "prune", "-f"}) prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(BeZero()) + Expect(prune).Should(Exit(0)) listAgain := podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"}) listAgain.WaitWithDefaultTimeout() - Expect(listAgain.ExitCode()).To(BeZero()) + Expect(listAgain).Should(Exit(0)) Expect(StringInSlice(net1, listAgain.OutputToStringArray())).To(BeFalse()) Expect(StringInSlice(net2, listAgain.OutputToStringArray())).To(BeTrue()) diff --git a/test/e2e/pause_test.go b/test/e2e/pause_test.go index 01ad7c071..ea7a96428 100644 --- a/test/e2e/pause_test.go +++ b/test/e2e/pause_test.go @@ -10,6 +10,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman pause", func() { @@ -69,7 +70,7 @@ var _ = Describe("Podman pause", func() { It("podman pause a created container by id", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"pause", cid}) @@ -83,12 +84,12 @@ var _ = Describe("Podman pause", func() { It("podman pause a running container by id", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"pause", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(strings.ToLower(podmanTest.GetContainerStatus())).To(ContainSubstring(pausedState)) @@ -99,13 +100,13 @@ var _ = Describe("Podman pause", func() { It("podman container pause a running container by id", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"container", "pause", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(strings.ToLower(podmanTest.GetContainerStatus())).To(ContainSubstring(pausedState)) @@ -116,13 +117,13 @@ var _ = Describe("Podman pause", func() { It("podman unpause a running container by id", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"unpause", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) }) @@ -130,20 +131,20 @@ var _ = Describe("Podman pause", func() { It("podman remove a paused container by id without force", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"pause", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(strings.ToLower(podmanTest.GetContainerStatus())).To(ContainSubstring(pausedState)) result = podmanTest.Podman([]string{"rm", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(2)) + Expect(result).Should(Exit(2)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(strings.ToLower(podmanTest.GetContainerStatus())).To(ContainSubstring(pausedState)) @@ -152,56 +153,56 @@ var _ = Describe("Podman pause", func() { It("podman remove a paused container by id with force", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"pause", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(strings.ToLower(podmanTest.GetContainerStatus())).To(ContainSubstring(pausedState)) result = podmanTest.Podman([]string{"rm", "--force", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) It("podman stop a paused container by id", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"pause", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(strings.ToLower(podmanTest.GetContainerStatus())).To(ContainSubstring(pausedState)) result = podmanTest.Podman([]string{"stop", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(strings.ToLower(podmanTest.GetContainerStatus())).To(ContainSubstring(pausedState)) result = podmanTest.Podman([]string{"unpause", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) result = podmanTest.Podman([]string{"rm", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(2)) + Expect(result).Should(Exit(2)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) result = podmanTest.Podman([]string{"rm", "-f", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -209,12 +210,12 @@ var _ = Describe("Podman pause", func() { It("podman pause a running container by name", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pause", "test1"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(strings.ToLower(podmanTest.GetContainerStatus())).To(Equal(pausedState)) @@ -225,23 +226,23 @@ var _ = Describe("Podman pause", func() { It("podman pause a running container by id and another by name", func() { session1 := podmanTest.RunTopContainer("test1") session1.WaitWithDefaultTimeout() - Expect(session1.ExitCode()).To(Equal(0)) + Expect(session1).Should(Exit(0)) session2 := podmanTest.RunTopContainer("") session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) cid2 := session2.OutputToString() result := podmanTest.Podman([]string{"pause", cid2}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) result = podmanTest.Podman([]string{"pause", "test1"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) result = podmanTest.Podman([]string{"unpause", "test1"}) @@ -253,7 +254,7 @@ var _ = Describe("Podman pause", func() { It("Pause all containers (no containers exist)", func() { result := podmanTest.Podman([]string{"pause", "--all"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -261,7 +262,7 @@ var _ = Describe("Podman pause", func() { It("Unpause all containers (no paused containers exist)", func() { result := podmanTest.Podman([]string{"unpause", "--all"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -270,26 +271,26 @@ var _ = Describe("Podman pause", func() { name := fmt.Sprintf("test%d", i) run := podmanTest.Podman([]string{"run", "-dt", "--name", name, nginx}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) } running := podmanTest.Podman([]string{"ps", "-q"}) running.WaitWithDefaultTimeout() - Expect(running.ExitCode()).To(Equal(0)) + Expect(running).Should(Exit(0)) Expect(len(running.OutputToStringArray())).To(Equal(3)) pause := podmanTest.Podman([]string{"pause", "--all"}) pause.WaitWithDefaultTimeout() - Expect(pause.ExitCode()).To(Equal(0)) + Expect(pause).Should(Exit(0)) running = podmanTest.Podman([]string{"ps", "-q"}) running.WaitWithDefaultTimeout() - Expect(running.ExitCode()).To(Equal(0)) + Expect(running).Should(Exit(0)) Expect(len(running.OutputToStringArray())).To(Equal(0)) unpause := podmanTest.Podman([]string{"unpause", "--all"}) unpause.WaitWithDefaultTimeout() - Expect(unpause.ExitCode()).To(Equal(0)) + Expect(unpause).Should(Exit(0)) }) It("Unpause a bunch of running containers", func() { @@ -297,20 +298,20 @@ var _ = Describe("Podman pause", func() { name := fmt.Sprintf("test%d", i) run := podmanTest.Podman([]string{"run", "-dt", "--name", name, nginx}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) } pause := podmanTest.Podman([]string{"pause", "--all"}) pause.WaitWithDefaultTimeout() - Expect(pause.ExitCode()).To(Equal(0)) + Expect(pause).Should(Exit(0)) unpause := podmanTest.Podman([]string{"unpause", "--all"}) unpause.WaitWithDefaultTimeout() - Expect(unpause.ExitCode()).To(Equal(0)) + Expect(unpause).Should(Exit(0)) running := podmanTest.Podman([]string{"ps", "-q"}) running.WaitWithDefaultTimeout() - Expect(running.ExitCode()).To(Equal(0)) + Expect(running).Should(Exit(0)) Expect(len(running.OutputToStringArray())).To(Equal(3)) }) diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 833991452..66bfdefe7 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -9,12 +9,14 @@ import ( "strconv" "strings" "text/template" + "time" "github.com/containers/podman/v3/pkg/util" . "github.com/containers/podman/v3/test/utils" "github.com/containers/storage/pkg/stringid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" "github.com/opencontainers/selinux/go-selinux" ) @@ -66,6 +68,75 @@ spec: shareProcessNamespace: true status: {} ` +var livenessProbePodYaml = ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: liveness-probe + labels: + app: alpine +spec: + replicas: 1 + selector: + matchLabels: + app: alpine + template: + metadata: + labels: + app: alpine + spec: + containers: + - command: + - top + - -d + - "1.5" + name: alpine + image: quay.io/libpod/alpine:latest + ports: + - containerPort: 80 + livenessProbe: + exec: + command: + - echo + - hello + initialDelaySeconds: 5 + periodSeconds: 5 +` +var livenessProbeUnhealthyPodYaml = ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: liveness-unhealthy-probe + labels: + app: alpine +spec: + replicas: 1 + selector: + matchLabels: + app: alpine + template: + metadata: + labels: + app: alpine + spec: + restartPolicy: Never + containers: + - command: + - top + - -d + - "1.5" + name: alpine + image: quay.io/libpod/alpine:latest + ports: + - containerPort: 80 + livenessProbe: + exec: + command: + - cat + - /randomfile + initialDelaySeconds: 0 + periodSeconds: 1 +` var selinuxLabelPodYaml = ` apiVersion: v1 @@ -515,7 +586,7 @@ func createSecret(podmanTest *PodmanTestIntegration, name string, value []byte) secret := podmanTest.Podman([]string{"secret", "create", name, secretFilePath}) secret.WaitWithDefaultTimeout() - Expect(secret.ExitCode()).To(Equal(0)) + Expect(secret).Should(Exit(0)) } // ConfigMap describes the options a kube yaml can be configured at configmap level @@ -1020,7 +1091,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Not(Equal(0))) + Expect(kube).To(ExitWithError()) }) @@ -1033,7 +1104,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "label-pod-test", "--format", "'{{ .ProcessLabel }}'"}) inspect.WaitWithDefaultTimeout() @@ -1049,7 +1120,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "testpod1", "--format", "'{{ .SharedNamespaces }}'"}) inspect.WaitWithDefaultTimeout() @@ -1060,13 +1131,43 @@ var _ = Describe("Podman play kube", func() { Expect(sharednamespaces).To(ContainSubstring("pid")) }) + It("podman play kube support container liveness probe", func() { + err := writeYaml(livenessProbePodYaml, kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube).Should(Exit(0)) + + inspect := podmanTest.Podman([]string{"inspect", "liveness-probe-pod-0-alpine", "--format", "'{{ .Config.Healthcheck }}'"}) + inspect.WaitWithDefaultTimeout() + healthcheckcmd := inspect.OutputToString() + // check if CMD-SHELL based equivalent health check is added to container + Expect(healthcheckcmd).To(ContainSubstring("CMD-SHELL")) + }) + + It("podman play kube liveness probe should fail", func() { + err := writeYaml(livenessProbeUnhealthyPodYaml, kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube).Should(Exit(0)) + + time.Sleep(2 * time.Second) + hc := podmanTest.Podman([]string{"healthcheck", "run", "liveness-unhealthy-probe-pod-0-alpine"}) + hc.WaitWithDefaultTimeout() + hcoutput := hc.OutputToString() + Expect(hcoutput).To(ContainSubstring("unhealthy")) + }) + It("podman play kube fail with nonexistent authfile", func() { err := generateKubeYaml("pod", getPod(), kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", "--authfile", "/tmp/nonexistent", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Not(Equal(0))) + Expect(kube).To(ExitWithError()) }) @@ -1077,16 +1178,16 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Cmd }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) cmd := inspect.OutputToString() inspect = podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Entrypoint }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) ep := inspect.OutputToString() // Use the defined command to override the image's command @@ -1102,18 +1203,18 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) // this image's ENTRYPOINT is `/entrypoint.sh` inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Entrypoint }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`/entrypoint.sh`)) // and its COMMAND is `/etc/docker/registry/config.yml` inspect = podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Cmd }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`[/etc/docker/registry/config.yml]`)) }) @@ -1126,18 +1227,18 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) // Use the defined command to override the image's command, and don't set the args // so the full command in result should not contains the image's command inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Entrypoint }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`echo hello`)) inspect = podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Cmd }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) // an empty command is reported as '[]' Expect(inspect.OutputToString()).To(ContainSubstring(`[]`)) }) @@ -1150,17 +1251,17 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) // this image's ENTRYPOINT is `/entrypoint.sh` inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Entrypoint }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`/entrypoint.sh`)) inspect = podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Cmd }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`[echo hello]`)) }) @@ -1174,16 +1275,16 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Entrypoint }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`echo`)) inspect = podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Cmd }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`[hello]`)) }) @@ -1195,11 +1296,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) logs := podmanTest.Podman([]string{"logs", getCtrNameInPod(p)}) logs.WaitWithDefaultTimeout() - Expect(logs.ExitCode()).To(Equal(0)) + Expect(logs).Should(Exit(0)) Expect(logs.OutputToString()).To(ContainSubstring("hello world")) }) @@ -1218,11 +1319,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "{{.HostConfig.RestartPolicy.Name}}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal(v[2])) } }) @@ -1240,11 +1341,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml, "--configmap", cmYamlPathname}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Env }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`FOO=foo`)) }) @@ -1261,7 +1362,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml, "--configmap", cmYamlPathname}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Not(Equal(0))) + Expect(kube).To(ExitWithError()) }) It("podman play kube test required env value from missing configmap", func() { @@ -1271,7 +1372,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Not(Equal(0))) + Expect(kube).To(ExitWithError()) }) It("podman play kube test optional env value from configmap with missing key", func() { @@ -1287,11 +1388,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml, "--configmap", cmYamlPathname}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ range .Config.Env }}[{{ . }}]{{end}}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`[FOO=]`)) }) @@ -1302,11 +1403,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ range .Config.Env }}[{{ . }}]{{end}}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`[FOO=]`)) }) @@ -1323,11 +1424,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml, "--configmap", cmYamlPathname}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Env }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`FOO1=foo1`)) Expect(inspect.OutputToString()).To(ContainSubstring(`FOO2=foo2`)) }) @@ -1339,7 +1440,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Not(Equal(0))) + Expect(kube).To(ExitWithError()) }) It("podman play kube test get all key-value pairs from optional configmap as envs", func() { @@ -1349,7 +1450,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) }) It("podman play kube test env value from secret", func() { @@ -1360,11 +1461,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Env }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`FOO=foo`)) }) @@ -1375,7 +1476,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Not(Equal(0))) + Expect(kube).To(ExitWithError()) }) It("podman play kube test required env value from secret with missing key", func() { @@ -1386,7 +1487,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Not(Equal(0))) + Expect(kube).To(ExitWithError()) }) It("podman play kube test optional env value from missing secret", func() { @@ -1396,11 +1497,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ range .Config.Env }}[{{ . }}]{{end}}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`[FOO=]`)) }) @@ -1412,11 +1513,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ range .Config.Env }}[{{ . }}]{{end}}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`[FOO=]`)) }) @@ -1428,11 +1529,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Env }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`FOO=foo`)) Expect(inspect.OutputToString()).To(ContainSubstring(`BAR=bar`)) }) @@ -1444,7 +1545,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Not(Equal(0))) + Expect(kube).To(ExitWithError()) }) It("podman play kube test get all key-value pairs from optional secret as envs", func() { @@ -1454,7 +1555,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) }) It("podman play kube test hostname", func() { @@ -1464,11 +1565,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "{{ .Config.Hostname }}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal(defaultPodName)) }) @@ -1480,11 +1581,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "{{ .Config.Hostname }}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal(hostname)) }) @@ -1503,11 +1604,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", pod.Name, "--format", "{{ .InfraConfig.HostAdd}}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()). To(Equal("[test1.podman.io:192.168.1.2 test2.podman.io:192.168.1.2 test3.podman.io:192.168.1.3 test4.podman.io:192.168.1.3]")) }) @@ -1522,11 +1623,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod)}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(capAdd)) }) @@ -1540,11 +1641,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod)}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(capDrop)) }) @@ -1556,11 +1657,11 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod)}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) }) It("podman play kube seccomp container level", func() { @@ -1582,11 +1683,11 @@ var _ = Describe("Podman play kube", func() { // CreateSeccompJson will put the profile into podmanTest.TempDir. Use --seccomp-profile-root to tell play kube where to look kube := podmanTest.Podman([]string{"play", "kube", "--seccomp-profile-root", podmanTest.TempDir, kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) logs := podmanTest.Podman([]string{"logs", getCtrNameInPod(pod)}) logs.WaitWithDefaultTimeout() - Expect(logs.ExitCode()).To(Equal(0)) + Expect(logs).Should(Exit(0)) Expect(logs.ErrorToString()).To(ContainSubstring("Operation not permitted")) }) @@ -1609,11 +1710,11 @@ var _ = Describe("Podman play kube", func() { // CreateSeccompJson will put the profile into podmanTest.TempDir. Use --seccomp-profile-root to tell play kube where to look kube := podmanTest.Podman([]string{"play", "kube", "--seccomp-profile-root", podmanTest.TempDir, kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) logs := podmanTest.Podman([]string{"logs", getCtrNameInPod(pod)}) logs.WaitWithDefaultTimeout() - Expect(logs.ExitCode()).To(Equal(0)) + Expect(logs).Should(Exit(0)) Expect(logs.ErrorToString()).To(ContainSubstring("Operation not permitted")) }) @@ -1624,17 +1725,17 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(125)) + Expect(kube).Should(Exit(125)) }) It("podman play kube with pull policy of missing", func() { - ctr := getCtr(withPullPolicy("missing"), withImage(BB)) + ctr := getCtr(withPullPolicy("Missing"), withImage(BB)) err := generateKubeYaml("pod", getPod(withCtr(ctr)), kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) }) It("podman play kube with pull always", func() { @@ -1644,11 +1745,11 @@ var _ = Describe("Podman play kube", func() { tag := podmanTest.Podman([]string{"tag", oldBB, BB}) tag.WaitWithDefaultTimeout() - Expect(tag.ExitCode()).To(BeZero()) + Expect(tag).Should(Exit(0)) rmi := podmanTest.Podman([]string{"rmi", oldBB}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(BeZero()) + Expect(rmi).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", BB}) inspect.WaitWithDefaultTimeout() @@ -1660,7 +1761,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect = podmanTest.Podman([]string{"inspect", BB}) inspect.WaitWithDefaultTimeout() @@ -1675,11 +1776,11 @@ var _ = Describe("Podman play kube", func() { tag := podmanTest.Podman([]string{"tag", oldBB, BB}) tag.WaitWithDefaultTimeout() - Expect(tag.ExitCode()).To(BeZero()) + Expect(tag).Should(Exit(0)) rmi := podmanTest.Podman([]string{"rmi", oldBB}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(BeZero()) + Expect(rmi).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", BB}) inspect.WaitWithDefaultTimeout() @@ -1691,7 +1792,7 @@ var _ = Describe("Podman play kube", func() { kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect = podmanTest.Podman([]string{"inspect", BB}) inspect.WaitWithDefaultTimeout() @@ -1713,11 +1814,11 @@ spec: pull := podmanTest.Podman([]string{"create", "--workdir", "/etc", "--name", "newBB", "--label", "key1=value1", "alpine"}) pull.WaitWithDefaultTimeout() - Expect(pull.ExitCode()).To(BeZero()) + Expect(pull).Should(Exit(0)) c := podmanTest.Podman([]string{"commit", "-c", "STOPSIGNAL=51", "newBB", "demo"}) c.WaitWithDefaultTimeout() - Expect(c.ExitCode()).To(Equal(0)) + Expect(c).Should(Exit(0)) conffile := filepath.Join(podmanTest.TempDir, "kube.yaml") tempdir, err = CreateTempDirInTempDir() @@ -1728,11 +1829,11 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", conffile}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "demo_pod-demo_kube"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) ctr := inspect.InspectContainerToJSON() Expect(ctr[0].Config.WorkingDir).To(ContainSubstring("/etc")) @@ -1749,12 +1850,12 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) podNames := getPodNamesInDeployment(deployment) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[0]), "--format", "'{{ .Config.Entrypoint }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) // yaml's command should override the image's Entrypoint Expect(inspect.OutputToString()).To(ContainSubstring(strings.Join(defaultCtrCmd, " "))) }) @@ -1768,13 +1869,13 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) podNames := getPodNamesInDeployment(deployment) for i = 0; i < numReplicas; i++ { inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[i]), "--format", "'{{ .Config.Entrypoint }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(strings.Join(defaultCtrCmd, " "))) } }) @@ -1790,7 +1891,7 @@ spec: session := podmanTest.Podman([]string{"network", "create", "--subnet", "10.25.31.0/24", net}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) ips := []string{"10.25.31.5", "10.25.31.10", "10.25.31.15"} playArgs := []string{"play", "kube", "--network", net} @@ -1804,20 +1905,20 @@ spec: kube := podmanTest.Podman(append(playArgs, kubeYaml)) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) podNames := getPodNamesInDeployment(deployment) for i = 0; i < numReplicas; i++ { inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[i]), "--format", "{{ .NetworkSettings.Networks." + net + ".IPAddress }}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal(ips[i])) } for i = 0; i < numReplicas; i++ { inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[i]), "--format", "{{ .NetworkSettings.Networks." + net + ".MacAddress }}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal(macs[i])) } }) @@ -1833,11 +1934,11 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"port", getCtrNameInPod(pod)}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal("5000/tcp -> 127.0.0.100:5000")) }) @@ -1850,7 +1951,7 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).NotTo(Equal(0)) + Expect(kube).To(ExitWithError()) Expect(kube.ErrorToString()).To(ContainSubstring(defaultVolName)) }) @@ -1866,7 +1967,7 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) }) It("podman play kube test with nonexistent File HostPath type volume", func() { @@ -1878,7 +1979,7 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).NotTo(Equal(0)) + Expect(kube).To(ExitWithError()) }) It("podman play kube test with File HostPath type volume", func() { @@ -1893,7 +1994,7 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) }) It("podman play kube test with FileOrCreate HostPath type volume", func() { @@ -1905,7 +2006,7 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) // the file should have been created _, err = os.Stat(hostPathLocation) @@ -1921,7 +2022,7 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) // the file should have been created st, err := os.Stat(hostPathLocation) @@ -1941,7 +2042,7 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).NotTo(Equal(0)) + Expect(kube).To(ExitWithError()) }) It("podman play kube test with read only HostPath volume", func() { @@ -1957,11 +2058,11 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{.HostConfig.Binds}}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) correct := fmt.Sprintf("%s:%s:%s", hostPathLocation, hostPathLocation, "ro") Expect(inspect.OutputToString()).To(ContainSubstring(correct)) @@ -1997,15 +2098,15 @@ VOLUME %s`, ALPINE, hostPathDir+"/") kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) result := podmanTest.Podman([]string{"exec", getCtrNameInPod(pod), "ls", hostPathDir + "/" + testfile}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod)}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) // If two volumes are specified and share the same destination, // only one will be mounted. Host path volumes take precedence. @@ -2025,11 +2126,11 @@ VOLUME %s`, ALPINE, hostPathDir+"/") kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "{{ (index .Mounts 0).Type }}:{{ (index .Mounts 0).Name }}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) correct := fmt.Sprintf("volume:%s", volumeName) Expect(inspect.OutputToString()).To(Equal(correct)) @@ -2048,13 +2149,13 @@ VOLUME %s`, ALPINE, hostPathDir+"/") kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) correctLabels := expectedLabelKey + ":" + expectedLabelValue for _, pod := range getPodNamesInDeployment(deployment) { inspect := podmanTest.Podman([]string{"pod", "inspect", pod.Name, "--format", "'{{ .Labels }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(correctLabels)) } }) @@ -2087,7 +2188,7 @@ VOLUME %s`, ALPINE, hostPathDir+"/") kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) for _, pod := range getPodNamesInDeployment(deployment) { inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&pod), "--format", ` @@ -2096,7 +2197,7 @@ CpuQuota: {{ .HostConfig.CpuQuota }} Memory: {{ .HostConfig.Memory }} MemoryReservation: {{ .HostConfig.MemoryReservation }}`}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(fmt.Sprintf("%s: %d", "CpuQuota", expectedCpuQuota))) Expect(inspect.OutputToString()).To(ContainSubstring("MemoryReservation: " + expectedMemoryRequest)) Expect(inspect.OutputToString()).To(ContainSubstring("Memory: " + expectedMemoryLimit)) @@ -2118,7 +2219,7 @@ MemoryReservation: {{ .HostConfig.MemoryReservation }}`}) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(125)) + Expect(kube).Should(Exit(125)) Expect(kube.ErrorToString()).To(ContainSubstring("invalid reference format")) }) @@ -2129,11 +2230,11 @@ MemoryReservation: {{ .HostConfig.MemoryReservation }}`}) kube := podmanTest.Podman([]string{"play", "kube", "--log-driver", "journald", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .HostConfig.LogConfig.Type }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring("journald")) }) @@ -2144,11 +2245,11 @@ MemoryReservation: {{ .HostConfig.MemoryReservation }}`}) kube := podmanTest.Podman([]string{"play", "kube", "--start=false", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "{{ .State.Running }}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal("false")) }) @@ -2163,11 +2264,11 @@ MemoryReservation: {{ .HostConfig.MemoryReservation }}`}) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", pod.Name, "--format", "{{ .InfraConfig.HostNetwork }}"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal("true")) }) @@ -2186,7 +2287,7 @@ MemoryReservation: {{ .HostConfig.MemoryReservation }}`}) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", volName, "--format", ` Name: {{ .Name }} @@ -2194,7 +2295,7 @@ Device: {{ .Options.device }} Type: {{ .Options.type }} o: {{ .Options.o }}`}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring("Name: " + volName)) Expect(inspect.OutputToString()).To(ContainSubstring("Device: " + volDevice)) Expect(inspect.OutputToString()).To(ContainSubstring("Type: " + volType)) @@ -2250,21 +2351,21 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) inspectVolume := podmanTest.Podman([]string{"inspect", volName, "--format", "'{{ .Name }}'"}) inspectVolume.WaitWithDefaultTimeout() - Expect(inspectVolume.ExitCode()).To(Equal(0)) + Expect(inspectVolume).Should(Exit(0)) Expect(inspectVolume.OutputToString()).To(ContainSubstring(volName)) inspectPod := podmanTest.Podman([]string{"inspect", podName + "-pod-0", "--format", "'{{ .State }}'"}) inspectPod.WaitWithDefaultTimeout() - Expect(inspectPod.ExitCode()).To(Equal(0)) + Expect(inspectPod).Should(Exit(0)) Expect(inspectPod.OutputToString()).To(ContainSubstring(`Running`)) inspectMounts := podmanTest.Podman([]string{"inspect", podName + "-pod-0-" + ctrName, "--format", "{{ (index .Mounts 0).Type }}:{{ (index .Mounts 0).Name }}"}) inspectMounts.WaitWithDefaultTimeout() - Expect(inspectMounts.ExitCode()).To(Equal(0)) + Expect(inspectMounts).Should(Exit(0)) correct := fmt.Sprintf("volume:%s", volName) Expect(inspectMounts.OutputToString()).To(Equal(correct)) @@ -2322,12 +2423,12 @@ spec: kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) for _, n := range podNames { inspect := podmanTest.Podman([]string{"inspect", n, "--format", "'{{ .State }}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`Running`)) } }) @@ -2364,7 +2465,7 @@ invalid kube kind kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Not(Equal(0))) + Expect(kube).To(ExitWithError()) }) It("podman play kube with auto update annotations for all containers", func() { @@ -2391,12 +2492,12 @@ invalid kube kind kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) for _, ctr := range []string{podName + "-" + ctr01Name, podName + "-" + ctr02Name} { inspect := podmanTest.Podman([]string{"inspect", ctr, "--format", "'{{.Config.Labels}}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(autoUpdateRegistry + ":" + autoUpdateRegistryValue)) Expect(inspect.OutputToString()).To(ContainSubstring(autoUpdateAuthfile + ":" + autoUpdateAuthfileValue)) @@ -2427,18 +2528,18 @@ invalid kube kind kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() - Expect(kube.ExitCode()).To(Equal(0)) + Expect(kube).Should(Exit(0)) podName := getPodNamesInDeployment(deployment)[0].Name inspect := podmanTest.Podman([]string{"inspect", podName + "-" + ctr01Name, "--format", "'{{.Config.Labels}}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(autoUpdateRegistry + ":" + autoUpdateRegistryValue)) inspect = podmanTest.Podman([]string{"inspect", podName + "-" + ctr02Name, "--format", "'{{.Config.Labels}}'"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring(`map[]`)) }) }) diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go index e437c98e6..4c6788b9d 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -14,6 +14,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman pod create", func() { @@ -79,7 +80,7 @@ var _ = Describe("Podman pod create", func() { name := "test" session := podmanTest.Podman([]string{"create", "--name", name, ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {name}}) Expect(ec).To(Not(Equal(0))) @@ -93,52 +94,52 @@ var _ = Describe("Podman pod create", func() { name := "test" session := podmanTest.Podman([]string{"pod", "create", "--name", name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) pod := session.OutputToString() webserver := podmanTest.Podman([]string{"run", "--pod", pod, "-dt", nginx}) webserver.WaitWithDefaultTimeout() - Expect(webserver.ExitCode()).To(Equal(0)) + Expect(webserver).Should(Exit(0)) check := SystemExec("nc", []string{"-z", "localhost", "80"}) - Expect(check.ExitCode()).To(Equal(1)) + Expect(check).Should(Exit(1)) }) It("podman create pod with network portbindings", func() { name := "test" session := podmanTest.Podman([]string{"pod", "create", "--name", name, "-p", "8080:80"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) pod := session.OutputToString() webserver := podmanTest.Podman([]string{"run", "--pod", pod, "-dt", nginx}) webserver.WaitWithDefaultTimeout() - Expect(webserver.ExitCode()).To(Equal(0)) + Expect(webserver).Should(Exit(0)) check := SystemExec("nc", []string{"-z", "localhost", "8080"}) - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) }) It("podman create pod with no infra but portbindings should fail", func() { name := "test" session := podmanTest.Podman([]string{"pod", "create", "--infra=false", "--name", name, "-p", "80:80"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman create pod with --no-hosts", func() { name := "test" podCreate := podmanTest.Podman([]string{"pod", "create", "--no-hosts", "--name", name}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) alpineResolvConf := podmanTest.Podman([]string{"run", "-ti", "--rm", "--no-hosts", ALPINE, "cat", "/etc/hosts"}) alpineResolvConf.WaitWithDefaultTimeout() - Expect(alpineResolvConf.ExitCode()).To(Equal(0)) + Expect(alpineResolvConf).Should(Exit(0)) podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "-ti", "--rm", ALPINE, "cat", "/etc/hosts"}) podResolvConf.WaitWithDefaultTimeout() - Expect(podResolvConf.ExitCode()).To(Equal(0)) + Expect(podResolvConf).Should(Exit(0)) Expect(podResolvConf.OutputToString()).To(Equal(alpineResolvConf.OutputToString())) }) @@ -146,18 +147,18 @@ var _ = Describe("Podman pod create", func() { name := "test" podCreate := podmanTest.Podman([]string{"pod", "create", "--no-hosts", "--name", name, "--infra=false"}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(125)) + Expect(podCreate).Should(Exit(125)) }) It("podman create pod with --add-host", func() { name := "test" podCreate := podmanTest.Podman([]string{"pod", "create", "--add-host", "test.example.com:12.34.56.78", "--name", name}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "-ti", "--rm", ALPINE, "cat", "/etc/hosts"}) podResolvConf.WaitWithDefaultTimeout() - Expect(podResolvConf.ExitCode()).To(Equal(0)) + Expect(podResolvConf).Should(Exit(0)) Expect(strings.Contains(podResolvConf.OutputToString(), "12.34.56.78 test.example.com")).To(BeTrue()) }) @@ -165,7 +166,7 @@ var _ = Describe("Podman pod create", func() { name := "test" podCreate := podmanTest.Podman([]string{"pod", "create", "--add-host", "test.example.com:12.34.56.78", "--name", name, "--infra=false"}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(125)) + Expect(podCreate).Should(Exit(125)) }) It("podman create pod with DNS server set", func() { @@ -173,11 +174,11 @@ var _ = Describe("Podman pod create", func() { server := "12.34.56.78" podCreate := podmanTest.Podman([]string{"pod", "create", "--dns", server, "--name", name}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "-ti", "--rm", ALPINE, "cat", "/etc/resolv.conf"}) podResolvConf.WaitWithDefaultTimeout() - Expect(podResolvConf.ExitCode()).To(Equal(0)) + Expect(podResolvConf).Should(Exit(0)) Expect(strings.Contains(podResolvConf.OutputToString(), fmt.Sprintf("nameserver %s", server))).To(BeTrue()) }) @@ -186,7 +187,7 @@ var _ = Describe("Podman pod create", func() { server := "12.34.56.78" podCreate := podmanTest.Podman([]string{"pod", "create", "--dns", server, "--name", name, "--infra=false"}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(125)) + Expect(podCreate).Should(Exit(125)) }) It("podman create pod with DNS option set", func() { @@ -194,11 +195,11 @@ var _ = Describe("Podman pod create", func() { option := "attempts:5" podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-opt", option, "--name", name}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "-ti", "--rm", ALPINE, "cat", "/etc/resolv.conf"}) podResolvConf.WaitWithDefaultTimeout() - Expect(podResolvConf.ExitCode()).To(Equal(0)) + Expect(podResolvConf).Should(Exit(0)) Expect(strings.Contains(podResolvConf.OutputToString(), fmt.Sprintf("options %s", option))).To(BeTrue()) }) @@ -207,7 +208,7 @@ var _ = Describe("Podman pod create", func() { option := "attempts:5" podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-opt", option, "--name", name, "--infra=false"}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(125)) + Expect(podCreate).Should(Exit(125)) }) It("podman create pod with DNS search domain set", func() { @@ -215,11 +216,11 @@ var _ = Describe("Podman pod create", func() { search := "example.com" podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-search", search, "--name", name}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "-ti", "--rm", ALPINE, "cat", "/etc/resolv.conf"}) podResolvConf.WaitWithDefaultTimeout() - Expect(podResolvConf.ExitCode()).To(Equal(0)) + Expect(podResolvConf).Should(Exit(0)) Expect(strings.Contains(podResolvConf.OutputToString(), fmt.Sprintf("search %s", search))).To(BeTrue()) }) @@ -228,7 +229,7 @@ var _ = Describe("Podman pod create", func() { search := "example.com" podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-search", search, "--name", name, "--infra=false"}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(125)) + Expect(podCreate).Should(Exit(125)) }) It("podman create pod with IP address", func() { @@ -238,12 +239,12 @@ var _ = Describe("Podman pod create", func() { podCreate.WaitWithDefaultTimeout() // Rootless should error without network if rootless.IsRootless() { - Expect(podCreate.ExitCode()).To(Equal(125)) + Expect(podCreate).Should(Exit(125)) } else { - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "-ti", "--rm", ALPINE, "ip", "addr"}) podResolvConf.WaitWithDefaultTimeout() - Expect(podResolvConf.ExitCode()).To(Equal(0)) + Expect(podResolvConf).Should(Exit(0)) Expect(strings.Contains(podResolvConf.OutputToString(), ip)).To(BeTrue()) } }) @@ -255,13 +256,13 @@ var _ = Describe("Podman pod create", func() { ip := GetRandomIPAddress() podCreate := podmanTest.Podman([]string{"pod", "create", "--ip", ip, "--name", podName}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) podCtr := podmanTest.Podman([]string{"run", "--name", ctrName, "--pod", podName, "-d", "-t", ALPINE, "top"}) podCtr.WaitWithDefaultTimeout() - Expect(podCtr.ExitCode()).To(Equal(0)) + Expect(podCtr).Should(Exit(0)) ctrInspect := podmanTest.Podman([]string{"inspect", ctrName}) ctrInspect.WaitWithDefaultTimeout() - Expect(ctrInspect.ExitCode()).To(Equal(0)) + Expect(ctrInspect).Should(Exit(0)) ctrJSON := ctrInspect.InspectContainerToJSON() Expect(ctrJSON[0].NetworkSettings.IPAddress).To(Equal(ip)) }) @@ -271,7 +272,7 @@ var _ = Describe("Podman pod create", func() { ip := GetRandomIPAddress() podCreate := podmanTest.Podman([]string{"pod", "create", "--ip", ip, "--name", name, "--infra=false"}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(125)) + Expect(podCreate).Should(Exit(125)) }) It("podman create pod with MAC address", func() { @@ -281,12 +282,12 @@ var _ = Describe("Podman pod create", func() { podCreate.WaitWithDefaultTimeout() // Rootless should error if rootless.IsRootless() { - Expect(podCreate.ExitCode()).To(Equal(125)) + Expect(podCreate).Should(Exit(125)) } else { - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "-ti", "--rm", ALPINE, "ip", "addr"}) podResolvConf.WaitWithDefaultTimeout() - Expect(podResolvConf.ExitCode()).To(Equal(0)) + Expect(podResolvConf).Should(Exit(0)) Expect(strings.Contains(podResolvConf.OutputToString(), mac)).To(BeTrue()) } }) @@ -296,7 +297,7 @@ var _ = Describe("Podman pod create", func() { mac := "92:d0:c6:0a:29:35" podCreate := podmanTest.Podman([]string{"pod", "create", "--mac-address", mac, "--name", name, "--infra=false"}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(125)) + Expect(podCreate).Should(Exit(125)) }) It("podman create pod and print id to external file", func() { @@ -314,7 +315,7 @@ var _ = Describe("Podman pod create", func() { session := podmanTest.Podman([]string{"pod", "create", "--name=abc", "--pod-id-file", targetFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) id, _ := ioutil.ReadFile(targetFile) check := podmanTest.Podman([]string{"pod", "inspect", "abc"}) @@ -327,14 +328,14 @@ var _ = Describe("Podman pod create", func() { // Make sure we error out with --name. session := podmanTest.Podman([]string{"pod", "create", "--replace", ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) // Create and replace 5 times in a row the "same" pod. podName := "testCtr" for i := 0; i < 5; i++ { session = podmanTest.Podman([]string{"pod", "create", "--replace", "--name", podName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) } }) @@ -342,22 +343,22 @@ var _ = Describe("Podman pod create", func() { name := "test" session := podmanTest.Podman([]string{"pod", "create", "--name", name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"pod", "inspect", name}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) data := check.InspectPodToJSON() check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID}) check1.WaitWithDefaultTimeout() - Expect(check1.ExitCode()).To(Equal(0)) + Expect(check1).Should(Exit(0)) Expect(check1.OutputToString()).To(Equal("/pause")) // check the Path and Args check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID}) check2.WaitWithDefaultTimeout() - Expect(check2.ExitCode()).To(Equal(0)) + Expect(check2).Should(Exit(0)) Expect(check2.OutputToString()).To(Equal("/pause:[/pause]")) }) @@ -365,22 +366,22 @@ var _ = Describe("Podman pod create", func() { name := "test" session := podmanTest.Podman([]string{"pod", "create", "--infra-command", "/pause1", "--name", name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"pod", "inspect", name}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) data := check.InspectPodToJSON() check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID}) check1.WaitWithDefaultTimeout() - Expect(check1.ExitCode()).To(Equal(0)) + Expect(check1).Should(Exit(0)) Expect(check1.OutputToString()).To(Equal("/pause1")) // check the Path and Args check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID}) check2.WaitWithDefaultTimeout() - Expect(check2.ExitCode()).To(Equal(0)) + Expect(check2).Should(Exit(0)) Expect(check2.OutputToString()).To(Equal("/pause1:[/pause1]")) }) @@ -392,22 +393,22 @@ entrypoint ["/fromimage"] name := "test" session := podmanTest.Podman([]string{"pod", "create", "--infra-image", "localhost/infra", "--name", name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"pod", "inspect", name}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) data := check.InspectPodToJSON() check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID}) check1.WaitWithDefaultTimeout() - Expect(check1.ExitCode()).To(Equal(0)) + Expect(check1).Should(Exit(0)) Expect(check1.OutputToString()).To(Equal("/fromimage")) // check the Path and Args check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID}) check2.WaitWithDefaultTimeout() - Expect(check2.ExitCode()).To(Equal(0)) + Expect(check2).Should(Exit(0)) Expect(check2.OutputToString()).To(Equal("/fromimage:[/fromimage]")) }) @@ -419,22 +420,22 @@ entrypoint ["/fromimage"] name := "test" session := podmanTest.Podman([]string{"pod", "create", "--infra-image", "localhost/infra", "--infra-command", "/fromcommand", "--name", name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"pod", "inspect", name}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) data := check.InspectPodToJSON() check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID}) check1.WaitWithDefaultTimeout() - Expect(check1.ExitCode()).To(Equal(0)) + Expect(check1).Should(Exit(0)) Expect(check1.OutputToString()).To(Equal("/fromcommand")) // check the Path and Args check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID}) check2.WaitWithDefaultTimeout() - Expect(check2.ExitCode()).To(Equal(0)) + Expect(check2).Should(Exit(0)) Expect(check2.OutputToString()).To(Equal("/fromcommand:[/fromcommand]")) }) @@ -442,11 +443,11 @@ entrypoint ["/fromimage"] name := "test" session := podmanTest.Podman([]string{"pod", "create", "--name", name, "--network", "slirp4netns:port_handler=slirp4netns", "-p", "8082:8000"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{.InfraConfig.NetworkOptions.slirp4netns}}", name}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) Expect(check.OutputToString()).To(Equal("[port_handler=slirp4netns]")) }) @@ -454,41 +455,41 @@ entrypoint ["/fromimage"] podName := "testpod" create := podmanTest.Podman([]string{"pod", "create", "--name", podName}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) status1 := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{ .State }}", podName}) status1.WaitWithDefaultTimeout() - Expect(status1.ExitCode()).To(Equal(0)) + Expect(status1).Should(Exit(0)) Expect(strings.Contains(status1.OutputToString(), "Created")).To(BeTrue()) ctr1 := podmanTest.Podman([]string{"run", "--pod", podName, "-d", ALPINE, "top"}) ctr1.WaitWithDefaultTimeout() - Expect(ctr1.ExitCode()).To(Equal(0)) + Expect(ctr1).Should(Exit(0)) status2 := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{ .State }}", podName}) status2.WaitWithDefaultTimeout() - Expect(status2.ExitCode()).To(Equal(0)) + Expect(status2).Should(Exit(0)) Expect(strings.Contains(status2.OutputToString(), "Running")).To(BeTrue()) ctr2 := podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) ctr2.WaitWithDefaultTimeout() - Expect(ctr2.ExitCode()).To(Equal(0)) + Expect(ctr2).Should(Exit(0)) status3 := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{ .State }}", podName}) status3.WaitWithDefaultTimeout() - Expect(status3.ExitCode()).To(Equal(0)) + Expect(status3).Should(Exit(0)) Expect(strings.Contains(status3.OutputToString(), "Degraded")).To(BeTrue()) }) It("podman create with unsupported network options", func() { podCreate := podmanTest.Podman([]string{"pod", "create", "--network", "container:doesnotmatter"}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(125)) + Expect(podCreate).Should(Exit(125)) Expect(podCreate.ErrorToString()).To(ContainSubstring("pods presently do not support network mode container")) podCreate = podmanTest.Podman([]string{"pod", "create", "--network", "ns:/does/not/matter"}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(125)) + Expect(podCreate).Should(Exit(125)) Expect(podCreate.ErrorToString()).To(ContainSubstring("pods presently do not support network mode path")) }) @@ -496,11 +497,11 @@ entrypoint ["/fromimage"] podName := "testPod" podCreate := podmanTest.Podman([]string{"pod", "create", "--network", "none", "--name", podName}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "ip", "-o", "-4", "addr"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("inet 127.0.0.1/8 scope host lo")) Expect(len(session.OutputToStringArray())).To(Equal(1)) }) @@ -515,7 +516,7 @@ ENTRYPOINT ["sleep","99999"] create := podmanTest.Podman([]string{"pod", "create", "--infra-image", iid}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(BeZero()) + Expect(create).Should(Exit(0)) }) It("podman pod create --cpus", func() { @@ -525,15 +526,15 @@ ENTRYPOINT ["sleep","99999"] numCPUStr := strconv.Itoa(int(numCPU)) podCreate := podmanTest.Podman([]string{"pod", "create", "--cpus", numCPUStr, "--name", podName}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) contCreate := podmanTest.Podman([]string{"container", "create", "--pod", podName, "alpine"}) contCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) podInspect := podmanTest.Podman([]string{"pod", "inspect", podName}) podInspect.WaitWithDefaultTimeout() - Expect(podInspect.ExitCode()).To(Equal(0)) + Expect(podInspect).Should(Exit(0)) podJSON := podInspect.InspectPodToJSON() Expect(podJSON.CPUPeriod).To(Equal(period)) Expect(podJSON.CPUQuota).To(Equal(quota)) @@ -547,16 +548,77 @@ ENTRYPOINT ["sleep","99999"] in := "0-" + numCPUStr podCreate := podmanTest.Podman([]string{"pod", "create", "--cpuset-cpus", in, "--name", podName}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) contCreate := podmanTest.Podman([]string{"container", "create", "--name", ctrName, "--pod", podName, "alpine"}) contCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) podInspect := podmanTest.Podman([]string{"pod", "inspect", podName}) podInspect.WaitWithDefaultTimeout() - Expect(podInspect.ExitCode()).To(Equal(0)) + Expect(podInspect).Should(Exit(0)) podJSON := podInspect.InspectPodToJSON() Expect(podJSON.CPUSetCPUs).To(Equal(in)) }) + + It("podman pod create --pid", func() { + podName := "pidPod" + ns := "ns:/proc/self/ns/" + podCreate := podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"}) + podCreate.WaitWithDefaultTimeout() + Expect(podCreate).Should(Exit(0)) + + podInspect := podmanTest.Podman([]string{"pod", "inspect", podName}) + podInspect.WaitWithDefaultTimeout() + Expect(podInspect).Should(Exit(0)) + podJSON := podInspect.InspectPodToJSON() + Expect(podJSON.InfraConfig.PidNS).To(Equal("path")) + + podName = "pidPod2" + ns = "pod" + + podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"}) + podCreate.WaitWithDefaultTimeout() + Expect(podCreate).Should(Exit(0)) + + podInspect = podmanTest.Podman([]string{"pod", "inspect", podName}) + podInspect.WaitWithDefaultTimeout() + Expect(podInspect).Should(Exit(0)) + podJSON = podInspect.InspectPodToJSON() + Expect(podJSON.InfraConfig.PidNS).To(Equal("pod")) + + podName = "pidPod3" + ns = "host" + + podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"}) + podCreate.WaitWithDefaultTimeout() + Expect(podCreate).Should(Exit(0)) + + podInspect = podmanTest.Podman([]string{"pod", "inspect", podName}) + podInspect.WaitWithDefaultTimeout() + Expect(podInspect).Should(Exit(0)) + podJSON = podInspect.InspectPodToJSON() + Expect(podJSON.InfraConfig.PidNS).To(Equal("host")) + + podName = "pidPod4" + ns = "private" + + podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"}) + podCreate.WaitWithDefaultTimeout() + Expect(podCreate).Should(Exit(0)) + + podInspect = podmanTest.Podman([]string{"pod", "inspect", podName}) + podInspect.WaitWithDefaultTimeout() + Expect(podInspect).Should(Exit(0)) + podJSON = podInspect.InspectPodToJSON() + Expect(podJSON.InfraConfig.PidNS).To(Equal("private")) + + podName = "pidPod5" + ns = "container:randomfakeid" + + podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"}) + podCreate.WaitWithDefaultTimeout() + Expect(podCreate).Should(ExitWithError()) + + }) }) diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go index 09f0d4e33..3bd7f48ab 100644 --- a/test/e2e/pod_infra_container_test.go +++ b/test/e2e/pod_infra_container_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman pod create", func() { @@ -36,7 +37,7 @@ var _ = Describe("Podman pod create", func() { It("podman create infra container", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() check := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc"}) @@ -53,54 +54,54 @@ var _ = Describe("Podman pod create", func() { It("podman start infra container", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"ps", "-qa", "--no-trunc", "--filter", "status=running"}) check.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(check.OutputToStringArray())).To(Equal(1)) }) It("podman start infra container different image", func() { session := podmanTest.Podman([]string{"pod", "create", "--infra-image", BB}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() // If we use the default entry point, we should exit with no error - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman infra container namespaces", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("", podID) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"ps", "-a", "--no-trunc", "--ns", "--format", "{{.Namespaces.IPC}} {{.Namespaces.NET}}"}) check.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(check.OutputToStringArray())).To(Equal(2)) Expect(check.OutputToStringArray()[0]).To(Equal(check.OutputToStringArray()[1])) check = podmanTest.Podman([]string{"ps", "-a", "--no-trunc", "--ns", "--format", "{{.IPC}} {{.NET}}"}) check.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(check.OutputToStringArray())).To(Equal(2)) Expect(check.OutputToStringArray()[0]).To(Equal(check.OutputToStringArray()[1])) }) @@ -108,20 +109,20 @@ var _ = Describe("Podman pod create", func() { It("podman pod correctly sets up NetNS", func() { session := podmanTest.Podman([]string{"pod", "create", "--share", "net"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "-d", "--pod", podID, nginx}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--pod", podID, fedoraMinimal, "curl", "localhost:80"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", fedoraMinimal, "curl", "localhost"}) session.WaitWithDefaultTimeout() @@ -131,43 +132,43 @@ var _ = Describe("Podman pod create", func() { It("podman pod correctly sets up IPCNS", func() { session := podmanTest.Podman([]string{"pod", "create", "--share", "ipc"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--pod", podID, fedoraMinimal, "/bin/sh", "-c", "'touch /dev/shm/hi'"}) session.WaitWithDefaultTimeout() if session.ExitCode() != 0 { Skip("ShmDir not initialized, skipping...") } - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--pod", podID, fedoraMinimal, "/bin/sh", "-c", "'ls /dev/shm'"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("hi")) }) It("podman pod correctly sets up PIDNS", func() { session := podmanTest.Podman([]string{"pod", "create", "--share", "pid", "--name", "test-pod"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("test-ctr", podID) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"top", "test-ctr", "pid"}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) PIDs := check.OutputToStringArray() Expect(len(PIDs)).To(Equal(3)) @@ -179,25 +180,25 @@ var _ = Describe("Podman pod create", func() { It("podman pod doesn't share PIDNS if requested to not", func() { session := podmanTest.Podman([]string{"pod", "create", "--share", "net", "--name", "test-pod"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("test-ctr", podID) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"top", "test-ctr", "pid"}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) ctrTop := check.OutputToStringArray() check = podmanTest.Podman([]string{"top", podID[:12] + "-infra", "pid"}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) infraTop := check.OutputToStringArray() ctrPID, _ := strconv.Atoi(ctrTop[1]) @@ -208,16 +209,16 @@ var _ = Describe("Podman pod create", func() { It("podman pod container can override pod net NS", func() { session := podmanTest.Podman([]string{"pod", "create", "--share", "net"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "-d", "--pod", podID, nginx}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--pod", podID, "--network", "bridge", nginx, "curl", "localhost"}) session.WaitWithDefaultTimeout() @@ -228,26 +229,26 @@ var _ = Describe("Podman pod create", func() { SkipIfRootlessCgroupsV1("Not supported for rootless + CGroupsV1") session := podmanTest.Podman([]string{"pod", "create", "--share", "pid"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--pod", podID, "--pid", "host", "-d", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"ps", "-a", "--ns", "--format", "{{.Namespaces.PIDNS}}"}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) outputArray := check.OutputToStringArray() Expect(len(outputArray)).To(Equal(2)) check = podmanTest.Podman([]string{"ps", "-a", "--ns", "--format", "{{.PIDNS}}"}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) outputArray = check.OutputToStringArray() Expect(len(outputArray)).To(Equal(2)) @@ -259,20 +260,20 @@ var _ = Describe("Podman pod create", func() { It("podman pod container can override pod not sharing pid", func() { session := podmanTest.Podman([]string{"pod", "create", "--share", "net"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--pod", podID, "--pid", "pod", "-d", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"ps", "-a", "--ns", "--format", "{{.PIDNS}}"}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) outputArray := check.OutputToStringArray() Expect(len(outputArray)).To(Equal(2)) @@ -284,20 +285,20 @@ var _ = Describe("Podman pod create", func() { It("podman pod container can override pod ipc NS", func() { session := podmanTest.Podman([]string{"pod", "create", "--share", "ipc"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--pod", podID, "--ipc", "host", "-d", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"ps", "-a", "--ns", "--format", "{{.IPC}}"}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) outputArray := check.OutputToStringArray() Expect(len(outputArray)).To(Equal(2)) @@ -309,12 +310,12 @@ var _ = Describe("Podman pod create", func() { It("podman pod infra container deletion", func() { session := podmanTest.Podman([]string{"pod", "create", "--share", "ipc"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"ps", "-aq"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) infraID := session.OutputToString() session = podmanTest.Podman([]string{"rm", infraID}) @@ -323,27 +324,27 @@ var _ = Describe("Podman pod create", func() { session = podmanTest.Podman([]string{"pod", "rm", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run in pod starts infra", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() result := podmanTest.Podman([]string{"ps", "-aq"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) infraID := result.OutputToString() result = podmanTest.Podman([]string{"run", "--pod", podID, "-d", ALPINE, "top"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"ps", "-aq"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0)) Expect(result.OutputToString()).To(ContainSubstring(infraID)) @@ -352,26 +353,26 @@ var _ = Describe("Podman pod create", func() { It("podman start in pod starts infra", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() result := podmanTest.Podman([]string{"ps", "-aq"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) infraID := result.OutputToString() result = podmanTest.Podman([]string{"create", "--pod", podID, ALPINE, "ls"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) ctrID := result.OutputToString() result = podmanTest.Podman([]string{"start", ctrID}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"ps", "-aq"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0)) Expect(result.OutputToString()).To(ContainSubstring(infraID)) @@ -380,7 +381,7 @@ var _ = Describe("Podman pod create", func() { It("podman run --add-host in pod", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() // verify we can add a host to the infra's /etc/hosts @@ -388,31 +389,31 @@ var _ = Describe("Podman pod create", func() { // permission denied error as of Fedora 33. session = podmanTest.Podman([]string{"run", "--pod", podID, "--add-host", "foobar:127.0.0.1", ALPINE, "ping", "-c", "1", "foobar"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // verify we can see the other hosts of infra's /etc/hosts session = podmanTest.Podman([]string{"run", "--pod", podID, ALPINE, "ping", "-c", "1", "foobar"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run hostname is shared", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() // verify we can add a host to the infra's /etc/hosts session = podmanTest.Podman([]string{"run", "--pod", podID, ALPINE, "hostname"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) hostname := session.OutputToString() infraName := podID[:12] + "-infra" // verify we can see the other hosts of infra's /etc/hosts session = podmanTest.Podman([]string{"inspect", infraName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(hostname)) }) }) diff --git a/test/e2e/pod_inspect_test.go b/test/e2e/pod_inspect_test.go index 036b08570..6633b228c 100644 --- a/test/e2e/pod_inspect_test.go +++ b/test/e2e/pod_inspect_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman pod inspect", func() { @@ -46,15 +47,15 @@ var _ = Describe("Podman pod inspect", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"pod", "inspect", podid}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.IsJSONOutputValid()).To(BeTrue()) podData := inspect.InspectPodToJSON() Expect(podData.ID).To(Equal(podid)) @@ -67,13 +68,13 @@ var _ = Describe("Podman pod inspect", func() { // Create the pod. session := podmanTest.Podman(createCommand) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Inspect the pod and make sure that the create command is // exactly how we created the pod. inspect := podmanTest.Podman([]string{"pod", "inspect", podName}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.IsJSONOutputValid()).To(BeTrue()) podData := inspect.InspectPodToJSON() // Let's get the last len(createCommand) items in the command. @@ -86,11 +87,11 @@ var _ = Describe("Podman pod inspect", func() { podName := "testPod" create := podmanTest.Podman([]string{"pod", "create", "--name", podName, "-p", "8080:80"}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) inspectOut := podmanTest.Podman([]string{"pod", "inspect", podName}) inspectOut.WaitWithDefaultTimeout() - Expect(inspectOut.ExitCode()).To(Equal(0)) + Expect(inspectOut).Should(Exit(0)) inspectJSON := new(define.InspectPodData) err := json.Unmarshal(inspectOut.Out.Contents(), inspectJSON) @@ -106,15 +107,15 @@ var _ = Describe("Podman pod inspect", func() { macAddr := "42:43:44:00:00:01" create := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--mac-address", macAddr}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) create = podmanTest.Podman([]string{"run", "-d", "--pod", podName, ALPINE, "top"}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) inspectOut := podmanTest.Podman([]string{"pod", "inspect", podName}) inspectOut.WaitWithDefaultTimeout() - Expect(inspectOut.ExitCode()).To(Equal(0)) + Expect(inspectOut).Should(Exit(0)) Expect(inspectOut.OutputToString()).To(ContainSubstring(macAddr)) }) diff --git a/test/e2e/pod_kill_test.go b/test/e2e/pod_kill_test.go index 92dcad292..7ab62ec5d 100644 --- a/test/e2e/pod_kill_test.go +++ b/test/e2e/pod_kill_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman pod kill", func() { @@ -45,15 +46,15 @@ var _ = Describe("Podman pod kill", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "kill", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -63,11 +64,11 @@ var _ = Describe("Podman pod kill", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "kill", "-s", "9", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -77,11 +78,11 @@ var _ = Describe("Podman pod kill", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "kill", "test1"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -91,11 +92,11 @@ var _ = Describe("Podman pod kill", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "kill", "-s", "bogus", "test1"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) }) @@ -105,24 +106,24 @@ var _ = Describe("Podman pod kill", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, podid2 := podmanTest.CreatePod(nil) Expect(ec).To(Equal(0)) session = podmanTest.RunTopContainerInPod("", podid2) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("", podid2) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if !IsRemote() { podid2 = "-l" } result := podmanTest.Podman([]string{"pod", "kill", podid2}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) }) @@ -133,23 +134,23 @@ var _ = Describe("Podman pod kill", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, podid2 := podmanTest.CreatePod(nil) Expect(ec).To(Equal(0)) session = podmanTest.RunTopContainerInPod("", podid2) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "kill", "-a"}) result.WaitWithDefaultTimeout() fmt.Println(result.OutputToString(), result.ErrorToString()) - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) }) diff --git a/test/e2e/pod_pause_test.go b/test/e2e/pod_pause_test.go index da3b106fa..7c092ba8e 100644 --- a/test/e2e/pod_pause_test.go +++ b/test/e2e/pod_pause_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman pod pause", func() { @@ -53,7 +54,7 @@ var _ = Describe("Podman pod pause", func() { result := podmanTest.Podman([]string{"pod", "pause", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman pod pause a running pod by id", func() { @@ -62,12 +63,12 @@ var _ = Describe("Podman pod pause", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "pause", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring(pausedState)) @@ -83,12 +84,12 @@ var _ = Describe("Podman pod pause", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "unpause", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) }) @@ -98,17 +99,17 @@ var _ = Describe("Podman pod pause", func() { session := podmanTest.RunTopContainerInPod("", "test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "pause", "test1"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(Equal(pausedState)) result = podmanTest.Podman([]string{"pod", "unpause", "test1"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) }) diff --git a/test/e2e/pod_pod_namespaces_test.go b/test/e2e/pod_pod_namespaces_test.go index ce93db63c..9e9b9b2d3 100644 --- a/test/e2e/pod_pod_namespaces_test.go +++ b/test/e2e/pod_pod_namespaces_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman pod create", func() { @@ -36,20 +37,20 @@ var _ = Describe("Podman pod create", func() { It("podman pod container share Namespaces", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--pod", podID, "-d", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"ps", "-a", "--ns", "--format", "{{.Namespaces.IPC}} {{.Namespaces.UTS}} {{.Namespaces.NET}}"}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) outputArray := check.OutputToStringArray() Expect(len(outputArray)).To(Equal(2)) @@ -63,39 +64,39 @@ var _ = Describe("Podman pod create", func() { It("podman pod container share ipc && /dev/shm ", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--rm", "--pod", podID, ALPINE, "touch", "/dev/shm/test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--rm", "--pod", podID, ALPINE, "ls", "/dev/shm/test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pod container dontshare PIDNS", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--pod", podID, "-d", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"ps", "-a", "--ns", "--format", "{{.Namespaces.PIDNS}}"}) check.WaitWithDefaultTimeout() - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) outputArray := check.OutputToStringArray() Expect(len(outputArray)).To(Equal(2)) diff --git a/test/e2e/pod_prune_test.go b/test/e2e/pod_prune_test.go index 2def95308..6273fcec3 100644 --- a/test/e2e/pod_prune_test.go +++ b/test/e2e/pod_prune_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman pod prune", func() { @@ -38,7 +39,7 @@ var _ = Describe("Podman pod prune", func() { result := podmanTest.Podman([]string{"pod", "prune", "--force"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman pod prune doesn't remove a pod with a running container", func() { @@ -47,11 +48,11 @@ var _ = Describe("Podman pod prune", func() { ec2 := podmanTest.RunTopContainerInPod("", podid) ec2.WaitWithDefaultTimeout() - Expect(ec2.ExitCode()).To(Equal(0)) + Expect(ec2).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "prune", "-f"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To((Equal(0))) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"ps", "-qa"}) result.WaitWithDefaultTimeout() @@ -67,7 +68,7 @@ var _ = Describe("Podman pod prune", func() { result := podmanTest.Podman([]string{"pod", "prune", "-f"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"ps", "-qa"}) result.WaitWithDefaultTimeout() diff --git a/test/e2e/pod_ps_test.go b/test/e2e/pod_ps_test.go index c5c0827bc..c27539d6f 100644 --- a/test/e2e/pod_ps_test.go +++ b/test/e2e/pod_ps_test.go @@ -39,7 +39,7 @@ var _ = Describe("Podman ps", func() { It("podman pod ps no pods", func() { session := podmanTest.Podman([]string{"pod", "ps"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pod ps default", func() { @@ -48,11 +48,11 @@ var _ = Describe("Podman ps", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "ps"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0)) }) @@ -79,7 +79,7 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0)) Expect(podid).To(Equal(result.OutputToStringArray()[0])) }) @@ -94,7 +94,7 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--latest"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(podid2)) Expect(result.OutputToString()).To(Not(ContainSubstring(podid1))) }) @@ -105,7 +105,7 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"pod", "ps", "--filter", fmt.Sprintf("id=%s", podid)}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman pod ps filter name regexp", func() { @@ -116,14 +116,14 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "name=mypod"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) output := result.OutputToStringArray() Expect(len(output)).To(Equal(2)) result = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "name=mypod$"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) output = result.OutputToStringArray() Expect(len(output)).To(Equal(1)) @@ -150,7 +150,7 @@ var _ = Describe("Podman ps", func() { session := podmanTest.Podman([]string{"pod", "ps", "--sort=name", "--format", "{{.Name}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) sortedArr := session.OutputToStringArray() @@ -164,14 +164,14 @@ var _ = Describe("Podman ps", func() { session := podmanTest.RunTopContainerInPod("test1", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, _ = podmanTest.RunLsContainerInPod("test2", podid) Expect(ec).To(Equal(0)) session = podmanTest.Podman([]string{"pod", "ps", "--format={{.ContainerNames}}", "--ctr-names"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("test1")) Expect(session.OutputToString()).To(ContainSubstring("test2")) }) @@ -182,7 +182,7 @@ var _ = Describe("Podman ps", func() { session := podmanTest.RunTopContainerInPod("test1", podid1) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec2, podid2 := podmanTest.CreatePod(nil) Expect(ec2).To(Equal(0)) @@ -192,25 +192,25 @@ var _ = Describe("Podman ps", func() { session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "ctr-names=test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(podid1)) Expect(session.OutputToString()).To(Not(ContainSubstring(podid2))) session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "ctr-names=test", "--filter", "ctr-status=running"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(podid1)) Expect(session.OutputToString()).To(Not(ContainSubstring(podid2))) session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", fmt.Sprintf("ctr-ids=%s", cid)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(podid2)) Expect(session.OutputToString()).To(Not(ContainSubstring(podid1))) session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "ctr-ids=" + cid[:40], "--filter", "ctr-ids=" + cid + "$"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(podid2)) Expect(session.OutputToString()).To(Not(ContainSubstring(podid1))) @@ -219,42 +219,42 @@ var _ = Describe("Podman ps", func() { session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "ctr-number=1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(podid1)) Expect(session.OutputToString()).To(ContainSubstring(podid2)) Expect(session.OutputToString()).To(Not(ContainSubstring(podid3))) session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "ctr-number=1", "--filter", "ctr-number=0"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(podid1)) Expect(session.OutputToString()).To(ContainSubstring(podid2)) Expect(session.OutputToString()).To(ContainSubstring(podid3)) session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "ctr-status=running"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(podid1)) Expect(session.OutputToString()).To(Not(ContainSubstring(podid2))) Expect(session.OutputToString()).To(Not(ContainSubstring(podid3))) session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "ctr-status=exited"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(podid2)) Expect(session.OutputToString()).To(Not(ContainSubstring(podid1))) Expect(session.OutputToString()).To(Not(ContainSubstring(podid3))) session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "ctr-status=exited", "--filter", "ctr-status=running"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(podid1)) Expect(session.OutputToString()).To(ContainSubstring(podid2)) Expect(session.OutputToString()).To(Not(ContainSubstring(podid3))) session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "ctr-status=created"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(BeEmpty()) }) @@ -282,22 +282,22 @@ var _ = Describe("Podman ps", func() { net := stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", net}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(net) session = podmanTest.Podman([]string{"pod", "create", "--network", net}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) podWithNet := session.OutputToString() session = podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) podWithoutNet := session.OutputToString() session = podmanTest.Podman([]string{"pod", "ps", "--no-trunc", "--filter", "network=" + net}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(podWithNet)) Expect(session.OutputToString()).To(Not(ContainSubstring(podWithoutNet))) }) @@ -305,11 +305,11 @@ var _ = Describe("Podman ps", func() { It("podman pod ps --format networks", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "ps", "--format", "{{ .Networks }}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) if isRootless() { // rootless container don't have a network by default Expect(session.OutputToString()).To(Equal("")) @@ -321,22 +321,22 @@ var _ = Describe("Podman ps", func() { net1 := stringid.GenerateNonCryptoID() session = podmanTest.Podman([]string{"network", "create", net1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(net1) net2 := stringid.GenerateNonCryptoID() session = podmanTest.Podman([]string{"network", "create", net2}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(net2) session = podmanTest.Podman([]string{"pod", "create", "--network", net1 + "," + net2}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) pid := session.OutputToString() session = podmanTest.Podman([]string{"pod", "ps", "--format", "{{ .Networks }}", "--filter", "id=" + pid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) // the output is not deterministic so check both possible orders Expect(session.OutputToString()).To(Or(Equal(net1+","+net2), Equal(net2+","+net1))) }) @@ -344,11 +344,11 @@ var _ = Describe("Podman ps", func() { It("pod no infra should ps", func() { session := podmanTest.Podman([]string{"pod", "create", "--infra=false"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ps := podmanTest.Podman([]string{"pod", "ps"}) ps.WaitWithDefaultTimeout() - Expect(ps.ExitCode()).To(Equal(0)) + Expect(ps).Should(Exit(0)) infra := podmanTest.Podman([]string{"pod", "ps", "--format", "{{.InfraId}}"}) infra.WaitWithDefaultTimeout() @@ -367,7 +367,15 @@ var _ = Describe("Podman ps", func() { session := podmanTest.Podman([]string{"pod", "ps", "--format", "{{.Labels}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("value1")) }) + + It("podman pod ps headers", func() { + session := podmanTest.Podman([]string{"pod", "ps", "--ctr-ids", "--ctr-names", "--ctr-status", "--ns"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToString()).To(MatchRegexp(`^POD ID\s+NAME\s+STATUS\s+CREATED\s+INFRA ID\s+IDS\s+NAMES\s+STATUS\s+CGROUP\s+NAMESPACES$`)) + }) + }) diff --git a/test/e2e/pod_restart_test.go b/test/e2e/pod_restart_test.go index 006421b93..448c110ce 100644 --- a/test/e2e/pod_restart_test.go +++ b/test/e2e/pod_restart_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman pod restart", func() { @@ -35,7 +36,7 @@ var _ = Describe("Podman pod restart", func() { It("podman pod restart bogus pod", func() { session := podmanTest.Podman([]string{"pod", "restart", "123"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman pod restart single empty pod", func() { @@ -44,7 +45,7 @@ var _ = Describe("Podman pod restart", func() { session := podmanTest.Podman([]string{"pod", "restart", podid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman pod restart single pod by name", func() { @@ -53,14 +54,14 @@ var _ = Describe("Podman pod restart", func() { session := podmanTest.RunTopContainerInPod("test1", "foobar99") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) startTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1"}) startTime.WaitWithDefaultTimeout() session = podmanTest.Podman([]string{"pod", "restart", "foobar99"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) restartTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1"}) restartTime.WaitWithDefaultTimeout() @@ -73,29 +74,29 @@ var _ = Describe("Podman pod restart", func() { session := podmanTest.RunTopContainerInPod("test1", "foobar99") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}}) Expect(ec).To(Equal(0)) session = podmanTest.RunTopContainerInPod("test2", "foobar100") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("test3", "foobar100") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("test4", "foobar100") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) startTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2", "test3", "test4"}) startTime.WaitWithDefaultTimeout() session = podmanTest.Podman([]string{"pod", "restart", "foobar99", "foobar100"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) restartTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2", "test3", "test4"}) restartTime.WaitWithDefaultTimeout() @@ -111,21 +112,21 @@ var _ = Describe("Podman pod restart", func() { session := podmanTest.RunTopContainerInPod("test1", "foobar99") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}}) Expect(ec).To(Equal(0)) session = podmanTest.RunTopContainerInPod("test2", "foobar100") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) startTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"}) startTime.WaitWithDefaultTimeout() session = podmanTest.Podman([]string{"pod", "restart", "-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) restartTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"}) restartTime.WaitWithDefaultTimeout() @@ -139,14 +140,14 @@ var _ = Describe("Podman pod restart", func() { session := podmanTest.RunTopContainerInPod("test1", "foobar99") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}}) Expect(ec).To(Equal(0)) session = podmanTest.RunTopContainerInPod("test2", "foobar100") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) startTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"}) startTime.WaitWithDefaultTimeout() @@ -157,7 +158,7 @@ var _ = Describe("Podman pod restart", func() { } session = podmanTest.Podman([]string{"pod", "restart", podid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) restartTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"}) restartTime.WaitWithDefaultTimeout() @@ -171,10 +172,10 @@ var _ = Describe("Podman pod restart", func() { session := podmanTest.RunTopContainerInPod("", "foobar99") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "restart", podid1, "doesnotexist"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) }) diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go index 6d710f020..c5d91d679 100644 --- a/test/e2e/pod_rm_test.go +++ b/test/e2e/pod_rm_test.go @@ -10,6 +10,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman pod rm", func() { @@ -42,7 +43,7 @@ var _ = Describe("Podman pod rm", func() { result := podmanTest.Podman([]string{"pod", "rm", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) // Also check that we don't leak cgroups err := filepath.Walk("/sys/fs/cgroup", func(path string, info os.FileInfo, err error) error { @@ -73,11 +74,11 @@ var _ = Describe("Podman pod rm", func() { } result := podmanTest.Podman([]string{"pod", "rm", latest}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(podid)) Expect(result.OutputToString()).To(Not(ContainSubstring(podid2))) }) @@ -91,7 +92,7 @@ var _ = Describe("Podman pod rm", func() { result := podmanTest.Podman([]string{"pod", "rm", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"ps", "-qa"}) result.WaitWithDefaultTimeout() @@ -104,11 +105,11 @@ var _ = Describe("Podman pod rm", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "rm", "-f", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"ps", "-q"}) result.WaitWithDefaultTimeout() @@ -126,7 +127,7 @@ var _ = Describe("Podman pod rm", func() { session := podmanTest.RunTopContainerInPod("", podid1) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podmanTest.WaitForContainer() Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) fmt.Printf("Started container running in one pod") @@ -165,22 +166,22 @@ var _ = Describe("Podman pod rm", func() { session := podmanTest.RunTopContainerInPod("", podid1) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "--pod", podid1, ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, _ = podmanTest.RunLsContainerInPod("", podid2) Expect(ec).To(Equal(0)) session = podmanTest.RunTopContainerInPod("", podid2) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "rm", "-fa"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"ps", "-q"}) result.WaitWithDefaultTimeout() @@ -195,7 +196,7 @@ var _ = Describe("Podman pod rm", func() { It("podman rm bogus pod", func() { session := podmanTest.Podman([]string{"pod", "rm", "bogus"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) }) It("podman rm bogus pod and a running pod", func() { @@ -204,15 +205,15 @@ var _ = Describe("Podman pod rm", func() { session := podmanTest.RunTopContainerInPod("test1", podid1) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "rm", "bogus", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) session = podmanTest.Podman([]string{"pod", "rm", "test1", "bogus"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) }) It("podman rm --ignore bogus pod and a running pod", func() { @@ -222,15 +223,15 @@ var _ = Describe("Podman pod rm", func() { session := podmanTest.RunTopContainerInPod("test1", podid1) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "rm", "--force", "--ignore", "bogus", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "rm", "--ignore", "test1", "bogus"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pod start/remove single pod via --pod-id-file", func() { @@ -244,21 +245,21 @@ var _ = Describe("Podman pod rm", func() { // Create a pod with --pod-id-file. session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--pod-id-file", tmpFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Create container inside the pod. session = podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "start", "--pod-id-file", tmpFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) // infra+top session = podmanTest.Podman([]string{"pod", "rm", "--pod-id-file", tmpFile, "--force"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -274,12 +275,12 @@ var _ = Describe("Podman pod rm", func() { // Create a pod with --pod-id-file. session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--pod-id-file", tmpFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Create container inside the pod. session = podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Append the id files along with the command. podIDFiles = append(podIDFiles, "--pod-id-file") @@ -290,14 +291,14 @@ var _ = Describe("Podman pod rm", func() { cmd = append(cmd, podIDFiles...) session := podmanTest.Podman(cmd) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(20)) // 10*(infra+top) cmd = []string{"pod", "rm", "--force"} cmd = append(cmd, podIDFiles...) session = podmanTest.Podman(cmd) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) }) diff --git a/test/e2e/pod_start_test.go b/test/e2e/pod_start_test.go index 5838f3310..93c200389 100644 --- a/test/e2e/pod_start_test.go +++ b/test/e2e/pod_start_test.go @@ -40,7 +40,7 @@ var _ = Describe("Podman pod start", func() { It("podman pod start bogus pod", func() { session := podmanTest.Podman([]string{"pod", "start", "123"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman pod start single empty pod", func() { @@ -49,7 +49,7 @@ var _ = Describe("Podman pod start", func() { session := podmanTest.Podman([]string{"pod", "start", podid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman pod start single pod by name", func() { @@ -58,11 +58,11 @@ var _ = Describe("Podman pod start", func() { session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "start", "foobar99"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pod start multiple pods", func() { @@ -71,18 +71,18 @@ var _ = Describe("Podman pod start", func() { session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec2, podid2 := podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}}) Expect(ec2).To(Equal(0)) session = podmanTest.Podman([]string{"create", "--pod", "foobar100", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "start", podid1, podid2}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) }) @@ -122,18 +122,18 @@ var _ = Describe("Podman pod start", func() { session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}}) Expect(ec).To(Equal(0)) session = podmanTest.Podman([]string{"create", "--pod", "foobar100", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "start", "--all"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) }) @@ -143,14 +143,14 @@ var _ = Describe("Podman pod start", func() { session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}}) Expect(ec).To(Equal(0)) session = podmanTest.Podman([]string{"create", "--pod", "foobar100", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podid := "--latest" if IsRemote() { @@ -158,7 +158,7 @@ var _ = Describe("Podman pod start", func() { } session = podmanTest.Podman([]string{"pod", "start", podid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) }) @@ -168,11 +168,11 @@ var _ = Describe("Podman pod start", func() { session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "start", podid, "doesnotexist"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman pod start single pod via --pod-id-file", func() { @@ -186,16 +186,16 @@ var _ = Describe("Podman pod start", func() { // Create a pod with --pod-id-file. session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--pod-id-file", tmpFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Create container inside the pod. session = podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "start", "--pod-id-file", tmpFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) // infra+top }) @@ -211,12 +211,12 @@ var _ = Describe("Podman pod start", func() { // Create a pod with --pod-id-file. session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--pod-id-file", tmpFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Create container inside the pod. session = podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Append the id files along with the command. podIDFiles = append(podIDFiles, "--pod-id-file") @@ -227,7 +227,7 @@ var _ = Describe("Podman pod start", func() { cmd = append(cmd, podIDFiles...) session := podmanTest.Podman(cmd) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(20)) // 10*(infra+top) }) @@ -241,11 +241,11 @@ var _ = Describe("Podman pod start", func() { // Create a pod with --infra-conmon-pid. session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--infra-conmon-pidfile", tmpFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "start", podName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) // infra readFirstLine := func(path string) string { diff --git a/test/e2e/pod_stats_test.go b/test/e2e/pod_stats_test.go index 2064cdc9f..46043b16d 100644 --- a/test/e2e/pod_stats_test.go +++ b/test/e2e/pod_stats_test.go @@ -40,13 +40,13 @@ var _ = Describe("Podman pod stats", func() { It("podman stats should run with no pods", func() { session := podmanTest.Podman([]string{"pod", "stats", "--no-stream"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman stats with a bogus pod", func() { session := podmanTest.Podman([]string{"pod", "stats", "foobar"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman stats on a specific running pod", func() { @@ -55,15 +55,15 @@ var _ = Describe("Podman pod stats", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) stats := podmanTest.Podman([]string{"pod", "stats", "--no-stream", podid}) stats.WaitWithDefaultTimeout() - Expect(stats.ExitCode()).To(Equal(0)) + Expect(stats).Should(Exit(0)) }) It("podman stats on a specific running pod with shortID", func() { @@ -72,15 +72,15 @@ var _ = Describe("Podman pod stats", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) stats := podmanTest.Podman([]string{"pod", "stats", "--no-stream", podid[:5]}) stats.WaitWithDefaultTimeout() - Expect(stats.ExitCode()).To(Equal(0)) + Expect(stats).Should(Exit(0)) }) It("podman stats on a specific running pod with name", func() { @@ -89,15 +89,15 @@ var _ = Describe("Podman pod stats", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) stats := podmanTest.Podman([]string{"pod", "stats", "--no-stream", "test"}) stats.WaitWithDefaultTimeout() - Expect(stats.ExitCode()).To(Equal(0)) + Expect(stats).Should(Exit(0)) }) It("podman stats on running pods", func() { @@ -106,15 +106,15 @@ var _ = Describe("Podman pod stats", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) stats := podmanTest.Podman([]string{"pod", "stats", "--no-stream"}) stats.WaitWithDefaultTimeout() - Expect(stats.ExitCode()).To(Equal(0)) + Expect(stats).Should(Exit(0)) }) It("podman stats on all pods", func() { @@ -123,15 +123,15 @@ var _ = Describe("Podman pod stats", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) stats := podmanTest.Podman([]string{"pod", "stats", "--no-stream", "-a"}) stats.WaitWithDefaultTimeout() - Expect(stats.ExitCode()).To(Equal(0)) + Expect(stats).Should(Exit(0)) }) It("podman stats with json output", func() { @@ -140,15 +140,15 @@ var _ = Describe("Podman pod stats", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) stats := podmanTest.Podman([]string{"pod", "stats", "--format", "json", "--no-stream", "-a"}) stats.WaitWithDefaultTimeout() - Expect(stats.ExitCode()).To(Equal(0)) + Expect(stats).Should(Exit(0)) Expect(stats.IsJSONOutputValid()).To(BeTrue()) }) It("podman stats with GO template", func() { @@ -157,7 +157,7 @@ var _ = Describe("Podman pod stats", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) stats := podmanTest.Podman([]string{"pod", "stats", "-a", "--no-reset", "--no-stream", "--format", "table {{.CID}} {{.Pod}} {{.Mem}} {{.MemUsage}} {{.CPU}} {{.NetIO}} {{.BlockIO}} {{.PIDS}} {{.Pod}}"}) stats.WaitWithDefaultTimeout() Expect(stats).To(Exit(0)) @@ -169,7 +169,7 @@ var _ = Describe("Podman pod stats", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) stats := podmanTest.Podman([]string{"pod", "stats", "-a", "--no-reset", "--no-stream", "--format", "\"table {{.ID}} \""}) stats.WaitWithDefaultTimeout() Expect(stats).To(ExitWithError()) @@ -180,15 +180,15 @@ var _ = Describe("Podman pod stats", func() { podName := "testPod" podCreate := podmanTest.Podman([]string{"pod", "create", "--net=host", "--name", podName}) podCreate.WaitWithDefaultTimeout() - Expect(podCreate.ExitCode()).To(Equal(0)) + Expect(podCreate).Should(Exit(0)) ctrRun := podmanTest.Podman([]string{"run", "-d", "--pod", podName, ALPINE, "top"}) ctrRun.WaitWithDefaultTimeout() - Expect(ctrRun.ExitCode()).To(Equal(0)) + Expect(ctrRun).Should(Exit(0)) stats := podmanTest.Podman([]string{"pod", "stats", "--format", "json", "--no-stream", podName}) stats.WaitWithDefaultTimeout() - Expect(stats.ExitCode()).To(Equal(0)) + Expect(stats).Should(Exit(0)) Expect(stats.IsJSONOutputValid()).To(BeTrue()) }) }) diff --git a/test/e2e/pod_stop_test.go b/test/e2e/pod_stop_test.go index 45e2f86a6..27ac7d965 100644 --- a/test/e2e/pod_stop_test.go +++ b/test/e2e/pod_stop_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman pod stop", func() { @@ -36,14 +37,14 @@ var _ = Describe("Podman pod stop", func() { It("podman pod stop bogus pod", func() { session := podmanTest.Podman([]string{"pod", "stop", "123"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman pod stop --ignore bogus pod", func() { session := podmanTest.Podman([]string{"pod", "stop", "--ignore", "123"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman stop bogus pod and a running pod", func() { @@ -52,11 +53,11 @@ var _ = Describe("Podman pod stop", func() { session := podmanTest.RunTopContainerInPod("test1", podid1) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "stop", "bogus", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman stop --ignore bogus pod and a running pod", func() { @@ -66,15 +67,15 @@ var _ = Describe("Podman pod stop", func() { session := podmanTest.RunTopContainerInPod("test1", podid1) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "stop", "--ignore", "bogus", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "stop", "--ignore", "test1", "bogus"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pod stop single empty pod", func() { @@ -83,7 +84,7 @@ var _ = Describe("Podman pod stop", func() { session := podmanTest.Podman([]string{"pod", "stop", podid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pod stop single pod by name", func() { @@ -92,11 +93,11 @@ var _ = Describe("Podman pod stop", func() { session := podmanTest.RunTopContainerInPod("", "foobar99") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "stop", "foobar99"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -106,18 +107,18 @@ var _ = Describe("Podman pod stop", func() { session := podmanTest.RunTopContainerInPod("", "foobar99") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec2, podid2 := podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}}) Expect(ec2).To(Equal(0)) session = podmanTest.RunTopContainerInPod("", "foobar100") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "stop", podid1, podid2}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -127,18 +128,18 @@ var _ = Describe("Podman pod stop", func() { session := podmanTest.RunTopContainerInPod("", "foobar99") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}}) Expect(ec).To(Equal(0)) session = podmanTest.RunTopContainerInPod("", "foobar100") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "stop", "--all"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -148,14 +149,14 @@ var _ = Describe("Podman pod stop", func() { session := podmanTest.RunTopContainerInPod("", "foobar99") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}}) Expect(ec).To(Equal(0)) session = podmanTest.RunTopContainerInPod("", "foobar100") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podid := "--latest" if IsRemote() { @@ -163,7 +164,7 @@ var _ = Describe("Podman pod stop", func() { } session = podmanTest.Podman([]string{"pod", "stop", podid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) }) @@ -173,11 +174,11 @@ var _ = Describe("Podman pod stop", func() { session := podmanTest.RunTopContainerInPod("", "foobar99") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "stop", podid1, "doesnotexist"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman pod start/stop single pod via --pod-id-file", func() { @@ -191,21 +192,21 @@ var _ = Describe("Podman pod stop", func() { // Create a pod with --pod-id-file. session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--pod-id-file", tmpFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Create container inside the pod. session = podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "start", "--pod-id-file", tmpFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) // infra+top session = podmanTest.Podman([]string{"pod", "stop", "--pod-id-file", tmpFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) @@ -221,12 +222,12 @@ var _ = Describe("Podman pod stop", func() { // Create a pod with --pod-id-file. session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--pod-id-file", tmpFile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Create container inside the pod. session = podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Append the id files along with the command. podIDFiles = append(podIDFiles, "--pod-id-file") @@ -237,14 +238,14 @@ var _ = Describe("Podman pod stop", func() { cmd = append(cmd, podIDFiles...) session := podmanTest.Podman(cmd) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(20)) // 10*(infra+top) cmd = []string{"pod", "stop"} cmd = append(cmd, podIDFiles...) session = podmanTest.Podman(cmd) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) }) diff --git a/test/e2e/pod_top_test.go b/test/e2e/pod_top_test.go index 9d9c138c4..253d4adf5 100644 --- a/test/e2e/pod_top_test.go +++ b/test/e2e/pod_top_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman top", func() { @@ -37,13 +38,13 @@ var _ = Describe("Podman top", func() { It("podman pod top without pod name or id", func() { result := podmanTest.Podman([]string{"pod", "top"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) }) It("podman pod top on bogus pod", func() { result := podmanTest.Podman([]string{"pod", "top", "1234"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) }) It("podman pod top on non-running pod", func() { @@ -52,7 +53,7 @@ var _ = Describe("Podman top", func() { result := podmanTest.Podman([]string{"top", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) }) It("podman pod top on pod", func() { @@ -61,14 +62,14 @@ var _ = Describe("Podman top", func() { session := podmanTest.Podman([]string{"run", "-d", "--pod", podid, ALPINE, "top", "-d", "2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if !IsRemote() { podid = "-l" } result := podmanTest.Podman([]string{"pod", "top", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1)) }) @@ -78,11 +79,11 @@ var _ = Describe("Podman top", func() { session := podmanTest.Podman([]string{"run", "-d", "--pod", podid, ALPINE, "top", "-d", "2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "top", podid, "pid", "%C", "args"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1)) }) @@ -92,7 +93,7 @@ var _ = Describe("Podman top", func() { session := podmanTest.Podman([]string{"run", "-d", "--pod", podid, ALPINE, "top", "-d", "2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // We need to pass -eo to force executing ps in the Alpine container. // Alpines stripped down ps(1) is accepting any kind of weird input in @@ -100,7 +101,7 @@ var _ = Describe("Podman top", func() { // the wrong input and still print the -ef output instead. result := podmanTest.Podman([]string{"pod", "top", podid, "-eo", "invalid"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) }) It("podman pod top on pod with containers in same pid namespace", func() { @@ -109,16 +110,16 @@ var _ = Describe("Podman top", func() { session := podmanTest.Podman([]string{"run", "-d", "--pod", podid, ALPINE, "top", "-d", "2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"run", "-d", "--pod", podid, "--pid", fmt.Sprintf("container:%s", cid), ALPINE, "top", "-d", "2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"pod", "top", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(Equal(3)) }) @@ -128,11 +129,11 @@ var _ = Describe("Podman top", func() { session := podmanTest.Podman([]string{"run", "-d", "--pod", podid, ALPINE, "top", "-d", "2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "-d", "--pod", podid, ALPINE, "top", "-d", "2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) for i := 0; i < 10; i++ { fmt.Println("Waiting for containers to be running .... ") @@ -143,7 +144,7 @@ var _ = Describe("Podman top", func() { } result := podmanTest.Podman([]string{"pod", "top", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(Equal(3)) }) }) diff --git a/test/e2e/port_test.go b/test/e2e/port_test.go index e9bbc2adc..e5c7576ae 100644 --- a/test/e2e/port_test.go +++ b/test/e2e/port_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman port", func() { @@ -48,7 +49,7 @@ var _ = Describe("Podman port", func() { It("podman port -l nginx", func() { session, cid := podmanTest.RunNginxWithHealthCheck("test1") - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if err := podmanTest.RunHealthCheck(cid); err != nil { Fail(err.Error()) @@ -59,14 +60,14 @@ var _ = Describe("Podman port", func() { } result := podmanTest.Podman([]string{"port", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) port := strings.Split(result.OutputToStringArray()[0], ":")[1] Expect(result.LineInOutputStartsWith(fmt.Sprintf("80/tcp -> 0.0.0.0:%s", port))).To(BeTrue()) }) It("podman container port -l nginx", func() { session, cid := podmanTest.RunNginxWithHealthCheck("") - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if err := podmanTest.RunHealthCheck(cid); err != nil { Fail(err.Error()) @@ -77,14 +78,14 @@ var _ = Describe("Podman port", func() { } result := podmanTest.Podman([]string{"container", "port", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) port := strings.Split(result.OutputToStringArray()[0], ":")[1] Expect(result.LineInOutputStartsWith(fmt.Sprintf("80/tcp -> 0.0.0.0:%s", port))).To(BeTrue()) }) It("podman port -l port nginx", func() { session, cid := podmanTest.RunNginxWithHealthCheck("") - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if err := podmanTest.RunHealthCheck(cid); err != nil { Fail(err.Error()) @@ -95,14 +96,14 @@ var _ = Describe("Podman port", func() { } result := podmanTest.Podman([]string{"port", cid, "80"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) port := strings.Split(result.OutputToStringArray()[0], ":")[1] Expect(result.LineInOutputStartsWith(fmt.Sprintf("0.0.0.0:%s", port))).To(BeTrue()) }) It("podman port -a nginx", func() { session, cid := podmanTest.RunNginxWithHealthCheck("") - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if err := podmanTest.RunHealthCheck(cid); err != nil { Fail(err.Error()) @@ -110,12 +111,12 @@ var _ = Describe("Podman port", func() { result := podmanTest.Podman([]string{"port", "-a"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman port nginx by name", func() { session, cid := podmanTest.RunNginxWithHealthCheck("portcheck") - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if err := podmanTest.RunHealthCheck(cid); err != nil { Fail(err.Error()) @@ -123,7 +124,7 @@ var _ = Describe("Podman port", func() { result := podmanTest.Podman([]string{"port", "portcheck"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result.LineInOutputStartsWith("80/tcp -> 0.0.0.0:") }) @@ -136,18 +137,18 @@ var _ = Describe("Podman port", func() { setup := podmanTest.Podman([]string{"run", "--name", "test", "-dt", "-p", "5000:5000", "-p", "5001:5001", ALPINE, "top"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(BeZero()) + Expect(setup).Should(Exit(0)) // Check that the first port was honored result1 := podmanTest.Podman([]string{"port", "test", "5000"}) result1.WaitWithDefaultTimeout() - Expect(result1.ExitCode()).To(BeZero()) + Expect(result1).Should(Exit(0)) Expect(result1.LineInOutputStartsWith("0.0.0.0:5000")).To(BeTrue()) // Check that the second port was honored result2 := podmanTest.Podman([]string{"port", "test", "5001"}) result2.WaitWithDefaultTimeout() - Expect(result2.ExitCode()).To(BeZero()) + Expect(result2).Should(Exit(0)) Expect(result2.LineInOutputStartsWith("0.0.0.0:5001")).To(BeTrue()) }) }) diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go index 419748adb..ff70a8cf4 100644 --- a/test/e2e/prune_test.go +++ b/test/e2e/prune_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var pruneImage = fmt.Sprintf(` @@ -15,6 +16,11 @@ LABEL RUN podman --version RUN apk update RUN apk add bash`, ALPINE) +var emptyPruneImage = ` +FROM scratch +ENV test1=test1 +ENV test2=test2` + var _ = Describe("Podman prune", func() { var ( tempdir string @@ -42,20 +48,20 @@ var _ = Describe("Podman prune", func() { It("podman container prune containers", func() { top := podmanTest.RunTopContainer("") top.WaitWithDefaultTimeout() - Expect(top.ExitCode()).To(Equal(0)) + Expect(top).Should(Exit(0)) top = podmanTest.RunTopContainer("") top.WaitWithDefaultTimeout() - Expect(top.ExitCode()).To(Equal(0)) + Expect(top).Should(Exit(0)) cid := top.OutputToString() stop := podmanTest.Podman([]string{"stop", cid}) stop.WaitWithDefaultTimeout() - Expect(stop.ExitCode()).To(Equal(0)) + Expect(stop).Should(Exit(0)) prune := podmanTest.Podman([]string{"container", "prune", "-f"}) prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(Equal(0)) + Expect(prune).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) }) @@ -63,11 +69,11 @@ var _ = Describe("Podman prune", func() { It("podman container prune after create containers", func() { create := podmanTest.Podman([]string{"create", "--name", "test", BB}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) prune := podmanTest.Podman([]string{"container", "prune", "-f"}) prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(Equal(0)) + Expect(prune).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) }) @@ -75,15 +81,15 @@ var _ = Describe("Podman prune", func() { It("podman container prune after create & init containers", func() { create := podmanTest.Podman([]string{"create", "--name", "test", BB}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) init := podmanTest.Podman([]string{"init", "test"}) init.WaitWithDefaultTimeout() - Expect(init.ExitCode()).To(Equal(0)) + Expect(init).Should(Exit(0)) prune := podmanTest.Podman([]string{"container", "prune", "-f"}) prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(Equal(0)) + Expect(prune).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) }) @@ -91,7 +97,7 @@ var _ = Describe("Podman prune", func() { It("podman image prune - remove only dangling images", func() { session := podmanTest.Podman([]string{"images", "-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) hasNone, _ := session.GrepString("<none>") Expect(hasNone).To(BeFalse()) numImages := len(session.OutputToStringArray()) @@ -99,22 +105,26 @@ var _ = Describe("Podman prune", func() { // Since there's no dangling image, none should be removed. session = podmanTest.Podman([]string{"image", "prune", "-f"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(0)) // Let's be extra sure that the same number of images is // reported. session = podmanTest.Podman([]string{"images", "-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(numImages)) - // Now build a new image with dangling intermediate images. + // Now build an image and untag it. The (intermediate) images + // should be removed recursively during pruning. podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true") + session = podmanTest.Podman([]string{"untag", "alpine_bash:latest"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"images", "-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) hasNone, _ = session.GrepString("<none>") Expect(hasNone).To(BeTrue()) // ! we have dangling ones numImages = len(session.OutputToStringArray()) @@ -123,7 +133,7 @@ var _ = Describe("Podman prune", func() { // remove them. session = podmanTest.Podman([]string{"image", "prune", "-f"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) numPrunedImages := len(session.OutputToStringArray()) Expect(numPrunedImages >= 1).To(BeTrue()) @@ -131,30 +141,37 @@ var _ = Describe("Podman prune", func() { // been removed. session = podmanTest.Podman([]string{"images", "-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(numImages - numPrunedImages)) }) - It("podman image prune skip cache images", func() { - podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true") + It("podman image prune - handle empty images", func() { + // As shown in #10832, empty images were not treated correctly + // in Podman. + podmanTest.BuildImage(emptyPruneImage, "empty:scratch", "true") - none := podmanTest.Podman([]string{"images", "-a"}) - none.WaitWithDefaultTimeout() - Expect(none.ExitCode()).To(Equal(0)) - hasNone, _ := none.GrepString("<none>") + session := podmanTest.Podman([]string{"images", "-a"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + hasNone, _ := session.GrepString("<none>") Expect(hasNone).To(BeTrue()) - prune := podmanTest.Podman([]string{"image", "prune", "-f"}) - prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(Equal(0)) + // Nothing will be pruned. + session = podmanTest.Podman([]string{"image", "prune", "-f"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(0)) - after := podmanTest.Podman([]string{"images", "-a"}) - after.WaitWithDefaultTimeout() - Expect(none.ExitCode()).To(Equal(0)) - // Check if all "dangling" images were pruned. - hasNoneAfter, _ := after.GrepString("<none>") - Expect(hasNoneAfter).To(BeFalse()) - Expect(len(after.OutputToStringArray()) > 1).To(BeTrue()) + // Now the image will be untagged, and its parent images will + // be removed recursively. + session = podmanTest.Podman([]string{"untag", "empty:scratch"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"image", "prune", "-f"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(2)) }) It("podman image prune dangling images", func() { @@ -162,18 +179,18 @@ var _ = Describe("Podman prune", func() { podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true") none := podmanTest.Podman([]string{"images", "-a"}) none.WaitWithDefaultTimeout() - Expect(none.ExitCode()).To(Equal(0)) + Expect(none).Should(Exit(0)) hasNone, result := none.GrepString("<none>") Expect(len(result)).To(Equal(2)) Expect(hasNone).To(BeTrue()) prune := podmanTest.Podman([]string{"image", "prune", "-f"}) prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(Equal(0)) + Expect(prune).Should(Exit(0)) after := podmanTest.Podman([]string{"images", "-a"}) after.WaitWithDefaultTimeout() - Expect(none.ExitCode()).To(Equal(0)) + Expect(none).Should(Exit(0)) hasNoneAfter, result := none.GrepString("<none>") Expect(hasNoneAfter).To(BeTrue()) Expect(len(after.OutputToStringArray()) > 1).To(BeTrue()) @@ -186,15 +203,15 @@ var _ = Describe("Podman prune", func() { images := podmanTest.Podman([]string{"images", "-a"}) images.WaitWithDefaultTimeout() - Expect(images.ExitCode()).To(Equal(0)) + Expect(images).Should(Exit(0)) prune := podmanTest.Podman([]string{"image", "prune", "-af"}) prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(Equal(0)) + Expect(prune).Should(Exit(0)) images = podmanTest.Podman([]string{"images", "-aq"}) images.WaitWithDefaultTimeout() - Expect(images.ExitCode()).To(Equal(0)) + Expect(images).Should(Exit(0)) // all images are unused, so they all should be deleted! Expect(len(images.OutputToStringArray())).To(Equal(len(CACHE_IMAGES))) }) @@ -204,7 +221,7 @@ var _ = Describe("Podman prune", func() { podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true") prune := podmanTest.Podman([]string{"system", "prune", "-a", "--force"}) prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(Equal(0)) + Expect(prune).Should(Exit(0)) images := podmanTest.Podman([]string{"images", "-aq"}) images.WaitWithDefaultTimeout() @@ -215,63 +232,63 @@ var _ = Describe("Podman prune", func() { It("podman system prune pods", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podid1 := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podid1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "stop", podid1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) pods := podmanTest.Podman([]string{"pod", "ps"}) pods.WaitWithDefaultTimeout() - Expect(pods.ExitCode()).To(Equal(0)) + Expect(pods).Should(Exit(0)) Expect(len(pods.OutputToStringArray())).To(Equal(3)) prune := podmanTest.Podman([]string{"system", "prune", "-f"}) prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(Equal(0)) + Expect(prune).Should(Exit(0)) pods = podmanTest.Podman([]string{"pod", "ps"}) pods.WaitWithDefaultTimeout() - Expect(pods.ExitCode()).To(Equal(0)) + Expect(pods).Should(Exit(0)) Expect(len(pods.OutputToStringArray())).To(Equal(2)) }) It("podman system prune - pod,container stopped", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podid1 := session.OutputToString() // Start and stop a pod to get it in exited state. session = podmanTest.Podman([]string{"pod", "start", podid1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "stop", podid1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Create a container. This container should be pruned. create := podmanTest.Podman([]string{"create", "--name", "test", BB}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) prune := podmanTest.Podman([]string{"system", "prune", "-f"}) prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(Equal(0)) + Expect(prune).Should(Exit(0)) pods := podmanTest.Podman([]string{"pod", "ps"}) pods.WaitWithDefaultTimeout() - Expect(pods.ExitCode()).To(Equal(0)) + Expect(pods).Should(Exit(0)) Expect(podmanTest.NumberOfPods()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -281,26 +298,26 @@ var _ = Describe("Podman prune", func() { // Start and stop a pod to get it in exited state. session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podid1 := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podid1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "stop", podid1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Start a pod and leave it running session = podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podid2 := session.OutputToString() session = podmanTest.Podman([]string{"pod", "start", podid2}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Number of pod should be 2. One exited one running. Expect(podmanTest.NumberOfPods()).To(Equal(2)) @@ -321,25 +338,25 @@ var _ = Describe("Podman prune", func() { // Adding unused volume should be pruned session = podmanTest.Podman([]string{"volume", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "-v", "myvol:/myvol", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(3)) session = podmanTest.Podman([]string{"system", "prune", "--force", "--volumes"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Volumes should be pruned. session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(0)) // One Pod should not be pruned as it was running @@ -357,35 +374,35 @@ var _ = Describe("Podman prune", func() { It("podman system prune - with dangling images true", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podid1 := session.OutputToString() // Start and stop a pod to get it in exited state. session = podmanTest.Podman([]string{"pod", "start", podid1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pod", "stop", podid1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Create a container. This container should be pruned. create := podmanTest.Podman([]string{"create", "--name", "test", BB}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) // Adding unused volume should not be pruned as volumes not set session = podmanTest.Podman([]string{"volume", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) prune := podmanTest.Podman([]string{"system", "prune", "-f", "-a"}) prune.WaitWithDefaultTimeout() - Expect(prune.ExitCode()).To(Equal(0)) + Expect(prune).Should(Exit(0)) pods := podmanTest.Podman([]string{"pod", "ps"}) pods.WaitWithDefaultTimeout() - Expect(pods.ExitCode()).To(Equal(0)) + Expect(pods).Should(Exit(0)) Expect(podmanTest.NumberOfPods()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -393,7 +410,7 @@ var _ = Describe("Podman prune", func() { // Volumes should not be pruned session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) images := podmanTest.Podman([]string{"images", "-aq"}) @@ -405,58 +422,58 @@ var _ = Describe("Podman prune", func() { It("podman system prune --volumes --filter", func() { session := podmanTest.Podman([]string{"volume", "create", "--label", "label1=value1", "myvol1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create", "--label", "sharedlabel1=slv1", "myvol2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create", "--label", "sharedlabel1=slv2", "myvol3"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create", "--label", "sharedlabel1", "myvol4"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "-v", "myvol5:/myvol5", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "-v", "myvol6:/myvol6", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(7)) session = podmanTest.Podman([]string{"system", "prune", "--force", "--volumes", "--filter", "label=label1=value1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(6)) session = podmanTest.Podman([]string{"system", "prune", "--force", "--volumes", "--filter", "label=sharedlabel1=slv1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(5)) session = podmanTest.Podman([]string{"system", "prune", "--force", "--volumes", "--filter", "label=sharedlabel1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(3)) podmanTest.Cleanup() diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index 2d7d84005..e27ff27a4 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -43,23 +43,23 @@ var _ = Describe("Podman ps", func() { It("podman ps no containers", func() { session := podmanTest.Podman([]string{"ps"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman container ps no containers", func() { session := podmanTest.Podman([]string{"container", "ps"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman ps default", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"ps"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0)) }) @@ -69,7 +69,7 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"ps", "-a"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0)) }) @@ -79,12 +79,12 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"container", "list", "-a"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0)) result = podmanTest.Podman([]string{"container", "ls", "-a"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0)) }) @@ -94,7 +94,7 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"ps", "-a", "--size"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0)) }) @@ -104,7 +104,7 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"ps", "-a", "-q"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0)) Expect(fullCid).To(ContainSubstring(result.OutputToStringArray()[0])) }) @@ -118,7 +118,7 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"ps", "-q", "--latest"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(Equal(1)) }) @@ -129,11 +129,11 @@ var _ = Describe("Podman ps", func() { // well. session := podmanTest.Podman([]string{"create", "alpine", "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"ps", "--last", "2"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(Equal(2)) // 1 container _, ec, _ := podmanTest.RunLsContainer("test1") @@ -147,17 +147,17 @@ var _ = Describe("Podman ps", func() { result = podmanTest.Podman([]string{"ps", "--last", "2"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(Equal(3)) // 2 containers result = podmanTest.Podman([]string{"ps", "--last", "3"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(Equal(4)) // 3 containers result = podmanTest.Podman([]string{"ps", "--last", "100"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(Equal(5)) // 4 containers (3 running + 1 created) }) @@ -167,7 +167,7 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"ps", "-aq", "--no-trunc"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0)) Expect(fullCid).To(Equal(result.OutputToStringArray()[0])) }) @@ -178,7 +178,7 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"ps", "-a", "--namespace"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).Should(BeNumerically(">", 0)) }) @@ -189,7 +189,7 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"ps", "-a", "--namespace", "--format", "{{with .Namespaces}}{{.Cgroup}}:{{.IPC}}:{{.MNT}}:{{.NET}}:{{.PIDNS}}:{{.User}}:{{.UTS}}{{end}}"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) // it must contains `::` when some ns is null. If it works normally, it should be "$num1:$num2:$num3" Expect(result.OutputToString()).To(Not(ContainSubstring(`::`))) }) @@ -197,7 +197,7 @@ var _ = Describe("Podman ps", func() { It("podman ps with no containers is valid json format", func() { result := podmanTest.Podman([]string{"ps", "--format", "json"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.IsJSONOutputValid()).To(BeTrue()) }) @@ -207,18 +207,18 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"ps", "-a", "--ns", "--format", "json"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.IsJSONOutputValid()).To(BeTrue()) }) It("podman ps json format Created field is int64", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"ps", "--format", "json"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) // Make sure Created field is an int64 created, err := result.jq(".[0].Created") @@ -233,7 +233,7 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"ps", "-a", "--format", "json"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.IsJSONOutputValid()).To(BeTrue()) // must contain "Status" match, StatusLine := result.GrepString(`Status`) @@ -261,19 +261,19 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"ps", "-q", "--no-trunc", "-a", "--filter", "ancestor=quay.io/libpod/alpine:latest"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal(cid)) // Query just by image name, without :latest tag result = podmanTest.Podman([]string{"ps", "-q", "--no-trunc", "-a", "--filter", "ancestor=quay.io/libpod/alpine"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal(cid)) // Query by truncated image name should not match ( should return empty output ) result = podmanTest.Podman([]string{"ps", "-q", "--no-trunc", "-a", "--filter", "ancestor=quay.io/libpod/alpi"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal("")) }) @@ -283,34 +283,34 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"ps", "-a", "--filter", fmt.Sprintf("id=%s", fullCid)}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman ps id filter flag", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) fullCid := session.OutputToString() result := podmanTest.Podman([]string{"ps", "-aq", "--no-trunc", "--filter", "status=running"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToStringArray()[0]).To(Equal(fullCid)) }) It("podman ps multiple filters", func() { session := podmanTest.Podman([]string{"run", "-d", "--name", "test1", "--label", "key1=value1", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) fullCid := session.OutputToString() session2 := podmanTest.Podman([]string{"run", "-d", "--name", "test2", "--label", "key1=value1", ALPINE, "top"}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) result := podmanTest.Podman([]string{"ps", "-aq", "--no-trunc", "--filter", "name=test1", "--filter", "label=key1=value1"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) output := result.OutputToStringArray() Expect(len(output)).To(Equal(1)) @@ -320,15 +320,15 @@ var _ = Describe("Podman ps", func() { It("podman ps filter by exited does not need all", func() { ctr := podmanTest.Podman([]string{"run", "-t", "-i", ALPINE, "ls", "/"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(Equal(0)) + Expect(ctr).Should(Exit(0)) psAll := podmanTest.Podman([]string{"ps", "-aq", "--no-trunc"}) psAll.WaitWithDefaultTimeout() - Expect(psAll.ExitCode()).To(Equal(0)) + Expect(psAll).Should(Exit(0)) psFilter := podmanTest.Podman([]string{"ps", "--no-trunc", "--quiet", "--filter", "status=exited"}) psFilter.WaitWithDefaultTimeout() - Expect(psFilter.ExitCode()).To(Equal(0)) + Expect(psFilter).Should(Exit(0)) Expect(psAll.OutputToString()).To(Equal(psFilter.OutputToString())) }) @@ -337,11 +337,11 @@ var _ = Describe("Podman ps", func() { ctrName := "aContainerName" ctr := podmanTest.Podman([]string{"create", "--name", ctrName, "-t", "-i", ALPINE, "ls", "/"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(Equal(0)) + Expect(ctr).Should(Exit(0)) psFilter := podmanTest.Podman([]string{"ps", "--no-trunc", "--quiet", "--format", "{{.Names}}", "--filter", fmt.Sprintf("name=%s", ctrName)}) psFilter.WaitWithDefaultTimeout() - Expect(psFilter.ExitCode()).To(Equal(0)) + Expect(psFilter).Should(Exit(0)) Expect(strings.Contains(psFilter.OutputToString(), ctrName)).To(BeFalse()) }) @@ -359,30 +359,30 @@ var _ = Describe("Podman ps", func() { It("podman --format by size", func() { session := podmanTest.Podman([]string{"create", BB, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "-t", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"ps", "-a", "--format", "{{.Size}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.ErrorToString()).To(ContainSubstring("Size format requires --size option")) }) It("podman --sort by size", func() { session := podmanTest.Podman([]string{"create", BB, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "-t", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"ps", "-a", "-s", "--sort=size", "--format", "{{.Size}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) sortedArr := session.OutputToStringArray() @@ -409,16 +409,16 @@ var _ = Describe("Podman ps", func() { It("podman --sort by command", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "-d", ALPINE, "pwd"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"ps", "-a", "--sort=command", "--format", "{{.Command}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) sortedArr := session.OutputToStringArray() @@ -432,16 +432,16 @@ var _ = Describe("Podman ps", func() { session := podmanTest.RunTopContainerInPod("", podid) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"ps", "--no-trunc"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(ContainSubstring(podid))) session = podmanTest.Podman([]string{"ps", "--pod", "--no-trunc"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(podid)) }) @@ -452,14 +452,14 @@ var _ = Describe("Podman ps", func() { session := podmanTest.RunTopContainerInPod("", podName) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // "--no-trunc" must be given. If not it will trunc the pod ID // in the output and you will have to trunc it in the test too. session = podmanTest.Podman([]string{"ps", "--pod", "--no-trunc"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(output).To(ContainSubstring(podid)) @@ -469,7 +469,7 @@ var _ = Describe("Podman ps", func() { It("podman ps test with single port range", func() { session := podmanTest.Podman([]string{"run", "-dt", "-p", "2000-2006:2000-2006", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"ps", "--format", "{{.Ports}}"}) session.WaitWithDefaultTimeout() @@ -481,7 +481,7 @@ var _ = Describe("Podman ps", func() { "run", "-p", "1000-2000:2000-3000", "-p", "1999-2999:3001-4001", ALPINE, }) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) Expect(session.ErrorToString()).To(ContainSubstring("conflicting port mappings for host port 1999")) }) @@ -496,7 +496,7 @@ var _ = Describe("Podman ps", func() { ALPINE, "top"}, ) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"ps", "--format", "{{.Ports}}"}) session.WaitWithDefaultTimeout() @@ -508,35 +508,35 @@ var _ = Describe("Podman ps", func() { It("podman ps sync flag", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) fullCid := session.OutputToString() result := podmanTest.Podman([]string{"ps", "-q", "--no-trunc", "--sync"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToStringArray()[0]).To(Equal(fullCid)) }) It("podman ps filter name regexp", func() { session := podmanTest.Podman([]string{"run", "-d", "--name", "test1", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) fullCid := session.OutputToString() session2 := podmanTest.Podman([]string{"run", "-d", "--name", "test11", ALPINE, "top"}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) result := podmanTest.Podman([]string{"ps", "-aq", "--no-trunc", "--filter", "name=test1"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) output := result.OutputToStringArray() Expect(len(output)).To(Equal(2)) result = podmanTest.Podman([]string{"ps", "-aq", "--no-trunc", "--filter", "name=test1$"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) output = result.OutputToStringArray() Expect(len(output)).To(Equal(1)) @@ -547,11 +547,11 @@ var _ = Describe("Podman ps", func() { ctrName := "testCtr" session := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"ps", "-q", "-a", "--format", "{{ .Names }}"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) output := result.OutputToStringArray() Expect(len(output)).To(Equal(1)) @@ -562,23 +562,23 @@ var _ = Describe("Podman ps", func() { podName := "testPod" pod := podmanTest.Podman([]string{"pod", "create", "-p", "8080:80", "--name", podName}) pod.WaitWithDefaultTimeout() - Expect(pod.ExitCode()).To(Equal(0)) + Expect(pod).Should(Exit(0)) ctrName := "testCtr" session := podmanTest.Podman([]string{"run", "--name", ctrName, "-dt", "--pod", podName, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ps := podmanTest.Podman([]string{"ps", "--filter", fmt.Sprintf("name=%s", ctrName), "--format", "{{.Ports}}"}) ps.WaitWithDefaultTimeout() - Expect(ps.ExitCode()).To(Equal(0)) + Expect(ps).Should(Exit(0)) Expect(ps.OutputToString()).To(ContainSubstring("0.0.0.0:8080->80/tcp")) }) It("podman ps truncate long create command", func() { session := podmanTest.Podman([]string{"run", ALPINE, "echo", "very", "long", "create", "command"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"ps", "-a"}) session.WaitWithDefaultTimeout() @@ -590,7 +590,7 @@ var _ = Describe("Podman ps", func() { result := podmanTest.Podman([]string{"ps", "-a", "--format", "{{.RunningFor}}"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring("ago")) }) @@ -598,26 +598,26 @@ var _ = Describe("Podman ps", func() { session := podmanTest.Podman([]string{"run", "-d", "--name", "test1", "--label", "foo=1", "--label", "bar=2", "--volume", "volume1:/test", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid1 := session.OutputToString() session = podmanTest.Podman([]string{"run", "--name", "test2", "--label", "foo=1", ALPINE, "ls", "/fail"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) session = podmanTest.Podman([]string{"create", "--name", "test3", ALPINE, cid1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--name", "test4", "--volume", "volume1:/test1", "--volume", "/:/test2", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"ps", "--all", "--filter", "name=test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(5)) Expect(session.LineInOutputContains("test1")).To(BeTrue()) Expect(session.LineInOutputContains("test2")).To(BeTrue()) @@ -626,7 +626,7 @@ var _ = Describe("Podman ps", func() { session = podmanTest.Podman([]string{"ps", "--all", "--filter", "name=test1", "--filter", "name=test2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(3)) Expect(session.LineInOutputContains("test1")).To(BeTrue()) Expect(session.LineInOutputContains("test2")).To(BeTrue()) @@ -634,19 +634,19 @@ var _ = Describe("Podman ps", func() { // check container id matches with regex session = podmanTest.Podman([]string{"ps", "--all", "--filter", "id=" + cid1[:40], "--filter", "id=" + cid1 + "$"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(session.LineInOutputContains("test1")).To(BeTrue()) session = podmanTest.Podman([]string{"ps", "--filter", "status=created"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(session.LineInOutputContains("test3")).To(BeTrue()) session = podmanTest.Podman([]string{"ps", "--filter", "status=created", "--filter", "status=exited"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(4)) Expect(session.LineInOutputContains("test2")).To(BeTrue()) Expect(session.LineInOutputContains("test3")).To(BeTrue()) @@ -654,63 +654,63 @@ var _ = Describe("Podman ps", func() { session = podmanTest.Podman([]string{"ps", "--all", "--filter", "label=foo=1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(3)) Expect(session.LineInOutputContains("test1")).To(BeTrue()) Expect(session.LineInOutputContains("test2")).To(BeTrue()) session = podmanTest.Podman([]string{"ps", "--filter", "label=foo=1", "--filter", "status=exited"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(session.LineInOutputContains("test2")).To(BeTrue()) session = podmanTest.Podman([]string{"ps", "--all", "--filter", "label=foo=1", "--filter", "label=non=1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(1)) session = podmanTest.Podman([]string{"ps", "--all", "--filter", "label=foo=1", "--filter", "label=bar=2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(session.LineInOutputContains("test1")).To(BeTrue()) session = podmanTest.Podman([]string{"ps", "--all", "--filter", "exited=1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(session.LineInOutputContains("test2")).To(BeTrue()) session = podmanTest.Podman([]string{"ps", "--all", "--filter", "exited=1", "--filter", "exited=0"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(3)) Expect(session.LineInOutputContains("test2")).To(BeTrue()) Expect(session.LineInOutputContains("test4")).To(BeTrue()) session = podmanTest.Podman([]string{"ps", "--all", "--filter", "volume=volume1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(3)) Expect(session.LineInOutputContains("test1")).To(BeTrue()) Expect(session.LineInOutputContains("test4")).To(BeTrue()) session = podmanTest.Podman([]string{"ps", "--all", "--filter", "volume=/:/test2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(session.LineInOutputContains("test4")).To(BeTrue()) session = podmanTest.Podman([]string{"ps", "--all", "--filter", "before=test2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(session.LineInOutputContains("test1")).To(BeTrue()) session = podmanTest.Podman([]string{"ps", "--all", "--filter", "since=test2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(3)) Expect(session.LineInOutputContains("test3")).To(BeTrue()) Expect(session.LineInOutputContains("test4")).To(BeTrue()) @@ -718,48 +718,48 @@ var _ = Describe("Podman ps", func() { It("podman ps filter pod", func() { pod1 := podmanTest.Podman([]string{"pod", "create", "--name", "pod1"}) pod1.WaitWithDefaultTimeout() - Expect(pod1.ExitCode()).To(BeZero()) + Expect(pod1).Should(Exit(0)) con1 := podmanTest.Podman([]string{"run", "-dt", "--pod", "pod1", ALPINE, "top"}) con1.WaitWithDefaultTimeout() - Expect(con1.ExitCode()).To(BeZero()) + Expect(con1).Should(Exit(0)) pod2 := podmanTest.Podman([]string{"pod", "create", "--name", "pod2"}) pod2.WaitWithDefaultTimeout() - Expect(pod2.ExitCode()).To(BeZero()) + Expect(pod2).Should(Exit(0)) con2 := podmanTest.Podman([]string{"run", "-dt", "--pod", "pod2", ALPINE, "top"}) con2.WaitWithDefaultTimeout() - Expect(con2.ExitCode()).To(BeZero()) + Expect(con2).Should(Exit(0)) // bogus pod name or id should not result in error session := podmanTest.Podman([]string{"ps", "--filter", "pod=1234"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) // filter by pod name session = podmanTest.Podman([]string{"ps", "-q", "--no-trunc", "--filter", "pod=pod1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(StringInSlice(pod1.OutputToString(), session.OutputToStringArray())) // filter by full pod id session = podmanTest.Podman([]string{"ps", "-q", "--no-trunc", "--filter", "pod=" + pod1.OutputToString()}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(StringInSlice(pod1.OutputToString(), session.OutputToStringArray())) // filter by partial pod id session = podmanTest.Podman([]string{"ps", "-q", "--no-trunc", "--filter", "pod=" + pod1.OutputToString()[0:12]}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(StringInSlice(pod1.OutputToString(), session.OutputToStringArray())) // filter by multiple pods is inclusive session = podmanTest.Podman([]string{"ps", "-q", "--no-trunc", "--filter", "pod=pod1", "--filter", "pod=pod2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(4)) Expect(StringInSlice(pod1.OutputToString(), session.OutputToStringArray())) Expect(StringInSlice(pod2.OutputToString(), session.OutputToStringArray())) @@ -770,22 +770,22 @@ var _ = Describe("Podman ps", func() { net := stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", net}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(net) session = podmanTest.Podman([]string{"create", "--network", net, ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) ctrWithNet := session.OutputToString() session = podmanTest.Podman([]string{"create", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) ctrWithoutNet := session.OutputToString() session = podmanTest.Podman([]string{"ps", "--all", "--no-trunc", "--filter", "network=" + net}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(ctrWithNet)) Expect(session.OutputToString()).To(Not(ContainSubstring(ctrWithoutNet))) }) @@ -793,11 +793,11 @@ var _ = Describe("Podman ps", func() { It("podman ps --format networks", func() { session := podmanTest.Podman([]string{"create", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"ps", "--all", "--format", "{{ .Networks }}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) if isRootless() { // rootless container don't have a network by default Expect(session.OutputToString()).To(Equal("")) @@ -809,22 +809,22 @@ var _ = Describe("Podman ps", func() { net1 := stringid.GenerateNonCryptoID() session = podmanTest.Podman([]string{"network", "create", net1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(net1) net2 := stringid.GenerateNonCryptoID() session = podmanTest.Podman([]string{"network", "create", net2}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) defer podmanTest.removeCNINetwork(net2) session = podmanTest.Podman([]string{"create", "--network", net1 + "," + net2, ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"ps", "--all", "--format", "{{ .Networks }}", "--filter", "id=" + cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) // the output is not deterministic so check both possible orders Expect(session.OutputToString()).To(Or(Equal(net1+","+net2), Equal(net2+","+net1))) }) diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go index 048f19b1e..c377f158d 100644 --- a/test/e2e/pull_test.go +++ b/test/e2e/pull_test.go @@ -10,6 +10,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman pull", func() { @@ -38,18 +39,18 @@ var _ = Describe("Podman pull", func() { It("podman pull multiple images with/without tag/digest", func() { session := podmanTest.Podman([]string{"pull", "busybox:musl", "alpine", "alpine:latest", "quay.io/libpod/cirros", "quay.io/libpod/testdigest_v2s2@sha256:755f4d90b3716e2bf57060d249e2cd61c9ac089b1233465c5c2cb2d7ee550fdb"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pull", "busybox:latest", "docker.io/library/ibetthisdoesnotexistfr:random", "alpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) - expectedError := "Error initializing source docker://ibetthisdoesnotexistfr:random" + Expect(session).Should(Exit(125)) + expectedError := "initializing source docker://ibetthisdoesnotexistfr:random" found, _ := session.ErrorGrepString(expectedError) Expect(found).To(Equal(true)) session = podmanTest.Podman([]string{"rmi", "busybox", "alpine", "testdigest_v2s2", "quay.io/libpod/cirros"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pull from docker a not existing image", func() { @@ -61,188 +62,188 @@ var _ = Describe("Podman pull", func() { It("podman pull from docker with tag", func() { session := podmanTest.Podman([]string{"pull", "quay.io/libpod/testdigest_v2s2:20200210"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2:20200210"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pull from docker without tag", func() { session := podmanTest.Podman([]string{"pull", "quay.io/libpod/testdigest_v2s2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pull from alternate registry with tag", func() { session := podmanTest.Podman([]string{"pull", cirros}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", cirros}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pull from alternate registry without tag", func() { session := podmanTest.Podman([]string{"pull", "quay.io/libpod/cirros"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", "quay.io/libpod/cirros"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pull by digest", func() { session := podmanTest.Podman([]string{"pull", "quay.io/libpod/testdigest_v2s2@sha256:755f4d90b3716e2bf57060d249e2cd61c9ac089b1233465c5c2cb2d7ee550fdb"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pull by digest (image list)", func() { session := podmanTest.Podman([]string{"pull", "--arch=arm64", ALPINELISTDIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // inspect using the digest of the list session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINELISTDIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(HavePrefix("[]")) // inspect using the digest of the list session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINELISTDIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) // inspect using the digest of the arch-specific image's manifest session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64DIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(HavePrefix("[]")) // inspect using the digest of the arch-specific image's manifest session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64DIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) // inspect using the image ID session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64ID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(HavePrefix("[]")) // inspect using the image ID session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64ID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) // remove using the digest of the list session = podmanTest.Podman([]string{"rmi", ALPINELISTDIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pull by instance digest (image list)", func() { session := podmanTest.Podman([]string{"pull", "--arch=arm64", ALPINEARM64DIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // inspect using the digest of the list session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINELISTDIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) // inspect using the digest of the list session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINELISTDIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) // inspect using the digest of the arch-specific image's manifest session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64DIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(HavePrefix("[]")) // inspect using the digest of the arch-specific image's manifest session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64DIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(Not(ContainSubstring(ALPINELISTDIGEST))) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) // inspect using the image ID session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64ID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(HavePrefix("[]")) // inspect using the image ID session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64ID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(Not(ContainSubstring(ALPINELISTDIGEST))) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) // remove using the digest of the instance session = podmanTest.Podman([]string{"rmi", ALPINEARM64DIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pull by tag (image list)", func() { session := podmanTest.Podman([]string{"pull", "--arch=arm64", ALPINELISTTAG}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // inspect using the tag we used for pulling session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINELISTTAG}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG)) // inspect using the tag we used for pulling session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINELISTTAG}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) // inspect using the digest of the list session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINELISTDIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG)) // inspect using the digest of the list session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINELISTDIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) // inspect using the digest of the arch-specific image's manifest session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64DIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG)) // inspect using the digest of the arch-specific image's manifest session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64DIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) // inspect using the image ID session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64ID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG)) // inspect using the image ID session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64ID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST)) Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) // remove using the tag session = podmanTest.Podman([]string{"rmi", ALPINELISTTAG}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pull bogus image", func() { @@ -259,23 +260,23 @@ var _ = Describe("Podman pull", func() { session := podmanTest.Podman([]string{"save", "-o", tarfn, "cirros"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", "cirros"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:%s", tarfn)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", "cirros"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Pulling a multi-image archive without further specifying // which image _must_ error out. Pulling is restricted to one // image. session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz")}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) expectedError := "Unexpected tar manifest.json: expected 1 item, got 2" found, _ := session.ErrorGrepString(expectedError) Expect(found).To(Equal(true)) @@ -284,31 +285,31 @@ var _ = Describe("Podman pull", func() { // and index syntax. session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz:@0")}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz:example.com/empty:latest")}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz:@1")}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz:example.com/empty/but:different")}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Now check for some errors. session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz:foo.com/does/not/exist:latest")}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) expectedError = "Tag \"foo.com/does/not/exist:latest\" not found" found, _ = session.ErrorGrepString(expectedError) Expect(found).To(Equal(true)) session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz:@2")}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) expectedError = "Invalid source index @2, only 2 manifest items available" found, _ = session.ErrorGrepString(expectedError) Expect(found).To(Equal(true)) @@ -322,16 +323,16 @@ var _ = Describe("Podman pull", func() { session := podmanTest.Podman([]string{"save", "--format", "oci-archive", "-o", tarfn, "cirros"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", "cirros"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pull", fmt.Sprintf("oci-archive:%s", tarfn)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", "cirros"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pull from local directory", func() { @@ -344,16 +345,16 @@ var _ = Describe("Podman pull", func() { session := podmanTest.Podman([]string{"push", "cirros", imgPath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", "cirros"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pull", imgPath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"images"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContainsTag(filepath.Join("localhost", dirpath), "latest")).To(BeTrue()) }) @@ -367,16 +368,16 @@ var _ = Describe("Podman pull", func() { session := podmanTest.Podman([]string{"push", "cirros", imgPath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", "cirros"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pull", imgPath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"images"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContainsTag(filepath.Join("localhost", dirpath), "latest")).To(BeTrue()) }) @@ -384,16 +385,16 @@ var _ = Describe("Podman pull", func() { podmanTest.RestoreArtifact(ALPINE) setup := podmanTest.Podman([]string{"images", ALPINE, "-q", "--no-trunc"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) shortImageId := strings.Split(setup.OutputToString(), ":")[1] rmi := podmanTest.Podman([]string{"rmi", ALPINE}) rmi.WaitWithDefaultTimeout() - Expect(rmi.ExitCode()).To(Equal(0)) + Expect(rmi).Should(Exit(0)) pull := podmanTest.Podman([]string{"pull", "-q", ALPINE}) pull.WaitWithDefaultTimeout() - Expect(pull.ExitCode()).To(Equal(0)) + Expect(pull).Should(Exit(0)) Expect(pull.OutputToString()).To(ContainSubstring(shortImageId)) }) @@ -401,18 +402,18 @@ var _ = Describe("Podman pull", func() { It("podman pull check all tags", func() { session := podmanTest.Podman([]string{"pull", "--all-tags", "k8s.gcr.io/pause"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"images"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 4)) }) It("podman pull from docker with nonexistent --authfile", func() { session := podmanTest.Podman([]string{"pull", "--authfile", "/tmp/nonexistent", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("podman pull + inspect from unqualified-search registry", func() { @@ -434,7 +435,7 @@ var _ = Describe("Podman pull", func() { getID := func(image string) string { setup := podmanTest.Podman([]string{"image", "inspect", image}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) data := setup.InspectImageJSON() // returns []inspect.ImageData Expect(len(data)).To(Equal(1)) @@ -444,11 +445,11 @@ var _ = Describe("Podman pull", func() { untag := func(image string) { setup := podmanTest.Podman([]string{"untag", image}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) setup = podmanTest.Podman([]string{"image", "inspect", image}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) data := setup.InspectImageJSON() // returns []inspect.ImageData Expect(len(data)).To(Equal(1)) @@ -458,10 +459,10 @@ var _ = Describe("Podman pull", func() { tag := func(image, tag string) { setup := podmanTest.Podman([]string{"tag", image, tag}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) setup = podmanTest.Podman([]string{"image", "exists", tag}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) } image1 := getID(ALPINE) @@ -502,7 +503,7 @@ var _ = Describe("Podman pull", func() { setup := podmanTest.Podman([]string{"image", "inspect", name}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) data := setup.InspectImageJSON() // returns []inspect.ImageData Expect(len(data)).To(Equal(1)) @@ -515,23 +516,23 @@ var _ = Describe("Podman pull", func() { It("podman pull --platform", func() { session := podmanTest.Podman([]string{"pull", "--platform=linux/bogus", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) expectedError := "no image found in manifest list for architecture bogus" Expect(session.ErrorToString()).To(ContainSubstring(expectedError)) session = podmanTest.Podman([]string{"pull", "--platform=linux/arm64", "--os", "windows", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) expectedError = "--platform option can not be specified with --arch or --os" Expect(session.ErrorToString()).To(ContainSubstring(expectedError)) session = podmanTest.Podman([]string{"pull", "-q", "--platform=linux/arm64", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) setup := podmanTest.Podman([]string{"image", "inspect", session.OutputToString()}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) data := setup.InspectImageJSON() // returns []inspect.ImageData Expect(len(data)).To(Equal(1)) @@ -542,23 +543,23 @@ var _ = Describe("Podman pull", func() { It("podman pull --arch", func() { session := podmanTest.Podman([]string{"pull", "--arch=bogus", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) expectedError := "no image found in manifest list for architecture bogus" Expect(session.ErrorToString()).To(ContainSubstring(expectedError)) session = podmanTest.Podman([]string{"pull", "--arch=arm64", "--os", "windows", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) expectedError = "no image found in manifest list for architecture" Expect(session.ErrorToString()).To(ContainSubstring(expectedError)) session = podmanTest.Podman([]string{"pull", "-q", "--arch=arm64", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) setup := podmanTest.Podman([]string{"image", "inspect", session.OutputToString()}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) data := setup.InspectImageJSON() // returns []inspect.ImageData Expect(len(data)).To(Equal(1)) diff --git a/test/e2e/push_test.go b/test/e2e/push_test.go index cc7c67941..b7e8309fb 100644 --- a/test/e2e/push_test.go +++ b/test/e2e/push_test.go @@ -10,6 +10,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman push", func() { @@ -40,11 +41,11 @@ var _ = Describe("Podman push", func() { SkipIfRemote("Remote push does not support containers-storage transport") session := podmanTest.Podman([]string{"push", ALPINE, "containers-storage:busybox:test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman push to dir", func() { @@ -53,13 +54,13 @@ var _ = Describe("Podman push", func() { session := podmanTest.Podman([]string{"push", "--remove-signatures", ALPINE, fmt.Sprintf("dir:%s", bbdir)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) bbdir = filepath.Join(podmanTest.TempDir, "busybox") session = podmanTest.Podman([]string{"push", "--format", "oci", ALPINE, fmt.Sprintf("dir:%s", bbdir)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman push to local registry", func() { @@ -74,7 +75,7 @@ var _ = Describe("Podman push", func() { defer lock.Unlock() session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5000:5000", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) { Skip("Cannot start docker registry.") @@ -82,7 +83,7 @@ var _ = Describe("Podman push", func() { push := podmanTest.Podman([]string{"push", "-q", "--tls-verify=false", "--remove-signatures", ALPINE, "localhost:5000/my-alpine"}) push.WaitWithDefaultTimeout() - Expect(push.ExitCode()).To(Equal(0)) + Expect(push).Should(Exit(0)) // Test --digestfile option push2 := podmanTest.Podman([]string{"push", "--tls-verify=false", "--digestfile=/tmp/digestfile.txt", "--remove-signatures", ALPINE, "localhost:5000/my-alpine"}) @@ -90,7 +91,7 @@ var _ = Describe("Podman push", func() { fi, err := os.Lstat("/tmp/digestfile.txt") Expect(err).To(BeNil()) Expect(fi.Name()).To(Equal("digestfile.txt")) - Expect(push2.ExitCode()).To(Equal(0)) + Expect(push2).Should(Exit(0)) }) It("podman push to local registry with authorization", func() { @@ -108,13 +109,13 @@ var _ = Describe("Podman push", func() { if IsCommandAvailable("getenforce") { ge := SystemExec("getenforce", []string{}) - Expect(ge.ExitCode()).To(Equal(0)) + Expect(ge).Should(Exit(0)) if ge.OutputToString() == "Enforcing" { se := SystemExec("setenforce", []string{"0"}) - Expect(se.ExitCode()).To(Equal(0)) + Expect(se).Should(Exit(0)) defer func() { se2 := SystemExec("setenforce", []string{"1"}) - Expect(se2.ExitCode()).To(Equal(0)) + Expect(se2).Should(Exit(0)) }() } } @@ -122,7 +123,7 @@ var _ = Describe("Podman push", func() { defer lock.Unlock() session := podmanTest.Podman([]string{"run", "--entrypoint", "htpasswd", registry, "-Bbn", "podmantest", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) f, _ := os.Create(filepath.Join(authPath, "htpasswd")) defer f.Close() @@ -136,7 +137,7 @@ var _ = Describe("Podman push", func() { "-v", strings.Join([]string{certPath, "/certs"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt", "-e", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key", registry}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) { Skip("Cannot start docker registry.") @@ -151,10 +152,10 @@ var _ = Describe("Podman push", func() { push = podmanTest.Podman([]string{"push", "--creds=podmantest:test", "--tls-verify=false", ALPINE, "localhost:5000/tlstest"}) push.WaitWithDefaultTimeout() - Expect(push.ExitCode()).To(Equal(0)) + Expect(push).Should(Exit(0)) setup := SystemExec("cp", []string{filepath.Join(certPath, "domain.crt"), "/etc/containers/certs.d/localhost:5000/ca.crt"}) - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) push = podmanTest.Podman([]string{"push", "--creds=podmantest:wrongpasswd", ALPINE, "localhost:5000/credstest"}) push.WaitWithDefaultTimeout() @@ -169,7 +170,7 @@ var _ = Describe("Podman push", func() { push = podmanTest.Podman([]string{"push", "--creds=podmantest:test", ALPINE, "localhost:5000/defaultflags"}) push.WaitWithDefaultTimeout() - Expect(push.ExitCode()).To(Equal(0)) + Expect(push).Should(Exit(0)) }) It("podman push to docker-archive", func() { @@ -178,7 +179,7 @@ var _ = Describe("Podman push", func() { session := podmanTest.Podman([]string{"push", ALPINE, fmt.Sprintf("docker-archive:%s:latest", tarfn)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman push to docker daemon", func() { @@ -189,7 +190,7 @@ var _ = Describe("Podman push", func() { setup = SystemExec("systemctl", []string{"start", "docker"}) defer func() { stop := SystemExec("systemctl", []string{"stop", "docker"}) - Expect(stop.ExitCode()).To(Equal(0)) + Expect(stop).Should(Exit(0)) }() } else if setup.ExitCode() != 0 { Skip("Docker is not available") @@ -197,14 +198,14 @@ var _ = Describe("Podman push", func() { session := podmanTest.Podman([]string{"push", ALPINE, "docker-daemon:alpine:podmantest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := SystemExec("docker", []string{"images", "--format", "{{.Repository}}:{{.Tag}}"}) - Expect(check.ExitCode()).To(Equal(0)) + Expect(check).Should(Exit(0)) Expect(check.OutputToString()).To(ContainSubstring("alpine:podmantest")) clean := SystemExec("docker", []string{"rmi", "alpine:podmantest"}) - Expect(clean.ExitCode()).To(Equal(0)) + Expect(clean).Should(Exit(0)) }) It("podman push to oci-archive", func() { @@ -213,7 +214,7 @@ var _ = Describe("Podman push", func() { session := podmanTest.Podman([]string{"push", ALPINE, fmt.Sprintf("oci-archive:%s:latest", tarfn)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman push to docker-archive no reference", func() { @@ -222,7 +223,7 @@ var _ = Describe("Podman push", func() { session := podmanTest.Podman([]string{"push", ALPINE, fmt.Sprintf("docker-archive:%s", tarfn)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman push to oci-archive no reference", func() { @@ -232,7 +233,7 @@ var _ = Describe("Podman push", func() { fmt.Sprintf("oci-archive:%s", ociarc)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) }) diff --git a/test/e2e/rename_test.go b/test/e2e/rename_test.go index 14696c0f6..0bd1792c9 100644 --- a/test/e2e/rename_test.go +++ b/test/e2e/rename_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("podman rename", func() { @@ -36,23 +37,23 @@ var _ = Describe("podman rename", func() { It("podman rename on non-existent container", func() { session := podmanTest.Podman([]string{"rename", "doesNotExist", "aNewName"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("Podman rename on existing container with bad name", func() { ctrName := "testCtr" ctr := podmanTest.Podman([]string{"create", "--name", ctrName, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(Equal(0)) + Expect(ctr).Should(Exit(0)) newName := "invalid<>:char" rename := podmanTest.Podman([]string{"rename", ctrName, newName}) rename.WaitWithDefaultTimeout() - Expect(rename.ExitCode()).To(Not(Equal(0))) + Expect(rename).To(ExitWithError()) ps := podmanTest.Podman([]string{"ps", "-aq", "--filter", fmt.Sprintf("name=%s", ctrName), "--format", "{{ .Names }}"}) ps.WaitWithDefaultTimeout() - Expect(ps.ExitCode()).To(Equal(0)) + Expect(ps).Should(Exit(0)) Expect(ps.OutputToString()).To(ContainSubstring(ctrName)) }) @@ -60,16 +61,16 @@ var _ = Describe("podman rename", func() { ctrName := "testCtr" ctr := podmanTest.Podman([]string{"create", "--name", ctrName, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(Equal(0)) + Expect(ctr).Should(Exit(0)) newName := "aNewName" rename := podmanTest.Podman([]string{"rename", ctrName, newName}) rename.WaitWithDefaultTimeout() - Expect(rename.ExitCode()).To(Equal(0)) + Expect(rename).Should(Exit(0)) ps := podmanTest.Podman([]string{"ps", "-aq", "--filter", fmt.Sprintf("name=%s", newName), "--format", "{{ .Names }}"}) ps.WaitWithDefaultTimeout() - Expect(ps.ExitCode()).To(Equal(0)) + Expect(ps).Should(Exit(0)) Expect(ps.OutputToString()).To(ContainSubstring(newName)) }) @@ -77,16 +78,16 @@ var _ = Describe("podman rename", func() { ctrName := "testCtr" ctr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(Equal(0)) + Expect(ctr).Should(Exit(0)) newName := "aNewName" rename := podmanTest.Podman([]string{"rename", ctrName, newName}) rename.WaitWithDefaultTimeout() - Expect(rename.ExitCode()).To(Equal(0)) + Expect(rename).Should(Exit(0)) ps := podmanTest.Podman([]string{"ps", "-aq", "--filter", fmt.Sprintf("name=%s", newName), "--format", "{{ .Names }}"}) ps.WaitWithDefaultTimeout() - Expect(ps.ExitCode()).To(Equal(0)) + Expect(ps).Should(Exit(0)) Expect(ps.OutputToString()).To(ContainSubstring(newName)) }) @@ -94,20 +95,20 @@ var _ = Describe("podman rename", func() { ctrName := "testCtr" ctr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(Equal(0)) + Expect(ctr).Should(Exit(0)) exec := podmanTest.Podman([]string{"exec", "-d", ctrName, "top"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(Equal(0)) + Expect(exec).Should(Exit(0)) newName := "aNewName" rename := podmanTest.Podman([]string{"rename", ctrName, newName}) rename.WaitWithDefaultTimeout() - Expect(rename.ExitCode()).To(Equal(0)) + Expect(rename).Should(Exit(0)) ps := podmanTest.Podman([]string{"ps", "-aq", "--filter", fmt.Sprintf("name=%s", newName), "--format", "{{ .Names }}"}) ps.WaitWithDefaultTimeout() - Expect(ps.ExitCode()).To(Equal(0)) + Expect(ps).Should(Exit(0)) Expect(ps.OutputToString()).To(ContainSubstring(newName)) }) }) diff --git a/test/e2e/restart_test.go b/test/e2e/restart_test.go index dc8e64e63..6a61c1292 100644 --- a/test/e2e/restart_test.go +++ b/test/e2e/restart_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman restart", func() { @@ -36,7 +37,7 @@ var _ = Describe("Podman restart", func() { It("Podman restart bogus container", func() { session := podmanTest.Podman([]string{"start", "123"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("Podman restart stopped container by name", func() { @@ -47,7 +48,7 @@ var _ = Describe("Podman restart", func() { session := podmanTest.Podman([]string{"restart", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) restartTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1"}) restartTime.WaitWithDefaultTimeout() Expect(restartTime.OutputToString()).To(Not(Equal(startTime.OutputToString()))) @@ -56,18 +57,18 @@ var _ = Describe("Podman restart", func() { It("Podman restart stopped container by ID", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() startTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", cid}) startTime.WaitWithDefaultTimeout() startSession := podmanTest.Podman([]string{"start", cid}) startSession.WaitWithDefaultTimeout() - Expect(startSession.ExitCode()).To(Equal(0)) + Expect(startSession).Should(Exit(0)) session2 := podmanTest.Podman([]string{"restart", cid}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) restartTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", cid}) restartTime.WaitWithDefaultTimeout() Expect(restartTime.OutputToString()).To(Not(Equal(startTime.OutputToString()))) @@ -82,7 +83,7 @@ var _ = Describe("Podman restart", func() { session := podmanTest.Podman([]string{"restart", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) restartTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1"}) restartTime.WaitWithDefaultTimeout() Expect(restartTime.OutputToString()).To(Not(Equal(startTime.OutputToString()))) @@ -97,7 +98,7 @@ var _ = Describe("Podman restart", func() { session := podmanTest.Podman([]string{"container", "restart", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) restartTime := podmanTest.Podman([]string{"container", "inspect", "--format='{{.State.StartedAt}}'", "test1"}) restartTime.WaitWithDefaultTimeout() Expect(restartTime.OutputToString()).To(Not(Equal(startTime.OutputToString()))) @@ -114,7 +115,7 @@ var _ = Describe("Podman restart", func() { session := podmanTest.Podman([]string{"restart", "test1", "test2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) restartTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"}) restartTime.WaitWithDefaultTimeout() Expect(restartTime.OutputToStringArray()[0]).To(Not(Equal(startTime.OutputToStringArray()[0]))) @@ -137,7 +138,7 @@ var _ = Describe("Podman restart", func() { } session := podmanTest.Podman([]string{"restart", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) restartTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"}) restartTime.WaitWithDefaultTimeout() Expect(restartTime.OutputToStringArray()[0]).To(Equal(startTime.OutputToStringArray()[0])) @@ -147,11 +148,11 @@ var _ = Describe("Podman restart", func() { It("Podman restart non-stop container with short timeout", func() { session := podmanTest.Podman([]string{"run", "-d", "--name", "test1", "--env", "STOPSIGNAL=SIGKILL", ALPINE, "sleep", "999"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) startTime := time.Now() session = podmanTest.Podman([]string{"restart", "-t", "2", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) timeSince := time.Since(startTime) Expect(timeSince < 10*time.Second).To(BeTrue()) Expect(timeSince > 2*time.Second).To(BeTrue()) @@ -163,14 +164,14 @@ var _ = Describe("Podman restart", func() { test2 := podmanTest.RunTopContainer("test2") test2.WaitWithDefaultTimeout() - Expect(test2.ExitCode()).To(Equal(0)) + Expect(test2).Should(Exit(0)) startTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"}) startTime.WaitWithDefaultTimeout() session := podmanTest.Podman([]string{"restart", "--all"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) restartTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"}) restartTime.WaitWithDefaultTimeout() Expect(restartTime.OutputToStringArray()[0]).To(Not(Equal(startTime.OutputToStringArray()[0]))) @@ -183,14 +184,14 @@ var _ = Describe("Podman restart", func() { test2 := podmanTest.RunTopContainer("test2") test2.WaitWithDefaultTimeout() - Expect(test2.ExitCode()).To(Equal(0)) + Expect(test2).Should(Exit(0)) startTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"}) startTime.WaitWithDefaultTimeout() session := podmanTest.Podman([]string{"restart", "-a", "--running"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) restartTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"}) restartTime.WaitWithDefaultTimeout() Expect(restartTime.OutputToStringArray()[0]).To(Equal(startTime.OutputToStringArray()[0])) @@ -205,22 +206,22 @@ var _ = Describe("Podman restart", func() { session := podmanTest.RunTopContainerInPod("host-restart-test", "foobar99") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) testCmd := []string{"exec", "host-restart-test", "sh", "-c", "wc -l < /etc/hosts"} // before restart beforeRestart := podmanTest.Podman(testCmd) beforeRestart.WaitWithDefaultTimeout() - Expect(beforeRestart.ExitCode()).To(Equal(0)) + Expect(beforeRestart).Should(Exit(0)) session = podmanTest.Podman([]string{"restart", "host-restart-test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) afterRestart := podmanTest.Podman(testCmd) afterRestart.WaitWithDefaultTimeout() - Expect(afterRestart.ExitCode()).To(Equal(0)) + Expect(afterRestart).Should(Exit(0)) // line count should be equal Expect(beforeRestart.OutputToString()).To(Equal(afterRestart.OutputToString())) @@ -229,22 +230,22 @@ var _ = Describe("Podman restart", func() { It("podman restart --all", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) session = podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) session = podmanTest.Podman([]string{"stop", "--all"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) session = podmanTest.Podman([]string{"restart", "--all"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) }) }) diff --git a/test/e2e/rm_test.go b/test/e2e/rm_test.go index 788d14141..ec4dce752 100644 --- a/test/e2e/rm_test.go +++ b/test/e2e/rm_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman rm", func() { @@ -39,93 +40,93 @@ var _ = Describe("Podman rm", func() { result := podmanTest.Podman([]string{"rm", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman rm refuse to remove a running container", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"rm", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(2)) + Expect(result).Should(Exit(2)) }) It("podman rm created container", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"rm", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman container rm created container", func() { session := podmanTest.Podman([]string{"container", "create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"container", "rm", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman rm running container with -f", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() result := podmanTest.Podman([]string{"rm", "-f", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman rm all containers", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"rm", "-a"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman rm all containers with one running and short options", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"rm", "-af"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman rm the latest container", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, ec, cid := podmanTest.RunLsContainer("test1") Expect(ec).To(Equal(0)) @@ -136,7 +137,7 @@ var _ = Describe("Podman rm", func() { } result := podmanTest.Podman([]string{"rm", latest}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) output := result.OutputToString() Expect(output).To(ContainSubstring(cid)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) @@ -153,13 +154,13 @@ var _ = Describe("Podman rm", func() { session := podmanTest.Podman([]string{"create", "--cidfile", tmpFile, ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToStringArray()[0] Expect(podmanTest.NumberOfContainers()).To(Equal(1)) result := podmanTest.Podman([]string{"rm", "--cidfile", tmpFile}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) output := result.OutputToString() Expect(output).To(ContainSubstring(cid)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -176,19 +177,19 @@ var _ = Describe("Podman rm", func() { session := podmanTest.Podman([]string{"create", "--cidfile", tmpFile1, ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid1 := session.OutputToStringArray()[0] Expect(podmanTest.NumberOfContainers()).To(Equal(1)) session = podmanTest.Podman([]string{"create", "--cidfile", tmpFile2, ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid2 := session.OutputToStringArray()[0] Expect(podmanTest.NumberOfContainers()).To(Equal(2)) result := podmanTest.Podman([]string{"rm", "--cidfile", tmpFile1, "--cidfile", tmpFile2}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) output := result.OutputToString() Expect(output).To(ContainSubstring(cid1)) Expect(output).To(ContainSubstring(cid2)) @@ -200,86 +201,86 @@ var _ = Describe("Podman rm", func() { result := podmanTest.Podman([]string{"rm", "--cidfile", "foobar", "--latest"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) result = podmanTest.Podman([]string{"rm", "--cidfile", "foobar", "--all"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) result = podmanTest.Podman([]string{"rm", "--cidfile", "foobar", "--all", "--latest"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) result = podmanTest.Podman([]string{"rm", "--latest", "--all"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) }) It("podman rm --all", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) session = podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(2)) session = podmanTest.Podman([]string{"rm", "--all"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) }) It("podman rm --ignore", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToStringArray()[0] Expect(podmanTest.NumberOfContainers()).To(Equal(1)) session = podmanTest.Podman([]string{"rm", "bogus", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) session = podmanTest.Podman([]string{"rm", "--ignore", "bogus", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) }) It("podman rm bogus container", func() { session := podmanTest.Podman([]string{"rm", "bogus"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) }) It("podman rm bogus container and a running container", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rm", "bogus", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) session = podmanTest.Podman([]string{"rm", "test1", "bogus"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) }) It("podman rm --ignore bogus container and a running container", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rm", "--force", "--ignore", "bogus", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rm", "--ignore", "test1", "bogus"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) }) diff --git a/test/e2e/run_apparmor_test.go b/test/e2e/run_apparmor_test.go index 1f9b9bc90..6532402ed 100644 --- a/test/e2e/run_apparmor_test.go +++ b/test/e2e/run_apparmor_test.go @@ -12,6 +12,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) // wip @@ -54,7 +55,7 @@ var _ = Describe("Podman run", func() { skipIfAppArmorDisabled() session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() // Verify that apparmor.Profile is being set @@ -66,7 +67,7 @@ var _ = Describe("Podman run", func() { skipIfAppArmorDisabled() session := podmanTest.Podman([]string{"create", "--privileged", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() // Verify that apparmor.Profile is being set @@ -78,7 +79,7 @@ var _ = Describe("Podman run", func() { skipIfAppArmorDisabled() session := podmanTest.Podman([]string{"create", "--security-opt", fmt.Sprintf("apparmor=%s", apparmor.Profile), "--privileged", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() // Verify that apparmor.Profile is being set @@ -105,11 +106,11 @@ profile aa-test-profile flags=(attach_disconnected,mediate_deleted) { aaFile := filepath.Join(os.TempDir(), "aaFile") Expect(ioutil.WriteFile(aaFile, []byte(aaProfile), 0755)).To(BeNil()) parse := SystemExec("apparmor_parser", []string{"-Kr", aaFile}) - Expect(parse.ExitCode()).To(Equal(0)) + Expect(parse).Should(Exit(0)) session := podmanTest.Podman([]string{"create", "--security-opt", "apparmor=aa-test-profile", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() // Verify that apparmor.Profile is being set @@ -121,14 +122,14 @@ profile aa-test-profile flags=(attach_disconnected,mediate_deleted) { skipIfAppArmorDisabled() session := podmanTest.Podman([]string{"run", "--security-opt", "apparmor=invalid", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).ToNot(Equal(0)) + Expect(session).To(ExitWithError()) }) It("podman run apparmor unconfined", func() { skipIfAppArmorDisabled() session := podmanTest.Podman([]string{"create", "--security-opt", "apparmor=unconfined", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() // Verify that apparmor.Profile is being set @@ -141,7 +142,7 @@ profile aa-test-profile flags=(attach_disconnected,mediate_deleted) { // Should fail if user specifies apparmor on disabled system session := podmanTest.Podman([]string{"create", "--security-opt", fmt.Sprintf("apparmor=%s", apparmor.Profile), ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).ToNot(Equal(0)) + Expect(session).To(ExitWithError()) }) It("podman run apparmor disabled no default", func() { @@ -149,7 +150,7 @@ profile aa-test-profile flags=(attach_disconnected,mediate_deleted) { // Should succeed if user specifies apparmor on disabled system session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() // Verify that apparmor.Profile is being set @@ -162,7 +163,7 @@ profile aa-test-profile flags=(attach_disconnected,mediate_deleted) { session := podmanTest.Podman([]string{"create", "--security-opt", "apparmor=unconfined", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() // Verify that apparmor.Profile is being set diff --git a/test/e2e/run_cgroup_parent_test.go b/test/e2e/run_cgroup_parent_test.go index 1df4c4033..300c3a8e0 100644 --- a/test/e2e/run_cgroup_parent_test.go +++ b/test/e2e/run_cgroup_parent_test.go @@ -9,6 +9,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run with --cgroup-parent", func() { @@ -43,7 +44,7 @@ var _ = Describe("Podman run with --cgroup-parent", func() { cgroup := "/zzz" run := podmanTest.Podman([]string{"run", "--cgroupns=host", "--cgroup-parent", cgroup, fedoraMinimal, "cat", "/proc/self/cgroup"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) ok, _ := run.GrepString(cgroup) Expect(ok).To(BeTrue()) }) @@ -56,7 +57,7 @@ var _ = Describe("Podman run with --cgroup-parent", func() { } run := podmanTest.Podman([]string{"run", "--cgroupns=host", fedoraMinimal, "cat", "/proc/self/cgroup"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) ok, _ := run.GrepString(cgroup) Expect(ok).To(BeTrue()) }) @@ -72,22 +73,22 @@ var _ = Describe("Podman run with --cgroup-parent", func() { run := podmanTest.Podman([]string{"run", "-d", "--cgroupns=host", fedoraMinimal, "sleep", "100"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) cid := run.OutputToString() exec := podmanTest.Podman([]string{"exec", cid, "cat", "/proc/self/cgroup"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(Equal(0)) + Expect(exec).Should(Exit(0)) cgroup := filepath.Dir(strings.TrimRight(strings.Replace(exec.OutputToString(), "0::", "", -1), "\n")) run = podmanTest.Podman([]string{"--cgroup-manager=cgroupfs", "run", "-d", fmt.Sprintf("--cgroup-parent=%s", cgroup), fedoraMinimal, "sleep", "100"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) exec = podmanTest.Podman([]string{"exec", cid, "cat", "/proc/self/cgroup"}) exec.WaitWithDefaultTimeout() - Expect(exec.ExitCode()).To(Equal(0)) + Expect(exec).Should(Exit(0)) cgroupEffective := filepath.Dir(strings.TrimRight(strings.Replace(exec.OutputToString(), "0::", "", -1), "\n")) Expect(cgroupEffective).To(Equal(cgroup)) @@ -100,7 +101,7 @@ var _ = Describe("Podman run with --cgroup-parent", func() { cgroup := "aaaa.slice" run := podmanTest.Podman([]string{"run", "--cgroupns=host", "--cgroup-parent", cgroup, fedoraMinimal, "cat", "/proc/1/cgroup"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) ok, _ := run.GrepString(cgroup) Expect(ok).To(BeTrue()) }) diff --git a/test/e2e/run_cleanup_test.go b/test/e2e/run_cleanup_test.go index 2dfaf1329..cfe11079d 100644 --- a/test/e2e/run_cleanup_test.go +++ b/test/e2e/run_cleanup_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run exit", func() { @@ -39,33 +40,33 @@ var _ = Describe("Podman run exit", func() { result := podmanTest.Podman([]string{"run", "-dt", ALPINE, "top"}) result.WaitWithDefaultTimeout() cid := result.OutputToString() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) mount := SystemExec("mount", nil) - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) Expect(mount.OutputToString()).To(ContainSubstring(cid)) pmount := podmanTest.Podman([]string{"mount", "--notruncate"}) pmount.WaitWithDefaultTimeout() - Expect(pmount.ExitCode()).To(Equal(0)) + Expect(pmount).Should(Exit(0)) Expect(pmount.OutputToString()).To(ContainSubstring(cid)) stop := podmanTest.Podman([]string{"stop", cid}) stop.WaitWithDefaultTimeout() - Expect(stop.ExitCode()).To(Equal(0)) + Expect(stop).Should(Exit(0)) // We have to force cleanup so the unmount happens podmanCleanupSession := podmanTest.Podman([]string{"container", "cleanup", cid}) podmanCleanupSession.WaitWithDefaultTimeout() - Expect(podmanCleanupSession.ExitCode()).To(Equal(0)) + Expect(podmanCleanupSession).Should(Exit(0)) mount = SystemExec("mount", nil) - Expect(mount.ExitCode()).To(Equal(0)) + Expect(mount).Should(Exit(0)) Expect(mount.OutputToString()).NotTo(ContainSubstring(cid)) pmount = podmanTest.Podman([]string{"mount", "--notruncate"}) pmount.WaitWithDefaultTimeout() - Expect(pmount.ExitCode()).To(Equal(0)) + Expect(pmount).Should(Exit(0)) Expect(pmount.OutputToString()).NotTo(ContainSubstring(cid)) }) diff --git a/test/e2e/run_cpu_test.go b/test/e2e/run_cpu_test.go index 2f4452ba4..6dbb5886d 100644 --- a/test/e2e/run_cpu_test.go +++ b/test/e2e/run_cpu_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run cpu", func() { @@ -50,7 +51,7 @@ var _ = Describe("Podman run cpu", func() { result = podmanTest.Podman([]string{"run", "--rm", "--cpu-period=5000", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_period_us"}) } result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.LineInOutputContains("5000")).To(BeTrue()) }) @@ -63,7 +64,7 @@ var _ = Describe("Podman run cpu", func() { result = podmanTest.Podman([]string{"run", "--rm", "--cpu-quota=5000", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"}) } result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.LineInOutputContains("5000")).To(BeTrue()) }) @@ -71,17 +72,17 @@ var _ = Describe("Podman run cpu", func() { if CGROUPSV2 { result := podmanTest.Podman([]string{"run", "--rm", "--cpu-quota=5000", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.max"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal("5000 100000")) } else { result := podmanTest.Podman([]string{"run", "--rm", "--cpus=0.5", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_period_us"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal("100000")) result = podmanTest.Podman([]string{"run", "--rm", "--cpus=0.5", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal("50000")) } }) @@ -91,12 +92,12 @@ var _ = Describe("Podman run cpu", func() { // [2-262144] is mapped to [1-10000] result := podmanTest.Podman([]string{"run", "--rm", "--cpu-shares=262144", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.weight"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal("10000")) } else { result := podmanTest.Podman([]string{"run", "--rm", "--cpu-shares=2", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.shares"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal("2")) } }) @@ -110,7 +111,7 @@ var _ = Describe("Podman run cpu", func() { result = podmanTest.Podman([]string{"run", "--rm", "--cpuset-cpus=0", ALPINE, "cat", "/sys/fs/cgroup/cpuset/cpuset.cpus"}) } result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal("0")) }) @@ -123,7 +124,7 @@ var _ = Describe("Podman run cpu", func() { result = podmanTest.Podman([]string{"run", "--rm", "--cpuset-mems=0", ALPINE, "cat", "/sys/fs/cgroup/cpuset/cpuset.mems"}) } result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(Equal("0")) }) diff --git a/test/e2e/run_device_test.go b/test/e2e/run_device_test.go index 735e44d3e..40de1d50d 100644 --- a/test/e2e/run_device_test.go +++ b/test/e2e/run_device_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run device", func() { @@ -42,28 +43,28 @@ var _ = Describe("Podman run device", func() { It("podman run device test", func() { session := podmanTest.Podman([]string{"run", "-q", "--security-opt", "label=disable", "--device", "/dev/kmsg", ALPINE, "ls", "--color=never", "/dev/kmsg"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("/dev/kmsg")) }) It("podman run device rename test", func() { session := podmanTest.Podman([]string{"run", "-q", "--security-opt", "label=disable", "--device", "/dev/kmsg:/dev/kmsg1", ALPINE, "ls", "--color=never", "/dev/kmsg1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("/dev/kmsg1")) }) It("podman run device permission test", func() { session := podmanTest.Podman([]string{"run", "-q", "--security-opt", "label=disable", "--device", "/dev/kmsg:r", ALPINE, "ls", "--color=never", "/dev/kmsg"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("/dev/kmsg")) }) It("podman run device rename and permission test", func() { session := podmanTest.Podman([]string{"run", "-q", "--security-opt", "label=disable", "--device", "/dev/kmsg:/dev/kmsg1:r", ALPINE, "ls", "--color=never", "/dev/kmsg1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("/dev/kmsg1")) }) It("podman run device rename and bad permission test", func() { @@ -79,11 +80,11 @@ var _ = Describe("Podman run device", func() { mknod := SystemExec("mknod", []string{"/dev/foodevdir/null", "c", "1", "3"}) mknod.WaitWithDefaultTimeout() - Expect(mknod.ExitCode()).To(Equal(0)) + Expect(mknod).Should(Exit(0)) session := podmanTest.Podman([]string{"run", "-q", "--device", "/dev/foodevdir:/dev/bar", ALPINE, "stat", "-c%t:%T", "/dev/bar/null"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("1:3")) }) @@ -93,7 +94,7 @@ var _ = Describe("Podman run device", func() { } session := podmanTest.Podman([]string{"run", "--privileged", ALPINE, "ls", "/dev/kvm"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run CDI device test", func() { @@ -110,13 +111,13 @@ var _ = Describe("Podman run device", func() { session := podmanTest.Podman([]string{"run", "-q", "--security-opt", "label=disable", "--device", "myKmsg", ALPINE, "ls", "--color=never", "/dev/kmsg1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("/dev/kmsg1")) }) It("podman run --gpus noop", func() { session := podmanTest.Podman([]string{"run", "--gpus", "all", ALPINE, "ls", "/"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) }) diff --git a/test/e2e/run_dns_test.go b/test/e2e/run_dns_test.go index 05f8c3f99..166160ad2 100644 --- a/test/e2e/run_dns_test.go +++ b/test/e2e/run_dns_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run dns", func() { @@ -35,14 +36,14 @@ var _ = Describe("Podman run dns", func() { It("podman run add search domain", func() { session := podmanTest.Podman([]string{"run", "--dns-search=foobar.com", ALPINE, "cat", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session.LineInOutputStartsWith("search foobar.com") }) It("podman run remove all search domain", func() { session := podmanTest.Podman([]string{"run", "--dns-search=.", ALPINE, "cat", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputStartsWith("search")).To(BeFalse()) }) @@ -55,14 +56,14 @@ var _ = Describe("Podman run dns", func() { It("podman run add dns server", func() { session := podmanTest.Podman([]string{"run", "--dns=1.2.3.4", ALPINE, "cat", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session.LineInOutputStartsWith("server 1.2.3.4") }) It("podman run add dns option", func() { session := podmanTest.Podman([]string{"run", "--dns-opt=debug", ALPINE, "cat", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session.LineInOutputStartsWith("options debug") }) @@ -75,7 +76,7 @@ var _ = Describe("Podman run dns", func() { It("podman run add host", func() { session := podmanTest.Podman([]string{"run", "--add-host=foobar:1.1.1.1", "--add-host=foobaz:2001:db8::68", ALPINE, "cat", "/etc/hosts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session.LineInOutputStartsWith("1.1.1.1 foobar") session.LineInOutputStartsWith("2001:db8::68 foobaz") }) @@ -83,19 +84,19 @@ var _ = Describe("Podman run dns", func() { It("podman run add hostname", func() { session := podmanTest.Podman([]string{"run", "--hostname=foobar", ALPINE, "cat", "/etc/hostname"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("foobar")) session = podmanTest.Podman([]string{"run", "--hostname=foobar", ALPINE, "hostname"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("foobar")) }) It("podman run add hostname sets /etc/hosts", func() { session := podmanTest.Podman([]string{"run", "-t", "-i", "--hostname=foobar", ALPINE, "cat", "/etc/hosts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("foobar")).To(BeTrue()) }) @@ -114,6 +115,6 @@ var _ = Describe("Podman run dns", func() { session = podmanTest.Podman([]string{"run", "--dns=1.2.3.4", "--network", "host", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To((Equal(0))) + Expect(session).Should(Exit(0)) }) }) diff --git a/test/e2e/run_entrypoint_test.go b/test/e2e/run_entrypoint_test.go index ddad89c85..9560b1627 100644 --- a/test/e2e/run_entrypoint_test.go +++ b/test/e2e/run_entrypoint_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run entrypoint", func() { @@ -40,7 +41,7 @@ CMD [] podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false") session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman run entrypoint == [\"\"]", func() { @@ -51,7 +52,7 @@ CMD [] podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false") session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest", "echo", "hello"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("hello")) }) @@ -62,7 +63,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"] podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false") session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) }) @@ -74,7 +75,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"] podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false") session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(4)) }) @@ -86,7 +87,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"] podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false") session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest", "-i"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(5)) }) @@ -97,7 +98,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"] podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false") session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest", "-i"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(5)) }) @@ -110,12 +111,12 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"] podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false") session := podmanTest.Podman([]string{"run", "--entrypoint=uname", "foobar.com/entrypoint:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputStartsWith("Linux")).To(BeTrue()) session = podmanTest.Podman([]string{"run", "--entrypoint", "", "foobar.com/entrypoint:latest", "uname"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputStartsWith("Linux")).To(BeTrue()) }) @@ -127,7 +128,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"] podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false") session := podmanTest.Podman([]string{"run", "--entrypoint=uname", "foobar.com/entrypoint:latest", "-r"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputStartsWith("Linux")).To(BeFalse()) }) }) diff --git a/test/e2e/run_env_test.go b/test/e2e/run_env_test.go index 83d8e8da6..9324c1957 100644 --- a/test/e2e/run_env_test.go +++ b/test/e2e/run_env_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run", func() { @@ -35,38 +36,38 @@ var _ = Describe("Podman run", func() { It("podman run environment test", func() { session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "printenv", "HOME"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("/root") Expect(match).Should(BeTrue()) session = podmanTest.Podman([]string{"run", "--rm", "--user", "2", ALPINE, "printenv", "HOME"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ = session.GrepString("/sbin") Expect(match).Should(BeTrue()) session = podmanTest.Podman([]string{"run", "--rm", "--env", "HOME=/foo", ALPINE, "printenv", "HOME"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ = session.GrepString("/foo") Expect(match).Should(BeTrue()) session = podmanTest.Podman([]string{"run", "--rm", "--env", "FOO=BAR,BAZ", ALPINE, "printenv", "FOO"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ = session.GrepString("BAR,BAZ") Expect(match).Should(BeTrue()) session = podmanTest.Podman([]string{"run", "--rm", "--env", "PATH=/bin", ALPINE, "printenv", "PATH"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ = session.GrepString("/bin") Expect(match).Should(BeTrue()) os.Setenv("FOO", "BAR") session = podmanTest.Podman([]string{"run", "--rm", "--env", "FOO", ALPINE, "printenv", "FOO"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ = session.GrepString("BAR") Expect(match).Should(BeTrue()) os.Unsetenv("FOO") @@ -74,17 +75,17 @@ var _ = Describe("Podman run", func() { session = podmanTest.Podman([]string{"run", "--rm", "--env", "FOO", ALPINE, "printenv", "FOO"}) session.WaitWithDefaultTimeout() Expect(len(session.OutputToString())).To(Equal(0)) - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "printenv"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // This currently does not work // Re-enable when hostname is an env variable session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "printenv"}) session.Wait(10) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ = session.GrepString("HOSTNAME") Expect(match).Should(BeTrue()) }) @@ -95,17 +96,17 @@ var _ = Describe("Podman run", func() { session.WaitWithDefaultTimeout() if IsRemote() { // podman-remote does not support --env-host - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) Expect(session.ErrorToString()).To(ContainSubstring("unknown flag: --env-host")) return } - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("BAR") Expect(match).Should(BeTrue()) session = podmanTest.PodmanAsUser([]string{"run", "--rm", "--env", "FOO=BAR1", "--env-host", ALPINE, "/bin/printenv", "FOO"}, 0, 0, "", env) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ = session.GrepString("BAR1") Expect(match).Should(BeTrue()) os.Unsetenv("FOO") @@ -119,25 +120,25 @@ var _ = Describe("Podman run", func() { } session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "printenv", "http_proxy"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("1.2.3.4") Expect(match).Should(BeTrue()) session = podmanTest.Podman([]string{"run", "--http-proxy=false", ALPINE, "printenv", "http_proxy"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) Expect(session.OutputToString()).To(Equal("")) session = podmanTest.Podman([]string{"run", "--env", "http_proxy=5.6.7.8", ALPINE, "printenv", "http_proxy"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ = session.GrepString("5.6.7.8") Expect(match).Should(BeTrue()) os.Unsetenv("http_proxy") session = podmanTest.Podman([]string{"run", "--http-proxy=false", "--env", "http_proxy=5.6.7.8", ALPINE, "printenv", "http_proxy"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ = session.GrepString("5.6.7.8") Expect(match).Should(BeTrue()) os.Unsetenv("http_proxy") diff --git a/test/e2e/run_exit_test.go b/test/e2e/run_exit_test.go index 3d969cbc2..e86718577 100644 --- a/test/e2e/run_exit_test.go +++ b/test/e2e/run_exit_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run exit", func() { @@ -36,34 +37,30 @@ var _ = Describe("Podman run exit", func() { It("podman run exit define.ExecErrorCodeGeneric", func() { result := podmanTest.Podman([]string{"run", "--foobar", ALPINE, "ls", "$tmp"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(define.ExecErrorCodeGeneric)) + Expect(result).Should(Exit(define.ExecErrorCodeGeneric)) }) It("podman run exit ExecErrorCodeCannotInvoke", func() { result := podmanTest.Podman([]string{"run", ALPINE, "/etc"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(define.ExecErrorCodeCannotInvoke)) + Expect(result).Should(Exit(define.ExecErrorCodeCannotInvoke)) }) It("podman run exit ExecErrorCodeNotFound", func() { result := podmanTest.Podman([]string{"run", ALPINE, "foobar"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Not(Equal(define.ExecErrorCodeGeneric))) - // TODO This is failing we believe because of a race condition - // Between conmon and podman closing the socket early. - // Test with the following, once the race condition is solved - // Expect(result.ExitCode()).To(Equal(define.ExecErrorCodeNotFound)) + Expect(result).Should(Exit(define.ExecErrorCodeNotFound)) }) It("podman run exit 0", func() { result := podmanTest.Podman([]string{"run", ALPINE, "ls"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman run exit 50", func() { result := podmanTest.Podman([]string{"run", ALPINE, "sh", "-c", "exit 50"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(50)) + Expect(result).Should(Exit(50)) }) }) diff --git a/test/e2e/run_memory_test.go b/test/e2e/run_memory_test.go index cb13993f4..e2f2937ba 100644 --- a/test/e2e/run_memory_test.go +++ b/test/e2e/run_memory_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run memory", func() { @@ -44,7 +45,7 @@ var _ = Describe("Podman run memory", func() { session = podmanTest.Podman([]string{"run", "--memory=40m", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.limit_in_bytes"}) } session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("41943040")) }) @@ -62,7 +63,7 @@ var _ = Describe("Podman run memory", func() { } session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("41943040")) }) @@ -70,7 +71,7 @@ var _ = Describe("Podman run memory", func() { SkipIfCgroupV2("memory-swappiness not supported on cgroupV2") session := podmanTest.Podman([]string{"run", "--memory-swappiness=15", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.swappiness"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("15")) }) @@ -88,7 +89,7 @@ var _ = Describe("Podman run memory", func() { } session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("41943040")) }) @@ -103,7 +104,7 @@ var _ = Describe("Podman run memory", func() { session = podmanTest.Podman([]string{"run", "--cgroupns=private", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes"}) } session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(err).To(BeNil()) if CGROUPSV2 { diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index 696cec76c..80a82ea05 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -9,6 +9,7 @@ import ( "github.com/containers/storage/pkg/stringid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" "github.com/uber/jaeger-client-go/utils" ) @@ -40,47 +41,47 @@ var _ = Describe("Podman run networking", func() { It("podman run network connection with default bridge", func() { session := podmanTest.Podman([]string{"run", "-dt", ALPINE, "wget", "www.podman.io"}) session.Wait(90) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run network connection with host", func() { session := podmanTest.Podman([]string{"run", "-dt", "--network", "host", ALPINE, "wget", "www.podman.io"}) session.Wait(90) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run network connection with default", func() { session := podmanTest.Podman([]string{"run", "--network", "default", ALPINE, "wget", "www.podman.io"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run network connection with none", func() { session := podmanTest.Podman([]string{"run", "--network", "none", ALPINE, "wget", "www.podman.io"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) Expect(session.ErrorToString()).To(ContainSubstring("wget: bad address 'www.podman.io'")) }) It("podman run network connection with private", func() { session := podmanTest.Podman([]string{"run", "--network", "private", ALPINE, "wget", "www.podman.io"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run network connection with loopback", func() { session := podmanTest.Podman([]string{"run", "--network", "host", ALPINE, "wget", "www.podman.io"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run network expose port 222", func() { SkipIfRootless("iptables is not supported for rootless users") session := podmanTest.Podman([]string{"run", "-dt", "--expose", "222-223", "-P", ALPINE, "/bin/sh"}) session.Wait(30) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) results := SystemExec("iptables", []string{"-t", "nat", "-L"}) - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) Expect(results.OutputToString()).To(ContainSubstring("222")) Expect(results.OutputToString()).To(ContainSubstring("223")) }) @@ -338,9 +339,9 @@ var _ = Describe("Podman run networking", func() { SkipIfRootless("iptables is not supported for rootless users") session := podmanTest.Podman([]string{"run", "-dt", "-p", "80:8000", ALPINE, "/bin/sh"}) session.Wait(30) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) results := SystemExec("iptables", []string{"-t", "nat", "-L"}) - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) Expect(results.OutputToString()).To(ContainSubstring("8000")) ncBusy := SystemExec("nc", []string{"-l", "-p", "80"}) @@ -350,7 +351,7 @@ var _ = Describe("Podman run networking", func() { It("podman run network expose host port 8081 to container port 8000 using rootlesskit port handler", func() { session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:port_handler=rootlesskit", "-dt", "-p", "8081:8000", ALPINE, "/bin/sh"}) session.Wait(30) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ncBusy := SystemExec("nc", []string{"-l", "-p", "8081"}) Expect(ncBusy).To(ExitWithError()) @@ -359,7 +360,7 @@ var _ = Describe("Podman run networking", func() { It("podman run network expose host port 8082 to container port 8000 using slirp4netns port handler", func() { session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:port_handler=slirp4netns", "-dt", "-p", "8082:8000", ALPINE, "/bin/sh"}) session.Wait(30) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ncBusy := SystemExec("nc", []string{"-l", "-p", "8082"}) Expect(ncBusy).To(ExitWithError()) }) @@ -367,41 +368,41 @@ var _ = Describe("Podman run networking", func() { It("podman run network expose host port 8080 to container port 8000 using invalid port handler", func() { session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:port_handler=invalid", "-dt", "-p", "8080:8000", ALPINE, "/bin/sh"}) session.Wait(30) - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("podman run slirp4netns network with host loopback", func() { session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:allow_host_loopback=true", ALPINE, "ping", "-c1", "10.0.2.2"}) session.Wait(30) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run slirp4netns network with mtu", func() { session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:mtu=9000", ALPINE, "ip", "addr"}) session.Wait(30) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("mtu 9000")) }) It("podman run slirp4netns network with different cidr", func() { slirp4netnsHelp := SystemExec("slirp4netns", []string{"--help"}) - Expect(slirp4netnsHelp.ExitCode()).To(Equal(0)) + Expect(slirp4netnsHelp).Should(Exit(0)) networkConfiguration := "slirp4netns:cidr=192.168.0.0/24,allow_host_loopback=true" session := podmanTest.Podman([]string{"run", "--network", networkConfiguration, ALPINE, "ping", "-c1", "192.168.0.2"}) session.Wait(30) if strings.Contains(slirp4netnsHelp.OutputToString(), "cidr") { - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) } else { - Expect(session.ExitCode()).ToNot(Equal(0)) + Expect(session).To(ExitWithError()) Expect(session.ErrorToString()).To(ContainSubstring("cidr not supported")) } }) It("podman run network bind to 127.0.0.1", func() { slirp4netnsHelp := SystemExec("slirp4netns", []string{"--help"}) - Expect(slirp4netnsHelp.ExitCode()).To(Equal(0)) + Expect(slirp4netnsHelp).Should(Exit(0)) networkConfiguration := "slirp4netns:outbound_addr=127.0.0.1,allow_host_loopback=true" if strings.Contains(slirp4netnsHelp.OutputToString(), "outbound-addr") { @@ -410,13 +411,13 @@ var _ = Describe("Podman run networking", func() { session.Wait(30) ncListener.Wait(30) - Expect(session.ExitCode()).To(Equal(0)) - Expect(ncListener.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) + Expect(ncListener).Should(Exit(0)) Expect(ncListener.ErrorToString()).To(ContainSubstring("127.0.0.1")) } else { session := podmanTest.Podman([]string{"run", "--network", networkConfiguration, "-dt", ALPINE, "nc", "-w", "2", "10.0.2.2", "8083"}) session.Wait(30) - Expect(session.ExitCode()).ToNot(Equal(0)) + Expect(session).To(ExitWithError()) Expect(session.ErrorToString()).To(ContainSubstring("outbound_addr not supported")) } }) @@ -426,7 +427,7 @@ var _ = Describe("Podman run networking", func() { Expect(err).To(BeNil()) slirp4netnsHelp := SystemExec("slirp4netns", []string{"--help"}) - Expect(slirp4netnsHelp.ExitCode()).To(Equal(0)) + Expect(slirp4netnsHelp).Should(Exit(0)) networkConfiguration := fmt.Sprintf("slirp4netns:outbound_addr=%s,allow_host_loopback=true", ip.String()) if strings.Contains(slirp4netnsHelp.OutputToString(), "outbound-addr") { @@ -435,13 +436,13 @@ var _ = Describe("Podman run networking", func() { session.Wait(30) ncListener.Wait(30) - Expect(session.ExitCode()).To(Equal(0)) - Expect(ncListener.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) + Expect(ncListener).Should(Exit(0)) Expect(ncListener.ErrorToString()).To(ContainSubstring(ip.String())) } else { session := podmanTest.Podman([]string{"run", "--network", networkConfiguration, "-dt", ALPINE, "nc", "-w", "2", "10.0.2.2", "8084"}) session.Wait(30) - Expect(session.ExitCode()).ToNot(Equal(0)) + Expect(session).To(ExitWithError()) Expect(session.ErrorToString()).To(ContainSubstring("outbound_addr not supported")) } }) @@ -449,10 +450,10 @@ var _ = Describe("Podman run networking", func() { It("podman run network expose ports in image metadata", func() { session := podmanTest.Podman([]string{"create", "--name", "test", "-t", "-P", nginx}) session.Wait(90) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) results := podmanTest.Podman([]string{"inspect", "test"}) results.Wait(30) - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) Expect(results.OutputToString()).To(ContainSubstring(`"80/tcp":`)) }) @@ -461,11 +462,11 @@ var _ = Describe("Podman run networking", func() { session := podmanTest.Podman([]string{"run", "--name", "test", "-dt", "-p", "80", ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "test"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) containerConfig := inspect.InspectContainerToJSON() Expect(containerConfig[0].NetworkSettings.Ports).To(Not(BeNil())) @@ -476,7 +477,7 @@ var _ = Describe("Podman run networking", func() { It("podman run hostname test", func() { session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "printenv", "HOSTNAME"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString(hostname) Expect(match).Should(BeFalse()) }) @@ -484,21 +485,21 @@ var _ = Describe("Podman run networking", func() { It("podman run --net host hostname test", func() { session := podmanTest.Podman([]string{"run", "--rm", "--net", "host", ALPINE, "printenv", "HOSTNAME"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString(hostname) Expect(match).Should(BeTrue()) }) It("podman run --net host --uts host hostname test", func() { session := podmanTest.Podman([]string{"run", "--rm", "--net", "host", "--uts", "host", ALPINE, "printenv", "HOSTNAME"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString(hostname) Expect(match).Should(BeTrue()) }) It("podman run --uts host hostname test", func() { session := podmanTest.Podman([]string{"run", "--rm", "--uts", "host", ALPINE, "printenv", "HOSTNAME"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString(hostname) Expect(match).Should(BeTrue()) }) @@ -506,7 +507,7 @@ var _ = Describe("Podman run networking", func() { It("podman run --net host --hostname ... hostname test", func() { session := podmanTest.Podman([]string{"run", "--rm", "--net", "host", "--hostname", "foobar", ALPINE, "printenv", "HOSTNAME"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("foobar") Expect(match).Should(BeTrue()) }) @@ -514,7 +515,7 @@ var _ = Describe("Podman run networking", func() { It("podman run --hostname ... hostname test", func() { session := podmanTest.Podman([]string{"run", "--rm", "--hostname", "foobar", ALPINE, "printenv", "HOSTNAME"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("foobar") Expect(match).Should(BeTrue()) }) @@ -523,59 +524,59 @@ var _ = Describe("Podman run networking", func() { ctrName := "ctrToJoin" ctr1 := podmanTest.RunTopContainer(ctrName) ctr1.WaitWithDefaultTimeout() - Expect(ctr1.ExitCode()).To(Equal(0)) + Expect(ctr1).Should(Exit(0)) ctr2 := podmanTest.Podman([]string{"run", "-d", "--net=container:" + ctrName, "--uts=container:" + ctrName, ALPINE, "true"}) ctr2.WaitWithDefaultTimeout() - Expect(ctr2.ExitCode()).To(Equal(0)) + Expect(ctr2).Should(Exit(0)) }) It("podman run --net container: copies hosts and resolv", func() { ctrName := "ctr1" ctr1 := podmanTest.RunTopContainer(ctrName) ctr1.WaitWithDefaultTimeout() - Expect(ctr1.ExitCode()).To(Equal(0)) + Expect(ctr1).Should(Exit(0)) // Exec in and modify /etc/resolv.conf and /etc/hosts exec1 := podmanTest.Podman([]string{"exec", ctrName, "sh", "-c", "echo nameserver 192.0.2.1 > /etc/resolv.conf"}) exec1.WaitWithDefaultTimeout() - Expect(exec1.ExitCode()).To(Equal(0)) + Expect(exec1).Should(Exit(0)) exec2 := podmanTest.Podman([]string{"exec", ctrName, "sh", "-c", "echo 192.0.2.2 test1 > /etc/hosts"}) exec2.WaitWithDefaultTimeout() - Expect(exec2.ExitCode()).To(Equal(0)) + Expect(exec2).Should(Exit(0)) ctrName2 := "ctr2" ctr2 := podmanTest.Podman([]string{"run", "-d", "--net=container:" + ctrName, "--name", ctrName2, ALPINE, "top"}) ctr2.WaitWithDefaultTimeout() - Expect(ctr2.ExitCode()).To(Equal(0)) + Expect(ctr2).Should(Exit(0)) exec3 := podmanTest.Podman([]string{"exec", "-i", ctrName2, "cat", "/etc/resolv.conf"}) exec3.WaitWithDefaultTimeout() - Expect(exec3.ExitCode()).To(Equal(0)) + Expect(exec3).Should(Exit(0)) Expect(exec3.OutputToString()).To(ContainSubstring("nameserver 192.0.2.1")) exec4 := podmanTest.Podman([]string{"exec", "-i", ctrName2, "cat", "/etc/hosts"}) exec4.WaitWithDefaultTimeout() - Expect(exec4.ExitCode()).To(Equal(0)) + Expect(exec4).Should(Exit(0)) Expect(exec4.OutputToString()).To(ContainSubstring("192.0.2.2 test1")) }) It("podman run /etc/hosts contains --hostname", func() { session := podmanTest.Podman([]string{"run", "--rm", "--hostname", "foohostname", ALPINE, "grep", "foohostname", "/etc/hosts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run --uidmap /etc/hosts contains --hostname", func() { SkipIfRootless("uidmap population of cninetworks not supported for rootless users") session := podmanTest.Podman([]string{"run", "--uidmap", "0:100000:1000", "--rm", "--hostname", "foohostname", ALPINE, "grep", "foohostname", "/etc/hosts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--uidmap", "0:100000:1000", "--rm", "--hostname", "foohostname", "-v", "/etc/hosts:/etc/hosts", ALPINE, "grep", "foohostname", "/etc/hosts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) }) It("podman run network in user created network namespace", func() { @@ -584,15 +585,15 @@ var _ = Describe("Podman run networking", func() { Skip("Cannot be run within a container.") } addXXX := SystemExec("ip", []string{"netns", "add", "xxx"}) - Expect(addXXX.ExitCode()).To(Equal(0)) + Expect(addXXX).Should(Exit(0)) defer func() { delXXX := SystemExec("ip", []string{"netns", "delete", "xxx"}) - Expect(delXXX.ExitCode()).To(Equal(0)) + Expect(delXXX).Should(Exit(0)) }() session := podmanTest.Podman([]string{"run", "-dt", "--net", "ns:/run/netns/xxx", ALPINE, "wget", "www.podman.io"}) session.Wait(90) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run n user created network namespace with resolv.conf", func() { @@ -601,22 +602,22 @@ var _ = Describe("Podman run networking", func() { Skip("Cannot be run within a container.") } addXXX2 := SystemExec("ip", []string{"netns", "add", "xxx2"}) - Expect(addXXX2.ExitCode()).To(Equal(0)) + Expect(addXXX2).Should(Exit(0)) defer func() { delXXX2 := SystemExec("ip", []string{"netns", "delete", "xxx2"}) - Expect(delXXX2.ExitCode()).To(Equal(0)) + Expect(delXXX2).Should(Exit(0)) }() mdXXX2 := SystemExec("mkdir", []string{"-p", "/etc/netns/xxx2"}) - Expect(mdXXX2.ExitCode()).To(Equal(0)) + Expect(mdXXX2).Should(Exit(0)) defer os.RemoveAll("/etc/netns/xxx2") nsXXX2 := SystemExec("bash", []string{"-c", "echo nameserver 11.11.11.11 > /etc/netns/xxx2/resolv.conf"}) - Expect(nsXXX2.ExitCode()).To(Equal(0)) + Expect(nsXXX2).Should(Exit(0)) session := podmanTest.Podman([]string{"run", "--net", "ns:/run/netns/xxx2", ALPINE, "cat", "/etc/resolv.conf"}) session.Wait(90) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("11.11.11.11")) }) @@ -632,12 +633,12 @@ var _ = Describe("Podman run networking", func() { ipAddr := "10.25.30.128" create := podmanTest.Podman([]string{"network", "create", "--subnet", "10.25.30.0/24", netName}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(BeZero()) + Expect(create).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) run := podmanTest.Podman([]string{"run", "-t", "-i", "--rm", "--net", netName, "--ip", ipAddr, ALPINE, "ip", "addr"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(BeZero()) + Expect(run).Should(Exit(0)) Expect(run.OutputToString()).To(ContainSubstring(ipAddr)) }) @@ -645,23 +646,23 @@ var _ = Describe("Podman run networking", func() { netName := stringid.GenerateNonCryptoID() create := podmanTest.Podman([]string{"network", "create", netName}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(BeZero()) + Expect(create).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) name := "nc-server" run := podmanTest.Podman([]string{"run", "--log-driver", "k8s-file", "-d", "--name", name, "--net", netName, ALPINE, "nc", "-l", "-p", "8080"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) // NOTE: we force the k8s-file log driver to make sure the // tests are passing inside a container. run = podmanTest.Podman([]string{"run", "--log-driver", "k8s-file", "--rm", "--net", netName, "--uidmap", "0:1:4096", ALPINE, "sh", "-c", fmt.Sprintf("echo podman | nc -w 1 %s.dns.podman 8080", name)}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) log := podmanTest.Podman([]string{"logs", name}) log.WaitWithDefaultTimeout() - Expect(log.ExitCode()).To(Equal(0)) + Expect(log).Should(Exit(0)) Expect(log.OutputToString()).To(Equal("podman")) }) @@ -671,23 +672,23 @@ var _ = Describe("Podman run networking", func() { podname := "testpod" create := podmanTest.Podman([]string{"network", "create", "--subnet", "10.25.40.0/24", netName}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(BeZero()) + Expect(create).Should(Exit(0)) defer podmanTest.removeCNINetwork(netName) run := podmanTest.Podman([]string{"run", "-t", "-i", "--rm", "--pod", "new:" + podname, "--net", netName, "--ip", ipAddr, ALPINE, "ip", "addr"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(BeZero()) + Expect(run).Should(Exit(0)) Expect(run.OutputToString()).To(ContainSubstring(ipAddr)) podrm := podmanTest.Podman([]string{"pod", "rm", "-f", podname}) podrm.WaitWithDefaultTimeout() - Expect(podrm.ExitCode()).To(BeZero()) + Expect(podrm).Should(Exit(0)) }) It("podman run net=host adds entry to /etc/hosts", func() { run := podmanTest.Podman([]string{"run", "--net=host", ALPINE, "cat", "/etc/hosts"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(BeZero()) + Expect(run).Should(Exit(0)) Expect(strings.Contains(run.OutputToString(), "127.0.1.1")).To(BeTrue()) }) @@ -695,7 +696,7 @@ var _ = Describe("Podman run networking", func() { hostname := "testctr" run := podmanTest.Podman([]string{"run", "--net=host", "--hostname", hostname, ALPINE, "hostname"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(BeZero()) + Expect(run).Should(Exit(0)) Expect(strings.Contains(run.OutputToString(), hostname)).To(BeTrue()) }) @@ -703,7 +704,7 @@ var _ = Describe("Podman run networking", func() { hostname := "testctr" run := podmanTest.Podman([]string{"run", "--net=none", "--hostname", hostname, ALPINE, "hostname"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(BeZero()) + Expect(run).Should(Exit(0)) Expect(strings.Contains(run.OutputToString(), hostname)).To(BeTrue()) }) @@ -711,7 +712,7 @@ var _ = Describe("Podman run networking", func() { hostname := "testctr" run := podmanTest.Podman([]string{"run", "--net=none", "--hostname", hostname, ALPINE, "cat", "/etc/hosts"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(BeZero()) + Expect(run).Should(Exit(0)) Expect(strings.Contains(run.OutputToString(), hostname)).To(BeTrue()) }) @@ -719,11 +720,11 @@ var _ = Describe("Podman run networking", func() { hostname := "testctr" run := podmanTest.Podman([]string{"run", netns, "--hostname", hostname, ALPINE, "ping", "-c", "1", hostname}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(BeZero()) + Expect(run).Should(Exit(0)) run = podmanTest.Podman([]string{"run", netns, "--hostname", hostname, "--name", "test", ALPINE, "ping", "-c", "1", "test"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(BeZero()) + Expect(run).Should(Exit(0)) } It("podman attempt to ping container name and hostname --net=none", func() { @@ -742,35 +743,35 @@ var _ = Describe("Podman run networking", func() { pod := "testpod" session := podmanTest.Podman([]string{"pod", "create", "--name", pod}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) net := "IntTest" + stringid.GenerateNonCryptoID() session = podmanTest.Podman([]string{"network", "create", net}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) pod2 := "testpod2" session = podmanTest.Podman([]string{"pod", "create", "--network", net, "--name", pod2}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--name", "con1", "--network", net, ALPINE, "nslookup", "con1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--name", "con2", "--pod", pod, "--network", net, ALPINE, "nslookup", "con2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--name", "con3", "--pod", pod2, ALPINE, "nslookup", "con1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) Expect(session.ErrorToString()).To(ContainSubstring("can't resolve 'con1'")) session = podmanTest.Podman([]string{"run", "--name", "con4", "--network", net, ALPINE, "nslookup", pod2 + ".dns.podman"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) }) It("podman run check dnsname adds dns search domain", func() { @@ -779,11 +780,11 @@ var _ = Describe("Podman run networking", func() { session := podmanTest.Podman([]string{"network", "create", net}) session.WaitWithDefaultTimeout() defer podmanTest.removeCNINetwork(net) - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--network", net, ALPINE, "cat", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("search dns.podman")) }) @@ -792,7 +793,7 @@ var _ = Describe("Podman run networking", func() { ctrName := "testctr" ctr := podmanTest.Podman([]string{"run", "-d", "--net=bridge", "--name", ctrName, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(BeZero()) + Expect(ctr).Should(Exit(0)) inspectOut := podmanTest.InspectContainer(ctrName) Expect(len(inspectOut)).To(Equal(1)) diff --git a/test/e2e/run_ns_test.go b/test/e2e/run_ns_test.go index c72891107..db81cc1a7 100644 --- a/test/e2e/run_ns_test.go +++ b/test/e2e/run_ns_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run ns", func() { @@ -38,12 +39,12 @@ var _ = Describe("Podman run ns", func() { SkipIfRootlessCgroupsV1("Not supported for rootless + CGroupsV1") session := podmanTest.Podman([]string{"run", fedoraMinimal, "bash", "-c", "echo $$"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("1")) session = podmanTest.Podman([]string{"run", "--pid=host", fedoraMinimal, "bash", "-c", "echo $$"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(Equal("1"))) session = podmanTest.Podman([]string{"run", "--pid=badpid", fedoraMinimal, "bash", "-c", "echo $$"}) @@ -54,7 +55,7 @@ var _ = Describe("Podman run ns", func() { It("podman run --cgroup private test", func() { session := podmanTest.Podman([]string{"run", "--cgroupns=private", fedoraMinimal, "cat", "/proc/self/cgroup"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(output).ToNot(ContainSubstring("slice")) @@ -62,41 +63,41 @@ var _ = Describe("Podman run ns", func() { It("podman run ipcns test", func() { setup := SystemExec("ls", []string{"--inode", "-d", "/dev/shm"}) - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) hostShm := setup.OutputToString() session := podmanTest.Podman([]string{"run", "--ipc=host", fedoraMinimal, "ls", "--inode", "-d", "/dev/shm"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(hostShm)) }) It("podman run ipcns ipcmk host test", func() { setup := SystemExec("ipcmk", []string{"-M", "1024"}) - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) output := strings.Split(setup.OutputToString(), " ") ipc := output[len(output)-1] session := podmanTest.Podman([]string{"run", "--ipc=host", fedoraMinimal, "ipcs", "-m", "-i", ipc}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) setup = SystemExec("ipcrm", []string{"-m", ipc}) - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) }) It("podman run ipcns ipcmk container test", func() { setup := podmanTest.Podman([]string{"run", "-d", "--name", "test1", fedoraMinimal, "sleep", "999"}) setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "test1", "ipcmk", "-M", "1024"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := strings.Split(session.OutputToString(), " ") ipc := output[len(output)-1] session = podmanTest.Podman([]string{"run", "--ipc=container:test1", fedoraMinimal, "ipcs", "-m", "-i", ipc}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run bad ipc pid test", func() { @@ -108,7 +109,7 @@ var _ = Describe("Podman run ns", func() { It("podman run mounts fresh cgroup", func() { session := podmanTest.Podman([]string{"run", fedoraMinimal, "grep", "cgroup", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(output).ToNot(ContainSubstring("..")) }) @@ -129,13 +130,13 @@ var _ = Describe("Podman run ns", func() { session := podmanTest.Podman([]string{"run", "--ipc=host", "--pid=host", ALPINE, "ls", "-l", "/proc/self/ns/pid"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) fields = strings.Split(session.OutputToString(), " ") ctrPidNS := strings.TrimSuffix(fields[len(fields)-1], "\n") session = podmanTest.Podman([]string{"run", "--ipc=host", "--pid=host", ALPINE, "ls", "-l", "/proc/self/ns/ipc"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) fields = strings.Split(session.OutputToString(), " ") ctrIpcNS := strings.TrimSuffix(fields[len(fields)-1], "\n") diff --git a/test/e2e/run_passwd_test.go b/test/e2e/run_passwd_test.go index 0d5dd5f3b..3e7e73fad 100644 --- a/test/e2e/run_passwd_test.go +++ b/test/e2e/run_passwd_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run passwd", func() { @@ -36,27 +37,27 @@ var _ = Describe("Podman run passwd", func() { It("podman run no user specified ", func() { session := podmanTest.Podman([]string{"run", "--read-only", BB, "mount"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("passwd")).To(BeFalse()) }) It("podman run user specified in container", func() { session := podmanTest.Podman([]string{"run", "--read-only", "-u", "bin", BB, "mount"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("passwd")).To(BeFalse()) }) It("podman run UID specified in container", func() { session := podmanTest.Podman([]string{"run", "--read-only", "-u", "2:1", BB, "mount"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("passwd")).To(BeFalse()) }) It("podman run UID not specified in container", func() { session := podmanTest.Podman([]string{"run", "--read-only", "-u", "20001:1", BB, "mount"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("passwd")).To(BeTrue()) }) @@ -68,48 +69,48 @@ USER 1000`, ALPINE) podmanTest.BuildImage(dockerfile, imgName, "false") session := podmanTest.Podman([]string{"run", "--rm", imgName, "ls", "/etc/"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(ContainSubstring("passwd"))) }) It("podman run with no user specified does not change --group specified", func() { session := podmanTest.Podman([]string{"run", "--read-only", BB, "mount"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("/etc/group")).To(BeFalse()) }) It("podman run group specified in container", func() { session := podmanTest.Podman([]string{"run", "--read-only", "-u", "root:bin", BB, "mount"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("/etc/group")).To(BeFalse()) }) It("podman run non-numeric group not specified in container", func() { session := podmanTest.Podman([]string{"run", "--read-only", "-u", "root:doesnotexist", BB, "mount"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("podman run numeric group specified in container", func() { session := podmanTest.Podman([]string{"run", "--read-only", "-u", "root:11", BB, "mount"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("/etc/group")).To(BeFalse()) }) It("podman run numeric group not specified in container", func() { session := podmanTest.Podman([]string{"run", "--read-only", "-u", "20001:20001", BB, "mount"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("/etc/group")).To(BeTrue()) }) It("podman run numeric user not specified in container modifies group", func() { session := podmanTest.Podman([]string{"run", "--read-only", "-u", "20001", BB, "mount"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("/etc/group")).To(BeTrue()) }) @@ -121,7 +122,7 @@ USER 1000`, ALPINE) podmanTest.BuildImage(dockerfile, imgName, "false") session := podmanTest.Podman([]string{"run", "--rm", imgName, "ls", "/etc/"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(ContainSubstring("/etc/group"))) }) }) diff --git a/test/e2e/run_privileged_test.go b/test/e2e/run_privileged_test.go index 0bf68e20b..3e4262cfb 100644 --- a/test/e2e/run_privileged_test.go +++ b/test/e2e/run_privileged_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" "github.com/syndtr/gocapability/capability" ) @@ -61,7 +62,7 @@ var _ = Describe("Podman privileged container tests", func() { It("podman privileged make sure sys is mounted rw", func() { session := podmanTest.Podman([]string{"run", "--privileged", BB, "mount"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, lines := session.GrepString("sysfs") Expect(ok).To(BeTrue()) Expect(lines[0]).To(ContainSubstring("sysfs (rw,")) @@ -69,11 +70,11 @@ var _ = Describe("Podman privileged container tests", func() { It("podman privileged CapEff", func() { hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"}) - Expect(hostCap.ExitCode()).To(Equal(0)) + Expect(hostCap).Should(Exit(0)) session := podmanTest.Podman([]string{"run", "--privileged", BB, "awk", "/^CapEff/ { print $2 }", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString()) }) @@ -81,11 +82,11 @@ var _ = Describe("Podman privileged container tests", func() { It("podman cap-add CapEff", func() { // Get caps of current process hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"}) - Expect(hostCap.ExitCode()).To(Equal(0)) + Expect(hostCap).Should(Exit(0)) session := podmanTest.Podman([]string{"run", "--cap-add", "all", BB, "awk", "/^CapEff/ { print $2 }", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString()) }) @@ -93,11 +94,11 @@ var _ = Describe("Podman privileged container tests", func() { It("podman cap-add CapEff with --user", func() { // Get caps of current process hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"}) - Expect(hostCap.ExitCode()).To(Equal(0)) + Expect(hostCap).Should(Exit(0)) session := podmanTest.Podman([]string{"run", "--user=bin", "--cap-add", "all", BB, "awk", "/^CapEff/ { print $2 }", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString()) }) @@ -105,24 +106,24 @@ var _ = Describe("Podman privileged container tests", func() { It("podman cap-drop CapEff", func() { session := podmanTest.Podman([]string{"run", "--cap-drop", "all", BB, "grep", "CapEff", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) capEff := strings.Split(session.OutputToString(), " ") Expect("0000000000000000").To(Equal(capEff[1])) }) It("podman privileged should disable seccomp by default", func() { hostSeccomp := SystemExec("grep", []string{"-Ei", "^Seccomp:\\s+0$", "/proc/self/status"}) - Expect(hostSeccomp.ExitCode()).To(Equal(0)) + Expect(hostSeccomp).Should(Exit(0)) session := podmanTest.Podman([]string{"run", "--privileged", ALPINE, "grep", "-Ei", "^Seccomp:\\s+0$", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman non-privileged should have very few devices", func() { session := podmanTest.Podman([]string{"run", "-t", BB, "ls", "-l", "/dev"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(17)) }) @@ -130,7 +131,7 @@ var _ = Describe("Podman privileged container tests", func() { SkipIfRootless("FIXME: This seems to be broken for rootless mode, /dev/ is close to the same") session := podmanTest.Podman([]string{"run", "--privileged", ALPINE, "ls", "-l", "/dev"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 20)) }) @@ -149,12 +150,12 @@ var _ = Describe("Podman privileged container tests", func() { session := podmanTest.Podman([]string{"run", BB, "grep", "NoNewPrivs", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) privs := strings.Split(session.OutputToString(), ":") session = podmanTest.Podman([]string{"run", "--security-opt", "no-new-privileges", BB, "grep", "NoNewPrivs", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) noprivs := strings.Split(session.OutputToString(), ":") Expect(privs[1]).To(Not(Equal(noprivs[1]))) diff --git a/test/e2e/run_restart_test.go b/test/e2e/run_restart_test.go index c996bdb25..35768ca51 100644 --- a/test/e2e/run_restart_test.go +++ b/test/e2e/run_restart_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run restart containers", func() { @@ -35,15 +36,15 @@ var _ = Describe("Podman run restart containers", func() { It("Podman start after successful run", func() { session := podmanTest.Podman([]string{"run", "--name", "test", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"wait", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session2 := podmanTest.Podman([]string{"start", "--attach", "test"}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) }) It("Podman start after signal kill", func() { @@ -53,10 +54,10 @@ var _ = Describe("Podman run restart containers", func() { killSession := podmanTest.Podman([]string{"kill", "-s", "9", "test1"}) killSession.WaitWithDefaultTimeout() - Expect(killSession.ExitCode()).To(Equal(0)) + Expect(killSession).Should(Exit(0)) session2 := podmanTest.Podman([]string{"start", "test1"}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) }) }) diff --git a/test/e2e/run_seccomp_test.go b/test/e2e/run_seccomp_test.go index ed1cdeecd..3a6adca0e 100644 --- a/test/e2e/run_seccomp_test.go +++ b/test/e2e/run_seccomp_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run", func() { @@ -35,20 +36,20 @@ var _ = Describe("Podman run", func() { It("podman run --seccomp-policy default", func() { session := podmanTest.Podman([]string{"run", "--seccomp-policy", "default", alpineSeccomp, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run --seccomp-policy ''", func() { // Empty string is interpreted as "default". session := podmanTest.Podman([]string{"run", "--seccomp-policy", "", alpineSeccomp, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run --seccomp-policy invalid", func() { session := podmanTest.Podman([]string{"run", "--seccomp-policy", "invalid", alpineSeccomp, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).ToNot(Equal(0)) + Expect(session).To(ExitWithError()) }) It("podman run --seccomp-policy image (block all syscalls)", func() { @@ -57,12 +58,12 @@ var _ = Describe("Podman run", func() { // TODO: we're getting a "cannot start a container that has // stopped" error which seems surprising. Investigate // why that is so. - Expect(session.ExitCode()).ToNot(Equal(0)) + Expect(session).To(ExitWithError()) }) It("podman run --seccomp-policy image (bogus profile)", func() { session := podmanTest.Podman([]string{"run", "--seccomp-policy", "image", alpineBogusSeccomp, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) }) diff --git a/test/e2e/run_security_labels_test.go b/test/e2e/run_security_labels_test.go index ae86bb690..1da80e61d 100644 --- a/test/e2e/run_security_labels_test.go +++ b/test/e2e/run_security_labels_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman generate kube", func() { @@ -37,11 +38,11 @@ var _ = Describe("Podman generate kube", func() { It("podman security labels", func() { test1 := podmanTest.Podman([]string{"create", "--label", "io.containers.capabilities=setuid,setgid", "--name", "test1", "alpine", "echo", "test1"}) test1.WaitWithDefaultTimeout() - Expect(test1.ExitCode()).To(BeZero()) + Expect(test1).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "test1"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) ctr := inspect.InspectContainerToJSON() caps := strings.Join(ctr[0].EffectiveCaps, ",") @@ -51,11 +52,11 @@ var _ = Describe("Podman generate kube", func() { It("podman bad security labels", func() { test1 := podmanTest.Podman([]string{"create", "--label", "io.containers.capabilities=sys_admin", "--name", "test1", "alpine", "echo", "test1"}) test1.WaitWithDefaultTimeout() - Expect(test1.ExitCode()).To(BeZero()) + Expect(test1).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "test1"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) ctr := inspect.InspectContainerToJSON() caps := strings.Join(ctr[0].EffectiveCaps, ",") @@ -65,11 +66,11 @@ var _ = Describe("Podman generate kube", func() { It("podman --cap-add sys_admin security labels", func() { test1 := podmanTest.Podman([]string{"create", "--cap-add", "SYS_ADMIN", "--label", "io.containers.capabilities=sys_admin", "--name", "test1", "alpine", "echo", "test1"}) test1.WaitWithDefaultTimeout() - Expect(test1.ExitCode()).To(BeZero()) + Expect(test1).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "test1"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) ctr := inspect.InspectContainerToJSON() caps := strings.Join(ctr[0].EffectiveCaps, ",") @@ -79,11 +80,11 @@ var _ = Describe("Podman generate kube", func() { It("podman --cap-drop all sys_admin security labels", func() { test1 := podmanTest.Podman([]string{"create", "--cap-drop", "all", "--label", "io.containers.capabilities=sys_admin", "--name", "test1", "alpine", "echo", "test1"}) test1.WaitWithDefaultTimeout() - Expect(test1.ExitCode()).To(BeZero()) + Expect(test1).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "test1"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) ctr := inspect.InspectContainerToJSON() caps := strings.Join(ctr[0].EffectiveCaps, ",") @@ -93,19 +94,19 @@ var _ = Describe("Podman generate kube", func() { It("podman security labels from image", func() { test1 := podmanTest.Podman([]string{"create", "--name", "test1", "alpine", "echo", "test1"}) test1.WaitWithDefaultTimeout() - Expect(test1.ExitCode()).To(BeZero()) + Expect(test1).Should(Exit(0)) commit := podmanTest.Podman([]string{"commit", "-c", "label=io.containers.capabilities=sys_chroot,setuid", "test1", "image1"}) commit.WaitWithDefaultTimeout() - Expect(commit.ExitCode()).To(BeZero()) + Expect(commit).Should(Exit(0)) image1 := podmanTest.Podman([]string{"create", "--name", "test2", "image1", "echo", "test1"}) image1.WaitWithDefaultTimeout() - Expect(image1.ExitCode()).To(BeZero()) + Expect(image1).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "test2"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) ctr := inspect.InspectContainerToJSON() caps := strings.Join(ctr[0].EffectiveCaps, ",") @@ -116,11 +117,11 @@ var _ = Describe("Podman generate kube", func() { It("podman --privileged security labels", func() { pull := podmanTest.Podman([]string{"create", "--privileged", "--label", "io.containers.capabilities=setuid,setgid", "--name", "test1", "alpine", "echo", "test"}) pull.WaitWithDefaultTimeout() - Expect(pull.ExitCode()).To(BeZero()) + Expect(pull).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "test1"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) ctr := inspect.InspectContainerToJSON() caps := strings.Join(ctr[0].EffectiveCaps, ",") @@ -138,11 +139,11 @@ LABEL io.containers.capabilities=chown,kill`, ALPINE) test1 := podmanTest.Podman([]string{"create", "--name", "test1", image, "echo", "test1"}) test1.WaitWithDefaultTimeout() - Expect(test1.ExitCode()).To(BeZero()) + Expect(test1).Should(Exit(0)) inspect := podmanTest.Podman([]string{"inspect", "test1"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) ctr := inspect.InspectContainerToJSON() caps := strings.Join(ctr[0].EffectiveCaps, ",") diff --git a/test/e2e/run_selinux_test.go b/test/e2e/run_selinux_test.go index 2886f06c1..1a5ef4d5d 100644 --- a/test/e2e/run_selinux_test.go +++ b/test/e2e/run_selinux_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" "github.com/opencontainers/selinux/go-selinux" ) @@ -40,7 +41,7 @@ var _ = Describe("Podman run", func() { It("podman run selinux", func() { session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("container_t") Expect(match).Should(BeTrue()) }) @@ -48,7 +49,7 @@ var _ = Describe("Podman run", func() { It("podman run selinux grep test", func() { session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "label=level:s0:c1,c2", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("s0:c1,c2") Expect(match).Should(BeTrue()) }) @@ -56,7 +57,7 @@ var _ = Describe("Podman run", func() { It("podman run selinux disable test", func() { session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "label=disable", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("spc_t") Expect(match).Should(BeTrue()) }) @@ -64,7 +65,7 @@ var _ = Describe("Podman run", func() { It("podman run selinux type check test", func() { session := podmanTest.Podman([]string{"run", "-it", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match1, _ := session.GrepString("container_t") match2, _ := session.GrepString("svirt_lxc_net_t") Expect(match1 || match2).Should(BeTrue()) @@ -73,7 +74,7 @@ var _ = Describe("Podman run", func() { It("podman run selinux type setup test", func() { session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "label=type:spc_t", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("spc_t") Expect(match).Should(BeTrue()) }) @@ -81,7 +82,7 @@ var _ = Describe("Podman run", func() { It("podman privileged selinux", func() { session := podmanTest.Podman([]string{"run", "--privileged", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("spc_t") Expect(match).Should(BeTrue()) }) @@ -89,7 +90,7 @@ var _ = Describe("Podman run", func() { It("podman test selinux label resolv.conf", func() { session := podmanTest.Podman([]string{"run", fedoraMinimal, "ls", "-Z", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("container_file_t") Expect(match).Should(BeTrue()) }) @@ -97,7 +98,7 @@ var _ = Describe("Podman run", func() { It("podman test selinux label hosts", func() { session := podmanTest.Podman([]string{"run", fedoraMinimal, "ls", "-Z", "/etc/hosts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("container_file_t") Expect(match).Should(BeTrue()) }) @@ -105,7 +106,7 @@ var _ = Describe("Podman run", func() { It("podman test selinux label hostname", func() { session := podmanTest.Podman([]string{"run", fedoraMinimal, "ls", "-Z", "/etc/hostname"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("container_file_t") Expect(match).Should(BeTrue()) }) @@ -113,7 +114,7 @@ var _ = Describe("Podman run", func() { It("podman test selinux label /run/secrets", func() { session := podmanTest.Podman([]string{"run", fedoraMinimal, "ls", "-dZ", "/run/secrets"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("container_file_t") Expect(match).Should(BeTrue()) }) @@ -121,7 +122,7 @@ var _ = Describe("Podman run", func() { It("podman test selinux --privileged label resolv.conf", func() { session := podmanTest.Podman([]string{"run", "--privileged", fedoraMinimal, "ls", "-Z", "/etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("container_file_t") Expect(match).Should(BeTrue()) }) @@ -129,7 +130,7 @@ var _ = Describe("Podman run", func() { It("podman test selinux --privileged label hosts", func() { session := podmanTest.Podman([]string{"run", "--privileged", fedoraMinimal, "ls", "-Z", "/etc/hosts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("container_file_t") Expect(match).Should(BeTrue()) }) @@ -137,7 +138,7 @@ var _ = Describe("Podman run", func() { It("podman test selinux --privileged label hostname", func() { session := podmanTest.Podman([]string{"run", "--privileged", fedoraMinimal, "ls", "-Z", "/etc/hostname"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("container_file_t") Expect(match).Should(BeTrue()) }) @@ -145,7 +146,7 @@ var _ = Describe("Podman run", func() { It("podman test selinux --privileged label /run/secrets", func() { session := podmanTest.Podman([]string{"run", "--privileged", fedoraMinimal, "ls", "-dZ", "/run/secrets"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("container_file_t") Expect(match).Should(BeTrue()) }) @@ -153,19 +154,19 @@ var _ = Describe("Podman run", func() { It("podman run selinux file type setup test", func() { session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "label=type:spc_t", "--security-opt", "label=filetype:container_var_lib_t", fedoraMinimal, "ls", "-Z", "/dev"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("container_var_lib_t") Expect(match).Should(BeTrue()) session = podmanTest.Podman([]string{"run", "-it", "--security-opt", "label=type:spc_t", "--security-opt", "label=filetype:foobar", fedoraMinimal, "ls", "-Z", "/dev"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(126)) + Expect(session).Should(Exit(126)) }) It("podman exec selinux check", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() - Expect(setup.ExitCode()).To(Equal(0)) + Expect(setup).Should(Exit(0)) session := podmanTest.Podman([]string{"exec", "test1", "cat", "/proc/1/attr/current"}) session.WaitWithDefaultTimeout() @@ -177,7 +178,7 @@ var _ = Describe("Podman run", func() { It("podman run --privileged and --security-opt SELinux options", func() { session := podmanTest.Podman([]string{"run", "-it", "--privileged", "--security-opt", "label=type:spc_t", "--security-opt", "label=level:s0:c1,c2", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("spc_t") Expect(match).To(BeTrue()) match2, _ := session.GrepString("s0:c1,c2") @@ -187,90 +188,90 @@ var _ = Describe("Podman run", func() { It("podman pod container share SELinux labels", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"run", "--pod", podID, ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) label1 := session.OutputToString() session = podmanTest.Podman([]string{"run", "--pod", podID, ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(label1)) session = podmanTest.Podman([]string{"pod", "rm", podID, "--force"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman pod container --infra=false doesn't share SELinux labels", func() { session := podmanTest.Podman([]string{"pod", "create", "--infra=false"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) podID := session.OutputToString() session = podmanTest.Podman([]string{"run", "--pod", podID, ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) label1 := session.OutputToString() session = podmanTest.Podman([]string{"run", "--pod", podID, ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(Equal(label1))) session = podmanTest.Podman([]string{"pod", "rm", podID, "--force"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman shared IPC NS container share SELinux labels", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "test1", "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) label1 := session.OutputToString() session = podmanTest.Podman([]string{"run", "--ipc", "container:test1", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(label1)) }) It("podman shared PID NS container share SELinux labels", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "test1", "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) label1 := session.OutputToString() session = podmanTest.Podman([]string{"run", "--pid", "container:test1", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(label1)) }) It("podman shared NET NS container doesn't share SELinux labels", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "test1", "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) label1 := session.OutputToString() session = podmanTest.Podman([]string{"run", "--net", "container:test1", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(Equal(label1))) }) @@ -278,35 +279,35 @@ var _ = Describe("Podman run", func() { SkipIfRootlessCgroupsV1("Not supported for rootless + CGroupsV1") session := podmanTest.Podman([]string{"run", "--pid=host", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("spc_t")) }) It("podman test --ipc=host", func() { session := podmanTest.Podman([]string{"run", "--ipc=host", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("spc_t")) }) It("podman test --ipc=net", func() { session := podmanTest.Podman([]string{"run", "--net=host", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("container_t")) }) It("podman test --ipc=net", func() { session := podmanTest.Podman([]string{"run", "--net=host", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("container_t")) }) It("podman test --ipc=net", func() { session := podmanTest.Podman([]string{"run", "--net=host", ALPINE, "cat", "/proc/self/attr/current"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("container_t")) }) @@ -321,7 +322,7 @@ var _ = Describe("Podman run", func() { } session := podmanTest.Podman([]string{"create", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"inspect", "--format", "{{ .ProcessLabel }}", cid}) session.WaitWithDefaultTimeout() @@ -337,7 +338,7 @@ var _ = Describe("Podman run", func() { It("podman test init labels", func() { session := podmanTest.Podman([]string{"create", ubi_init, "/sbin/init"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"inspect", "--format", "{{ .ProcessLabel }}", cid}) session.WaitWithDefaultTimeout() @@ -347,7 +348,7 @@ var _ = Describe("Podman run", func() { It("podman relabels named volume with :Z", func() { session := podmanTest.Podman([]string{"run", "-v", "testvol:/test1/test:Z", fedoraMinimal, "ls", "-alZ", "/test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString(":s0:") Expect(match).Should(BeTrue()) }) diff --git a/test/e2e/run_signal_test.go b/test/e2e/run_signal_test.go index f601bee72..e9c073a6c 100644 --- a/test/e2e/run_signal_test.go +++ b/test/e2e/run_signal_test.go @@ -13,6 +13,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" "golang.org/x/sys/unix" ) @@ -129,10 +130,10 @@ var _ = Describe("Podman run with --sig-proxy", func() { // Kill with -9 to guarantee the container dies killSession := podmanTest.Podman([]string{"kill", "-s", "9", "test2"}) killSession.WaitWithDefaultTimeout() - Expect(killSession.ExitCode()).To(Equal(0)) + Expect(killSession).Should(Exit(0)) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).ToNot(Equal(0)) + Expect(session).To(ExitWithError()) ok, _ = session.GrepString("Received") Expect(ok).To(BeFalse()) }) diff --git a/test/e2e/run_staticip_test.go b/test/e2e/run_staticip_test.go index bff142b12..6dd7a14d0 100644 --- a/test/e2e/run_staticip_test.go +++ b/test/e2e/run_staticip_test.go @@ -9,6 +9,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run with --ip flag", func() { @@ -60,7 +61,7 @@ var _ = Describe("Podman run with --ip flag", func() { ip := GetRandomIPAddress() result := podmanTest.Podman([]string{"run", "-ti", "--ip", ip, ALPINE, "ip", "addr"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(ip + "/16")) }) @@ -68,7 +69,7 @@ var _ = Describe("Podman run with --ip flag", func() { ip := GetRandomIPAddress() result := podmanTest.Podman([]string{"run", "-dt", "--ip", ip, nginx}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) for i := 0; i < 10; i++ { fmt.Println("Waiting for nginx", err) time.Sleep(1 * time.Second) diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 5a29b035b..3c65c02d1 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -16,6 +16,7 @@ import ( "github.com/mrunalp/fileutils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run", func() { @@ -44,29 +45,29 @@ var _ = Describe("Podman run", func() { It("podman run a container based on local image", func() { session := podmanTest.Podman([]string{"run", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run check /run/.containerenv", func() { session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/run/.containerenv"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("")) session = podmanTest.Podman([]string{"run", "--privileged", "--name=test1", ALPINE, "cat", "/run/.containerenv"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("name=\"test1\"")) Expect(session.OutputToString()).To(ContainSubstring("image=\"" + ALPINE + "\"")) session = podmanTest.Podman([]string{"run", "-v", "/:/host", ALPINE, "cat", "/run/.containerenv"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("graphRootMounted=1")) session = podmanTest.Podman([]string{"run", "-v", "/:/host", "--privileged", ALPINE, "cat", "/run/.containerenv"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("graphRootMounted=1")) }) @@ -75,40 +76,40 @@ var _ = Describe("Podman run", func() { session := podmanTest.Podman([]string{"run", imageName, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull")) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run --signature-policy", func() { SkipIfRemote("SigPolicy not handled by remote") session := podmanTest.Podman([]string{"run", "--pull=always", "--signature-policy", "/no/such/file", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"run", "--pull=always", "--signature-policy", "/etc/containers/policy.json", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run --rm with --restart", func() { session := podmanTest.Podman([]string{"run", "--rm", "--restart", "", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--rm", "--restart", "no", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--rm", "--restart", "on-failure", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--rm", "--restart", "always", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"run", "--rm", "--restart", "unless-stopped", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("podman run a container based on on a short name with localhost", func() { @@ -121,7 +122,7 @@ var _ = Describe("Podman run", func() { session := podmanTest.Podman([]string{"run", "libpod/alpine_nginx:latest", "ls"}) session.WaitWithDefaultTimeout() Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull")) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman container run a container based on on a short name with localhost", func() { @@ -134,20 +135,20 @@ var _ = Describe("Podman run", func() { session := podmanTest.Podman([]string{"container", "run", "libpod/alpine_nginx:latest", "ls"}) session.WaitWithDefaultTimeout() Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull")) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run a container based on local image with short options", func() { session := podmanTest.Podman([]string{"run", "-dt", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run a container based on local image with short options and args", func() { // regression test for #714 session := podmanTest.Podman([]string{"run", ALPINE, "find", "/etc", "-name", "hosts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("/etc/hosts") Expect(match).Should(BeTrue()) }) @@ -157,7 +158,7 @@ var _ = Describe("Podman run", func() { hostname := "test_hostname" session := podmanTest.Podman([]string{"run", "-ti", "--rm", "--name", name, "--hostname", hostname, ALPINE, "cat", "/etc/hosts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString(name) Expect(match).Should(BeTrue()) match, _ = session.GrepString(hostname) @@ -167,7 +168,7 @@ var _ = Describe("Podman run", func() { It("podman run a container based on remote image", func() { session := podmanTest.Podman([]string{"run", "-dt", BB_GLIBC, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run a container with a --rootfs", func() { @@ -184,25 +185,25 @@ var _ = Describe("Podman run", func() { csession := podmanTest.Podman([]string{"run", "--name", uniqueString, ALPINE, "/bin/sh", "-c", fmt.Sprintf("echo %s > %s", uniqueString, testFilePath)}) csession.WaitWithDefaultTimeout() - Expect(csession.ExitCode()).To(Equal(0)) + Expect(csession).Should(Exit(0)) // Export from working container image guarantees working root esession := podmanTest.Podman([]string{"export", "--output", tarball, uniqueString}) esession.WaitWithDefaultTimeout() - Expect(esession.ExitCode()).To(Equal(0)) + Expect(esession).Should(Exit(0)) Expect(tarball).Should(BeARegularFile()) // N/B: This will loose any extended attributes like SELinux types fmt.Fprintf(os.Stderr, "Extracting container root tarball\n") tarsession := SystemExec("tar", []string{"xf", tarball, "-C", rootfs}) - Expect(tarsession.ExitCode()).To(Equal(0)) + Expect(tarsession).Should(Exit(0)) Expect(filepath.Join(rootfs, uls)).Should(BeADirectory()) // Other tests confirm SELinux types, just confirm --rootfs is working. session := podmanTest.Podman([]string{"run", "-i", "--security-opt", "label=disable", "--rootfs", rootfs, "cat", testFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Validate changes made in original container and export stdoutLines := session.OutputToStringArray() @@ -213,10 +214,10 @@ var _ = Describe("Podman run", func() { It("podman run a container with --init", func() { session := podmanTest.Podman([]string{"run", "--name", "test", "--init", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"inspect", "test"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() Expect(conData[0].Path).To(Equal("/dev/init")) Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("TRUE")) @@ -225,10 +226,10 @@ var _ = Describe("Podman run", func() { It("podman run a container with --init and --init-path", func() { session := podmanTest.Podman([]string{"run", "--name", "test", "--init", "--init-path", "/usr/libexec/podman/catatonit", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"inspect", "test"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() Expect(conData[0].Path).To(Equal("/dev/init")) Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("TRUE")) @@ -237,10 +238,10 @@ var _ = Describe("Podman run", func() { It("podman run a container without --init", func() { session := podmanTest.Podman([]string{"run", "--name", "test", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"inspect", "test"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() Expect(conData[0].Path).To(Equal("ls")) Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("FALSE")) @@ -259,56 +260,56 @@ var _ = Describe("Podman run", func() { It("podman run mask and unmask path test", func() { session := podmanTest.Podman([]string{"run", "-d", "--name=maskCtr1", "--security-opt", "unmask=ALL", "--security-opt", "mask=/proc/acpi", ALPINE, "sleep", "200"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "maskCtr1", "ls", "/sys/firmware"}) session.WaitWithDefaultTimeout() Expect(session.OutputToString()).To(Not(BeEmpty())) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "maskCtr1", "ls", "/proc/acpi"}) session.WaitWithDefaultTimeout() Expect(session.OutputToString()).To(BeEmpty()) session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr2", "--security-opt", "unmask=/proc/acpi:/sys/firmware", ALPINE, "sleep", "200"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "maskCtr2", "ls", "/sys/firmware"}) session.WaitWithDefaultTimeout() Expect(session.OutputToString()).To(Not(BeEmpty())) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "maskCtr2", "ls", "/proc/acpi"}) session.WaitWithDefaultTimeout() Expect(session.OutputToString()).To(Not(BeEmpty())) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr3", "--security-opt", "mask=/sys/power/disk", ALPINE, "sleep", "200"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "maskCtr3", "cat", "/sys/power/disk"}) session.WaitWithDefaultTimeout() Expect(session.OutputToString()).To(BeEmpty()) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr4", "--security-opt", "systempaths=unconfined", ALPINE, "sleep", "200"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "maskCtr4", "ls", "/sys/firmware"}) session.WaitWithDefaultTimeout() Expect(session.OutputToString()).To(Not(BeEmpty())) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr5", "--security-opt", "systempaths=unconfined", ALPINE, "grep", "/proc", "/proc/self/mounts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToStringArray()).Should(HaveLen(1)) session = podmanTest.Podman([]string{"run", "-d", "--security-opt", "unmask=/proc/*", ALPINE, "grep", "/proc", "/proc/self/mounts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToStringArray()).Should(HaveLen(1)) session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/proc/a*", ALPINE, "ls", "/proc/acpi"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(BeEmpty())) }) @@ -319,32 +320,32 @@ var _ = Describe("Podman run", func() { rwOnCGroups := "/sys/fs/cgroup cgroup2 rw" session := podmanTest.Podman([]string{"run", "--security-opt", "unmask=ALL", "--security-opt", "mask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups)) session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups)) session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup///", ALPINE, "cat", "/proc/mounts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups)) session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=ALL", ALPINE, "cat", "/proc/mounts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups)) session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup", "--security-opt", "mask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups)) session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup", ALPINE, "ls", "/sys/fs/cgroup"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).ToNot(BeEmpty()) }) @@ -368,32 +369,32 @@ var _ = Describe("Podman run", func() { session := podmanTest.Podman([]string{"run", "-it", "--privileged", ALPINE, "grep", "Seccomp", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.OutputToString()).To(ContainSubstring("0")) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run seccomp test no profile should be default", func() { session := podmanTest.Podman([]string{"run", "-it", ALPINE, "grep", "Seccomp", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.OutputToString()).To(ContainSubstring("2")) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run capabilities test", func() { session := podmanTest.Podman([]string{"run", "--rm", "--cap-add", "all", ALPINE, "cat", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--rm", "--cap-add", "sys_admin", ALPINE, "cat", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--rm", "--cap-drop", "all", ALPINE, "cat", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--rm", "--cap-drop", "setuid", ALPINE, "cat", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run user capabilities test", func() { @@ -404,67 +405,67 @@ var _ = Describe("Podman run", func() { } session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapBnd", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapEff", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapInh", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapBnd", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapEff", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapInh", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapBnd", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapEff", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) session = podmanTest.Podman([]string{"run", "--user=1000:1000", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000002")) session = podmanTest.Podman([]string{"run", "--user=1000:1000", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000002")) session = podmanTest.Podman([]string{"run", "--user=0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) session = podmanTest.Podman([]string{"run", "--user=0:0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) session = podmanTest.Podman([]string{"run", "--user=0:0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) if os.Geteuid() > 0 { @@ -476,17 +477,17 @@ var _ = Describe("Podman run", func() { } session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000002")) session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--privileged", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000002")) } }) @@ -502,12 +503,12 @@ USER bin`, BB) podmanTest.BuildImage(dockerfile, "test", "false") session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapBnd", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapEff", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) }) @@ -517,29 +518,29 @@ USER bin`, BB) if !isRootless() { session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "rtprio=99", "--cap-add=sys_nice", fedoraMinimal, "cat", "/proc/self/sched"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) } session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=2048:2048", fedoraMinimal, "ulimit", "-n"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("2048")) session = podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=1024:1028", fedoraMinimal, "ulimit", "-n"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("1024")) if !CGROUPSV2 { // --oom-kill-disable not supported on cgroups v2. session = podmanTest.Podman([]string{"run", "--rm", "--oom-kill-disable=true", fedoraMinimal, "echo", "memory-hog"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) } session = podmanTest.Podman([]string{"run", "--rm", "--oom-score-adj=111", fedoraMinimal, "cat", "/proc/self/oom_score_adj"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("111")) }) @@ -553,7 +554,7 @@ USER bin`, BB) session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "host", fedoraMinimal, "ulimit", "-Hn"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ulimitCtrStr := strings.TrimSpace(session.OutputToString()) ulimitCtr, err := strconv.ParseUint(ulimitCtrStr, 10, 0) @@ -565,7 +566,7 @@ USER bin`, BB) It("podman run with cidfile", func() { session := podmanTest.Podman([]string{"run", "--cidfile", tempdir + "cidfile", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) err := os.Remove(tempdir + "cidfile") Expect(err).To(BeNil()) }) @@ -574,13 +575,13 @@ USER bin`, BB) SkipIfRootless("Network sysctls are not available root rootless") session := podmanTest.Podman([]string{"run", "--rm", "--sysctl", "net.core.somaxconn=65535", ALPINE, "sysctl", "net.core.somaxconn"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("net.core.somaxconn = 65535")) // network sysctls should fail if --net=host is set session = podmanTest.Podman([]string{"run", "--net", "host", "--rm", "--sysctl", "net.core.somaxconn=65535", ALPINE, "sysctl", "net.core.somaxconn"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman run blkio-weight test", func() { @@ -595,7 +596,7 @@ USER bin`, BB) } session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/io.bfq.weight"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // there was a documentation issue in the kernel that reported a different range [1-10000] for the io controller. // older versions of crun/runc used it. For the time being allow both versions to pass the test. // FIXME: drop "|51" once all the runtimes we test have the fix in place. @@ -606,7 +607,7 @@ USER bin`, BB) } session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.weight"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("15")) } }) @@ -624,7 +625,7 @@ USER bin`, BB) } session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2 Expect(session.OutputToString()).To(ContainSubstring("1048576")) } @@ -642,7 +643,7 @@ USER bin`, BB) session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_bps_device"}) } session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2 Expect(session.OutputToString()).To(ContainSubstring("1048576")) } @@ -660,7 +661,7 @@ USER bin`, BB) } session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2 Expect(session.OutputToString()).To(ContainSubstring("100")) } @@ -678,7 +679,7 @@ USER bin`, BB) } session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2 Expect(session.OutputToString()).To(ContainSubstring("100")) } @@ -706,7 +707,7 @@ USER bin`, BB) session := podmanTest.Podman([]string{"run", ALPINE, "printenv", "NOTIFY_SOCKET"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 0)) }) @@ -714,7 +715,7 @@ USER bin`, BB) log := filepath.Join(podmanTest.TempDir, "/container.log") session := podmanTest.Podman([]string{"run", "--rm", "--log-driver", "k8s-file", "--log-opt", fmt.Sprintf("path=%s", log), ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, err := os.Stat(log) Expect(err).To(BeNil()) _ = os.Remove(log) @@ -724,11 +725,11 @@ USER bin`, BB) podmanTest.AddImageToRWStore(BB) tag := podmanTest.Podman([]string{"tag", BB, "bb"}) tag.WaitWithDefaultTimeout() - Expect(tag.ExitCode()).To(Equal(0)) + Expect(tag).Should(Exit(0)) session := podmanTest.Podman([]string{"run", "--rm", "bb", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman test hooks", func() { @@ -741,7 +742,7 @@ USER bin`, BB) session := podmanTest.Podman([]string{"run", ALPINE, "ls"}) session.Wait(10) os.Unsetenv("HOOK_OPTION") - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run with subscription secrets", func() { @@ -771,16 +772,16 @@ USER bin`, BB) err = ioutil.WriteFile(keyFile, []byte(mountString), 0755) Expect(err).To(BeNil()) execSession := SystemExec("ln", []string{"-s", targetDir, filepath.Join(secretsDir, "mysymlink")}) - Expect(execSession.ExitCode()).To(Equal(0)) + Expect(execSession).Should(Exit(0)) session := podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "cat", "/run/secrets/test.txt"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(secretsString)) session = podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "ls", "/run/secrets/mysymlink"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("key.pem")) }) @@ -792,7 +793,7 @@ USER bin`, BB) session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "ls", "/run/secrets"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("system-fips")) err = os.Remove(fipsFile) @@ -802,63 +803,63 @@ USER bin`, BB) It("podman run without group-add", func() { session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("27(video),777,65533(nogroup)")).To(BeFalse()) }) It("podman run with group-add", func() { session := podmanTest.Podman([]string{"run", "--rm", "--group-add=audio", "--group-add=nogroup", "--group-add=777", ALPINE, "id"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("777,65533(nogroup)")).To(BeTrue()) }) It("podman run with user (default)", func() { session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("uid=0(root) gid=0(root)")).To(BeTrue()) }) It("podman run with user (integer, not in /etc/passwd)", func() { session := podmanTest.Podman([]string{"run", "--rm", "--user=1234", ALPINE, "id"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("uid=1234(1234) gid=0(root)")) }) It("podman run with user (integer, in /etc/passwd)", func() { session := podmanTest.Podman([]string{"run", "--rm", "--user=8", ALPINE, "id"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("uid=8(mail) gid=12(mail)")).To(BeTrue()) }) It("podman run with user (username)", func() { session := podmanTest.Podman([]string{"run", "--rm", "--user=mail", ALPINE, "id"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.LineInOutputContains("uid=8(mail) gid=12(mail)")).To(BeTrue()) }) It("podman run with user:group (username:integer)", func() { session := podmanTest.Podman([]string{"run", "--rm", "--user=mail:21", ALPINE, "id"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=21(ftp)")) }) It("podman run with user:group (integer:groupname)", func() { session := podmanTest.Podman([]string{"run", "--rm", "--user=8:ftp", ALPINE, "id"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=21(ftp)")) }) It("podman run with user, verify caps dropped", func() { session := podmanTest.Podman([]string{"run", "--rm", "--user=1234", ALPINE, "grep", "CapEff", "/proc/self/status"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) capEff := strings.Split(session.OutputToString(), " ") Expect("0000000000000000").To(Equal(capEff[1])) }) @@ -866,10 +867,10 @@ USER bin`, BB) It("podman run with attach stdin outputs container ID", func() { session := podmanTest.Podman([]string{"run", "--attach", "stdin", ALPINE, "printenv"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ps := podmanTest.Podman([]string{"ps", "-aq", "--no-trunc"}) ps.WaitWithDefaultTimeout() - Expect(ps.ExitCode()).To(Equal(0)) + Expect(ps).Should(Exit(0)) Expect(ps.LineInOutputContains(session.OutputToString())).To(BeTrue()) }) @@ -882,44 +883,44 @@ USER bin`, BB) It("podman run with attach stderr does not print stdout", func() { session := podmanTest.Podman([]string{"run", "--rm", "--attach", "stderr", ALPINE, "ls", "/"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("")) }) It("podman run attach nonsense errors", func() { session := podmanTest.Podman([]string{"run", "--rm", "--attach", "asdfasdf", ALPINE, "ls", "/"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman run exit code on failure to exec", func() { session := podmanTest.Podman([]string{"run", ALPINE, "/etc"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(126)) + Expect(session).Should(Exit(126)) }) It("podman run error on exec", func() { session := podmanTest.Podman([]string{"run", ALPINE, "sh", "-c", "exit 100"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(100)) + Expect(session).Should(Exit(100)) }) It("podman run with named volume", func() { session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "stat", "-c", "%a %Y", "/var/tmp"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) perms := session.OutputToString() session = podmanTest.Podman([]string{"run", "--rm", "-v", "test:/var/tmp", ALPINE, "stat", "-c", "%a %Y", "/var/tmp"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(perms)) }) It("podman run with built-in volume image", func() { session := podmanTest.Podman([]string{"run", "--rm", redis, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) dockerfile := fmt.Sprintf(`FROM %s RUN mkdir -p /myvol/data && chown -R mail.0 /myvol @@ -929,7 +930,7 @@ USER mail`, BB) podmanTest.BuildImage(dockerfile, "test", "false") session = podmanTest.Podman([]string{"run", "--rm", "test", "ls", "-al", "/myvol/data"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("mail root")) }) @@ -947,21 +948,21 @@ USER mail`, BB) session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint, ALPINE, "cat", mountpoint + filename}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ctrID := session.OutputToString() session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "cat", mountpoint + filename}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(data)) session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "sh", "-c", "echo test >> " + mountpoint + filename}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "--attach", ctrID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(data + "test")) }) @@ -979,55 +980,55 @@ USER mail`, BB) session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint, ALPINE, "cat", mountpoint + filename}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ctrID := session.OutputToString() // check that the read only option works session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro", ALPINE, "touch", mountpoint + "abc.txt"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) Expect(session.ErrorToString()).To(ContainSubstring("Read-only file system")) // check that both z and ro options work session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro,z", ALPINE, "cat", mountpoint + filename}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(data)) // check that multiple ro/rw are not working session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro,rw", ALPINE, "cat", mountpoint + filename}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) Expect(session.ErrorToString()).To(ContainSubstring("cannot set ro or rw options more than once")) // check that multiple z options are not working session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":z,z,ro", ALPINE, "cat", mountpoint + filename}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) Expect(session.ErrorToString()).To(ContainSubstring("cannot set :z more than once in mount options")) // create new read only volume session = podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint + ":ro", ALPINE, "cat", mountpoint + filename}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ctrID = session.OutputToString() // check if the original volume was mounted as read only that --volumes-from also mount it as read only session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "touch", mountpoint + "abc.txt"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) Expect(session.ErrorToString()).To(ContainSubstring("Read-only file system")) }) It("podman run --volumes-from flag with built-in volumes", func() { session := podmanTest.Podman([]string{"create", redis, "sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ctrID := session.OutputToString() session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("data")) }) @@ -1041,7 +1042,7 @@ USER mail`, BB) session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:z", ALPINE, "touch", "/myvol2/foo.txt"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run --volumes flag with empty host dir", func() { @@ -1069,7 +1070,7 @@ USER mail`, BB) session := podmanTest.Podman([]string{"run", "--mount", "type=bind,src=" + vol1 + ",target=/myvol1,z", "--mount", "type=bind,src=" + vol2 + ",target=/myvol2,z", ALPINE, "touch", "/myvol2/foo.txt"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run findmnt nothing shared", func() { @@ -1082,7 +1083,7 @@ USER mail`, BB) session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:z", fedoraMinimal, "findmnt", "-o", "TARGET,PROPAGATION"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, _ := session.GrepString("shared") Expect(match).Should(BeFalse()) }) @@ -1097,7 +1098,7 @@ USER mail`, BB) session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:shared,z", fedoraMinimal, "findmnt", "-o", "TARGET,PROPAGATION"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) match, shared := session.GrepString("shared") Expect(match).Should(BeTrue()) // make sure it's only shared (and not 'shared,slave') @@ -1108,7 +1109,7 @@ USER mail`, BB) It("podman run --security-opts proc-opts=", func() { session := podmanTest.Podman([]string{"run", "--security-opt", "proc-opts=nosuid,exec", fedoraMinimal, "findmnt", "-noOPTIONS", "/proc"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(output).To(ContainSubstring("nosuid")) Expect(output).To(Not(ContainSubstring("exec"))) @@ -1118,25 +1119,25 @@ USER mail`, BB) SkipIfRootless("FIXME: rootless users are not allowed to mount bind-nonrecursive (Could this be a Kernel bug?") session := podmanTest.Podman([]string{"run", "--mount", "type=bind,bind-nonrecursive,slave,src=/,target=/host", fedoraMinimal, "findmnt", "-nR", "/host"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(1)) }) It("podman run --mount type=devpts,target=/foo/bar", func() { session := podmanTest.Podman([]string{"run", "--mount", "type=devpts,target=/foo/bar", fedoraMinimal, "stat", "-f", "-c%T", "/foo/bar"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("devpts")) }) It("podman run --pod automatically", func() { session := podmanTest.Podman([]string{"run", "-d", "--pod", "new:foobar", ALPINE, "nc", "-l", "-p", "8080"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--pod", "foobar", ALPINE, "/bin/sh", "-c", "echo test | nc -w 1 127.0.0.1 8080"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"pod", "ps", "--no-trunc"}) check.WaitWithDefaultTimeout() @@ -1148,14 +1149,14 @@ USER mail`, BB) hostname := "abc" session := podmanTest.Podman([]string{"run", "--pod", "new:foobar", "--hostname", hostname, ALPINE, "cat", "/etc/hostname"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(hostname)) }) It("podman run --rm should work", func() { session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"wait", "test"}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) @@ -1191,7 +1192,7 @@ USER mail`, BB) It("podman run readonly container should NOT mount /dev/shm read/only", func() { session := podmanTest.Podman([]string{"run", "--read-only", ALPINE, "mount"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(ContainSubstring("/dev/shm type tmpfs (ro,"))) }) @@ -1199,7 +1200,7 @@ USER mail`, BB) It("podman run readonly container should NOT mount /run noexec", func() { session := podmanTest.Podman([]string{"run", "--read-only", ALPINE, "sh", "-c", "mount | grep \"/run \""}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(ContainSubstring("noexec"))) }) @@ -1280,7 +1281,7 @@ USER mail`, BB) container := podmanTest.Podman([]string{"run", "--rm", "--cgroups=split", ALPINE, "cat", "/proc/self/cgroup"}) container.WaitWithDefaultTimeout() - Expect(container.ExitCode()).To(Equal(0)) + Expect(container).Should(Exit(0)) lines := container.OutputToStringArray() cgroup := "" @@ -1322,7 +1323,7 @@ USER mail`, BB) ctrName := "testctr" container := podmanTest.Podman([]string{"run", "--name", ctrName, "-d", "--cgroups=disabled", ALPINE, "top"}) container.WaitWithDefaultTimeout() - Expect(container.ExitCode()).To(Equal(0)) + Expect(container).Should(Exit(0)) // Get PID and get cgroups of that PID inspectOut := podmanTest.InspectContainer(ctrName) @@ -1354,7 +1355,7 @@ USER mail`, BB) ctrName := "testctr" container := podmanTest.Podman([]string{"run", "--name", ctrName, "-d", "--cgroups=enabled", ALPINE, "top"}) container.WaitWithDefaultTimeout() - Expect(container.ExitCode()).To(Equal(0)) + Expect(container).Should(Exit(0)) // Get PID and get cgroups of that PID inspectOut := podmanTest.InspectContainer(ctrName) @@ -1378,7 +1379,7 @@ USER mail`, BB) It("podman run should fail with nonexistent authfile", func() { session := podmanTest.Podman([]string{"run", "--authfile", "/tmp/nonexistent", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("podman run --device-cgroup-rule", func() { @@ -1386,24 +1387,24 @@ USER mail`, BB) deviceCgroupRule := "c 42:* rwm" session := podmanTest.Podman([]string{"run", "--cap-add", "mknod", "--name", "test", "-d", "--device-cgroup-rule", deviceCgroupRule, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "test", "mknod", "newDev", "c", "42", "1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run --replace", func() { // Make sure we error out with --name. session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) // Run and replace 5 times in a row the "same" container. ctrName := "testCtr" for i := 0; i < 5; i++ { session := podmanTest.Podman([]string{"run", "--detach", "--replace", "--name", ctrName, ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) } }) @@ -1416,13 +1417,13 @@ USER mail`, BB) } session := podmanTest.PodmanExtraFiles([]string{"run", "--preserve-fds", "1", ALPINE, "ls"}, files) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run --preserve-fds invalid fd", func() { session := podmanTest.Podman([]string{"run", "--preserve-fds", "2", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) Expect(session.ErrorToString()).To(ContainSubstring("file descriptor 3 is not available")) }) @@ -1430,7 +1431,7 @@ USER mail`, BB) groupName := "kvm" session := podmanTest.Podman([]string{"run", "-t", "-i", "--group-add", groupName, "--privileged", fedoraMinimal, "groups"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(strings.Contains(session.OutputToString(), groupName)).To(BeTrue()) }) @@ -1450,7 +1451,7 @@ USER mail`, BB) badTZFile := fmt.Sprintf("../../../%s", tzFile) session := podmanTest.Podman([]string{"run", "--tz", badTZFile, "--rm", ALPINE, "date"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) Expect(session.ErrorToString()).To(ContainSubstring("error finding timezone for container")) err = os.Remove(tzFile) @@ -1458,20 +1459,20 @@ USER mail`, BB) session = podmanTest.Podman([]string{"run", "--tz", "foo", "--rm", ALPINE, "date"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"run", "--tz", "America", "--rm", ALPINE, "date"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"run", "--tz", "Pacific/Honolulu", "--rm", ALPINE, "date", "+'%H %Z'"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("HST")) session = podmanTest.Podman([]string{"run", "--tz", "local", "--rm", ALPINE, "date", "+'%H %Z'"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) t := time.Now() z, _ := t.Zone() h := strconv.Itoa(t.Hour()) @@ -1485,7 +1486,7 @@ USER mail`, BB) limit := "4321" session := podmanTest.Podman([]string{"run", "--pids-limit", limit, "--net=none", "--rm", ALPINE, "cat", "/sys/fs/cgroup/pids.max"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(limit)) }) @@ -1496,27 +1497,27 @@ USER mail`, BB) session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("0022")) session = podmanTest.Podman([]string{"run", "--umask", "0002", "--rm", ALPINE, "sh", "-c", "umask"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("0002")) session = podmanTest.Podman([]string{"run", "--umask", "0077", "--rm", fedoraMinimal, "umask"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("0077")) session = podmanTest.Podman([]string{"run", "--umask", "22", "--rm", ALPINE, "sh", "-c", "umask"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("0022")) session = podmanTest.Podman([]string{"run", "--umask", "9999", "--rm", ALPINE, "sh", "-c", "umask"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) Expect(session.ErrorToString()).To(ContainSubstring("Invalid umask")) }) @@ -1527,14 +1528,14 @@ WORKDIR /madethis`, BB) podmanTest.BuildImage(dockerfile, "test", "false") session := podmanTest.Podman([]string{"run", "--rm", "test", "pwd"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("/madethis")) }) It("podman run --entrypoint does not use image command", func() { session := podmanTest.Podman([]string{"run", "--entrypoint", "/bin/echo", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // We can't guarantee the output is completely empty, some // nonprintables seem to work their way in. Expect(session.OutputToString()).To(Not(ContainSubstring("/bin/sh"))) @@ -1543,42 +1544,42 @@ WORKDIR /madethis`, BB) It("podman run a container with log-level (lower case)", func() { session := podmanTest.Podman([]string{"--log-level=info", "run", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run a container with log-level (upper case)", func() { session := podmanTest.Podman([]string{"--log-level=INFO", "run", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run a container with --pull never should fail if no local store", func() { session := podmanTest.Podman([]string{"run", "--pull", "never", "docker.io/library/debian:latest", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman run container with --pull missing and only pull once", func() { session := podmanTest.Podman([]string{"run", "--pull", "missing", cirros, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull")) session = podmanTest.Podman([]string{"run", "--pull", "missing", cirros, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull")) }) It("podman run container with --pull missing should pull image multiple times", func() { session := podmanTest.Podman([]string{"run", "--pull", "always", cirros, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull")) session = podmanTest.Podman([]string{"run", "--pull", "always", cirros, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull")) }) @@ -1586,7 +1587,7 @@ WORKDIR /madethis`, BB) hostnameEnv := "test123" session := podmanTest.Podman([]string{"run", "--hostname", "testctr", "--env", fmt.Sprintf("HOSTNAME=%s", hostnameEnv), ALPINE, "printenv", "HOSTNAME"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(hostnameEnv)) }) @@ -1598,16 +1599,16 @@ WORKDIR /madethis`, BB) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(secretsString)) session = podmanTest.Podman([]string{"inspect", "secr", "--format", " {{(index .Config.Secrets 0).Name}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("mysecret")) }) @@ -1620,16 +1621,16 @@ WORKDIR /madethis`, BB) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=mount", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(secretsString)) session = podmanTest.Podman([]string{"inspect", "secr", "--format", " {{(index .Config.Secrets 0).Name}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("mysecret")) }) @@ -1642,11 +1643,11 @@ WORKDIR /madethis`, BB) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env", "--name", "secr", ALPINE, "printenv", "mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(secretsString)) }) @@ -1658,15 +1659,15 @@ WORKDIR /madethis`, BB) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // target with mount type should fail session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=mount,target=anotherplace", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env,target=anotherplace", "--name", "secr", ALPINE, "printenv", "anotherplace"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(secretsString)) }) @@ -1678,19 +1679,19 @@ WORKDIR /madethis`, BB) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // check default permissions session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "secr", ALPINE, "ls", "-l", "/run/secrets/mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(output).To(ContainSubstring("-r--r--r--")) Expect(output).To(ContainSubstring("root")) session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=mount,uid=1000,gid=1001,mode=777", "--name", "secr2", ALPINE, "ls", "-ln", "/run/secrets/mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output = session.OutputToString() Expect(output).To(ContainSubstring("-rwxrwxrwx")) Expect(output).To(ContainSubstring("1000")) @@ -1705,11 +1706,11 @@ WORKDIR /madethis`, BB) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "nonroot", "--user", "200:200", ALPINE, "cat", "/run/secrets/mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(secretsString)) }) @@ -1721,56 +1722,56 @@ WORKDIR /madethis`, BB) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Invalid type session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=other", "--name", "secr", ALPINE, "printenv", "mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) // Invalid option session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,invalid=invalid", "--name", "secr", ALPINE, "printenv", "mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) // Option syntax not valid session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type", "--name", "secr", ALPINE, "printenv", "mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) // mount option with env type session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env,uid=1000", "--name", "secr", ALPINE, "printenv", "mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) // No source given session = podmanTest.Podman([]string{"run", "--secret", "type=env", "--name", "secr", ALPINE, "printenv", "mysecret"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("podman run --requires", func() { depName := "ctr1" depContainer := podmanTest.Podman([]string{"create", "--name", depName, ALPINE, "top"}) depContainer.WaitWithDefaultTimeout() - Expect(depContainer.ExitCode()).To(Equal(0)) + Expect(depContainer).Should(Exit(0)) mainName := "ctr2" mainContainer := podmanTest.Podman([]string{"run", "--name", mainName, "--requires", depName, "-d", ALPINE, "top"}) mainContainer.WaitWithDefaultTimeout() - Expect(mainContainer.ExitCode()).To(Equal(0)) + Expect(mainContainer).Should(Exit(0)) stop := podmanTest.Podman([]string{"stop", "--all"}) stop.WaitWithDefaultTimeout() - Expect(stop.ExitCode()).To(Equal(0)) + Expect(stop).Should(Exit(0)) start := podmanTest.Podman([]string{"start", mainName}) start.WaitWithDefaultTimeout() - Expect(start.ExitCode()).To(Equal(0)) + Expect(start).Should(Exit(0)) running := podmanTest.Podman([]string{"ps", "-q"}) running.WaitWithDefaultTimeout() - Expect(running.ExitCode()).To(Equal(0)) + Expect(running).Should(Exit(0)) Expect(len(running.OutputToStringArray())).To(Equal(2)) }) @@ -1779,7 +1780,7 @@ WORKDIR /madethis`, BB) pidfile := tempdir + "pidfile" session := podmanTest.Podman([]string{"run", "--pidfile", pidfile, ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) readFirstLine := func(path string) string { content, err := ioutil.ReadFile(path) Expect(err).To(BeNil()) diff --git a/test/e2e/run_userns_test.go b/test/e2e/run_userns_test.go index 79ef707a2..1fe95a1bf 100644 --- a/test/e2e/run_userns_test.go +++ b/test/e2e/run_userns_test.go @@ -10,6 +10,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman UserNS support", func() { @@ -45,7 +46,7 @@ var _ = Describe("Podman UserNS support", func() { It("podman uidmapping and gidmapping", func() { session := podmanTest.Podman([]string{"run", "--uidmap=0:100:5000", "--gidmap=0:200:5000", "alpine", "echo", "hello"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString("hello") Expect(ok).To(BeTrue()) }) @@ -57,7 +58,7 @@ var _ = Describe("Podman UserNS support", func() { It("podman uidmapping and gidmapping with short-opts", func() { session := podmanTest.Podman([]string{"run", "--uidmap=0:1:5000", "--gidmap=0:200:5000", "-it", "alpine", "echo", "hello"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString("hello") Expect(ok).To(BeTrue()) }) @@ -65,7 +66,7 @@ var _ = Describe("Podman UserNS support", func() { It("podman uidmapping and gidmapping with a volume", func() { session := podmanTest.Podman([]string{"run", "--uidmap=0:1:500", "--gidmap=0:200:5000", "-v", "my-foo-volume:/foo:Z", "alpine", "echo", "hello"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString("hello") Expect(ok).To(BeTrue()) }) @@ -73,7 +74,7 @@ var _ = Describe("Podman UserNS support", func() { It("podman uidmapping and gidmapping --net=host", func() { session := podmanTest.Podman([]string{"run", "--net=host", "--uidmap=0:1:5000", "--gidmap=0:200:5000", "alpine", "echo", "hello"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString("hello") Expect(ok).To(BeTrue()) }) @@ -81,7 +82,7 @@ var _ = Describe("Podman UserNS support", func() { It("podman --userns=keep-id", func() { session := podmanTest.Podman([]string{"run", "--userns=keep-id", "alpine", "id", "-u"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) uid := fmt.Sprintf("%d", os.Geteuid()) ok, _ := session.GrepString(uid) Expect(ok).To(BeTrue()) @@ -90,7 +91,7 @@ var _ = Describe("Podman UserNS support", func() { It("podman --userns=keep-id check passwd", func() { session := podmanTest.Podman([]string{"run", "--userns=keep-id", "alpine", "id", "-un"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) u, err := user.Current() Expect(err).To(BeNil()) ok, _ := session.GrepString(u.Name) @@ -100,14 +101,14 @@ var _ = Describe("Podman UserNS support", func() { It("podman --userns=keep-id root owns /usr", func() { session := podmanTest.Podman([]string{"run", "--userns=keep-id", "alpine", "stat", "-c%u", "/usr"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("0")) }) It("podman --userns=keep-id --user root:root", func() { session := podmanTest.Podman([]string{"run", "--userns=keep-id", "--user", "root:root", "alpine", "id", "-u"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("0")) }) @@ -124,16 +125,16 @@ var _ = Describe("Podman UserNS support", func() { ctrName := "ctr-name" session := podmanTest.Podman([]string{"run", "--userns=keep-id", "--user", "root:root", "-d", "--stop-signal", "9", "--name", ctrName, fedoraMinimal, "sleep", "600"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) exec1 := podmanTest.Podman([]string{"exec", "-t", "-i", ctrName, "cat", "/etc/passwd"}) exec1.WaitWithDefaultTimeout() - Expect(exec1.ExitCode()).To(Equal(0)) + Expect(exec1).Should(Exit(0)) Expect(exec1.OutputToString()).To(ContainSubstring(userName)) exec2 := podmanTest.Podman([]string{"exec", "-t", "-i", ctrName, "useradd", "testuser"}) exec2.WaitWithDefaultTimeout() - Expect(exec2.ExitCode()).To(Equal(0)) + Expect(exec2).Should(Exit(0)) }) It("podman --userns=auto", func() { @@ -156,7 +157,7 @@ var _ = Describe("Podman UserNS support", func() { for i := 0; i < 5; i++ { session := podmanTest.Podman([]string{"run", "--userns=auto", "alpine", "cat", "/proc/self/uid_map"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) l := session.OutputToString() Expect(strings.Contains(l, "1024")).To(BeTrue()) m[l] = l @@ -184,22 +185,22 @@ var _ = Describe("Podman UserNS support", func() { session := podmanTest.Podman([]string{"run", "--userns=auto:size=500", "alpine", "cat", "/proc/self/uid_map"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString("500") session = podmanTest.Podman([]string{"run", "--userns=auto:size=3000", "alpine", "cat", "/proc/self/uid_map"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ = session.GrepString("3000") session = podmanTest.Podman([]string{"run", "--userns=auto", "--user=2000:3000", "alpine", "cat", "/proc/self/uid_map"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ = session.GrepString("3001") session = podmanTest.Podman([]string{"run", "--userns=auto", "--user=4000:1000", "alpine", "cat", "/proc/self/uid_map"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ = session.GrepString("4001") Expect(ok).To(BeTrue()) }) @@ -223,13 +224,13 @@ var _ = Describe("Podman UserNS support", func() { session := podmanTest.Podman([]string{"run", "--userns=auto:uidmapping=0:0:1", "alpine", "cat", "/proc/self/uid_map"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(output).To(MatchRegexp("\\s0\\s0\\s1")) session = podmanTest.Podman([]string{"run", "--userns=auto:size=8192,uidmapping=0:0:1", "alpine", "cat", "/proc/self/uid_map"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString("8191") Expect(ok).To(BeTrue()) }) @@ -253,13 +254,13 @@ var _ = Describe("Podman UserNS support", func() { session := podmanTest.Podman([]string{"run", "--userns=auto:gidmapping=0:0:1", "alpine", "cat", "/proc/self/gid_map"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(output).To(MatchRegexp("\\s0\\s0\\s1")) session = podmanTest.Podman([]string{"run", "--userns=auto:size=8192,gidmapping=0:0:1", "alpine", "cat", "/proc/self/gid_map"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString("8191") Expect(ok).To(BeTrue()) }) @@ -268,19 +269,19 @@ var _ = Describe("Podman UserNS support", func() { ctrName := "userns-ctr" session := podmanTest.Podman([]string{"run", "-d", "--uidmap=0:0:1", "--uidmap=1:1:4998", "--name", ctrName, "alpine", "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // runc has an issue and we also need to join the IPC namespace. session = podmanTest.Podman([]string{"run", "--rm", "--userns=container:" + ctrName, "--ipc=container:" + ctrName, "alpine", "cat", "/proc/self/uid_map"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString("4998") Expect(ok).To(BeTrue()) session = podmanTest.Podman([]string{"run", "--rm", "--userns=container:" + ctrName, "--net=container:" + ctrName, "alpine", "cat", "/proc/self/uid_map"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ = session.GrepString("4998") Expect(ok).To(BeTrue()) @@ -298,17 +299,17 @@ var _ = Describe("Podman UserNS support", func() { for _, tt := range tests { session := podmanTest.Podman([]string{"run", "-d", "--user", tt.arg, "--mount", "type=volume,src=" + tt.vol + ",dst=/home/user", "alpine", "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspectUID := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .UID }}", tt.vol}) inspectUID.WaitWithDefaultTimeout() - Expect(inspectUID.ExitCode()).To(Equal(0)) + Expect(inspectUID).Should(Exit(0)) Expect(inspectUID.OutputToString()).To(Equal(tt.uid)) // Make sure we're defaulting to 0. inspectGID := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .GID }}", tt.vol}) inspectGID.WaitWithDefaultTimeout() - Expect(inspectGID.ExitCode()).To(Equal(0)) + Expect(inspectGID).Should(Exit(0)) Expect(inspectGID.OutputToString()).To(Equal(tt.gid)) } }) diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go index 4be1b2009..d1f6ea80e 100644 --- a/test/e2e/run_volume_test.go +++ b/test/e2e/run_volume_test.go @@ -13,7 +13,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/onsi/gomega/gexec" + . "github.com/onsi/gomega/gexec" ) // in-container mount point: using a path that is definitely not present @@ -50,21 +50,21 @@ var _ = Describe("Podman run with volumes", func() { session := podmanTest.Podman([]string{"run", "--rm", "-v", vol, ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, matches := session.GrepString(dest) Expect(found).Should(BeTrue()) Expect(matches[0]).To(ContainSubstring("rw")) session = podmanTest.Podman([]string{"run", "--rm", "-v", vol + ":ro", ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, matches = session.GrepString(dest) Expect(found).Should(BeTrue()) Expect(matches[0]).To(ContainSubstring("ro")) session = podmanTest.Podman([]string{"run", "--rm", "-v", vol + ":shared", ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, matches = session.GrepString(dest) Expect(found).Should(BeTrue()) Expect(matches[0]).To(ContainSubstring("rw")) @@ -73,7 +73,7 @@ var _ = Describe("Podman run with volumes", func() { // Cached is ignored session = podmanTest.Podman([]string{"run", "--rm", "-v", vol + ":cached", ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, matches = session.GrepString(dest) Expect(found).Should(BeTrue()) Expect(matches[0]).To(ContainSubstring("rw")) @@ -82,7 +82,7 @@ var _ = Describe("Podman run with volumes", func() { // Delegated is ignored session = podmanTest.Podman([]string{"run", "--rm", "-v", vol + ":delegated", ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, matches = session.GrepString(dest) Expect(found).Should(BeTrue()) Expect(matches[0]).To(ContainSubstring("rw")) @@ -99,22 +99,22 @@ var _ = Describe("Podman run with volumes", func() { session := podmanTest.Podman([]string{"run", "--rm", "--mount", mount, ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(dest + " rw")) session = podmanTest.Podman([]string{"run", "--rm", "--mount", mount + ",ro", ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(dest + " ro")) session = podmanTest.Podman([]string{"run", "--rm", "--mount", mount + ",readonly", ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(dest + " ro")) session = podmanTest.Podman([]string{"run", "--rm", "--mount", mount + ",consistency=delegated,shared", ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, matches := session.GrepString(dest) Expect(found).Should(BeTrue()) Expect(matches[0]).To(ContainSubstring("rw")) @@ -122,29 +122,29 @@ var _ = Describe("Podman run with volumes", func() { session = podmanTest.Podman([]string{"run", "--rm", "--mount", "type=tmpfs,target=" + dest, ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(dest + " rw,nosuid,nodev,relatime - tmpfs")) session = podmanTest.Podman([]string{"run", "--rm", "--mount", "type=tmpfs,target=/etc/ssl,tmpcopyup", ALPINE, "ls", "/etc/ssl"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("certs")) session = podmanTest.Podman([]string{"run", "--rm", "--mount", "type=tmpfs,target=/etc/ssl,tmpcopyup,notmpcopyup", ALPINE, "ls", "/etc/ssl"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"run", "--rm", "--mount", "type=bind,src=/tmp,target=/tmp,tmpcopyup", ALPINE, "true"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"run", "--rm", "--mount", "type=bind,src=/tmp,target=/tmp,notmpcopyup", ALPINE, "true"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) session = podmanTest.Podman([]string{"run", "--rm", "--mount", "type=tmpfs,target=/etc/ssl,notmpcopyup", ALPINE, "ls", "/etc/ssl"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(ContainSubstring("certs"))) }) @@ -153,7 +153,7 @@ var _ = Describe("Podman run with volumes", func() { os.Mkdir(mountPath, 0755) session := podmanTest.Podman([]string{"run", "-v", mountPath + ":" + dest, "-v", "/tmp" + ":" + dest, ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman run with conflict between image volume and user mount succeeds", func() { @@ -167,7 +167,7 @@ var _ = Describe("Podman run with volumes", func() { Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"run", "-v", fmt.Sprintf("%s:/data", mountPath), redis, "ls", "/data/test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman run with mount flag and boolean options", func() { @@ -177,12 +177,12 @@ var _ = Describe("Podman run with volumes", func() { session := podmanTest.Podman([]string{"run", "--rm", "--mount", mount + ",ro=false", ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(dest + " rw")) session = podmanTest.Podman([]string{"run", "--rm", "--mount", mount + ",ro=true", ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(dest + " ro")) session = podmanTest.Podman([]string{"run", "--rm", "--mount", mount + ",ro=true,rw=false", ALPINE, "grep", dest, "/proc/self/mountinfo"}) @@ -193,7 +193,7 @@ var _ = Describe("Podman run with volumes", func() { It("podman run with volume flag and multiple named volumes", func() { session := podmanTest.Podman([]string{"run", "--rm", "-v", "testvol1:/testvol1", "-v", "testvol2:/testvol2", ALPINE, "grep", "/testvol", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("/testvol1")) Expect(session.OutputToString()).To(ContainSubstring("/testvol2")) }) @@ -205,7 +205,7 @@ var _ = Describe("Podman run with volumes", func() { session := podmanTest.Podman([]string{"run", "--rm", "-v", mountPath + ":" + dest + ":suid,dev,exec", ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, matches := session.GrepString(dest) Expect(found).Should(BeTrue()) Expect(matches[0]).To(Not(ContainSubstring("noexec"))) @@ -214,7 +214,7 @@ var _ = Describe("Podman run with volumes", func() { session = podmanTest.Podman([]string{"run", "--rm", "--tmpfs", dest + ":suid,dev,exec", ALPINE, "grep", dest, "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, matches = session.GrepString(dest) Expect(found).Should(BeTrue()) Expect(matches[0]).To(Not(ContainSubstring("noexec"))) @@ -234,13 +234,13 @@ var _ = Describe("Podman run with volumes", func() { volName := "testvol" mkVolume := podmanTest.Podman([]string{"volume", "create", "--opt", "type=tmpfs", "--opt", "device=tmpfs", "--opt", "o=nodev", "testvol"}) mkVolume.WaitWithDefaultTimeout() - Expect(mkVolume.ExitCode()).To(Equal(0)) + Expect(mkVolume).Should(Exit(0)) // Volume not mounted on create - mountCmd1, err := gexec.Start(exec.Command("mount"), GinkgoWriter, GinkgoWriter) + mountCmd1, err := Start(exec.Command("mount"), GinkgoWriter, GinkgoWriter) Expect(err).To(BeNil()) mountCmd1.Wait(90) - Expect(mountCmd1.ExitCode()).To(Equal(0)) + Expect(mountCmd1).Should(Exit(0)) os.Stdout.Sync() os.Stderr.Sync() mountOut1 := strings.Join(strings.Fields(string(mountCmd1.Out.Contents())), " ") @@ -250,13 +250,13 @@ var _ = Describe("Podman run with volumes", func() { ctrName := "testctr" podmanSession := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "-v", fmt.Sprintf("%s:/testvol", volName), ALPINE, "top"}) podmanSession.WaitWithDefaultTimeout() - Expect(podmanSession.ExitCode()).To(Equal(0)) + Expect(podmanSession).Should(Exit(0)) // Volume now mounted as container is running - mountCmd2, err := gexec.Start(exec.Command("mount"), GinkgoWriter, GinkgoWriter) + mountCmd2, err := Start(exec.Command("mount"), GinkgoWriter, GinkgoWriter) Expect(err).To(BeNil()) mountCmd2.Wait(90) - Expect(mountCmd2.ExitCode()).To(Equal(0)) + Expect(mountCmd2).Should(Exit(0)) os.Stdout.Sync() os.Stderr.Sync() mountOut2 := strings.Join(strings.Fields(string(mountCmd2.Out.Contents())), " ") @@ -266,18 +266,18 @@ var _ = Describe("Podman run with volumes", func() { // Stop the container to unmount podmanStopSession := podmanTest.Podman([]string{"stop", "--time", "0", ctrName}) podmanStopSession.WaitWithDefaultTimeout() - Expect(podmanStopSession.ExitCode()).To(Equal(0)) + Expect(podmanStopSession).Should(Exit(0)) // We have to force cleanup so the unmount happens podmanCleanupSession := podmanTest.Podman([]string{"container", "cleanup", ctrName}) podmanCleanupSession.WaitWithDefaultTimeout() - Expect(podmanCleanupSession.ExitCode()).To(Equal(0)) + Expect(podmanCleanupSession).Should(Exit(0)) // Ensure volume is unmounted - mountCmd3, err := gexec.Start(exec.Command("mount"), GinkgoWriter, GinkgoWriter) + mountCmd3, err := Start(exec.Command("mount"), GinkgoWriter, GinkgoWriter) Expect(err).To(BeNil()) mountCmd3.Wait(90) - Expect(mountCmd3.ExitCode()).To(Equal(0)) + Expect(mountCmd3).Should(Exit(0)) os.Stdout.Sync() os.Stderr.Sync() mountOut3 := strings.Join(strings.Fields(string(mountCmd3.Out.Contents())), " ") @@ -288,21 +288,21 @@ var _ = Describe("Podman run with volumes", func() { It("podman named volume copyup", func() { baselineSession := podmanTest.Podman([]string{"run", "--rm", "-t", "-i", ALPINE, "ls", "/etc/apk/"}) baselineSession.WaitWithDefaultTimeout() - Expect(baselineSession.ExitCode()).To(Equal(0)) + Expect(baselineSession).Should(Exit(0)) baselineOutput := baselineSession.OutputToString() inlineVolumeSession := podmanTest.Podman([]string{"run", "--rm", "-t", "-i", "-v", "testvol1:/etc/apk", ALPINE, "ls", "/etc/apk/"}) inlineVolumeSession.WaitWithDefaultTimeout() - Expect(inlineVolumeSession.ExitCode()).To(Equal(0)) + Expect(inlineVolumeSession).Should(Exit(0)) Expect(inlineVolumeSession.OutputToString()).To(Equal(baselineOutput)) makeVolumeSession := podmanTest.Podman([]string{"volume", "create", "testvol2"}) makeVolumeSession.WaitWithDefaultTimeout() - Expect(makeVolumeSession.ExitCode()).To(Equal(0)) + Expect(makeVolumeSession).Should(Exit(0)) separateVolumeSession := podmanTest.Podman([]string{"run", "--rm", "-t", "-i", "-v", "testvol2:/etc/apk", ALPINE, "ls", "/etc/apk/"}) separateVolumeSession.WaitWithDefaultTimeout() - Expect(separateVolumeSession.ExitCode()).To(Equal(0)) + Expect(separateVolumeSession).Should(Exit(0)) Expect(separateVolumeSession.OutputToString()).To(Equal(baselineOutput)) }) @@ -315,62 +315,62 @@ RUN sh -c "cd /etc/apk && ln -s ../../testfile"`, ALPINE) baselineSession := podmanTest.Podman([]string{"run", "--rm", "-t", "-i", imgName, "ls", "/etc/apk/"}) baselineSession.WaitWithDefaultTimeout() - Expect(baselineSession.ExitCode()).To(Equal(0)) + Expect(baselineSession).Should(Exit(0)) baselineOutput := baselineSession.OutputToString() outputSession := podmanTest.Podman([]string{"run", "-t", "-i", "-v", "/etc/apk/", imgName, "ls", "/etc/apk/"}) outputSession.WaitWithDefaultTimeout() - Expect(outputSession.ExitCode()).To(Equal(0)) + Expect(outputSession).Should(Exit(0)) Expect(outputSession.OutputToString()).To(Equal(baselineOutput)) }) It("podman named volume copyup empty directory", func() { baselineSession := podmanTest.Podman([]string{"run", "--rm", "-t", "-i", ALPINE, "ls", "/srv"}) baselineSession.WaitWithDefaultTimeout() - Expect(baselineSession.ExitCode()).To(Equal(0)) + Expect(baselineSession).Should(Exit(0)) baselineOutput := baselineSession.OutputToString() outputSession := podmanTest.Podman([]string{"run", "-t", "-i", "-v", "/srv", ALPINE, "ls", "/srv"}) outputSession.WaitWithDefaultTimeout() - Expect(outputSession.ExitCode()).To(Equal(0)) + Expect(outputSession).Should(Exit(0)) Expect(outputSession.OutputToString()).To(Equal(baselineOutput)) }) It("podman named volume copyup of /var", func() { baselineSession := podmanTest.Podman([]string{"run", "--rm", "-t", "-i", fedoraMinimal, "ls", "/var"}) baselineSession.WaitWithDefaultTimeout() - Expect(baselineSession.ExitCode()).To(Equal(0)) + Expect(baselineSession).Should(Exit(0)) baselineOutput := baselineSession.OutputToString() outputSession := podmanTest.Podman([]string{"run", "-t", "-i", "-v", "/var", fedoraMinimal, "ls", "/var"}) outputSession.WaitWithDefaultTimeout() - Expect(outputSession.ExitCode()).To(Equal(0)) + Expect(outputSession).Should(Exit(0)) Expect(outputSession.OutputToString()).To(Equal(baselineOutput)) }) It("podman read-only tmpfs conflict with volume", func() { session := podmanTest.Podman([]string{"run", "--rm", "-t", "-i", "--read-only", "-v", "tmp_volume:" + dest, ALPINE, "touch", dest + "/a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session2 := podmanTest.Podman([]string{"run", "--rm", "-t", "-i", "--read-only", "--tmpfs", dest, ALPINE, "touch", dest + "/a"}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) }) It("podman run with anonymous volume", func() { list1 := podmanTest.Podman([]string{"volume", "list", "--quiet"}) list1.WaitWithDefaultTimeout() - Expect(list1.ExitCode()).To(Equal(0)) + Expect(list1).Should(Exit(0)) Expect(list1.OutputToString()).To(Equal("")) session := podmanTest.Podman([]string{"create", "-v", "/test", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) list2 := podmanTest.Podman([]string{"volume", "list", "--quiet"}) list2.WaitWithDefaultTimeout() - Expect(list2.ExitCode()).To(Equal(0)) + Expect(list2).Should(Exit(0)) arr := list2.OutputToStringArray() Expect(len(arr)).To(Equal(1)) Expect(arr[0]).To(Not(Equal(""))) @@ -379,57 +379,57 @@ RUN sh -c "cd /etc/apk && ln -s ../../testfile"`, ALPINE) It("podman rm -v removes anonymous volume", func() { list1 := podmanTest.Podman([]string{"volume", "list", "--quiet"}) list1.WaitWithDefaultTimeout() - Expect(list1.ExitCode()).To(Equal(0)) + Expect(list1).Should(Exit(0)) Expect(list1.OutputToString()).To(Equal("")) ctrName := "testctr" session := podmanTest.Podman([]string{"create", "--name", ctrName, "-v", "/test", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) list2 := podmanTest.Podman([]string{"volume", "list", "--quiet"}) list2.WaitWithDefaultTimeout() - Expect(list2.ExitCode()).To(Equal(0)) + Expect(list2).Should(Exit(0)) arr := list2.OutputToStringArray() Expect(len(arr)).To(Equal(1)) Expect(arr[0]).To(Not(Equal(""))) remove := podmanTest.Podman([]string{"rm", "-v", ctrName}) remove.WaitWithDefaultTimeout() - Expect(remove.ExitCode()).To(Equal(0)) + Expect(remove).Should(Exit(0)) list3 := podmanTest.Podman([]string{"volume", "list", "--quiet"}) list3.WaitWithDefaultTimeout() - Expect(list3.ExitCode()).To(Equal(0)) + Expect(list3).Should(Exit(0)) Expect(list3.OutputToString()).To(Equal("")) }) It("podman rm -v retains named volume", func() { list1 := podmanTest.Podman([]string{"volume", "list", "--quiet"}) list1.WaitWithDefaultTimeout() - Expect(list1.ExitCode()).To(Equal(0)) + Expect(list1).Should(Exit(0)) Expect(list1.OutputToString()).To(Equal("")) ctrName := "testctr" volName := "testvol" session := podmanTest.Podman([]string{"create", "--name", ctrName, "-v", fmt.Sprintf("%s:/test", volName), ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) list2 := podmanTest.Podman([]string{"volume", "list", "--quiet"}) list2.WaitWithDefaultTimeout() - Expect(list2.ExitCode()).To(Equal(0)) + Expect(list2).Should(Exit(0)) arr := list2.OutputToStringArray() Expect(len(arr)).To(Equal(1)) Expect(arr[0]).To(Equal(volName)) remove := podmanTest.Podman([]string{"rm", "-v", ctrName}) remove.WaitWithDefaultTimeout() - Expect(remove.ExitCode()).To(Equal(0)) + Expect(remove).Should(Exit(0)) list3 := podmanTest.Podman([]string{"volume", "list", "--quiet"}) list3.WaitWithDefaultTimeout() - Expect(list3.ExitCode()).To(Equal(0)) + Expect(list3).Should(Exit(0)) arr2 := list3.OutputToStringArray() Expect(len(arr2)).To(Equal(1)) Expect(arr2[0]).To(Equal(volName)) @@ -438,7 +438,7 @@ RUN sh -c "cd /etc/apk && ln -s ../../testfile"`, ALPINE) It("podman run image volume is not noexec", func() { session := podmanTest.Podman([]string{"run", "--rm", redis, "grep", "/data", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(ContainSubstring("noexec"))) }) @@ -446,22 +446,22 @@ RUN sh -c "cd /etc/apk && ln -s ../../testfile"`, ALPINE) volName := "testVol" volCreate := podmanTest.Podman([]string{"volume", "create", "--opt", "type=tmpfs", "--opt", "device=tmpfs", "--opt", "o=invalid", volName}) volCreate.WaitWithDefaultTimeout() - Expect(volCreate.ExitCode()).To(Equal(0)) + Expect(volCreate).Should(Exit(0)) volMount := podmanTest.Podman([]string{"run", "--rm", "-v", fmt.Sprintf("%s:/tmp", volName), ALPINE, "ls"}) volMount.WaitWithDefaultTimeout() - Expect(volMount.ExitCode()).To(Not(Equal(0))) + Expect(volMount).To(ExitWithError()) }) It("Podman fix for CVE-2020-1726", func() { volName := "testVol" volCreate := podmanTest.Podman([]string{"volume", "create", volName}) volCreate.WaitWithDefaultTimeout() - Expect(volCreate.ExitCode()).To(Equal(0)) + Expect(volCreate).Should(Exit(0)) volPath := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{.Mountpoint}}", volName}) volPath.WaitWithDefaultTimeout() - Expect(volPath.ExitCode()).To(Equal(0)) + Expect(volPath).Should(Exit(0)) path := volPath.OutputToString() fileName := "thisIsATestFile" @@ -471,7 +471,7 @@ RUN sh -c "cd /etc/apk && ln -s ../../testfile"`, ALPINE) runLs := podmanTest.Podman([]string{"run", "-t", "-i", "--rm", "-v", fmt.Sprintf("%v:/etc/ssl", volName), ALPINE, "ls", "-1", "/etc/ssl"}) runLs.WaitWithDefaultTimeout() - Expect(runLs.ExitCode()).To(Equal(0)) + Expect(runLs).Should(Exit(0)) outputArr := runLs.OutputToStringArray() Expect(len(outputArr)).To(Equal(1)) Expect(strings.Contains(outputArr[0], fileName)).To(BeTrue()) @@ -486,7 +486,7 @@ VOLUME /test/`, ALPINE) ctrName := "testCtr" create := podmanTest.Podman([]string{"create", "-v", "/tmp:/test", "--name", ctrName, image, "ls"}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) data := podmanTest.InspectContainer(ctrName) Expect(len(data)).To(Equal(1)) @@ -514,7 +514,7 @@ VOLUME /test/`, ALPINE) // Make sure host directory gets mounted in to container as overlay session := podmanTest.Podman([]string{"run", "--rm", "-v", fmt.Sprintf("%s:/run/test:O", mountPath), ALPINE, "grep", "/run/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, matches := session.GrepString("/run/test") Expect(found).Should(BeTrue()) Expect(matches[0]).To(ContainSubstring("overlay")) @@ -522,37 +522,37 @@ VOLUME /test/`, ALPINE) // Make sure host files show up in the container session = podmanTest.Podman([]string{"run", "--rm", "-v", fmt.Sprintf("%s:/run/test:O", mountPath), ALPINE, "ls", "/run/test/test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Make sure modifications in container do not show up on host session = podmanTest.Podman([]string{"run", "--rm", "-v", fmt.Sprintf("%s:/run/test:O", mountPath), ALPINE, "touch", "/run/test/container"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) _, err = os.Stat(filepath.Join(mountPath, "container")) Expect(err).To(Not(BeNil())) // Make sure modifications in container disappear when container is stopped session = podmanTest.Podman([]string{"create", "-v", fmt.Sprintf("%s:/run/test:O", mountPath), ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "-l"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "-l", "touch", "/run/test/container"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "-l", "ls", "/run/test/container"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stop", "-l"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "-l"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "-l", "ls", "/run/test/container"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("overlay volume conflicts with named volume and mounts", func() { @@ -570,25 +570,27 @@ VOLUME /test/`, ALPINE) session := podmanTest.Podman([]string{"volume", "create", volName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // overlay and named volume destinations conflict session = podmanTest.Podman([]string{"run", "--rm", "-v", fmt.Sprintf("%s:%s:O", mountPath, mountDest), "-v", fmt.Sprintf("%s:%s", volName, mountDest), ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) // overlay and bind mount destinations conflict session = podmanTest.Podman([]string{"run", "--rm", "-v", fmt.Sprintf("%s:%s:O", mountPath, mountDest), "--mount", fmt.Sprintf("type=bind,src=%s,target=%s", mountSrc, mountDest), ALPINE}) - Expect(session.ExitCode()).To(Not(Equal(0))) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) // overlay and tmpfs mount destinations conflict session = podmanTest.Podman([]string{"run", "--rm", "-v", fmt.Sprintf("%s:%s:O", mountPath, mountDest), "--mount", fmt.Sprintf("type=tmpfs,target=%s", mountDest), ALPINE}) - Expect(session.ExitCode()).To(Not(Equal(0))) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) }) It("same volume in multiple places does not deadlock", func() { volName := "testVol1" session := podmanTest.Podman([]string{"run", "-t", "-i", "-v", fmt.Sprintf("%s:/test1", volName), "-v", fmt.Sprintf("%s:/test2", volName), "--rm", ALPINE, "sh", "-c", "mount | grep /test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) }) @@ -625,20 +627,20 @@ VOLUME /test/`, ALPINE) session := podmanTest.Podman([]string{"run", "--rm", "--user", "888:888", "-v", vol, ALPINE, "stat", "-c", "%u:%g", dest}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, _ := session.GrepString("888:888") Expect(found).Should(BeTrue()) session = podmanTest.Podman([]string{"run", "--rm", "--user", "888:888", "--userns", "auto", "-v", vol, ALPINE, "stat", "-c", "%u:%g", dest}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, _ = session.GrepString("888:888") Expect(found).Should(BeTrue()) vol = vol + ",O" session = podmanTest.Podman([]string{"run", "--rm", "--user", "888:888", "--userns", "keep-id", "-v", vol, ALPINE, "stat", "-c", "%u:%g", dest}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) found, _ = session.GrepString("888:888") Expect(found).Should(BeTrue()) }) @@ -654,17 +656,17 @@ USER testuser`, fedoraMinimal) test1 := podmanTest.Podman([]string{"run", "-v", "testvol1:/test", imgName, "bash", "-c", "ls -al /test | grep -v root | grep -v total"}) test1.WaitWithDefaultTimeout() - Expect(test1.ExitCode()).To(Equal(0)) + Expect(test1).Should(Exit(0)) Expect(strings.Contains(test1.OutputToString(), testString)).To(BeTrue()) volName := "testvol2" vol := podmanTest.Podman([]string{"volume", "create", volName}) vol.WaitWithDefaultTimeout() - Expect(vol.ExitCode()).To(Equal(0)) + Expect(vol).Should(Exit(0)) test2 := podmanTest.Podman([]string{"run", "-v", fmt.Sprintf("%s:/test", volName), imgName, "bash", "-c", "ls -al /test | grep -v root | grep -v total"}) test2.WaitWithDefaultTimeout() - Expect(test2.ExitCode()).To(Equal(0)) + Expect(test2).Should(Exit(0)) Expect(strings.Contains(test2.OutputToString(), testString)).To(BeTrue()) }) @@ -673,31 +675,31 @@ USER testuser`, fedoraMinimal) volName := "testVol" volCreate := podmanTest.Podman([]string{"volume", "create", "--opt", "o=uid=1000", volName}) volCreate.WaitWithDefaultTimeout() - Expect(volCreate.ExitCode()).To(Equal(0)) + Expect(volCreate).Should(Exit(0)) volMount := podmanTest.Podman([]string{"run", "--rm", "-v", fmt.Sprintf("%s:/test", volName), ALPINE, "stat", "-c", "%u", "/test"}) volMount.WaitWithDefaultTimeout() - Expect(volMount.ExitCode()).To(Equal(0)) + Expect(volMount).Should(Exit(0)) Expect(volMount.OutputToString()).To(Equal("1000")) volName = "testVol2" volCreate = podmanTest.Podman([]string{"volume", "create", "--opt", "o=gid=1000", volName}) volCreate.WaitWithDefaultTimeout() - Expect(volCreate.ExitCode()).To(Equal(0)) + Expect(volCreate).Should(Exit(0)) volMount = podmanTest.Podman([]string{"run", "--rm", "-v", fmt.Sprintf("%s:/test", volName), ALPINE, "stat", "-c", "%g", "/test"}) volMount.WaitWithDefaultTimeout() - Expect(volMount.ExitCode()).To(Equal(0)) + Expect(volMount).Should(Exit(0)) Expect(volMount.OutputToString()).To(Equal("1000")) volName = "testVol3" volCreate = podmanTest.Podman([]string{"volume", "create", "--opt", "o=uid=1000,gid=1000", volName}) volCreate.WaitWithDefaultTimeout() - Expect(volCreate.ExitCode()).To(Equal(0)) + Expect(volCreate).Should(Exit(0)) volMount = podmanTest.Podman([]string{"run", "--rm", "-v", fmt.Sprintf("%s:/test", volName), ALPINE, "stat", "-c", "%u:%g", "/test"}) volMount.WaitWithDefaultTimeout() - Expect(volMount.ExitCode()).To(Equal(0)) + Expect(volMount).Should(Exit(0)) Expect(volMount.OutputToString()).To(Equal("1000:1000")) }) }) diff --git a/test/e2e/run_working_dir_test.go b/test/e2e/run_working_dir_test.go index de0f55134..ac78110bf 100644 --- a/test/e2e/run_working_dir_test.go +++ b/test/e2e/run_working_dir_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman run", func() { @@ -36,14 +37,14 @@ var _ = Describe("Podman run", func() { It("podman run a container without workdir", func() { session := podmanTest.Podman([]string{"run", ALPINE, "pwd"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("/")) }) It("podman run a container using non existing --workdir", func() { session := podmanTest.Podman([]string{"run", "--workdir", "/home/foobar", ALPINE, "pwd"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(126)) + Expect(session).Should(Exit(126)) }) It("podman run a container on an image with a workdir", func() { @@ -54,7 +55,7 @@ WORKDIR /etc/foobar`, ALPINE) session := podmanTest.Podman([]string{"run", "test", "pwd"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("/etc/foobar")) session = podmanTest.Podman([]string{"run", "test", "ls", "-ld", "."}) @@ -63,7 +64,7 @@ WORKDIR /etc/foobar`, ALPINE) session = podmanTest.Podman([]string{"run", "--workdir", "/home/foobar", "test", "pwd"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("/home/foobar")) }) }) diff --git a/test/e2e/runlabel_test.go b/test/e2e/runlabel_test.go index 54fa7e2f6..e67b6cba1 100644 --- a/test/e2e/runlabel_test.go +++ b/test/e2e/runlabel_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var PodmanDockerfile = fmt.Sprintf(` @@ -52,11 +53,11 @@ var _ = Describe("podman container runlabel", func() { result := podmanTest.Podman([]string{"container", "runlabel", "RUN", image}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"rmi", image}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman container runlabel (ls -la)", func() { @@ -65,11 +66,11 @@ var _ = Describe("podman container runlabel", func() { result := podmanTest.Podman([]string{"container", "runlabel", "RUN", image}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) result = podmanTest.Podman([]string{"rmi", image}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman container runlabel --display", func() { image := "podman-runlabel-test:ls" @@ -77,12 +78,12 @@ var _ = Describe("podman container runlabel", func() { result := podmanTest.Podman([]string{"container", "runlabel", "--display", "RUN", image}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(podmanTest.PodmanBinary + " -la")) result = podmanTest.Podman([]string{"rmi", image}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("podman container runlabel bogus label should result in non-zero exit code", func() { result := podmanTest.Podman([]string{"container", "runlabel", "RUN", ALPINE}) @@ -105,13 +106,13 @@ var _ = Describe("podman container runlabel", func() { podmanTest.BuildImage(GlobalDockerfile, image, "false") result := podmanTest.Podman([]string{"--syslog", "--log-level", "debug", "container", "runlabel", "RUN", image}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring("--syslog true")) Expect(result.OutputToString()).To(ContainSubstring("--log-level debug")) result = podmanTest.Podman([]string{"rmi", image}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) It("runlabel should fail with nonexistent authfile", func() { @@ -121,10 +122,10 @@ var _ = Describe("podman container runlabel", func() { // runlabel should fail with nonexistent authfile result := podmanTest.Podman([]string{"container", "runlabel", "--authfile", "/tmp/nonexistent", "RUN", image}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Not(Equal(0))) + Expect(result).To(ExitWithError()) result = podmanTest.Podman([]string{"rmi", image}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) }) }) diff --git a/test/e2e/save_test.go b/test/e2e/save_test.go index 69184649f..0b3a88da3 100644 --- a/test/e2e/save_test.go +++ b/test/e2e/save_test.go @@ -12,6 +12,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman save", func() { @@ -42,7 +43,7 @@ var _ = Describe("Podman save", func() { save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) }) It("podman save oci flag", func() { @@ -50,7 +51,7 @@ var _ = Describe("Podman save", func() { save := podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-archive", ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) }) It("podman save with stdout", func() { @@ -59,7 +60,7 @@ var _ = Describe("Podman save", func() { save := podmanTest.Podman([]string{"save", ALPINE, ">", outfile}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) }) It("podman save quiet flag", func() { @@ -67,7 +68,7 @@ var _ = Describe("Podman save", func() { save := podmanTest.Podman([]string{"save", "-q", "-o", outfile, ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) }) It("podman save bogus image", func() { @@ -86,7 +87,7 @@ var _ = Describe("Podman save", func() { save := podmanTest.Podman([]string{"save", "--format", "oci-dir", "-o", outdir, ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) }) It("podman save to directory with v2s2 docker format", func() { @@ -97,7 +98,7 @@ var _ = Describe("Podman save", func() { save := podmanTest.Podman([]string{"save", "--format", "docker-dir", "-o", outdir, ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) }) It("podman save to directory with docker format and compression", func() { @@ -108,7 +109,7 @@ var _ = Describe("Podman save", func() { save := podmanTest.Podman([]string{"save", "--compress", "--format", "docker-dir", "-o", outdir, ALPINE}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) }) It("podman save to directory with --compress but not use docker-dir and oci-dir", func() { @@ -120,12 +121,12 @@ var _ = Describe("Podman save", func() { save := podmanTest.Podman([]string{"save", "--compress", "--format", "docker-archive", "-o", outdir, ALPINE}) save.WaitWithDefaultTimeout() // should not be 0 - Expect(save.ExitCode()).ToNot(Equal(0)) + Expect(save).To(ExitWithError()) save = podmanTest.Podman([]string{"save", "--compress", "--format", "oci-archive", "-o", outdir, ALPINE}) save.WaitWithDefaultTimeout() // should not be 0 - Expect(save.ExitCode()).ToNot(Equal(0)) + Expect(save).To(ExitWithError()) }) @@ -154,7 +155,7 @@ var _ = Describe("Podman save", func() { port := 5000 session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", strings.Join([]string{strconv.Itoa(port), strconv.Itoa(port)}, ":"), "quay.io/libpod/registry:2.6"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) { Skip("Cannot start docker registry.") } @@ -183,19 +184,19 @@ default-docker: session = podmanTest.Podman([]string{"tag", ALPINE, "localhost:5000/alpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"push", "--tls-verify=false", "--sign-by", "foo@bar.com", "localhost:5000/alpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", ALPINE, "localhost:5000/alpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"pull", "--tls-verify=false", "--signature-policy=sign/policy.json", "localhost:5000/alpine"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) outfile := filepath.Join(podmanTest.TempDir, "temp.tar") save := podmanTest.Podman([]string{"save", "remove-signatures=true", "-o", outfile, "localhost:5000/alpine"}) @@ -207,13 +208,13 @@ default-docker: // pull a digest reference session := podmanTest.Podman([]string{"pull", ALPINELISTDIGEST}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // save a digest reference should exit without error. outfile := filepath.Join(podmanTest.TempDir, "temp.tar") save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINELISTDIGEST}) save.WaitWithDefaultTimeout() - Expect(save.ExitCode()).To(Equal(0)) + Expect(save).Should(Exit(0)) }) It("podman save --multi-image-archive (tagged images)", func() { @@ -224,7 +225,7 @@ default-docker: // Refer to images via ID instead of tag. session := podmanTest.Podman([]string{"images", "--format", "{{.ID}}"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ids := session.OutputToStringArray() Expect(len(RESTORE_IMAGES), len(ids)) @@ -239,17 +240,17 @@ func multiImageSave(podmanTest *PodmanTestIntegration, images []string) { outfile := filepath.Join(podmanTest.TempDir, "temp.tar") session := podmanTest.Podman(append([]string{"save", "-o", outfile, "--multi-image-archive"}, images...)) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Remove all images. session = podmanTest.Podman([]string{"rmi", "-af"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Now load the archive. session = podmanTest.Podman([]string{"load", "-i", outfile}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Grep for each image in the `podman load` output. for _, image := range images { found, _ := session.GrepString(image) @@ -260,6 +261,6 @@ func multiImageSave(podmanTest *PodmanTestIntegration, images []string) { for _, image := range images { session = podmanTest.Podman([]string{"image", "exists", image}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) } } diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index 8c388d0ee..b0faabf6c 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -12,6 +12,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) type endpoint struct { @@ -87,7 +88,7 @@ registries = ['{{.Host}}:{{.Port}}']` It("podman search", func() { search := podmanTest.Podman([]string{"search", "alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(len(search.OutputToStringArray())).To(BeNumerically(">", 1)) Expect(search.LineInOutputContains("docker.io/library/alpine")).To(BeTrue()) }) @@ -95,14 +96,14 @@ registries = ['{{.Host}}:{{.Port}}']` It("podman search single registry flag", func() { search := podmanTest.Podman([]string{"search", "quay.io/skopeo/stable:latest"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(search.LineInOutputContains("quay.io/skopeo/stable")).To(BeTrue()) }) It("podman search image with description", func() { search := podmanTest.Podman([]string{"search", "quay.io/libpod/whalesay"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) output := string(search.Out.Contents()) match, _ := regexp.MatchString(`(?m)^quay.io\s+quay.io/libpod/whalesay\s+Static image used for automated testing.+$`, output) Expect(match).To(BeTrue()) @@ -111,7 +112,7 @@ registries = ['{{.Host}}:{{.Port}}']` It("podman search format flag", func() { search := podmanTest.Podman([]string{"search", "--format", "table {{.Index}} {{.Name}}", "alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(len(search.OutputToStringArray())).To(BeNumerically(">", 1)) Expect(search.LineInOutputContains("docker.io/library/alpine")).To(BeTrue()) }) @@ -119,7 +120,7 @@ registries = ['{{.Host}}:{{.Port}}']` It("podman search format json", func() { search := podmanTest.Podman([]string{"search", "--format", "json", "alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(search.IsJSONOutputValid()).To(BeTrue()) Expect(search.OutputToString()).To(ContainSubstring("docker.io/library/alpine")) }) @@ -127,7 +128,7 @@ registries = ['{{.Host}}:{{.Port}}']` It("podman search format json list tags", func() { search := podmanTest.Podman([]string{"search", "--list-tags", "--format", "json", "alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(search.IsJSONOutputValid()).To(BeTrue()) Expect(search.OutputToString()).To(ContainSubstring("docker.io/library/alpine")) Expect(search.OutputToString()).To(ContainSubstring("3.10")) @@ -137,7 +138,7 @@ registries = ['{{.Host}}:{{.Port}}']` It("podman search no-trunc flag", func() { search := podmanTest.Podman([]string{"search", "--no-trunc", "alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(len(search.OutputToStringArray())).To(BeNumerically(">", 1)) Expect(search.LineInOutputContains("docker.io/library/alpine")).To(BeTrue()) Expect(search.LineInOutputContains("...")).To(BeFalse()) @@ -146,24 +147,24 @@ registries = ['{{.Host}}:{{.Port}}']` It("podman search limit flag", func() { search := podmanTest.Podman([]string{"search", "docker.io/alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(len(search.OutputToStringArray())).To(Equal(26)) search = podmanTest.Podman([]string{"search", "--limit", "3", "docker.io/alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(len(search.OutputToStringArray())).To(Equal(4)) search = podmanTest.Podman([]string{"search", "--limit", "30", "docker.io/alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(len(search.OutputToStringArray())).To(Equal(31)) }) It("podman search with filter stars", func() { search := podmanTest.Podman([]string{"search", "--filter", "stars=10", "--format", "{{.Stars}}", "alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) output := search.OutputToStringArray() for i := 0; i < len(output); i++ { Expect(strconv.Atoi(output[i])).To(BeNumerically(">=", 10)) @@ -173,7 +174,7 @@ registries = ['{{.Host}}:{{.Port}}']` It("podman search with filter is-official", func() { search := podmanTest.Podman([]string{"search", "--filter", "is-official", "--format", "{{.Official}}", "alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) output := search.OutputToStringArray() for i := 0; i < len(output); i++ { Expect(output[i]).To(Equal("[OK]")) @@ -183,7 +184,7 @@ registries = ['{{.Host}}:{{.Port}}']` It("podman search with filter is-automated", func() { search := podmanTest.Podman([]string{"search", "--filter", "is-automated=false", "--format", "{{.Automated}}", "alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) output := search.OutputToStringArray() for i := 0; i < len(output); i++ { Expect(output[i]).To(Equal("")) @@ -201,7 +202,7 @@ registries = ['{{.Host}}:{{.Port}}']` "-p", fmt.Sprintf("%s:5000", registryEndpoints[0].Port), registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) fakereg.WaitWithDefaultTimeout() - Expect(fakereg.ExitCode()).To(Equal(0)) + Expect(fakereg).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) { Skip("Cannot start docker registry.") @@ -213,7 +214,7 @@ registries = ['{{.Host}}:{{.Port}}']` // if this test succeeded, there will be no output (there is no entry named fake/image:andtag in an empty registry) // and the exit code will be 0 - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(search.OutputToString()).Should(BeEmpty()) Expect(search.ErrorToString()).Should(BeEmpty()) }) @@ -228,7 +229,7 @@ registries = ['{{.Host}}:{{.Port}}']` "-p", fmt.Sprintf("%s:5000", registryEndpoints[3].Port), registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) registry.WaitWithDefaultTimeout() - Expect(registry.ExitCode()).To(Equal(0)) + Expect(registry).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry3", "listening on", 20, 1) { Skip("Cannot start docker registry.") @@ -238,17 +239,17 @@ registries = ['{{.Host}}:{{.Port}}']` image := fmt.Sprintf("%s/my-alpine", registryEndpoints[3].Address()) push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image}) push.WaitWithDefaultTimeout() - Expect(push.ExitCode()).To(Equal(0)) + Expect(push).Should(Exit(0)) search := podmanTest.Podman([]string{"search", image, "--tls-verify=false"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(search.OutputToString()).ShouldNot(BeEmpty()) // podman search v2 registry with empty query searchEmpty := podmanTest.Podman([]string{"search", fmt.Sprintf("%s/", registryEndpoints[3].Address()), "--tls-verify=false"}) searchEmpty.WaitWithDefaultTimeout() - Expect(searchEmpty.ExitCode()).To(BeZero()) + Expect(searchEmpty).Should(Exit(0)) Expect(len(searchEmpty.OutputToStringArray())).To(BeNumerically(">=", 1)) match, _ := search.GrepString("my-alpine") Expect(match).Should(BeTrue()) @@ -264,7 +265,7 @@ registries = ['{{.Host}}:{{.Port}}']` registry := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%s:5000", registryEndpoints[4].Port), "--name", "registry4", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) registry.WaitWithDefaultTimeout() - Expect(registry.ExitCode()).To(Equal(0)) + Expect(registry).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry4", "listening on", 20, 1) { Skip("Cannot start docker registry.") @@ -274,7 +275,7 @@ registries = ['{{.Host}}:{{.Port}}']` image := fmt.Sprintf("%s/my-alpine", registryEndpoints[4].Address()) push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image}) push.WaitWithDefaultTimeout() - Expect(push.ExitCode()).To(Equal(0)) + Expect(push).Should(Exit(0)) // registries.conf set up var buffer bytes.Buffer @@ -289,7 +290,7 @@ registries = ['{{.Host}}:{{.Port}}']` search := podmanTest.Podman([]string{"search", image}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) match, _ := search.GrepString("my-alpine") Expect(match).Should(BeTrue()) Expect(search.ErrorToString()).Should(BeEmpty()) @@ -307,7 +308,7 @@ registries = ['{{.Host}}:{{.Port}}']` registry := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%s:5000", registryEndpoints[5].Port), "--name", "registry5", registry}) registry.WaitWithDefaultTimeout() - Expect(registry.ExitCode()).To(Equal(0)) + Expect(registry).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry5", "listening on", 20, 1) { Skip("Cannot start docker registry.") @@ -317,7 +318,7 @@ registries = ['{{.Host}}:{{.Port}}']` image := fmt.Sprintf("%s/my-alpine", registryEndpoints[5].Address()) push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image}) push.WaitWithDefaultTimeout() - Expect(push.ExitCode()).To(Equal(0)) + Expect(push).Should(Exit(0)) var buffer bytes.Buffer registryFileTmpl.Execute(&buffer, registryEndpoints[5]) @@ -327,7 +328,7 @@ registries = ['{{.Host}}:{{.Port}}']` search := podmanTest.Podman([]string{"search", image, "--tls-verify=true"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(125)) + Expect(search).Should(Exit(125)) Expect(search.OutputToString()).Should(BeEmpty()) match, _ := search.ErrorGrepString("error") Expect(match).Should(BeTrue()) @@ -345,7 +346,7 @@ registries = ['{{.Host}}:{{.Port}}']` registry := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%s:5000", registryEndpoints[6].Port), "--name", "registry6", registry}) registry.WaitWithDefaultTimeout() - Expect(registry.ExitCode()).To(Equal(0)) + Expect(registry).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry6", "listening on", 20, 1) { Skip("Cannot start docker registry.") @@ -355,7 +356,7 @@ registries = ['{{.Host}}:{{.Port}}']` image := fmt.Sprintf("%s/my-alpine", registryEndpoints[6].Address()) push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image}) push.WaitWithDefaultTimeout() - Expect(push.ExitCode()).To(Equal(0)) + Expect(push).Should(Exit(0)) var buffer bytes.Buffer registryFileBadTmpl.Execute(&buffer, registryEndpoints[6]) @@ -370,7 +371,7 @@ registries = ['{{.Host}}:{{.Port}}']` search := podmanTest.Podman([]string{"search", image}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(125)) + Expect(search).Should(Exit(125)) Expect(search.OutputToString()).Should(BeEmpty()) match, _ := search.ErrorGrepString("error") Expect(match).Should(BeTrue()) @@ -391,7 +392,7 @@ registries = ['{{.Host}}:{{.Port}}']` registryLocal := podmanTest.Podman([]string{"run", "-d", "--net=host", "-p", fmt.Sprintf("%s:5000", registryEndpoints[7].Port), "--name", "registry7", registry}) registryLocal.WaitWithDefaultTimeout() - Expect(registryLocal.ExitCode()).To(Equal(0)) + Expect(registryLocal).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry7", "listening on", 20, 1) { Skip("Cannot start docker registry.") @@ -399,7 +400,7 @@ registries = ['{{.Host}}:{{.Port}}']` registryLocal = podmanTest.Podman([]string{"run", "-d", "-p", "6000:5000", "--name", "registry8", registry}) registryLocal.WaitWithDefaultTimeout() - Expect(registryLocal.ExitCode()).To(Equal(0)) + Expect(registryLocal).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry8", "listening on", 20, 1) { Skip("Cannot start docker registry.") @@ -408,7 +409,7 @@ registries = ['{{.Host}}:{{.Port}}']` podmanTest.RestoreArtifact(ALPINE) push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, "localhost:6000/my-alpine"}) push.WaitWithDefaultTimeout() - Expect(push.ExitCode()).To(Equal(0)) + Expect(push).Should(Exit(0)) // registries.conf set up var buffer bytes.Buffer @@ -424,7 +425,7 @@ registries = ['{{.Host}}:{{.Port}}']` search := podmanTest.Podman([]string{"search", "my-alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(125)) + Expect(search).Should(Exit(125)) Expect(search.OutputToString()).Should(BeEmpty()) match, _ := search.ErrorGrepString("error") Expect(match).Should(BeTrue()) @@ -437,35 +438,35 @@ registries = ['{{.Host}}:{{.Port}}']` It("podman search fail with nonexistent --authfile", func() { search := podmanTest.Podman([]string{"search", "--authfile", "/tmp/nonexistent", ALPINE}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Not(Equal(0))) + Expect(search).To(ExitWithError()) }) It("podman search with wildcards", func() { search := podmanTest.Podman([]string{"search", "--limit", "30", "registry.redhat.io/*"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(len(search.OutputToStringArray())).To(Equal(31)) search = podmanTest.Podman([]string{"search", "registry.redhat.io/*openshift*"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(len(search.OutputToStringArray()) > 1).To(BeTrue()) }) It("podman search repository tags", func() { search := podmanTest.Podman([]string{"search", "--list-tags", "--limit", "30", "docker.io/library/alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(len(search.OutputToStringArray())).To(Equal(31)) search = podmanTest.Podman([]string{"search", "--list-tags", "docker.io/library/alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(len(search.OutputToStringArray()) > 2).To(BeTrue()) search = podmanTest.Podman([]string{"search", "--filter=is-official", "--list-tags", "docker.io/library/alpine"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Not(Equal(0))) + Expect(search).To(ExitWithError()) search = podmanTest.Podman([]string{"search", "--list-tags", "docker.io/library/"}) search.WaitWithDefaultTimeout() @@ -475,7 +476,7 @@ registries = ['{{.Host}}:{{.Port}}']` It("podman search with limit over 100", func() { search := podmanTest.Podman([]string{"search", "--limit", "130", "registry.redhat.io/rhel"}) search.WaitWithDefaultTimeout() - Expect(search.ExitCode()).To(Equal(0)) + Expect(search).Should(Exit(0)) Expect(len(search.OutputToStringArray())).To(Equal(131)) }) }) diff --git a/test/e2e/secret_test.go b/test/e2e/secret_test.go index 392129784..8bbc889d7 100644 --- a/test/e2e/secret_test.go +++ b/test/e2e/secret_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman secret", func() { @@ -42,15 +43,15 @@ var _ = Describe("Podman secret", func() { session := podmanTest.Podman([]string{"secret", "create", "--driver-opts", "opt1=val", "a", secretFilePath}) session.WaitWithDefaultTimeout() secrID := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.ID}}", secrID}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal(secrID)) inspect = podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.Spec.Driver.Options}}", secrID}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(ContainSubstring("opt1:val")) }) @@ -61,7 +62,7 @@ var _ = Describe("Podman secret", func() { session := podmanTest.Podman([]string{"secret", "create", "?!", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("podman secret inspect", func() { @@ -72,11 +73,11 @@ var _ = Describe("Podman secret", func() { session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) session.WaitWithDefaultTimeout() secrID := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"secret", "inspect", secrID}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.IsJSONOutputValid()).To(BeTrue()) }) @@ -88,11 +89,11 @@ var _ = Describe("Podman secret", func() { session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) session.WaitWithDefaultTimeout() secrID := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.ID}}", secrID}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal(secrID)) }) @@ -104,16 +105,16 @@ var _ = Describe("Podman secret", func() { session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) session.WaitWithDefaultTimeout() secrID := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session2 := podmanTest.Podman([]string{"secret", "create", "b", secretFilePath}) session2.WaitWithDefaultTimeout() secrID2 := session2.OutputToString() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) inspect := podmanTest.Podman([]string{"secret", "inspect", secrID, secrID2}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.IsJSONOutputValid()).To(BeTrue()) }) @@ -124,7 +125,7 @@ var _ = Describe("Podman secret", func() { inspect := podmanTest.Podman([]string{"secret", "inspect", "bogus"}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Not(Equal(0))) + Expect(inspect).To(ExitWithError()) }) @@ -135,11 +136,11 @@ var _ = Describe("Podman secret", func() { session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) list := podmanTest.Podman([]string{"secret", "ls"}) list.WaitWithDefaultTimeout() - Expect(list.ExitCode()).To(Equal(0)) + Expect(list).Should(Exit(0)) Expect(len(list.OutputToStringArray())).To(Equal(2)) }) @@ -151,12 +152,12 @@ var _ = Describe("Podman secret", func() { session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) list := podmanTest.Podman([]string{"secret", "ls", "--format", "table {{.Name}}"}) list.WaitWithDefaultTimeout() - Expect(list.ExitCode()).To(Equal(0)) + Expect(list).Should(Exit(0)) Expect(len(list.OutputToStringArray())).To(Equal(2), list.OutputToString()) }) @@ -168,16 +169,16 @@ var _ = Describe("Podman secret", func() { session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) session.WaitWithDefaultTimeout() secrID := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) removed := podmanTest.Podman([]string{"secret", "rm", "a"}) removed.WaitWithDefaultTimeout() - Expect(removed.ExitCode()).To(Equal(0)) + Expect(removed).Should(Exit(0)) Expect(removed.OutputToString()).To(Equal(secrID)) session = podmanTest.Podman([]string{"secret", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(1)) }) @@ -188,18 +189,18 @@ var _ = Describe("Podman secret", func() { session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"secret", "create", "b", secretFilePath}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) removed := podmanTest.Podman([]string{"secret", "rm", "-a"}) removed.WaitWithDefaultTimeout() - Expect(removed.ExitCode()).To(Equal(0)) + Expect(removed).Should(Exit(0)) session = podmanTest.Podman([]string{"secret", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(1)) }) @@ -208,7 +209,7 @@ var _ = Describe("Podman secret", func() { session := podmanTest.Podman([]string{"secret", "create", "--env", "a", "MYENVVAR"}) session.WaitWithDefaultTimeout() secrID := session.OutputToString() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) os.Setenv("MYENVVAR", "somedata") if IsRemote() { @@ -218,11 +219,11 @@ var _ = Describe("Podman secret", func() { session = podmanTest.Podman([]string{"secret", "create", "--env", "a", "MYENVVAR"}) session.WaitWithDefaultTimeout() secrID = session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.ID}}", secrID}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(inspect.OutputToString()).To(Equal(secrID)) }) diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go index cb2db0810..073631ef7 100644 --- a/test/e2e/start_test.go +++ b/test/e2e/start_test.go @@ -39,79 +39,81 @@ var _ = Describe("Podman start", func() { It("podman start bogus container", func() { session := podmanTest.Podman([]string{"start", "123"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman start single container by id", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"start", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman start --rm removed on failure", func() { session := podmanTest.Podman([]string{"create", "--name=test", "--rm", ALPINE, "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) session = podmanTest.Podman([]string{"container", "exists", "test"}) - Expect(session.ExitCode()).To(Not(Equal(0))) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) }) It("podman start --rm --attach removed on failure", func() { session := podmanTest.Podman([]string{"create", "--rm", ALPINE, "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"start", "--attach", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) session = podmanTest.Podman([]string{"container", "exists", cid}) - Expect(session.ExitCode()).To(Not(Equal(0))) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) }) It("podman container start single container by id", func() { session := podmanTest.Podman([]string{"container", "create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"container", "start", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(cid)) }) It("podman container start single container by short id", func() { session := podmanTest.Podman([]string{"container", "create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() shortID := cid[0:10] session = podmanTest.Podman([]string{"container", "start", shortID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(shortID)) }) It("podman container start single container by short id", func() { session := podmanTest.Podman([]string{"container", "create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() shortID := cid[0:10] session = podmanTest.Podman([]string{"container", "start", shortID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(shortID)) session = podmanTest.Podman([]string{"stop", shortID}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(shortID)) }) @@ -119,10 +121,10 @@ var _ = Describe("Podman start", func() { name := "foobar99" session := podmanTest.Podman([]string{"create", "--name", name, ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", name}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if podmanTest.RemoteTest { Skip("Container-start name check doesn't work on remote client. It always returns the full ID.") } @@ -132,12 +134,12 @@ var _ = Describe("Podman start", func() { It("podman start single container with attach and test the signal", func() { session := podmanTest.Podman([]string{"create", "--entrypoint", "sh", ALPINE, "-c", "exit 1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"start", "--attach", cid}) session.WaitWithDefaultTimeout() // It should forward the signal - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) }) It("podman start multiple containers", func() { @@ -149,7 +151,7 @@ var _ = Describe("Podman start", func() { cid2 := session2.OutputToString() session = podmanTest.Podman([]string{"start", cid1, cid2}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman start multiple containers with bogus", func() { @@ -158,25 +160,25 @@ var _ = Describe("Podman start", func() { cid1 := session.OutputToString() session = podmanTest.Podman([]string{"start", cid1, "doesnotexist"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman multiple containers -- attach should fail", func() { session := podmanTest.Podman([]string{"create", "--name", "foobar1", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "--name", "foobar2", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "-a", "foobar1", "foobar2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman failed to start with --rm should delete the container", func() { session := podmanTest.Podman([]string{"create", "--name", "test1", "-it", "--rm", ALPINE, "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) start := podmanTest.Podman([]string{"start", "test1"}) start.WaitWithDefaultTimeout() @@ -215,12 +217,12 @@ var _ = Describe("Podman start", func() { pidfile := tempdir + "pidfile" session := podmanTest.Podman([]string{"create", "--pidfile", pidfile, ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"start", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) readFirstLine := func(path string) string { content, err := ioutil.ReadFile(path) Expect(err).To(BeNil()) diff --git a/test/e2e/stats_test.go b/test/e2e/stats_test.go index 7ab3dabc9..e32d515a0 100644 --- a/test/e2e/stats_test.go +++ b/test/e2e/stats_test.go @@ -11,6 +11,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) // TODO: we need to check the output. Currently, we only check the exit codes @@ -43,62 +44,62 @@ var _ = Describe("Podman stats", func() { It("podman stats with bogus container", func() { session := podmanTest.Podman([]string{"stats", "--no-stream", "123"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman stats on a running container", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"stats", "--no-stream", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman stats on all containers", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stats", "--no-stream", "-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman stats on all running containers", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stats", "--no-stream"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman stats only output cids", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stats", "--all", "--no-stream", "--format", "\"{{.ID}}\""}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman stats only output CPU data", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stats", "--all", "--no-stream", "--format", "\"{{.ID}} {{.UpTime}} {{.AVGCPU}}\""}) session.WaitWithDefaultTimeout() Expect(session.LineInOutputContains("UpTime")).To(BeTrue()) Expect(session.LineInOutputContains("AVGCPU")).To(BeTrue()) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman stats with json output", func() { var found bool session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) for i := 0; i < 5; i++ { ps := podmanTest.Podman([]string{"ps", "-q"}) ps.WaitWithDefaultTimeout() @@ -111,42 +112,42 @@ var _ = Describe("Podman stats", func() { Expect(found).To(BeTrue()) stats := podmanTest.Podman([]string{"stats", "--all", "--no-stream", "--format", "json"}) stats.WaitWithDefaultTimeout() - Expect(stats.ExitCode()).To(Equal(0)) + Expect(stats).Should(Exit(0)) Expect(stats.IsJSONOutputValid()).To(BeTrue()) }) It("podman stats on a container with no net ns", func() { session := podmanTest.Podman([]string{"run", "-d", "--net", "none", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stats", "--no-stream", "-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman stats on a container that joined another's net ns", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"run", "-d", "--net", fmt.Sprintf("container:%s", cid), ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stats", "--no-stream", "-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman stats on container with forced slirp4netns", func() { // This will force the slirp4netns net mode to be tested as root session := podmanTest.Podman([]string{"run", "-d", "--net", "slirp4netns", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stats", "--no-stream", "-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) // Regression test for #8265 @@ -160,19 +161,19 @@ var _ = Describe("Podman stats", func() { session := podmanTest.Podman([]string{"run", "-d", "--name", ctrNoLimit0, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "-d", "--name", ctrNoLimit1, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "-d", "--name", ctrWithLimit, "--memory", "50m", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stats", "--no-stream", "--format", "{{.MemLimit}}", ctrNoLimit0, ctrNoLimit1, ctrWithLimit}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // We have three containers. The unlimited ones need to have // the same limit, the limited one a lower one. diff --git a/test/e2e/stop_test.go b/test/e2e/stop_test.go index d6d58c94c..a984bf6d0 100644 --- a/test/e2e/stop_test.go +++ b/test/e2e/stop_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman stop", func() { @@ -37,18 +38,18 @@ var _ = Describe("Podman stop", func() { It("podman stop bogus container", func() { session := podmanTest.Podman([]string{"stop", "foobar"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman stop --ignore bogus container", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"stop", "--ignore", "foobar", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(output).To(ContainSubstring(cid)) }) @@ -56,84 +57,84 @@ var _ = Describe("Podman stop", func() { It("podman stop container by id", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() session = podmanTest.Podman([]string{"stop", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) finalCtrs.WaitWithDefaultTimeout() - Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(finalCtrs).Should(Exit(0)) Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop container by name", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stop", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) finalCtrs.WaitWithDefaultTimeout() - Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(finalCtrs).Should(Exit(0)) Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman container stop by name", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"container", "stop", "test1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) finalCtrs.WaitWithDefaultTimeout() - Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(finalCtrs).Should(Exit(0)) Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop stopped container", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session2 := podmanTest.Podman([]string{"stop", "test1"}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) session3 := podmanTest.Podman([]string{"stop", "test1"}) session3.WaitWithDefaultTimeout() - Expect(session3.ExitCode()).To(Equal(0)) + Expect(session3).Should(Exit(0)) finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) finalCtrs.WaitWithDefaultTimeout() - Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(finalCtrs).Should(Exit(0)) Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop all containers -t", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid1 := session.OutputToString() session = podmanTest.RunTopContainer("test2") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid2 := session.OutputToString() session = podmanTest.RunTopContainer("test3") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid3 := session.OutputToString() session = podmanTest.Podman([]string{"stop", "-a", "-t", "1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(output).To(ContainSubstring(cid1)) Expect(output).To(ContainSubstring(cid2)) @@ -141,42 +142,42 @@ var _ = Describe("Podman stop", func() { finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) finalCtrs.WaitWithDefaultTimeout() - Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(finalCtrs).Should(Exit(0)) Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop container --time", func() { session := podmanTest.RunTopContainer("test4") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stop", "--time", "0", "test4"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(output).To(ContainSubstring("test4")) finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) finalCtrs.WaitWithDefaultTimeout() - Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(finalCtrs).Should(Exit(0)) Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop container --timeout", func() { session := podmanTest.Podman([]string{"run", "-d", "--name", "test5", ALPINE, "sleep", "100"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stop", "--timeout", "0", "test5"}) // Without timeout container stops in 10 seconds // If not stopped in 5 seconds, then --timeout did not work session.Wait(5) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) output := session.OutputToString() Expect(output).To(ContainSubstring("test5")) finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) finalCtrs.WaitWithDefaultTimeout() - Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(finalCtrs).Should(Exit(0)) Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) @@ -184,52 +185,52 @@ var _ = Describe("Podman stop", func() { SkipIfRemote("--latest flag n/a") session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"stop", "-l", "-t", "1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) finalCtrs.WaitWithDefaultTimeout() - Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(finalCtrs).Should(Exit(0)) Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop all containers with one stopped", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session2 := podmanTest.RunTopContainer("test2") session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) cid := "-l" if IsRemote() { cid = "test2" } session3 := podmanTest.Podman([]string{"stop", cid, "-t", "1"}) session3.WaitWithDefaultTimeout() - Expect(session3.ExitCode()).To(Equal(0)) + Expect(session3).Should(Exit(0)) session4 := podmanTest.Podman([]string{"stop", "-a", "-t", "1"}) session4.WaitWithDefaultTimeout() - Expect(session4.ExitCode()).To(Equal(0)) + Expect(session4).Should(Exit(0)) finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) finalCtrs.WaitWithDefaultTimeout() - Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(finalCtrs).Should(Exit(0)) Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop all containers with one created", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session2 := podmanTest.Podman([]string{"create", ALPINE, "/bin/sh"}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) session3 := podmanTest.Podman([]string{"stop", "-a", "-t", "1"}) session3.WaitWithDefaultTimeout() - Expect(session3.ExitCode()).To(Equal(0)) + Expect(session3).Should(Exit(0)) finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) finalCtrs.WaitWithDefaultTimeout() - Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(finalCtrs).Should(Exit(0)) Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) @@ -243,16 +244,16 @@ var _ = Describe("Podman stop", func() { session := podmanTest.Podman([]string{"create", "--cidfile", tmpFile, ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToStringArray()[0] session = podmanTest.Podman([]string{"start", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"stop", "--cidfile", tmpFile}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) output := result.OutputToString() Expect(output).To(ContainSubstring(cid)) }) @@ -268,19 +269,19 @@ var _ = Describe("Podman stop", func() { session := podmanTest.Podman([]string{"run", "--cidfile", tmpFile1, "-d", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid1 := session.OutputToStringArray()[0] Expect(podmanTest.NumberOfContainers()).To(Equal(1)) session = podmanTest.Podman([]string{"run", "--cidfile", tmpFile2, "-d", ALPINE, "top"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid2 := session.OutputToStringArray()[0] Expect(podmanTest.NumberOfContainers()).To(Equal(2)) result := podmanTest.Podman([]string{"stop", "--cidfile", tmpFile1, "--cidfile", tmpFile2}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) output := result.OutputToString() Expect(output).To(ContainSubstring(cid1)) Expect(output).To(ContainSubstring(cid2)) @@ -292,52 +293,52 @@ var _ = Describe("Podman stop", func() { result := podmanTest.Podman([]string{"stop", "--cidfile", "foobar", "--latest"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) result = podmanTest.Podman([]string{"stop", "--cidfile", "foobar", "--all"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) result = podmanTest.Podman([]string{"stop", "--cidfile", "foobar", "--all", "--latest"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) result = podmanTest.Podman([]string{"stop", "--latest", "--all"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) }) It("podman stop --all", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) session = podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) session = podmanTest.Podman([]string{"stop", "--all"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) It("podman stop --ignore", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid := session.OutputToString() Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) session = podmanTest.Podman([]string{"stop", "bogus", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) session = podmanTest.Podman([]string{"stop", "--ignore", "bogus", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) }) diff --git a/test/e2e/system_df_test.go b/test/e2e/system_df_test.go index 9aee85ca3..4dc1f3591 100644 --- a/test/e2e/system_df_test.go +++ b/test/e2e/system_df_test.go @@ -9,6 +9,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("podman system df", func() { @@ -38,24 +39,24 @@ var _ = Describe("podman system df", func() { It("podman system df", func() { session := podmanTest.Podman([]string{"create", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create", "data"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "-v", "data:/data", "--name", "container1", BB}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"images", "-q"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) totImages := strconv.Itoa(len(session.OutputToStringArray())) session = podmanTest.Podman([]string{"system", "df"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(4)) images := strings.Fields(session.OutputToStringArray()[1]) containers := strings.Fields(session.OutputToStringArray()[2]) @@ -69,14 +70,14 @@ var _ = Describe("podman system df", func() { podmanTest.AddImageToRWStore(ALPINE) session := podmanTest.Podman([]string{"create", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"image", "untag", ALPINE}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"system", "df"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) }) diff --git a/test/e2e/system_reset_test.go b/test/e2e/system_reset_test.go index fcfcdaf85..102526a46 100644 --- a/test/e2e/system_reset_test.go +++ b/test/e2e/system_reset_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("podman system reset", func() { @@ -39,25 +40,25 @@ var _ = Describe("podman system reset", func() { session := podmanTest.Podman([]string{"rmi", "--force", "--all"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"images", "-n"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) l := len(session.OutputToStringArray()) podmanTest.AddImageToRWStore(ALPINE) session = podmanTest.Podman([]string{"volume", "create", "data"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "-v", "data:/data", ALPINE, "echo", "hello"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"system", "reset", "-f"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // If remote then the API service should have exited // On local tests this is a noop @@ -65,17 +66,17 @@ var _ = Describe("podman system reset", func() { session = podmanTest.Podman([]string{"images", "-n"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(l)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(0)) session = podmanTest.Podman([]string{"container", "ls", "-q"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(0)) }) }) diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go index 8dc14d5f7..bb51d6ac2 100644 --- a/test/e2e/systemd_test.go +++ b/test/e2e/systemd_test.go @@ -10,6 +10,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman systemd", func() { @@ -57,21 +58,21 @@ WantedBy=multi-user.target stop := SystemExec("bash", []string{"-c", "systemctl stop redis"}) os.Remove("/etc/systemd/system/redis.service") SystemExec("bash", []string{"-c", "systemctl daemon-reload"}) - Expect(stop.ExitCode()).To(Equal(0)) + Expect(stop).Should(Exit(0)) }() create := podmanTest.Podman([]string{"create", "--name", "redis", redis}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) enable := SystemExec("bash", []string{"-c", "systemctl daemon-reload"}) - Expect(enable.ExitCode()).To(Equal(0)) + Expect(enable).Should(Exit(0)) start := SystemExec("bash", []string{"-c", "systemctl start redis"}) - Expect(start.ExitCode()).To(Equal(0)) + Expect(start).Should(Exit(0)) logs := SystemExec("bash", []string{"-c", "journalctl -n 20 -u redis"}) - Expect(logs.ExitCode()).To(Equal(0)) + Expect(logs).Should(Exit(0)) status := SystemExec("bash", []string{"-c", "systemctl status redis"}) Expect(status.OutputToString()).To(ContainSubstring("active (running)")) @@ -81,19 +82,19 @@ WantedBy=multi-user.target ctrName := "testSystemd" run := podmanTest.Podman([]string{"run", "--name", ctrName, "-t", "-i", "-d", ubi_init, "/sbin/init"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) ctrID := run.OutputToString() logs := podmanTest.Podman([]string{"logs", ctrName}) logs.WaitWithDefaultTimeout() - Expect(logs.ExitCode()).To(Equal(0)) + Expect(logs).Should(Exit(0)) // Give container 10 seconds to start started := false for i := 0; i < 10; i++ { runningCtrs := podmanTest.Podman([]string{"ps", "-q", "--no-trunc"}) runningCtrs.WaitWithDefaultTimeout() - Expect(runningCtrs.ExitCode()).To(Equal(0)) + Expect(runningCtrs).Should(Exit(0)) if strings.Contains(runningCtrs.OutputToString(), ctrID) { started = true @@ -107,12 +108,12 @@ WantedBy=multi-user.target systemctl := podmanTest.Podman([]string{"exec", "-t", "-i", ctrName, "systemctl", "status", "--no-pager"}) systemctl.WaitWithDefaultTimeout() - Expect(systemctl.ExitCode()).To(Equal(0)) + Expect(systemctl).Should(Exit(0)) Expect(strings.Contains(systemctl.OutputToString(), "State:")).To(BeTrue()) result := podmanTest.Podman([]string{"inspect", ctrName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() Expect(len(conData)).To(Equal(1)) Expect(conData[0].Config.SystemdMode).To(BeTrue()) @@ -120,7 +121,7 @@ WantedBy=multi-user.target if CGROUPSV2 || !rootless.IsRootless() { stats := podmanTest.Podman([]string{"stats", "--no-stream", ctrName}) stats.WaitWithDefaultTimeout() - Expect(stats.ExitCode()).To(Equal(0)) + Expect(stats).Should(Exit(0)) } }) @@ -128,11 +129,11 @@ WantedBy=multi-user.target ctrName := "testCtr" run := podmanTest.Podman([]string{"create", "--name", ctrName, "--entrypoint", "/sbin/init", ubi_init}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) result := podmanTest.Podman([]string{"inspect", ctrName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() Expect(len(conData)).To(Equal(1)) Expect(conData[0].Config.SystemdMode).To(BeTrue()) @@ -142,11 +143,11 @@ WantedBy=multi-user.target ctrName := "testCtrUidMap" run := podmanTest.Podman([]string{"run", "-d", "--uidmap=0:1:1000", "--name", ctrName, ALPINE, "top"}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) session := podmanTest.Podman([]string{"inspect", "--format", "{{.ConmonPidFile}}", ctrName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) pidFile := strings.TrimSuffix(session.OutputToString(), "\n") _, err := ioutil.ReadFile(pidFile) @@ -157,11 +158,11 @@ WantedBy=multi-user.target ctrName := "testCtr" run := podmanTest.Podman([]string{"create", "--name", ctrName, "--systemd", "always", ALPINE}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(0)) + Expect(run).Should(Exit(0)) result := podmanTest.Podman([]string{"inspect", ctrName}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) conData := result.InspectContainerToJSON() Expect(len(conData)).To(Equal(1)) Expect(conData[0].Config.SystemdMode).To(BeTrue()) @@ -170,7 +171,7 @@ WantedBy=multi-user.target It("podman run --systemd container should NOT mount /run noexec", func() { session := podmanTest.Podman([]string{"run", "--systemd", "always", ALPINE, "sh", "-c", "mount | grep \"/run \""}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(ContainSubstring("noexec"))) }) diff --git a/test/e2e/tag_test.go b/test/e2e/tag_test.go index 83b6d023d..b835d3776 100644 --- a/test/e2e/tag_test.go +++ b/test/e2e/tag_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman tag", func() { @@ -35,11 +36,11 @@ var _ = Describe("Podman tag", func() { It("podman tag shortname:latest", func() { session := podmanTest.Podman([]string{"tag", ALPINE, "foobar:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) results := podmanTest.Podman([]string{"inspect", "foobar:latest"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) inspectData := results.InspectImageJSON() Expect(StringInSlice("quay.io/libpod/alpine:latest", inspectData[0].RepoTags)).To(BeTrue()) Expect(StringInSlice("localhost/foobar:latest", inspectData[0].RepoTags)).To(BeTrue()) @@ -48,11 +49,11 @@ var _ = Describe("Podman tag", func() { It("podman tag shortname", func() { session := podmanTest.Podman([]string{"tag", ALPINE, "foobar"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) results := podmanTest.Podman([]string{"inspect", "foobar:latest"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) inspectData := results.InspectImageJSON() Expect(StringInSlice("quay.io/libpod/alpine:latest", inspectData[0].RepoTags)).To(BeTrue()) Expect(StringInSlice("localhost/foobar:latest", inspectData[0].RepoTags)).To(BeTrue()) @@ -61,11 +62,11 @@ var _ = Describe("Podman tag", func() { It("podman tag shortname:tag", func() { session := podmanTest.Podman([]string{"tag", ALPINE, "foobar:new"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) results := podmanTest.Podman([]string{"inspect", "foobar:new"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) inspectData := results.InspectImageJSON() Expect(StringInSlice("quay.io/libpod/alpine:latest", inspectData[0].RepoTags)).To(BeTrue()) Expect(StringInSlice("localhost/foobar:new", inspectData[0].RepoTags)).To(BeTrue()) @@ -74,14 +75,14 @@ var _ = Describe("Podman tag", func() { It("podman tag shortname image no tag", func() { session := podmanTest.Podman([]string{"tag", ALPINE, "foobar"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) results := podmanTest.Podman([]string{"tag", "foobar", "barfoo"}) results.WaitWithDefaultTimeout() - Expect(results.ExitCode()).To(Equal(0)) + Expect(results).Should(Exit(0)) verify := podmanTest.Podman([]string{"inspect", "barfoo"}) verify.WaitWithDefaultTimeout() - Expect(verify.ExitCode()).To(Equal(0)) + Expect(verify).Should(Exit(0)) }) }) diff --git a/test/e2e/toolbox_test.go b/test/e2e/toolbox_test.go index 16300bebc..e1fe44675 100644 --- a/test/e2e/toolbox_test.go +++ b/test/e2e/toolbox_test.go @@ -39,6 +39,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Toolbox-specific testing", func() { @@ -70,7 +71,7 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"run", "--dns", "none", ALPINE, "sh", "-c", "rm -f /etc/resolv.conf; touch -d '1970-01-01 00:02:03' /etc/resolv.conf; stat -c %s:%Y /etc/resolv.conf"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0:123")) }) @@ -80,7 +81,7 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"run", "--no-hosts", ALPINE, "sh", "-c", "rm -f /etc/hosts; touch -d '1970-01-01 00:02:03' /etc/hosts; stat -c %s:%Y /etc/hosts"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("0:123")) }) @@ -100,16 +101,16 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"create", "--name", "test", "--ulimit", "host", ALPINE, "sleep", "1000"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "test", "sh", "-c", "ulimit -H -n"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) containerHardLimit, err = strconv.Atoi(strings.Trim(session.OutputToString(), "\n")) Expect(err).To(BeNil()) Expect(containerHardLimit).To(BeNumerically(">=", rlimit.Max)) @@ -141,16 +142,16 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"create", "--name", "test", "--ipc=host", "--pid=host", ALPINE, "sleep", "1000"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"exec", "test", "df", "/dev/shm"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) lines = session.OutputToStringArray() fields = strings.Fields(lines[len(lines)-1]) containerShmSize, err = strconv.Atoi(fields[1]) @@ -168,7 +169,7 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--user", "root:root", ALPINE, "id"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("uid=0(root) gid=0(root)")) }) @@ -185,12 +186,12 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"create", "--name", "test", "--userns=keep-id", ALPINE, "sleep", "1000"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(err).To(BeNil()) session = podmanTest.Podman([]string{"start", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) expectedOutput := fmt.Sprintf("uid=%s(%s) gid=%s(%s)", currentUser.Uid, currentUser.Username, @@ -199,7 +200,7 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"exec", "test", "id"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(expectedOutput)) }) @@ -218,11 +219,11 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", fmt.Sprintf("%s; %s; echo READY; sleep 1000", useradd, passwd)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(WaitContainerReady(podmanTest, "test", "READY", 5, 1)).To(BeTrue()) @@ -231,14 +232,14 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"exec", "test", "cat", "/etc/passwd"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(expectedOutput)) expectedOutput = "passwd: Note: deleting a password also unlocks the password." session = podmanTest.Podman([]string{"logs", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.ErrorToString()).To(ContainSubstring(expectedOutput)) }) @@ -253,22 +254,22 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", fmt.Sprintf("%s; echo READY; sleep 1000", groupadd)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(WaitContainerReady(podmanTest, "test", "READY", 5, 1)).To(BeTrue()) session = podmanTest.Podman([]string{"exec", "test", "cat", "/etc/group"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(groupName)) session = podmanTest.Podman([]string{"logs", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("READY")) }) @@ -297,11 +298,11 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", fmt.Sprintf("%s; %s; %s; echo READY; sleep 1000", useradd, groupadd, usermod)}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(WaitContainerReady(podmanTest, "test", "READY", 5, 1)).To(BeTrue()) @@ -310,12 +311,12 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"exec", "test", "cat", "/etc/passwd"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(expectedUser)) session = podmanTest.Podman([]string{"logs", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("READY")) }) @@ -325,12 +326,12 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"run", "--privileged", "--userns=keep-id", "--user", "root:root", ALPINE, "mount", "-t", "tmpfs", "tmpfs", "/tmp"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"run", "--privileged", "--userns=keep-id", "--user", "root:root", ALPINE, "mount", "--rbind", "/tmp", "/var/tmp"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman create + start - with all needed switches for create - sleep as entry-point", func() { @@ -355,17 +356,17 @@ var _ = Describe("Toolbox-specific testing", func() { "--user", "root:root", fedoraToolbox, "sh", "-c", "echo READY; sleep 1000"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(WaitContainerReady(podmanTest, "test", "READY", 5, 1)).To(BeTrue()) session = podmanTest.Podman([]string{"logs", "test"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("READY")) }) @@ -377,7 +378,7 @@ var _ = Describe("Toolbox-specific testing", func() { session = podmanTest.Podman([]string{"run", "-v", fmt.Sprintf("%s:%s", currentUser.HomeDir, currentUser.HomeDir), "--userns=keep-id", fedoraToolbox, "sh", "-c", "echo $HOME"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(currentUser.HomeDir)) if rootless.IsRootless() { @@ -388,7 +389,7 @@ var _ = Describe("Toolbox-specific testing", func() { "--volume", volumeArg, fedoraToolbox, "sh", "-c", "echo $HOME"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring(currentUser.HomeDir)) } }) diff --git a/test/e2e/top_test.go b/test/e2e/top_test.go index d7105b17a..3cf6244b6 100644 --- a/test/e2e/top_test.go +++ b/test/e2e/top_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman top", func() { @@ -35,13 +36,13 @@ var _ = Describe("Podman top", func() { It("podman top without container name or id", func() { result := podmanTest.Podman([]string{"top"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) }) It("podman top on bogus container", func() { result := podmanTest.Podman([]string{"top", "1234"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) }) It("podman top on non-running container", func() { @@ -49,68 +50,68 @@ var _ = Describe("Podman top", func() { Expect(ec).To(Equal(0)) result := podmanTest.Podman([]string{"top", cid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) }) It("podman top on container", func() { session := podmanTest.Podman([]string{"run", "--name", "test", "-d", ALPINE, "top", "-d", "2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"top", "test"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1)) }) It("podman container top on container", func() { session := podmanTest.Podman([]string{"container", "run", "--name", "test", "-d", ALPINE, "top", "-d", "2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"container", "top", "test"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1)) }) It("podman top with options", func() { session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top", "-d", "2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"top", session.OutputToString(), "pid", "%C", "args"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1)) }) It("podman top with ps(1) options", func() { session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top", "-d", "2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"top", session.OutputToString(), "aux"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1)) }) It("podman top with comma-separated options", func() { session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top", "-d", "2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) result := podmanTest.Podman([]string{"top", session.OutputToString(), "user,pid,comm"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(0)) + Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1)) }) It("podman top on container invalid options", func() { top := podmanTest.RunTopContainer("") top.WaitWithDefaultTimeout() - Expect(top.ExitCode()).To(Equal(0)) + Expect(top).Should(Exit(0)) cid := top.OutputToString() // We need to pass -eo to force executing ps in the Alpine container. @@ -119,7 +120,7 @@ var _ = Describe("Podman top", func() { // the wrong input and still print the -ef output instead. result := podmanTest.Podman([]string{"top", cid, "-eo", "invalid"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result).Should(Exit(125)) }) }) diff --git a/test/e2e/tree_test.go b/test/e2e/tree_test.go index 33c69554b..492dc50b2 100644 --- a/test/e2e/tree_test.go +++ b/test/e2e/tree_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman image tree", func() { @@ -45,16 +46,16 @@ ENV foo=bar session := podmanTest.Podman([]string{"image", "tree", "test:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"image", "tree", "--whatrequires", "quay.io/libpod/cirros:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", "test:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"rmi", "quay.io/libpod/cirros:latest"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) }) diff --git a/test/e2e/trust_test.go b/test/e2e/trust_test.go index ae7b987ae..7f97f280a 100644 --- a/test/e2e/trust_test.go +++ b/test/e2e/trust_test.go @@ -9,6 +9,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman trust", func() { @@ -43,7 +44,7 @@ var _ = Describe("Podman trust", func() { } session := podmanTest.Podman([]string{"image", "trust", "show", "--registrypath", filepath.Dir(path), "--policypath", filepath.Join(filepath.Dir(path), "policy.json")}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) outArray := session.OutputToStringArray() Expect(len(outArray)).To(Equal(3)) @@ -61,7 +62,7 @@ var _ = Describe("Podman trust", func() { } session := podmanTest.Podman([]string{"image", "trust", "set", "--policypath", filepath.Join(filepath.Dir(path), "trust_set_test.json"), "-t", "accept", "default"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) var teststruct map[string][]map[string]string policyContent, err := ioutil.ReadFile(filepath.Join(filepath.Dir(path), "trust_set_test.json")) if err != nil { @@ -77,7 +78,7 @@ var _ = Describe("Podman trust", func() { It("podman image trust show --json", func() { session := podmanTest.Podman([]string{"image", "trust", "show", "--json"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) var teststruct []map[string]string json.Unmarshal(session.Out.Contents(), &teststruct) @@ -90,7 +91,7 @@ var _ = Describe("Podman trust", func() { It("podman image trust show --raw", func() { session := podmanTest.Podman([]string{"image", "trust", "show", "--raw"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) Expect(session.OutputToString()).To(ContainSubstring("default")) Expect(session.OutputToString()).To(ContainSubstring("insecureAcceptAnything")) diff --git a/test/e2e/unshare_test.go b/test/e2e/unshare_test.go index 24ab98916..eacdda68a 100644 --- a/test/e2e/unshare_test.go +++ b/test/e2e/unshare_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman unshare", func() { @@ -45,7 +46,7 @@ var _ = Describe("Podman unshare", func() { userNS, _ := os.Readlink("/proc/self/ns/user") session := podmanTest.Podman([]string{"unshare", "readlink", "/proc/self/ns/user"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) ok, _ := session.GrepString(userNS) Expect(ok).To(BeFalse()) }) @@ -53,7 +54,7 @@ var _ = Describe("Podman unshare", func() { It("podman unshare --rootles-cni", func() { session := podmanTest.Podman([]string{"unshare", "--rootless-cni", "ip", "addr"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("tap0")) }) }) diff --git a/test/e2e/untag_test.go b/test/e2e/untag_test.go index d0d271715..b247ad5da 100644 --- a/test/e2e/untag_test.go +++ b/test/e2e/untag_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman untag", func() { @@ -39,25 +40,25 @@ var _ = Describe("Podman untag", func() { cmd = append(cmd, tags...) session := podmanTest.Podman(cmd) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Make sure that all tags exists. for _, t := range tags { session = podmanTest.Podman([]string{"image", "exists", t}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) } // No arguments -> remove all tags. session = podmanTest.Podman([]string{"untag", cirros}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) // Make sure that none of tags exists anymore. for _, t := range tags { session = podmanTest.Podman([]string{"image", "exists", t}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) } }) @@ -78,19 +79,19 @@ var _ = Describe("Podman untag", func() { for _, tt := range tests { session := podmanTest.Podman([]string{"tag", cirros, tt.tag}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"image", "exists", tt.normalized}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"untag", cirros, tt.tag}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"image", "exists", tt.normalized}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) } }) diff --git a/test/e2e/volume_create_test.go b/test/e2e/volume_create_test.go index ab65146eb..51005d177 100644 --- a/test/e2e/volume_create_test.go +++ b/test/e2e/volume_create_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman volume create", func() { @@ -37,7 +38,7 @@ var _ = Describe("Podman volume create", func() { session := podmanTest.Podman([]string{"volume", "create"}) session.WaitWithDefaultTimeout() volName := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"volume", "ls", "-q"}) check.WaitWithDefaultTimeout() @@ -50,7 +51,7 @@ var _ = Describe("Podman volume create", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol"}) session.WaitWithDefaultTimeout() volName := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) check := podmanTest.Podman([]string{"volume", "ls", "-q"}) check.WaitWithDefaultTimeout() @@ -71,16 +72,16 @@ var _ = Describe("Podman volume create", func() { gid := "4000" session := podmanTest.Podman([]string{"volume", "create", "--opt", fmt.Sprintf("o=uid=%s,gid=%s", uid, gid), volName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspectUID := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .UID }}", volName}) inspectUID.WaitWithDefaultTimeout() - Expect(inspectUID.ExitCode()).To(Equal(0)) + Expect(inspectUID).Should(Exit(0)) Expect(inspectUID.OutputToString()).To(Equal(uid)) inspectGID := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .GID }}", volName}) inspectGID.WaitWithDefaultTimeout() - Expect(inspectGID.ExitCode()).To(Equal(0)) + Expect(inspectGID).Should(Exit(0)) Expect(inspectGID.OutputToString()).To(Equal(gid)) // options should containt `uid=3000,gid=4000:3000:4000` @@ -88,7 +89,7 @@ var _ = Describe("Podman volume create", func() { optionStrFormatExpect := fmt.Sprintf(`uid=%s,gid=%s:%s:%s`, uid, gid, uid, gid) inspectOpts := podmanTest.Podman([]string{"volume", "inspect", "--format", optionFormat, volName}) inspectOpts.WaitWithDefaultTimeout() - Expect(inspectOpts.ExitCode()).To(Equal(0)) + Expect(inspectOpts).Should(Exit(0)) Expect(inspectOpts.OutputToString()).To(Equal(optionStrFormatExpect)) }) }) diff --git a/test/e2e/volume_exists_test.go b/test/e2e/volume_exists_test.go index edbeb2c69..2118eb307 100644 --- a/test/e2e/volume_exists_test.go +++ b/test/e2e/volume_exists_test.go @@ -7,6 +7,7 @@ import ( "github.com/containers/storage/pkg/stringid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman volume exists", func() { @@ -37,14 +38,14 @@ var _ = Describe("Podman volume exists", func() { vol := "vol" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"volume", "create", vol}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(BeZero()) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "exists", vol}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "exists", stringid.GenerateNonCryptoID()}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) }) }) diff --git a/test/e2e/volume_inspect_test.go b/test/e2e/volume_inspect_test.go index 05aaf1025..db95ba675 100644 --- a/test/e2e/volume_inspect_test.go +++ b/test/e2e/volume_inspect_test.go @@ -7,6 +7,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman volume inspect", func() { @@ -37,11 +38,11 @@ var _ = Describe("Podman volume inspect", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol"}) session.WaitWithDefaultTimeout() volName := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "inspect", volName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) }) @@ -49,11 +50,11 @@ var _ = Describe("Podman volume inspect", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol"}) session.WaitWithDefaultTimeout() volName := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "inspect", "--format", "{{.Name}}", volName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal(volName)) }) @@ -61,16 +62,16 @@ var _ = Describe("Podman volume inspect", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol1"}) session.WaitWithDefaultTimeout() volName1 := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create", "myvol2"}) session.WaitWithDefaultTimeout() volName2 := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "inspect", "--format", "{{.Name}}", "--all"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(session.OutputToStringArray()[0]).To(Equal(volName1)) Expect(session.OutputToStringArray()[1]).To(Equal(volName2)) @@ -80,11 +81,11 @@ var _ = Describe("Podman volume inspect", func() { volName := "testvol" session := podmanTest.Podman([]string{"volume", "create", "--opt", "type=tmpfs", volName}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) inspect := podmanTest.Podman([]string{"volume", "inspect", volName}) inspect.WaitWithDefaultTimeout() - Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect).Should(Exit(0)) Expect(strings.Contains(inspect.OutputToString(), "tmpfs")).To(BeTrue()) }) }) diff --git a/test/e2e/volume_ls_test.go b/test/e2e/volume_ls_test.go index cb5ecbcc3..0dd1a2b7c 100644 --- a/test/e2e/volume_ls_test.go +++ b/test/e2e/volume_ls_test.go @@ -37,29 +37,29 @@ var _ = Describe("Podman volume ls", func() { It("podman ls volume", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) }) It("podman ls volume with JSON format", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls", "--format", "json"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) }) It("podman ls volume with Go template", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls", "--format", "table {{.Name}} {{.Driver}} {{.Scope}}"}) session.WaitWithDefaultTimeout() @@ -72,32 +72,48 @@ var _ = Describe("Podman volume ls", func() { session := podmanTest.Podman([]string{"volume", "create", "--label", "foo=bar", "myvol"}) volName := session.OutputToString() session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls", "--filter", "label=foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(session.OutputToStringArray()[1]).To(ContainSubstring(volName)) session = podmanTest.Podman([]string{"volume", "ls", "--filter", "label=foo=foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(0)) session = podmanTest.Podman([]string{"volume", "ls", "--filter", "label=foo=bar"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(session.OutputToStringArray()[1]).To(ContainSubstring(volName)) session = podmanTest.Podman([]string{"volume", "ls", "--filter", "label=foo=baz"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(0)) + }) + + It("podman ls volume with --filter until flag", func() { + session := podmanTest.Podman([]string{"volume", "create"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"volume", "ls", "--filter", "until=5000000000"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(2)) + + session = podmanTest.Podman([]string{"volume", "ls", "--filter", "until=50000"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(0)) }) @@ -105,52 +121,52 @@ var _ = Describe("Podman volume ls", func() { volName1 := "volume1" session := podmanTest.Podman([]string{"volume", "create", volName1}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) volName2 := "volume2" session2 := podmanTest.Podman([]string{"volume", "create", volName2}) session2.WaitWithDefaultTimeout() - Expect(session2.ExitCode()).To(Equal(0)) + Expect(session2).Should(Exit(0)) ctr := podmanTest.Podman([]string{"create", "-v", fmt.Sprintf("%s:/test", volName2), ALPINE, "sh"}) ctr.WaitWithDefaultTimeout() - Expect(ctr.ExitCode()).To(Equal(0)) + Expect(ctr).Should(Exit(0)) lsNoDangling := podmanTest.Podman([]string{"volume", "ls", "--filter", "dangling=false", "--quiet"}) lsNoDangling.WaitWithDefaultTimeout() - Expect(lsNoDangling.ExitCode()).To(Equal(0)) + Expect(lsNoDangling).Should(Exit(0)) Expect(lsNoDangling.OutputToString()).To(ContainSubstring(volName2)) lsDangling := podmanTest.Podman([]string{"volume", "ls", "--filter", "dangling=true", "--quiet"}) lsDangling.WaitWithDefaultTimeout() - Expect(lsDangling.ExitCode()).To(Equal(0)) + Expect(lsDangling).Should(Exit(0)) Expect(lsDangling.OutputToString()).To(ContainSubstring(volName1)) }) It("podman ls volume with multiple --filter flag", func() { session := podmanTest.Podman([]string{"volume", "create", "--label", "foo=bar", "myvol"}) volName := session.OutputToString() session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create", "--label", "foo2=bar2", "anothervol"}) anotherVol := session.OutputToString() session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls", "--filter", "label=foo", "--filter", "label=foo2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(3)) Expect(session.OutputToStringArray()[1]).To(ContainSubstring(volName)) Expect(session.OutputToStringArray()[2]).To(ContainSubstring(anotherVol)) session = podmanTest.Podman([]string{"volume", "ls", "--filter", "label=foo=bar", "--filter", "label=foo2=bar2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(3)) Expect(session.OutputToStringArray()[1]).To(ContainSubstring(volName)) Expect(session.OutputToStringArray()[2]).To(ContainSubstring(anotherVol)) diff --git a/test/e2e/volume_plugin_test.go b/test/e2e/volume_plugin_test.go index 183050e8c..cdf635b14 100644 --- a/test/e2e/volume_plugin_test.go +++ b/test/e2e/volume_plugin_test.go @@ -8,6 +8,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman volume plugins", func() { @@ -41,13 +42,13 @@ var _ = Describe("Podman volume plugins", func() { It("volume create with nonexistent plugin errors", func() { session := podmanTest.Podman([]string{"volume", "create", "--driver", "notexist", "test_volume_name"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("volume create with not-running plugin does not error", func() { session := podmanTest.Podman([]string{"volume", "create", "--driver", "testvol0", "test_volume_name"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Not(Equal(0))) + Expect(session).To(ExitWithError()) }) It("volume create and remove with running plugin succeeds", func() { @@ -60,27 +61,27 @@ var _ = Describe("Podman volume plugins", func() { pluginName := "testvol1" plugin := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath}) plugin.WaitWithDefaultTimeout() - Expect(plugin.ExitCode()).To(Equal(0)) + Expect(plugin).Should(Exit(0)) volName := "testVolume1" create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) ls1 := podmanTest.Podman([]string{"volume", "ls", "-q"}) ls1.WaitWithDefaultTimeout() - Expect(ls1.ExitCode()).To(Equal(0)) + Expect(ls1).Should(Exit(0)) arrOutput := ls1.OutputToStringArray() Expect(len(arrOutput)).To(Equal(1)) Expect(arrOutput[0]).To(ContainSubstring(volName)) remove := podmanTest.Podman([]string{"volume", "rm", volName}) remove.WaitWithDefaultTimeout() - Expect(remove.ExitCode()).To(Equal(0)) + Expect(remove).Should(Exit(0)) ls2 := podmanTest.Podman([]string{"volume", "ls", "-q"}) ls2.WaitWithDefaultTimeout() - Expect(ls2.ExitCode()).To(Equal(0)) + Expect(ls2).Should(Exit(0)) Expect(len(ls2.OutputToStringArray())).To(Equal(0)) }) @@ -94,16 +95,16 @@ var _ = Describe("Podman volume plugins", func() { pluginName := "testvol2" plugin := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath}) plugin.WaitWithDefaultTimeout() - Expect(plugin.ExitCode()).To(Equal(0)) + Expect(plugin).Should(Exit(0)) volName := "testVolume1" create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) volInspect := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .Driver }}", volName}) volInspect.WaitWithDefaultTimeout() - Expect(volInspect.ExitCode()).To(Equal(0)) + Expect(volInspect).Should(Exit(0)) Expect(volInspect.OutputToString()).To(ContainSubstring(pluginName)) }) @@ -118,33 +119,33 @@ var _ = Describe("Podman volume plugins", func() { ctrName := "pluginCtr" plugin := podmanTest.Podman([]string{"run", "--name", ctrName, "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath}) plugin.WaitWithDefaultTimeout() - Expect(plugin.ExitCode()).To(Equal(0)) + Expect(plugin).Should(Exit(0)) volName := "testVolume1" create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) ls1 := podmanTest.Podman([]string{"volume", "ls", "-q"}) ls1.WaitWithDefaultTimeout() - Expect(ls1.ExitCode()).To(Equal(0)) + Expect(ls1).Should(Exit(0)) arrOutput := ls1.OutputToStringArray() Expect(len(arrOutput)).To(Equal(1)) Expect(arrOutput[0]).To(ContainSubstring(volName)) stop := podmanTest.Podman([]string{"stop", "--timeout", "0", ctrName}) stop.WaitWithDefaultTimeout() - Expect(stop.ExitCode()).To(Equal(0)) + Expect(stop).Should(Exit(0)) // Remove should exit non-zero because missing plugin remove := podmanTest.Podman([]string{"volume", "rm", volName}) remove.WaitWithDefaultTimeout() - Expect(remove.ExitCode()).To(Not(Equal(0))) + Expect(remove).To(ExitWithError()) // But the volume should still be gone ls2 := podmanTest.Podman([]string{"volume", "ls", "-q"}) ls2.WaitWithDefaultTimeout() - Expect(ls2.ExitCode()).To(Equal(0)) + Expect(ls2).Should(Exit(0)) Expect(len(ls2.OutputToStringArray())).To(Equal(0)) }) @@ -158,20 +159,20 @@ var _ = Describe("Podman volume plugins", func() { pluginName := "testvol4" plugin := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath}) plugin.WaitWithDefaultTimeout() - Expect(plugin.ExitCode()).To(Equal(0)) + Expect(plugin).Should(Exit(0)) volName := "testVolume1" create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName}) create.WaitWithDefaultTimeout() - Expect(create.ExitCode()).To(Equal(0)) + Expect(create).Should(Exit(0)) ctr1 := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", fmt.Sprintf("%v:/test", volName), ALPINE, "sh", "-c", "touch /test/testfile && echo helloworld > /test/testfile"}) ctr1.WaitWithDefaultTimeout() - Expect(ctr1.ExitCode()).To(Equal(0)) + Expect(ctr1).Should(Exit(0)) ctr2 := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", fmt.Sprintf("%v:/test", volName), ALPINE, "cat", "/test/testfile"}) ctr2.WaitWithDefaultTimeout() - Expect(ctr2.ExitCode()).To(Equal(0)) + Expect(ctr2).Should(Exit(0)) Expect(ctr2.OutputToString()).To(ContainSubstring("helloworld")) // HACK: `volume rm -f` is timing out trying to remove containers using the volume. @@ -179,6 +180,6 @@ var _ = Describe("Podman volume plugins", func() { // TODO: fix this when I get back rmAll := podmanTest.Podman([]string{"rm", "-af"}) rmAll.WaitWithDefaultTimeout() - Expect(rmAll.ExitCode()).To(Equal(0)) + Expect(rmAll).Should(Exit(0)) }) }) diff --git a/test/e2e/volume_prune_test.go b/test/e2e/volume_prune_test.go index 1d4e64ec7..364ca0ab7 100644 --- a/test/e2e/volume_prune_test.go +++ b/test/e2e/volume_prune_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman volume prune", func() { @@ -35,88 +36,119 @@ var _ = Describe("Podman volume prune", func() { It("podman prune volume", func() { session := podmanTest.Podman([]string{"volume", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "-v", "myvol:/myvol", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(4)) session = podmanTest.Podman([]string{"volume", "prune", "--force"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(2)) podmanTest.Cleanup() }) + It("podman prune volume --filter until", func() { + session := podmanTest.Podman([]string{"volume", "create", "--label", "label1=value1", "myvol1"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"volume", "ls"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(2)) + + session = podmanTest.Podman([]string{"volume", "prune", "--force", "--filter", "until=50"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"volume", "ls"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(2)) + + session = podmanTest.Podman([]string{"volume", "prune", "--force", "--filter", "until=5000000000"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"volume", "ls"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(0)) + + podmanTest.Cleanup() + }) + It("podman prune volume --filter", func() { session := podmanTest.Podman([]string{"volume", "create", "--label", "label1=value1", "myvol1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create", "--label", "sharedlabel1=slv1", "myvol2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create", "--label", "sharedlabel1=slv2", "myvol3"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create", "--label", "sharedlabel1", "myvol4"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "-v", "myvol5:/myvol5", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "-v", "myvol6:/myvol6", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(7)) session = podmanTest.Podman([]string{"volume", "prune", "--force", "--filter", "label=label1=value1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(6)) session = podmanTest.Podman([]string{"volume", "prune", "--force", "--filter", "label=sharedlabel1=slv1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(5)) session = podmanTest.Podman([]string{"volume", "prune", "--force", "--filter", "label=sharedlabel1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(3)) podmanTest.Cleanup() @@ -125,28 +157,28 @@ var _ = Describe("Podman volume prune", func() { It("podman system prune --volume", func() { session := podmanTest.Podman([]string{"volume", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"create", "-v", "myvol:/myvol", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(4)) session = podmanTest.Podman([]string{"system", "prune", "--force", "--volumes"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(0)) podmanTest.Cleanup() diff --git a/test/e2e/volume_rm_test.go b/test/e2e/volume_rm_test.go index 883a503c4..b979444bc 100644 --- a/test/e2e/volume_rm_test.go +++ b/test/e2e/volume_rm_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman volume rm", func() { @@ -35,15 +36,15 @@ var _ = Describe("Podman volume rm", func() { It("podman volume rm", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "rm", "myvol"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(0)) }) @@ -51,20 +52,20 @@ var _ = Describe("Podman volume rm", func() { session := podmanTest.Podman([]string{"create", "-v", "myvol:/myvol", ALPINE, "ls"}) cid := session.OutputToString() session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "rm", "myvol"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(2)) + Expect(session).Should(Exit(2)) Expect(session.ErrorToString()).To(ContainSubstring(cid)) session = podmanTest.Podman([]string{"volume", "rm", "-f", "myvol"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(0)) podmanTest.Cleanup() @@ -73,51 +74,51 @@ var _ = Describe("Podman volume rm", func() { It("podman volume remove bogus", func() { session := podmanTest.Podman([]string{"volume", "rm", "bogus"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(1)) + Expect(session).Should(Exit(1)) }) It("podman rm with --all flag", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "rm", "-a"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(0)) }) It("podman volume rm by partial name", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "rm", "myv"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(0)) }) It("podman volume rm by nonunique partial name", func() { session := podmanTest.Podman([]string{"volume", "create", "myvol1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "create", "myvol2"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"volume", "rm", "myv"}) session.WaitWithDefaultTimeout() @@ -125,7 +126,7 @@ var _ = Describe("Podman volume rm", func() { session = podmanTest.Podman([]string{"volume", "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray()) >= 2).To(BeTrue()) }) }) diff --git a/test/e2e/wait_test.go b/test/e2e/wait_test.go index 71df28ca8..96bc8dbde 100644 --- a/test/e2e/wait_test.go +++ b/test/e2e/wait_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman wait", func() { @@ -35,7 +36,7 @@ var _ = Describe("Podman wait", func() { It("podman wait on bogus container", func() { session := podmanTest.Podman([]string{"wait", "1234"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) @@ -43,91 +44,91 @@ var _ = Describe("Podman wait", func() { session := podmanTest.Podman([]string{"run", "-d", ALPINE, "ls"}) session.Wait(10) cid := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"wait", cid}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman wait on a sleeping container", func() { session := podmanTest.Podman([]string{"run", "-d", ALPINE, "sleep", "1"}) session.Wait(20) cid := session.OutputToString() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"wait", cid}) session.Wait(20) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman wait on latest container", func() { session := podmanTest.Podman([]string{"run", "-d", ALPINE, "sleep", "1"}) session.Wait(20) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if IsRemote() { session = podmanTest.Podman([]string{"wait", session.OutputToString()}) } else { session = podmanTest.Podman([]string{"wait", "-l"}) } session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman container wait on latest container", func() { session := podmanTest.Podman([]string{"container", "run", "-d", ALPINE, "sleep", "1"}) session.Wait(20) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) if IsRemote() { session = podmanTest.Podman([]string{"container", "wait", session.OutputToString()}) } else { session = podmanTest.Podman([]string{"container", "wait", "-l"}) } session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman container wait on latest container with --interval flag", func() { session := podmanTest.Podman([]string{"container", "run", "-d", ALPINE, "sleep", "1"}) session.Wait(20) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"container", "wait", "-i", "5000", session.OutputToString()}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman container wait on latest container with --interval flag", func() { session := podmanTest.Podman([]string{"container", "run", "-d", ALPINE, "sleep", "1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"container", "wait", "--interval", "1s", session.OutputToString()}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) }) It("podman container wait on container with bogus --interval", func() { session := podmanTest.Podman([]string{"container", "run", "-d", ALPINE, "sleep", "1"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"container", "wait", "--interval", "100days", session.OutputToString()}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) It("podman wait on three containers", func() { session := podmanTest.Podman([]string{"run", "-d", ALPINE, "sleep", "1"}) session.Wait(20) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid1 := session.OutputToString() session = podmanTest.Podman([]string{"run", "-d", ALPINE, "sleep", "1"}) session.Wait(20) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid2 := session.OutputToString() session = podmanTest.Podman([]string{"run", "-d", ALPINE, "sleep", "1"}) session.Wait(20) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) cid3 := session.OutputToString() session = podmanTest.Podman([]string{"wait", cid1, cid2, cid3}) session.Wait(20) - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) Expect(session.OutputToStringArray()).To(Equal([]string{"0", "0", "0"})) }) }) diff --git a/test/python/docker/__init__.py b/test/python/docker/__init__.py index 59b7987f4..f75185192 100644 --- a/test/python/docker/__init__.py +++ b/test/python/docker/__init__.py @@ -27,7 +27,7 @@ class Podman(object): # No support for tmpfs (/tmp) or extfs (/var/tmp) # self.cmd.append("--storage-driver=overlay") - if os.getenv("DEBUG"): + if os.getenv("PODMAN_PYTHON_TEST_DEBUG"): self.cmd.append("--log-level=debug") self.cmd.append("--syslog=true") diff --git a/test/python/docker/compat/test_containers.py b/test/python/docker/compat/test_containers.py index 511ab1451..1ad1e7f15 100644 --- a/test/python/docker/compat/test_containers.py +++ b/test/python/docker/compat/test_containers.py @@ -7,6 +7,7 @@ from typing import IO, Optional from docker import DockerClient, errors from docker.models.containers import Container +from docker.models.images import Image from test.python.docker import Podman from test.python.docker.compat import common, constant @@ -139,7 +140,7 @@ class TestContainers(unittest.TestCase): def test_remove_container_without_force(self): # Validate current container count - self.assertTrue(len(self.client.containers.list()), 1) + self.assertEqual(len(self.client.containers.list()), 1) # Remove running container should throw error top = self.client.containers.get(TestContainers.topContainerId) @@ -228,12 +229,25 @@ class TestContainers(unittest.TestCase): ret, out = ctr.exec_run(["stat", "-c", "%u:%g", "/tmp/a.txt"]) self.assertEqual(ret, 0) - self.assertTrue(out.startswith(b'1042:1043'), "assert correct uid/gid") + self.assertEqual(out.rstrip(), b'1042:1043', "UID/GID of copied file") ret, out = ctr.exec_run(["cat", "/tmp/a.txt"]) self.assertEqual(ret, 0) - self.assertTrue(out.startswith(test_file_content), "assert file content") + self.assertEqual(out.rstrip(), test_file_content, "Content of copied file") finally: if ctr is not None: ctr.stop() ctr.remove() + + def test_mount_preexisting_dir(self): + dockerfile = (B'FROM quay.io/libpod/alpine:latest\n' + B'USER root\n' + B'RUN mkdir -p /workspace\n' + B'RUN chown 1042:1043 /workspace') + img: Image + img, out = self.client.images.build(fileobj=io.BytesIO(dockerfile)) + ctr: Container = self.client.containers.create(image=img.id, detach=True, command="top", + volumes=["test_mount_preexisting_dir_vol:/workspace"]) + ctr.start() + ret, out = ctr.exec_run(["stat", "-c", "%u:%g", "/workspace"]) + self.assertEqual(out.rstrip(), b'1042:1043', "UID/GID set in dockerfile") diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 32fc85c4e..3d9d834b3 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -706,4 +706,21 @@ EOF run_podman rmi nomtab } +@test "podman run --device-cgroup-rule tests" { + skip_if_rootless "cannot add devices in rootless mode" + + run_podman run --device-cgroup-rule="b 7:* rmw" --rm $IMAGE + run_podman run --device-cgroup-rule="c 7:* rmw" --rm $IMAGE + run_podman run --device-cgroup-rule="a 7:1 rmw" --rm $IMAGE + run_podman run --device-cgroup-rule="a 7 rmw" --rm $IMAGE + run_podman 125 run --device-cgroup-rule="b 7:* rmX" --rm $IMAGE + is "$output" "Error: invalid device access in device-access-add: X" + run_podman 125 run --device-cgroup-rule="b 7:2" --rm $IMAGE + is "$output" 'Error: invalid device cgroup rule requires type, major:Minor, and access rules: "b 7:2"' + run_podman 125 run --device-cgroup-rule="x 7:* rmw" --rm $IMAGE + is "$output" "Error: invalid device type in device-access-add:" + run_podman 125 run --device-cgroup-rule="a a:* rmw" --rm $IMAGE + is "$output" "Error: strconv.ParseInt: parsing \"a\": invalid syntax" +} + # vim: filetype=sh diff --git a/test/system/035-logs.bats b/test/system/035-logs.bats index ccf83df14..32282c8e1 100644 --- a/test/system/035-logs.bats +++ b/test/system/035-logs.bats @@ -24,6 +24,9 @@ load helpers # test --since with Unix timestamps run_podman logs --since 1000 $cid + # test --until with Unix timestamps + run_podman logs --until 1000 $cid + run_podman rm $cid } @@ -125,4 +128,50 @@ $s_after" _log_test_since journald } +function _log_test_until() { + local driver=$1 + + s_before="before_$(random_string)_${driver}" + s_after="after_$(random_string)_${driver}" + + before=$(date --iso-8601=seconds) + sleep 5 + run_podman run --log-driver=$driver -d --name test $IMAGE sh -c \ + "echo $s_before; trap 'echo $s_after; exit' SIGTERM; while :; do sleep 1; done" + + # sleep a second to make sure the date is after the first echo + sleep 1 + run_podman stop test + # sleep for 20 seconds to get the proper after time + sleep 20 + + run_podman logs test + is "$output" \ + "$s_before +$s_after" + + run_podman logs --until $before test + is "$output" \ + "" + + after=$(date --iso-8601=seconds) + + run_podman logs --until $after test + is "$output" \ + "$s_before +$s_after" + run_podman rm -f test +} + +@test "podman logs - until k8s-file" { + _log_test_until k8s-file +} + +@test "podman logs - until journald" { + # We can't use journald on RHEL as rootless: rhbz#1895105 + skip_if_journald_unavailable + + _log_test_until journald +} + # vim: filetype=sh diff --git a/test/system/065-cp.bats b/test/system/065-cp.bats index 5778eb46e..39f439e7b 100644 --- a/test/system/065-cp.bats +++ b/test/system/065-cp.bats @@ -22,8 +22,7 @@ load helpers mkdir -p $srcdir/subdir echo "${randomcontent[2]}" > $srcdir/subdir/dotfile. - run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity - run_podman exec cpcontainer mkdir /srv/subdir + run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sh -c "mkdir /srv/subdir; sleep infinity" # Commit the image for testing non-running containers run_podman commit -q cpcontainer @@ -41,7 +40,6 @@ load helpers 0 | /tmp | /tmp/hostfile0 | copy to /tmp 1 | /tmp/ | /tmp/hostfile1 | copy to /tmp/ 2 | /tmp/. | /tmp/hostfile2 | copy to /tmp/. -0 | /tmp/hostfile2 | /tmp/hostfile2 | overwrite previous copy 0 | /tmp/anotherbase.txt | /tmp/anotherbase.txt | copy to /tmp, new name 0 | . | /srv/hostfile0 | copy to workdir (rel path), new name 1 | ./ | /srv/hostfile1 | copy to workdir (rel path), new name @@ -175,11 +173,12 @@ load helpers random-1-$(random_string 15) random-2-$(random_string 20) ) - run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity - run_podman exec cpcontainer sh -c "echo ${randomcontent[0]} > /tmp/containerfile" - run_podman exec cpcontainer sh -c "echo ${randomcontent[0]} > /tmp/dotfile." - run_podman exec cpcontainer sh -c "echo ${randomcontent[1]} > /srv/containerfile1" - run_podman exec cpcontainer sh -c "mkdir /srv/subdir; echo ${randomcontent[2]} > /srv/subdir/containerfile2" + run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sh -c "mkdir /srv/subdir; + echo ${randomcontent[0]} > /tmp/containerfile; + echo ${randomcontent[0]} > /tmp/dotfile.; + echo ${randomcontent[1]} > /srv/containerfile1; + echo ${randomcontent[2]} > /srv/subdir/containerfile2; + sleep infinity" # Commit the image for testing non-running containers run_podman commit -q cpcontainer @@ -226,6 +225,98 @@ load helpers } +@test "podman cp file from container to container" { + # Create 3 files with random content in the container. + local -a randomcontent=( + random-0-$(random_string 10) + random-1-$(random_string 15) + random-2-$(random_string 20) + ) + + run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sh -c "mkdir /srv/subdir; + echo ${randomcontent[0]} > /tmp/containerfile; + echo ${randomcontent[0]} > /tmp/dotfile.; + echo ${randomcontent[1]} > /srv/containerfile1; + echo ${randomcontent[2]} > /srv/subdir/containerfile2; + sleep infinity" + + # Commit the image for testing non-running containers + run_podman commit -q cpcontainer + cpimage="$output" + + # format is: <id> | <source arg to cp> | <destination arg (appended to $srcdir) to cp> | <full dest path (appended to $srcdir)> | <test name> + tests=" +0 | /tmp/containerfile | | /containerfile | / +0 | /tmp/dotfile. | | /dotfile. | / +0 | /tmp/containerfile | / | /containerfile | / +0 | /tmp/containerfile | /. | /containerfile | /. +0 | /tmp/containerfile | /newfile | /newfile | /newfile +1 | containerfile1 | / | /containerfile1 | copy from workdir (rel path) to / +2 | subdir/containerfile2 | / | /containerfile2 | copy from workdir/subdir (rel path) to / +" + + # From RUNNING container + while read id src dest dest_fullname description; do + # dest may be "''" for empty table cells + if [[ $dest == "''" ]];then + unset dest + fi + + # To RUNNING container + run_podman run -d $IMAGE sleep infinity + destcontainer="$output" + run_podman cp cpcontainer:$src $destcontainer:"/$dest" + run_podman exec $destcontainer cat "/$dest_fullname" + is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to /$dest)" + run_podman kill $destcontainer + run_podman rm -f $destcontainer + + # To CREATED container + run_podman create $IMAGE sleep infinity + destcontainer="$output" + run_podman cp cpcontainer:$src $destcontainer:"/$dest" + run_podman start $destcontainer + run_podman exec $destcontainer cat "/$dest_fullname" + is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to /$dest)" + run_podman kill $destcontainer + run_podman rm -f $destcontainer + done < <(parse_table "$tests") + run_podman kill cpcontainer + run_podman rm -f cpcontainer + + # From CREATED container + run_podman create --name cpcontainer --workdir=/srv $cpimage + while read id src dest dest_fullname description; do + # dest may be "''" for empty table cells + if [[ $dest == "''" ]];then + unset dest + fi + + # To RUNNING container + run_podman run -d $IMAGE sleep infinity + destcontainer="$output" + run_podman cp cpcontainer:$src $destcontainer:"/$dest" + run_podman exec $destcontainer cat "/$dest_fullname" + is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to /$dest)" + run_podman kill $destcontainer + run_podman rm -f $destcontainer + + # To CREATED container + run_podman create $IMAGE sleep infinity + destcontainer="$output" + run_podman cp cpcontainer:$src $destcontainer:"/$dest" + run_podman start $destcontainer + run_podman exec $destcontainer cat "/$dest_fullname" + is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to /$dest)" + run_podman kill $destcontainer + run_podman rm -f $destcontainer + done < <(parse_table "$tests") + run_podman rm -f cpcontainer + + run_podman rmi -f $cpimage +} + + @test "podman cp dir from host to container" { srcdir=$PODMAN_TMPDIR mkdir -p $srcdir/dir/sub @@ -241,8 +332,7 @@ load helpers mkdir -p $srcdir/dir. cp -r $srcdir/dir/* $srcdir/dir. - run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity - run_podman exec cpcontainer mkdir /srv/subdir + run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sh -c "mkdir /srv/subdir; sleep infinity" # Commit the image for testing non-running containers run_podman commit -q cpcontainer @@ -309,12 +399,12 @@ load helpers random-0-$(random_string 10) random-1-$(random_string 15) ) - run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity - run_podman exec cpcontainer sh -c "mkdir /srv/subdir; echo ${randomcontent[0]} > /srv/subdir/containerfile0" - run_podman exec cpcontainer sh -c "echo ${randomcontent[1]} > /srv/subdir/containerfile1" - # "." and "dir/." will copy the contents, so make sure that a dir ending - # with dot is treated correctly. - run_podman exec cpcontainer sh -c 'mkdir /tmp/subdir.; cp /srv/subdir/* /tmp/subdir./' + + run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sh -c "mkdir /srv/subdir; + echo ${randomcontent[0]} > /srv/subdir/containerfile0; \ + echo ${randomcontent[1]} > /srv/subdir/containerfile1; \ + mkdir /tmp/subdir.; cp /srv/subdir/* /tmp/subdir./; \ + sleep infinity" # Commit the image for testing non-running containers run_podman commit -q cpcontainer @@ -377,6 +467,110 @@ load helpers } +@test "podman cp dir from container to container" { + # Create 2 files with random content in the container. + local -a randomcontent=( + random-0-$(random_string 10) + random-1-$(random_string 15) + ) + + run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sh -c "mkdir /srv/subdir; + echo ${randomcontent[0]} > /srv/subdir/containerfile0; \ + echo ${randomcontent[1]} > /srv/subdir/containerfile1; \ + mkdir /tmp/subdir.; cp /srv/subdir/* /tmp/subdir./; \ + sleep infinity" + + # Commit the image for testing non-running containers + run_podman commit -q cpcontainer + cpimage="$output" + + # format is: <source arg to cp (appended to /srv)> | <dest> | <full dest path> | <test name> + tests=" +/srv | | /srv/subdir | copy /srv +/srv | /newdir | /newdir/subdir | copy /srv to /newdir +/srv/ | | /srv/subdir | copy /srv/ +/srv/. | | /subdir | copy /srv/. +/srv/. | /newdir | /newdir/subdir | copy /srv/. to /newdir +/srv/subdir/. | | | copy /srv/subdir/. +/tmp/subdir. | | /subdir. | copy /tmp/subdir. +" + + # From RUNNING container + while read src dest dest_fullname description; do + if [[ $src == "''" ]];then + unset src + fi + if [[ $dest == "''" ]];then + unset dest + fi + if [[ $dest_fullname == "''" ]];then + unset dest_fullname + fi + + # To RUNNING container + run_podman run -d $IMAGE sleep infinity + destcontainer="$output" + run_podman cp cpcontainer:$src $destcontainer:"/$dest" + run_podman exec $destcontainer cat "/$dest_fullname/containerfile0" "/$dest_fullname/containerfile1" + is "$output" "${randomcontent[0]} +${randomcontent[1]}" "$description" + run_podman kill $destcontainer + run_podman rm -f $destcontainer + + # To CREATED container + run_podman create $IMAGE sleep infinity + destcontainer="$output" + run_podman cp cpcontainer:$src $destcontainer:"/$dest" + run_podman start $destcontainer + run_podman exec $destcontainer cat "/$dest_fullname/containerfile0" "/$dest_fullname/containerfile1" + is "$output" "${randomcontent[0]} +${randomcontent[1]}" "$description" + run_podman kill $destcontainer + run_podman rm -f $destcontainer + done < <(parse_table "$tests") + run_podman kill cpcontainer + run_podman rm -f cpcontainer + + # From CREATED container + run_podman create --name cpcontainer --workdir=/srv $cpimage + while read src dest dest_fullname description; do + if [[ $src == "''" ]];then + unset src + fi + if [[ $dest == "''" ]];then + unset dest + fi + if [[ $dest_fullname == "''" ]];then + unset dest_fullname + fi + + # To RUNNING container + run_podman run -d $IMAGE sleep infinity + destcontainer="$output" + run_podman cp cpcontainer:$src $destcontainer:"/$dest" + run_podman exec $destcontainer cat "/$dest_fullname/containerfile0" "/$dest_fullname/containerfile1" + is "$output" "${randomcontent[0]} +${randomcontent[1]}" "$description" + run_podman kill $destcontainer + run_podman rm -f $destcontainer + + # To CREATED container + run_podman create $IMAGE sleep infinity + destcontainer="$output" + run_podman start $destcontainer + run_podman cp cpcontainer:$src $destcontainer:"/$dest" + run_podman exec $destcontainer cat "/$dest_fullname/containerfile0" "/$dest_fullname/containerfile1" + is "$output" "${randomcontent[0]} +${randomcontent[1]}" "$description" + run_podman kill $destcontainer + run_podman rm -f $destcontainer + done < <(parse_table "$tests") + + run_podman rm -f cpcontainer + run_podman rmi -f $cpimage +} + + @test "podman cp symlinked directory from container" { destdir=$PODMAN_TMPDIR/cp-weird-symlink mkdir -p $destdir @@ -387,10 +581,10 @@ load helpers random-1-$(random_string 15) ) - run_podman run -d --name cpcontainer $IMAGE sleep infinity - run_podman exec cpcontainer sh -c "echo ${randomcontent[0]} > /tmp/containerfile0" - run_podman exec cpcontainer sh -c "echo ${randomcontent[1]} > /tmp/containerfile1" - run_podman exec cpcontainer sh -c "mkdir /tmp/sub && cd /tmp/sub && ln -s .. weirdlink" + run_podman run -d --name cpcontainer $IMAGE sh -c "echo ${randomcontent[0]} > /tmp/containerfile0; \ + echo ${randomcontent[1]} > /tmp/containerfile1; \ + mkdir /tmp/sub && cd /tmp/sub && ln -s .. weirdlink; \ + sleep infinity" # Commit the image for testing non-running containers run_podman commit -q cpcontainer diff --git a/test/system/070-build.bats b/test/system/070-build.bats index c45a661fe..26113e45c 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -509,6 +509,40 @@ EOF done } +# Regression test for #9867 +# Make sure that if you exclude everything in context dir, that +# the Containerfile/Dockerfile in the context dir are used +@test "podman build with ignore '*'" { + local tmpdir=$PODMAN_TMPDIR/build-test-$(random_string 10) + mkdir -p $tmpdir + + cat >$tmpdir/Containerfile <<EOF +FROM scratch +EOF + +cat >$tmpdir/.dockerignore <<EOF +* +EOF + + run_podman build -t build_test $tmpdir + + # Rename Containerfile to Dockerfile + mv $tmpdir/Containerfile $tmpdir/Dockerfile + + run_podman build -t build_test $tmpdir + + # Rename Dockerfile to foofile + mv $tmpdir/Dockerfile $tmpdir/foofile + + run_podman 125 build -t build_test $tmpdir + is "$output" ".*Dockerfile: no such file or directory" + + run_podman build -t build_test -f $tmpdir/foofile $tmpdir + + # Clean up + run_podman rmi -f build_test +} + @test "podman build - stdin test" { # Random workdir, and random string to verify build output workdir=/$(random_string 10) @@ -715,16 +749,9 @@ RUN echo $random_string EOF run_podman 125 build -t build_test --pull-never $tmpdir - # FIXME: this is just ridiculous. Even after #10030 and #10034, Ubuntu - # remote *STILL* flakes this test! It fails with the correct exit status, - # but the error output is 'Error: stream dropped, unexpected failure' - # Let's just stop checking on podman-remote. As long as it exits 125, - # we're happy. - if ! is_remote; then - is "$output" \ - ".*Error: error creating build container: quay.io/libpod/nosuchimage:nosuchtag: image not known" \ - "--pull-never fails with expected error message" - fi + is "$output" \ + ".*Error: error creating build container: quay.io/libpod/nosuchimage:nosuchtag: image not known" \ + "--pull-never fails with expected error message" } @test "podman build --logfile test" { @@ -817,7 +844,7 @@ EOF run_podman rmi -f build_test } -@test "podman build -f test " { +@test "podman build -f test" { tmpdir=$PODMAN_TMPDIR/build-test subdir=$tmpdir/subdir mkdir -p $subdir @@ -843,6 +870,44 @@ EOF run_podman rmi -f build_test } +@test "podman build .dockerignore failure test" { + tmpdir=$PODMAN_TMPDIR/build-test + subdir=$tmpdir/subdir + mkdir -p $subdir + + cat >$tmpdir/.dockerignore <<EOF +* +subdir +!*/sub1* +EOF + cat >$tmpdir/Containerfile <<EOF +FROM $IMAGE +COPY ./ ./ +COPY subdir ./ +EOF + run_podman 125 build -t build_test $tmpdir + is "$output" ".*Error: error building at STEP \"COPY subdir ./\"" ".dockerignore was ignored" +} + +@test "podman build .containerignore and .dockerignore test" { + tmpdir=$PODMAN_TMPDIR/build-test + mkdir -p $tmpdir + touch $tmpdir/test1 $tmpdir/test2 + cat >$tmpdir/.containerignore <<EOF +test2* +EOF + cat >$tmpdir/.dockerignore <<EOF +test1* +EOF + cat >$tmpdir/Containerfile <<EOF +FROM $IMAGE +COPY ./ /tmp/test/ +RUN ls /tmp/test/ +EOF + run_podman build -t build_test $tmpdir + is "$output" ".*test1" "test1 should exists in the final image" +} + function teardown() { # A timeout or other error in 'build' can leave behind stale images # that podman can't even see and which will cascade into subsequent @@ -850,6 +915,9 @@ function teardown() { run_podman '?' rm -a -f run_podman '?' rmi -f build_test + # Many of the tests above leave interim layers behind. Clean them up. + run_podman '?' image prune -f + basic_teardown } diff --git a/test/system/075-exec.bats b/test/system/075-exec.bats index badf44c49..3e8c3c1ea 100644 --- a/test/system/075-exec.bats +++ b/test/system/075-exec.bats @@ -59,8 +59,6 @@ load helpers # Issue #4785 - piping to exec statement - fixed in #4818 # Issue #5046 - piping to exec truncates results (actually a conmon issue) @test "podman exec - cat from stdin" { - skip_if_remote "FIXME: pending #7360" - run_podman run -d $IMAGE sh -c 'while [ ! -e /stop ]; do sleep 0.1;done' cid="$output" diff --git a/test/system/090-events.bats b/test/system/090-events.bats index d889bd7f9..22edaeee9 100644 --- a/test/system/090-events.bats +++ b/test/system/090-events.bats @@ -81,6 +81,7 @@ function _events_disjunctive_filters() { @test "events with disjunctive filters - journald" { skip_if_remote "remote does not support --events-backend" + skip_if_journald_unavailable "system does not support journald events" _events_disjunctive_filters --events-backend=journald } diff --git a/test/system/120-load.bats b/test/system/120-load.bats index 67687a5b0..97ea0f528 100644 --- a/test/system/120-load.bats +++ b/test/system/120-load.bats @@ -134,8 +134,16 @@ verify_iid_and_name() { } @test "podman load - multi-image archive" { - img1="quay.io/libpod/testimage:00000000" - img2="quay.io/libpod/testimage:20200902" + # img1 & 2 should be images that are not locally present; they must also + # be usable on the host arch. The nonlocal image (:000000xx) is kept + # up-to-date for all RHEL/Fedora arches; the other image we use is + # the one tagged ':multiimage', which as of 2021-07-15 is :20210610 + # but that tag will grow stale over time. If/when this test fails, + # your first approach should be to manually update :multiimage to + # point to a more recent testimage. (Use the quay.io GUI, it's waaay + # easier than pulling/pushing the correct manifest.) + img1=${PODMAN_NONLOCAL_IMAGE_FQN} + img2="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:multiimage" archive=$PODMAN_TMPDIR/myimage-$(random_string 8).tar run_podman pull $img1 @@ -151,8 +159,9 @@ verify_iid_and_name() { } @test "podman load - multi-image archive with redirect" { - img1="quay.io/libpod/testimage:00000000" - img2="quay.io/libpod/testimage:20200902" + # (see comments in test above re: img1 & 2) + img1=${PODMAN_NONLOCAL_IMAGE_FQN} + img2="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:multiimage" archive=$PODMAN_TMPDIR/myimage-$(random_string 8).tar run_podman pull $img1 diff --git a/test/system/125-import.bats b/test/system/125-import.bats new file mode 100644 index 000000000..c53711618 --- /dev/null +++ b/test/system/125-import.bats @@ -0,0 +1,45 @@ +#!/usr/bin/env bats -*- bats -*- +# +# tests for podman import +# + +load helpers + +@test "podman import" { + local archive=$PODMAN_TMPDIR/archive.tar + local random_content=$(random_string 12) + # Generate a random name and tag (must be lower-case) + local random_name=x0$(random_string 12 | tr A-Z a-z) + local random_tag=t0$(random_string 7 | tr A-Z a-z) + local fqin=localhost/$random_name:$random_tag + + run_podman run --name import $IMAGE sh -c "echo ${random_content} > /random.txt" + run_podman export import -o $archive + run_podman rm -f import + + # Simple import + run_podman import -q $archive + iid="$output" + run_podman run -t --rm $iid cat /random.txt + is "$output" "$random_content" "simple import" + run_podman rmi -f $iid + + # Simple import via stdin + run_podman import -q - < <(cat $archive) + iid="$output" + run_podman run -t --rm $iid cat /random.txt + is "$output" "$random_content" "simple import via stdin" + run_podman rmi -f $iid + + # Tagged import + run_podman import -q $archive $fqin + run_podman run -t --rm $fqin cat /random.txt + is "$output" "$random_content" "tagged import" + run_podman rmi -f $fqin + + # Tagged import via stdin + run_podman import -q - $fqin < <(cat $archive) + run_podman run -t --rm $fqin cat /random.txt + is "$output" "$random_content" "tagged import via stdin" + run_podman rmi -f $fqin +} diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats index 054eda908..266f91298 100644 --- a/test/system/200-pod.bats +++ b/test/system/200-pod.bats @@ -205,6 +205,7 @@ function random_ip() { # entrypoint to confirm that --infra-command will override. local infra_image="infra_$(random_string 10 | tr A-Z a-z)" local infra_command="/pause_$(random_string 10)" + local infra_name="infra_container_$(random_string 10 | tr A-Z a-z)" run_podman build -t $infra_image - << EOF FROM $IMAGE RUN ln /home/podman/pause $infra_command @@ -225,7 +226,8 @@ EOF --publish "$port_out:$port_in" \ --label "${labelname}=${labelvalue}" \ --infra-image "$infra_image" \ - --infra-command "$infra_command" + --infra-command "$infra_command" \ + --infra-name "$infra_name" pod_id="$output" # Check --pod-id-file @@ -237,6 +239,9 @@ EOF # confirm that entrypoint is what we set run_podman container inspect --format '{{.Config.Entrypoint}}' $infra_cid is "$output" "$infra_command" "infra-command took effect" + # confirm that infra container name is set + run_podman container inspect --format '{{.Name}}' $infra_cid + is "$output" "$infra_name" "infra-name took effect" # Check each of the options if [ -n "$mac_option" ]; then @@ -310,6 +315,16 @@ EOF run_podman rm $cid run_podman pod rm -f mypod run_podman rmi $infra_image + +} + +@test "podman pod create should fail when infra-name is already in use" { + local infra_name="infra_container_$(random_string 10 | tr A-Z a-z)" + run_podman pod create --infra-name "$infra_name" + run_podman '?' pod create --infra-name "$infra_name" + if [ $status -eq 0 ]; then + die "Podman should fail when user try to create two pods with the same infra-name value" + fi } # vim: filetype=sh diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats index 4ea192009..ee951ff21 100644 --- a/test/system/250-systemd.bats +++ b/test/system/250-systemd.bats @@ -4,17 +4,10 @@ # load helpers +load helpers.systemd SERVICE_NAME="podman_test_$(random_string)" -SYSTEMCTL="systemctl" -UNIT_DIR="/usr/lib/systemd/system" -if is_rootless; then - UNIT_DIR="$HOME/.config/systemd/user" - mkdir -p $UNIT_DIR - - SYSTEMCTL="$SYSTEMCTL --user" -fi UNIT_FILE="$UNIT_DIR/$SERVICE_NAME.service" function setup() { @@ -24,38 +17,28 @@ function setup() { } function teardown() { - run '?' $SYSTEMCTL stop "$SERVICE_NAME" + run '?' systemctl stop "$SERVICE_NAME" rm -f "$UNIT_FILE" - $SYSTEMCTL daemon-reload + systemctl daemon-reload run_podman rmi -a basic_teardown } -# Helper to setup xdg runtime for rootless -function xdg_rootless() { - # podman initializes this if unset, but systemctl doesn't - if is_rootless; then - if [ -z "$XDG_RUNTIME_DIR" ]; then - export XDG_RUNTIME_DIR=/run/user/$(id -u) - fi - fi -} - # Helper to start a systemd service running a container function service_setup() { run_podman generate systemd --new $cname echo "$output" > "$UNIT_FILE" run_podman rm $cname - $SYSTEMCTL daemon-reload + systemctl daemon-reload - run $SYSTEMCTL start "$SERVICE_NAME" + run systemctl start "$SERVICE_NAME" if [ $status -ne 0 ]; then die "Error starting systemd unit $SERVICE_NAME, output: $output" fi - run $SYSTEMCTL status "$SERVICE_NAME" + run systemctl status "$SERVICE_NAME" if [ $status -ne 0 ]; then die "Non-zero status of systemd unit $SERVICE_NAME, output: $output" fi @@ -63,20 +46,18 @@ function service_setup() { # Helper to stop a systemd service running a container function service_cleanup() { - run $SYSTEMCTL stop "$SERVICE_NAME" + run systemctl stop "$SERVICE_NAME" if [ $status -ne 0 ]; then die "Error stopping systemd unit $SERVICE_NAME, output: $output" fi rm -f "$UNIT_FILE" - $SYSTEMCTL daemon-reload + systemctl daemon-reload } # These tests can fail in dev. environment because of SELinux. # quick fix: chcon -t container_runtime_exec_t ./bin/podman @test "podman generate - systemd - basic" { - xdg_rootless - cname=$(random_string) # See #7407 for --pull=always. run_podman create --pull=always --name $cname --label "io.containers.autoupdate=registry" $IMAGE top @@ -100,8 +81,6 @@ function service_cleanup() { } @test "podman autoupdate local" { - xdg_rootless - cname=$(random_string) run_podman create --name $cname --label "io.containers.autoupdate=local" $IMAGE top @@ -119,7 +98,7 @@ function service_cleanup() { # Run auto-update and check that it restarted the container run_podman commit --change "CMD=/bin/bash" $cname $IMAGE run_podman auto-update - is $output $SERVICE_NAME "autoupdate local restarted container" + is "$output" ".*$SERVICE_NAME.*" "autoupdate local restarted container" # All good. Stop service, clean up. service_cleanup @@ -128,8 +107,6 @@ function service_cleanup() { # These tests can fail in dev. environment because of SELinux. # quick fix: chcon -t container_runtime_exec_t ./bin/podman @test "podman generate systemd - envar" { - xdg_rootless - cname=$(random_string) FOO=value BAR=%s run_podman create --name $cname --env FOO -e BAR --env MYVAR=myval \ $IMAGE sh -c 'printenv && sleep 100' diff --git a/test/system/255-auto-update.bats b/test/system/255-auto-update.bats index 3713243d5..25eaba45b 100644 --- a/test/system/255-auto-update.bats +++ b/test/system/255-auto-update.bats @@ -4,14 +4,12 @@ # load helpers +load helpers.systemd -UNIT_DIR="/usr/lib/systemd/system" SNAME_FILE=$BATS_TMPDIR/services function setup() { skip_if_remote "systemd tests are meaningless over remote" - skip_if_rootless - basic_setup } @@ -29,7 +27,7 @@ function teardown() { rm -f $SNAME_FILE run_podman ? rmi quay.io/libpod/alpine:latest - run_podman ? rmi quay.io/libpod/alpine_nginx:latest + run_podman ? rmi quay.io/libpod/busybox:latest run_podman ? rmi quay.io/libpod/localtest:latest basic_teardown } @@ -58,8 +56,7 @@ function generate_service() { fi run_podman run -d --name $cname $label $target_img top -d 120 - run_podman generate systemd --new $cname - echo "$output" > "$UNIT_DIR/container-$cname.service" + (cd $UNIT_DIR; run_podman generate systemd --new --files --name $cname) echo "container-$cname" >> $SNAME_FILE run_podman rm -f $cname @@ -121,8 +118,13 @@ function _confirm_update() { generate_service alpine image _wait_service_ready container-$cname.service - run_podman auto-update + run_podman auto-update --dry-run --format "{{.Unit}},{{.Image}},{{.Updated}},{{.Policy}}" + is "$output" ".*container-$cname.service,quay.io/libpod/alpine:latest,pending,registry.*" "Image update is pending." + + run_podman auto-update --format "{{.Unit}},{{.Image}},{{.Updated}},{{.Policy}}" is "$output" "Trying to pull.*" "Image is updated." + is "$output" ".*container-$cname.service,quay.io/libpod/alpine:latest,true,registry.*" "Image is updated." + _confirm_update $cname $ori_image } @@ -151,10 +153,18 @@ function _confirm_update() { @test "podman auto-update - label io.containers.autoupdate=local" { generate_service localtest local - podman commit --change CMD=/bin/bash $cname quay.io/libpod/localtest:latest + image=quay.io/libpod/localtest:latest + podman commit --change CMD=/bin/bash $cname $image + podman image inspect --format "{{.ID}}" $image + imageID="$output" _wait_service_ready container-$cname.service - run_podman auto-update + run_podman auto-update --dry-run --format "{{.Unit}},{{.Image}},{{.Updated}},{{.Policy}}" + is "$output" ".*container-$cname.service,quay.io/libpod/localtest:latest,pending,local.*" "Image update is pending." + + run_podman auto-update --format "{{.Unit}},{{.Image}},{{.Updated}},{{.Policy}}" + is "$output" ".*container-$cname.service,quay.io/libpod/localtest:latest,true,local.*" "Image is updated." + _confirm_update $cname $ori_image } @@ -172,7 +182,7 @@ function _confirm_update() { do local img_base="alpine" if [[ $auto_update == "registry" ]]; then - img_base="alpine_nginx" + img_base="busybox" elif [[ $auto_update == "local" ]]; then img_base="localtest" fi @@ -236,7 +246,7 @@ EOF [Unit] Description=Podman auto-update testing service Documentation=man:podman-auto-update(1) -Wants=network.target +Wants=network-online.target After=network-online.target [Service] diff --git a/test/system/270-socket-activation.bats b/test/system/270-socket-activation.bats index 25206c6a7..031ba161b 100644 --- a/test/system/270-socket-activation.bats +++ b/test/system/270-socket-activation.bats @@ -4,21 +4,12 @@ # load helpers +load helpers.systemd SERVICE_NAME="podman_test_$(random_string)" -SYSTEMCTL="systemctl" -UNIT_DIR="/usr/lib/systemd/system" SERVICE_SOCK_ADDR="/run/podman/podman.sock" - if is_rootless; then - UNIT_DIR="$HOME/.config/systemd/user" - mkdir -p $UNIT_DIR - - SYSTEMCTL="$SYSTEMCTL --user" - if [ -z "$XDG_RUNTIME_DIR" ]; then - export XDG_RUNTIME_DIR=/run/user/$(id -u) - fi SERVICE_SOCK_ADDR="$XDG_RUNTIME_DIR/podman/podman.sock" fi @@ -66,13 +57,13 @@ EOF rm -f $pause_pid fi fi - $SYSTEMCTL start "$SERVICE_NAME.socket" + systemctl start "$SERVICE_NAME.socket" } function teardown() { - $SYSTEMCTL stop "$SERVICE_NAME.socket" + systemctl stop "$SERVICE_NAME.socket" rm -f "$SERVICE_FILE" "$SOCKET_FILE" - $SYSTEMCTL daemon-reload + systemctl daemon-reload basic_teardown } diff --git a/test/system/271-tcp-cors-server.bats b/test/system/271-tcp-cors-server.bats new file mode 100644 index 000000000..cdfa82e82 --- /dev/null +++ b/test/system/271-tcp-cors-server.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats -*- bats -*- +# +# Tests podman system service CORS enabled +# + +load helpers + +SERVICE_NAME="podman_test_$(random_string)" + +SERVICE_TCP_HOST="localhost" + +SERVICE_FILE="$UNIT_DIR/$SERVICE_NAME.service" +SOCKET_FILE="$UNIT_DIR/$SERVICE_NAME.socket" + +@test "podman system service - tcp CORS" { + skip_if_remote "system service tests are meaningless over remote" + PORT=$(( ((RANDOM<<15)|RANDOM) % 63001 + 2000 )) + run_podman system service --cors="*" tcp:$SERVICE_TCP_HOST:$PORT -t 20 & + podman_pid="$!" + sleep 5s + run curl -s --max-time 10 -vvv $SERVICE_TCP_HOST:$PORT/_ping 2>&1 + is "$output" ".*< Access-Control-Allow-Origin: \*.*" "access-control-allow-origin verifies CORS is set" + kill $podman_pid + wait $podman_pid || true +} + +@test "podman system service - tcp without CORS" { + skip_if_remote "system service tests are meaningless over remote" + PORT=$(( ((RANDOM<<15)|RANDOM) % 63001 + 2000 )) + run_podman system service tcp:$SERVICE_TCP_HOST:$PORT -t 20 & + podman_pid="$!" + sleep 5s + (curl -s --max-time 10 -vvv $SERVICE_TCP_HOST:$PORT/_ping 2>&1 | grep -Eq "Access-Control-Allow-Origin:") && false || true + kill $podman_pid + wait $podman_pid || true +} + +@test "podman system service - CORS enabled in logs" { + skip_if_remote "system service tests are meaningless over remote" + run_podman system service --log-level="debug" --cors="*" -t 1 + is "$output" ".*CORS Headers were set to \*.*" "debug log confirms CORS headers set" +} + +# vim: filetype=sh diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats index d55a786f7..495c7948b 100644 --- a/test/system/500-networking.bats +++ b/test/system/500-networking.bats @@ -20,7 +20,6 @@ load helpers # Copied from tsweeney's https://github.com/containers/podman/issues/4827 @test "podman networking: port on localhost" { - skip_if_remote "FIXME: reevaluate this one after #7360 is fixed" random_1=$(random_string 30) random_2=$(random_string 30) @@ -140,6 +139,8 @@ load helpers $IMAGE nc -l -n -v -p $myport cid="$output" + wait_for_output "listening on .*:$myport .*" $cid + # emit random string, and check it teststring=$(random_string 30) echo "$teststring" | nc 127.0.0.1 $myport diff --git a/test/system/helpers.bash b/test/system/helpers.bash index 1859a2168..bd9471ace 100644 --- a/test/system/helpers.bash +++ b/test/system/helpers.bash @@ -278,6 +278,24 @@ function wait_for_ready { wait_for_output 'READY' "$@" } +################### +# wait_for_port # Returns once port is available on host +################### +function wait_for_port() { + local host=$1 # Probably "localhost" + local port=$2 # Numeric port + local _timeout=${3:-5} # Optional; default to 5 seconds + + # Wait + while [ $_timeout -gt 0 ]; do + { exec 5<> /dev/tcp/$host/$port; } &>/dev/null && return + sleep 1 + _timeout=$(( $_timeout - 1 )) + done + + die "Timed out waiting for $host:$port" +} + # END podman helpers ############################################################################### # BEGIN miscellaneous tools diff --git a/test/system/helpers.systemd.bash b/test/system/helpers.systemd.bash new file mode 100644 index 000000000..4bde912a4 --- /dev/null +++ b/test/system/helpers.systemd.bash @@ -0,0 +1,30 @@ +# -*- bash -*- +# +# BATS helpers for systemd-related functionality +# + +# podman initializes this if unset, but systemctl doesn't +if [ -z "$XDG_RUNTIME_DIR" ]; then + if is_rootless; then + export XDG_RUNTIME_DIR=/run/user/$(id -u) + fi +fi + +# For tests which write systemd unit files +UNIT_DIR="/run/systemd/system" +_DASHUSER= +if is_rootless; then + UNIT_DIR="${XDG_RUNTIME_DIR}/systemd/user" + # Why isn't systemd smart enough to figure this out on its own? + _DASHUSER="--user" +fi + +mkdir -p $UNIT_DIR + +systemctl() { + command systemctl $_DASHUSER "$@" +} + +journalctl() { + command journalctl $_DASHUSER "$@" +} diff --git a/troubleshooting.md b/troubleshooting.md index 575ee16b8..24dcb8e35 100644 --- a/troubleshooting.md +++ b/troubleshooting.md @@ -356,7 +356,7 @@ If you do mount in the host's `/var/lib/containers/storage`, however, you must a Not doing this will cause Podman in the container to detect that temporary files have been cleared, leading it to assume a system restart has taken place. This can cause Podman to reset container states and lose track of running containers. -For running containers on the host from inside a container, we also recommend the [Podman remote client](remote_client.md), which only requires a single socket to be mounted into the container. +For running containers on the host from inside a container, we also recommend the [Podman remote client](docs/tutorials/remote_client.md), which only requires a single socket to be mounted into the container. ### 14) Rootless 'podman build' fails EPERM on NFS: diff --git a/vendor/github.com/Microsoft/hcsshim/errors.go b/vendor/github.com/Microsoft/hcsshim/errors.go index 794308673..f367022e7 100644 --- a/vendor/github.com/Microsoft/hcsshim/errors.go +++ b/vendor/github.com/Microsoft/hcsshim/errors.go @@ -59,7 +59,7 @@ var ( // ErrVmcomputeOperationInvalidState is an error encountered when the compute system is not in a valid state for the requested operation ErrVmcomputeOperationInvalidState = hcs.ErrVmcomputeOperationInvalidState - // ErrProcNotFound is an error encountered when the the process cannot be found + // ErrProcNotFound is an error encountered when a procedure look up fails. ErrProcNotFound = hcs.ErrProcNotFound // ErrVmcomputeOperationAccessIsDenied is an error which can be encountered when enumerating compute systems in RS1/RS2 @@ -159,7 +159,7 @@ func (e *ProcessError) Error() string { // IsNotExist checks if an error is caused by the Container or Process not existing. // Note: Currently, ErrElementNotFound can mean that a Process has either // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist -// will currently return true when the error is ErrElementNotFound or ErrProcNotFound. +// will currently return true when the error is ErrElementNotFound. func IsNotExist(err error) bool { if _, ok := err.(EndpointNotFoundError); ok { return true @@ -192,7 +192,7 @@ func IsTimeout(err error) bool { // a Container or Process being already stopped. // Note: Currently, ErrElementNotFound can mean that a Process has either // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist -// will currently return true when the error is ErrElementNotFound or ErrProcNotFound. +// will currently return true when the error is ErrElementNotFound. func IsAlreadyStopped(err error) bool { return hcs.IsAlreadyStopped(getInnerError(err)) } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go index 7696e4b48..644f0ab71 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go @@ -60,7 +60,7 @@ var ( // ErrVmcomputeOperationInvalidState is an error encountered when the compute system is not in a valid state for the requested operation ErrVmcomputeOperationInvalidState = syscall.Errno(0xc0370105) - // ErrProcNotFound is an error encountered when the the process cannot be found + // ErrProcNotFound is an error encountered when a procedure look up fails. ErrProcNotFound = syscall.Errno(0x7f) // ErrVmcomputeOperationAccessIsDenied is an error which can be encountered when enumerating compute systems in RS1/RS2 @@ -242,12 +242,11 @@ func makeProcessError(process *Process, op string, err error, events []ErrorEven // IsNotExist checks if an error is caused by the Container or Process not existing. // Note: Currently, ErrElementNotFound can mean that a Process has either // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist -// will currently return true when the error is ErrElementNotFound or ErrProcNotFound. +// will currently return true when the error is ErrElementNotFound. func IsNotExist(err error) bool { err = getInnerError(err) return err == ErrComputeSystemDoesNotExist || - err == ErrElementNotFound || - err == ErrProcNotFound + err == ErrElementNotFound } // IsAlreadyClosed checks if an error is caused by the Container or Process having been @@ -278,12 +277,11 @@ func IsTimeout(err error) bool { // a Container or Process being already stopped. // Note: Currently, ErrElementNotFound can mean that a Process has either // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist -// will currently return true when the error is ErrElementNotFound or ErrProcNotFound. +// will currently return true when the error is ErrElementNotFound. func IsAlreadyStopped(err error) bool { err = getInnerError(err) return err == ErrVmcomputeAlreadyStopped || - err == ErrElementNotFound || - err == ErrProcNotFound + err == ErrElementNotFound } // IsNotSupported returns a boolean indicating whether the error is caused by diff --git a/vendor/github.com/checkpoint-restore/go-criu/.gitignore b/vendor/github.com/checkpoint-restore/go-criu/.gitignore deleted file mode 100644 index f1c90e3d5..000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -test/test -test/piggie -test/phaul -image -rpc/rpc.proto diff --git a/vendor/github.com/checkpoint-restore/go-criu/.travis.yml b/vendor/github.com/checkpoint-restore/go-criu/.travis.yml deleted file mode 100644 index 741dbf0a1..000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ -language: go -sudo: required -os: - - linux -go: - - "1.8" - - "1.9" - - "1.10" -env: - # Run the tests with CRIU master and criu-dev - - CRIU_BRANCH="master" - - CRIU_BRANCH="criu-dev" -install: - - sudo apt-get update - - sudo apt-get install -y libprotobuf-dev libprotobuf-c0-dev protobuf-c-compiler protobuf-compiler python-protobuf libnl-3-dev libnet-dev libcap-dev - - go get github.com/checkpoint-restore/go-criu - - git clone --single-branch -b ${CRIU_BRANCH} https://github.com/checkpoint-restore/criu.git - - cd criu; make - - sudo install -D -m 755 criu/criu /usr/sbin/ - - cd .. -script: - # This builds the code without running the tests. - - make build phaul test/test test/phaul test/piggie - # Run actual test as root as it uses CRIU. - - sudo make test phaul-test diff --git a/vendor/github.com/checkpoint-restore/go-criu/Makefile b/vendor/github.com/checkpoint-restore/go-criu/Makefile deleted file mode 100644 index ee44ee448..000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -GO ?= go -CC ?= gcc -ifeq ($(GOPATH),) -export GOPATH := $(shell $(GO) env GOPATH) -endif -FIRST_GOPATH := $(firstword $(subst :, ,$(GOPATH))) -GOBIN := $(shell $(GO) env GOBIN) -ifeq ($(GOBIN),) - GOBIN := $(FIRST_GOPATH)/bin -endif - -all: build test phaul phaul-test - -lint: - @golint . test phaul -build: - @$(GO) build -v - -test/piggie: test/piggie.c - @$(CC) $^ -o $@ - -test/test: test/main.go - @$(GO) build -v -o test/test test/main.go - -test: test/test test/piggie - mkdir -p image - test/piggie - test/test dump `pidof piggie` image - test/test restore image - pkill -9 piggie || : - -phaul: - @cd phaul; go build -v - -test/phaul: test/phaul-main.go - @$(GO) build -v -o test/phaul test/phaul-main.go - -phaul-test: test/phaul test/piggie - rm -rf image - test/piggie - test/phaul `pidof piggie` - pkill -9 piggie || : - -clean: - @rm -f test/test test/piggie test/phaul - @rm -rf image - @rm -f rpc/rpc.proto - -install.tools: - if [ ! -x "$(GOBIN)/golint" ]; then \ - $(GO) get -u golang.org/x/lint/golint; \ - fi - -rpc/rpc.proto: - curl -s https://raw.githubusercontent.com/checkpoint-restore/criu/master/images/rpc.proto -o $@ - -rpc/rpc.pb.go: rpc/rpc.proto - protoc --go_out=. $^ - -.PHONY: build test clean lint phaul diff --git a/vendor/github.com/checkpoint-restore/go-criu/rpc/rpc.pb.go b/vendor/github.com/checkpoint-restore/go-criu/rpc/rpc.pb.go deleted file mode 100644 index 230faace5..000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/rpc/rpc.pb.go +++ /dev/null @@ -1,1211 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: rpc/rpc.proto - -/* -Package rpc is a generated protocol buffer package. - -It is generated from these files: - rpc/rpc.proto - -It has these top-level messages: - CriuPageServerInfo - CriuVethPair - ExtMountMap - JoinNamespace - InheritFd - CgroupRoot - UnixSk - CriuOpts - CriuDumpResp - CriuRestoreResp - CriuNotify - CriuFeatures - CriuReq - CriuResp - CriuVersion -*/ -package rpc - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type CriuCgMode int32 - -const ( - CriuCgMode_IGNORE CriuCgMode = 0 - CriuCgMode_CG_NONE CriuCgMode = 1 - CriuCgMode_PROPS CriuCgMode = 2 - CriuCgMode_SOFT CriuCgMode = 3 - CriuCgMode_FULL CriuCgMode = 4 - CriuCgMode_STRICT CriuCgMode = 5 - CriuCgMode_DEFAULT CriuCgMode = 6 -) - -var CriuCgMode_name = map[int32]string{ - 0: "IGNORE", - 1: "CG_NONE", - 2: "PROPS", - 3: "SOFT", - 4: "FULL", - 5: "STRICT", - 6: "DEFAULT", -} -var CriuCgMode_value = map[string]int32{ - "IGNORE": 0, - "CG_NONE": 1, - "PROPS": 2, - "SOFT": 3, - "FULL": 4, - "STRICT": 5, - "DEFAULT": 6, -} - -func (x CriuCgMode) Enum() *CriuCgMode { - p := new(CriuCgMode) - *p = x - return p -} -func (x CriuCgMode) String() string { - return proto.EnumName(CriuCgMode_name, int32(x)) -} -func (x *CriuCgMode) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(CriuCgMode_value, data, "CriuCgMode") - if err != nil { - return err - } - *x = CriuCgMode(value) - return nil -} -func (CriuCgMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -type CriuReqType int32 - -const ( - CriuReqType_EMPTY CriuReqType = 0 - CriuReqType_DUMP CriuReqType = 1 - CriuReqType_RESTORE CriuReqType = 2 - CriuReqType_CHECK CriuReqType = 3 - CriuReqType_PRE_DUMP CriuReqType = 4 - CriuReqType_PAGE_SERVER CriuReqType = 5 - CriuReqType_NOTIFY CriuReqType = 6 - CriuReqType_CPUINFO_DUMP CriuReqType = 7 - CriuReqType_CPUINFO_CHECK CriuReqType = 8 - CriuReqType_FEATURE_CHECK CriuReqType = 9 - CriuReqType_VERSION CriuReqType = 10 - CriuReqType_WAIT_PID CriuReqType = 11 - CriuReqType_PAGE_SERVER_CHLD CriuReqType = 12 -) - -var CriuReqType_name = map[int32]string{ - 0: "EMPTY", - 1: "DUMP", - 2: "RESTORE", - 3: "CHECK", - 4: "PRE_DUMP", - 5: "PAGE_SERVER", - 6: "NOTIFY", - 7: "CPUINFO_DUMP", - 8: "CPUINFO_CHECK", - 9: "FEATURE_CHECK", - 10: "VERSION", - 11: "WAIT_PID", - 12: "PAGE_SERVER_CHLD", -} -var CriuReqType_value = map[string]int32{ - "EMPTY": 0, - "DUMP": 1, - "RESTORE": 2, - "CHECK": 3, - "PRE_DUMP": 4, - "PAGE_SERVER": 5, - "NOTIFY": 6, - "CPUINFO_DUMP": 7, - "CPUINFO_CHECK": 8, - "FEATURE_CHECK": 9, - "VERSION": 10, - "WAIT_PID": 11, - "PAGE_SERVER_CHLD": 12, -} - -func (x CriuReqType) Enum() *CriuReqType { - p := new(CriuReqType) - *p = x - return p -} -func (x CriuReqType) String() string { - return proto.EnumName(CriuReqType_name, int32(x)) -} -func (x *CriuReqType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(CriuReqType_value, data, "CriuReqType") - if err != nil { - return err - } - *x = CriuReqType(value) - return nil -} -func (CriuReqType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -type CriuPageServerInfo struct { - Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - Port *int32 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"` - Pid *int32 `protobuf:"varint,3,opt,name=pid" json:"pid,omitempty"` - Fd *int32 `protobuf:"varint,4,opt,name=fd" json:"fd,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CriuPageServerInfo) Reset() { *m = CriuPageServerInfo{} } -func (m *CriuPageServerInfo) String() string { return proto.CompactTextString(m) } -func (*CriuPageServerInfo) ProtoMessage() {} -func (*CriuPageServerInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -func (m *CriuPageServerInfo) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -func (m *CriuPageServerInfo) GetPort() int32 { - if m != nil && m.Port != nil { - return *m.Port - } - return 0 -} - -func (m *CriuPageServerInfo) GetPid() int32 { - if m != nil && m.Pid != nil { - return *m.Pid - } - return 0 -} - -func (m *CriuPageServerInfo) GetFd() int32 { - if m != nil && m.Fd != nil { - return *m.Fd - } - return 0 -} - -type CriuVethPair struct { - IfIn *string `protobuf:"bytes,1,req,name=if_in,json=ifIn" json:"if_in,omitempty"` - IfOut *string `protobuf:"bytes,2,req,name=if_out,json=ifOut" json:"if_out,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CriuVethPair) Reset() { *m = CriuVethPair{} } -func (m *CriuVethPair) String() string { return proto.CompactTextString(m) } -func (*CriuVethPair) ProtoMessage() {} -func (*CriuVethPair) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -func (m *CriuVethPair) GetIfIn() string { - if m != nil && m.IfIn != nil { - return *m.IfIn - } - return "" -} - -func (m *CriuVethPair) GetIfOut() string { - if m != nil && m.IfOut != nil { - return *m.IfOut - } - return "" -} - -type ExtMountMap struct { - Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"` - Val *string `protobuf:"bytes,2,req,name=val" json:"val,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *ExtMountMap) Reset() { *m = ExtMountMap{} } -func (m *ExtMountMap) String() string { return proto.CompactTextString(m) } -func (*ExtMountMap) ProtoMessage() {} -func (*ExtMountMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } - -func (m *ExtMountMap) GetKey() string { - if m != nil && m.Key != nil { - return *m.Key - } - return "" -} - -func (m *ExtMountMap) GetVal() string { - if m != nil && m.Val != nil { - return *m.Val - } - return "" -} - -type JoinNamespace struct { - Ns *string `protobuf:"bytes,1,req,name=ns" json:"ns,omitempty"` - NsFile *string `protobuf:"bytes,2,req,name=ns_file,json=nsFile" json:"ns_file,omitempty"` - ExtraOpt *string `protobuf:"bytes,3,opt,name=extra_opt,json=extraOpt" json:"extra_opt,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *JoinNamespace) Reset() { *m = JoinNamespace{} } -func (m *JoinNamespace) String() string { return proto.CompactTextString(m) } -func (*JoinNamespace) ProtoMessage() {} -func (*JoinNamespace) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } - -func (m *JoinNamespace) GetNs() string { - if m != nil && m.Ns != nil { - return *m.Ns - } - return "" -} - -func (m *JoinNamespace) GetNsFile() string { - if m != nil && m.NsFile != nil { - return *m.NsFile - } - return "" -} - -func (m *JoinNamespace) GetExtraOpt() string { - if m != nil && m.ExtraOpt != nil { - return *m.ExtraOpt - } - return "" -} - -type InheritFd struct { - Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"` - Fd *int32 `protobuf:"varint,2,req,name=fd" json:"fd,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *InheritFd) Reset() { *m = InheritFd{} } -func (m *InheritFd) String() string { return proto.CompactTextString(m) } -func (*InheritFd) ProtoMessage() {} -func (*InheritFd) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } - -func (m *InheritFd) GetKey() string { - if m != nil && m.Key != nil { - return *m.Key - } - return "" -} - -func (m *InheritFd) GetFd() int32 { - if m != nil && m.Fd != nil { - return *m.Fd - } - return 0 -} - -type CgroupRoot struct { - Ctrl *string `protobuf:"bytes,1,opt,name=ctrl" json:"ctrl,omitempty"` - Path *string `protobuf:"bytes,2,req,name=path" json:"path,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CgroupRoot) Reset() { *m = CgroupRoot{} } -func (m *CgroupRoot) String() string { return proto.CompactTextString(m) } -func (*CgroupRoot) ProtoMessage() {} -func (*CgroupRoot) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } - -func (m *CgroupRoot) GetCtrl() string { - if m != nil && m.Ctrl != nil { - return *m.Ctrl - } - return "" -} - -func (m *CgroupRoot) GetPath() string { - if m != nil && m.Path != nil { - return *m.Path - } - return "" -} - -type UnixSk struct { - Inode *uint32 `protobuf:"varint,1,req,name=inode" json:"inode,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *UnixSk) Reset() { *m = UnixSk{} } -func (m *UnixSk) String() string { return proto.CompactTextString(m) } -func (*UnixSk) ProtoMessage() {} -func (*UnixSk) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } - -func (m *UnixSk) GetInode() uint32 { - if m != nil && m.Inode != nil { - return *m.Inode - } - return 0 -} - -type CriuOpts struct { - ImagesDirFd *int32 `protobuf:"varint,1,req,name=images_dir_fd,json=imagesDirFd" json:"images_dir_fd,omitempty"` - Pid *int32 `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"` - LeaveRunning *bool `protobuf:"varint,3,opt,name=leave_running,json=leaveRunning" json:"leave_running,omitempty"` - ExtUnixSk *bool `protobuf:"varint,4,opt,name=ext_unix_sk,json=extUnixSk" json:"ext_unix_sk,omitempty"` - TcpEstablished *bool `protobuf:"varint,5,opt,name=tcp_established,json=tcpEstablished" json:"tcp_established,omitempty"` - EvasiveDevices *bool `protobuf:"varint,6,opt,name=evasive_devices,json=evasiveDevices" json:"evasive_devices,omitempty"` - ShellJob *bool `protobuf:"varint,7,opt,name=shell_job,json=shellJob" json:"shell_job,omitempty"` - FileLocks *bool `protobuf:"varint,8,opt,name=file_locks,json=fileLocks" json:"file_locks,omitempty"` - LogLevel *int32 `protobuf:"varint,9,opt,name=log_level,json=logLevel,def=2" json:"log_level,omitempty"` - LogFile *string `protobuf:"bytes,10,opt,name=log_file,json=logFile" json:"log_file,omitempty"` - Ps *CriuPageServerInfo `protobuf:"bytes,11,opt,name=ps" json:"ps,omitempty"` - NotifyScripts *bool `protobuf:"varint,12,opt,name=notify_scripts,json=notifyScripts" json:"notify_scripts,omitempty"` - Root *string `protobuf:"bytes,13,opt,name=root" json:"root,omitempty"` - ParentImg *string `protobuf:"bytes,14,opt,name=parent_img,json=parentImg" json:"parent_img,omitempty"` - TrackMem *bool `protobuf:"varint,15,opt,name=track_mem,json=trackMem" json:"track_mem,omitempty"` - AutoDedup *bool `protobuf:"varint,16,opt,name=auto_dedup,json=autoDedup" json:"auto_dedup,omitempty"` - WorkDirFd *int32 `protobuf:"varint,17,opt,name=work_dir_fd,json=workDirFd" json:"work_dir_fd,omitempty"` - LinkRemap *bool `protobuf:"varint,18,opt,name=link_remap,json=linkRemap" json:"link_remap,omitempty"` - Veths []*CriuVethPair `protobuf:"bytes,19,rep,name=veths" json:"veths,omitempty"` - CpuCap *uint32 `protobuf:"varint,20,opt,name=cpu_cap,json=cpuCap,def=4294967295" json:"cpu_cap,omitempty"` - ForceIrmap *bool `protobuf:"varint,21,opt,name=force_irmap,json=forceIrmap" json:"force_irmap,omitempty"` - ExecCmd []string `protobuf:"bytes,22,rep,name=exec_cmd,json=execCmd" json:"exec_cmd,omitempty"` - ExtMnt []*ExtMountMap `protobuf:"bytes,23,rep,name=ext_mnt,json=extMnt" json:"ext_mnt,omitempty"` - ManageCgroups *bool `protobuf:"varint,24,opt,name=manage_cgroups,json=manageCgroups" json:"manage_cgroups,omitempty"` - CgRoot []*CgroupRoot `protobuf:"bytes,25,rep,name=cg_root,json=cgRoot" json:"cg_root,omitempty"` - RstSibling *bool `protobuf:"varint,26,opt,name=rst_sibling,json=rstSibling" json:"rst_sibling,omitempty"` - InheritFd []*InheritFd `protobuf:"bytes,27,rep,name=inherit_fd,json=inheritFd" json:"inherit_fd,omitempty"` - AutoExtMnt *bool `protobuf:"varint,28,opt,name=auto_ext_mnt,json=autoExtMnt" json:"auto_ext_mnt,omitempty"` - ExtSharing *bool `protobuf:"varint,29,opt,name=ext_sharing,json=extSharing" json:"ext_sharing,omitempty"` - ExtMasters *bool `protobuf:"varint,30,opt,name=ext_masters,json=extMasters" json:"ext_masters,omitempty"` - SkipMnt []string `protobuf:"bytes,31,rep,name=skip_mnt,json=skipMnt" json:"skip_mnt,omitempty"` - EnableFs []string `protobuf:"bytes,32,rep,name=enable_fs,json=enableFs" json:"enable_fs,omitempty"` - UnixSkIno []*UnixSk `protobuf:"bytes,33,rep,name=unix_sk_ino,json=unixSkIno" json:"unix_sk_ino,omitempty"` - ManageCgroupsMode *CriuCgMode `protobuf:"varint,34,opt,name=manage_cgroups_mode,json=manageCgroupsMode,enum=CriuCgMode" json:"manage_cgroups_mode,omitempty"` - GhostLimit *uint32 `protobuf:"varint,35,opt,name=ghost_limit,json=ghostLimit,def=1048576" json:"ghost_limit,omitempty"` - IrmapScanPaths []string `protobuf:"bytes,36,rep,name=irmap_scan_paths,json=irmapScanPaths" json:"irmap_scan_paths,omitempty"` - External []string `protobuf:"bytes,37,rep,name=external" json:"external,omitempty"` - EmptyNs *uint32 `protobuf:"varint,38,opt,name=empty_ns,json=emptyNs" json:"empty_ns,omitempty"` - JoinNs []*JoinNamespace `protobuf:"bytes,39,rep,name=join_ns,json=joinNs" json:"join_ns,omitempty"` - CgroupProps *string `protobuf:"bytes,41,opt,name=cgroup_props,json=cgroupProps" json:"cgroup_props,omitempty"` - CgroupPropsFile *string `protobuf:"bytes,42,opt,name=cgroup_props_file,json=cgroupPropsFile" json:"cgroup_props_file,omitempty"` - CgroupDumpController []string `protobuf:"bytes,43,rep,name=cgroup_dump_controller,json=cgroupDumpController" json:"cgroup_dump_controller,omitempty"` - FreezeCgroup *string `protobuf:"bytes,44,opt,name=freeze_cgroup,json=freezeCgroup" json:"freeze_cgroup,omitempty"` - Timeout *uint32 `protobuf:"varint,45,opt,name=timeout" json:"timeout,omitempty"` - TcpSkipInFlight *bool `protobuf:"varint,46,opt,name=tcp_skip_in_flight,json=tcpSkipInFlight" json:"tcp_skip_in_flight,omitempty"` - WeakSysctls *bool `protobuf:"varint,47,opt,name=weak_sysctls,json=weakSysctls" json:"weak_sysctls,omitempty"` - LazyPages *bool `protobuf:"varint,48,opt,name=lazy_pages,json=lazyPages" json:"lazy_pages,omitempty"` - StatusFd *int32 `protobuf:"varint,49,opt,name=status_fd,json=statusFd" json:"status_fd,omitempty"` - OrphanPtsMaster *bool `protobuf:"varint,50,opt,name=orphan_pts_master,json=orphanPtsMaster" json:"orphan_pts_master,omitempty"` - ConfigFile *string `protobuf:"bytes,51,opt,name=config_file,json=configFile" json:"config_file,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CriuOpts) Reset() { *m = CriuOpts{} } -func (m *CriuOpts) String() string { return proto.CompactTextString(m) } -func (*CriuOpts) ProtoMessage() {} -func (*CriuOpts) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } - -const Default_CriuOpts_LogLevel int32 = 2 -const Default_CriuOpts_CpuCap uint32 = 4294967295 -const Default_CriuOpts_GhostLimit uint32 = 1048576 - -func (m *CriuOpts) GetImagesDirFd() int32 { - if m != nil && m.ImagesDirFd != nil { - return *m.ImagesDirFd - } - return 0 -} - -func (m *CriuOpts) GetPid() int32 { - if m != nil && m.Pid != nil { - return *m.Pid - } - return 0 -} - -func (m *CriuOpts) GetLeaveRunning() bool { - if m != nil && m.LeaveRunning != nil { - return *m.LeaveRunning - } - return false -} - -func (m *CriuOpts) GetExtUnixSk() bool { - if m != nil && m.ExtUnixSk != nil { - return *m.ExtUnixSk - } - return false -} - -func (m *CriuOpts) GetTcpEstablished() bool { - if m != nil && m.TcpEstablished != nil { - return *m.TcpEstablished - } - return false -} - -func (m *CriuOpts) GetEvasiveDevices() bool { - if m != nil && m.EvasiveDevices != nil { - return *m.EvasiveDevices - } - return false -} - -func (m *CriuOpts) GetShellJob() bool { - if m != nil && m.ShellJob != nil { - return *m.ShellJob - } - return false -} - -func (m *CriuOpts) GetFileLocks() bool { - if m != nil && m.FileLocks != nil { - return *m.FileLocks - } - return false -} - -func (m *CriuOpts) GetLogLevel() int32 { - if m != nil && m.LogLevel != nil { - return *m.LogLevel - } - return Default_CriuOpts_LogLevel -} - -func (m *CriuOpts) GetLogFile() string { - if m != nil && m.LogFile != nil { - return *m.LogFile - } - return "" -} - -func (m *CriuOpts) GetPs() *CriuPageServerInfo { - if m != nil { - return m.Ps - } - return nil -} - -func (m *CriuOpts) GetNotifyScripts() bool { - if m != nil && m.NotifyScripts != nil { - return *m.NotifyScripts - } - return false -} - -func (m *CriuOpts) GetRoot() string { - if m != nil && m.Root != nil { - return *m.Root - } - return "" -} - -func (m *CriuOpts) GetParentImg() string { - if m != nil && m.ParentImg != nil { - return *m.ParentImg - } - return "" -} - -func (m *CriuOpts) GetTrackMem() bool { - if m != nil && m.TrackMem != nil { - return *m.TrackMem - } - return false -} - -func (m *CriuOpts) GetAutoDedup() bool { - if m != nil && m.AutoDedup != nil { - return *m.AutoDedup - } - return false -} - -func (m *CriuOpts) GetWorkDirFd() int32 { - if m != nil && m.WorkDirFd != nil { - return *m.WorkDirFd - } - return 0 -} - -func (m *CriuOpts) GetLinkRemap() bool { - if m != nil && m.LinkRemap != nil { - return *m.LinkRemap - } - return false -} - -func (m *CriuOpts) GetVeths() []*CriuVethPair { - if m != nil { - return m.Veths - } - return nil -} - -func (m *CriuOpts) GetCpuCap() uint32 { - if m != nil && m.CpuCap != nil { - return *m.CpuCap - } - return Default_CriuOpts_CpuCap -} - -func (m *CriuOpts) GetForceIrmap() bool { - if m != nil && m.ForceIrmap != nil { - return *m.ForceIrmap - } - return false -} - -func (m *CriuOpts) GetExecCmd() []string { - if m != nil { - return m.ExecCmd - } - return nil -} - -func (m *CriuOpts) GetExtMnt() []*ExtMountMap { - if m != nil { - return m.ExtMnt - } - return nil -} - -func (m *CriuOpts) GetManageCgroups() bool { - if m != nil && m.ManageCgroups != nil { - return *m.ManageCgroups - } - return false -} - -func (m *CriuOpts) GetCgRoot() []*CgroupRoot { - if m != nil { - return m.CgRoot - } - return nil -} - -func (m *CriuOpts) GetRstSibling() bool { - if m != nil && m.RstSibling != nil { - return *m.RstSibling - } - return false -} - -func (m *CriuOpts) GetInheritFd() []*InheritFd { - if m != nil { - return m.InheritFd - } - return nil -} - -func (m *CriuOpts) GetAutoExtMnt() bool { - if m != nil && m.AutoExtMnt != nil { - return *m.AutoExtMnt - } - return false -} - -func (m *CriuOpts) GetExtSharing() bool { - if m != nil && m.ExtSharing != nil { - return *m.ExtSharing - } - return false -} - -func (m *CriuOpts) GetExtMasters() bool { - if m != nil && m.ExtMasters != nil { - return *m.ExtMasters - } - return false -} - -func (m *CriuOpts) GetSkipMnt() []string { - if m != nil { - return m.SkipMnt - } - return nil -} - -func (m *CriuOpts) GetEnableFs() []string { - if m != nil { - return m.EnableFs - } - return nil -} - -func (m *CriuOpts) GetUnixSkIno() []*UnixSk { - if m != nil { - return m.UnixSkIno - } - return nil -} - -func (m *CriuOpts) GetManageCgroupsMode() CriuCgMode { - if m != nil && m.ManageCgroupsMode != nil { - return *m.ManageCgroupsMode - } - return CriuCgMode_IGNORE -} - -func (m *CriuOpts) GetGhostLimit() uint32 { - if m != nil && m.GhostLimit != nil { - return *m.GhostLimit - } - return Default_CriuOpts_GhostLimit -} - -func (m *CriuOpts) GetIrmapScanPaths() []string { - if m != nil { - return m.IrmapScanPaths - } - return nil -} - -func (m *CriuOpts) GetExternal() []string { - if m != nil { - return m.External - } - return nil -} - -func (m *CriuOpts) GetEmptyNs() uint32 { - if m != nil && m.EmptyNs != nil { - return *m.EmptyNs - } - return 0 -} - -func (m *CriuOpts) GetJoinNs() []*JoinNamespace { - if m != nil { - return m.JoinNs - } - return nil -} - -func (m *CriuOpts) GetCgroupProps() string { - if m != nil && m.CgroupProps != nil { - return *m.CgroupProps - } - return "" -} - -func (m *CriuOpts) GetCgroupPropsFile() string { - if m != nil && m.CgroupPropsFile != nil { - return *m.CgroupPropsFile - } - return "" -} - -func (m *CriuOpts) GetCgroupDumpController() []string { - if m != nil { - return m.CgroupDumpController - } - return nil -} - -func (m *CriuOpts) GetFreezeCgroup() string { - if m != nil && m.FreezeCgroup != nil { - return *m.FreezeCgroup - } - return "" -} - -func (m *CriuOpts) GetTimeout() uint32 { - if m != nil && m.Timeout != nil { - return *m.Timeout - } - return 0 -} - -func (m *CriuOpts) GetTcpSkipInFlight() bool { - if m != nil && m.TcpSkipInFlight != nil { - return *m.TcpSkipInFlight - } - return false -} - -func (m *CriuOpts) GetWeakSysctls() bool { - if m != nil && m.WeakSysctls != nil { - return *m.WeakSysctls - } - return false -} - -func (m *CriuOpts) GetLazyPages() bool { - if m != nil && m.LazyPages != nil { - return *m.LazyPages - } - return false -} - -func (m *CriuOpts) GetStatusFd() int32 { - if m != nil && m.StatusFd != nil { - return *m.StatusFd - } - return 0 -} - -func (m *CriuOpts) GetOrphanPtsMaster() bool { - if m != nil && m.OrphanPtsMaster != nil { - return *m.OrphanPtsMaster - } - return false -} - -func (m *CriuOpts) GetConfigFile() string { - if m != nil && m.ConfigFile != nil { - return *m.ConfigFile - } - return "" -} - -type CriuDumpResp struct { - Restored *bool `protobuf:"varint,1,opt,name=restored" json:"restored,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CriuDumpResp) Reset() { *m = CriuDumpResp{} } -func (m *CriuDumpResp) String() string { return proto.CompactTextString(m) } -func (*CriuDumpResp) ProtoMessage() {} -func (*CriuDumpResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } - -func (m *CriuDumpResp) GetRestored() bool { - if m != nil && m.Restored != nil { - return *m.Restored - } - return false -} - -type CriuRestoreResp struct { - Pid *int32 `protobuf:"varint,1,req,name=pid" json:"pid,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CriuRestoreResp) Reset() { *m = CriuRestoreResp{} } -func (m *CriuRestoreResp) String() string { return proto.CompactTextString(m) } -func (*CriuRestoreResp) ProtoMessage() {} -func (*CriuRestoreResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } - -func (m *CriuRestoreResp) GetPid() int32 { - if m != nil && m.Pid != nil { - return *m.Pid - } - return 0 -} - -type CriuNotify struct { - Script *string `protobuf:"bytes,1,opt,name=script" json:"script,omitempty"` - Pid *int32 `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CriuNotify) Reset() { *m = CriuNotify{} } -func (m *CriuNotify) String() string { return proto.CompactTextString(m) } -func (*CriuNotify) ProtoMessage() {} -func (*CriuNotify) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } - -func (m *CriuNotify) GetScript() string { - if m != nil && m.Script != nil { - return *m.Script - } - return "" -} - -func (m *CriuNotify) GetPid() int32 { - if m != nil && m.Pid != nil { - return *m.Pid - } - return 0 -} - -// -// List of features which can queried via -// CRIU_REQ_TYPE__FEATURE_CHECK -type CriuFeatures struct { - MemTrack *bool `protobuf:"varint,1,opt,name=mem_track,json=memTrack" json:"mem_track,omitempty"` - LazyPages *bool `protobuf:"varint,2,opt,name=lazy_pages,json=lazyPages" json:"lazy_pages,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CriuFeatures) Reset() { *m = CriuFeatures{} } -func (m *CriuFeatures) String() string { return proto.CompactTextString(m) } -func (*CriuFeatures) ProtoMessage() {} -func (*CriuFeatures) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } - -func (m *CriuFeatures) GetMemTrack() bool { - if m != nil && m.MemTrack != nil { - return *m.MemTrack - } - return false -} - -func (m *CriuFeatures) GetLazyPages() bool { - if m != nil && m.LazyPages != nil { - return *m.LazyPages - } - return false -} - -type CriuReq struct { - Type *CriuReqType `protobuf:"varint,1,req,name=type,enum=CriuReqType" json:"type,omitempty"` - Opts *CriuOpts `protobuf:"bytes,2,opt,name=opts" json:"opts,omitempty"` - NotifySuccess *bool `protobuf:"varint,3,opt,name=notify_success,json=notifySuccess" json:"notify_success,omitempty"` - // - // When set service won't close the connection but - // will wait for more req-s to appear. Works not - // for all request types. - KeepOpen *bool `protobuf:"varint,4,opt,name=keep_open,json=keepOpen" json:"keep_open,omitempty"` - // - // 'features' can be used to query which features - // are supported by the installed criu/kernel - // via RPC. - Features *CriuFeatures `protobuf:"bytes,5,opt,name=features" json:"features,omitempty"` - // 'pid' is used for WAIT_PID - Pid *uint32 `protobuf:"varint,6,opt,name=pid" json:"pid,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CriuReq) Reset() { *m = CriuReq{} } -func (m *CriuReq) String() string { return proto.CompactTextString(m) } -func (*CriuReq) ProtoMessage() {} -func (*CriuReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } - -func (m *CriuReq) GetType() CriuReqType { - if m != nil && m.Type != nil { - return *m.Type - } - return CriuReqType_EMPTY -} - -func (m *CriuReq) GetOpts() *CriuOpts { - if m != nil { - return m.Opts - } - return nil -} - -func (m *CriuReq) GetNotifySuccess() bool { - if m != nil && m.NotifySuccess != nil { - return *m.NotifySuccess - } - return false -} - -func (m *CriuReq) GetKeepOpen() bool { - if m != nil && m.KeepOpen != nil { - return *m.KeepOpen - } - return false -} - -func (m *CriuReq) GetFeatures() *CriuFeatures { - if m != nil { - return m.Features - } - return nil -} - -func (m *CriuReq) GetPid() uint32 { - if m != nil && m.Pid != nil { - return *m.Pid - } - return 0 -} - -type CriuResp struct { - Type *CriuReqType `protobuf:"varint,1,req,name=type,enum=CriuReqType" json:"type,omitempty"` - Success *bool `protobuf:"varint,2,req,name=success" json:"success,omitempty"` - Dump *CriuDumpResp `protobuf:"bytes,3,opt,name=dump" json:"dump,omitempty"` - Restore *CriuRestoreResp `protobuf:"bytes,4,opt,name=restore" json:"restore,omitempty"` - Notify *CriuNotify `protobuf:"bytes,5,opt,name=notify" json:"notify,omitempty"` - Ps *CriuPageServerInfo `protobuf:"bytes,6,opt,name=ps" json:"ps,omitempty"` - CrErrno *int32 `protobuf:"varint,7,opt,name=cr_errno,json=crErrno" json:"cr_errno,omitempty"` - Features *CriuFeatures `protobuf:"bytes,8,opt,name=features" json:"features,omitempty"` - CrErrmsg *string `protobuf:"bytes,9,opt,name=cr_errmsg,json=crErrmsg" json:"cr_errmsg,omitempty"` - Version *CriuVersion `protobuf:"bytes,10,opt,name=version" json:"version,omitempty"` - Status *int32 `protobuf:"varint,11,opt,name=status" json:"status,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CriuResp) Reset() { *m = CriuResp{} } -func (m *CriuResp) String() string { return proto.CompactTextString(m) } -func (*CriuResp) ProtoMessage() {} -func (*CriuResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } - -func (m *CriuResp) GetType() CriuReqType { - if m != nil && m.Type != nil { - return *m.Type - } - return CriuReqType_EMPTY -} - -func (m *CriuResp) GetSuccess() bool { - if m != nil && m.Success != nil { - return *m.Success - } - return false -} - -func (m *CriuResp) GetDump() *CriuDumpResp { - if m != nil { - return m.Dump - } - return nil -} - -func (m *CriuResp) GetRestore() *CriuRestoreResp { - if m != nil { - return m.Restore - } - return nil -} - -func (m *CriuResp) GetNotify() *CriuNotify { - if m != nil { - return m.Notify - } - return nil -} - -func (m *CriuResp) GetPs() *CriuPageServerInfo { - if m != nil { - return m.Ps - } - return nil -} - -func (m *CriuResp) GetCrErrno() int32 { - if m != nil && m.CrErrno != nil { - return *m.CrErrno - } - return 0 -} - -func (m *CriuResp) GetFeatures() *CriuFeatures { - if m != nil { - return m.Features - } - return nil -} - -func (m *CriuResp) GetCrErrmsg() string { - if m != nil && m.CrErrmsg != nil { - return *m.CrErrmsg - } - return "" -} - -func (m *CriuResp) GetVersion() *CriuVersion { - if m != nil { - return m.Version - } - return nil -} - -func (m *CriuResp) GetStatus() int32 { - if m != nil && m.Status != nil { - return *m.Status - } - return 0 -} - -// Answer for criu_req_type.VERSION requests -type CriuVersion struct { - Major *int32 `protobuf:"varint,1,req,name=major" json:"major,omitempty"` - Minor *int32 `protobuf:"varint,2,req,name=minor" json:"minor,omitempty"` - Gitid *string `protobuf:"bytes,3,opt,name=gitid" json:"gitid,omitempty"` - Sublevel *int32 `protobuf:"varint,4,opt,name=sublevel" json:"sublevel,omitempty"` - Extra *int32 `protobuf:"varint,5,opt,name=extra" json:"extra,omitempty"` - Name *string `protobuf:"bytes,6,opt,name=name" json:"name,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CriuVersion) Reset() { *m = CriuVersion{} } -func (m *CriuVersion) String() string { return proto.CompactTextString(m) } -func (*CriuVersion) ProtoMessage() {} -func (*CriuVersion) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } - -func (m *CriuVersion) GetMajor() int32 { - if m != nil && m.Major != nil { - return *m.Major - } - return 0 -} - -func (m *CriuVersion) GetMinor() int32 { - if m != nil && m.Minor != nil { - return *m.Minor - } - return 0 -} - -func (m *CriuVersion) GetGitid() string { - if m != nil && m.Gitid != nil { - return *m.Gitid - } - return "" -} - -func (m *CriuVersion) GetSublevel() int32 { - if m != nil && m.Sublevel != nil { - return *m.Sublevel - } - return 0 -} - -func (m *CriuVersion) GetExtra() int32 { - if m != nil && m.Extra != nil { - return *m.Extra - } - return 0 -} - -func (m *CriuVersion) GetName() string { - if m != nil && m.Name != nil { - return *m.Name - } - return "" -} - -func init() { - proto.RegisterType((*CriuPageServerInfo)(nil), "criu_page_server_info") - proto.RegisterType((*CriuVethPair)(nil), "criu_veth_pair") - proto.RegisterType((*ExtMountMap)(nil), "ext_mount_map") - proto.RegisterType((*JoinNamespace)(nil), "join_namespace") - proto.RegisterType((*InheritFd)(nil), "inherit_fd") - proto.RegisterType((*CgroupRoot)(nil), "cgroup_root") - proto.RegisterType((*UnixSk)(nil), "unix_sk") - proto.RegisterType((*CriuOpts)(nil), "criu_opts") - proto.RegisterType((*CriuDumpResp)(nil), "criu_dump_resp") - proto.RegisterType((*CriuRestoreResp)(nil), "criu_restore_resp") - proto.RegisterType((*CriuNotify)(nil), "criu_notify") - proto.RegisterType((*CriuFeatures)(nil), "criu_features") - proto.RegisterType((*CriuReq)(nil), "criu_req") - proto.RegisterType((*CriuResp)(nil), "criu_resp") - proto.RegisterType((*CriuVersion)(nil), "criu_version") - proto.RegisterEnum("CriuCgMode", CriuCgMode_name, CriuCgMode_value) - proto.RegisterEnum("CriuReqType", CriuReqType_name, CriuReqType_value) -} - -func init() { proto.RegisterFile("rpc/rpc.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 1835 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xeb, 0x72, 0x5b, 0xb7, - 0x11, 0x0e, 0x29, 0xf1, 0x06, 0x5e, 0x7c, 0x0c, 0x5f, 0x02, 0xc7, 0xb5, 0xad, 0xd0, 0x51, 0xa2, - 0x2a, 0x2e, 0x93, 0x30, 0x76, 0x5c, 0x67, 0xda, 0x1f, 0x1e, 0x8a, 0x74, 0xd8, 0x48, 0x22, 0x07, - 0xa4, 0xdc, 0xc9, 0x2f, 0xcc, 0xd1, 0x39, 0x20, 0x05, 0xf3, 0xdc, 0x0a, 0x80, 0x8a, 0xe4, 0x97, - 0xe8, 0xbf, 0x3e, 0x57, 0xde, 0xa4, 0xaf, 0xd0, 0xd9, 0x05, 0x28, 0x4b, 0x49, 0x66, 0xd2, 0x7f, - 0xd8, 0x0f, 0xbb, 0xc0, 0xde, 0x77, 0x49, 0x5b, 0x17, 0xd1, 0x57, 0xba, 0x88, 0x7a, 0x85, 0xce, - 0x6d, 0xde, 0x5d, 0x92, 0x7b, 0x91, 0x56, 0x6b, 0x51, 0x84, 0x4b, 0x29, 0x8c, 0xd4, 0xe7, 0x52, - 0x0b, 0x95, 0x2d, 0x72, 0xca, 0x48, 0x2d, 0x8c, 0x63, 0x2d, 0x8d, 0x61, 0xa5, 0x9d, 0xd2, 0x5e, - 0x83, 0x6f, 0x48, 0x4a, 0xc9, 0x76, 0x91, 0x6b, 0xcb, 0xca, 0x3b, 0xa5, 0xbd, 0x0a, 0xc7, 0x33, - 0x0d, 0xc8, 0x56, 0xa1, 0x62, 0xb6, 0x85, 0x10, 0x1c, 0x69, 0x87, 0x94, 0x17, 0x31, 0xdb, 0x46, - 0xa0, 0xbc, 0x88, 0xbb, 0x7f, 0x23, 0x1d, 0xfc, 0xe8, 0x5c, 0xda, 0x33, 0x51, 0x84, 0x4a, 0xd3, - 0x3b, 0xa4, 0xa2, 0x16, 0x42, 0x65, 0xac, 0xb4, 0x53, 0xde, 0x6b, 0xf0, 0x6d, 0xb5, 0x18, 0x67, - 0xf4, 0x1e, 0xa9, 0xaa, 0x85, 0xc8, 0xd7, 0xf0, 0x3c, 0xa0, 0x15, 0xb5, 0x98, 0xac, 0x6d, 0xf7, - 0x5b, 0xd2, 0x96, 0x17, 0x56, 0xa4, 0xf9, 0x3a, 0xb3, 0x22, 0x0d, 0x0b, 0xf8, 0x70, 0x25, 0x2f, - 0xbd, 0x28, 0x1c, 0x01, 0x39, 0x0f, 0x13, 0x2f, 0x06, 0xc7, 0xee, 0x5b, 0xd2, 0x79, 0x97, 0xab, - 0x4c, 0x64, 0x61, 0x2a, 0x4d, 0x11, 0x46, 0x12, 0x94, 0xca, 0x8c, 0x17, 0x2a, 0x67, 0x86, 0x7e, - 0x4c, 0x6a, 0x99, 0x11, 0x0b, 0x95, 0x48, 0x2f, 0x57, 0xcd, 0xcc, 0x48, 0x25, 0x92, 0x3e, 0x24, - 0x0d, 0x79, 0x61, 0x75, 0x28, 0xf2, 0xc2, 0xa2, 0x55, 0x0d, 0x5e, 0x47, 0x60, 0x52, 0xd8, 0x6e, - 0x8f, 0x10, 0x95, 0x9d, 0x49, 0xad, 0xac, 0x58, 0xc4, 0xbf, 0xa3, 0x89, 0x33, 0x1d, 0x1e, 0x74, - 0xa6, 0xbf, 0x20, 0xcd, 0x68, 0xa9, 0xf3, 0x75, 0x21, 0x74, 0x9e, 0x5b, 0xf0, 0x5f, 0x64, 0x75, - 0xe2, 0xdd, 0x8a, 0x67, 0xf4, 0x69, 0x68, 0xcf, 0xbc, 0x16, 0x78, 0xee, 0x3e, 0x21, 0xb5, 0x75, - 0xa6, 0x2e, 0x84, 0x59, 0xd1, 0xbb, 0xa4, 0xa2, 0xb2, 0x3c, 0x96, 0xf8, 0x4b, 0x9b, 0x3b, 0xa2, - 0xfb, 0xdf, 0x36, 0x69, 0xa0, 0x4f, 0xf3, 0xc2, 0x1a, 0xda, 0x25, 0x6d, 0x95, 0x86, 0x4b, 0x69, - 0x44, 0xac, 0xb4, 0x58, 0xc4, 0xc8, 0x5b, 0xe1, 0x4d, 0x07, 0x1e, 0x28, 0x3d, 0x8a, 0x37, 0x61, - 0x2a, 0x7f, 0x08, 0xd3, 0x53, 0xd2, 0x4e, 0x64, 0x78, 0x2e, 0x85, 0x5e, 0x67, 0x99, 0xca, 0x96, - 0x68, 0x6c, 0x9d, 0xb7, 0x10, 0xe4, 0x0e, 0xa3, 0x8f, 0x49, 0x13, 0xbc, 0xef, 0xb5, 0xc1, 0xa0, - 0xd6, 0x39, 0x38, 0xe8, 0x24, 0x53, 0x17, 0xb3, 0x15, 0xfd, 0x82, 0xdc, 0xb2, 0x51, 0x21, 0xa4, - 0xb1, 0xe1, 0x69, 0xa2, 0xcc, 0x99, 0x8c, 0x59, 0x05, 0x79, 0x3a, 0x36, 0x2a, 0x86, 0x1f, 0x50, - 0x60, 0x94, 0xe7, 0xa1, 0x51, 0xe7, 0x52, 0xc4, 0xf2, 0x5c, 0x45, 0xd2, 0xb0, 0xaa, 0x63, 0xf4, - 0xf0, 0x81, 0x43, 0xc1, 0xff, 0xe6, 0x4c, 0x26, 0x89, 0x78, 0x97, 0x9f, 0xb2, 0x1a, 0xb2, 0xd4, - 0x11, 0xf8, 0x47, 0x7e, 0x4a, 0x1f, 0x11, 0x02, 0x21, 0x13, 0x49, 0x1e, 0xad, 0x0c, 0xab, 0x3b, - 0x6d, 0x00, 0x39, 0x04, 0x80, 0x3e, 0x26, 0x8d, 0x24, 0x5f, 0x8a, 0x44, 0x9e, 0xcb, 0x84, 0x35, - 0xc0, 0xd4, 0xef, 0x4b, 0x7d, 0x5e, 0x4f, 0xf2, 0xe5, 0x21, 0x40, 0xf4, 0x01, 0x81, 0xb3, 0x8b, - 0x3a, 0x71, 0xa9, 0x9d, 0xe4, 0x4b, 0x0c, 0xfb, 0xe7, 0xa4, 0x5c, 0x18, 0xd6, 0xdc, 0x29, 0xed, - 0x35, 0xfb, 0xf7, 0x7b, 0xbf, 0x5b, 0x18, 0xbc, 0x5c, 0x18, 0xba, 0x4b, 0x3a, 0x59, 0x6e, 0xd5, - 0xe2, 0x52, 0x98, 0x48, 0xab, 0xc2, 0x1a, 0xd6, 0x42, 0x2d, 0xda, 0x0e, 0x9d, 0x39, 0x10, 0xa2, - 0x0a, 0x11, 0x67, 0x6d, 0x17, 0x69, 0x8c, 0xfe, 0x23, 0x42, 0x8a, 0x50, 0xcb, 0xcc, 0x0a, 0x95, - 0x2e, 0x59, 0x07, 0x6f, 0x1a, 0x0e, 0x19, 0xa7, 0x4b, 0x30, 0xdc, 0xea, 0x30, 0x5a, 0x89, 0x54, - 0xa6, 0xec, 0x96, 0x33, 0x1c, 0x81, 0x23, 0x99, 0x82, 0x6c, 0xb8, 0xb6, 0xb9, 0x88, 0x65, 0xbc, - 0x2e, 0x58, 0xe0, 0x0c, 0x07, 0xe4, 0x00, 0x00, 0x08, 0xd3, 0xcf, 0xb9, 0x5e, 0x6d, 0xe2, 0x7f, - 0x1b, 0xa3, 0xdc, 0x00, 0xc8, 0x45, 0xff, 0x11, 0x21, 0x89, 0xca, 0x56, 0x42, 0xcb, 0x34, 0x2c, - 0x18, 0x75, 0xe2, 0x80, 0x70, 0x00, 0xe8, 0x2e, 0xa9, 0x40, 0x71, 0x1a, 0x76, 0x67, 0x67, 0x6b, - 0xaf, 0xd9, 0xbf, 0xd5, 0xbb, 0x59, 0xaf, 0xdc, 0xdd, 0xd2, 0xa7, 0xa4, 0x16, 0x15, 0x6b, 0x11, - 0x85, 0x05, 0xbb, 0xbb, 0x53, 0xda, 0x6b, 0x7f, 0x4f, 0x9e, 0xf7, 0x5f, 0x3d, 0x7f, 0xf5, 0xdd, - 0xcb, 0xfe, 0xab, 0x17, 0xbc, 0x1a, 0x15, 0xeb, 0x41, 0x58, 0xd0, 0x27, 0xa4, 0xb9, 0xc8, 0x75, - 0x24, 0x85, 0xd2, 0xf0, 0xd7, 0x3d, 0xfc, 0x8b, 0x20, 0x34, 0x06, 0x04, 0x82, 0x20, 0x2f, 0x64, - 0x24, 0xa2, 0x34, 0x66, 0xf7, 0x77, 0xb6, 0x20, 0x08, 0x40, 0x0f, 0x52, 0x48, 0x92, 0x1a, 0xd6, - 0x7a, 0x66, 0xd9, 0xc7, 0xa8, 0x49, 0xa7, 0x77, 0xa3, 0xf6, 0x79, 0x55, 0x5e, 0xd8, 0xa3, 0xcc, - 0x42, 0x14, 0xd2, 0x30, 0x83, 0xf8, 0xb8, 0xf2, 0x32, 0x8c, 0xb9, 0x28, 0x38, 0x74, 0xe0, 0x40, - 0xba, 0x4b, 0x6a, 0xd1, 0x12, 0x4b, 0x8f, 0x3d, 0xc0, 0xf7, 0x5a, 0xbd, 0x6b, 0xe5, 0xc8, 0xab, - 0xd1, 0x92, 0x43, 0x60, 0x9e, 0x90, 0xa6, 0x36, 0x56, 0x18, 0x75, 0x9a, 0x40, 0x1d, 0x7c, 0xe2, - 0x54, 0xd6, 0xc6, 0xce, 0x1c, 0x42, 0xf7, 0xaf, 0x97, 0x3d, 0x7b, 0x88, 0x4f, 0x35, 0x7b, 0x1f, - 0x20, 0xde, 0xf0, 0xe7, 0x51, 0x4c, 0x77, 0x48, 0x0b, 0x23, 0xb5, 0x31, 0xe4, 0x4f, 0xee, 0x35, - 0xc0, 0x86, 0x4e, 0xf9, 0x27, 0xae, 0xa6, 0xcc, 0x59, 0xa8, 0xe1, 0xbb, 0x47, 0x8e, 0x41, 0x5e, - 0xd8, 0x99, 0x43, 0x36, 0x0c, 0x69, 0x68, 0xac, 0xd4, 0x86, 0x3d, 0xbe, 0x62, 0x38, 0x72, 0x08, - 0xb8, 0xd0, 0xac, 0x54, 0x81, 0xef, 0x3f, 0x71, 0x2e, 0x04, 0x1a, 0x1e, 0x87, 0xf6, 0x95, 0x85, - 0xa7, 0x89, 0x14, 0x0b, 0xc3, 0x76, 0xf0, 0xae, 0xee, 0x80, 0x91, 0xa1, 0x7b, 0xa4, 0xe9, 0x2b, - 0x59, 0xa8, 0x2c, 0x67, 0x9f, 0xa2, 0x21, 0xf5, 0x9e, 0xc7, 0x78, 0x63, 0x8d, 0x45, 0x3d, 0xce, - 0x72, 0xfa, 0x77, 0x72, 0xe7, 0xa6, 0x83, 0x45, 0x0a, 0x4d, 0xa8, 0xbb, 0x53, 0xda, 0xeb, 0xf4, - 0xdb, 0x2e, 0x3f, 0xa2, 0x25, 0x82, 0xfc, 0xf6, 0x0d, 0xa7, 0x1f, 0xe5, 0xb1, 0x84, 0x8f, 0x96, - 0x67, 0xb9, 0xb1, 0x22, 0x51, 0xa9, 0xb2, 0xec, 0x29, 0x66, 0x4b, 0xed, 0x9b, 0xaf, 0x9f, 0xff, - 0xf5, 0xc5, 0xcb, 0xef, 0x38, 0xc1, 0xbb, 0x43, 0xb8, 0xa2, 0x7b, 0x24, 0xc0, 0x44, 0x11, 0x26, - 0x0a, 0x33, 0x01, 0xdd, 0xcf, 0xb0, 0xcf, 0x50, 0xed, 0x0e, 0xe2, 0xb3, 0x28, 0xcc, 0xa6, 0x80, - 0xd2, 0x4f, 0x20, 0x6f, 0xac, 0xd4, 0x59, 0x98, 0xb0, 0x5d, 0x6f, 0x98, 0xa7, 0x31, 0xa7, 0xd2, - 0xc2, 0x5e, 0x8a, 0xcc, 0xb0, 0xcf, 0xe1, 0x33, 0x5e, 0x43, 0xfa, 0x18, 0x6c, 0xae, 0xb9, 0x51, - 0x60, 0xd8, 0x17, 0x3e, 0xbb, 0x6f, 0x8e, 0x06, 0x5e, 0x05, 0xfa, 0xd8, 0xd0, 0x4f, 0x49, 0xcb, - 0x67, 0x47, 0xa1, 0xf3, 0xc2, 0xb0, 0x3f, 0x63, 0x85, 0xfa, 0x06, 0x3e, 0x05, 0x88, 0xee, 0x93, - 0xdb, 0xd7, 0x59, 0x5c, 0x27, 0xd9, 0x47, 0xbe, 0x5b, 0xd7, 0xf8, 0xb0, 0xa3, 0x3c, 0x27, 0xf7, - 0x3d, 0x6f, 0xbc, 0x4e, 0x0b, 0x11, 0xe5, 0x99, 0xd5, 0x79, 0x92, 0x48, 0xcd, 0xbe, 0x44, 0xed, - 0xef, 0xba, 0xdb, 0x83, 0x75, 0x5a, 0x0c, 0xae, 0xee, 0xa0, 0x2b, 0x2f, 0xb4, 0x94, 0xef, 0x37, - 0x8e, 0x67, 0xcf, 0xf0, 0xf5, 0x96, 0x03, 0x9d, 0x8f, 0x61, 0x42, 0x5b, 0x95, 0x4a, 0x98, 0x95, - 0x7f, 0x71, 0xd6, 0x7a, 0x92, 0x7e, 0x49, 0x28, 0xf4, 0x63, 0xcc, 0x0e, 0x95, 0x89, 0x45, 0xa2, - 0x96, 0x67, 0x96, 0xf5, 0x30, 0x83, 0xa0, 0x53, 0xcf, 0x56, 0xaa, 0x18, 0x67, 0x23, 0x84, 0xc1, - 0xe0, 0x9f, 0x65, 0xb8, 0x12, 0xe6, 0xd2, 0x44, 0x36, 0x31, 0xec, 0x2b, 0x64, 0x6b, 0x02, 0x36, - 0x73, 0x10, 0x36, 0x8e, 0xf0, 0xfd, 0x25, 0xf6, 0x42, 0xc3, 0xbe, 0xf6, 0x8d, 0x23, 0x7c, 0x7f, - 0x39, 0x05, 0x00, 0x9b, 0xb5, 0x0d, 0xed, 0xda, 0x40, 0x5d, 0x7c, 0x83, 0x5d, 0xa7, 0xee, 0x80, - 0x51, 0x0c, 0xce, 0xca, 0x75, 0x71, 0x06, 0x61, 0xb5, 0xc6, 0x67, 0x33, 0xeb, 0x3b, 0x55, 0xdc, - 0xc5, 0xd4, 0x1a, 0x97, 0xd2, 0x90, 0xf2, 0x51, 0x9e, 0x2d, 0x94, 0x6f, 0xce, 0xdf, 0xa2, 0xd1, - 0xc4, 0x41, 0xe0, 0xcd, 0xee, 0x33, 0xbf, 0x44, 0xa0, 0x2f, 0xb5, 0x34, 0x05, 0xe4, 0x83, 0x96, - 0xc6, 0xe6, 0x5a, 0xc6, 0x38, 0x50, 0xeb, 0xfc, 0x8a, 0xee, 0xee, 0x92, 0xdb, 0xc8, 0xed, 0x01, - 0x27, 0xe0, 0x47, 0xa0, 0x1b, 0x8e, 0x70, 0xec, 0xbe, 0x24, 0x4d, 0x64, 0x73, 0xbd, 0x9b, 0xde, - 0x27, 0x55, 0xd7, 0xd4, 0xfd, 0x80, 0xf6, 0xd4, 0x6f, 0x67, 0x67, 0xf7, 0x47, 0xd2, 0x46, 0xc1, - 0x85, 0x0c, 0xed, 0x5a, 0x3b, 0x47, 0xa4, 0x32, 0x15, 0xd8, 0xaf, 0x37, 0xda, 0xa4, 0x32, 0x9d, - 0x03, 0xfd, 0x2b, 0x27, 0x96, 0x7f, 0xe5, 0xc4, 0xee, 0x2f, 0x25, 0x52, 0xf7, 0xda, 0xfe, 0x8b, - 0x76, 0xc9, 0xb6, 0xbd, 0x2c, 0xdc, 0xb8, 0xef, 0xf4, 0x3b, 0xbd, 0xcd, 0x85, 0x00, 0x94, 0xe3, - 0x1d, 0x7d, 0x4c, 0xb6, 0x61, 0xee, 0xe3, 0x4b, 0xcd, 0x3e, 0xe9, 0x5d, 0x6d, 0x02, 0x1c, 0xf1, - 0xeb, 0x33, 0x6a, 0x1d, 0x45, 0xb0, 0xc7, 0x6d, 0xdd, 0x98, 0x51, 0x0e, 0x04, 0x9d, 0x57, 0x52, - 0x16, 0x22, 0x2f, 0x64, 0xe6, 0x27, 0x7b, 0x1d, 0x80, 0x49, 0x21, 0x33, 0xba, 0x4f, 0xea, 0x1b, - 0xe3, 0x70, 0xa2, 0x37, 0x37, 0xba, 0x6c, 0x50, 0x7e, 0x75, 0xbf, 0xf1, 0x4f, 0x15, 0x53, 0x11, - 0xfd, 0xf3, 0xef, 0x2d, 0xbf, 0x9f, 0xa0, 0xe3, 0xff, 0x1f, 0x9b, 0x18, 0xa9, 0x6d, 0x94, 0x85, - 0x4d, 0xa8, 0xce, 0x37, 0x24, 0x7d, 0x4a, 0xb6, 0x21, 0xe8, 0x68, 0xc3, 0xd5, 0x6c, 0xba, 0x4a, - 0x03, 0x8e, 0x97, 0xf4, 0x19, 0xa9, 0xf9, 0x58, 0xa3, 0x25, 0xcd, 0x3e, 0xed, 0xfd, 0x26, 0x01, - 0xf8, 0x86, 0x85, 0x7e, 0x46, 0xaa, 0xce, 0x15, 0xde, 0xb4, 0x56, 0xef, 0x5a, 0x1a, 0x70, 0x7f, - 0xe7, 0x57, 0x82, 0xea, 0x1f, 0xae, 0x04, 0x0f, 0x20, 0x7c, 0x42, 0x6a, 0x9d, 0xe5, 0xb8, 0xb0, - 0x54, 0x78, 0x2d, 0xd2, 0x43, 0x20, 0x6f, 0x78, 0xb1, 0xfe, 0x07, 0x5e, 0x7c, 0x08, 0x2e, 0x83, - 0x67, 0x52, 0xb3, 0xc4, 0xe5, 0xa5, 0xc1, 0xeb, 0xf8, 0x4e, 0x6a, 0x96, 0x30, 0x19, 0xcf, 0xa5, - 0x36, 0x2a, 0xcf, 0x70, 0x71, 0x69, 0x6e, 0x7a, 0xb0, 0x07, 0xf9, 0xe6, 0x16, 0x73, 0x18, 0x0b, - 0x10, 0x77, 0x99, 0x0a, 0xf7, 0x54, 0xf7, 0x3f, 0x25, 0xd2, 0xba, 0x2e, 0x01, 0x8b, 0x65, 0x1a, - 0xbe, 0xcb, 0xb5, 0xaf, 0x07, 0x47, 0x20, 0xaa, 0xb2, 0x5c, 0xfb, 0x1d, 0xd6, 0x11, 0x80, 0x2e, - 0x95, 0xf5, 0x5b, 0x7e, 0x83, 0x3b, 0x02, 0x0a, 0xd0, 0xac, 0x4f, 0xdd, 0xb2, 0xb5, 0xed, 0x6b, - 0xdf, 0xd3, 0x20, 0x81, 0x4b, 0x33, 0x3a, 0xb8, 0xc2, 0x1d, 0x01, 0x5b, 0x11, 0xb4, 0x5d, 0xf4, - 0x69, 0x83, 0xe3, 0x79, 0x5f, 0x78, 0xbd, 0xfc, 0x34, 0xa1, 0x84, 0x54, 0xc7, 0x6f, 0x8e, 0x27, - 0x7c, 0x18, 0x7c, 0x44, 0x9b, 0xa4, 0x36, 0x78, 0x23, 0x8e, 0x27, 0xc7, 0xc3, 0xa0, 0x44, 0x1b, - 0xa4, 0x32, 0xe5, 0x93, 0xe9, 0x2c, 0x28, 0xd3, 0x3a, 0xd9, 0x9e, 0x4d, 0x46, 0xf3, 0x60, 0x0b, - 0x4e, 0xa3, 0x93, 0xc3, 0xc3, 0x60, 0x1b, 0xe4, 0x66, 0x73, 0x3e, 0x1e, 0xcc, 0x83, 0x0a, 0xc8, - 0x1d, 0x0c, 0x47, 0xaf, 0x4f, 0x0e, 0xe7, 0x41, 0x75, 0xff, 0x97, 0x92, 0x2f, 0xd6, 0x4d, 0xc6, - 0xc1, 0x4b, 0xc3, 0xa3, 0xe9, 0xfc, 0xa7, 0xe0, 0x23, 0x90, 0x3f, 0x38, 0x39, 0x9a, 0x06, 0x25, - 0x90, 0xe1, 0xc3, 0xd9, 0x1c, 0x3e, 0x2e, 0x03, 0xc7, 0xe0, 0x87, 0xe1, 0xe0, 0xc7, 0x60, 0x8b, - 0xb6, 0x48, 0x7d, 0xca, 0x87, 0x02, 0xb9, 0xb6, 0xe9, 0x2d, 0xd2, 0x9c, 0xbe, 0x7e, 0x33, 0x14, - 0xb3, 0x21, 0x7f, 0x3b, 0xe4, 0x41, 0x05, 0xbe, 0x3d, 0x9e, 0xcc, 0xc7, 0xa3, 0x9f, 0x82, 0x2a, - 0x0d, 0x48, 0x6b, 0x30, 0x3d, 0x19, 0x1f, 0x8f, 0x26, 0x8e, 0xbd, 0x46, 0x6f, 0x93, 0xf6, 0x06, - 0x71, 0xef, 0xd5, 0x01, 0x1a, 0x0d, 0x5f, 0xcf, 0x4f, 0xf8, 0xd0, 0x43, 0x0d, 0xf8, 0xfa, 0xed, - 0x90, 0xcf, 0xc6, 0x93, 0xe3, 0x80, 0xc0, 0x7f, 0xff, 0x7c, 0x3d, 0x9e, 0x8b, 0xe9, 0xf8, 0x20, - 0x68, 0xd2, 0xbb, 0x24, 0xb8, 0xf6, 0x9f, 0x18, 0xfc, 0x70, 0x78, 0x10, 0xb4, 0xfe, 0x17, 0x00, - 0x00, 0xff, 0xff, 0xf8, 0x9f, 0x0e, 0x7d, 0xca, 0x0d, 0x00, 0x00, -} diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/.gitignore b/vendor/github.com/checkpoint-restore/go-criu/v5/.gitignore new file mode 100644 index 000000000..6c7385fa2 --- /dev/null +++ b/vendor/github.com/checkpoint-restore/go-criu/v5/.gitignore @@ -0,0 +1,5 @@ +test/test +test/piggie/piggie +test/phaul +image +stats/stats.proto diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/.golangci.yml b/vendor/github.com/checkpoint-restore/go-criu/v5/.golangci.yml new file mode 100644 index 000000000..fbbac4b41 --- /dev/null +++ b/vendor/github.com/checkpoint-restore/go-criu/v5/.golangci.yml @@ -0,0 +1,12 @@ +run: + skip_dirs: + - rpc + - stats + +linters: + disable-all: false + presets: + - bugs + - performance + - unused + - format diff --git a/vendor/github.com/checkpoint-restore/go-criu/LICENSE b/vendor/github.com/checkpoint-restore/go-criu/v5/LICENSE index 8dada3eda..8dada3eda 100644 --- a/vendor/github.com/checkpoint-restore/go-criu/LICENSE +++ b/vendor/github.com/checkpoint-restore/go-criu/v5/LICENSE diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/Makefile b/vendor/github.com/checkpoint-restore/go-criu/v5/Makefile new file mode 100644 index 000000000..a5c5f5542 --- /dev/null +++ b/vendor/github.com/checkpoint-restore/go-criu/v5/Makefile @@ -0,0 +1,62 @@ +GO ?= go +CC ?= gcc + +all: build test phaul-test + +lint: + golangci-lint run ./... + +build: + $(GO) build -v ./... + +TEST_BINARIES := test/test test/piggie/piggie test/phaul/phaul +test-bin: $(TEST_BINARIES) + +test/piggie/piggie: test/piggie/piggie.c + $(CC) $^ -o $@ + +test/test: test/*.go + $(GO) build -v -o $@ $^ + +test: $(TEST_BINARIES) + mkdir -p image + PID=$$(test/piggie/piggie) && { \ + test/test dump $$PID image && \ + test/test restore image; \ + pkill -9 piggie; \ + } + rm -rf image + +test/phaul/phaul: test/phaul/*.go + $(GO) build -v -o $@ $^ + +phaul-test: $(TEST_BINARIES) + rm -rf image + PID=$$(test/piggie/piggie) && { \ + test/phaul/phaul $$PID; \ + pkill -9 piggie; \ + } + +clean: + @rm -f $(TEST_BINARIES) + @rm -rf image + @rm -f rpc/rpc.proto stats/stats.proto + +rpc/rpc.proto: + curl -sSL https://raw.githubusercontent.com/checkpoint-restore/criu/master/images/rpc.proto -o $@ + +stats/stats.proto: + curl -sSL https://raw.githubusercontent.com/checkpoint-restore/criu/master/images/stats.proto -o $@ + +rpc/rpc.pb.go: rpc/rpc.proto + protoc --go_out=. --go_opt=Mrpc/rpc.proto=rpc/ $^ + +stats/stats.pb.go: stats/stats.proto + protoc --go_out=. $^ + +vendor: + GO111MODULE=on $(GO) mod tidy + GO111MODULE=on $(GO) mod vendor + GO111MODULE=on $(GO) mod verify + +.PHONY: build test phaul-test test-bin clean lint vendor diff --git a/vendor/github.com/checkpoint-restore/go-criu/README.md b/vendor/github.com/checkpoint-restore/go-criu/v5/README.md index 539627324..390da3e98 100644 --- a/vendor/github.com/checkpoint-restore/go-criu/README.md +++ b/vendor/github.com/checkpoint-restore/go-criu/v5/README.md @@ -1,8 +1,10 @@ -[![master](https://travis-ci.org/checkpoint-restore/go-criu.svg?branch=master)](https://travis-ci.org/checkpoint-restore/go-criu) +[![test](https://github.com/checkpoint-restore/go-criu/workflows/ci/badge.svg?branch=master)](https://github.com/checkpoint-restore/go-criu/actions?query=workflow%3Aci) +[![verify](https://github.com/checkpoint-restore/go-criu/workflows/verify/badge.svg?branch=master)](https://github.com/checkpoint-restore/go-criu/actions?query=workflow%3Averify) +[![Go Reference](https://pkg.go.dev/badge/github.com/checkpoint-restore/go-criu.svg)](https://pkg.go.dev/github.com/checkpoint-restore/go-criu) -## go-criu -- Go bindings for [CRIU](https://criu.org/) +## go-criu -- Go bindings for CRIU -This repository provides Go bindings for CRIU. The code is based on the Go based PHaul +This repository provides Go bindings for [CRIU](https://criu.org/). The code is based on the Go-based PHaul implementation from the CRIU repository. For easier inclusion into other Go projects the CRIU Go bindings have been moved to this repository. @@ -10,24 +12,46 @@ The Go bindings provide an easy way to use the CRIU RPC calls from Go without th to set up all the infrastructure to make the actual RPC connection to CRIU. The following example would print the version of CRIU: -``` +```go +import ( + "log" + + "github.com/checkpoint/restore/go-criu/v5" +) + +func main() { c := criu.MakeCriu() version, err := c.GetCriuVersion() - fmt.Println(version) + if err != nil { + log.Fatalln(err) + } + log.Println(version) +} ``` + or to just check if at least a certain CRIU version is installed: -``` + +```go c := criu.MakeCriu() result, err := c.IsCriuAtLeast(31100) ``` ## Releases -go-criu will carry the same version number as CRIU. This implies that each -go-criu release will pull in the necessary changes from CRIU before making a -release. +The first go-criu release was 3.11 based on CRIU 3.11. The initial plan +was to follow CRIU so that go-criu would carry the same version number as +CRIU. + +As go-criu is imported in other projects and as Go modules are expected +to follow Semantic Versioning go-criu will also follow Semantic Versioning +starting with the 4.0.0 release. -The first go-criu release was 3.11 based on CRIU 3.11. +The following table shows the relation between go-criu and criu versions: + +| Major version | Latest release | CRIU version | +| -------------- | -------------- | ------------ | +| v5 | 5.0.0 | 3.15 | +| v4 | 4.1.0 | 3.14 | ## How to contribute @@ -61,6 +85,11 @@ by adding a "Signed-off-by" line containing the contributor's name and e-mail to every commit message. Your signature certifies that you wrote the patch or otherwise have the right to pass it on as an open-source patch. -### License +### License and copyright + +Unless mentioned otherwise in a specific file's header, all code in +this project is released under the Apache 2.0 license. -The license of go-criu is the Apache 2.0 license. +The author of a change remains the copyright holder of their code +(no copyright assignment). The list of authors and contributors can be +retrieved from the git commit history and in some cases, the file headers. diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/go.mod b/vendor/github.com/checkpoint-restore/go-criu/v5/go.mod new file mode 100644 index 000000000..69595701f --- /dev/null +++ b/vendor/github.com/checkpoint-restore/go-criu/v5/go.mod @@ -0,0 +1,9 @@ +module github.com/checkpoint-restore/go-criu/v5 + +go 1.13 + +require ( + github.com/golang/protobuf v1.5.2 + golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c + google.golang.org/protobuf v1.26.0 +) diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/go.sum b/vendor/github.com/checkpoint-restore/go-criu/v5/go.sum new file mode 100644 index 000000000..7e17df214 --- /dev/null +++ b/vendor/github.com/checkpoint-restore/go-criu/v5/go.sum @@ -0,0 +1,12 @@ +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= diff --git a/vendor/github.com/checkpoint-restore/go-criu/main.go b/vendor/github.com/checkpoint-restore/go-criu/v5/main.go index cf94c376e..78811c309 100644 --- a/vendor/github.com/checkpoint-restore/go-criu/main.go +++ b/vendor/github.com/checkpoint-restore/go-criu/v5/main.go @@ -8,19 +8,28 @@ import ( "strconv" "syscall" - "github.com/checkpoint-restore/go-criu/rpc" - "github.com/golang/protobuf/proto" + "github.com/checkpoint-restore/go-criu/v5/rpc" + "google.golang.org/protobuf/proto" ) // Criu struct type Criu struct { - swrkCmd *exec.Cmd - swrkSk *os.File + swrkCmd *exec.Cmd + swrkSk *os.File + swrkPath string } // MakeCriu returns the Criu object required for most operations func MakeCriu() *Criu { - return &Criu{} + return &Criu{ + swrkPath: "criu", + } +} + +// SetCriuPath allows setting the path to the CRIU binary +// if it is in a non standard location +func (c *Criu) SetCriuPath(path string) { + c.swrkPath = path } // Prepare sets up everything for the RPC communication to CRIU @@ -36,7 +45,8 @@ func (c *Criu) Prepare() error { defer srv.Close() args := []string{"swrk", strconv.Itoa(fds[1])} - cmd := exec.Command("criu", args...) + // #nosec G204 + cmd := exec.Command(c.swrkPath, args...) err = cmd.Start() if err != nil { @@ -55,7 +65,7 @@ func (c *Criu) Cleanup() { if c.swrkCmd != nil { c.swrkSk.Close() c.swrkSk = nil - c.swrkCmd.Wait() + _ = c.swrkCmd.Wait() c.swrkCmd = nil } } @@ -178,28 +188,28 @@ func (c *Criu) doSwrkWithResp(reqType rpc.CriuReqType, opts *rpc.CriuOpts, nfy N } // Dump dumps a process -func (c *Criu) Dump(opts rpc.CriuOpts, nfy Notify) error { - return c.doSwrk(rpc.CriuReqType_DUMP, &opts, nfy) +func (c *Criu) Dump(opts *rpc.CriuOpts, nfy Notify) error { + return c.doSwrk(rpc.CriuReqType_DUMP, opts, nfy) } // Restore restores a process -func (c *Criu) Restore(opts rpc.CriuOpts, nfy Notify) error { - return c.doSwrk(rpc.CriuReqType_RESTORE, &opts, nfy) +func (c *Criu) Restore(opts *rpc.CriuOpts, nfy Notify) error { + return c.doSwrk(rpc.CriuReqType_RESTORE, opts, nfy) } // PreDump does a pre-dump -func (c *Criu) PreDump(opts rpc.CriuOpts, nfy Notify) error { - return c.doSwrk(rpc.CriuReqType_PRE_DUMP, &opts, nfy) +func (c *Criu) PreDump(opts *rpc.CriuOpts, nfy Notify) error { + return c.doSwrk(rpc.CriuReqType_PRE_DUMP, opts, nfy) } // StartPageServer starts the page server -func (c *Criu) StartPageServer(opts rpc.CriuOpts) error { - return c.doSwrk(rpc.CriuReqType_PAGE_SERVER, &opts, nil) +func (c *Criu) StartPageServer(opts *rpc.CriuOpts) error { + return c.doSwrk(rpc.CriuReqType_PAGE_SERVER, opts, nil) } // StartPageServerChld starts the page server and returns PID and port -func (c *Criu) StartPageServerChld(opts rpc.CriuOpts) (int, int, error) { - resp, err := c.doSwrkWithResp(rpc.CriuReqType_PAGE_SERVER_CHLD, &opts, nil) +func (c *Criu) StartPageServerChld(opts *rpc.CriuOpts) (int, int, error) { + resp, err := c.doSwrkWithResp(rpc.CriuReqType_PAGE_SERVER_CHLD, opts, nil) if err != nil { return 0, 0, err } @@ -219,8 +229,8 @@ func (c *Criu) GetCriuVersion() (int, error) { return 0, fmt.Errorf("Unexpected CRIU RPC response") } - version := int(*resp.GetVersion().Major) * 10000 - version += int(*resp.GetVersion().Minor) * 100 + version := int(*resp.GetVersion().MajorNumber) * 10000 + version += int(*resp.GetVersion().MinorNumber) * 100 if resp.GetVersion().Sublevel != nil { version += int(*resp.GetVersion().Sublevel) } diff --git a/vendor/github.com/checkpoint-restore/go-criu/notify.go b/vendor/github.com/checkpoint-restore/go-criu/v5/notify.go index 1c8547b43..a177f2bb5 100644 --- a/vendor/github.com/checkpoint-restore/go-criu/notify.go +++ b/vendor/github.com/checkpoint-restore/go-criu/v5/notify.go @@ -1,6 +1,6 @@ package criu -//Notify interface +// Notify interface type Notify interface { PreDump() error PostDump() error @@ -14,8 +14,7 @@ type Notify interface { } // NoNotify struct -type NoNotify struct { -} +type NoNotify struct{} // PreDump NoNotify func (c NoNotify) PreDump() error { diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.pb.go b/vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.pb.go new file mode 100644 index 000000000..9f22f1539 --- /dev/null +++ b/vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.pb.go @@ -0,0 +1,2237 @@ +// SPDX-License-Identifier: MIT + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.14.0 +// source: rpc/rpc.proto + +package rpc + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type CriuCgMode int32 + +const ( + CriuCgMode_IGNORE CriuCgMode = 0 + CriuCgMode_CG_NONE CriuCgMode = 1 + CriuCgMode_PROPS CriuCgMode = 2 + CriuCgMode_SOFT CriuCgMode = 3 + CriuCgMode_FULL CriuCgMode = 4 + CriuCgMode_STRICT CriuCgMode = 5 + CriuCgMode_DEFAULT CriuCgMode = 6 +) + +// Enum value maps for CriuCgMode. +var ( + CriuCgMode_name = map[int32]string{ + 0: "IGNORE", + 1: "CG_NONE", + 2: "PROPS", + 3: "SOFT", + 4: "FULL", + 5: "STRICT", + 6: "DEFAULT", + } + CriuCgMode_value = map[string]int32{ + "IGNORE": 0, + "CG_NONE": 1, + "PROPS": 2, + "SOFT": 3, + "FULL": 4, + "STRICT": 5, + "DEFAULT": 6, + } +) + +func (x CriuCgMode) Enum() *CriuCgMode { + p := new(CriuCgMode) + *p = x + return p +} + +func (x CriuCgMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CriuCgMode) Descriptor() protoreflect.EnumDescriptor { + return file_rpc_rpc_proto_enumTypes[0].Descriptor() +} + +func (CriuCgMode) Type() protoreflect.EnumType { + return &file_rpc_rpc_proto_enumTypes[0] +} + +func (x CriuCgMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *CriuCgMode) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = CriuCgMode(num) + return nil +} + +// Deprecated: Use CriuCgMode.Descriptor instead. +func (CriuCgMode) EnumDescriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{0} +} + +type CriuPreDumpMode int32 + +const ( + CriuPreDumpMode_SPLICE CriuPreDumpMode = 1 + CriuPreDumpMode_VM_READ CriuPreDumpMode = 2 +) + +// Enum value maps for CriuPreDumpMode. +var ( + CriuPreDumpMode_name = map[int32]string{ + 1: "SPLICE", + 2: "VM_READ", + } + CriuPreDumpMode_value = map[string]int32{ + "SPLICE": 1, + "VM_READ": 2, + } +) + +func (x CriuPreDumpMode) Enum() *CriuPreDumpMode { + p := new(CriuPreDumpMode) + *p = x + return p +} + +func (x CriuPreDumpMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CriuPreDumpMode) Descriptor() protoreflect.EnumDescriptor { + return file_rpc_rpc_proto_enumTypes[1].Descriptor() +} + +func (CriuPreDumpMode) Type() protoreflect.EnumType { + return &file_rpc_rpc_proto_enumTypes[1] +} + +func (x CriuPreDumpMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *CriuPreDumpMode) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = CriuPreDumpMode(num) + return nil +} + +// Deprecated: Use CriuPreDumpMode.Descriptor instead. +func (CriuPreDumpMode) EnumDescriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{1} +} + +type CriuReqType int32 + +const ( + CriuReqType_EMPTY CriuReqType = 0 + CriuReqType_DUMP CriuReqType = 1 + CriuReqType_RESTORE CriuReqType = 2 + CriuReqType_CHECK CriuReqType = 3 + CriuReqType_PRE_DUMP CriuReqType = 4 + CriuReqType_PAGE_SERVER CriuReqType = 5 + CriuReqType_NOTIFY CriuReqType = 6 + CriuReqType_CPUINFO_DUMP CriuReqType = 7 + CriuReqType_CPUINFO_CHECK CriuReqType = 8 + CriuReqType_FEATURE_CHECK CriuReqType = 9 + CriuReqType_VERSION CriuReqType = 10 + CriuReqType_WAIT_PID CriuReqType = 11 + CriuReqType_PAGE_SERVER_CHLD CriuReqType = 12 +) + +// Enum value maps for CriuReqType. +var ( + CriuReqType_name = map[int32]string{ + 0: "EMPTY", + 1: "DUMP", + 2: "RESTORE", + 3: "CHECK", + 4: "PRE_DUMP", + 5: "PAGE_SERVER", + 6: "NOTIFY", + 7: "CPUINFO_DUMP", + 8: "CPUINFO_CHECK", + 9: "FEATURE_CHECK", + 10: "VERSION", + 11: "WAIT_PID", + 12: "PAGE_SERVER_CHLD", + } + CriuReqType_value = map[string]int32{ + "EMPTY": 0, + "DUMP": 1, + "RESTORE": 2, + "CHECK": 3, + "PRE_DUMP": 4, + "PAGE_SERVER": 5, + "NOTIFY": 6, + "CPUINFO_DUMP": 7, + "CPUINFO_CHECK": 8, + "FEATURE_CHECK": 9, + "VERSION": 10, + "WAIT_PID": 11, + "PAGE_SERVER_CHLD": 12, + } +) + +func (x CriuReqType) Enum() *CriuReqType { + p := new(CriuReqType) + *p = x + return p +} + +func (x CriuReqType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CriuReqType) Descriptor() protoreflect.EnumDescriptor { + return file_rpc_rpc_proto_enumTypes[2].Descriptor() +} + +func (CriuReqType) Type() protoreflect.EnumType { + return &file_rpc_rpc_proto_enumTypes[2] +} + +func (x CriuReqType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *CriuReqType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = CriuReqType(num) + return nil +} + +// Deprecated: Use CriuReqType.Descriptor instead. +func (CriuReqType) EnumDescriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{2} +} + +type CriuPageServerInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` + Port *int32 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"` + Pid *int32 `protobuf:"varint,3,opt,name=pid" json:"pid,omitempty"` + Fd *int32 `protobuf:"varint,4,opt,name=fd" json:"fd,omitempty"` +} + +func (x *CriuPageServerInfo) Reset() { + *x = CriuPageServerInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CriuPageServerInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CriuPageServerInfo) ProtoMessage() {} + +func (x *CriuPageServerInfo) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CriuPageServerInfo.ProtoReflect.Descriptor instead. +func (*CriuPageServerInfo) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{0} +} + +func (x *CriuPageServerInfo) GetAddress() string { + if x != nil && x.Address != nil { + return *x.Address + } + return "" +} + +func (x *CriuPageServerInfo) GetPort() int32 { + if x != nil && x.Port != nil { + return *x.Port + } + return 0 +} + +func (x *CriuPageServerInfo) GetPid() int32 { + if x != nil && x.Pid != nil { + return *x.Pid + } + return 0 +} + +func (x *CriuPageServerInfo) GetFd() int32 { + if x != nil && x.Fd != nil { + return *x.Fd + } + return 0 +} + +type CriuVethPair struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IfIn *string `protobuf:"bytes,1,req,name=if_in,json=ifIn" json:"if_in,omitempty"` + IfOut *string `protobuf:"bytes,2,req,name=if_out,json=ifOut" json:"if_out,omitempty"` +} + +func (x *CriuVethPair) Reset() { + *x = CriuVethPair{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CriuVethPair) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CriuVethPair) ProtoMessage() {} + +func (x *CriuVethPair) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CriuVethPair.ProtoReflect.Descriptor instead. +func (*CriuVethPair) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{1} +} + +func (x *CriuVethPair) GetIfIn() string { + if x != nil && x.IfIn != nil { + return *x.IfIn + } + return "" +} + +func (x *CriuVethPair) GetIfOut() string { + if x != nil && x.IfOut != nil { + return *x.IfOut + } + return "" +} + +type ExtMountMap struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"` + Val *string `protobuf:"bytes,2,req,name=val" json:"val,omitempty"` +} + +func (x *ExtMountMap) Reset() { + *x = ExtMountMap{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExtMountMap) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtMountMap) ProtoMessage() {} + +func (x *ExtMountMap) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtMountMap.ProtoReflect.Descriptor instead. +func (*ExtMountMap) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{2} +} + +func (x *ExtMountMap) GetKey() string { + if x != nil && x.Key != nil { + return *x.Key + } + return "" +} + +func (x *ExtMountMap) GetVal() string { + if x != nil && x.Val != nil { + return *x.Val + } + return "" +} + +type JoinNamespace struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ns *string `protobuf:"bytes,1,req,name=ns" json:"ns,omitempty"` + NsFile *string `protobuf:"bytes,2,req,name=ns_file,json=nsFile" json:"ns_file,omitempty"` + ExtraOpt *string `protobuf:"bytes,3,opt,name=extra_opt,json=extraOpt" json:"extra_opt,omitempty"` +} + +func (x *JoinNamespace) Reset() { + *x = JoinNamespace{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *JoinNamespace) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JoinNamespace) ProtoMessage() {} + +func (x *JoinNamespace) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JoinNamespace.ProtoReflect.Descriptor instead. +func (*JoinNamespace) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{3} +} + +func (x *JoinNamespace) GetNs() string { + if x != nil && x.Ns != nil { + return *x.Ns + } + return "" +} + +func (x *JoinNamespace) GetNsFile() string { + if x != nil && x.NsFile != nil { + return *x.NsFile + } + return "" +} + +func (x *JoinNamespace) GetExtraOpt() string { + if x != nil && x.ExtraOpt != nil { + return *x.ExtraOpt + } + return "" +} + +type InheritFd struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"` + Fd *int32 `protobuf:"varint,2,req,name=fd" json:"fd,omitempty"` +} + +func (x *InheritFd) Reset() { + *x = InheritFd{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InheritFd) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InheritFd) ProtoMessage() {} + +func (x *InheritFd) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InheritFd.ProtoReflect.Descriptor instead. +func (*InheritFd) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{4} +} + +func (x *InheritFd) GetKey() string { + if x != nil && x.Key != nil { + return *x.Key + } + return "" +} + +func (x *InheritFd) GetFd() int32 { + if x != nil && x.Fd != nil { + return *x.Fd + } + return 0 +} + +type CgroupRoot struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ctrl *string `protobuf:"bytes,1,opt,name=ctrl" json:"ctrl,omitempty"` + Path *string `protobuf:"bytes,2,req,name=path" json:"path,omitempty"` +} + +func (x *CgroupRoot) Reset() { + *x = CgroupRoot{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CgroupRoot) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CgroupRoot) ProtoMessage() {} + +func (x *CgroupRoot) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CgroupRoot.ProtoReflect.Descriptor instead. +func (*CgroupRoot) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{5} +} + +func (x *CgroupRoot) GetCtrl() string { + if x != nil && x.Ctrl != nil { + return *x.Ctrl + } + return "" +} + +func (x *CgroupRoot) GetPath() string { + if x != nil && x.Path != nil { + return *x.Path + } + return "" +} + +type UnixSk struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Inode *uint32 `protobuf:"varint,1,req,name=inode" json:"inode,omitempty"` +} + +func (x *UnixSk) Reset() { + *x = UnixSk{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnixSk) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnixSk) ProtoMessage() {} + +func (x *UnixSk) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnixSk.ProtoReflect.Descriptor instead. +func (*UnixSk) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{6} +} + +func (x *UnixSk) GetInode() uint32 { + if x != nil && x.Inode != nil { + return *x.Inode + } + return 0 +} + +type CriuOpts struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ImagesDirFd *int32 `protobuf:"varint,1,req,name=images_dir_fd,json=imagesDirFd" json:"images_dir_fd,omitempty"` + Pid *int32 `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"` // if not set on dump, will dump requesting process + LeaveRunning *bool `protobuf:"varint,3,opt,name=leave_running,json=leaveRunning" json:"leave_running,omitempty"` + ExtUnixSk *bool `protobuf:"varint,4,opt,name=ext_unix_sk,json=extUnixSk" json:"ext_unix_sk,omitempty"` + TcpEstablished *bool `protobuf:"varint,5,opt,name=tcp_established,json=tcpEstablished" json:"tcp_established,omitempty"` + EvasiveDevices *bool `protobuf:"varint,6,opt,name=evasive_devices,json=evasiveDevices" json:"evasive_devices,omitempty"` + ShellJob *bool `protobuf:"varint,7,opt,name=shell_job,json=shellJob" json:"shell_job,omitempty"` + FileLocks *bool `protobuf:"varint,8,opt,name=file_locks,json=fileLocks" json:"file_locks,omitempty"` + LogLevel *int32 `protobuf:"varint,9,opt,name=log_level,json=logLevel,def=2" json:"log_level,omitempty"` + LogFile *string `protobuf:"bytes,10,opt,name=log_file,json=logFile" json:"log_file,omitempty"` // No subdirs are allowed. Consider using work-dir + Ps *CriuPageServerInfo `protobuf:"bytes,11,opt,name=ps" json:"ps,omitempty"` + NotifyScripts *bool `protobuf:"varint,12,opt,name=notify_scripts,json=notifyScripts" json:"notify_scripts,omitempty"` + Root *string `protobuf:"bytes,13,opt,name=root" json:"root,omitempty"` + ParentImg *string `protobuf:"bytes,14,opt,name=parent_img,json=parentImg" json:"parent_img,omitempty"` + TrackMem *bool `protobuf:"varint,15,opt,name=track_mem,json=trackMem" json:"track_mem,omitempty"` + AutoDedup *bool `protobuf:"varint,16,opt,name=auto_dedup,json=autoDedup" json:"auto_dedup,omitempty"` + WorkDirFd *int32 `protobuf:"varint,17,opt,name=work_dir_fd,json=workDirFd" json:"work_dir_fd,omitempty"` + LinkRemap *bool `protobuf:"varint,18,opt,name=link_remap,json=linkRemap" json:"link_remap,omitempty"` + Veths []*CriuVethPair `protobuf:"bytes,19,rep,name=veths" json:"veths,omitempty"` // DEPRECATED, use external instead + CpuCap *uint32 `protobuf:"varint,20,opt,name=cpu_cap,json=cpuCap,def=4294967295" json:"cpu_cap,omitempty"` + ForceIrmap *bool `protobuf:"varint,21,opt,name=force_irmap,json=forceIrmap" json:"force_irmap,omitempty"` + ExecCmd []string `protobuf:"bytes,22,rep,name=exec_cmd,json=execCmd" json:"exec_cmd,omitempty"` + ExtMnt []*ExtMountMap `protobuf:"bytes,23,rep,name=ext_mnt,json=extMnt" json:"ext_mnt,omitempty"` // DEPRECATED, use external instead + ManageCgroups *bool `protobuf:"varint,24,opt,name=manage_cgroups,json=manageCgroups" json:"manage_cgroups,omitempty"` // backward compatibility + CgRoot []*CgroupRoot `protobuf:"bytes,25,rep,name=cg_root,json=cgRoot" json:"cg_root,omitempty"` + RstSibling *bool `protobuf:"varint,26,opt,name=rst_sibling,json=rstSibling" json:"rst_sibling,omitempty"` // swrk only + InheritFd []*InheritFd `protobuf:"bytes,27,rep,name=inherit_fd,json=inheritFd" json:"inherit_fd,omitempty"` // swrk only + AutoExtMnt *bool `protobuf:"varint,28,opt,name=auto_ext_mnt,json=autoExtMnt" json:"auto_ext_mnt,omitempty"` + ExtSharing *bool `protobuf:"varint,29,opt,name=ext_sharing,json=extSharing" json:"ext_sharing,omitempty"` + ExtMasters *bool `protobuf:"varint,30,opt,name=ext_masters,json=extMasters" json:"ext_masters,omitempty"` + SkipMnt []string `protobuf:"bytes,31,rep,name=skip_mnt,json=skipMnt" json:"skip_mnt,omitempty"` + EnableFs []string `protobuf:"bytes,32,rep,name=enable_fs,json=enableFs" json:"enable_fs,omitempty"` + UnixSkIno []*UnixSk `protobuf:"bytes,33,rep,name=unix_sk_ino,json=unixSkIno" json:"unix_sk_ino,omitempty"` // DEPRECATED, use external instead + ManageCgroupsMode *CriuCgMode `protobuf:"varint,34,opt,name=manage_cgroups_mode,json=manageCgroupsMode,enum=CriuCgMode" json:"manage_cgroups_mode,omitempty"` + GhostLimit *uint32 `protobuf:"varint,35,opt,name=ghost_limit,json=ghostLimit,def=1048576" json:"ghost_limit,omitempty"` + IrmapScanPaths []string `protobuf:"bytes,36,rep,name=irmap_scan_paths,json=irmapScanPaths" json:"irmap_scan_paths,omitempty"` + External []string `protobuf:"bytes,37,rep,name=external" json:"external,omitempty"` + EmptyNs *uint32 `protobuf:"varint,38,opt,name=empty_ns,json=emptyNs" json:"empty_ns,omitempty"` + JoinNs []*JoinNamespace `protobuf:"bytes,39,rep,name=join_ns,json=joinNs" json:"join_ns,omitempty"` + CgroupProps *string `protobuf:"bytes,41,opt,name=cgroup_props,json=cgroupProps" json:"cgroup_props,omitempty"` + CgroupPropsFile *string `protobuf:"bytes,42,opt,name=cgroup_props_file,json=cgroupPropsFile" json:"cgroup_props_file,omitempty"` + CgroupDumpController []string `protobuf:"bytes,43,rep,name=cgroup_dump_controller,json=cgroupDumpController" json:"cgroup_dump_controller,omitempty"` + FreezeCgroup *string `protobuf:"bytes,44,opt,name=freeze_cgroup,json=freezeCgroup" json:"freeze_cgroup,omitempty"` + Timeout *uint32 `protobuf:"varint,45,opt,name=timeout" json:"timeout,omitempty"` + TcpSkipInFlight *bool `protobuf:"varint,46,opt,name=tcp_skip_in_flight,json=tcpSkipInFlight" json:"tcp_skip_in_flight,omitempty"` + WeakSysctls *bool `protobuf:"varint,47,opt,name=weak_sysctls,json=weakSysctls" json:"weak_sysctls,omitempty"` + LazyPages *bool `protobuf:"varint,48,opt,name=lazy_pages,json=lazyPages" json:"lazy_pages,omitempty"` + StatusFd *int32 `protobuf:"varint,49,opt,name=status_fd,json=statusFd" json:"status_fd,omitempty"` + OrphanPtsMaster *bool `protobuf:"varint,50,opt,name=orphan_pts_master,json=orphanPtsMaster" json:"orphan_pts_master,omitempty"` + ConfigFile *string `protobuf:"bytes,51,opt,name=config_file,json=configFile" json:"config_file,omitempty"` + TcpClose *bool `protobuf:"varint,52,opt,name=tcp_close,json=tcpClose" json:"tcp_close,omitempty"` + LsmProfile *string `protobuf:"bytes,53,opt,name=lsm_profile,json=lsmProfile" json:"lsm_profile,omitempty"` + TlsCacert *string `protobuf:"bytes,54,opt,name=tls_cacert,json=tlsCacert" json:"tls_cacert,omitempty"` + TlsCacrl *string `protobuf:"bytes,55,opt,name=tls_cacrl,json=tlsCacrl" json:"tls_cacrl,omitempty"` + TlsCert *string `protobuf:"bytes,56,opt,name=tls_cert,json=tlsCert" json:"tls_cert,omitempty"` + TlsKey *string `protobuf:"bytes,57,opt,name=tls_key,json=tlsKey" json:"tls_key,omitempty"` + Tls *bool `protobuf:"varint,58,opt,name=tls" json:"tls,omitempty"` + TlsNoCnVerify *bool `protobuf:"varint,59,opt,name=tls_no_cn_verify,json=tlsNoCnVerify" json:"tls_no_cn_verify,omitempty"` + CgroupYard *string `protobuf:"bytes,60,opt,name=cgroup_yard,json=cgroupYard" json:"cgroup_yard,omitempty"` + PreDumpMode *CriuPreDumpMode `protobuf:"varint,61,opt,name=pre_dump_mode,json=preDumpMode,enum=CriuPreDumpMode,def=1" json:"pre_dump_mode,omitempty"` + PidfdStoreSk *int32 `protobuf:"varint,62,opt,name=pidfd_store_sk,json=pidfdStoreSk" json:"pidfd_store_sk,omitempty"` + LsmMountContext *string `protobuf:"bytes,63,opt,name=lsm_mount_context,json=lsmMountContext" json:"lsm_mount_context,omitempty"` // optional bool check_mounts = 128; +} + +// Default values for CriuOpts fields. +const ( + Default_CriuOpts_LogLevel = int32(2) + Default_CriuOpts_CpuCap = uint32(4294967295) + Default_CriuOpts_GhostLimit = uint32(1048576) + Default_CriuOpts_PreDumpMode = CriuPreDumpMode_SPLICE +) + +func (x *CriuOpts) Reset() { + *x = CriuOpts{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CriuOpts) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CriuOpts) ProtoMessage() {} + +func (x *CriuOpts) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CriuOpts.ProtoReflect.Descriptor instead. +func (*CriuOpts) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{7} +} + +func (x *CriuOpts) GetImagesDirFd() int32 { + if x != nil && x.ImagesDirFd != nil { + return *x.ImagesDirFd + } + return 0 +} + +func (x *CriuOpts) GetPid() int32 { + if x != nil && x.Pid != nil { + return *x.Pid + } + return 0 +} + +func (x *CriuOpts) GetLeaveRunning() bool { + if x != nil && x.LeaveRunning != nil { + return *x.LeaveRunning + } + return false +} + +func (x *CriuOpts) GetExtUnixSk() bool { + if x != nil && x.ExtUnixSk != nil { + return *x.ExtUnixSk + } + return false +} + +func (x *CriuOpts) GetTcpEstablished() bool { + if x != nil && x.TcpEstablished != nil { + return *x.TcpEstablished + } + return false +} + +func (x *CriuOpts) GetEvasiveDevices() bool { + if x != nil && x.EvasiveDevices != nil { + return *x.EvasiveDevices + } + return false +} + +func (x *CriuOpts) GetShellJob() bool { + if x != nil && x.ShellJob != nil { + return *x.ShellJob + } + return false +} + +func (x *CriuOpts) GetFileLocks() bool { + if x != nil && x.FileLocks != nil { + return *x.FileLocks + } + return false +} + +func (x *CriuOpts) GetLogLevel() int32 { + if x != nil && x.LogLevel != nil { + return *x.LogLevel + } + return Default_CriuOpts_LogLevel +} + +func (x *CriuOpts) GetLogFile() string { + if x != nil && x.LogFile != nil { + return *x.LogFile + } + return "" +} + +func (x *CriuOpts) GetPs() *CriuPageServerInfo { + if x != nil { + return x.Ps + } + return nil +} + +func (x *CriuOpts) GetNotifyScripts() bool { + if x != nil && x.NotifyScripts != nil { + return *x.NotifyScripts + } + return false +} + +func (x *CriuOpts) GetRoot() string { + if x != nil && x.Root != nil { + return *x.Root + } + return "" +} + +func (x *CriuOpts) GetParentImg() string { + if x != nil && x.ParentImg != nil { + return *x.ParentImg + } + return "" +} + +func (x *CriuOpts) GetTrackMem() bool { + if x != nil && x.TrackMem != nil { + return *x.TrackMem + } + return false +} + +func (x *CriuOpts) GetAutoDedup() bool { + if x != nil && x.AutoDedup != nil { + return *x.AutoDedup + } + return false +} + +func (x *CriuOpts) GetWorkDirFd() int32 { + if x != nil && x.WorkDirFd != nil { + return *x.WorkDirFd + } + return 0 +} + +func (x *CriuOpts) GetLinkRemap() bool { + if x != nil && x.LinkRemap != nil { + return *x.LinkRemap + } + return false +} + +func (x *CriuOpts) GetVeths() []*CriuVethPair { + if x != nil { + return x.Veths + } + return nil +} + +func (x *CriuOpts) GetCpuCap() uint32 { + if x != nil && x.CpuCap != nil { + return *x.CpuCap + } + return Default_CriuOpts_CpuCap +} + +func (x *CriuOpts) GetForceIrmap() bool { + if x != nil && x.ForceIrmap != nil { + return *x.ForceIrmap + } + return false +} + +func (x *CriuOpts) GetExecCmd() []string { + if x != nil { + return x.ExecCmd + } + return nil +} + +func (x *CriuOpts) GetExtMnt() []*ExtMountMap { + if x != nil { + return x.ExtMnt + } + return nil +} + +func (x *CriuOpts) GetManageCgroups() bool { + if x != nil && x.ManageCgroups != nil { + return *x.ManageCgroups + } + return false +} + +func (x *CriuOpts) GetCgRoot() []*CgroupRoot { + if x != nil { + return x.CgRoot + } + return nil +} + +func (x *CriuOpts) GetRstSibling() bool { + if x != nil && x.RstSibling != nil { + return *x.RstSibling + } + return false +} + +func (x *CriuOpts) GetInheritFd() []*InheritFd { + if x != nil { + return x.InheritFd + } + return nil +} + +func (x *CriuOpts) GetAutoExtMnt() bool { + if x != nil && x.AutoExtMnt != nil { + return *x.AutoExtMnt + } + return false +} + +func (x *CriuOpts) GetExtSharing() bool { + if x != nil && x.ExtSharing != nil { + return *x.ExtSharing + } + return false +} + +func (x *CriuOpts) GetExtMasters() bool { + if x != nil && x.ExtMasters != nil { + return *x.ExtMasters + } + return false +} + +func (x *CriuOpts) GetSkipMnt() []string { + if x != nil { + return x.SkipMnt + } + return nil +} + +func (x *CriuOpts) GetEnableFs() []string { + if x != nil { + return x.EnableFs + } + return nil +} + +func (x *CriuOpts) GetUnixSkIno() []*UnixSk { + if x != nil { + return x.UnixSkIno + } + return nil +} + +func (x *CriuOpts) GetManageCgroupsMode() CriuCgMode { + if x != nil && x.ManageCgroupsMode != nil { + return *x.ManageCgroupsMode + } + return CriuCgMode_IGNORE +} + +func (x *CriuOpts) GetGhostLimit() uint32 { + if x != nil && x.GhostLimit != nil { + return *x.GhostLimit + } + return Default_CriuOpts_GhostLimit +} + +func (x *CriuOpts) GetIrmapScanPaths() []string { + if x != nil { + return x.IrmapScanPaths + } + return nil +} + +func (x *CriuOpts) GetExternal() []string { + if x != nil { + return x.External + } + return nil +} + +func (x *CriuOpts) GetEmptyNs() uint32 { + if x != nil && x.EmptyNs != nil { + return *x.EmptyNs + } + return 0 +} + +func (x *CriuOpts) GetJoinNs() []*JoinNamespace { + if x != nil { + return x.JoinNs + } + return nil +} + +func (x *CriuOpts) GetCgroupProps() string { + if x != nil && x.CgroupProps != nil { + return *x.CgroupProps + } + return "" +} + +func (x *CriuOpts) GetCgroupPropsFile() string { + if x != nil && x.CgroupPropsFile != nil { + return *x.CgroupPropsFile + } + return "" +} + +func (x *CriuOpts) GetCgroupDumpController() []string { + if x != nil { + return x.CgroupDumpController + } + return nil +} + +func (x *CriuOpts) GetFreezeCgroup() string { + if x != nil && x.FreezeCgroup != nil { + return *x.FreezeCgroup + } + return "" +} + +func (x *CriuOpts) GetTimeout() uint32 { + if x != nil && x.Timeout != nil { + return *x.Timeout + } + return 0 +} + +func (x *CriuOpts) GetTcpSkipInFlight() bool { + if x != nil && x.TcpSkipInFlight != nil { + return *x.TcpSkipInFlight + } + return false +} + +func (x *CriuOpts) GetWeakSysctls() bool { + if x != nil && x.WeakSysctls != nil { + return *x.WeakSysctls + } + return false +} + +func (x *CriuOpts) GetLazyPages() bool { + if x != nil && x.LazyPages != nil { + return *x.LazyPages + } + return false +} + +func (x *CriuOpts) GetStatusFd() int32 { + if x != nil && x.StatusFd != nil { + return *x.StatusFd + } + return 0 +} + +func (x *CriuOpts) GetOrphanPtsMaster() bool { + if x != nil && x.OrphanPtsMaster != nil { + return *x.OrphanPtsMaster + } + return false +} + +func (x *CriuOpts) GetConfigFile() string { + if x != nil && x.ConfigFile != nil { + return *x.ConfigFile + } + return "" +} + +func (x *CriuOpts) GetTcpClose() bool { + if x != nil && x.TcpClose != nil { + return *x.TcpClose + } + return false +} + +func (x *CriuOpts) GetLsmProfile() string { + if x != nil && x.LsmProfile != nil { + return *x.LsmProfile + } + return "" +} + +func (x *CriuOpts) GetTlsCacert() string { + if x != nil && x.TlsCacert != nil { + return *x.TlsCacert + } + return "" +} + +func (x *CriuOpts) GetTlsCacrl() string { + if x != nil && x.TlsCacrl != nil { + return *x.TlsCacrl + } + return "" +} + +func (x *CriuOpts) GetTlsCert() string { + if x != nil && x.TlsCert != nil { + return *x.TlsCert + } + return "" +} + +func (x *CriuOpts) GetTlsKey() string { + if x != nil && x.TlsKey != nil { + return *x.TlsKey + } + return "" +} + +func (x *CriuOpts) GetTls() bool { + if x != nil && x.Tls != nil { + return *x.Tls + } + return false +} + +func (x *CriuOpts) GetTlsNoCnVerify() bool { + if x != nil && x.TlsNoCnVerify != nil { + return *x.TlsNoCnVerify + } + return false +} + +func (x *CriuOpts) GetCgroupYard() string { + if x != nil && x.CgroupYard != nil { + return *x.CgroupYard + } + return "" +} + +func (x *CriuOpts) GetPreDumpMode() CriuPreDumpMode { + if x != nil && x.PreDumpMode != nil { + return *x.PreDumpMode + } + return Default_CriuOpts_PreDumpMode +} + +func (x *CriuOpts) GetPidfdStoreSk() int32 { + if x != nil && x.PidfdStoreSk != nil { + return *x.PidfdStoreSk + } + return 0 +} + +func (x *CriuOpts) GetLsmMountContext() string { + if x != nil && x.LsmMountContext != nil { + return *x.LsmMountContext + } + return "" +} + +type CriuDumpResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Restored *bool `protobuf:"varint,1,opt,name=restored" json:"restored,omitempty"` +} + +func (x *CriuDumpResp) Reset() { + *x = CriuDumpResp{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CriuDumpResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CriuDumpResp) ProtoMessage() {} + +func (x *CriuDumpResp) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CriuDumpResp.ProtoReflect.Descriptor instead. +func (*CriuDumpResp) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{8} +} + +func (x *CriuDumpResp) GetRestored() bool { + if x != nil && x.Restored != nil { + return *x.Restored + } + return false +} + +type CriuRestoreResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Pid *int32 `protobuf:"varint,1,req,name=pid" json:"pid,omitempty"` +} + +func (x *CriuRestoreResp) Reset() { + *x = CriuRestoreResp{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CriuRestoreResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CriuRestoreResp) ProtoMessage() {} + +func (x *CriuRestoreResp) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CriuRestoreResp.ProtoReflect.Descriptor instead. +func (*CriuRestoreResp) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{9} +} + +func (x *CriuRestoreResp) GetPid() int32 { + if x != nil && x.Pid != nil { + return *x.Pid + } + return 0 +} + +type CriuNotify struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Script *string `protobuf:"bytes,1,opt,name=script" json:"script,omitempty"` + Pid *int32 `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"` +} + +func (x *CriuNotify) Reset() { + *x = CriuNotify{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CriuNotify) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CriuNotify) ProtoMessage() {} + +func (x *CriuNotify) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CriuNotify.ProtoReflect.Descriptor instead. +func (*CriuNotify) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{10} +} + +func (x *CriuNotify) GetScript() string { + if x != nil && x.Script != nil { + return *x.Script + } + return "" +} + +func (x *CriuNotify) GetPid() int32 { + if x != nil && x.Pid != nil { + return *x.Pid + } + return 0 +} + +// +// List of features which can queried via +// CRIU_REQ_TYPE__FEATURE_CHECK +type CriuFeatures struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MemTrack *bool `protobuf:"varint,1,opt,name=mem_track,json=memTrack" json:"mem_track,omitempty"` + LazyPages *bool `protobuf:"varint,2,opt,name=lazy_pages,json=lazyPages" json:"lazy_pages,omitempty"` + PidfdStore *bool `protobuf:"varint,3,opt,name=pidfd_store,json=pidfdStore" json:"pidfd_store,omitempty"` +} + +func (x *CriuFeatures) Reset() { + *x = CriuFeatures{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CriuFeatures) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CriuFeatures) ProtoMessage() {} + +func (x *CriuFeatures) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CriuFeatures.ProtoReflect.Descriptor instead. +func (*CriuFeatures) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{11} +} + +func (x *CriuFeatures) GetMemTrack() bool { + if x != nil && x.MemTrack != nil { + return *x.MemTrack + } + return false +} + +func (x *CriuFeatures) GetLazyPages() bool { + if x != nil && x.LazyPages != nil { + return *x.LazyPages + } + return false +} + +func (x *CriuFeatures) GetPidfdStore() bool { + if x != nil && x.PidfdStore != nil { + return *x.PidfdStore + } + return false +} + +type CriuReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type *CriuReqType `protobuf:"varint,1,req,name=type,enum=CriuReqType" json:"type,omitempty"` + Opts *CriuOpts `protobuf:"bytes,2,opt,name=opts" json:"opts,omitempty"` + NotifySuccess *bool `protobuf:"varint,3,opt,name=notify_success,json=notifySuccess" json:"notify_success,omitempty"` + // + // When set service won't close the connection but + // will wait for more req-s to appear. Works not + // for all request types. + KeepOpen *bool `protobuf:"varint,4,opt,name=keep_open,json=keepOpen" json:"keep_open,omitempty"` + // + // 'features' can be used to query which features + // are supported by the installed criu/kernel + // via RPC. + Features *CriuFeatures `protobuf:"bytes,5,opt,name=features" json:"features,omitempty"` + // 'pid' is used for WAIT_PID + Pid *uint32 `protobuf:"varint,6,opt,name=pid" json:"pid,omitempty"` +} + +func (x *CriuReq) Reset() { + *x = CriuReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CriuReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CriuReq) ProtoMessage() {} + +func (x *CriuReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CriuReq.ProtoReflect.Descriptor instead. +func (*CriuReq) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{12} +} + +func (x *CriuReq) GetType() CriuReqType { + if x != nil && x.Type != nil { + return *x.Type + } + return CriuReqType_EMPTY +} + +func (x *CriuReq) GetOpts() *CriuOpts { + if x != nil { + return x.Opts + } + return nil +} + +func (x *CriuReq) GetNotifySuccess() bool { + if x != nil && x.NotifySuccess != nil { + return *x.NotifySuccess + } + return false +} + +func (x *CriuReq) GetKeepOpen() bool { + if x != nil && x.KeepOpen != nil { + return *x.KeepOpen + } + return false +} + +func (x *CriuReq) GetFeatures() *CriuFeatures { + if x != nil { + return x.Features + } + return nil +} + +func (x *CriuReq) GetPid() uint32 { + if x != nil && x.Pid != nil { + return *x.Pid + } + return 0 +} + +type CriuResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type *CriuReqType `protobuf:"varint,1,req,name=type,enum=CriuReqType" json:"type,omitempty"` + Success *bool `protobuf:"varint,2,req,name=success" json:"success,omitempty"` + Dump *CriuDumpResp `protobuf:"bytes,3,opt,name=dump" json:"dump,omitempty"` + Restore *CriuRestoreResp `protobuf:"bytes,4,opt,name=restore" json:"restore,omitempty"` + Notify *CriuNotify `protobuf:"bytes,5,opt,name=notify" json:"notify,omitempty"` + Ps *CriuPageServerInfo `protobuf:"bytes,6,opt,name=ps" json:"ps,omitempty"` + CrErrno *int32 `protobuf:"varint,7,opt,name=cr_errno,json=crErrno" json:"cr_errno,omitempty"` + Features *CriuFeatures `protobuf:"bytes,8,opt,name=features" json:"features,omitempty"` + CrErrmsg *string `protobuf:"bytes,9,opt,name=cr_errmsg,json=crErrmsg" json:"cr_errmsg,omitempty"` + Version *CriuVersion `protobuf:"bytes,10,opt,name=version" json:"version,omitempty"` + Status *int32 `protobuf:"varint,11,opt,name=status" json:"status,omitempty"` +} + +func (x *CriuResp) Reset() { + *x = CriuResp{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CriuResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CriuResp) ProtoMessage() {} + +func (x *CriuResp) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CriuResp.ProtoReflect.Descriptor instead. +func (*CriuResp) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{13} +} + +func (x *CriuResp) GetType() CriuReqType { + if x != nil && x.Type != nil { + return *x.Type + } + return CriuReqType_EMPTY +} + +func (x *CriuResp) GetSuccess() bool { + if x != nil && x.Success != nil { + return *x.Success + } + return false +} + +func (x *CriuResp) GetDump() *CriuDumpResp { + if x != nil { + return x.Dump + } + return nil +} + +func (x *CriuResp) GetRestore() *CriuRestoreResp { + if x != nil { + return x.Restore + } + return nil +} + +func (x *CriuResp) GetNotify() *CriuNotify { + if x != nil { + return x.Notify + } + return nil +} + +func (x *CriuResp) GetPs() *CriuPageServerInfo { + if x != nil { + return x.Ps + } + return nil +} + +func (x *CriuResp) GetCrErrno() int32 { + if x != nil && x.CrErrno != nil { + return *x.CrErrno + } + return 0 +} + +func (x *CriuResp) GetFeatures() *CriuFeatures { + if x != nil { + return x.Features + } + return nil +} + +func (x *CriuResp) GetCrErrmsg() string { + if x != nil && x.CrErrmsg != nil { + return *x.CrErrmsg + } + return "" +} + +func (x *CriuResp) GetVersion() *CriuVersion { + if x != nil { + return x.Version + } + return nil +} + +func (x *CriuResp) GetStatus() int32 { + if x != nil && x.Status != nil { + return *x.Status + } + return 0 +} + +// Answer for criu_req_type.VERSION requests +type CriuVersion struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MajorNumber *int32 `protobuf:"varint,1,req,name=major_number,json=majorNumber" json:"major_number,omitempty"` + MinorNumber *int32 `protobuf:"varint,2,req,name=minor_number,json=minorNumber" json:"minor_number,omitempty"` + Gitid *string `protobuf:"bytes,3,opt,name=gitid" json:"gitid,omitempty"` + Sublevel *int32 `protobuf:"varint,4,opt,name=sublevel" json:"sublevel,omitempty"` + Extra *int32 `protobuf:"varint,5,opt,name=extra" json:"extra,omitempty"` + Name *string `protobuf:"bytes,6,opt,name=name" json:"name,omitempty"` +} + +func (x *CriuVersion) Reset() { + *x = CriuVersion{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_rpc_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CriuVersion) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CriuVersion) ProtoMessage() {} + +func (x *CriuVersion) ProtoReflect() protoreflect.Message { + mi := &file_rpc_rpc_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CriuVersion.ProtoReflect.Descriptor instead. +func (*CriuVersion) Descriptor() ([]byte, []int) { + return file_rpc_rpc_proto_rawDescGZIP(), []int{14} +} + +func (x *CriuVersion) GetMajorNumber() int32 { + if x != nil && x.MajorNumber != nil { + return *x.MajorNumber + } + return 0 +} + +func (x *CriuVersion) GetMinorNumber() int32 { + if x != nil && x.MinorNumber != nil { + return *x.MinorNumber + } + return 0 +} + +func (x *CriuVersion) GetGitid() string { + if x != nil && x.Gitid != nil { + return *x.Gitid + } + return "" +} + +func (x *CriuVersion) GetSublevel() int32 { + if x != nil && x.Sublevel != nil { + return *x.Sublevel + } + return 0 +} + +func (x *CriuVersion) GetExtra() int32 { + if x != nil && x.Extra != nil { + return *x.Extra + } + return 0 +} + +func (x *CriuVersion) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +var File_rpc_rpc_proto protoreflect.FileDescriptor + +var file_rpc_rpc_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0x67, 0x0a, 0x15, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x66, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x66, 0x64, 0x22, 0x3c, 0x0a, 0x0e, 0x63, 0x72, 0x69, 0x75, + 0x5f, 0x76, 0x65, 0x74, 0x68, 0x5f, 0x70, 0x61, 0x69, 0x72, 0x12, 0x13, 0x0a, 0x05, 0x69, 0x66, + 0x5f, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x69, 0x66, 0x49, 0x6e, 0x12, + 0x15, 0x0a, 0x06, 0x69, 0x66, 0x5f, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, + 0x05, 0x69, 0x66, 0x4f, 0x75, 0x74, 0x22, 0x33, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x5f, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x02, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x6c, + 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, 0x03, 0x76, 0x61, 0x6c, 0x22, 0x56, 0x0a, 0x0e, 0x6a, + 0x6f, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x02, 0x6e, 0x73, 0x12, 0x17, 0x0a, + 0x07, 0x6e, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, 0x06, + 0x6e, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, + 0x6f, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x74, 0x72, 0x61, + 0x4f, 0x70, 0x74, 0x22, 0x2e, 0x0a, 0x0a, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x5f, 0x66, + 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x66, 0x64, 0x18, 0x02, 0x20, 0x02, 0x28, 0x05, 0x52, + 0x02, 0x66, 0x64, 0x22, 0x35, 0x0a, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x72, 0x6f, + 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x74, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x63, 0x74, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, + 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x1f, 0x0a, 0x07, 0x75, 0x6e, + 0x69, 0x78, 0x5f, 0x73, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, + 0x20, 0x02, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x8c, 0x11, 0x0a, 0x09, + 0x63, 0x72, 0x69, 0x75, 0x5f, 0x6f, 0x70, 0x74, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x73, 0x5f, 0x64, 0x69, 0x72, 0x5f, 0x66, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x05, + 0x52, 0x0b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x44, 0x69, 0x72, 0x46, 0x64, 0x12, 0x10, 0x0a, + 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, + 0x23, 0x0a, 0x0d, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x75, 0x6e, + 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x78, + 0x5f, 0x73, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x78, 0x74, 0x55, 0x6e, + 0x69, 0x78, 0x53, 0x6b, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x63, 0x70, 0x5f, 0x65, 0x73, 0x74, 0x61, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x74, + 0x63, 0x70, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x27, 0x0a, + 0x0f, 0x65, 0x76, 0x61, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x65, 0x76, 0x61, 0x73, 0x69, 0x76, 0x65, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x5f, + 0x6a, 0x6f, 0x62, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x68, 0x65, 0x6c, 0x6c, + 0x4a, 0x6f, 0x62, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x6b, + 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x6f, 0x63, + 0x6b, 0x73, 0x12, 0x1e, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x05, 0x3a, 0x01, 0x32, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x76, + 0x65, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x26, 0x0a, + 0x02, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x72, 0x69, 0x75, + 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, + 0x6f, 0x52, 0x02, 0x70, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6e, + 0x6f, 0x74, 0x69, 0x66, 0x79, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, + 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, + 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6d, 0x67, 0x18, 0x0e, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x6d, 0x67, 0x12, + 0x1b, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x5f, 0x6d, 0x65, 0x6d, 0x18, 0x0f, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x4d, 0x65, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, + 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x64, 0x65, 0x64, 0x75, 0x70, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x44, 0x65, 0x64, 0x75, 0x70, 0x12, 0x1e, 0x0a, 0x0b, 0x77, + 0x6f, 0x72, 0x6b, 0x5f, 0x64, 0x69, 0x72, 0x5f, 0x66, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x44, 0x69, 0x72, 0x46, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, + 0x69, 0x6e, 0x6b, 0x5f, 0x72, 0x65, 0x6d, 0x61, 0x70, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x6d, 0x61, 0x70, 0x12, 0x25, 0x0a, 0x05, 0x76, 0x65, + 0x74, 0x68, 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x72, 0x69, 0x75, + 0x5f, 0x76, 0x65, 0x74, 0x68, 0x5f, 0x70, 0x61, 0x69, 0x72, 0x52, 0x05, 0x76, 0x65, 0x74, 0x68, + 0x73, 0x12, 0x23, 0x0a, 0x07, 0x63, 0x70, 0x75, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x14, 0x20, 0x01, + 0x28, 0x0d, 0x3a, 0x0a, 0x34, 0x32, 0x39, 0x34, 0x39, 0x36, 0x37, 0x32, 0x39, 0x35, 0x52, 0x06, + 0x63, 0x70, 0x75, 0x43, 0x61, 0x70, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, + 0x69, 0x72, 0x6d, 0x61, 0x70, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x49, 0x72, 0x6d, 0x61, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x78, 0x65, 0x63, 0x5f, + 0x63, 0x6d, 0x64, 0x18, 0x16, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x65, 0x78, 0x65, 0x63, 0x43, + 0x6d, 0x64, 0x12, 0x27, 0x0a, 0x07, 0x65, 0x78, 0x74, 0x5f, 0x6d, 0x6e, 0x74, 0x18, 0x17, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x65, 0x78, 0x74, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x6d, 0x61, 0x70, 0x52, 0x06, 0x65, 0x78, 0x74, 0x4d, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x18, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x43, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x73, 0x12, 0x25, 0x0a, 0x07, 0x63, 0x67, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x19, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x72, 0x6f, 0x6f, + 0x74, 0x52, 0x06, 0x63, 0x67, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x73, 0x74, + 0x5f, 0x73, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, + 0x72, 0x73, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x2a, 0x0a, 0x0a, 0x69, 0x6e, + 0x68, 0x65, 0x72, 0x69, 0x74, 0x5f, 0x66, 0x64, 0x18, 0x1b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, + 0x2e, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x5f, 0x66, 0x64, 0x52, 0x09, 0x69, 0x6e, 0x68, + 0x65, 0x72, 0x69, 0x74, 0x46, 0x64, 0x12, 0x20, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x65, + 0x78, 0x74, 0x5f, 0x6d, 0x6e, 0x74, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, + 0x74, 0x6f, 0x45, 0x78, 0x74, 0x4d, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x5f, + 0x73, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, + 0x78, 0x74, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, + 0x5f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, + 0x65, 0x78, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x6b, + 0x69, 0x70, 0x5f, 0x6d, 0x6e, 0x74, 0x18, 0x1f, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x6b, + 0x69, 0x70, 0x4d, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x66, 0x73, 0x18, 0x20, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x46, 0x73, 0x12, 0x28, 0x0a, 0x0b, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x73, 0x6b, 0x5f, 0x69, 0x6e, + 0x6f, 0x18, 0x21, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x73, + 0x6b, 0x52, 0x09, 0x75, 0x6e, 0x69, 0x78, 0x53, 0x6b, 0x49, 0x6e, 0x6f, 0x12, 0x3d, 0x0a, 0x13, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x5f, 0x6d, + 0x6f, 0x64, 0x65, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x63, 0x72, 0x69, 0x75, + 0x5f, 0x63, 0x67, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x52, 0x11, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x43, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x28, 0x0a, 0x0b, 0x67, + 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0d, + 0x3a, 0x07, 0x31, 0x30, 0x34, 0x38, 0x35, 0x37, 0x36, 0x52, 0x0a, 0x67, 0x68, 0x6f, 0x73, 0x74, + 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x69, 0x72, 0x6d, 0x61, 0x70, 0x5f, 0x73, + 0x63, 0x61, 0x6e, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x24, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0e, 0x69, 0x72, 0x6d, 0x61, 0x70, 0x53, 0x63, 0x61, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, + 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x25, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x65, + 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x6e, 0x73, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x65, + 0x6d, 0x70, 0x74, 0x79, 0x4e, 0x73, 0x12, 0x28, 0x0a, 0x07, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x6e, + 0x73, 0x18, 0x27, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x06, 0x6a, 0x6f, 0x69, 0x6e, 0x4e, 0x73, + 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x73, + 0x18, 0x29, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x72, + 0x6f, 0x70, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x70, 0x72, + 0x6f, 0x70, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x70, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x12, + 0x34, 0x0a, 0x16, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x2b, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x14, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x65, 0x65, 0x7a, 0x65, 0x5f, + 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x72, + 0x65, 0x65, 0x7a, 0x65, 0x43, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x74, 0x63, 0x70, 0x5f, 0x73, 0x6b, 0x69, 0x70, + 0x5f, 0x69, 0x6e, 0x5f, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x18, 0x2e, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0f, 0x74, 0x63, 0x70, 0x53, 0x6b, 0x69, 0x70, 0x49, 0x6e, 0x46, 0x6c, 0x69, 0x67, 0x68, + 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x65, 0x61, 0x6b, 0x5f, 0x73, 0x79, 0x73, 0x63, 0x74, 0x6c, + 0x73, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, 0x65, 0x61, 0x6b, 0x53, 0x79, 0x73, + 0x63, 0x74, 0x6c, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x70, 0x61, 0x67, + 0x65, 0x73, 0x18, 0x30, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6c, 0x61, 0x7a, 0x79, 0x50, 0x61, + 0x67, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x66, 0x64, + 0x18, 0x31, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x46, 0x64, + 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x72, 0x70, 0x68, 0x61, 0x6e, 0x5f, 0x70, 0x74, 0x73, 0x5f, 0x6d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x18, 0x32, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6f, 0x72, 0x70, + 0x68, 0x61, 0x6e, 0x50, 0x74, 0x73, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x33, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1b, 0x0a, + 0x09, 0x74, 0x63, 0x70, 0x5f, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x18, 0x34, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x74, 0x63, 0x70, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x73, + 0x6d, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x35, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x6c, 0x73, 0x6d, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x74, + 0x6c, 0x73, 0x5f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x18, 0x36, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x74, 0x6c, 0x73, 0x43, 0x61, 0x63, 0x65, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6c, + 0x73, 0x5f, 0x63, 0x61, 0x63, 0x72, 0x6c, 0x18, 0x37, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, + 0x6c, 0x73, 0x43, 0x61, 0x63, 0x72, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x6c, 0x73, 0x5f, 0x63, + 0x65, 0x72, 0x74, 0x18, 0x38, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x6c, 0x73, 0x43, 0x65, + 0x72, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x6c, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x39, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x74, + 0x6c, 0x73, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x74, 0x6c, 0x73, 0x12, 0x27, 0x0a, + 0x10, 0x74, 0x6c, 0x73, 0x5f, 0x6e, 0x6f, 0x5f, 0x63, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, + 0x79, 0x18, 0x3b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x74, 0x6c, 0x73, 0x4e, 0x6f, 0x43, 0x6e, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x5f, 0x79, 0x61, 0x72, 0x64, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x59, 0x61, 0x72, 0x64, 0x12, 0x3f, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x5f, 0x64, + 0x75, 0x6d, 0x70, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, + 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x70, 0x72, 0x65, 0x5f, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x6d, + 0x6f, 0x64, 0x65, 0x3a, 0x06, 0x53, 0x50, 0x4c, 0x49, 0x43, 0x45, 0x52, 0x0b, 0x70, 0x72, 0x65, + 0x44, 0x75, 0x6d, 0x70, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x69, 0x64, 0x66, + 0x64, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x73, 0x6b, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x0c, 0x70, 0x69, 0x64, 0x66, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x6b, 0x12, 0x2a, + 0x0a, 0x11, 0x6c, 0x73, 0x6d, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x18, 0x3f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x73, 0x6d, 0x4d, 0x6f, + 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x2c, 0x0a, 0x0e, 0x63, 0x72, + 0x69, 0x75, 0x5f, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x12, 0x1a, 0x0a, 0x08, + 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x22, 0x25, 0x0a, 0x11, 0x63, 0x72, 0x69, 0x75, + 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a, + 0x03, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x05, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, + 0x37, 0x0a, 0x0b, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x6c, 0x0a, 0x0d, 0x63, 0x72, 0x69, 0x75, + 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, + 0x5f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6d, 0x65, + 0x6d, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x70, + 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6c, 0x61, 0x7a, 0x79, + 0x50, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x69, 0x64, 0x66, 0x64, 0x5f, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, 0x69, 0x64, 0x66, + 0x64, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x08, 0x63, 0x72, 0x69, 0x75, 0x5f, + 0x72, 0x65, 0x71, 0x12, 0x22, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, + 0x0e, 0x32, 0x0e, 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x72, 0x65, 0x71, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x04, 0x6f, 0x70, 0x74, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x6f, 0x70, 0x74, + 0x73, 0x52, 0x04, 0x6f, 0x70, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, + 0x79, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1b, + 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x2a, 0x0a, 0x08, 0x66, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x63, 0x72, 0x69, 0x75, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x08, 0x66, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x8f, 0x03, 0x0a, 0x09, 0x63, 0x72, + 0x69, 0x75, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x12, 0x22, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x01, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x72, 0x65, 0x71, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x02, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x04, 0x64, 0x75, 0x6d, 0x70, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x64, 0x75, 0x6d, 0x70, 0x5f, + 0x72, 0x65, 0x73, 0x70, 0x52, 0x04, 0x64, 0x75, 0x6d, 0x70, 0x12, 0x2c, 0x0a, 0x07, 0x72, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x72, + 0x69, 0x75, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x52, + 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x69, + 0x66, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, + 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x06, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x26, + 0x0a, 0x02, 0x70, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x72, 0x69, + 0x75, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x6e, + 0x66, 0x6f, 0x52, 0x02, 0x70, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x72, 0x5f, 0x65, 0x72, 0x72, + 0x6e, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x63, 0x72, 0x45, 0x72, 0x72, 0x6e, + 0x6f, 0x12, 0x2a, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x1b, 0x0a, + 0x09, 0x63, 0x72, 0x5f, 0x65, 0x72, 0x72, 0x6d, 0x73, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x63, 0x72, 0x45, 0x72, 0x72, 0x6d, 0x73, 0x67, 0x12, 0x27, 0x0a, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x72, + 0x69, 0x75, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xb0, 0x01, 0x0a, 0x0c, + 0x63, 0x72, 0x69, 0x75, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, + 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x02, + 0x28, 0x05, 0x52, 0x0b, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, + 0x21, 0x0a, 0x0c, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, + 0x02, 0x20, 0x02, 0x28, 0x05, 0x52, 0x0b, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x4e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x69, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x67, 0x69, 0x74, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x2a, 0x5f, + 0x0a, 0x0c, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x63, 0x67, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x0a, + 0x0a, 0x06, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x47, + 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x52, 0x4f, 0x50, 0x53, + 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x4f, 0x46, 0x54, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, + 0x46, 0x55, 0x4c, 0x4c, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, + 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x06, 0x2a, + 0x2d, 0x0a, 0x12, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x70, 0x72, 0x65, 0x5f, 0x64, 0x75, 0x6d, 0x70, + 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x50, 0x4c, 0x49, 0x43, 0x45, 0x10, + 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x56, 0x4d, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x02, 0x2a, 0xd0, + 0x01, 0x0a, 0x0d, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x72, 0x65, 0x71, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, + 0x55, 0x4d, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x53, 0x54, 0x4f, 0x52, 0x45, + 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, 0x03, 0x12, 0x0c, 0x0a, + 0x08, 0x50, 0x52, 0x45, 0x5f, 0x44, 0x55, 0x4d, 0x50, 0x10, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x50, + 0x41, 0x47, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, + 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x59, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x50, 0x55, 0x49, + 0x4e, 0x46, 0x4f, 0x5f, 0x44, 0x55, 0x4d, 0x50, 0x10, 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x50, + 0x55, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, 0x08, 0x12, 0x11, 0x0a, + 0x0d, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, 0x09, + 0x12, 0x0b, 0x0a, 0x07, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x0a, 0x12, 0x0c, 0x0a, + 0x08, 0x57, 0x41, 0x49, 0x54, 0x5f, 0x50, 0x49, 0x44, 0x10, 0x0b, 0x12, 0x14, 0x0a, 0x10, 0x50, + 0x41, 0x47, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x43, 0x48, 0x4c, 0x44, 0x10, + 0x0c, +} + +var ( + file_rpc_rpc_proto_rawDescOnce sync.Once + file_rpc_rpc_proto_rawDescData = file_rpc_rpc_proto_rawDesc +) + +func file_rpc_rpc_proto_rawDescGZIP() []byte { + file_rpc_rpc_proto_rawDescOnce.Do(func() { + file_rpc_rpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_rpc_proto_rawDescData) + }) + return file_rpc_rpc_proto_rawDescData +} + +var file_rpc_rpc_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_rpc_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_rpc_rpc_proto_goTypes = []interface{}{ + (CriuCgMode)(0), // 0: criu_cg_mode + (CriuPreDumpMode)(0), // 1: criu_pre_dump_mode + (CriuReqType)(0), // 2: criu_req_type + (*CriuPageServerInfo)(nil), // 3: criu_page_server_info + (*CriuVethPair)(nil), // 4: criu_veth_pair + (*ExtMountMap)(nil), // 5: ext_mount_map + (*JoinNamespace)(nil), // 6: join_namespace + (*InheritFd)(nil), // 7: inherit_fd + (*CgroupRoot)(nil), // 8: cgroup_root + (*UnixSk)(nil), // 9: unix_sk + (*CriuOpts)(nil), // 10: criu_opts + (*CriuDumpResp)(nil), // 11: criu_dump_resp + (*CriuRestoreResp)(nil), // 12: criu_restore_resp + (*CriuNotify)(nil), // 13: criu_notify + (*CriuFeatures)(nil), // 14: criu_features + (*CriuReq)(nil), // 15: criu_req + (*CriuResp)(nil), // 16: criu_resp + (*CriuVersion)(nil), // 17: criu_version +} +var file_rpc_rpc_proto_depIdxs = []int32{ + 3, // 0: criu_opts.ps:type_name -> criu_page_server_info + 4, // 1: criu_opts.veths:type_name -> criu_veth_pair + 5, // 2: criu_opts.ext_mnt:type_name -> ext_mount_map + 8, // 3: criu_opts.cg_root:type_name -> cgroup_root + 7, // 4: criu_opts.inherit_fd:type_name -> inherit_fd + 9, // 5: criu_opts.unix_sk_ino:type_name -> unix_sk + 0, // 6: criu_opts.manage_cgroups_mode:type_name -> criu_cg_mode + 6, // 7: criu_opts.join_ns:type_name -> join_namespace + 1, // 8: criu_opts.pre_dump_mode:type_name -> criu_pre_dump_mode + 2, // 9: criu_req.type:type_name -> criu_req_type + 10, // 10: criu_req.opts:type_name -> criu_opts + 14, // 11: criu_req.features:type_name -> criu_features + 2, // 12: criu_resp.type:type_name -> criu_req_type + 11, // 13: criu_resp.dump:type_name -> criu_dump_resp + 12, // 14: criu_resp.restore:type_name -> criu_restore_resp + 13, // 15: criu_resp.notify:type_name -> criu_notify + 3, // 16: criu_resp.ps:type_name -> criu_page_server_info + 14, // 17: criu_resp.features:type_name -> criu_features + 17, // 18: criu_resp.version:type_name -> criu_version + 19, // [19:19] is the sub-list for method output_type + 19, // [19:19] is the sub-list for method input_type + 19, // [19:19] is the sub-list for extension type_name + 19, // [19:19] is the sub-list for extension extendee + 0, // [0:19] is the sub-list for field type_name +} + +func init() { file_rpc_rpc_proto_init() } +func file_rpc_rpc_proto_init() { + if File_rpc_rpc_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_rpc_rpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CriuPageServerInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CriuVethPair); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExtMountMap); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*JoinNamespace); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InheritFd); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CgroupRoot); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnixSk); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CriuOpts); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CriuDumpResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CriuRestoreResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CriuNotify); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CriuFeatures); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CriuReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CriuResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_rpc_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CriuVersion); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_rpc_rpc_proto_rawDesc, + NumEnums: 3, + NumMessages: 15, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_rpc_rpc_proto_goTypes, + DependencyIndexes: file_rpc_rpc_proto_depIdxs, + EnumInfos: file_rpc_rpc_proto_enumTypes, + MessageInfos: file_rpc_rpc_proto_msgTypes, + }.Build() + File_rpc_rpc_proto = out.File + file_rpc_rpc_proto_rawDesc = nil + file_rpc_rpc_proto_goTypes = nil + file_rpc_rpc_proto_depIdxs = nil +} diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.proto b/vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.proto new file mode 100644 index 000000000..61e1b24f4 --- /dev/null +++ b/vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.proto @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: MIT + +syntax = "proto2"; + +message criu_page_server_info { + optional string address = 1; + optional int32 port = 2; + optional int32 pid = 3; + optional int32 fd = 4; +} + +message criu_veth_pair { + required string if_in = 1; + required string if_out = 2; +}; + +message ext_mount_map { + required string key = 1; + required string val = 2; +}; + +message join_namespace { + required string ns = 1; + required string ns_file = 2; + optional string extra_opt = 3; +} + +message inherit_fd { + required string key = 1; + required int32 fd = 2; +}; + +message cgroup_root { + optional string ctrl = 1; + required string path = 2; +}; + +message unix_sk { + required uint32 inode = 1; +}; + +enum criu_cg_mode { + IGNORE = 0; + CG_NONE = 1; + PROPS = 2; + SOFT = 3; + FULL = 4; + STRICT = 5; + DEFAULT = 6; +}; + +enum criu_pre_dump_mode { + SPLICE = 1; + VM_READ = 2; +}; + +message criu_opts { + required int32 images_dir_fd = 1; + optional int32 pid = 2; /* if not set on dump, will dump requesting process */ + + optional bool leave_running = 3; + optional bool ext_unix_sk = 4; + optional bool tcp_established = 5; + optional bool evasive_devices = 6; + optional bool shell_job = 7; + optional bool file_locks = 8; + optional int32 log_level = 9 [default = 2]; + optional string log_file = 10; /* No subdirs are allowed. Consider using work-dir */ + + optional criu_page_server_info ps = 11; + + optional bool notify_scripts = 12; + + optional string root = 13; + optional string parent_img = 14; + optional bool track_mem = 15; + optional bool auto_dedup = 16; + + optional int32 work_dir_fd = 17; + optional bool link_remap = 18; + repeated criu_veth_pair veths = 19; /* DEPRECATED, use external instead */ + + optional uint32 cpu_cap = 20 [default = 0xffffffff]; + optional bool force_irmap = 21; + repeated string exec_cmd = 22; + + repeated ext_mount_map ext_mnt = 23; /* DEPRECATED, use external instead */ + optional bool manage_cgroups = 24; /* backward compatibility */ + repeated cgroup_root cg_root = 25; + + optional bool rst_sibling = 26; /* swrk only */ + repeated inherit_fd inherit_fd = 27; /* swrk only */ + + optional bool auto_ext_mnt = 28; + optional bool ext_sharing = 29; + optional bool ext_masters = 30; + + repeated string skip_mnt = 31; + repeated string enable_fs = 32; + + repeated unix_sk unix_sk_ino = 33; /* DEPRECATED, use external instead */ + + optional criu_cg_mode manage_cgroups_mode = 34; + optional uint32 ghost_limit = 35 [default = 0x100000]; + repeated string irmap_scan_paths = 36; + repeated string external = 37; + optional uint32 empty_ns = 38; + repeated join_namespace join_ns = 39; + + optional string cgroup_props = 41; + optional string cgroup_props_file = 42; + repeated string cgroup_dump_controller = 43; + + optional string freeze_cgroup = 44; + optional uint32 timeout = 45; + optional bool tcp_skip_in_flight = 46; + optional bool weak_sysctls = 47; + optional bool lazy_pages = 48; + optional int32 status_fd = 49; + optional bool orphan_pts_master = 50; + optional string config_file = 51; + optional bool tcp_close = 52; + optional string lsm_profile = 53; + optional string tls_cacert = 54; + optional string tls_cacrl = 55; + optional string tls_cert = 56; + optional string tls_key = 57; + optional bool tls = 58; + optional bool tls_no_cn_verify = 59; + optional string cgroup_yard = 60; + optional criu_pre_dump_mode pre_dump_mode = 61 [default = SPLICE]; + optional int32 pidfd_store_sk = 62; + optional string lsm_mount_context = 63; +/* optional bool check_mounts = 128; */ +} + +message criu_dump_resp { + optional bool restored = 1; +} + +message criu_restore_resp { + required int32 pid = 1; +} + +message criu_notify { + optional string script = 1; + optional int32 pid = 2; +} + +enum criu_req_type { + EMPTY = 0; + DUMP = 1; + RESTORE = 2; + CHECK = 3; + PRE_DUMP = 4; + PAGE_SERVER = 5; + + NOTIFY = 6; + + CPUINFO_DUMP = 7; + CPUINFO_CHECK = 8; + + FEATURE_CHECK = 9; + + VERSION = 10; + + WAIT_PID = 11; + PAGE_SERVER_CHLD = 12; +} + +/* + * List of features which can queried via + * CRIU_REQ_TYPE__FEATURE_CHECK + */ +message criu_features { + optional bool mem_track = 1; + optional bool lazy_pages = 2; + optional bool pidfd_store = 3; +} + +/* + * Request -- each type corresponds to must-be-there + * request arguments of respective type + */ + +message criu_req { + required criu_req_type type = 1; + + optional criu_opts opts = 2; + optional bool notify_success = 3; + + /* + * When set service won't close the connection but + * will wait for more req-s to appear. Works not + * for all request types. + */ + optional bool keep_open = 4; + /* + * 'features' can be used to query which features + * are supported by the installed criu/kernel + * via RPC. + */ + optional criu_features features = 5; + + /* 'pid' is used for WAIT_PID */ + optional uint32 pid = 6; +} + +/* + * Response -- it states whether the request was served + * and additional request-specific information + */ + +message criu_resp { + required criu_req_type type = 1; + required bool success = 2; + + optional criu_dump_resp dump = 3; + optional criu_restore_resp restore = 4; + optional criu_notify notify = 5; + optional criu_page_server_info ps = 6; + + optional int32 cr_errno = 7; + optional criu_features features = 8; + optional string cr_errmsg = 9; + optional criu_version version = 10; + + optional int32 status = 11; +} + +/* Answer for criu_req_type.VERSION requests */ +message criu_version { + required int32 major_number = 1; + required int32 minor_number = 2; + optional string gitid = 3; + optional int32 sublevel = 4; + optional int32 extra = 5; + optional string name = 6; +} diff --git a/vendor/github.com/containers/buildah/.cirrus.yml b/vendor/github.com/containers/buildah/.cirrus.yml index db5c3808a..73ab4fc11 100644 --- a/vendor/github.com/containers/buildah/.cirrus.yml +++ b/vendor/github.com/containers/buildah/.cirrus.yml @@ -30,7 +30,7 @@ env: UBUNTU_NAME: "ubuntu-2104" PRIOR_UBUNTU_NAME: "ubuntu-2010" - IMAGE_SUFFIX: "c6032583541653504" + IMAGE_SUFFIX: "c6248193773010944" FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}" PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}" UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX}" @@ -173,7 +173,7 @@ conformance_task: - env: STORAGE_DRIVER: 'overlay' - setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}' + setup_script: '${SCRIPT_BASE}/setup.sh conformance |& ${_TIMESTAMP}' conformance_test_script: '${SCRIPT_BASE}/test.sh conformance |& ${_TIMESTAMP}' @@ -358,9 +358,12 @@ success_task: - static_build container: - image: "quay.io/libpod/fedora-minimal:latest" + image: "quay.io/libpod/alpine:latest" cpu: 1 memory: 1 + env: + CIRRUS_SHELL: direct # execute command directly + clone_script: mkdir -p $CIRRUS_WORKING_DIR script: /bin/true diff --git a/vendor/github.com/containers/buildah/add.go b/vendor/github.com/containers/buildah/add.go index ad178dc6b..f17e3a9c9 100644 --- a/vendor/github.com/containers/buildah/add.go +++ b/vendor/github.com/containers/buildah/add.go @@ -602,12 +602,43 @@ func (b *Builder) userForRun(mountPoint string, userspec string) (specs.User, st // userForRun() does, except for the case where we're passed a single numeric // value, where we need to use that value for both the UID and the GID. func (b *Builder) userForCopy(mountPoint string, userspec string) (uint32, uint32, error) { - if id, err := strconv.ParseUint(userspec, 10, 32); err == nil { - return uint32(id), uint32(id), nil + var ( + user, group string + uid, gid uint64 + err error + ) + + split := strings.SplitN(userspec, ":", 2) + user = split[0] + if len(split) > 1 { + group = split[1] + } + + // If userspec did not specify any values for user or group, then fail + if user == "" && group == "" { + return 0, 0, errors.Errorf("can't find uid for user %s", userspec) + } + + // If userspec specifies values for user or group, check for numeric values + // and return early. If not, then translate username/groupname + if user != "" { + uid, err = strconv.ParseUint(user, 10, 32) + } + if err == nil { + // default gid to uid + gid = uid + if group != "" { + gid, err = strconv.ParseUint(group, 10, 32) + } } - user, _, err := b.userForRun(mountPoint, userspec) + // If err != nil, then user or group not numeric, check filesystem + if err == nil { + return uint32(uid), uint32(gid), nil + } + + owner, _, err := b.userForRun(mountPoint, userspec) if err != nil { return 0xffffffff, 0xffffffff, err } - return user.UID, user.GID, nil + return owner.UID, owner.GID, nil } diff --git a/vendor/github.com/containers/buildah/chroot/run.go b/vendor/github.com/containers/buildah/chroot/run.go index 7cb1d710e..591003568 100644 --- a/vendor/github.com/containers/buildah/chroot/run.go +++ b/vendor/github.com/containers/buildah/chroot/run.go @@ -161,7 +161,7 @@ func RunUsingChroot(spec *specs.Spec, bundlePath, homeDir string, stdin io.Reade cmd := unshare.Command(runUsingChrootCommand) cmd.Stdin, cmd.Stdout, cmd.Stderr = stdin, stdout, stderr cmd.Dir = "/" - cmd.Env = append([]string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())}, os.Environ()...) + cmd.Env = []string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())} logrus.Debugf("Running %#v in %#v", cmd.Cmd, cmd) confwg.Add(1) @@ -207,7 +207,7 @@ func runUsingChrootMain() { os.Exit(1) } - if options.Spec == nil { + if options.Spec == nil || options.Spec.Process == nil { fmt.Fprintf(os.Stderr, "invalid options spec in runUsingChrootMain\n") os.Exit(1) } @@ -573,7 +573,7 @@ func runUsingChroot(spec *specs.Spec, bundlePath string, ctty *os.File, stdin io cmd := unshare.Command(append([]string{runUsingChrootExecCommand}, spec.Process.Args...)...) cmd.Stdin, cmd.Stdout, cmd.Stderr = stdin, stdout, stderr cmd.Dir = "/" - cmd.Env = append([]string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())}, os.Environ()...) + cmd.Env = []string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())} cmd.UnshareFlags = syscall.CLONE_NEWUTS | syscall.CLONE_NEWNS requestedUserNS := false for _, ns := range spec.Linux.Namespaces { @@ -663,7 +663,7 @@ func runUsingChrootExecMain() { // Set the hostname. We're already in a distinct UTS namespace and are admins in the user // namespace which created it, so we shouldn't get a permissions error, but seccomp policy // might deny our attempt to call sethostname() anyway, so log a debug message for that. - if options.Spec == nil { + if options.Spec == nil || options.Spec.Process == nil { fmt.Fprintf(os.Stderr, "invalid options spec passed in\n") os.Exit(1) } @@ -819,7 +819,6 @@ func runUsingChrootExecMain() { // Output debug messages when that differs from what we're being asked to do. func logNamespaceDiagnostics(spec *specs.Spec) { sawMountNS := false - sawUserNS := false sawUTSNS := false for _, ns := range spec.Linux.Namespaces { switch ns.Type { @@ -854,9 +853,8 @@ func logNamespaceDiagnostics(spec *specs.Spec) { } case specs.UserNamespace: if ns.Path != "" { - logrus.Debugf("unable to join user namespace %q, creating a new one", ns.Path) + logrus.Debugf("unable to join user namespace, sorry about that") } - sawUserNS = true case specs.UTSNamespace: if ns.Path != "" { logrus.Debugf("unable to join UTS namespace %q, creating a new one", ns.Path) @@ -867,9 +865,6 @@ func logNamespaceDiagnostics(spec *specs.Spec) { if !sawMountNS { logrus.Debugf("mount namespace not requested, but creating a new one anyway") } - if !sawUserNS { - logrus.Debugf("user namespace not requested, but creating a new one anyway") - } if !sawUTSNS { logrus.Debugf("UTS namespace not requested, but creating a new one anyway") } diff --git a/vendor/github.com/containers/buildah/go.mod b/vendor/github.com/containers/buildah/go.mod index 7145f69a5..68721b73c 100644 --- a/vendor/github.com/containers/buildah/go.mod +++ b/vendor/github.com/containers/buildah/go.mod @@ -4,10 +4,10 @@ go 1.12 require ( github.com/containernetworking/cni v0.8.1 - github.com/containers/common v0.40.1 + github.com/containers/common v0.41.1-0.20210721112610-c95d2f794edf github.com/containers/image/v5 v5.13.2 - github.com/containers/ocicrypt v1.1.1 - github.com/containers/storage v1.32.5 + github.com/containers/ocicrypt v1.1.2 + github.com/containers/storage v1.32.6 github.com/docker/distribution v2.7.1+incompatible github.com/docker/go-units v0.4.0 github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316 @@ -18,10 +18,10 @@ require ( github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect github.com/mattn/go-shellwords v1.0.12 github.com/onsi/ginkgo v1.16.4 - github.com/onsi/gomega v1.13.0 + github.com/onsi/gomega v1.14.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 - github.com/opencontainers/runc v1.0.0 + github.com/opencontainers/runc v1.0.1 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 github.com/opencontainers/runtime-tools v0.9.0 github.com/opencontainers/selinux v1.8.2 @@ -29,13 +29,13 @@ require ( github.com/pkg/errors v0.9.1 github.com/seccomp/libseccomp-golang v0.9.2-0.20200616122406-847368b35ebf github.com/sirupsen/logrus v1.8.1 - github.com/spf13/cobra v1.1.3 + github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 go.etcd.io/bbolt v1.3.6 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 - golang.org/x/sync v0.0.0-20201207232520-09787c993a3a + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20210603125802-9665404d3644 k8s.io/klog v1.0.0 // indirect ) diff --git a/vendor/github.com/containers/buildah/go.sum b/vendor/github.com/containers/buildah/go.sum index 763db376d..ce7eb6c74 100644 --- a/vendor/github.com/containers/buildah/go.sum +++ b/vendor/github.com/containers/buildah/go.sum @@ -10,18 +10,33 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg= github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0= @@ -58,8 +73,9 @@ github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg3 github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= -github.com/Microsoft/hcsshim v0.8.17 h1:yFHH5bghP9ij5Y34PPaMOE8g//oXZ0uJQeMENVo2zcI= github.com/Microsoft/hcsshim v0.8.17/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= +github.com/Microsoft/hcsshim v0.8.20 h1:ZTwcx3NS8n07kPf/JZ1qwU6vnjhVPMUWlXBF8r9UxrE= +github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -76,6 +92,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -91,7 +108,7 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= @@ -120,8 +137,11 @@ github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.6.1/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= @@ -205,22 +225,22 @@ github.com/containernetworking/cni v0.8.1 h1:7zpDnQ3T3s4ucOuJ/ZCLrYBxzkg0AELFfII github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= -github.com/containers/common v0.40.1 h1:ehhWdMyglWC1+UWMNSZMeIemJ5wCEGP/0oGlCDg4q7M= -github.com/containers/common v0.40.1/go.mod h1:X4F+6vmeAWKMMTNHlOBwOnkf5TQAkQACcuNsKjfcodw= +github.com/containers/common v0.41.1-0.20210721112610-c95d2f794edf h1:z0ciG0ByyJG3WCBpLYd2XLThCC7UBaH7GeSfXY4sAqc= +github.com/containers/common v0.41.1-0.20210721112610-c95d2f794edf/go.mod h1:Ba5YVNCnyX6xDtg1JqEHa2EMVMW5UbHmIyEqsEwpeGE= github.com/containers/image/v5 v5.13.2 h1:AgYunV/9d2fRkrmo23wH2MkqeHolFd6oQCkK+1PpuFA= github.com/containers/image/v5 v5.13.2/go.mod h1:GkWursKDlDcUIT7L7vZf70tADvZCk/Ga0wgS0MuF0ag= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= -github.com/containers/ocicrypt v1.1.1 h1:prL8l9w3ntVqXvNH1CiNn5ENjcCnr38JqpSyvKKB4GI= github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= +github.com/containers/ocicrypt v1.1.2 h1:Ez+GAMP/4GLix5Ywo/fL7O0nY771gsBIigiqUm1aXz0= +github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= github.com/containers/storage v1.32.2/go.mod h1:YIBxxjfXZTi04Ah49sh1uSGfmT1V89+I5i3deRobzQo= -github.com/containers/storage v1.32.5 h1:DXgmyA+oOs7YAzKkEqgC5O8l2UuDGJcwEFbdt49qiak= -github.com/containers/storage v1.32.5/go.mod h1:8/DVVDqniaUlUV0D0q7cEnXK6Bs2uU3FPqNZVPumwEs= +github.com/containers/storage v1.32.6 h1:NqdFRewXO/PYPjgCAScoigZc5QUA21yapSEj6kqD8cw= +github.com/containers/storage v1.32.6/go.mod h1:mdB+b89p+jU8zpzLTVXA0gWMmIo0WrkfGMh1R8O2IQw= 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= github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= @@ -290,6 +310,9 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -350,6 +373,9 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -365,6 +391,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= @@ -375,9 +402,11 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= @@ -387,11 +416,19 @@ github.com/google/go-intervals v0.0.2/go.mod h1:MkaR3LNRfeKLPmqgJYs4E66z5InYjmCj github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -416,6 +453,7 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -443,6 +481,7 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= @@ -485,6 +524,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -497,7 +537,7 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw= github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= 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= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= @@ -531,6 +571,7 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/sys/mount v0.2.0 h1:WhCW5B355jtxndN5ovugJlMFJawbUODuW8fSnEH6SSM= @@ -570,7 +611,6 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.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.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= 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/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= @@ -579,8 +619,8 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa 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/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= -github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/onsi/gomega v1.14.0 h1:ep6kpPVwmr/nTbklSx2nrLNSIO62DoYAhnPNIMhK8gI= +github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= 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= @@ -597,8 +637,9 @@ github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= github.com/opencontainers/runc v1.0.0-rc95/go.mod h1:z+bZxa/+Tz/FmYVWkhUajJdzFeOqjc5vrqskhVyHGUM= -github.com/opencontainers/runc v1.0.0 h1:QOhAQAYUlKeofuyeKdR6ITvOnXLPbEAjPMjz9wCUXcU= github.com/opencontainers/runc v1.0.0/go.mod h1:MU2S3KEB2ZExnhnAQYbwjdYV6HwKtDlNbA2Z2OeNDeA= +github.com/opencontainers/runc v1.0.1 h1:G18PGckGdAm3yVQRWDVQ1rLSLntiniKJ0cNRT2Tm5gs= +github.com/opencontainers/runc v1.0.1/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -620,12 +661,14 @@ github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913/go.mod h1:J6OG github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -666,6 +709,7 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -685,13 +729,16 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= -github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -699,7 +746,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 h1:lIOOHPEbXzO3vnmx2gok1Tfs31Q8GQqKLc8vVqyQq/I= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -755,8 +802,11 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= @@ -766,17 +816,26 @@ go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 h1:A/5uWzF44DlIgdm/PQFwfMkW0JX+cIcQi/SwLAmZP5M= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -785,6 +844,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -813,6 +873,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -821,6 +883,9 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -840,6 +905,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -851,13 +917,24 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 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/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -865,16 +942,25 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -921,11 +1007,18 @@ golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -936,13 +1029,21 @@ golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210216224549-f992740a1bac/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201113234701-d7a72108b828/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -954,6 +1055,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/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/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -997,10 +1099,27 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 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= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1016,12 +1135,26 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1042,10 +1175,32 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a h1:pOwg4OoaRYScjmR4LlLgdtnyoHYTSAVhhqe5uPdpII8= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1058,9 +1213,19 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1086,7 +1251,7 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= @@ -1098,14 +1263,16 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= @@ -1117,6 +1284,7 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= diff --git a/vendor/github.com/containers/buildah/imagebuildah/build.go b/vendor/github.com/containers/buildah/imagebuildah/build.go index a315d7f7d..954ef7f8a 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/build.go +++ b/vendor/github.com/containers/buildah/imagebuildah/build.go @@ -39,7 +39,7 @@ const ( ) // Mount is a mountpoint for the build container. -type Mount specs.Mount +type Mount = specs.Mount type BuildOptions = define.BuildOptions diff --git a/vendor/github.com/containers/buildah/imagebuildah/executor.go b/vendor/github.com/containers/buildah/imagebuildah/executor.go index c754ae3c0..606015ba7 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/executor.go +++ b/vendor/github.com/containers/buildah/imagebuildah/executor.go @@ -165,8 +165,7 @@ func NewExecutor(logger *logrus.Logger, store storage.Store, options define.Buil if err != nil { return nil, err } - - transientMounts = append([]Mount{Mount(mount)}, transientMounts...) + transientMounts = append([]Mount{mount}, transientMounts...) } secrets, err := parse.Secrets(options.CommonBuildOpts.Secrets) @@ -569,7 +568,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image // Build maps of every named base image and every referenced stage root // filesystem. Individual stages can use them to determine whether or // not they can skip certain steps near the end of their stages. - for _, stage := range stages { + for stageIndex, stage := range stages { node := stage.Node // first line for node != nil { // each line for _, child := range node.Children { // tokens on this line, though we only care about the first @@ -589,7 +588,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image // FROM instruction uses argument values, // we might not record the right value here. b.baseMap[base] = true - logrus.Debugf("base: %q", base) + logrus.Debugf("base for stage %d: %q", stageIndex, base) } } case "ADD", "COPY": @@ -601,7 +600,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image // not record the right value here. rootfs := strings.TrimPrefix(flag, "--from=") b.rootfsMap[rootfs] = true - logrus.Debugf("rootfs: %q", rootfs) + logrus.Debugf("rootfs needed for COPY in stage %d: %q", stageIndex, rootfs) } } } diff --git a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go index be105901b..d3d5cc7c4 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go +++ b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go @@ -434,7 +434,7 @@ func (s *StageExecutor) Run(run imagebuilder.Run, config docker.Config) error { Runtime: s.executor.runtime, Args: s.executor.runtimeArgs, NoPivot: os.Getenv("BUILDAH_NOPIVOT") != "", - Mounts: convertMounts(s.executor.transientMounts), + Mounts: append([]Mount{}, s.executor.transientMounts...), Env: config.Env, User: config.User, WorkingDir: config.WorkingDir, @@ -557,13 +557,6 @@ func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBCo OciDecryptConfig: s.executor.ociDecryptConfig, } - // Check and see if the image is a pseudonym for the end result of a - // previous stage, named by an AS clause in the Dockerfile. - s.executor.stagesLock.Lock() - if asImageFound, ok := s.executor.imageMap[from]; ok { - builderOptions.FromImage = asImageFound - } - s.executor.stagesLock.Unlock() builder, err = buildah.NewBuilder(ctx, s.executor.store, builderOptions) if err != nil { return nil, errors.Wrapf(err, "error creating build container") @@ -684,15 +677,20 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, // If the base image's name corresponds to the result of an earlier // stage, make sure that stage has finished building an image, and - // substitute that image's ID for the base image's name here. If not, - // then go on assuming that it's just a regular image that's either in - // local storage, or one that we have to pull from a registry. + // substitute that image's ID for the base image's name here and force + // the pull policy to "never" to avoid triggering an error when it's + // set to "always", which doesn't make sense for image IDs. + // If not, then go on assuming that it's just a regular image that's + // either in local storage, or one that we have to pull from a + // registry, subject to the passed-in pull policy. if isStage, err := s.executor.waitForStage(ctx, base, s.stages[:s.index]); isStage && err != nil { return "", nil, err } + pullPolicy := s.executor.pullPolicy s.executor.stagesLock.Lock() if stageImage, isPreviousStage := s.executor.imageMap[base]; isPreviousStage { base = stageImage + pullPolicy = define.PullNever } s.executor.stagesLock.Unlock() @@ -723,7 +721,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, // Create the (first) working container for this stage. Reinitializing // the imagebuilder configuration may alter the list of steps we have, // so take a snapshot of them *after* that. - if _, err := s.prepare(ctx, base, true, true, s.executor.pullPolicy); err != nil { + if _, err := s.prepare(ctx, base, true, true, pullPolicy); err != nil { return "", nil, err } children := stage.Node.Children diff --git a/vendor/github.com/containers/buildah/imagebuildah/util.go b/vendor/github.com/containers/buildah/imagebuildah/util.go index 7519672bf..598e407a8 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/util.go +++ b/vendor/github.com/containers/buildah/imagebuildah/util.go @@ -2,26 +2,11 @@ package imagebuildah import ( "github.com/containers/buildah" - "github.com/opencontainers/runtime-spec/specs-go" ) // InitReexec is a wrapper for buildah.InitReexec(). It should be called at // the start of main(), and if it returns true, main() should return -// immediately. +// successfully immediately. func InitReexec() bool { return buildah.InitReexec() } - -func convertMounts(mounts []Mount) []specs.Mount { - specmounts := []specs.Mount{} - for _, m := range mounts { - s := specs.Mount{ - Destination: m.Destination, - Type: m.Type, - Source: m.Source, - Options: m.Options, - } - specmounts = append(specmounts, s) - } - return specmounts -} diff --git a/vendor/github.com/containers/buildah/install.md b/vendor/github.com/containers/buildah/install.md index 0cec56c75..30ec26cc3 100644 --- a/vendor/github.com/containers/buildah/install.md +++ b/vendor/github.com/containers/buildah/install.md @@ -153,9 +153,7 @@ sudo apt-get -qq -y install buildah ### Kernel Version Requirements To run Buildah on Red Hat Enterprise Linux or CentOS, version 7.4 or higher is required. -On other Linux distributions Buildah requires a kernel version of 4.0 or -higher in order to support the OverlayFS filesystem. The kernel version can be checked -with the 'uname -a' command. +On other Linux distributions Buildah requires a kernel version that supports the OverlayFS and/or fuse-overlayfs filesystem -- you'll need to consult your distribution's documentation to determine a minimum version number. ### runc Requirement diff --git a/vendor/github.com/containers/buildah/pkg/parse/parse.go b/vendor/github.com/containers/buildah/pkg/parse/parse.go index 0a09dd75a..5ba2f51d0 100644 --- a/vendor/github.com/containers/buildah/pkg/parse/parse.go +++ b/vendor/github.com/containers/buildah/pkg/parse/parse.go @@ -15,6 +15,7 @@ import ( "unicode" "github.com/containers/buildah/define" + "github.com/containers/common/pkg/parse" "github.com/containers/image/v5/types" "github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/unshare" @@ -205,13 +206,13 @@ func Volume(volume string) (specs.Mount, error) { if err := validateVolumeMountHostDir(arr[0]); err != nil { return mount, err } - if err := ValidateVolumeCtrDir(arr[1]); err != nil { + if err := parse.ValidateVolumeCtrDir(arr[1]); err != nil { return mount, err } mountOptions := "" if len(arr) > 2 { mountOptions = arr[2] - if _, err := ValidateVolumeOpts(strings.Split(arr[2], ",")); err != nil { + if _, err := parse.ValidateVolumeOpts(strings.Split(arr[2], ",")); err != nil { return mount, err } } @@ -360,7 +361,7 @@ func GetBindMount(args []string) (specs.Mount, error) { if len(kv) == 1 { return newMount, errors.Wrapf(optionArgError, kv[0]) } - if err := ValidateVolumeHostDir(kv[1]); err != nil { + if err := parse.ValidateVolumeHostDir(kv[1]); err != nil { return newMount, err } newMount.Source = kv[1] @@ -369,7 +370,7 @@ func GetBindMount(args []string) (specs.Mount, error) { if len(kv) == 1 { return newMount, errors.Wrapf(optionArgError, kv[0]) } - if err := ValidateVolumeCtrDir(kv[1]); err != nil { + if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil { return newMount, err } newMount.Destination = kv[1] @@ -391,7 +392,7 @@ func GetBindMount(args []string) (specs.Mount, error) { newMount.Source = newMount.Destination } - opts, err := ValidateVolumeOpts(newMount.Options) + opts, err := parse.ValidateVolumeOpts(newMount.Options) if err != nil { return newMount, err } @@ -433,7 +434,7 @@ func GetTmpfsMount(args []string) (specs.Mount, error) { if len(kv) == 1 { return newMount, errors.Wrapf(optionArgError, kv[0]) } - if err := ValidateVolumeCtrDir(kv[1]); err != nil { + if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil { return newMount, err } newMount.Destination = kv[1] @@ -452,17 +453,7 @@ func GetTmpfsMount(args []string) (specs.Mount, error) { // ValidateVolumeHostDir validates a volume mount's source directory func ValidateVolumeHostDir(hostDir string) error { - if len(hostDir) == 0 { - return errors.Errorf("host directory cannot be empty") - } - if filepath.IsAbs(hostDir) { - if _, err := os.Stat(hostDir); err != nil { - return errors.WithStack(err) - } - } - // If hostDir is not an absolute path, that means the user wants to create a - // named volume. This will be done later on in the code. - return nil + return parse.ValidateVolumeHostDir(hostDir) } // validates the host path of buildah --volume @@ -478,75 +469,12 @@ func validateVolumeMountHostDir(hostDir string) error { // ValidateVolumeCtrDir validates a volume mount's destination directory. func ValidateVolumeCtrDir(ctrDir string) error { - if len(ctrDir) == 0 { - return errors.Errorf("container directory cannot be empty") - } - if !filepath.IsAbs(ctrDir) { - return errors.Errorf("invalid container path %q, must be an absolute path", ctrDir) - } - return nil + return parse.ValidateVolumeCtrDir(ctrDir) } // ValidateVolumeOpts validates a volume's options func ValidateVolumeOpts(options []string) ([]string, error) { - var foundRootPropagation, foundRWRO, foundLabelChange, bindType, foundExec, foundDev, foundSuid, foundChown int - finalOpts := make([]string, 0, len(options)) - for _, opt := range options { - switch opt { - case "noexec", "exec": - foundExec++ - if foundExec > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'noexec' or 'exec' option", strings.Join(options, ", ")) - } - case "nodev", "dev": - foundDev++ - if foundDev > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'nodev' or 'dev' option", strings.Join(options, ", ")) - } - case "nosuid", "suid": - foundSuid++ - if foundSuid > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'nosuid' or 'suid' option", strings.Join(options, ", ")) - } - case "rw", "ro": - foundRWRO++ - if foundRWRO > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'rw' or 'ro' option", strings.Join(options, ", ")) - } - case "z", "Z", "O": - foundLabelChange++ - if foundLabelChange > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'z', 'Z', or 'O' option", strings.Join(options, ", ")) - } - case "U": - foundChown++ - if foundChown > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'U' option", strings.Join(options, ", ")) - } - case "private", "rprivate", "shared", "rshared", "slave", "rslave", "unbindable", "runbindable": - foundRootPropagation++ - if foundRootPropagation > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 '[r]shared', '[r]private', '[r]slave' or '[r]unbindable' option", strings.Join(options, ", ")) - } - case "bind", "rbind": - bindType++ - if bindType > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 '[r]bind' option", strings.Join(options, ", ")) - } - case "cached", "delegated": - // The discarded ops are OS X specific volume options - // introduced in a recent Docker version. - // They have no meaning on Linux, so here we silently - // drop them. This matches Docker's behavior (the options - // are intended to be always safe to use, even not on OS - // X). - continue - default: - return nil, errors.Errorf("invalid option type %q", opt) - } - finalOpts = append(finalOpts, opt) - } - return finalOpts, nil + return parse.ValidateVolumeOpts(options) } // validateExtraHost validates that the specified string is a valid extrahost and returns it. @@ -601,7 +529,7 @@ func SystemContextFromOptions(c *cobra.Command) (*types.SystemContext, error) { creds, err := c.Flags().GetString("creds") if err == nil && c.Flag("creds").Changed { var err error - ctx.DockerAuthConfig, err = getDockerAuth(creds) + ctx.DockerAuthConfig, err = AuthConfig(creds) if err != nil { return nil, err } @@ -734,7 +662,9 @@ func parseCreds(creds string) (string, string) { return up[0], up[1] } -func getDockerAuth(creds string) (*types.DockerAuthConfig, error) { +// AuthConfig parses the creds in format [username[:password] into an auth +// config. +func AuthConfig(creds string) (*types.DockerAuthConfig, error) { username, password := parseCreds(creds) if username == "" { fmt.Print("Username: ") diff --git a/vendor/github.com/containers/buildah/util/util.go b/vendor/github.com/containers/buildah/util/util.go index cf027d4d0..c6f022d4e 100644 --- a/vendor/github.com/containers/buildah/util/util.go +++ b/vendor/github.com/containers/buildah/util/util.go @@ -163,7 +163,7 @@ func FindImage(store storage.Store, firstRegistry string, systemContext *types.S return nil, nil, err } - localImage, _, err := runtime.LookupImage(image, &libimage.LookupImageOptions{IgnorePlatform: true}) + localImage, _, err := runtime.LookupImage(image, nil) if err != nil { return nil, nil, err } diff --git a/vendor/github.com/containers/common/libimage/filters.go b/vendor/github.com/containers/common/libimage/filters.go index 280e06761..0cc5cc311 100644 --- a/vendor/github.com/containers/common/libimage/filters.go +++ b/vendor/github.com/containers/common/libimage/filters.go @@ -63,14 +63,14 @@ func (r *Runtime) compileImageFilters(ctx context.Context, filters []string) ([] switch key { case "after", "since": - img, _, err := r.LookupImage(value, &LookupImageOptions{IgnorePlatform: true}) + img, _, err := r.LookupImage(value, nil) if err != nil { return nil, errors.Wrapf(err, "could not find local image for filter %q", filter) } filterFuncs = append(filterFuncs, filterAfter(img.Created())) case "before": - img, _, err := r.LookupImage(value, &LookupImageOptions{IgnorePlatform: true}) + img, _, err := r.LookupImage(value, nil) if err != nil { return nil, errors.Wrapf(err, "could not find local image for filter %q", filter) } @@ -88,7 +88,7 @@ func (r *Runtime) compileImageFilters(ctx context.Context, filters []string) ([] if err != nil { return nil, errors.Wrapf(err, "non-boolean value %q for dangling filter", value) } - filterFuncs = append(filterFuncs, filterDangling(dangling)) + filterFuncs = append(filterFuncs, filterDangling(ctx, dangling)) case "id": filterFuncs = append(filterFuncs, filterID(value)) @@ -201,9 +201,13 @@ func filterContainers(value bool) filterFunc { } // filterDangling creates a dangling filter for matching the specified value. -func filterDangling(value bool) filterFunc { +func filterDangling(ctx context.Context, value bool) filterFunc { return func(img *Image) (bool, error) { - return img.IsDangling() == value, nil + isDangling, err := img.IsDangling(ctx) + if err != nil { + return false, err + } + return isDangling == value, nil } } diff --git a/vendor/github.com/containers/common/libimage/image.go b/vendor/github.com/containers/common/libimage/image.go index 19b929dc7..5b060a185 100644 --- a/vendor/github.com/containers/common/libimage/image.go +++ b/vendor/github.com/containers/common/libimage/image.go @@ -121,24 +121,29 @@ func (i *Image) IsReadOnly() bool { return i.storageImage.ReadOnly } -// IsDangling returns true if the image is dangling. An image is considered -// dangling if no names are associated with it in the containers storage. -func (i *Image) IsDangling() bool { - return len(i.Names()) == 0 +// IsDangling returns true if the image is dangling, that is an untagged image +// without children. +func (i *Image) IsDangling(ctx context.Context) (bool, error) { + if len(i.Names()) > 0 { + return false, nil + } + children, err := i.getChildren(ctx, false) + if err != nil { + return false, err + } + return len(children) == 0, nil } // IsIntermediate returns true if the image is an intermediate image, that is -// a dangling image without children. +// an untagged image with children. func (i *Image) IsIntermediate(ctx context.Context) (bool, error) { - // If the image has tags, it's not an intermediate one. - if !i.IsDangling() { + if len(i.Names()) > 0 { return false, nil } children, err := i.getChildren(ctx, false) if err != nil { return false, err } - // No tags, no children -> intermediate! return len(children) != 0, nil } @@ -271,7 +276,7 @@ type RemoveImageReport struct { // remove removes the image along with all dangling parent images that no other // image depends on. The image must not be set read-only and not be used by -// containers. +// containers. Returns IDs of removed/untagged images in order. // // If the image is used by containers return storage.ErrImageUsedByContainer. // Use force to remove these containers. @@ -282,7 +287,12 @@ type RemoveImageReport struct { // // This function is internal. Users of libimage should always use // `(*Runtime).RemoveImages()`. -func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, referencedBy string, options *RemoveImagesOptions) error { +func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, referencedBy string, options *RemoveImagesOptions) ([]string, error) { + processedIDs := []string{} + return i.removeRecursive(ctx, rmMap, processedIDs, referencedBy, options) +} + +func (i *Image) removeRecursive(ctx context.Context, rmMap map[string]*RemoveImageReport, processedIDs []string, referencedBy string, options *RemoveImagesOptions) ([]string, error) { // If referencedBy is empty, the image is considered to be removed via // `image remove --all` which alters the logic below. @@ -294,7 +304,7 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, logrus.Debugf("Removing image %s", i.ID()) if i.IsReadOnly() { - return errors.Errorf("cannot remove read-only image %q", i.ID()) + return processedIDs, errors.Errorf("cannot remove read-only image %q", i.ID()) } if i.runtime.eventChannel != nil { @@ -306,7 +316,7 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, if exists { // If the image has already been removed, we're done. if report.Removed { - return nil + return processedIDs, nil } } else { report = &RemoveImageReport{ID: i.ID()} @@ -333,7 +343,7 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, if options.WithSize { size, err := i.Size() if handleError(err) != nil { - return err + return processedIDs, err } report.Size = size } @@ -354,18 +364,18 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, byDigest := strings.HasPrefix(referencedBy, "sha256:") if !options.Force { if byID && numNames > 1 { - return errors.Errorf("unable to delete image %q by ID with more than one tag (%s): please force removal", i.ID(), i.Names()) + return processedIDs, errors.Errorf("unable to delete image %q by ID with more than one tag (%s): please force removal", i.ID(), i.Names()) } else if byDigest && numNames > 1 { // FIXME - Docker will remove the digest but containers storage // does not support that yet, so our hands are tied. - return errors.Errorf("unable to delete image %q by digest with more than one tag (%s): please force removal", i.ID(), i.Names()) + return processedIDs, errors.Errorf("unable to delete image %q by digest with more than one tag (%s): please force removal", i.ID(), i.Names()) } } // Only try to untag if we know it's not an ID or digest. if !byID && !byDigest { if err := i.Untag(referencedBy); handleError(err) != nil { - return err + return processedIDs, err } report.Untagged = append(report.Untagged, referencedBy) @@ -374,14 +384,15 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, } } + processedIDs = append(processedIDs, i.ID()) if skipRemove { - return nil + return processedIDs, nil } // Perform the actual removal. First, remove containers if needed. if options.Force { if err := i.removeContainers(options.RemoveContainerFunc); err != nil { - return err + return processedIDs, err } } @@ -407,7 +418,7 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, } if _, err := i.runtime.store.DeleteImage(i.ID(), true); handleError(err) != nil { - return err + return processedIDs, err } report.Untagged = append(report.Untagged, i.Names()...) @@ -417,27 +428,24 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, // Check if can remove the parent image. if parent == nil { - return nil + return processedIDs, nil } - if !parent.IsDangling() { - return nil - } - - // If the image has siblings, we don't remove the parent. - hasSiblings, err := parent.HasChildren(ctx) + // Only remove the parent if it's dangling, that is being untagged and + // without children. + danglingParent, err := parent.IsDangling(ctx) if err != nil { // See Podman commit fd9dd7065d44: we need to // be tolerant toward corrupted images. logrus.Warnf("error determining if an image is a parent: %v, ignoring the error", err) - hasSiblings = false + danglingParent = false } - if hasSiblings { - return nil + if !danglingParent { + return processedIDs, nil } // Recurse into removing the parent. - return parent.remove(ctx, rmMap, "", options) + return parent.removeRecursive(ctx, rmMap, processedIDs, "", options) } // Tag the image with the specified name and store it in the local containers diff --git a/vendor/github.com/containers/common/libimage/image_tree.go b/vendor/github.com/containers/common/libimage/image_tree.go index b8b9cb216..d48aeeada 100644 --- a/vendor/github.com/containers/common/libimage/image_tree.go +++ b/vendor/github.com/containers/common/libimage/image_tree.go @@ -80,6 +80,10 @@ func (i *Image) Tree(traverseChildren bool) (string, error) { } func imageTreeTraverseChildren(node *layerNode, parent gotree.Tree) error { + if node.layer == nil { + return nil + } + var tags string repoTags, err := node.repoTags() if err != nil { diff --git a/vendor/github.com/containers/common/libimage/import.go b/vendor/github.com/containers/common/libimage/import.go index 2addfdf98..9926aaec7 100644 --- a/vendor/github.com/containers/common/libimage/import.go +++ b/vendor/github.com/containers/common/libimage/import.go @@ -86,16 +86,12 @@ func (r *Runtime) Import(ctx context.Context, path string, options *ImportOption return "", err } - name := options.Tag - if name == "" { - name, err = getImageDigest(ctx, srcRef, r.systemContextCopy()) - if err != nil { - return "", err - } - name = "sha256:" + name[1:] // strip leading "@" + id, err := getImageDigest(ctx, srcRef, r.systemContextCopy()) + if err != nil { + return "", err } - destRef, err := storageTransport.Transport.ParseStoreReference(r.store, name) + destRef, err := storageTransport.Transport.ParseStoreReference(r.store, id) if err != nil { return "", err } @@ -110,5 +106,19 @@ func (r *Runtime) Import(ctx context.Context, path string, options *ImportOption return "", err } - return name, nil + // Strip the leading @ off the id. + name := id[1:] + + // If requested, tag the imported image. + if options.Tag != "" { + image, _, err := r.LookupImage(name, nil) + if err != nil { + return "", errors.Wrap(err, "looking up imported image") + } + if err := image.Tag(options.Tag); err != nil { + return "", err + } + } + + return "sha256:" + name, nil } diff --git a/vendor/github.com/containers/common/libimage/layer_tree.go b/vendor/github.com/containers/common/libimage/layer_tree.go index 4195b43c0..05f21531b 100644 --- a/vendor/github.com/containers/common/libimage/layer_tree.go +++ b/vendor/github.com/containers/common/libimage/layer_tree.go @@ -15,6 +15,9 @@ type layerTree struct { // ociCache is a cache for Image.ID -> OCI Image. Translations are done // on-demand. ociCache map[string]*ociv1.Image + // emptyImages do not have any top-layer so we cannot create a + // *layerNode for them. + emptyImages []*Image } // node returns a layerNode for the specified layerID. @@ -105,6 +108,7 @@ func (r *Runtime) layerTree() (*layerTree, error) { img := images[i] // do not leak loop variable outside the scope topLayer := img.TopLayer() if topLayer == "" { + tree.emptyImages = append(tree.emptyImages, img) continue } node, exists := tree.nodes[topLayer] @@ -126,22 +130,13 @@ func (r *Runtime) layerTree() (*layerTree, error) { // either the same top layer as parent or parent being the true parent layer. // Furthermore, the history of the parent and child images must match with the // parent having one history item less. If all is true, all images are -// returned. Otherwise, the first image is returned. +// returned. Otherwise, the first image is returned. Note that manifest lists +// do not have children. func (t *layerTree) children(ctx context.Context, parent *Image, all bool) ([]*Image, error) { if parent.TopLayer() == "" { - return nil, nil - } - - var children []*Image - - parentNode, exists := t.nodes[parent.TopLayer()] - if !exists { - // Note: erroring out in this case has turned out having been a - // mistake. Users may not be able to recover, so we're now - // throwing a warning to guide them to resolve the issue and - // turn the errors non-fatal. - logrus.Warnf("Layer %s not found in layer tree. The storage may be corrupted, consider running `podman system reset`.", parent.TopLayer()) - return children, nil + if isManifestList, _ := parent.IsManifestList(ctx); isManifestList { + return nil, nil + } } parentID := parent.ID() @@ -163,6 +158,38 @@ func (t *layerTree) children(ctx context.Context, parent *Image, all bool) ([]*I return areParentAndChild(parentOCI, childOCI), nil } + var children []*Image + + // Empty images are special in that they do not have any physical layer + // but yet can have a parent-child relation. Hence, compare the + // "parent" image to all other known empty images. + if parent.TopLayer() == "" { + for i := range t.emptyImages { + empty := t.emptyImages[i] + isParent, err := checkParent(empty) + if err != nil { + return nil, err + } + if isParent { + children = append(children, empty) + if !all { + break + } + } + } + return children, nil + } + + parentNode, exists := t.nodes[parent.TopLayer()] + if !exists { + // Note: erroring out in this case has turned out having been a + // mistake. Users may not be able to recover, so we're now + // throwing a warning to guide them to resolve the issue and + // turn the errors non-fatal. + logrus.Warnf("Layer %s not found in layer tree. The storage may be corrupted, consider running `podman system reset`.", parent.TopLayer()) + return children, nil + } + // addChildrenFrom adds child images of parent to children. Returns // true if any image is a child of parent. addChildrenFromNode := func(node *layerNode) (bool, error) { @@ -204,8 +231,37 @@ func (t *layerTree) children(ctx context.Context, parent *Image, all bool) ([]*I } // parent returns the parent image or nil if no parent image could be found. +// Note that manifest lists do not have parents. func (t *layerTree) parent(ctx context.Context, child *Image) (*Image, error) { if child.TopLayer() == "" { + if isManifestList, _ := child.IsManifestList(ctx); isManifestList { + return nil, nil + } + } + + childID := child.ID() + childOCI, err := t.toOCI(ctx, child) + if err != nil { + return nil, err + } + + // Empty images are special in that they do not have any physical layer + // but yet can have a parent-child relation. Hence, compare the + // "child" image to all other known empty images. + if child.TopLayer() == "" { + for _, empty := range t.emptyImages { + if childID == empty.ID() { + continue + } + emptyOCI, err := t.toOCI(ctx, empty) + if err != nil { + return nil, err + } + // History check. + if areParentAndChild(emptyOCI, childOCI) { + return empty, nil + } + } return nil, nil } @@ -219,14 +275,8 @@ func (t *layerTree) parent(ctx context.Context, child *Image) (*Image, error) { return nil, nil } - childOCI, err := t.toOCI(ctx, child) - if err != nil { - return nil, err - } - // Check images from the parent node (i.e., parent layer) and images // with the same layer (i.e., same top layer). - childID := child.ID() images := node.images if node.parent != nil { images = append(images, node.parent.images...) diff --git a/vendor/github.com/containers/common/libimage/manifest_list.go b/vendor/github.com/containers/common/libimage/manifest_list.go index 73678131c..4e8959004 100644 --- a/vendor/github.com/containers/common/libimage/manifest_list.go +++ b/vendor/github.com/containers/common/libimage/manifest_list.go @@ -78,7 +78,6 @@ func (r *Runtime) LookupManifestList(name string) (*ManifestList, error) { func (r *Runtime) lookupManifestList(name string) (*Image, manifests.List, error) { lookupOptions := &LookupImageOptions{ - IgnorePlatform: true, lookupManifest: true, } image, _, err := r.LookupImage(name, lookupOptions) diff --git a/vendor/github.com/containers/common/libimage/pull.go b/vendor/github.com/containers/common/libimage/pull.go index ee91b17ab..1a6ad1ce2 100644 --- a/vendor/github.com/containers/common/libimage/pull.go +++ b/vendor/github.com/containers/common/libimage/pull.go @@ -10,6 +10,7 @@ import ( "github.com/containers/common/pkg/config" registryTransport "github.com/containers/image/v5/docker" dockerArchiveTransport "github.com/containers/image/v5/docker/archive" + dockerDaemonTransport "github.com/containers/image/v5/docker/daemon" "github.com/containers/image/v5/docker/reference" ociArchiveTransport "github.com/containers/image/v5/oci/archive" ociTransport "github.com/containers/image/v5/oci/layout" @@ -55,13 +56,20 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP var possiblyUnqualifiedName string // used for short-name resolution ref, err := alltransports.ParseImageName(name) if err != nil { + // Check whether `name` points to a transport. If so, we + // return the error. Otherwise we assume that `name` refers to + // an image on a registry (e.g., "fedora"). + if alltransports.TransportFromImageName(name) != nil { + return nil, err + } + // If the image clearly refers to a local one, we can look it up directly. // In fact, we need to since they are not parseable. if strings.HasPrefix(name, "sha256:") || (len(name) == 64 && !strings.ContainsAny(name, "/.:@")) { if pullPolicy == config.PullPolicyAlways { return nil, errors.Errorf("pull policy is always but image has been referred to by ID (%s)", name) } - local, _, err := r.LookupImage(name, &LookupImageOptions{IgnorePlatform: true}) + local, _, err := r.LookupImage(name, nil) if err != nil { return nil, err } @@ -146,7 +154,7 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP localImages := []*Image{} for _, name := range pulledImages { - local, _, err := r.LookupImage(name, &LookupImageOptions{IgnorePlatform: true}) + local, _, err := r.LookupImage(name, nil) if err != nil { return nil, errors.Wrapf(err, "error locating pulled image %q name in containers storage", name) } @@ -169,6 +177,15 @@ func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference, var storageName, imageName string switch ref.Transport().Name() { + case dockerDaemonTransport.Transport.Name(): + // Normalize to docker.io if needed (see containers/podman/issues/10998). + named, err := reference.ParseNormalizedNamed(ref.StringWithinTransport()) + if err != nil { + return nil, err + } + imageName = named.String() + storageName = imageName + case ociTransport.Transport.Name(): split := strings.SplitN(ref.StringWithinTransport(), ":", 2) storageName = toLocalImageName(split[0]) @@ -362,15 +379,13 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str // resolved name for pulling. Assume we're doing a `pull foo`. // If there's already a local image "localhost/foo", then we should // attempt pulling that instead of doing the full short-name dance. - lookupOptions := &LookupImageOptions{ - // NOTE: we must ignore the platform of a local image when - // doing lookups. Some images set an incorrect or even invalid - // platform (see containers/podman/issues/10682). Doing the - // lookup while ignoring the platform checks prevents - // redundantly downloading the same image. - IgnorePlatform: true, - } - localImage, resolvedImageName, err = r.LookupImage(imageName, lookupOptions) + // + // NOTE: we must ignore the platform of a local image when doing + // lookups here, even if arch/os/variant is set. Some images set an + // incorrect or even invalid platform (see containers/podman/issues/10682). + // Doing the lookup while ignoring the platform checks prevents + // redundantly downloading the same image. + localImage, resolvedImageName, err = r.LookupImage(imageName, nil) if err != nil && errors.Cause(err) != storage.ErrImageUnknown { logrus.Errorf("Looking up %s in local storage: %v", imageName, err) } @@ -396,8 +411,23 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str // very likely a bug but a consistent one in Podman/Buildah and should // be addressed at a later point. if pullPolicy != config.PullPolicyAlways { - logrus.Debugf("Enforcing pull policy to %q to support custom platform (arch: %q, os: %q, variant: %q)", "always", options.Architecture, options.OS, options.Variant) - pullPolicy = config.PullPolicyAlways + switch { + // User input clearly refer to a local image. + case strings.HasPrefix(imageName, "localhost/"): + logrus.Debugf("Enforcing pull policy to %q to support custom platform (arch: %q, os: %q, variant: %q)", "never", options.Architecture, options.OS, options.Variant) + pullPolicy = config.PullPolicyNever + + // Image resolved to a local one, so let's still have a + // look at the registries or aliases but use it + // otherwise. + case strings.HasPrefix(resolvedImageName, "localhost/"): + logrus.Debugf("Enforcing pull policy to %q to support custom platform (arch: %q, os: %q, variant: %q)", "newer", options.Architecture, options.OS, options.Variant) + pullPolicy = config.PullPolicyNewer + + default: + logrus.Debugf("Enforcing pull policy to %q to support custom platform (arch: %q, os: %q, variant: %q)", "always", options.Architecture, options.OS, options.Variant) + pullPolicy = config.PullPolicyAlways + } } } diff --git a/vendor/github.com/containers/common/libimage/push.go b/vendor/github.com/containers/common/libimage/push.go index 1896b796f..7203838aa 100644 --- a/vendor/github.com/containers/common/libimage/push.go +++ b/vendor/github.com/containers/common/libimage/push.go @@ -31,8 +31,7 @@ func (r *Runtime) Push(ctx context.Context, source, destination string, options // Look up the local image. Note that we need to ignore the platform // and push what the user specified (containers/podman/issues/10344). - lookupOptions := &LookupImageOptions{IgnorePlatform: true} - image, resolvedSource, err := r.LookupImage(source, lookupOptions) + image, resolvedSource, err := r.LookupImage(source, nil) if err != nil { return nil, err } diff --git a/vendor/github.com/containers/common/libimage/runtime.go b/vendor/github.com/containers/common/libimage/runtime.go index d07d6a83a..26a04dad5 100644 --- a/vendor/github.com/containers/common/libimage/runtime.go +++ b/vendor/github.com/containers/common/libimage/runtime.go @@ -3,8 +3,6 @@ package libimage import ( "context" "os" - "path/filepath" - "runtime" "strings" "github.com/containers/image/v5/docker/reference" @@ -95,10 +93,6 @@ func RuntimeFromStore(store storage.Store, options *RuntimeOptions) (*Runtime, e setRegistriesConfPath(&systemContext) - if systemContext.BlobInfoCacheDir == "" { - systemContext.BlobInfoCacheDir = filepath.Join(store.GraphRoot(), "cache") - } - return &Runtime{ store: store, systemContext: systemContext, @@ -142,7 +136,7 @@ func (r *Runtime) storageToImage(storageImage *storage.Image, ref types.ImageRef // Exists returns true if the specicifed image exists in the local containers // storage. Note that it may return false if an image corrupted. func (r *Runtime) Exists(name string) (bool, error) { - image, _, err := r.LookupImage(name, &LookupImageOptions{IgnorePlatform: true}) + image, _, err := r.LookupImage(name, nil) if err != nil && errors.Cause(err) != storage.ErrImageUnknown { return false, err } @@ -158,11 +152,6 @@ func (r *Runtime) Exists(name string) (bool, error) { // LookupImageOptions allow for customizing local image lookups. type LookupImageOptions struct { - // If set, the image will be purely looked up by name. No matching to - // the current platform will be performed. This can be helpful when - // the platform does not matter, for instance, for image removal. - IgnorePlatform bool - // Lookup an image matching the specified architecture. Architecture string // Lookup an image matching the specified OS. @@ -173,13 +162,23 @@ type LookupImageOptions struct { // If set, do not look for items/instances in the manifest list that // match the current platform but return the manifest list as is. lookupManifest bool + + // If the image resolves to a manifest list, we usually lookup a + // matching instance and error if none could be found. In this case, + // just return the manifest list. Required for image removal. + returnManifestIfNoInstance bool } -// Lookup Image looks up `name` in the local container storage matching the -// specified SystemContext. Returns the image and the name it has been found -// with. Note that name may also use the `containers-storage:` prefix used to -// refer to the containers-storage transport. Returns storage.ErrImageUnknown -// if the image could not be found. +// Lookup Image looks up `name` in the local container storage. Returns the +// image and the name it has been found with. Note that name may also use the +// `containers-storage:` prefix used to refer to the containers-storage +// transport. Returns storage.ErrImageUnknown if the image could not be found. +// +// Unless specified via the options, the image will be looked up by name only +// without matching the architecture, os or variant. An exception is if the +// image resolves to a manifest list, where an instance of the manifest list +// matching the local or specified platform (via options.{Architecture,OS,Variant}) +// is returned. // // If the specified name uses the `containers-storage` transport, the resolved // name is empty. @@ -221,23 +220,17 @@ func (r *Runtime) LookupImage(name string, options *LookupImageOptions) (*Image, name = strings.TrimPrefix(name, "sha256:") } - // Set the platform for matching local images. - if !options.IgnorePlatform { - if options.Architecture == "" { - options.Architecture = r.systemContext.ArchitectureChoice - } - if options.Architecture == "" { - options.Architecture = runtime.GOARCH - } - if options.OS == "" { - options.OS = r.systemContext.OSChoice - } - if options.OS == "" { - options.OS = runtime.GOOS - } - if options.Variant == "" { - options.Variant = r.systemContext.VariantChoice - } + // Unless specified, set the platform specified in the system context + // for later platform matching. Builder likes to set these things via + // the system context at runtime creation. + if options.Architecture == "" { + options.Architecture = r.systemContext.ArchitectureChoice + } + if options.OS == "" { + options.OS = r.systemContext.OSChoice + } + if options.Variant == "" { + options.Variant = r.systemContext.VariantChoice } // First, check if we have an exact match in the storage. Maybe an ID @@ -327,10 +320,8 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo } instance, err := manifestList.LookupInstance(context.Background(), options.Architecture, options.OS, options.Variant) if err != nil { - // NOTE: If we are not looking for a specific platform - // and already found the manifest list, then return it - // instead of the error. - if options.IgnorePlatform { + if options.returnManifestIfNoInstance { + logrus.Debug("No matching instance was found: returning manifest list instead") return image, nil } return nil, errors.Wrap(storage.ErrImageUnknown, err.Error()) @@ -342,10 +333,6 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo image = instance } - if options.IgnorePlatform { - return image, nil - } - matches, err := r.imageReferenceMatchesContext(ref, options) if err != nil { return nil, err @@ -440,7 +427,7 @@ func (r *Runtime) ResolveName(name string) (string, error) { if name == "" { return "", nil } - image, resolvedName, err := r.LookupImage(name, &LookupImageOptions{IgnorePlatform: true}) + image, resolvedName, err := r.LookupImage(name, nil) if err != nil && errors.Cause(err) != storage.ErrImageUnknown { return "", err } @@ -460,9 +447,10 @@ func (r *Runtime) ResolveName(name string) (string, error) { // imageReferenceMatchesContext return true if the specified reference matches // the platform (os, arch, variant) as specified by the lookup options. func (r *Runtime) imageReferenceMatchesContext(ref types.ImageReference, options *LookupImageOptions) (bool, error) { - if options.IgnorePlatform { + if options.Architecture+options.OS+options.Variant == "" { return true, nil } + ctx := context.Background() img, err := ref.NewImage(ctx, &r.systemContext) if err != nil { @@ -473,12 +461,18 @@ func (r *Runtime) imageReferenceMatchesContext(ref types.ImageReference, options if err != nil { return false, err } - if options.OS == data.Os && options.Architecture == data.Architecture { - if options.Variant == "" || options.Variant == data.Variant { - return true, nil - } + + if options.Architecture != "" && options.Architecture != data.Architecture { + return false, err + } + if options.OS != "" && options.OS != data.Os { + return false, err + } + if options.Variant != "" && options.Variant != data.Variant { + return false, err } - return false, nil + + return true, nil } // ListImagesOptions allow for customizing listing images. @@ -503,9 +497,8 @@ func (r *Runtime) ListImages(ctx context.Context, names []string, options *ListI var images []*Image if len(names) > 0 { - lookupOpts := LookupImageOptions{IgnorePlatform: true} for _, name := range names { - image, _, err := r.LookupImage(name, &lookupOpts) + image, _, err := r.LookupImage(name, nil) if err != nil { return nil, err } @@ -594,34 +587,29 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem rmErrors = append(rmErrors, err) } - orderedIDs := []string{} // determinism and relative order deleteMap := make(map[string]*deleteMe) // ID -> deleteMe - + toDelete := []string{} // Look up images in the local containers storage and fill out - // orderedIDs and the deleteMap. + // toDelete and the deleteMap. switch { case len(names) > 0: // Look up the images one-by-one. That allows for removing // images that have been looked up successfully while reporting // lookup errors at the end. - lookupOptions := LookupImageOptions{IgnorePlatform: true} for _, name := range names { - img, resolvedName, err := r.LookupImage(name, &lookupOptions) + img, resolvedName, err := r.LookupImage(name, &LookupImageOptions{returnManifestIfNoInstance: true}) if err != nil { appendError(err) continue } dm, exists := deleteMap[img.ID()] if !exists { - orderedIDs = append(orderedIDs, img.ID()) + toDelete = append(toDelete, img.ID()) dm = &deleteMe{image: img} deleteMap[img.ID()] = dm } dm.referencedBy = append(dm.referencedBy, resolvedName) } - if len(orderedIDs) == 0 { - return nil, rmErrors - } default: filteredImages, err := r.ListImages(ctx, nil, &ListImagesOptions{Filters: options.Filters}) @@ -630,14 +618,21 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem return nil, rmErrors } for _, img := range filteredImages { - orderedIDs = append(orderedIDs, img.ID()) + toDelete = append(toDelete, img.ID()) deleteMap[img.ID()] = &deleteMe{image: img} } } + // Return early if there's no image to delete. + if len(deleteMap) == 0 { + return nil, rmErrors + } + // Now remove the images in the given order. rmMap := make(map[string]*RemoveImageReport) - for _, id := range orderedIDs { + orderedIDs := []string{} + visitedIDs := make(map[string]bool) + for _, id := range toDelete { del, exists := deleteMap[id] if !exists { appendError(errors.Errorf("internal error: ID %s not in found in image-deletion map", id)) @@ -647,9 +642,17 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem del.referencedBy = []string{""} } for _, ref := range del.referencedBy { - if err := del.image.remove(ctx, rmMap, ref, options); err != nil { + processedIDs, err := del.image.remove(ctx, rmMap, ref, options) + if err != nil { appendError(err) - continue + } + // NOTE: make sure to add given ID only once to orderedIDs. + for _, id := range processedIDs { + if visited := visitedIDs[id]; visited { + continue + } + orderedIDs = append(orderedIDs, id) + visitedIDs[id] = true } } } diff --git a/vendor/github.com/containers/common/libimage/save.go b/vendor/github.com/containers/common/libimage/save.go index 10d26bebf..e1b8c3f75 100644 --- a/vendor/github.com/containers/common/libimage/save.go +++ b/vendor/github.com/containers/common/libimage/save.go @@ -74,7 +74,7 @@ func (r *Runtime) Save(ctx context.Context, names []string, format, path string, // saveSingleImage saves the specified image name to the specified path. // Supported formats are "oci-archive", "oci-dir" and "docker-dir". func (r *Runtime) saveSingleImage(ctx context.Context, name, format, path string, options *SaveOptions) error { - image, imageName, err := r.LookupImage(name, &LookupImageOptions{IgnorePlatform: true}) + image, imageName, err := r.LookupImage(name, nil) if err != nil { return err } @@ -155,7 +155,7 @@ func (r *Runtime) saveDockerArchive(ctx context.Context, names []string, path st visitedNames := make(map[string]bool) // filters duplicate names for _, name := range names { // Look up local images. - image, imageName, err := r.LookupImage(name, &LookupImageOptions{IgnorePlatform: true}) + image, imageName, err := r.LookupImage(name, nil) if err != nil { return err } diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go index 68076b117..84876026d 100644 --- a/vendor/github.com/containers/common/pkg/config/config.go +++ b/vendor/github.com/containers/common/pkg/config/config.go @@ -158,6 +158,13 @@ type ContainersConfig struct { // PidNS indicates how to create a pid namespace for the container PidNS string `toml:"pidns,omitempty"` + // Copy the content from the underlying image into the newly created + // volume when the container is created instead of when it is started. + // If false, the container engine will not copy the content until + // the container is started. Setting it to true may have negative + // performance implications. + PrepareVolumeOnCreate bool `toml:"prepare_volume_on_create,omitempty"` + // RootlessNetworking depicts the "kind" of networking for rootless // containers. Valid options are `slirp4netns` and `cni`. Default is // `slirp4netns` @@ -384,6 +391,10 @@ type EngineConfig struct { // will refer to the plugin as) mapped to a path, which must point to a // Unix socket that conforms to the Volume Plugin specification. VolumePlugins map[string]string `toml:"volume_plugins,omitempty"` + + // ChownCopiedFiles tells the container engine whether to chown files copied + // into a container to the container's primary uid/gid. + ChownCopiedFiles bool `toml:"chown_copied_files"` } // SetOptions contains a subset of options in a Config. It's used to indicate if diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf index 0c8c7532e..f429b96ed 100644 --- a/vendor/github.com/containers/common/pkg/config/containers.conf +++ b/vendor/github.com/containers/common/pkg/config/containers.conf @@ -189,6 +189,13 @@ default_sysctls = [ # # pids_limit = 2048 +# Copy the content from the underlying image into the newly created volume +# when the container is created instead of when it is started. If false, +# the container engine will not copy the content until the container is started. +# Setting it to true may have negative performance implications. +# +# prepare_volume_on_create = false + # Indicates the networking to be used for rootless containers # rootless_networking = "slirp4netns" @@ -243,6 +250,12 @@ default_sysctls = [ # The network table contains settings pertaining to the management of # CNI plugins. +[secrets] +# driver = "file" + +[secrets.opts] +# root = "/example/directory" + [network] # Path to directory where CNI plugin binaries are located. @@ -503,9 +516,3 @@ default_sysctls = [ # TOML does not provide a way to end a table other than a further table being # defined, so every key hereafter will be part of [volume_plugins] and not the # main config. - -[secret] -# driver = "file" - -[secret.opts] -# root = "/example/directory" diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go index 5abb6326f..a16dd0e02 100644 --- a/vendor/github.com/containers/common/pkg/config/default.go +++ b/vendor/github.com/containers/common/pkg/config/default.go @@ -340,6 +340,8 @@ func defaultConfigFromMemory() (*EngineConfig, error) { c.LockType = "shm" c.MachineEnabled = false + c.ChownCopiedFiles = true + return c, nil } diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go index 8907e21ab..47dca527c 100644 --- a/vendor/github.com/containers/common/version/version.go +++ b/vendor/github.com/containers/common/version/version.go @@ -1,4 +1,4 @@ package version // Version is the version of the build. -const Version = "0.40.2-dev" +const Version = "0.41.1-dev" diff --git a/vendor/github.com/containers/image/v5/copy/copy.go b/vendor/github.com/containers/image/v5/copy/copy.go index 62f47c013..9bc479d23 100644 --- a/vendor/github.com/containers/image/v5/copy/copy.go +++ b/vendor/github.com/containers/image/v5/copy/copy.go @@ -92,7 +92,7 @@ func (d *digestingReader) Read(p []byte) (int, error) { // Coverage: This should not happen, the hash.Hash interface requires // d.digest.Write to never return an error, and the io.Writer interface // requires n2 == len(input) if no error is returned. - return 0, errors.Wrapf(err, "Error updating digest during verification: %d vs. %d", n2, n) + return 0, errors.Wrapf(err, "updating digest during verification: %d vs. %d", n2, n) } } if err == io.EOF { @@ -123,6 +123,7 @@ type copier struct { ociEncryptConfig *encconfig.EncryptConfig maxParallelDownloads uint downloadForeignLayers bool + fetchPartialBlobs bool } // imageCopier tracks state specific to a single image (possibly an item of a manifest list) @@ -194,15 +195,21 @@ type Options struct { // OciDecryptConfig contains the config that can be used to decrypt an image if it is // encrypted if non-nil. If nil, it does not attempt to decrypt an image. OciDecryptConfig *encconfig.DecryptConfig + // MaxParallelDownloads indicates the maximum layers to pull at the same time. A reasonable default is used if this is left as 0. MaxParallelDownloads uint + // When OptimizeDestinationImageAlreadyExists is set, optimize the copy assuming that the destination image already // exists (and is equivalent). Making the eventual (no-op) copy more performant for this case. Enabling the option // is slightly pessimistic if the destination image doesn't exist, or is not equivalent. OptimizeDestinationImageAlreadyExists bool + // Download layer contents with "nondistributable" media types ("foreign" layers) and translate the layer media type // to not indicate "nondistributable". DownloadForeignLayers bool + + // FetchPartialBlobs indicates whether to attempt to fetch the blob partially. Experimental. + FetchPartialBlobs bool } // validateImageListSelection returns an error if the passed-in value is not one that we recognize as a valid ImageListSelection value @@ -240,7 +247,7 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, dest, err := destRef.NewImageDestination(ctx, options.DestinationCtx) if err != nil { - return nil, errors.Wrapf(err, "Error initializing destination %s", transports.ImageName(destRef)) + return nil, errors.Wrapf(err, "initializing destination %s", transports.ImageName(destRef)) } defer func() { if err := dest.Close(); err != nil { @@ -250,7 +257,7 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, rawSource, err := srcRef.NewImageSource(ctx, options.SourceCtx) if err != nil { - return nil, errors.Wrapf(err, "Error initializing source %s", transports.ImageName(srcRef)) + return nil, errors.Wrapf(err, "initializing source %s", transports.ImageName(srcRef)) } defer func() { if err := rawSource.Close(); err != nil { @@ -283,6 +290,7 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, ociEncryptConfig: options.OciEncryptConfig, maxParallelDownloads: options.MaxParallelDownloads, downloadForeignLayers: options.DownloadForeignLayers, + fetchPartialBlobs: options.FetchPartialBlobs, } // Default to using gzip compression unless specified otherwise. if options.DestinationCtx == nil || options.DestinationCtx.CompressionFormat == nil { @@ -302,7 +310,7 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, unparsedToplevel := image.UnparsedInstance(rawSource, nil) multiImage, err := isMultiImage(ctx, unparsedToplevel) if err != nil { - return nil, errors.Wrapf(err, "Error determining manifest MIME type for %s", transports.ImageName(srcRef)) + return nil, errors.Wrapf(err, "determining manifest MIME type for %s", transports.ImageName(srcRef)) } if !multiImage { @@ -315,15 +323,15 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, // matches the current system to copy, and copy it. mfest, manifestType, err := unparsedToplevel.Manifest(ctx) if err != nil { - return nil, errors.Wrapf(err, "Error reading manifest for %s", transports.ImageName(srcRef)) + return nil, errors.Wrapf(err, "reading manifest for %s", transports.ImageName(srcRef)) } manifestList, err := manifest.ListFromBlob(mfest, manifestType) if err != nil { - return nil, errors.Wrapf(err, "Error parsing primary manifest as list for %s", transports.ImageName(srcRef)) + return nil, errors.Wrapf(err, "parsing primary manifest as list for %s", transports.ImageName(srcRef)) } instanceDigest, err := manifestList.ChooseInstance(options.SourceCtx) // try to pick one that matches options.SourceCtx if err != nil { - return nil, errors.Wrapf(err, "Error choosing an image from manifest list %s", transports.ImageName(srcRef)) + return nil, errors.Wrapf(err, "choosing an image from manifest list %s", transports.ImageName(srcRef)) } logrus.Debugf("Source is a manifest list; copying (only) instance %s for current system", instanceDigest) unparsedInstance := image.UnparsedInstance(rawSource, &instanceDigest) @@ -334,7 +342,7 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, } else { /* options.ImageListSelection == CopyAllImages or options.ImageListSelection == CopySpecificImages, */ // If we were asked to copy multiple images and can't, that's an error. if !supportsMultipleImages(c.dest) { - return nil, errors.Errorf("Error copying multiple images: destination transport %q does not support copying multiple images as a group", destRef.Transport().Name()) + return nil, errors.Errorf("copying multiple images: destination transport %q does not support copying multiple images as a group", destRef.Transport().Name()) } // Copy some or all of the images. switch options.ImageListSelection { @@ -343,13 +351,13 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, case CopySpecificImages: logrus.Debugf("Source is a manifest list; copying some instances") } - if copiedManifest, _, err = c.copyMultipleImages(ctx, policyContext, options, unparsedToplevel); err != nil { + if copiedManifest, err = c.copyMultipleImages(ctx, policyContext, options, unparsedToplevel); err != nil { return nil, err } } if err := c.dest.Commit(ctx, unparsedToplevel); err != nil { - return nil, errors.Wrap(err, "Error committing the finished image") + return nil, errors.Wrap(err, "committing the finished image") } return copiedManifest, nil @@ -376,12 +384,12 @@ func supportsMultipleImages(dest types.ImageDestination) bool { func compareImageDestinationManifestEqual(ctx context.Context, options *Options, src types.Image, targetInstance *digest.Digest, dest types.ImageDestination) (bool, []byte, string, digest.Digest, error) { srcManifest, _, err := src.Manifest(ctx) if err != nil { - return false, nil, "", "", errors.Wrapf(err, "Error reading manifest from image") + return false, nil, "", "", errors.Wrapf(err, "reading manifest from image") } srcManifestDigest, err := manifest.Digest(srcManifest) if err != nil { - return false, nil, "", "", errors.Wrapf(err, "Error calculating manifest digest") + return false, nil, "", "", errors.Wrapf(err, "calculating manifest digest") } destImageSource, err := dest.Reference().NewImageSource(ctx, options.DestinationCtx) @@ -398,7 +406,7 @@ func compareImageDestinationManifestEqual(ctx context.Context, options *Options, destManifestDigest, err := manifest.Digest(destManifest) if err != nil { - return false, nil, "", "", errors.Wrapf(err, "Error calculating manifest digest") + return false, nil, "", "", errors.Wrapf(err, "calculating manifest digest") } logrus.Debugf("Comparing source and destination manifest digests: %v vs. %v", srcManifestDigest, destManifestDigest) @@ -412,15 +420,15 @@ func compareImageDestinationManifestEqual(ctx context.Context, options *Options, // copyMultipleImages copies some or all of an image list's instances, using // policyContext to validate source image admissibility. -func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signature.PolicyContext, options *Options, unparsedToplevel *image.UnparsedImage) (copiedManifest []byte, copiedManifestType string, retErr error) { +func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signature.PolicyContext, options *Options, unparsedToplevel *image.UnparsedImage) (copiedManifest []byte, retErr error) { // Parse the list and get a copy of the original value after it's re-encoded. manifestList, manifestType, err := unparsedToplevel.Manifest(ctx) if err != nil { - return nil, "", errors.Wrapf(err, "Error reading manifest list") + return nil, errors.Wrapf(err, "reading manifest list") } originalList, err := manifest.ListFromBlob(manifestList, manifestType) if err != nil { - return nil, "", errors.Wrapf(err, "Error parsing manifest list %q", string(manifestList)) + return nil, errors.Wrapf(err, "parsing manifest list %q", string(manifestList)) } updatedList := originalList.Clone() @@ -432,14 +440,14 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur c.Printf("Getting image list signatures\n") s, err := c.rawSource.GetSignatures(ctx, nil) if err != nil { - return nil, "", errors.Wrap(err, "Error reading signatures") + return nil, errors.Wrap(err, "reading signatures") } sigs = s } if len(sigs) != 0 { c.Printf("Checking if image list destination supports signatures\n") if err := c.dest.SupportsSignatures(ctx); err != nil { - return nil, "", errors.Wrapf(err, "Can not copy signatures to %s", transports.ImageName(c.dest.Reference())) + return nil, errors.Wrapf(err, "Can not copy signatures to %s", transports.ImageName(c.dest.Reference())) } } canModifyManifestList := (len(sigs) == 0) @@ -454,11 +462,11 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur } selectedListType, otherManifestMIMETypeCandidates, err := c.determineListConversion(manifestType, c.dest.SupportedManifestMIMETypes(), forceListMIMEType) if err != nil { - return nil, "", errors.Wrapf(err, "Error determining manifest list type to write to destination") + return nil, errors.Wrapf(err, "determining manifest list type to write to destination") } if selectedListType != originalList.MIMEType() { if !canModifyManifestList { - return nil, "", errors.Errorf("Error: manifest list must be converted to type %q to be written to destination, but that would invalidate signatures", selectedListType) + return nil, errors.Errorf("manifest list must be converted to type %q to be written to destination, but that would invalidate signatures", selectedListType) } } @@ -483,7 +491,7 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur if skip { update, err := updatedList.Instance(instanceDigest) if err != nil { - return nil, "", err + return nil, err } logrus.Debugf("Skipping instance %s (%d/%d)", instanceDigest, i+1, len(instanceDigests)) // Record the digest/size/type of the manifest that we didn't copy. @@ -496,7 +504,7 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur unparsedInstance := image.UnparsedInstance(c.rawSource, &instanceDigest) updatedManifest, updatedManifestType, updatedManifestDigest, err := c.copyOneImage(ctx, policyContext, options, unparsedToplevel, unparsedInstance, &instanceDigest) if err != nil { - return nil, "", err + return nil, err } instancesCopied++ // Record the result of a possible conversion here. @@ -510,7 +518,7 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur // Now reset the digest/size/types of the manifests in the list to account for any conversions that we made. if err = updatedList.UpdateInstances(updates); err != nil { - return nil, "", errors.Wrapf(err, "Error updating manifest list") + return nil, errors.Wrapf(err, "updating manifest list") } // Iterate through supported list types, preferred format first. @@ -525,7 +533,7 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur if thisListType != updatedList.MIMEType() { attemptedList, err = updatedList.ConvertToMIMEType(thisListType) if err != nil { - return nil, "", errors.Wrapf(err, "Error converting manifest list to list with MIME type %q", thisListType) + return nil, errors.Wrapf(err, "converting manifest list to list with MIME type %q", thisListType) } } @@ -533,17 +541,17 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur // by serializing them both so that we can compare them. attemptedManifestList, err := attemptedList.Serialize() if err != nil { - return nil, "", errors.Wrapf(err, "Error encoding updated manifest list (%q: %#v)", updatedList.MIMEType(), updatedList.Instances()) + return nil, errors.Wrapf(err, "encoding updated manifest list (%q: %#v)", updatedList.MIMEType(), updatedList.Instances()) } originalManifestList, err := originalList.Serialize() if err != nil { - return nil, "", errors.Wrapf(err, "Error encoding original manifest list for comparison (%q: %#v)", originalList.MIMEType(), originalList.Instances()) + return nil, errors.Wrapf(err, "encoding original manifest list for comparison (%q: %#v)", originalList.MIMEType(), originalList.Instances()) } // If we can't just use the original value, but we have to change it, flag an error. if !bytes.Equal(attemptedManifestList, originalManifestList) { if !canModifyManifestList { - return nil, "", errors.Errorf("Error: manifest list must be converted to type %q to be written to destination, but that would invalidate signatures", thisListType) + return nil, errors.Errorf(" manifest list must be converted to type %q to be written to destination, but that would invalidate signatures", thisListType) } logrus.Debugf("Manifest list has been updated") } else { @@ -563,24 +571,24 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur break } if errs != nil { - return nil, "", fmt.Errorf("Uploading manifest list failed, attempted the following formats: %s", strings.Join(errs, ", ")) + return nil, fmt.Errorf("Uploading manifest list failed, attempted the following formats: %s", strings.Join(errs, ", ")) } // Sign the manifest list. if options.SignBy != "" { newSig, err := c.createSignature(manifestList, options.SignBy) if err != nil { - return nil, "", err + return nil, err } sigs = append(sigs, newSig) } c.Printf("Storing list signatures\n") if err := c.dest.PutSignatures(ctx, sigs, nil); err != nil { - return nil, "", errors.Wrap(err, "Error writing signatures") + return nil, errors.Wrap(err, "writing signatures") } - return manifestList, selectedListType, nil + return manifestList, nil } // copyOneImage copies a single (non-manifest-list) image unparsedImage, using policyContext to validate @@ -591,7 +599,7 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli multiImage, err := isMultiImage(ctx, unparsedImage) if err != nil { // FIXME FIXME: How to name a reference for the sub-image? - return nil, "", "", errors.Wrapf(err, "Error determining manifest MIME type for %s", transports.ImageName(unparsedImage.Reference())) + return nil, "", "", errors.Wrapf(err, "determining manifest MIME type for %s", transports.ImageName(unparsedImage.Reference())) } if multiImage { return nil, "", "", fmt.Errorf("Unexpectedly received a manifest list instead of a manifest for a single image") @@ -605,7 +613,7 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli } src, err := image.FromUnparsedImage(ctx, options.SourceCtx, unparsedImage) if err != nil { - return nil, "", "", errors.Wrapf(err, "Error initializing image from source %s", transports.ImageName(c.rawSource.Reference())) + return nil, "", "", errors.Wrapf(err, "initializing image from source %s", transports.ImageName(c.rawSource.Reference())) } // If the destination is a digested reference, make a note of that, determine what digest value we're @@ -617,20 +625,20 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli destIsDigestedReference = true sourceManifest, _, err := src.Manifest(ctx) if err != nil { - return nil, "", "", errors.Wrapf(err, "Error reading manifest from source image") + return nil, "", "", errors.Wrapf(err, "reading manifest from source image") } matches, err := manifest.MatchesDigest(sourceManifest, digested.Digest()) if err != nil { - return nil, "", "", errors.Wrapf(err, "Error computing digest of source image's manifest") + return nil, "", "", errors.Wrapf(err, "computing digest of source image's manifest") } if !matches { manifestList, _, err := unparsedToplevel.Manifest(ctx) if err != nil { - return nil, "", "", errors.Wrapf(err, "Error reading manifest from source image") + return nil, "", "", errors.Wrapf(err, "reading manifest from source image") } matches, err = manifest.MatchesDigest(manifestList, digested.Digest()) if err != nil { - return nil, "", "", errors.Wrapf(err, "Error computing digest of source image's manifest") + return nil, "", "", errors.Wrapf(err, "computing digest of source image's manifest") } if !matches { return nil, "", "", errors.New("Digest of source image's manifest would not match destination reference") @@ -650,7 +658,7 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli c.Printf("Getting image source signatures\n") s, err := src.Signatures(ctx) if err != nil { - return nil, "", "", errors.Wrap(err, "Error reading signatures") + return nil, "", "", errors.Wrap(err, "reading signatures") } sigs = s } @@ -785,7 +793,7 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli c.Printf("Storing signatures\n") if err := c.dest.PutSignatures(ctx, sigs, targetInstance); err != nil { - return nil, "", "", errors.Wrap(err, "Error writing signatures") + return nil, "", "", errors.Wrap(err, "writing signatures") } return manifestBytes, retManifestType, retManifestDigest, nil @@ -805,11 +813,11 @@ func checkImageDestinationForCurrentRuntime(ctx context.Context, sys *types.Syst if dest.MustMatchRuntimeOS() { c, err := src.OCIConfig(ctx) if err != nil { - return errors.Wrapf(err, "Error parsing image configuration") + return errors.Wrapf(err, "parsing image configuration") } wantedPlatforms, err := platform.WantedPlatforms(sys) if err != nil { - return errors.Wrapf(err, "error getting current platform information %#v", sys) + return errors.Wrapf(err, "getting current platform information %#v", sys) } options := newOrderedSet() @@ -1034,13 +1042,13 @@ func (ic *imageCopier) copyUpdatedConfigAndManifest(ctx context.Context, instanc } pi, err := ic.src.UpdatedImage(ctx, *ic.manifestUpdates) if err != nil { - return nil, "", errors.Wrap(err, "Error creating an updated image manifest") + return nil, "", errors.Wrap(err, "creating an updated image manifest") } pendingImage = pi } man, _, err := pendingImage.Manifest(ctx) if err != nil { - return nil, "", errors.Wrap(err, "Error reading manifest") + return nil, "", errors.Wrap(err, "reading manifest") } if err := ic.c.copyConfig(ctx, pendingImage); err != nil { @@ -1056,7 +1064,7 @@ func (ic *imageCopier) copyUpdatedConfigAndManifest(ctx context.Context, instanc instanceDigest = &manifestDigest } if err := ic.c.dest.PutManifest(ctx, man, instanceDigest); err != nil { - return nil, "", errors.Wrapf(err, "Error writing manifest %q", string(man)) + return nil, "", errors.Wrapf(err, "writing manifest %q", string(man)) } return man, manifestDigest, nil } @@ -1072,9 +1080,25 @@ func (c *copier) newProgressPool(ctx context.Context) (*mpb.Progress, func()) { } } +// customPartialBlobCounter provides a decorator function for the partial blobs retrieval progress bar +func customPartialBlobCounter(filler interface{}, wcc ...decor.WC) decor.Decorator { + producer := func(filler interface{}) decor.DecorFunc { + return func(s decor.Statistics) string { + if s.Total == 0 { + pairFmt := "%.1f / %.1f (skipped: %.1f)" + return fmt.Sprintf(pairFmt, decor.SizeB1024(s.Current), decor.SizeB1024(s.Total), decor.SizeB1024(s.Refill)) + } + pairFmt := "%.1f / %.1f (skipped: %.1f = %.2f%%)" + percentage := 100.0 * float64(s.Refill) / float64(s.Total) + return fmt.Sprintf(pairFmt, decor.SizeB1024(s.Current), decor.SizeB1024(s.Total), decor.SizeB1024(s.Refill), percentage) + } + } + return decor.Any(producer(filler), wcc...) +} + // createProgressBar creates a mpb.Bar in pool. Note that if the copier's reportWriter // is ioutil.Discard, the progress bar's output will be discarded -func (c *copier) createProgressBar(pool *mpb.Progress, info types.BlobInfo, kind string, onComplete string) *mpb.Bar { +func (c *copier) createProgressBar(pool *mpb.Progress, partial bool, info types.BlobInfo, kind string, onComplete string) *mpb.Bar { // shortDigestLen is the length of the digest used for blobs. const shortDigestLen = 12 @@ -1091,18 +1115,30 @@ func (c *copier) createProgressBar(pool *mpb.Progress, info types.BlobInfo, kind // Use a normal progress bar when we know the size (i.e., size > 0). // Otherwise, use a spinner to indicate that something's happening. var bar *mpb.Bar + sstyle := mpb.SpinnerStyle(".", "..", "...", "....", "").PositionLeft() if info.Size > 0 { - bar = pool.AddBar(info.Size, - mpb.BarFillerClearOnComplete(), - mpb.PrependDecorators( - decor.OnComplete(decor.Name(prefix), onComplete), - ), - mpb.AppendDecorators( - decor.OnComplete(decor.CountersKibiByte("%.1f / %.1f"), ""), - ), - ) + if partial { + bar = pool.AddBar(info.Size, + mpb.BarFillerClearOnComplete(), + mpb.PrependDecorators( + decor.OnComplete(decor.Name(prefix), onComplete), + ), + mpb.AppendDecorators( + customPartialBlobCounter(sstyle.Build()), + ), + ) + } else { + bar = pool.AddBar(info.Size, + mpb.BarFillerClearOnComplete(), + mpb.PrependDecorators( + decor.OnComplete(decor.Name(prefix), onComplete), + ), + mpb.AppendDecorators( + decor.OnComplete(decor.CountersKibiByte("%.1f / %.1f"), ""), + ), + ) + } } else { - sstyle := mpb.SpinnerStyle(".", "..", "...", "....", "").PositionLeft() bar = pool.Add(0, sstyle.Build(), mpb.BarFillerClearOnComplete(), @@ -1123,13 +1159,13 @@ func (c *copier) copyConfig(ctx context.Context, src types.Image) error { if srcInfo.Digest != "" { configBlob, err := src.ConfigBlob(ctx) if err != nil { - return errors.Wrapf(err, "Error reading config blob %s", srcInfo.Digest) + return errors.Wrapf(err, "reading config blob %s", srcInfo.Digest) } destInfo, err := func() (types.BlobInfo, error) { // A scope for defer progressPool, progressCleanup := c.newProgressPool(ctx) defer progressCleanup() - bar := c.createProgressBar(progressPool, srcInfo, "config", "done") + bar := c.createProgressBar(progressPool, false, srcInfo, "config", "done") destInfo, err := c.copyBlobFromStream(ctx, bytes.NewReader(configBlob), srcInfo, nil, false, true, false, bar, -1, false) if err != nil { return types.BlobInfo{}, err @@ -1213,11 +1249,11 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to } if err != nil { - return types.BlobInfo{}, "", errors.Wrapf(err, "Error trying to reuse blob %s at destination", srcInfo.Digest) + return types.BlobInfo{}, "", errors.Wrapf(err, "trying to reuse blob %s at destination", srcInfo.Digest) } if reused { logrus.Debugf("Skipping blob %s (already present):", srcInfo.Digest) - bar := ic.c.createProgressBar(pool, srcInfo, "blob", "skipped: already exists") + bar := ic.c.createProgressBar(pool, false, srcInfo, "blob", "skipped: already exists") bar.SetTotal(0, true) // Throw an event that the layer has been skipped @@ -1244,14 +1280,57 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to } } + // A partial pull is managed by the destination storage, that decides what portions + // of the source file are not known yet and must be fetched. + // Attempt a partial only when the source allows to retrieve a blob partially and + // the destination has support for it. + imgSource, okSource := ic.c.rawSource.(internalTypes.ImageSourceSeekable) + imgDest, okDest := ic.c.dest.(internalTypes.ImageDestinationPartial) + if ic.c.fetchPartialBlobs && okSource && okDest && !diffIDIsNeeded { + bar := ic.c.createProgressBar(pool, true, srcInfo, "blob", "done") + + progress := make(chan int64) + terminate := make(chan interface{}) + + defer close(terminate) + defer close(progress) + + proxy := imageSourceSeekableProxy{ + source: imgSource, + progress: progress, + } + go func() { + for { + select { + case written := <-progress: + bar.IncrInt64(written) + case <-terminate: + return + } + } + }() + + bar.SetTotal(srcInfo.Size, false) + info, err := imgDest.PutBlobPartial(ctx, proxy, srcInfo, ic.c.blobInfoCache) + if err == nil { + bar.SetRefill(srcInfo.Size - bar.Current()) + bar.SetCurrent(srcInfo.Size) + bar.SetTotal(srcInfo.Size, true) + logrus.Debugf("Retrieved partial blob %v", srcInfo.Digest) + return info, cachedDiffID, nil + } + bar.Abort(true) + logrus.Errorf("Failed to retrieve partial blob: %v", err) + } + // Fallback: copy the layer, computing the diffID if we need to do so srcStream, srcBlobSize, err := ic.c.rawSource.GetBlob(ctx, srcInfo, ic.c.blobInfoCache) if err != nil { - return types.BlobInfo{}, "", errors.Wrapf(err, "Error reading blob %s", srcInfo.Digest) + return types.BlobInfo{}, "", errors.Wrapf(err, "reading blob %s", srcInfo.Digest) } defer srcStream.Close() - bar := ic.c.createProgressBar(pool, srcInfo, "blob", "done") + bar := ic.c.createProgressBar(pool, false, srcInfo, "blob", "done") blobInfo, diffIDChan, err := ic.copyLayerFromStream(ctx, srcStream, types.BlobInfo{Digest: srcInfo.Digest, Size: srcBlobSize, MediaType: srcInfo.MediaType, Annotations: srcInfo.Annotations}, diffIDIsNeeded, toEncrypt, bar, layerIndex, emptyLayer) if err != nil { @@ -1265,7 +1344,7 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to return types.BlobInfo{}, "", ctx.Err() case diffIDResult := <-diffIDChan: if diffIDResult.err != nil { - return types.BlobInfo{}, "", errors.Wrap(diffIDResult.err, "Error computing layer DiffID") + return types.BlobInfo{}, "", errors.Wrap(diffIDResult.err, "computing layer DiffID") } logrus.Debugf("Computed DiffID %s for layer %s", diffIDResult.digest, srcInfo.Digest) // This is safe because we have just computed diffIDResult.Digest ourselves, and in the process @@ -1288,7 +1367,7 @@ func (ic *imageCopier) copyLayerFromStream(ctx context.Context, srcStream io.Rea var getDiffIDRecorder func(compression.DecompressorFunc) io.Writer // = nil var diffIDChan chan diffIDResult - err := errors.New("Internal error: unexpected panic in copyLayer") // For pipeWriter.CloseWithError below + err := errors.New("Internal error: unexpected panic in copyLayer") // For pipeWriter.CloseWithbelow if diffIDIsNeeded { diffIDChan = make(chan diffIDResult, 1) // Buffered, so that sending a value after this or our caller has failed and exited does not block. pipeReader, pipeWriter := io.Pipe() @@ -1350,7 +1429,7 @@ type errorAnnotationReader struct { func (r errorAnnotationReader) Read(b []byte) (n int, err error) { n, err = r.reader.Read(b) if err != io.EOF { - return n, errors.Wrapf(err, "error happened during read") + return n, errors.Wrapf(err, "happened during read") } return n, err } @@ -1377,7 +1456,7 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr // read stream to the end, and validation does not happen. digestingReader, err := newDigestingReader(srcStream, srcInfo.Digest) if err != nil { - return types.BlobInfo{}, errors.Wrapf(err, "Error preparing to verify blob %s", srcInfo.Digest) + return types.BlobInfo{}, errors.Wrapf(err, "preparing to verify blob %s", srcInfo.Digest) } var destStream io.Reader = digestingReader @@ -1391,7 +1470,7 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr var d digest.Digest destStream, d, err = ocicrypt.DecryptLayer(c.ociDecryptConfig, destStream, newDesc, false) if err != nil { - return types.BlobInfo{}, errors.Wrapf(err, "Error decrypting layer %s", srcInfo.Digest) + return types.BlobInfo{}, errors.Wrapf(err, "decrypting layer %s", srcInfo.Digest) } srcInfo.Digest = d @@ -1408,7 +1487,7 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr // This requires us to “peek ahead” into the stream to read the initial part, which requires us to chain through another io.Reader returned by DetectCompression. compressionFormat, decompressor, destStream, err := compression.DetectCompressionFormat(destStream) // We could skip this in some cases, but let's keep the code path uniform if err != nil { - return types.BlobInfo{}, errors.Wrapf(err, "Error reading blob %s", srcInfo.Digest) + return types.BlobInfo{}, errors.Wrapf(err, "reading blob %s", srcInfo.Digest) } isCompressed := decompressor != nil if expectedCompressionFormat, known := expectedCompressionFormats[srcInfo.MediaType]; known && isCompressed && compressionFormat.Name() != expectedCompressionFormat.Name() { @@ -1425,6 +1504,7 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr originalLayerReader = destStream } + compressionMetadata := map[string]string{} // === Deal with layer compression/decompression if necessary // WARNING: If you are adding new reasons to change the blob, update also the OptimizeDestinationImageAlreadyExists // short-circuit conditions @@ -1453,7 +1533,7 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr // If this fails while writing data, it will do pipeWriter.CloseWithError(); if it fails otherwise, // e.g. because we have exited and due to pipeReader.Close() above further writing to the pipe has failed, // we don’t care. - go c.compressGoroutine(pipeWriter, destStream, *uploadCompressionFormat) // Closes pipeWriter + go c.compressGoroutine(pipeWriter, destStream, compressionMetadata, *uploadCompressionFormat) // Closes pipeWriter destStream = pipeReader inputInfo.Digest = "" inputInfo.Size = -1 @@ -1473,7 +1553,7 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr pipeReader, pipeWriter := io.Pipe() defer pipeReader.Close() - go c.compressGoroutine(pipeWriter, s, *uploadCompressionFormat) // Closes pipeWriter + go c.compressGoroutine(pipeWriter, s, compressionMetadata, *uploadCompressionFormat) // Closes pipeWriter destStream = pipeReader inputInfo.Digest = "" @@ -1533,7 +1613,7 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr s, fin, err := ocicrypt.EncryptLayer(c.ociEncryptConfig, destStream, desc) if err != nil { - return types.BlobInfo{}, errors.Wrapf(err, "Error encrypting blob %s", srcInfo.Digest) + return types.BlobInfo{}, errors.Wrapf(err, "encrypting blob %s", srcInfo.Digest) } destStream = s @@ -1576,7 +1656,7 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr uploadedInfo, err = c.dest.PutBlob(ctx, &errorAnnotationReader{destStream}, inputInfo, c.blobInfoCache, isConfig) } if err != nil { - return types.BlobInfo{}, errors.Wrap(err, "Error writing blob") + return types.BlobInfo{}, errors.Wrap(err, "writing blob") } uploadedInfo.Annotations = srcInfo.Annotations @@ -1608,7 +1688,7 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr logrus.Debugf("Consuming rest of the original blob to satisfy getOriginalLayerCopyWriter") _, err := io.Copy(ioutil.Discard, originalLayerReader) if err != nil { - return types.BlobInfo{}, errors.Wrapf(err, "Error reading input blob %s", srcInfo.Digest) + return types.BlobInfo{}, errors.Wrapf(err, "reading input blob %s", srcInfo.Digest) } } @@ -1640,23 +1720,42 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr c.blobInfoCache.RecordDigestCompressorName(srcInfo.Digest, srcCompressorName) } } + + // Copy all the metadata generated by the compressor into the annotations. + if uploadedInfo.Annotations == nil { + uploadedInfo.Annotations = map[string]string{} + } + for k, v := range compressionMetadata { + uploadedInfo.Annotations[k] = v + } + return uploadedInfo, nil } -// compressGoroutine reads all input from src and writes its compressed equivalent to dest. -func (c *copier) compressGoroutine(dest *io.PipeWriter, src io.Reader, compressionFormat compression.Algorithm) { - err := errors.New("Internal error: unexpected panic in compressGoroutine") - defer func() { // Note that this is not the same as {defer dest.CloseWithError(err)}; we need err to be evaluated lazily. - _ = dest.CloseWithError(err) // CloseWithError(nil) is equivalent to Close(), always returns nil - }() - - compressor, err := compression.CompressStream(dest, compressionFormat, c.compressionLevel) +// doCompression reads all input from src and writes its compressed equivalent to dest. +func doCompression(dest io.Writer, src io.Reader, metadata map[string]string, compressionFormat compression.Algorithm, compressionLevel *int) error { + compressor, err := compression.CompressStreamWithMetadata(dest, metadata, compressionFormat, compressionLevel) if err != nil { - return + return err } - defer compressor.Close() buf := make([]byte, compressionBufferSize) _, err = io.CopyBuffer(compressor, src, buf) // Sets err to nil, i.e. causes dest.Close() + if err != nil { + compressor.Close() + return err + } + + return compressor.Close() +} + +// compressGoroutine reads all input from src and writes its compressed equivalent to dest. +func (c *copier) compressGoroutine(dest *io.PipeWriter, src io.Reader, metadata map[string]string, compressionFormat compression.Algorithm) { + err := errors.New("Internal error: unexpected panic in compressGoroutine") + defer func() { // Note that this is not the same as {defer dest.CloseWithError(err)}; we need err to be evaluated lazily. + _ = dest.CloseWithError(err) // CloseWithError(nil) is equivalent to Close(), always returns nil + }() + + err = doCompression(dest, src, metadata, compressionFormat, c.compressionLevel) } diff --git a/vendor/github.com/containers/image/v5/copy/manifest.go b/vendor/github.com/containers/image/v5/copy/manifest.go index 0c0164cbf..b97edbf08 100644 --- a/vendor/github.com/containers/image/v5/copy/manifest.go +++ b/vendor/github.com/containers/image/v5/copy/manifest.go @@ -45,7 +45,7 @@ func (os *orderedSet) append(s string) { func (ic *imageCopier) determineManifestConversion(ctx context.Context, destSupportedManifestMIMETypes []string, forceManifestMIMEType string, requiresOciEncryption bool) (string, []string, error) { _, srcType, err := ic.src.Manifest(ctx) if err != nil { // This should have been cached?! - return "", nil, errors.Wrap(err, "Error reading manifest") + return "", nil, errors.Wrap(err, "reading manifest") } normalizedSrcType := manifest.NormalizedMIMEType(srcType) if srcType != normalizedSrcType { @@ -137,30 +137,29 @@ func (c *copier) determineListConversion(currentListMIMEType string, destSupport if forcedListMIMEType != "" { destSupportedMIMETypes = []string{forcedListMIMEType} } - var selectedType string - var otherSupportedTypes []string - for i := range destSupportedMIMETypes { - // The second priority is the first member of the list of acceptable types that is a list, - // but keep going in case current type occurs later in the list. - if selectedType == "" && manifest.MIMETypeIsMultiImage(destSupportedMIMETypes[i]) { - selectedType = destSupportedMIMETypes[i] - } - // The first priority is the current type, if it's in the list, since that lets us avoid a - // conversion that isn't strictly necessary. - if destSupportedMIMETypes[i] == currentListMIMEType { - selectedType = destSupportedMIMETypes[i] + + prioritizedTypes := newOrderedSet() + // The first priority is the current type, if it's in the list, since that lets us avoid a + // conversion that isn't strictly necessary. + for _, t := range destSupportedMIMETypes { + if t == currentListMIMEType { + prioritizedTypes.append(currentListMIMEType) + break } } // Pick out the other list types that we support. - for i := range destSupportedMIMETypes { - if selectedType != destSupportedMIMETypes[i] && manifest.MIMETypeIsMultiImage(destSupportedMIMETypes[i]) { - otherSupportedTypes = append(otherSupportedTypes, destSupportedMIMETypes[i]) + for _, t := range destSupportedMIMETypes { + if manifest.MIMETypeIsMultiImage(t) { + prioritizedTypes.append(t) } } + logrus.Debugf("Manifest list has MIME type %s, ordered candidate list [%s]", currentListMIMEType, strings.Join(destSupportedMIMETypes, ", ")) - if selectedType == "" { + if len(prioritizedTypes.list) == 0 { return "", nil, errors.Errorf("destination does not support any supported manifest list types (%v)", manifest.SupportedListMIMETypes) } + selectedType := prioritizedTypes.list[0] + otherSupportedTypes := prioritizedTypes.list[1:] if selectedType != currentListMIMEType { logrus.Debugf("... will convert to %s first, and then try %v", selectedType, otherSupportedTypes) } else { diff --git a/vendor/github.com/containers/image/v5/copy/progress_reader.go b/vendor/github.com/containers/image/v5/copy/progress_reader.go index 0761065a2..42f490d32 100644 --- a/vendor/github.com/containers/image/v5/copy/progress_reader.go +++ b/vendor/github.com/containers/image/v5/copy/progress_reader.go @@ -1,9 +1,11 @@ package copy import ( + "context" "io" "time" + internalTypes "github.com/containers/image/v5/internal/types" "github.com/containers/image/v5/types" ) @@ -77,3 +79,26 @@ func (r *progressReader) Read(p []byte) (int, error) { } return n, err } + +// imageSourceSeekableProxy wraps ImageSourceSeekable and keeps track of how many bytes +// are received. +type imageSourceSeekableProxy struct { + // source is the seekable input to read from. + source internalTypes.ImageSourceSeekable + // progress is the chan where the total number of bytes read so far are reported. + progress chan int64 +} + +// GetBlobAt reads from the ImageSourceSeekable and report how many bytes were received +// to the progress chan. +func (s imageSourceSeekableProxy) GetBlobAt(ctx context.Context, bInfo types.BlobInfo, chunks []internalTypes.ImageSourceChunk) (chan io.ReadCloser, chan error, error) { + rc, errs, err := s.source.GetBlobAt(ctx, bInfo, chunks) + if err == nil { + total := int64(0) + for _, c := range chunks { + total += int64(c.Length) + } + s.progress <- total + } + return rc, errs, err +} diff --git a/vendor/github.com/containers/image/v5/copy/sign.go b/vendor/github.com/containers/image/v5/copy/sign.go index 8f46e9de6..61612a4d3 100644 --- a/vendor/github.com/containers/image/v5/copy/sign.go +++ b/vendor/github.com/containers/image/v5/copy/sign.go @@ -10,7 +10,7 @@ import ( func (c *copier) createSignature(manifest []byte, keyIdentity string) ([]byte, error) { mech, err := signature.NewGPGSigningMechanism() if err != nil { - return nil, errors.Wrap(err, "Error initializing GPG") + return nil, errors.Wrap(err, "initializing GPG") } defer mech.Close() if err := mech.SupportsSigning(); err != nil { @@ -25,7 +25,7 @@ func (c *copier) createSignature(manifest []byte, keyIdentity string) ([]byte, e c.Printf("Signing manifest\n") newSig, err := signature.SignDockerManifest(manifest, dockerReference.String(), mech, keyIdentity) if err != nil { - return nil, errors.Wrap(err, "Error creating signature") + return nil, errors.Wrap(err, "creating signature") } return newSig, nil } diff --git a/vendor/github.com/containers/image/v5/directory/directory_dest.go b/vendor/github.com/containers/image/v5/directory/directory_dest.go index 5cafd2674..49957ac4e 100644 --- a/vendor/github.com/containers/image/v5/directory/directory_dest.go +++ b/vendor/github.com/containers/image/v5/directory/directory_dest.go @@ -34,7 +34,7 @@ func newImageDestination(ref dirReference, compress bool) (types.ImageDestinatio // if the contents don't match throw an error dirExists, err := pathExists(d.ref.resolvedPath) if err != nil { - return nil, errors.Wrapf(err, "error checking for path %q", d.ref.resolvedPath) + return nil, errors.Wrapf(err, "checking for path %q", d.ref.resolvedPath) } if dirExists { isEmpty, err := isDirEmpty(d.ref.resolvedPath) @@ -45,7 +45,7 @@ func newImageDestination(ref dirReference, compress bool) (types.ImageDestinatio if !isEmpty { versionExists, err := pathExists(d.ref.versionPath()) if err != nil { - return nil, errors.Wrapf(err, "error checking if path exists %q", d.ref.versionPath()) + return nil, errors.Wrapf(err, "checking if path exists %q", d.ref.versionPath()) } if versionExists { contents, err := ioutil.ReadFile(d.ref.versionPath()) @@ -61,7 +61,7 @@ func newImageDestination(ref dirReference, compress bool) (types.ImageDestinatio } // delete directory contents so that only one image is in the directory at a time if err = removeDirContents(d.ref.resolvedPath); err != nil { - return nil, errors.Wrapf(err, "error erasing contents in %q", d.ref.resolvedPath) + return nil, errors.Wrapf(err, "erasing contents in %q", d.ref.resolvedPath) } logrus.Debugf("overwriting existing container image directory %q", d.ref.resolvedPath) } @@ -74,7 +74,7 @@ func newImageDestination(ref dirReference, compress bool) (types.ImageDestinatio // create version file err = ioutil.WriteFile(d.ref.versionPath(), []byte(version), 0644) if err != nil { - return nil, errors.Wrapf(err, "error creating version file %q", d.ref.versionPath()) + return nil, errors.Wrapf(err, "creating version file %q", d.ref.versionPath()) } return d, nil } @@ -239,6 +239,9 @@ func (d *dirImageDestination) PutSignatures(ctx context.Context, signatures [][] } // Commit marks the process of storing the image as successful and asks for the image to be persisted. +// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list +// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the +// original manifest list digest, if desired. // WARNING: This does not have any transactional semantics: // - Uploaded data MAY be visible to others before Commit() is called // - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed) diff --git a/vendor/github.com/containers/image/v5/docker/archive/dest.go b/vendor/github.com/containers/image/v5/docker/archive/dest.go index e874e02e0..d4248db21 100644 --- a/vendor/github.com/containers/image/v5/docker/archive/dest.go +++ b/vendor/github.com/containers/image/v5/docker/archive/dest.go @@ -67,6 +67,9 @@ func (d *archiveImageDestination) Close() error { } // Commit marks the process of storing the image as successful and asks for the image to be persisted. +// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list +// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the +// original manifest list digest, if desired. // WARNING: This does not have any transactional semantics: // - Uploaded data MAY be visible to others before Commit() is called // - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed) diff --git a/vendor/github.com/containers/image/v5/docker/archive/reader.go b/vendor/github.com/containers/image/v5/docker/archive/reader.go index c7bb311bc..4bb519a26 100644 --- a/vendor/github.com/containers/image/v5/docker/archive/reader.go +++ b/vendor/github.com/containers/image/v5/docker/archive/reader.go @@ -81,14 +81,14 @@ func (r *Reader) List() ([][]types.ImageReference, error) { } ref, err := newReference(r.path, nt, -1, r.archive, nil) if err != nil { - return nil, errors.Wrapf(err, "Error creating a reference for tag %#v in manifest item @%d", tag, imageIndex) + return nil, errors.Wrapf(err, "creating a reference for tag %#v in manifest item @%d", tag, imageIndex) } refs = append(refs, ref) } if len(refs) == 0 { ref, err := newReference(r.path, nil, imageIndex, r.archive, nil) if err != nil { - return nil, errors.Wrapf(err, "Error creating a reference for manifest item @%d", imageIndex) + return nil, errors.Wrapf(err, "creating a reference for manifest item @%d", imageIndex) } refs = append(refs, ref) } diff --git a/vendor/github.com/containers/image/v5/docker/archive/writer.go b/vendor/github.com/containers/image/v5/docker/archive/writer.go index afac2aaee..6a4b8c645 100644 --- a/vendor/github.com/containers/image/v5/docker/archive/writer.go +++ b/vendor/github.com/containers/image/v5/docker/archive/writer.go @@ -60,7 +60,7 @@ func openArchiveForWriting(path string) (*os.File, error) { // only in a different way. Either way, it’s up to the user to not have two writers to the same path.) fh, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644) if err != nil { - return nil, errors.Wrapf(err, "error opening file %q", path) + return nil, errors.Wrapf(err, "opening file %q", path) } succeeded := false defer func() { @@ -70,7 +70,7 @@ func openArchiveForWriting(path string) (*os.File, error) { }() fhStat, err := fh.Stat() if err != nil { - return nil, errors.Wrapf(err, "error statting file %q", path) + return nil, errors.Wrapf(err, "statting file %q", path) } if fhStat.Mode().IsRegular() && fhStat.Size() != 0 { diff --git a/vendor/github.com/containers/image/v5/docker/daemon/daemon_dest.go b/vendor/github.com/containers/image/v5/docker/daemon/daemon_dest.go index 88609b3dc..f68981472 100644 --- a/vendor/github.com/containers/image/v5/docker/daemon/daemon_dest.go +++ b/vendor/github.com/containers/image/v5/docker/daemon/daemon_dest.go @@ -42,7 +42,7 @@ func newImageDestination(ctx context.Context, sys *types.SystemContext, ref daem c, err := newDockerClient(sys) if err != nil { - return nil, errors.Wrap(err, "Error initializing docker engine client") + return nil, errors.Wrap(err, "initializing docker engine client") } reader, writer := io.Pipe() @@ -84,7 +84,7 @@ func imageLoadGoroutine(ctx context.Context, c *client.Client, reader *io.PipeRe resp, err := c.ImageLoad(ctx, reader, true) if err != nil { - err = errors.Wrap(err, "Error saving image to docker engine") + err = errors.Wrap(err, "saving image to docker engine") return } defer resp.Body.Close() @@ -128,6 +128,9 @@ func (d *daemonImageDestination) Reference() types.ImageReference { } // Commit marks the process of storing the image as successful and asks for the image to be persisted. +// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list +// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the +// original manifest list digest, if desired. // WARNING: This does not have any transactional semantics: // - Uploaded data MAY be visible to others before Commit() is called // - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed) diff --git a/vendor/github.com/containers/image/v5/docker/daemon/daemon_src.go b/vendor/github.com/containers/image/v5/docker/daemon/daemon_src.go index 74a678817..a6d8a6cf5 100644 --- a/vendor/github.com/containers/image/v5/docker/daemon/daemon_src.go +++ b/vendor/github.com/containers/image/v5/docker/daemon/daemon_src.go @@ -25,13 +25,13 @@ type daemonImageSource struct { func newImageSource(ctx context.Context, sys *types.SystemContext, ref daemonReference) (types.ImageSource, error) { c, err := newDockerClient(sys) if err != nil { - return nil, errors.Wrap(err, "Error initializing docker engine client") + return nil, errors.Wrap(err, "initializing docker engine client") } // Per NewReference(), ref.StringWithinTransport() is either an image ID (config digest), or a !reference.NameOnly() reference. // Either way ImageSave should create a tarball with exactly one image. inputStream, err := c.ImageSave(ctx, []string{ref.StringWithinTransport()}) if err != nil { - return nil, errors.Wrap(err, "Error loading image from docker engine") + return nil, errors.Wrap(err, "loading image from docker engine") } defer inputStream.Close() 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 a9533ea39..14c11dfd0 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_client.go +++ b/vendor/github.com/containers/image/v5/docker/docker_client.go @@ -92,7 +92,7 @@ type bearerToken struct { expirationTime time.Time } -// dockerClient is configuration for dealing with a single Docker registry. +// dockerClient is configuration for dealing with a single container registry. type dockerClient struct { // The following members are set by newDockerClient and do not change afterwards. sys *types.SystemContext @@ -213,10 +213,9 @@ func dockerCertDir(sys *types.SystemContext, hostPort string) (string, error) { // “write” specifies whether the client will be used for "write" access (in particular passed to lookaside.go:toplevelFromSection) // signatureBase is always set in the return value func newDockerClientFromRef(sys *types.SystemContext, ref dockerReference, write bool, actions string) (*dockerClient, error) { - registry := reference.Domain(ref.ref) - auth, err := config.GetCredentials(sys, registry) + auth, err := config.GetCredentialsForRef(sys, ref.ref) if err != nil { - return nil, errors.Wrapf(err, "error getting username and password") + return nil, errors.Wrapf(err, "getting username and password") } sigBase, err := SignatureStorageBaseURL(sys, ref, write) @@ -224,6 +223,7 @@ func newDockerClientFromRef(sys *types.SystemContext, ref dockerReference, write return nil, err } + registry := reference.Domain(ref.ref) client, err := newDockerClient(sys, registry, ref.ref.Name()) if err != nil { return nil, err @@ -269,7 +269,7 @@ func newDockerClient(sys *types.SystemContext, registry, reference string) (*doc skipVerify := false reg, err := sysregistriesv2.FindRegistry(sys, reference) if err != nil { - return nil, errors.Wrapf(err, "error loading registries") + return nil, errors.Wrapf(err, "loading registries") } if reg != nil { if reg.Blocked { @@ -297,7 +297,7 @@ func newDockerClient(sys *types.SystemContext, registry, reference string) (*doc func CheckAuth(ctx context.Context, sys *types.SystemContext, username, password, registry string) error { client, err := newDockerClient(sys, registry, registry) if err != nil { - return errors.Wrapf(err, "error creating new docker client") + return errors.Wrapf(err, "creating new docker client") } client.auth = types.DockerAuthConfig{ Username: username, @@ -343,9 +343,10 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima v1Res := &V1Results{} // Get credentials from authfile for the underlying hostname - auth, err := config.GetCredentials(sys, registry) + // lint:ignore SA1019 We can't use GetCredentialsForRef because we want to search the whole registry. + auth, err := config.GetCredentials(sys, registry) // nolint:staticcheck // https://github.com/golangci/golangci-lint/issues/741 if err != nil { - return nil, errors.Wrapf(err, "error getting username and password") + return nil, errors.Wrapf(err, "getting username and password") } // The /v2/_catalog endpoint has been disabled for docker.io therefore @@ -359,7 +360,7 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima client, err := newDockerClient(sys, hostname, registry) if err != nil { - return nil, errors.Wrapf(err, "error creating new docker client") + return nil, errors.Wrapf(err, "creating new docker client") } client.auth = auth if sys != nil { @@ -422,7 +423,14 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima res := SearchResult{ Name: repo, } - searchRes = append(searchRes, res) + // bugzilla.redhat.com/show_bug.cgi?id=1976283 + // If we have a full match, make sure it's listed as the first result. + // (Note there might be a full match we never see if we reach the result limit first.) + if repo == image { + searchRes = append([]SearchResult{res}, searchRes...) + } else { + searchRes = append(searchRes, res) + } } } @@ -751,7 +759,7 @@ func (c *dockerClient) detectPropertiesHelper(ctx context.Context) error { err = ping("http") } if err != nil { - err = errors.Wrapf(err, "error pinging docker registry %s", c.registry) + err = errors.Wrapf(err, "pinging container registry %s", c.registry) if c.sys != nil && c.sys.DockerDisableV1Ping { return err } @@ -799,7 +807,7 @@ func (c *dockerClient) getExtensionsSignatures(ctx context.Context, ref dockerRe defer res.Body.Close() if res.StatusCode != http.StatusOK { - return nil, errors.Wrapf(clientLib.HandleErrorResponse(res), "Error downloading signatures for %s in %s", manifestDigest, ref.ref.Name()) + return nil, errors.Wrapf(clientLib.HandleErrorResponse(res), "downloading signatures for %s in %s", manifestDigest, ref.ref.Name()) } body, err := iolimits.ReadAtMost(res.Body, iolimits.MaxSignatureListBodySize) @@ -809,7 +817,7 @@ func (c *dockerClient) getExtensionsSignatures(ctx context.Context, ref dockerRe var parsedBody extensionSignatureList if err := json.Unmarshal(body, &parsedBody); err != nil { - return nil, errors.Wrapf(err, "Error decoding signature list") + return nil, errors.Wrapf(err, "decoding signature list") } return &parsedBody, nil } diff --git a/vendor/github.com/containers/image/v5/docker/docker_image.go b/vendor/github.com/containers/image/v5/docker/docker_image.go index f9fe4e8a3..567a4bcf4 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image.go @@ -73,7 +73,7 @@ func GetRepositoryTags(ctx context.Context, sys *types.SystemContext, ref types. return nil, err } defer res.Body.Close() - if err := httpResponseToError(res, "Error fetching tags list"); err != nil { + if err := httpResponseToError(res, "fetching tags list"); err != nil { return nil, err } @@ -141,7 +141,7 @@ func GetDigest(ctx context.Context, sys *types.SystemContext, ref types.ImageRef defer res.Body.Close() if res.StatusCode != http.StatusOK { - return "", errors.Wrapf(registryHTTPResponseToError(res), "Error reading digest %s in %s", tagOrDigest, dr.ref.Name()) + return "", errors.Wrapf(registryHTTPResponseToError(res), "reading digest %s in %s", tagOrDigest, dr.ref.Name()) } dig, err := digest.Parse(res.Header.Get("Docker-Content-Digest")) diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go index e11084dc8..84694e157 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go @@ -154,11 +154,11 @@ func (d *dockerImageDestination) PutBlob(ctx context.Context, stream io.Reader, defer res.Body.Close() if res.StatusCode != http.StatusAccepted { logrus.Debugf("Error initiating layer upload, response %#v", *res) - return types.BlobInfo{}, errors.Wrapf(registryHTTPResponseToError(res), "Error initiating layer upload to %s in %s", uploadPath, d.c.registry) + return types.BlobInfo{}, errors.Wrapf(registryHTTPResponseToError(res), "initiating layer upload to %s in %s", uploadPath, d.c.registry) } uploadLocation, err := res.Location() if err != nil { - return types.BlobInfo{}, errors.Wrap(err, "Error determining upload URL") + return types.BlobInfo{}, errors.Wrap(err, "determining upload URL") } digester := digest.Canonical.Digester() @@ -175,11 +175,11 @@ func (d *dockerImageDestination) PutBlob(ctx context.Context, stream io.Reader, } defer res.Body.Close() if !successStatus(res.StatusCode) { - return nil, errors.Wrapf(registryHTTPResponseToError(res), "Error uploading layer chunked") + return nil, errors.Wrapf(registryHTTPResponseToError(res), "uploading layer chunked") } uploadLocation, err := res.Location() if err != nil { - return nil, errors.Wrap(err, "Error determining upload URL") + return nil, errors.Wrap(err, "determining upload URL") } return uploadLocation, nil }() @@ -201,7 +201,7 @@ func (d *dockerImageDestination) PutBlob(ctx context.Context, stream io.Reader, defer res.Body.Close() if res.StatusCode != http.StatusCreated { logrus.Debugf("Error uploading layer, response %#v", *res) - return types.BlobInfo{}, errors.Wrapf(registryHTTPResponseToError(res), "Error uploading layer to %s", uploadLocation) + return types.BlobInfo{}, errors.Wrapf(registryHTTPResponseToError(res), "uploading layer to %s", uploadLocation) } logrus.Debugf("Upload of layer %s complete", computedDigest) @@ -226,7 +226,7 @@ func (d *dockerImageDestination) blobExists(ctx context.Context, repo reference. return true, getBlobSize(res), nil case http.StatusUnauthorized: logrus.Debugf("... not authorized") - return false, -1, errors.Wrapf(registryHTTPResponseToError(res), "Error checking whether a blob %s exists in %s", digest, repo.Name()) + return false, -1, errors.Wrapf(registryHTTPResponseToError(res), "checking whether a blob %s exists in %s", digest, repo.Name()) case http.StatusNotFound: logrus.Debugf("... not present") return false, -1, nil @@ -261,7 +261,7 @@ func (d *dockerImageDestination) mountBlob(ctx context.Context, srcRepo referenc // NOTE: This does not really work in docker/distribution servers, which incorrectly require the "delete" action in the token's scope, and is thus entirely untested. uploadLocation, err := res.Location() if err != nil { - return errors.Wrap(err, "Error determining upload URL after a mount attempt") + return errors.Wrap(err, "determining upload URL after a mount attempt") } logrus.Debugf("... started an upload instead of mounting, trying to cancel at %s", uploadLocation.String()) res2, err := d.c.makeRequestToResolvedURL(ctx, "DELETE", uploadLocation.String(), nil, nil, -1, v2Auth, extraScope) @@ -277,7 +277,7 @@ func (d *dockerImageDestination) mountBlob(ctx context.Context, srcRepo referenc return fmt.Errorf("Mounting %s from %s to %s started an upload instead", srcDigest, srcRepo.Name(), d.ref.ref.Name()) default: logrus.Debugf("Error mounting, response %#v", *res) - return errors.Wrapf(registryHTTPResponseToError(res), "Error mounting %s from %s to %s", srcDigest, srcRepo.Name(), d.ref.ref.Name()) + return errors.Wrapf(registryHTTPResponseToError(res), "mounting %s from %s to %s", srcDigest, srcRepo.Name(), d.ref.ref.Name()) } } @@ -392,7 +392,7 @@ func (d *dockerImageDestination) PutManifest(ctx context.Context, m []byte, inst // Double-check that the manifest we've been given matches the digest we've been given. matches, err := manifest.MatchesDigest(m, *instanceDigest) if err != nil { - return errors.Wrapf(err, "error digesting manifest in PutManifest") + return errors.Wrapf(err, "digesting manifest in PutManifest") } if !matches { manifestDigest, merr := manifest.Digest(m) @@ -430,7 +430,7 @@ func (d *dockerImageDestination) PutManifest(ctx context.Context, m []byte, inst } defer res.Body.Close() if !successStatus(res.StatusCode) { - err = errors.Wrapf(registryHTTPResponseToError(res), "Error uploading manifest %s to %s", refTail, d.ref.ref.Name()) + err = errors.Wrapf(registryHTTPResponseToError(res), "uploading manifest %s to %s", refTail, d.ref.ref.Name()) if isManifestInvalidError(errors.Cause(err)) { err = types.ManifestTypeRejectedError{Err: err} } @@ -621,7 +621,7 @@ sigExists: randBytes := make([]byte, 16) n, err := rand.Read(randBytes) if err != nil || n != 16 { - return errors.Wrapf(err, "Error generating random signature len %d", n) + return errors.Wrapf(err, "generating random signature len %d", n) } signatureName = fmt.Sprintf("%s@%032x", manifestDigest.String(), randBytes) if _, ok := existingSigNames[signatureName]; !ok { @@ -651,7 +651,7 @@ sigExists: logrus.Debugf("Error body %s", string(body)) } logrus.Debugf("Error uploading signature, status %d, %#v", res.StatusCode, res) - return errors.Wrapf(registryHTTPResponseToError(res), "Error uploading signature to %s in %s", path, d.c.registry) + return errors.Wrapf(registryHTTPResponseToError(res), "uploading signature to %s in %s", path, d.c.registry) } } @@ -659,6 +659,9 @@ sigExists: } // Commit marks the process of storing the image as successful and asks for the image to be persisted. +// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list +// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the +// original manifest list digest, if desired. // WARNING: This does not have any transactional semantics: // - Uploaded data MAY be visible to others before Commit() is called // - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed) 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 6916b7dad..c5a428ba0 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 @@ -6,14 +6,17 @@ import ( "io" "io/ioutil" "mime" + "mime/multipart" "net/http" "net/url" "os" "strconv" "strings" + "sync" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/internal/iolimits" + internalTypes "github.com/containers/image/v5/internal/types" "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/pkg/sysregistriesv2" "github.com/containers/image/v5/types" @@ -36,7 +39,7 @@ type dockerImageSource struct { func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerReference) (*dockerImageSource, error) { registry, err := sysregistriesv2.FindRegistry(sys, ref.ref.Name()) if err != nil { - return nil, errors.Wrapf(err, "error loading registries configuration") + return nil, errors.Wrapf(err, "loading registries configuration") } if registry == nil { // No configuration was found for the provided reference, so use the @@ -69,7 +72,6 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerRef } else { logrus.Debugf("Trying to access %q", pullSource.Reference) } - logrus.Debugf("Trying to access %q", pullSource.Reference) s, err := newImageSourceAttempt(ctx, sys, ref, pullSource) if err == nil { return s, nil @@ -197,7 +199,7 @@ func (s *dockerImageSource) fetchManifest(ctx context.Context, tagOrDigest strin logrus.Debugf("Content-Type from manifest GET is %q", res.Header.Get("Content-Type")) defer res.Body.Close() if res.StatusCode != http.StatusOK { - return nil, "", errors.Wrapf(registryHTTPResponseToError(res), "Error reading manifest %s in %s", tagOrDigest, s.physicalRef.ref.Name()) + return nil, "", errors.Wrapf(registryHTTPResponseToError(res), "reading manifest %s in %s", tagOrDigest, s.physicalRef.ref.Name()) } manblob, err := iolimits.ReadAtMost(res.Body, iolimits.MaxManifestBodySize) @@ -276,6 +278,82 @@ func (s *dockerImageSource) HasThreadSafeGetBlob() bool { return true } +// GetBlobAt returns a stream for the specified blob. +func (s *dockerImageSource) GetBlobAt(ctx context.Context, info types.BlobInfo, chunks []internalTypes.ImageSourceChunk) (chan io.ReadCloser, chan error, error) { + headers := make(map[string][]string) + + var rangeVals []string + for _, c := range chunks { + rangeVals = append(rangeVals, fmt.Sprintf("%d-%d", c.Offset, c.Offset+c.Length-1)) + } + + headers["Range"] = []string{fmt.Sprintf("bytes=%s", strings.Join(rangeVals, ","))} + + if len(info.URLs) != 0 { + return nil, nil, fmt.Errorf("external URLs not supported with GetBlobAt") + } + + path := fmt.Sprintf(blobsPath, reference.Path(s.physicalRef.ref), info.Digest.String()) + logrus.Debugf("Downloading %s", path) + res, err := s.c.makeRequest(ctx, "GET", path, headers, nil, v2Auth, nil) + if err != nil { + return nil, nil, err + } + if err := httpResponseToError(res, "Error fetching partial blob"); err != nil { + if res.Body != nil { + res.Body.Close() + } + return nil, nil, err + } + if res.StatusCode != http.StatusPartialContent { + res.Body.Close() + return nil, nil, errors.Errorf("invalid status code returned when fetching blob %d (%s)", res.StatusCode, http.StatusText(res.StatusCode)) + } + + mediaType, params, err := mime.ParseMediaType(res.Header.Get("Content-Type")) + if err != nil { + return nil, nil, err + } + + streams := make(chan io.ReadCloser) + errs := make(chan error) + + go func() { + defer close(streams) + defer close(errs) + if !strings.HasPrefix(mediaType, "multipart/") { + streams <- res.Body + return + } + boundary, found := params["boundary"] + if !found { + errs <- errors.Errorf("could not find boundary") + return + } + buffered := makeBufferedNetworkReader(res.Body, 64, 16384) + defer buffered.Close() + mr := multipart.NewReader(buffered, boundary) + for { + p, err := mr.NextPart() + if err != nil { + if err != io.EOF { + errs <- err + } + return + } + s := signalCloseReader{ + Closed: make(chan interface{}), + Stream: p, + } + streams <- s + // NextPart() cannot be called while the current part + // is being read, so wait until it is closed + <-s.Closed + } + }() + return streams, errs, nil +} + // GetBlob returns a stream for the specified blob, and the blob’s size (or -1 if unknown). // The Digest field in BlobInfo is guaranteed to be provided, Size may be -1 and MediaType may be optionally provided. // May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location. @@ -499,3 +577,119 @@ func deleteImage(ctx context.Context, sys *types.SystemContext, ref dockerRefere return nil } + +type bufferedNetworkReaderBuffer struct { + data []byte + len int + consumed int + err error +} + +type bufferedNetworkReader struct { + stream io.Reader + emptyBuffer chan *bufferedNetworkReaderBuffer + readyBuffer chan *bufferedNetworkReaderBuffer + terminate chan bool + current *bufferedNetworkReaderBuffer + mutex sync.Mutex + gotEOF bool +} + +// handleBufferedNetworkReader runs in a goroutine +func handleBufferedNetworkReader(br *bufferedNetworkReader) { + defer close(br.readyBuffer) + for { + select { + case b := <-br.emptyBuffer: + b.len, b.err = br.stream.Read(b.data) + br.readyBuffer <- b + if b.err != nil { + return + } + case <-br.terminate: + return + } + } +} + +func (n *bufferedNetworkReader) Close() { + close(n.terminate) + close(n.emptyBuffer) +} + +func (n *bufferedNetworkReader) read(p []byte) (int, error) { + if n.current != nil { + copied := copy(p, n.current.data[n.current.consumed:n.current.len]) + n.current.consumed += copied + if n.current.consumed == n.current.len { + n.emptyBuffer <- n.current + n.current = nil + } + if copied > 0 { + return copied, nil + } + } + if n.gotEOF { + return 0, io.EOF + } + + var b *bufferedNetworkReaderBuffer + + select { + case b = <-n.readyBuffer: + if b.err != nil { + if b.err != io.EOF { + return b.len, b.err + } + n.gotEOF = true + } + b.consumed = 0 + n.current = b + return n.read(p) + case <-n.terminate: + return 0, io.EOF + } +} + +func (n *bufferedNetworkReader) Read(p []byte) (int, error) { + n.mutex.Lock() + defer n.mutex.Unlock() + + return n.read(p) +} + +func makeBufferedNetworkReader(stream io.Reader, nBuffers, bufferSize uint) *bufferedNetworkReader { + br := bufferedNetworkReader{ + stream: stream, + emptyBuffer: make(chan *bufferedNetworkReaderBuffer, nBuffers), + readyBuffer: make(chan *bufferedNetworkReaderBuffer, nBuffers), + terminate: make(chan bool), + } + + go func() { + handleBufferedNetworkReader(&br) + }() + + for i := uint(0); i < nBuffers; i++ { + b := bufferedNetworkReaderBuffer{ + data: make([]byte, bufferSize), + } + br.emptyBuffer <- &b + } + + return &br +} + +type signalCloseReader struct { + Closed chan interface{} + Stream io.ReadCloser +} + +func (s signalCloseReader) Read(p []byte) (int, error) { + return s.Stream.Read(p) +} + +func (s signalCloseReader) Close() error { + defer close(s.Closed) + return s.Stream.Close() +} diff --git a/vendor/github.com/containers/image/v5/docker/docker_transport.go b/vendor/github.com/containers/image/v5/docker/docker_transport.go index 8b8e57968..541e053f3 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_transport.go +++ b/vendor/github.com/containers/image/v5/docker/docker_transport.go @@ -16,7 +16,7 @@ func init() { transports.Register(Transport) } -// Transport is an ImageTransport for Docker registry-hosted images. +// Transport is an ImageTransport for container registry-hosted images. var Transport = dockerTransport{} type dockerTransport struct{} diff --git a/vendor/github.com/containers/image/v5/docker/errors.go b/vendor/github.com/containers/image/v5/docker/errors.go index 5b5008af7..6f2c5fde5 100644 --- a/vendor/github.com/containers/image/v5/docker/errors.go +++ b/vendor/github.com/containers/image/v5/docker/errors.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" + internalTypes "github.com/containers/image/v5/internal/types" "github.com/docker/distribution/registry/client" perrors "github.com/pkg/errors" ) @@ -12,7 +13,7 @@ import ( var ( // ErrV1NotSupported is returned when we're trying to talk to a // docker V1 registry. - ErrV1NotSupported = errors.New("can't talk to a V1 docker registry") + ErrV1NotSupported = errors.New("can't talk to a V1 container registry") // ErrTooManyRequests is returned when the status code returned is 429 ErrTooManyRequests = errors.New("too many requests to registry") ) @@ -32,11 +33,15 @@ func httpResponseToError(res *http.Response, context string) error { switch res.StatusCode { case http.StatusOK: return nil + case http.StatusPartialContent: + return nil case http.StatusTooManyRequests: return ErrTooManyRequests case http.StatusUnauthorized: err := client.HandleErrorResponse(res) return ErrUnauthorizedForCredentials{Err: err} + case http.StatusBadRequest: + return internalTypes.BadPartialRequestError{Status: res.Status} default: if context != "" { context = context + ": " diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go index 9559dfb56..a558657b6 100644 --- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go +++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go @@ -140,11 +140,11 @@ func (d *Destination) PutBlob(ctx context.Context, stream io.Reader, inputInfo t if isConfig { buf, err := iolimits.ReadAtMost(stream, iolimits.MaxConfigBodySize) if err != nil { - return types.BlobInfo{}, errors.Wrap(err, "Error reading Config file stream") + return types.BlobInfo{}, errors.Wrap(err, "reading Config file stream") } d.config = buf if err := d.archive.sendFileLocked(d.archive.configPath(inputInfo.Digest), inputInfo.Size, bytes.NewReader(buf)); err != nil { - return types.BlobInfo{}, errors.Wrap(err, "Error writing Config file") + return types.BlobInfo{}, errors.Wrap(err, "writing Config file") } } else { if err := d.archive.sendFileLocked(d.archive.physicalLayerPath(inputInfo.Digest), inputInfo.Size, stream); err != nil { @@ -187,7 +187,7 @@ func (d *Destination) PutManifest(ctx context.Context, m []byte, instanceDigest // so the caller trying a different manifest kind would be pointless. var man manifest.Schema2 if err := json.Unmarshal(m, &man); err != nil { - return errors.Wrap(err, "Error parsing manifest") + return errors.Wrap(err, "parsing manifest") } if man.SchemaVersion != 2 || man.MediaType != manifest.DockerV2Schema2MediaType { return errors.Errorf("Unsupported manifest type, need a Docker schema 2 manifest") diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/reader.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/reader.go index 83de0c520..6164ceb66 100644 --- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/reader.go +++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/reader.go @@ -30,7 +30,7 @@ type Reader struct { func NewReaderFromFile(sys *types.SystemContext, path string) (*Reader, error) { file, err := os.Open(path) if err != nil { - return nil, errors.Wrapf(err, "error opening file %q", path) + return nil, errors.Wrapf(err, "opening file %q", path) } defer file.Close() @@ -38,7 +38,7 @@ func NewReaderFromFile(sys *types.SystemContext, path string) (*Reader, error) { // as a source. Otherwise we pass the stream to NewReaderFromStream. stream, isCompressed, err := compression.AutoDecompress(file) if err != nil { - return nil, errors.Wrapf(err, "Error detecting compression for file %q", path) + return nil, errors.Wrapf(err, "detecting compression for file %q", path) } defer stream.Close() if !isCompressed { @@ -55,7 +55,7 @@ func NewReaderFromStream(sys *types.SystemContext, inputStream io.Reader) (*Read // Save inputStream to a temporary file tarCopyFile, err := ioutil.TempFile(tmpdir.TemporaryDirectoryForBigFiles(sys), "docker-tar") if err != nil { - return nil, errors.Wrap(err, "error creating temporary file") + return nil, errors.Wrap(err, "creating temporary file") } defer tarCopyFile.Close() @@ -71,7 +71,7 @@ func NewReaderFromStream(sys *types.SystemContext, inputStream io.Reader) (*Read // giving users really confusing "invalid tar header" errors). uncompressedStream, _, err := compression.AutoDecompress(inputStream) if err != nil { - return nil, errors.Wrap(err, "Error auto-decompressing input") + return nil, errors.Wrap(err, "auto-decompressing input") } defer uncompressedStream.Close() @@ -80,7 +80,7 @@ func NewReaderFromStream(sys *types.SystemContext, inputStream io.Reader) (*Read // TODO: This can take quite some time, and should ideally be cancellable // using a context.Context. if _, err := io.Copy(tarCopyFile, uncompressedStream); err != nil { - return nil, errors.Wrapf(err, "error copying contents to temporary file %q", tarCopyFile.Name()) + return nil, errors.Wrapf(err, "copying contents to temporary file %q", tarCopyFile.Name()) } succeeded = true @@ -113,7 +113,7 @@ func newReader(path string, removeOnClose bool) (*Reader, error) { return nil, err } if err := json.Unmarshal(bytes, &r.Manifest); err != nil { - return nil, errors.Wrap(err, "Error decoding tar manifest.json") + return nil, errors.Wrap(err, "decoding tar manifest.json") } succeeded = true @@ -258,7 +258,7 @@ func findTarComponent(inputFile io.Reader, componentPath string) (*tar.Reader, * func (r *Reader) readTarComponent(path string, limit int) ([]byte, error) { file, err := r.openTarComponent(path) if err != nil { - return nil, errors.Wrapf(err, "Error loading tar component %s", path) + return nil, errors.Wrapf(err, "loading tar component %s", path) } defer file.Close() bytes, err := iolimits.ReadAtMost(file, limit) diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go index bd65ef844..b8d84d245 100644 --- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go +++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go @@ -80,7 +80,7 @@ func (s *Source) ensureCachedDataIsPresentPrivate() error { } var parsedConfig manifest.Schema2Image // There's a lot of info there, but we only really care about layer DiffIDs. if err := json.Unmarshal(configBytes, &parsedConfig); err != nil { - return errors.Wrapf(err, "Error decoding tar config %s", tarManifest.Config) + return errors.Wrapf(err, "decoding tar config %s", tarManifest.Config) } if parsedConfig.RootFS == nil { return errors.Errorf("Invalid image config (rootFS is not set): %s", tarManifest.Config) @@ -164,7 +164,7 @@ func (s *Source) prepareLayerData(tarManifest *ManifestItem, parsedConfig *manif // the slower method of checking if it's compressed. uncompressedStream, isCompressed, err := compression.AutoDecompress(t) if err != nil { - return nil, errors.Wrapf(err, "Error auto-decompressing %s to determine its size", layerPath) + return nil, errors.Wrapf(err, "auto-decompressing %s to determine its size", layerPath) } defer uncompressedStream.Close() @@ -172,7 +172,7 @@ func (s *Source) prepareLayerData(tarManifest *ManifestItem, parsedConfig *manif if isCompressed { uncompressedSize, err = io.Copy(ioutil.Discard, uncompressedStream) if err != nil { - return nil, errors.Wrapf(err, "Error reading %s to find its size", layerPath) + return nil, errors.Wrapf(err, "reading %s to find its size", layerPath) } } li.size = uncompressedSize @@ -292,7 +292,7 @@ func (s *Source) GetBlob(ctx context.Context, info types.BlobInfo, cache types.B uncompressedStream, _, err := compression.AutoDecompress(underlyingStream) if err != nil { - return nil, 0, errors.Wrapf(err, "Error auto-decompressing blob %s", info.Digest) + return nil, 0, errors.Wrapf(err, "auto-decompressing blob %s", info.Digest) } newStream := uncompressedReadCloser{ diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go index e0683b3cd..255f0d354 100644 --- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go +++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go @@ -94,16 +94,16 @@ func (w *Writer) ensureSingleLegacyLayerLocked(layerID string, layerDigest diges // See also the comment in physicalLayerPath. physicalLayerPath := w.physicalLayerPath(layerDigest) if err := w.sendSymlinkLocked(filepath.Join(layerID, legacyLayerFileName), filepath.Join("..", physicalLayerPath)); err != nil { - return errors.Wrap(err, "Error creating layer symbolic link") + return errors.Wrap(err, "creating layer symbolic link") } b := []byte("1.0") if err := w.sendBytesLocked(filepath.Join(layerID, legacyVersionFileName), b); err != nil { - return errors.Wrap(err, "Error writing VERSION file") + return errors.Wrap(err, "writing VERSION file") } if err := w.sendBytesLocked(filepath.Join(layerID, legacyConfigFileName), configBytes); err != nil { - return errors.Wrap(err, "Error writing config json file") + return errors.Wrap(err, "writing config json file") } w.legacyLayers[layerID] = struct{}{} @@ -128,7 +128,7 @@ func (w *Writer) writeLegacyMetadataLocked(layerDescriptors []manifest.Schema2De var config map[string]*json.RawMessage err := json.Unmarshal(configBytes, &config) if err != nil { - return errors.Wrap(err, "Error unmarshaling config") + return errors.Wrap(err, "unmarshaling config") } for _, attr := range [7]string{"architecture", "config", "container", "container_config", "created", "docker_version", "os"} { layerConfig[attr] = config[attr] @@ -152,7 +152,7 @@ func (w *Writer) writeLegacyMetadataLocked(layerDescriptors []manifest.Schema2De layerConfig["layer_id"] = chainID b, err := json.Marshal(layerConfig) // Note that layerConfig["id"] is not set yet at this point. if err != nil { - return errors.Wrap(err, "Error marshaling layer config") + return errors.Wrap(err, "marshaling layer config") } delete(layerConfig, "layer_id") layerID := digest.Canonical.FromBytes(b).Hex() @@ -160,7 +160,7 @@ func (w *Writer) writeLegacyMetadataLocked(layerDescriptors []manifest.Schema2De configBytes, err := json.Marshal(layerConfig) if err != nil { - return errors.Wrap(err, "Error marshaling layer config") + return errors.Wrap(err, "marshaling layer config") } if err := w.ensureSingleLegacyLayerLocked(layerID, l.Digest, configBytes); err != nil { @@ -280,10 +280,10 @@ func (w *Writer) Close() error { b, err = json.Marshal(w.repositories) if err != nil { - return errors.Wrap(err, "Error marshaling repositories") + return errors.Wrap(err, "marshaling repositories") } if err := w.sendBytesLocked(legacyRepositoriesFileName, b); err != nil { - return errors.Wrap(err, "Error writing config json file") + return errors.Wrap(err, "writing config json file") } if err := w.tar.Close(); err != nil { diff --git a/vendor/github.com/containers/image/v5/docker/lookaside.go b/vendor/github.com/containers/image/v5/docker/lookaside.go index 0d5d8d82a..515e59327 100644 --- a/vendor/github.com/containers/image/v5/docker/lookaside.go +++ b/vendor/github.com/containers/image/v5/docker/lookaside.go @@ -154,7 +154,7 @@ func loadAndMergeConfig(dirPath string) (*registryConfiguration, error) { var config registryConfiguration err = yaml.Unmarshal(configBytes, &config) if err != nil { - return nil, errors.Wrapf(err, "Error parsing %s", configPath) + return nil, errors.Wrapf(err, "parsing %s", configPath) } if config.DefaultDocker != nil { diff --git a/vendor/github.com/containers/image/v5/image/docker_list.go b/vendor/github.com/containers/image/v5/image/docker_list.go index 651c301aa..4fe84413c 100644 --- a/vendor/github.com/containers/image/v5/image/docker_list.go +++ b/vendor/github.com/containers/image/v5/image/docker_list.go @@ -11,20 +11,20 @@ import ( func manifestSchema2FromManifestList(ctx context.Context, sys *types.SystemContext, src types.ImageSource, manblob []byte) (genericManifest, error) { list, err := manifest.Schema2ListFromManifest(manblob) if err != nil { - return nil, errors.Wrapf(err, "Error parsing schema2 manifest list") + return nil, errors.Wrapf(err, "parsing schema2 manifest list") } targetManifestDigest, err := list.ChooseInstance(sys) if err != nil { - return nil, errors.Wrapf(err, "Error choosing image instance") + return nil, errors.Wrapf(err, "choosing image instance") } manblob, mt, err := src.GetManifest(ctx, &targetManifestDigest) if err != nil { - return nil, errors.Wrapf(err, "Error loading manifest for target platform") + return nil, errors.Wrapf(err, "loading manifest for target platform") } matches, err := manifest.MatchesDigest(manblob, targetManifestDigest) if err != nil { - return nil, errors.Wrap(err, "Error computing manifest digest") + return nil, errors.Wrap(err, "computing manifest digest") } if !matches { return nil, errors.Errorf("Image manifest does not match selected manifest digest %s", targetManifestDigest) diff --git a/vendor/github.com/containers/image/v5/image/docker_schema2.go b/vendor/github.com/containers/image/v5/image/docker_schema2.go index 61ca83364..b250a6b1d 100644 --- a/vendor/github.com/containers/image/v5/image/docker_schema2.go +++ b/vendor/github.com/containers/image/v5/image/docker_schema2.go @@ -289,7 +289,7 @@ func (m *manifestSchema2) convertToManifestSchema1(ctx context.Context, options // and anyway this blob is so small that it’s easier to just copy it than to worry about figuring out another location where to get it. info, err := dest.PutBlob(ctx, bytes.NewReader(GzippedEmptyLayer), emptyLayerBlobInfo, none.NoCache, false) if err != nil { - return nil, errors.Wrap(err, "Error uploading empty layer") + return nil, errors.Wrap(err, "uploading empty layer") } if info.Digest != emptyLayerBlobInfo.Digest { return nil, errors.Errorf("Internal error: Uploaded empty layer has digest %#v instead of %s", info.Digest, emptyLayerBlobInfo.Digest) diff --git a/vendor/github.com/containers/image/v5/image/oci_index.go b/vendor/github.com/containers/image/v5/image/oci_index.go index 022e03aca..4e6ca879a 100644 --- a/vendor/github.com/containers/image/v5/image/oci_index.go +++ b/vendor/github.com/containers/image/v5/image/oci_index.go @@ -11,20 +11,20 @@ import ( func manifestOCI1FromImageIndex(ctx context.Context, sys *types.SystemContext, src types.ImageSource, manblob []byte) (genericManifest, error) { index, err := manifest.OCI1IndexFromManifest(manblob) if err != nil { - return nil, errors.Wrapf(err, "Error parsing OCI1 index") + return nil, errors.Wrapf(err, "parsing OCI1 index") } targetManifestDigest, err := index.ChooseInstance(sys) if err != nil { - return nil, errors.Wrapf(err, "Error choosing image instance") + return nil, errors.Wrapf(err, "choosing image instance") } manblob, mt, err := src.GetManifest(ctx, &targetManifestDigest) if err != nil { - return nil, errors.Wrapf(err, "Error loading manifest for target platform") + return nil, errors.Wrapf(err, "loading manifest for target platform") } matches, err := manifest.MatchesDigest(manblob, targetManifestDigest) if err != nil { - return nil, errors.Wrap(err, "Error computing manifest digest") + return nil, errors.Wrap(err, "computing manifest digest") } if !matches { return nil, errors.Errorf("Image manifest does not match selected manifest digest %s", targetManifestDigest) diff --git a/vendor/github.com/containers/image/v5/image/unparsed.go b/vendor/github.com/containers/image/v5/image/unparsed.go index 4e3028d85..c64852f72 100644 --- a/vendor/github.com/containers/image/v5/image/unparsed.go +++ b/vendor/github.com/containers/image/v5/image/unparsed.go @@ -53,7 +53,7 @@ func (i *UnparsedImage) Manifest(ctx context.Context) ([]byte, string, error) { if digest, haveDigest := i.expectedManifestDigest(); haveDigest { matches, err := manifest.MatchesDigest(m, digest) if err != nil { - return nil, "", errors.Wrap(err, "Error computing manifest digest") + return nil, "", errors.Wrap(err, "computing manifest digest") } if !matches { return nil, "", errors.Errorf("Manifest does not match provided manifest digest %s", digest) diff --git a/vendor/github.com/containers/image/v5/internal/types/types.go b/vendor/github.com/containers/image/v5/internal/types/types.go index 4a863ba34..e0355a477 100644 --- a/vendor/github.com/containers/image/v5/internal/types/types.go +++ b/vendor/github.com/containers/image/v5/internal/types/types.go @@ -58,3 +58,33 @@ type TryReusingBlobOptions struct { // The reference of the image that contains the target blob. SrcRef reference.Named } + +// ImageSourceChunk is a portion of a blob. +// This API is experimental and can be changed without bumping the major version number. +type ImageSourceChunk struct { + Offset uint64 + Length uint64 +} + +// ImageSourceSeekable is an image source that permits to fetch chunks of the entire blob. +// This API is experimental and can be changed without bumping the major version number. +type ImageSourceSeekable interface { + // GetBlobAt returns a stream for the specified blob. + GetBlobAt(context.Context, publicTypes.BlobInfo, []ImageSourceChunk) (chan io.ReadCloser, chan error, error) +} + +// ImageDestinationPartial is a service to store a blob by requesting the missing chunks to a ImageSourceSeekable. +// This API is experimental and can be changed without bumping the major version number. +type ImageDestinationPartial interface { + // PutBlobPartial writes contents of stream and returns data representing the result. + PutBlobPartial(ctx context.Context, stream ImageSourceSeekable, srcInfo publicTypes.BlobInfo, cache publicTypes.BlobInfoCache) (publicTypes.BlobInfo, error) +} + +// BadPartialRequestError is returned by ImageSourceSeekable.GetBlobAt on an invalid request. +type BadPartialRequestError struct { + Status string +} + +func (e BadPartialRequestError) Error() string { + return e.Status +} diff --git a/vendor/github.com/containers/image/v5/manifest/common.go b/vendor/github.com/containers/image/v5/manifest/common.go index 3ece948a0..5930640ac 100644 --- a/vendor/github.com/containers/image/v5/manifest/common.go +++ b/vendor/github.com/containers/image/v5/manifest/common.go @@ -68,7 +68,7 @@ func compressionVariantMIMEType(variantTable []compressionMIMETypeSet, mimeType if mt == mimeType { // Found the variant name := mtsUncompressed if algorithm != nil { - name = algorithm.Name() + name = algorithm.InternalUnstableUndocumentedMIMEQuestionMark() } if res, ok := variants[name]; ok { if res != mtsUnsupportedMIMEType { diff --git a/vendor/github.com/containers/image/v5/manifest/docker_schema1.go b/vendor/github.com/containers/image/v5/manifest/docker_schema1.go index 58527d713..8679cad11 100644 --- a/vendor/github.com/containers/image/v5/manifest/docker_schema1.go +++ b/vendor/github.com/containers/image/v5/manifest/docker_schema1.go @@ -109,7 +109,7 @@ func (m *Schema1) initialize() error { m.ExtractedV1Compatibility = make([]Schema1V1Compatibility, len(m.History)) for i, h := range m.History { if err := json.Unmarshal([]byte(h.V1Compatibility), &m.ExtractedV1Compatibility[i]); err != nil { - return errors.Wrapf(err, "Error parsing v2s1 history entry %d", i) + return errors.Wrapf(err, "parsing v2s1 history entry %d", i) } } return nil @@ -242,14 +242,14 @@ func (m *Schema1) ToSchema2Config(diffIDs []digest.Digest) ([]byte, error) { config := []byte(m.History[0].V1Compatibility) err := json.Unmarshal(config, &s1) if err != nil { - return nil, errors.Wrapf(err, "error decoding configuration") + return nil, errors.Wrapf(err, "decoding configuration") } // Images created with versions prior to 1.8.3 require us to re-encode the encoded object, // adding some fields that aren't "omitempty". if s1.DockerVersion != "" && versions.LessThan(s1.DockerVersion, "1.8.3") { config, err = json.Marshal(&s1) if err != nil { - return nil, errors.Wrapf(err, "error re-encoding compat image config %#v", s1) + return nil, errors.Wrapf(err, "re-encoding compat image config %#v", s1) } } // Build the history. @@ -276,7 +276,7 @@ func (m *Schema1) ToSchema2Config(diffIDs []digest.Digest) ([]byte, error) { raw := make(map[string]*json.RawMessage) err = json.Unmarshal(config, &raw) if err != nil { - return nil, errors.Wrapf(err, "error re-decoding compat image config %#v", s1) + return nil, errors.Wrapf(err, "re-decoding compat image config %#v", s1) } // Drop some fields. delete(raw, "id") diff --git a/vendor/github.com/containers/image/v5/manifest/docker_schema2.go b/vendor/github.com/containers/image/v5/manifest/docker_schema2.go index 6cb605263..584b5f09c 100644 --- a/vendor/github.com/containers/image/v5/manifest/docker_schema2.go +++ b/vendor/github.com/containers/image/v5/manifest/docker_schema2.go @@ -242,7 +242,7 @@ func (m *Schema2) UpdateLayerInfos(layerInfos []types.BlobInfo) error { } mimeType, err := updatedMIMEType(schema2CompressionMIMETypeSets, mimeType, info) if err != nil { - return errors.Wrapf(err, "Error preparing updated manifest, layer %q", info.Digest) + return errors.Wrapf(err, "preparing updated manifest, layer %q", info.Digest) } m.LayersDescriptors[i].MediaType = mimeType m.LayersDescriptors[i].Digest = info.Digest diff --git a/vendor/github.com/containers/image/v5/manifest/docker_schema2_list.go b/vendor/github.com/containers/image/v5/manifest/docker_schema2_list.go index bfedff69c..9ebb8d6b9 100644 --- a/vendor/github.com/containers/image/v5/manifest/docker_schema2_list.go +++ b/vendor/github.com/containers/image/v5/manifest/docker_schema2_list.go @@ -91,7 +91,7 @@ func (list *Schema2List) UpdateInstances(updates []ListUpdate) error { func (list *Schema2List) ChooseInstance(ctx *types.SystemContext) (digest.Digest, error) { wantedPlatforms, err := platform.WantedPlatforms(ctx) if err != nil { - return "", errors.Wrapf(err, "error getting platform information %#v", ctx) + return "", errors.Wrapf(err, "getting platform information %#v", ctx) } for _, wantedPlatform := range wantedPlatforms { for _, d := range list.Manifests { @@ -115,7 +115,7 @@ func (list *Schema2List) ChooseInstance(ctx *types.SystemContext) (digest.Digest func (list *Schema2List) Serialize() ([]byte, error) { buf, err := json.Marshal(list) if err != nil { - return nil, errors.Wrapf(err, "error marshaling Schema2List %#v", list) + return nil, errors.Wrapf(err, "marshaling Schema2List %#v", list) } return buf, nil } @@ -190,7 +190,7 @@ func Schema2ListFromManifest(manifest []byte) (*Schema2List, error) { Manifests: []Schema2ManifestDescriptor{}, } if err := json.Unmarshal(manifest, &list); err != nil { - return nil, errors.Wrapf(err, "error unmarshaling Schema2List %q", string(manifest)) + return nil, errors.Wrapf(err, "unmarshaling Schema2List %q", string(manifest)) } return &list, nil } diff --git a/vendor/github.com/containers/image/v5/manifest/manifest.go b/vendor/github.com/containers/image/v5/manifest/manifest.go index 32680e09d..4b644f253 100644 --- a/vendor/github.com/containers/image/v5/manifest/manifest.go +++ b/vendor/github.com/containers/image/v5/manifest/manifest.go @@ -195,7 +195,7 @@ func MatchesDigest(manifest []byte, expectedDigest digest.Digest) (bool, error) } // AddDummyV2S1Signature adds an JWS signature with a temporary key (i.e. useless) to a v2s1 manifest. -// This is useful to make the manifest acceptable to a Docker Registry (even though nothing needs or wants the JWS signature). +// This is useful to make the manifest acceptable to a docker/distribution registry (even though nothing needs or wants the JWS signature). func AddDummyV2S1Signature(manifest []byte) ([]byte, error) { key, err := libtrust.GenerateECP256PrivateKey() if err != nil { diff --git a/vendor/github.com/containers/image/v5/manifest/oci.go b/vendor/github.com/containers/image/v5/manifest/oci.go index c6299d8e6..24ce6d080 100644 --- a/vendor/github.com/containers/image/v5/manifest/oci.go +++ b/vendor/github.com/containers/image/v5/manifest/oci.go @@ -127,7 +127,7 @@ func (m *OCI1) UpdateLayerInfos(layerInfos []types.BlobInfo) error { } mimeType, err := updatedMIMEType(oci1CompressionMIMETypeSets, mimeType, info) if err != nil { - return errors.Wrapf(err, "Error preparing updated manifest, layer %q", info.Digest) + return errors.Wrapf(err, "preparing updated manifest, layer %q", info.Digest) } if info.CryptoOperation == types.Encrypt { encMediaType, err := getEncryptedMediaType(mimeType) diff --git a/vendor/github.com/containers/image/v5/manifest/oci_index.go b/vendor/github.com/containers/image/v5/manifest/oci_index.go index 7bdea8fb2..5b4111e4e 100644 --- a/vendor/github.com/containers/image/v5/manifest/oci_index.go +++ b/vendor/github.com/containers/image/v5/manifest/oci_index.go @@ -75,7 +75,7 @@ func (index *OCI1Index) UpdateInstances(updates []ListUpdate) error { func (index *OCI1Index) ChooseInstance(ctx *types.SystemContext) (digest.Digest, error) { wantedPlatforms, err := platform.WantedPlatforms(ctx) if err != nil { - return "", errors.Wrapf(err, "error getting platform information %#v", ctx) + return "", errors.Wrapf(err, "getting platform information %#v", ctx) } for _, wantedPlatform := range wantedPlatforms { for _, d := range index.Manifests { @@ -108,7 +108,7 @@ func (index *OCI1Index) ChooseInstance(ctx *types.SystemContext) (digest.Digest, func (index *OCI1Index) Serialize() ([]byte, error) { buf, err := json.Marshal(index) if err != nil { - return nil, errors.Wrapf(err, "error marshaling OCI1Index %#v", index) + return nil, errors.Wrapf(err, "marshaling OCI1Index %#v", index) } return buf, nil } @@ -200,7 +200,7 @@ func OCI1IndexFromManifest(manifest []byte) (*OCI1Index, error) { }, } if err := json.Unmarshal(manifest, &index); err != nil { - return nil, errors.Wrapf(err, "error unmarshaling OCI1Index %q", string(manifest)) + return nil, errors.Wrapf(err, "unmarshaling OCI1Index %q", string(manifest)) } return &index, nil } diff --git a/vendor/github.com/containers/image/v5/oci/archive/oci_dest.go b/vendor/github.com/containers/image/v5/oci/archive/oci_dest.go index c874eb775..065a0b055 100644 --- a/vendor/github.com/containers/image/v5/oci/archive/oci_dest.go +++ b/vendor/github.com/containers/image/v5/oci/archive/oci_dest.go @@ -22,12 +22,12 @@ type ociArchiveImageDestination struct { func newImageDestination(ctx context.Context, sys *types.SystemContext, ref ociArchiveReference) (types.ImageDestination, error) { tempDirRef, err := createOCIRef(sys, ref.image) if err != nil { - return nil, errors.Wrapf(err, "error creating oci reference") + return nil, errors.Wrapf(err, "creating oci reference") } unpackedDest, err := tempDirRef.ociRefExtracted.NewImageDestination(ctx, sys) if err != nil { if err := tempDirRef.deleteTempDir(); err != nil { - return nil, errors.Wrapf(err, "error deleting temp directory %q", tempDirRef.tempDirectory) + return nil, errors.Wrapf(err, "deleting temp directory %q", tempDirRef.tempDirectory) } return nil, err } @@ -129,10 +129,13 @@ func (d *ociArchiveImageDestination) PutSignatures(ctx context.Context, signatur } // Commit marks the process of storing the image as successful and asks for the image to be persisted +// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list +// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the +// original manifest list digest, if desired. // after the directory is made, it is tarred up into a file and the directory is deleted func (d *ociArchiveImageDestination) Commit(ctx context.Context, unparsedToplevel types.UnparsedImage) error { if err := d.unpackedDest.Commit(ctx, unparsedToplevel); err != nil { - return errors.Wrapf(err, "error storing image %q", d.ref.image) + return errors.Wrapf(err, "storing image %q", d.ref.image) } // path of directory to tar up @@ -147,13 +150,13 @@ func tarDirectory(src, dst string) error { // input is a stream of bytes from the archive of the directory at path input, err := archive.Tar(src, archive.Uncompressed) if err != nil { - return errors.Wrapf(err, "error retrieving stream of bytes from %q", src) + return errors.Wrapf(err, "retrieving stream of bytes from %q", src) } // creates the tar file outFile, err := os.Create(dst) if err != nil { - return errors.Wrapf(err, "error creating tar file %q", dst) + return errors.Wrapf(err, "creating tar file %q", dst) } defer outFile.Close() diff --git a/vendor/github.com/containers/image/v5/oci/archive/oci_src.go b/vendor/github.com/containers/image/v5/oci/archive/oci_src.go index 8f07b3307..20b392dc0 100644 --- a/vendor/github.com/containers/image/v5/oci/archive/oci_src.go +++ b/vendor/github.com/containers/image/v5/oci/archive/oci_src.go @@ -23,13 +23,13 @@ type ociArchiveImageSource struct { func newImageSource(ctx context.Context, sys *types.SystemContext, ref ociArchiveReference) (types.ImageSource, error) { tempDirRef, err := createUntarTempDir(sys, ref) if err != nil { - return nil, errors.Wrap(err, "error creating temp directory") + return nil, errors.Wrap(err, "creating temp directory") } unpackedSrc, err := tempDirRef.ociRefExtracted.NewImageSource(ctx, sys) if err != nil { if err := tempDirRef.deleteTempDir(); err != nil { - return nil, errors.Wrapf(err, "error deleting temp directory %q", tempDirRef.tempDirectory) + return nil, errors.Wrapf(err, "deleting temp directory %q", tempDirRef.tempDirectory) } return nil, err } @@ -52,7 +52,7 @@ func LoadManifestDescriptorWithContext(sys *types.SystemContext, imgRef types.Im } tempDirRef, err := createUntarTempDir(sys, ociArchRef) if err != nil { - return imgspecv1.Descriptor{}, errors.Wrap(err, "error creating temp directory") + return imgspecv1.Descriptor{}, errors.Wrap(err, "creating temp directory") } defer func() { err := tempDirRef.deleteTempDir() @@ -61,7 +61,7 @@ func LoadManifestDescriptorWithContext(sys *types.SystemContext, imgRef types.Im descriptor, err := ocilayout.LoadManifestDescriptor(tempDirRef.ociRefExtracted) if err != nil { - return imgspecv1.Descriptor{}, errors.Wrap(err, "error loading index") + return imgspecv1.Descriptor{}, errors.Wrap(err, "loading index") } return descriptor, nil } diff --git a/vendor/github.com/containers/image/v5/oci/archive/oci_transport.go b/vendor/github.com/containers/image/v5/oci/archive/oci_transport.go index c808539d2..54d325d34 100644 --- a/vendor/github.com/containers/image/v5/oci/archive/oci_transport.go +++ b/vendor/github.com/containers/image/v5/oci/archive/oci_transport.go @@ -163,7 +163,7 @@ func (t *tempDirOCIRef) deleteTempDir() error { func createOCIRef(sys *types.SystemContext, image string) (tempDirOCIRef, error) { dir, err := ioutil.TempDir(tmpdir.TemporaryDirectoryForBigFiles(sys), "oci") if err != nil { - return tempDirOCIRef{}, errors.Wrapf(err, "error creating temp directory") + return tempDirOCIRef{}, errors.Wrapf(err, "creating temp directory") } ociRef, err := ocilayout.NewReference(dir, image) if err != nil { @@ -178,7 +178,7 @@ func createOCIRef(sys *types.SystemContext, image string) (tempDirOCIRef, error) func createUntarTempDir(sys *types.SystemContext, ref ociArchiveReference) (tempDirOCIRef, error) { tempDirRef, err := createOCIRef(sys, ref.image) if err != nil { - return tempDirOCIRef{}, errors.Wrap(err, "error creating oci reference") + return tempDirOCIRef{}, errors.Wrap(err, "creating oci reference") } src := ref.resolvedFile dst := tempDirRef.tempDirectory @@ -190,9 +190,9 @@ func createUntarTempDir(sys *types.SystemContext, ref ociArchiveReference) (temp defer arch.Close() if err := archive.NewDefaultArchiver().Untar(arch, dst, &archive.TarOptions{NoLchown: true}); err != nil { if err := tempDirRef.deleteTempDir(); err != nil { - return tempDirOCIRef{}, errors.Wrapf(err, "error deleting temp directory %q", tempDirRef.tempDirectory) + return tempDirOCIRef{}, errors.Wrapf(err, "deleting temp directory %q", tempDirRef.tempDirectory) } - return tempDirOCIRef{}, errors.Wrapf(err, "error untarring file %q", tempDirRef.tempDirectory) + return tempDirOCIRef{}, errors.Wrapf(err, "untarring file %q", tempDirRef.tempDirectory) } return tempDirRef, nil } diff --git a/vendor/github.com/containers/image/v5/oci/layout/oci_dest.go b/vendor/github.com/containers/image/v5/oci/layout/oci_dest.go index 1230e8ca3..d1d06d64d 100644 --- a/vendor/github.com/containers/image/v5/oci/layout/oci_dest.go +++ b/vendor/github.com/containers/image/v5/oci/layout/oci_dest.go @@ -303,6 +303,9 @@ func (d *ociImageDestination) PutSignatures(ctx context.Context, signatures [][] } // Commit marks the process of storing the image as successful and asks for the image to be persisted. +// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list +// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the +// original manifest list digest, if desired. // WARNING: This does not have any transactional semantics: // - Uploaded data MAY be visible to others before Commit() is called // - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed) diff --git a/vendor/github.com/containers/image/v5/openshift/openshift-copies.go b/vendor/github.com/containers/image/v5/openshift/openshift-copies.go index ec88b4ebf..f9f811784 100644 --- a/vendor/github.com/containers/image/v5/openshift/openshift-copies.go +++ b/vendor/github.com/containers/image/v5/openshift/openshift-copies.go @@ -579,7 +579,7 @@ func (rules *clientConfigLoadingRules) Load() (*clientcmdConfig, error) { continue } if err != nil { - errlist = append(errlist, errors.Wrapf(err, "Error loading config file \"%s\"", filename)) + errlist = append(errlist, errors.Wrapf(err, "loading config file \"%s\"", filename)) continue } diff --git a/vendor/github.com/containers/image/v5/openshift/openshift.go b/vendor/github.com/containers/image/v5/openshift/openshift.go index 426046e66..889772fc0 100644 --- a/vendor/github.com/containers/image/v5/openshift/openshift.go +++ b/vendor/github.com/containers/image/v5/openshift/openshift.go @@ -164,7 +164,7 @@ type openshiftImageSource struct { // Values specific to this image sys *types.SystemContext // State - docker types.ImageSource // The Docker Registry endpoint, or nil if not resolved yet + docker types.ImageSource // The docker/distribution API endpoint, or nil if not resolved yet imageStreamImageName string // Resolved image identifier, or "" if not known yet } @@ -316,7 +316,7 @@ func (s *openshiftImageSource) ensureImageIsResolved(ctx context.Context) error type openshiftImageDestination struct { client *openshiftClient - docker types.ImageDestination // The Docker Registry endpoint + docker types.ImageDestination // The docker/distribution API endpoint // State imageStreamImageName string // "" if not yet known } @@ -435,14 +435,14 @@ func (d *openshiftImageDestination) PutManifest(ctx context.Context, m []byte, i } func (d *openshiftImageDestination) PutSignatures(ctx context.Context, signatures [][]byte, instanceDigest *digest.Digest) error { - var imageStreamName string + var imageStreamImageName string if instanceDigest == nil { if d.imageStreamImageName == "" { return errors.Errorf("Internal error: Unknown manifest digest, can't add signatures") } - imageStreamName = d.imageStreamImageName + imageStreamImageName = d.imageStreamImageName } else { - imageStreamName = instanceDigest.String() + imageStreamImageName = instanceDigest.String() } // Because image signatures are a shared resource in Atomic Registry, the default upload @@ -452,7 +452,7 @@ func (d *openshiftImageDestination) PutSignatures(ctx context.Context, signature return nil // No need to even read the old state. } - image, err := d.client.getImage(ctx, imageStreamName) + image, err := d.client.getImage(ctx, imageStreamImageName) if err != nil { return err } @@ -475,9 +475,9 @@ sigExists: randBytes := make([]byte, 16) n, err := rand.Read(randBytes) if err != nil || n != 16 { - return errors.Wrapf(err, "Error generating random signature len %d", n) + return errors.Wrapf(err, "generating random signature len %d", n) } - signatureName = fmt.Sprintf("%s@%032x", imageStreamName, randBytes) + signatureName = fmt.Sprintf("%s@%032x", imageStreamImageName, randBytes) if _, ok := existingSigNames[signatureName]; !ok { break } @@ -506,6 +506,9 @@ sigExists: } // Commit marks the process of storing the image as successful and asks for the image to be persisted. +// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list +// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the +// original manifest list digest, if desired. // WARNING: This does not have any transactional semantics: // - Uploaded data MAY be visible to others before Commit() is called // - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed) diff --git a/vendor/github.com/containers/image/v5/pkg/compression/compression.go b/vendor/github.com/containers/image/v5/pkg/compression/compression.go index d5cfd8d31..718b50c05 100644 --- a/vendor/github.com/containers/image/v5/pkg/compression/compression.go +++ b/vendor/github.com/containers/image/v5/pkg/compression/compression.go @@ -9,6 +9,7 @@ import ( "github.com/containers/image/v5/pkg/compression/internal" "github.com/containers/image/v5/pkg/compression/types" + "github.com/containers/storage/pkg/chunked" "github.com/klauspost/pgzip" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -20,19 +21,22 @@ type Algorithm = types.Algorithm var ( // Gzip compression. - Gzip = internal.NewAlgorithm("gzip", []byte{0x1F, 0x8B, 0x08}, GzipDecompressor, gzipCompressor) + Gzip = internal.NewAlgorithm("gzip", "gzip", []byte{0x1F, 0x8B, 0x08}, GzipDecompressor, gzipCompressor) // Bzip2 compression. - Bzip2 = internal.NewAlgorithm("bzip2", []byte{0x42, 0x5A, 0x68}, Bzip2Decompressor, bzip2Compressor) + Bzip2 = internal.NewAlgorithm("bzip2", "bzip2", []byte{0x42, 0x5A, 0x68}, Bzip2Decompressor, bzip2Compressor) // Xz compression. - Xz = internal.NewAlgorithm("Xz", []byte{0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00}, XzDecompressor, xzCompressor) + Xz = internal.NewAlgorithm("Xz", "xz", []byte{0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00}, XzDecompressor, xzCompressor) // Zstd compression. - Zstd = internal.NewAlgorithm("zstd", []byte{0x28, 0xb5, 0x2f, 0xfd}, ZstdDecompressor, zstdCompressor) + Zstd = internal.NewAlgorithm("zstd", "zstd", []byte{0x28, 0xb5, 0x2f, 0xfd}, ZstdDecompressor, zstdCompressor) + // Zstd:chunked compression. + ZstdChunked = internal.NewAlgorithm("zstd:chunked", "zstd", []byte{0x28, 0xb5, 0x2f, 0xfd}, ZstdDecompressor, chunked.ZstdCompressor) compressionAlgorithms = map[string]Algorithm{ - Gzip.Name(): Gzip, - Bzip2.Name(): Bzip2, - Xz.Name(): Xz, - Zstd.Name(): Zstd, + Gzip.Name(): Gzip, + Bzip2.Name(): Bzip2, + Xz.Name(): Xz, + Zstd.Name(): Zstd, + ZstdChunked.Name(): ZstdChunked, } ) @@ -69,7 +73,7 @@ func XzDecompressor(r io.Reader) (io.ReadCloser, error) { } // gzipCompressor is a CompressorFunc for the gzip compression algorithm. -func gzipCompressor(r io.Writer, level *int) (io.WriteCloser, error) { +func gzipCompressor(r io.Writer, metadata map[string]string, level *int) (io.WriteCloser, error) { if level != nil { return pgzip.NewWriterLevel(r, *level) } @@ -77,18 +81,25 @@ func gzipCompressor(r io.Writer, level *int) (io.WriteCloser, error) { } // bzip2Compressor is a CompressorFunc for the bzip2 compression algorithm. -func bzip2Compressor(r io.Writer, level *int) (io.WriteCloser, error) { +func bzip2Compressor(r io.Writer, metadata map[string]string, level *int) (io.WriteCloser, error) { return nil, fmt.Errorf("bzip2 compression not supported") } // xzCompressor is a CompressorFunc for the xz compression algorithm. -func xzCompressor(r io.Writer, level *int) (io.WriteCloser, error) { +func xzCompressor(r io.Writer, metadata map[string]string, level *int) (io.WriteCloser, error) { return xz.NewWriter(r) } // CompressStream returns the compressor by its name func CompressStream(dest io.Writer, algo Algorithm, level *int) (io.WriteCloser, error) { - return internal.AlgorithmCompressor(algo)(dest, level) + m := map[string]string{} + return internal.AlgorithmCompressor(algo)(dest, m, level) +} + +// CompressStreamWithMetadata returns the compressor by its name. If the compression +// generates any metadata, it is written to the provided metadata map. +func CompressStreamWithMetadata(dest io.Writer, metadata map[string]string, algo Algorithm, level *int) (io.WriteCloser, error) { + return internal.AlgorithmCompressor(algo)(dest, metadata, level) } // DetectCompressionFormat returns an Algorithm and DecompressorFunc if the input is recognized as a compressed format, an invalid @@ -135,13 +146,13 @@ func DetectCompression(input io.Reader) (DecompressorFunc, io.Reader, error) { func AutoDecompress(stream io.Reader) (io.ReadCloser, bool, error) { decompressor, stream, err := DetectCompression(stream) if err != nil { - return nil, false, errors.Wrapf(err, "Error detecting compression") + return nil, false, errors.Wrapf(err, "detecting compression") } var res io.ReadCloser if decompressor != nil { res, err = decompressor(stream) if err != nil { - return nil, false, errors.Wrapf(err, "Error initializing decompression") + return nil, false, errors.Wrapf(err, "initializing decompression") } } else { res = ioutil.NopCloser(stream) diff --git a/vendor/github.com/containers/image/v5/pkg/compression/internal/types.go b/vendor/github.com/containers/image/v5/pkg/compression/internal/types.go index 6092a9517..5df5370b0 100644 --- a/vendor/github.com/containers/image/v5/pkg/compression/internal/types.go +++ b/vendor/github.com/containers/image/v5/pkg/compression/internal/types.go @@ -4,7 +4,7 @@ import "io" // CompressorFunc writes the compressed stream to the given writer using the specified compression level. // The caller must call Close() on the stream (even if the input stream does not need closing!). -type CompressorFunc func(io.Writer, *int) (io.WriteCloser, error) +type CompressorFunc func(io.Writer, map[string]string, *int) (io.WriteCloser, error) // DecompressorFunc returns the decompressed stream, given a compressed stream. // The caller must call Close() on the decompressed stream (even if the compressed input stream does not need closing!). @@ -13,6 +13,7 @@ type DecompressorFunc func(io.Reader) (io.ReadCloser, error) // Algorithm is a compression algorithm that can be used for CompressStream. type Algorithm struct { name string + mime string prefix []byte decompressor DecompressorFunc compressor CompressorFunc @@ -21,9 +22,10 @@ type Algorithm struct { // NewAlgorithm creates an Algorithm instance. // This function exists so that Algorithm instances can only be created by code that // is allowed to import this internal subpackage. -func NewAlgorithm(name string, prefix []byte, decompressor DecompressorFunc, compressor CompressorFunc) Algorithm { +func NewAlgorithm(name, mime string, prefix []byte, decompressor DecompressorFunc, compressor CompressorFunc) Algorithm { return Algorithm{ name: name, + mime: mime, prefix: prefix, decompressor: decompressor, compressor: compressor, @@ -35,6 +37,12 @@ func (c Algorithm) Name() string { return c.name } +// InternalUnstableUndocumentedMIMEQuestionMark ??? +// DO NOT USE THIS anywhere outside of c/image until it is properly documented. +func (c Algorithm) InternalUnstableUndocumentedMIMEQuestionMark() string { + return c.mime +} + // AlgorithmCompressor returns the compressor field of algo. // This is a function instead of a public method so that it is only callable from by code // that is allowed to import this internal subpackage. diff --git a/vendor/github.com/containers/image/v5/pkg/compression/zstd.go b/vendor/github.com/containers/image/v5/pkg/compression/zstd.go index 962fe9676..39ae014d2 100644 --- a/vendor/github.com/containers/image/v5/pkg/compression/zstd.go +++ b/vendor/github.com/containers/image/v5/pkg/compression/zstd.go @@ -40,13 +40,13 @@ func zstdWriter(dest io.Writer) (io.WriteCloser, error) { return zstd.NewWriter(dest) } -func zstdWriterWithLevel(dest io.Writer, level int) (io.WriteCloser, error) { +func zstdWriterWithLevel(dest io.Writer, level int) (*zstd.Encoder, error) { el := zstd.EncoderLevelFromZstd(level) return zstd.NewWriter(dest, zstd.WithEncoderLevel(el)) } // zstdCompressor is a CompressorFunc for the zstd compression algorithm. -func zstdCompressor(r io.Writer, level *int) (io.WriteCloser, error) { +func zstdCompressor(r io.Writer, metadata map[string]string, level *int) (io.WriteCloser, error) { if level == nil { return zstdWriter(r) } diff --git a/vendor/github.com/containers/image/v5/pkg/docker/config/config.go b/vendor/github.com/containers/image/v5/pkg/docker/config/config.go index ec7c2fcc3..8436741f3 100644 --- a/vendor/github.com/containers/image/v5/pkg/docker/config/config.go +++ b/vendor/github.com/containers/image/v5/pkg/docker/config/config.go @@ -11,6 +11,7 @@ import ( "runtime" "strings" + "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/pkg/sysregistriesv2" "github.com/containers/image/v5/types" "github.com/containers/storage/pkg/homedir" @@ -51,12 +52,19 @@ var ( ErrNotSupported = errors.New("not supported") ) -// SetCredentials stores the username and password in the credential helper or file -// and returns path to file or helper name in format (helper:%s). +// SetCredentials stores the username and password in a location +// appropriate for sys and the users’ configuration. +// A valid key can be either a registry hostname or additionally a namespace if +// the AuthenticationFileHelper is being unsed. // Returns a human-redable description of the location that was updated. // NOTE: The return value is only intended to be read by humans; its form is not an API, // it may change (or new forms can be added) any time. -func SetCredentials(sys *types.SystemContext, registry, username, password string) (string, error) { +func SetCredentials(sys *types.SystemContext, key, username, password string) (string, error) { + isNamespaced, err := validateKey(key) + if err != nil { + return "", err + } + helpers, err := sysregistriesv2.CredentialHelpers(sys) if err != nil { return "", err @@ -71,33 +79,45 @@ func SetCredentials(sys *types.SystemContext, registry, username, password strin // Special-case the built-in helpers for auth files. case sysregistriesv2.AuthenticationFileHelper: desc, err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) { - if ch, exists := auths.CredHelpers[registry]; exists { - return false, setAuthToCredHelper(ch, registry, username, password) + if ch, exists := auths.CredHelpers[key]; exists { + if isNamespaced { + return false, unsupportedNamespaceErr(ch) + } + return false, setAuthToCredHelper(ch, key, username, password) } creds := base64.StdEncoding.EncodeToString([]byte(username + ":" + password)) newCreds := dockerAuthConfig{Auth: creds} - auths.AuthConfigs[registry] = newCreds + auths.AuthConfigs[key] = newCreds return true, nil }) // External helpers. default: - desc = fmt.Sprintf("credential helper: %s", helper) - err = setAuthToCredHelper(helper, registry, username, password) + if isNamespaced { + err = unsupportedNamespaceErr(helper) + } else { + desc = fmt.Sprintf("credential helper: %s", helper) + err = setAuthToCredHelper(helper, key, username, password) + } } if err != nil { multiErr = multierror.Append(multiErr, err) - logrus.Debugf("Error storing credentials for %s in credential helper %s: %v", registry, helper, err) + logrus.Debugf("Error storing credentials for %s in credential helper %s: %v", key, helper, err) continue } - logrus.Debugf("Stored credentials for %s in credential helper %s", registry, helper) + logrus.Debugf("Stored credentials for %s in credential helper %s", key, helper) return desc, nil } return "", multiErr } +func unsupportedNamespaceErr(helper string) error { + return errors.Errorf("namespaced key is not supported for credential helper %s", helper) +} + // SetAuthentication stores the username and password in the credential helper or file -func SetAuthentication(sys *types.SystemContext, registry, username, password string) error { - _, err := SetCredentials(sys, registry, username, password) +// See the documentation of SetCredentials for format of "key" +func SetAuthentication(sys *types.SystemContext, key, username, password string) error { + _, err := SetCredentials(sys, key, username, password) return err } @@ -125,7 +145,7 @@ func GetAllCredentials(sys *types.SystemContext) (map[string]types.DockerAuthCon // readJSONFile returns an empty map in case the path doesn't exist. auths, err := readJSONFile(path.path, path.legacyFormat) if err != nil { - return nil, errors.Wrapf(err, "error reading JSON file %q", path.path) + return nil, errors.Wrapf(err, "reading JSON file %q", path.path) } // Credential helpers in the auth file have a // direct mapping to a registry, so we can just @@ -215,13 +235,34 @@ func getAuthFilePaths(sys *types.SystemContext, homeDir string) []authPath { // helpers with falling back to using either auth.json // file or .docker/config.json, including support for OAuth2 and IdentityToken. // If an entry is not found, an empty struct is returned. +// +// Deprecated: GetCredentialsForRef should be used in favor of this API +// because it allows different credentials for different repositories on the +// same registry. func GetCredentials(sys *types.SystemContext, registry string) (types.DockerAuthConfig, error) { - return getCredentialsWithHomeDir(sys, registry, homedir.Get()) + return getCredentialsWithHomeDir(sys, nil, registry, homedir.Get()) } -// getCredentialsWithHomeDir is an internal implementation detail of GetCredentials, -// it exists only to allow testing it with an artificial home directory. -func getCredentialsWithHomeDir(sys *types.SystemContext, registry, homeDir string) (types.DockerAuthConfig, error) { +// GetCredentialsForRef returns the registry credentials necessary for +// accessing ref on the registry ref points to, +// appropriate for sys and the users’ configuration. +// If an entry is not found, an empty struct is returned. +func GetCredentialsForRef(sys *types.SystemContext, ref reference.Named) (types.DockerAuthConfig, error) { + return getCredentialsWithHomeDir(sys, ref, reference.Domain(ref), homedir.Get()) +} + +// getCredentialsWithHomeDir is an internal implementation detail of +// GetCredentialsForRef and GetCredentials. It exists only to allow testing it +// with an artificial home directory. +func getCredentialsWithHomeDir(sys *types.SystemContext, ref reference.Named, registry, homeDir string) (types.DockerAuthConfig, error) { + // consistency check of the ref and registry arguments + if ref != nil && reference.Domain(ref) != registry { + return types.DockerAuthConfig{}, errors.Errorf( + "internal error: provided reference domain %q name does not match registry %q", + reference.Domain(ref), registry, + ) + } + if sys != nil && sys.DockerAuthConfig != nil { logrus.Debugf("Returning credentials for %s from DockerAuthConfig", registry) return *sys.DockerAuthConfig, nil @@ -230,7 +271,7 @@ func getCredentialsWithHomeDir(sys *types.SystemContext, registry, homeDir strin // Anonymous function to query credentials from auth files. getCredentialsFromAuthFiles := func() (types.DockerAuthConfig, error) { for _, path := range getAuthFilePaths(sys, homeDir) { - authConfig, err := findAuthentication(registry, path.path, path.legacyFormat) + authConfig, err := findAuthentication(ref, registry, path.path, path.legacyFormat) if err != nil { return types.DockerAuthConfig{}, err } @@ -284,7 +325,7 @@ func getCredentialsWithHomeDir(sys *types.SystemContext, registry, homeDir strin // .docker/config.json // // Deprecated: This API only has support for username and password. To get the -// support for oauth2 in docker registry authentication, we added the new +// support for oauth2 in container registry authentication, we added the new // GetCredentials API. The new API should be used and this API is kept to // maintain backward compatibility. func GetAuthentication(sys *types.SystemContext, registry string) (string, string, error) { @@ -294,7 +335,7 @@ func GetAuthentication(sys *types.SystemContext, registry string) (string, strin // getAuthenticationWithHomeDir is an internal implementation detail of GetAuthentication, // it exists only to allow testing it with an artificial home directory. func getAuthenticationWithHomeDir(sys *types.SystemContext, registry, homeDir string) (string, string, error) { - auth, err := getCredentialsWithHomeDir(sys, registry, homeDir) + auth, err := getCredentialsWithHomeDir(sys, nil, registry, homeDir) if err != nil { return "", "", err } @@ -304,9 +345,16 @@ func getAuthenticationWithHomeDir(sys *types.SystemContext, registry, homeDir st return auth.Username, auth.Password, nil } -// RemoveAuthentication removes credentials for `registry` from all possible +// RemoveAuthentication removes credentials for `key` from all possible // sources such as credential helpers and auth files. -func RemoveAuthentication(sys *types.SystemContext, registry string) error { +// A valid key can be either a registry hostname or additionally a namespace if +// the AuthenticationFileHelper is being unsed. +func RemoveAuthentication(sys *types.SystemContext, key string) error { + isNamespaced, err := validateKey(key) + if err != nil { + return err + } + helpers, err := sysregistriesv2.CredentialHelpers(sys) if err != nil { return err @@ -316,17 +364,22 @@ func RemoveAuthentication(sys *types.SystemContext, registry string) error { isLoggedIn := false removeFromCredHelper := func(helper string) { - err := deleteAuthFromCredHelper(helper, registry) - if err == nil { - logrus.Debugf("Credentials for %q were deleted from credential helper %s", registry, helper) - isLoggedIn = true - return - } - if credentials.IsErrCredentialsNotFoundMessage(err.Error()) { - logrus.Debugf("Not logged in to %s with credential helper %s", registry, helper) + if isNamespaced { + logrus.Debugf("Not removing credentials because namespaced keys are not supported for the credential helper: %s", helper) return + } else { + err := deleteAuthFromCredHelper(helper, key) + if err == nil { + logrus.Debugf("Credentials for %q were deleted from credential helper %s", key, helper) + isLoggedIn = true + return + } + if credentials.IsErrCredentialsNotFoundMessage(err.Error()) { + logrus.Debugf("Not logged in to %s with credential helper %s", key, helper) + return + } } - multiErr = multierror.Append(multiErr, errors.Wrapf(err, "error removing credentials for %s from credential helper %s", registry, helper)) + multiErr = multierror.Append(multiErr, errors.Wrapf(err, "removing credentials for %s from credential helper %s", key, helper)) } for _, helper := range helpers { @@ -335,15 +388,12 @@ func RemoveAuthentication(sys *types.SystemContext, registry string) error { // Special-case the built-in helper for auth files. case sysregistriesv2.AuthenticationFileHelper: _, err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) { - if innerHelper, exists := auths.CredHelpers[registry]; exists { + if innerHelper, exists := auths.CredHelpers[key]; exists { removeFromCredHelper(innerHelper) } - if _, ok := auths.AuthConfigs[registry]; ok { - isLoggedIn = true - delete(auths.AuthConfigs, registry) - } else if _, ok := auths.AuthConfigs[normalizeRegistry(registry)]; ok { + if _, ok := auths.AuthConfigs[key]; ok { isLoggedIn = true - delete(auths.AuthConfigs, normalizeRegistry(registry)) + delete(auths.AuthConfigs, key) } return true, multiErr }) @@ -486,13 +536,13 @@ func readJSONFile(path string, legacyFormat bool) (dockerConfigFile, error) { if legacyFormat { if err = json.Unmarshal(raw, &auths.AuthConfigs); err != nil { - return dockerConfigFile{}, errors.Wrapf(err, "error unmarshaling JSON at %q", path) + return dockerConfigFile{}, errors.Wrapf(err, "unmarshaling JSON at %q", path) } return auths, nil } if err = json.Unmarshal(raw, &auths); err != nil { - return dockerConfigFile{}, errors.Wrapf(err, "error unmarshaling JSON at %q", path) + return dockerConfigFile{}, errors.Wrapf(err, "unmarshaling JSON at %q", path) } if auths.AuthConfigs == nil { @@ -524,21 +574,21 @@ func modifyJSON(sys *types.SystemContext, editor func(auths *dockerConfigFile) ( auths, err := readJSONFile(path, false) if err != nil { - return "", errors.Wrapf(err, "error reading JSON file %q", path) + return "", errors.Wrapf(err, "reading JSON file %q", path) } updated, err := editor(&auths) if err != nil { - return "", errors.Wrapf(err, "error updating %q", path) + return "", errors.Wrapf(err, "updating %q", path) } if updated { newData, err := json.MarshalIndent(auths, "", "\t") if err != nil { - return "", errors.Wrapf(err, "error marshaling JSON %q", path) + return "", errors.Wrapf(err, "marshaling JSON %q", path) } if err = ioutil.WriteFile(path, newData, 0600); err != nil { - return "", errors.Wrapf(err, "error writing to file %q", path) + return "", errors.Wrapf(err, "writing to file %q", path) } } @@ -575,11 +625,13 @@ func deleteAuthFromCredHelper(credHelper, registry string) error { return helperclient.Erase(p, registry) } -// findAuthentication looks for auth of registry in path -func findAuthentication(registry, path string, legacyFormat bool) (types.DockerAuthConfig, error) { +// findAuthentication looks for auth of registry in path. If ref is +// not nil, then it will be taken into account when looking up the +// authentication credentials. +func findAuthentication(ref reference.Named, registry, path string, legacyFormat bool) (types.DockerAuthConfig, error) { auths, err := readJSONFile(path, legacyFormat) if err != nil { - return types.DockerAuthConfig{}, errors.Wrapf(err, "error reading JSON file %q", path) + return types.DockerAuthConfig{}, errors.Wrapf(err, "reading JSON file %q", path) } // First try cred helpers. They should always be normalized. @@ -587,16 +639,36 @@ func findAuthentication(registry, path string, legacyFormat bool) (types.DockerA return getAuthFromCredHelper(ch, registry) } - // I'm feeling lucky - if val, exists := auths.AuthConfigs[registry]; exists { - return decodeDockerAuth(val) + // Support for different paths in auth. + // (This is not a feature of ~/.docker/config.json; we support it even for + // those files as an extension.) + var keys []string + if !legacyFormat && ref != nil { + keys = authKeysForRef(ref) + } else { + keys = []string{registry} + } + + // Repo or namespace keys are only supported as exact matches. For registry + // keys we prefer exact matches as well. + for _, key := range keys { + if val, exists := auths.AuthConfigs[key]; exists { + return decodeDockerAuth(val) + } } // bad luck; let's normalize the entries first - registry = normalizeRegistry(registry) + // This primarily happens for legacyFormat, which for a time used API URLs + // (http[s:]//…/v1/) as keys. + // Secondarily, (docker login) accepted URLs with no normalization for + // several years, and matched registry hostnames against that, so support + // those entries even in non-legacyFormat ~/.docker/config.json. + // The docker.io registry still uses the /v1/ key with a special host name, + // so account for that as well. + registry = normalizeAuthFileKey(registry, legacyFormat) normalizedAuths := map[string]dockerAuthConfig{} for k, v := range auths.AuthConfigs { - normalizedAuths[normalizeRegistry(k)] = v + normalizedAuths[normalizeAuthFileKey(k, legacyFormat)] = v } if val, exists := normalizedAuths[registry]; exists { @@ -606,6 +678,28 @@ func findAuthentication(registry, path string, legacyFormat bool) (types.DockerA return types.DockerAuthConfig{}, nil } +// authKeysForRef returns the valid paths for a provided reference. For example, +// when given a reference "quay.io/repo/ns/image:tag", then it would return +// - quay.io/repo/ns/image +// - quay.io/repo/ns +// - quay.io/repo +// - quay.io +func authKeysForRef(ref reference.Named) (res []string) { + name := ref.Name() + + for { + res = append(res, name) + + lastSlash := strings.LastIndex(name, "/") + if lastSlash == -1 { + break + } + name = name[:lastSlash] + } + + return res +} + // decodeDockerAuth decodes the username and password, which is // encoded in base64. func decodeDockerAuth(conf dockerAuthConfig) (types.DockerAuthConfig, error) { @@ -629,27 +723,36 @@ func decodeDockerAuth(conf dockerAuthConfig) (types.DockerAuthConfig, error) { }, nil } -// convertToHostname converts a registry url which has http|https prepended -// to just an hostname. -// Copied from github.com/docker/docker/registry/auth.go -func convertToHostname(url string) string { - stripped := url - if strings.HasPrefix(url, "http://") { - stripped = strings.TrimPrefix(url, "http://") - } else if strings.HasPrefix(url, "https://") { - stripped = strings.TrimPrefix(url, "https://") - } +// normalizeAuthFileKey takes a key, converts it to a host name and normalizes +// the resulting registry. +func normalizeAuthFileKey(key string, legacyFormat bool) string { + stripped := strings.TrimPrefix(key, "http://") + stripped = strings.TrimPrefix(stripped, "https://") - nameParts := strings.SplitN(stripped, "/", 2) + if legacyFormat || stripped != key { + stripped = strings.SplitN(stripped, "/", 2)[0] + } - return nameParts[0] + return normalizeRegistry(stripped) } +// normalizeRegistry converts the provided registry if a known docker.io host +// is provided. func normalizeRegistry(registry string) string { - normalized := convertToHostname(registry) - switch normalized { + switch registry { case "registry-1.docker.io", "docker.io": return "index.docker.io" } - return normalized + return registry +} + +// validateKey verifies that the input key does not have a prefix that is not +// allowed and returns an indicator if the key is namespaced. +func validateKey(key string) (isNamespaced bool, err error) { + if strings.HasPrefix(key, "http://") || strings.HasPrefix(key, "https://") { + return isNamespaced, errors.Errorf("key %s contains http[s]:// prefix", key) + } + + // check if the provided key contains one or more subpaths. + return strings.ContainsRune(key, '/'), nil } diff --git a/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go b/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go index 93c75b944..1354ee46d 100644 --- a/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go +++ b/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go @@ -73,7 +73,7 @@ func removeAllAuthFromKernelKeyring() error { //nolint:deadcode,unused if strings.HasPrefix(keyDescribe, keyDescribePrefix) { err := keyctl.Unlink(userkeyring, k) if err != nil { - return errors.Wrapf(err, "error unlinking key %d", k.ID()) + return errors.Wrapf(err, "unlinking key %d", k.ID()) } logrus.Debugf("unlinked key %d:%s", k.ID(), keyAttr) } @@ -100,16 +100,16 @@ func setAuthToKernelKeyring(registry, username, password string) error { //nolin // link the key to userKeyring userKeyring, err := keyctl.UserKeyring() if err != nil { - return errors.Wrapf(err, "error getting user keyring") + return errors.Wrapf(err, "getting user keyring") } err = keyctl.Link(userKeyring, id) if err != nil { - return errors.Wrapf(err, "error linking the key to user keyring") + return errors.Wrapf(err, "linking the key to user keyring") } // unlink the key from session keyring err = keyctl.Unlink(keyring, id) if err != nil { - return errors.Wrapf(err, "error unlinking the key from session keyring") + return errors.Wrapf(err, "unlinking the key from session keyring") } return nil } diff --git a/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go b/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go index ab1eee8f3..fb0a15b99 100644 --- a/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go +++ b/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go @@ -211,7 +211,7 @@ func (c *PullCandidate) Record() error { value := reference.TrimNamed(c.Value) if err := Add(c.resolved.systemContext, name.String(), value); err != nil { - return errors.Wrapf(err, "error recording short-name alias (%q=%q)", c.resolved.userInput, c.Value) + return errors.Wrapf(err, "recording short-name alias (%q=%q)", c.resolved.userInput, c.Value) } return nil } @@ -323,7 +323,7 @@ func Resolve(ctx *types.SystemContext, name string) (*Resolved, error) { for _, reg := range unqualifiedSearchRegistries { named, err := reference.ParseNormalizedNamed(fmt.Sprintf("%s/%s", reg, name)) if err != nil { - return nil, errors.Wrapf(err, "error creating reference with unqualified-search registry %q", reg) + return nil, errors.Wrapf(err, "creating reference with unqualified-search registry %q", reg) } // Make sure to add ":latest" if needed named = reference.TagNameOnly(named) @@ -450,7 +450,7 @@ func ResolveLocally(ctx *types.SystemContext, name string) ([]reference.Named, e for _, reg := range append([]string{"localhost"}, unqualifiedSearchRegistries...) { named, err := reference.ParseNormalizedNamed(fmt.Sprintf("%s/%s", reg, name)) if err != nil { - return nil, errors.Wrapf(err, "error creating reference with unqualified-search registry %q", reg) + return nil, errors.Wrapf(err, "creating reference with unqualified-search registry %q", reg) } // Make sure to add ":latest" if needed named = reference.TagNameOnly(named) diff --git a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/shortnames.go b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/shortnames.go index 784a616dc..7122e869f 100644 --- a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/shortnames.go +++ b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/shortnames.go @@ -3,6 +3,7 @@ package sysregistriesv2 import ( "os" "path/filepath" + "reflect" "strings" "github.com/BurntSushi/toml" @@ -49,6 +50,17 @@ type shortNameAliasConf struct { // reference counter parts. // Note that Aliases is niled after being loaded from a file. Aliases map[string]string `toml:"aliases"` + + // If you add any field, make sure to update nonempty() below. +} + +// nonempty returns true if config contains at least one configuration entry. +func (c *shortNameAliasConf) nonempty() bool { + copy := *c // A shallow copy + if copy.Aliases != nil && len(copy.Aliases) == 0 { + copy.Aliases = nil + } + return !reflect.DeepEqual(copy, shortNameAliasConf{}) } // alias combines the parsed value of an alias with the config file it has been @@ -197,7 +209,7 @@ func RemoveShortNameAlias(ctx *types.SystemContext, name string) error { func parseShortNameValue(alias string) (reference.Named, error) { ref, err := reference.Parse(alias) if err != nil { - return nil, errors.Wrapf(err, "error parsing alias %q", alias) + return nil, errors.Wrapf(err, "parsing alias %q", alias) } if _, ok := ref.(reference.Digested); ok { @@ -306,14 +318,14 @@ func loadShortNameAliasConf(confPath string) (*shortNameAliasConf, *shortNameAli _, err := toml.DecodeFile(confPath, &conf) if err != nil && !os.IsNotExist(err) { // It's okay if the config doesn't exist. Other errors are not. - return nil, nil, errors.Wrapf(err, "error loading short-name aliases config file %q", confPath) + return nil, nil, errors.Wrapf(err, "loading short-name aliases config file %q", confPath) } // Even if we don’t always need the cache, doing so validates the machine-generated config. The // file could still be corrupted by another process or user. cache, err := newShortNameAliasCache(confPath, &conf) if err != nil { - return nil, nil, errors.Wrapf(err, "error loading short-name aliases config file %q", confPath) + return nil, nil, errors.Wrapf(err, "loading short-name aliases config file %q", confPath) } return &conf, cache, nil diff --git a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go index 880f8c871..4c1629f56 100644 --- a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go +++ b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "reflect" "regexp" "sort" "strings" @@ -87,7 +88,7 @@ func (e *Endpoint) rewriteReference(ref reference.Named, prefix string) (referen newNamedRef = e.Location + refString[prefixLen:] newParsedRef, err := reference.ParseNamed(newNamedRef) if err != nil { - return nil, errors.Wrapf(err, "error rewriting reference") + return nil, errors.Wrapf(err, "rewriting reference") } return newParsedRef, nil @@ -172,9 +173,17 @@ type V1RegistriesConf struct { // Nonempty returns true if config contains at least one configuration entry. func (config *V1RegistriesConf) Nonempty() bool { - return (len(config.V1TOMLConfig.Search.Registries) != 0 || - len(config.V1TOMLConfig.Insecure.Registries) != 0 || - len(config.V1TOMLConfig.Block.Registries) != 0) + copy := *config // A shallow copy + if copy.V1TOMLConfig.Search.Registries != nil && len(copy.V1TOMLConfig.Search.Registries) == 0 { + copy.V1TOMLConfig.Search.Registries = nil + } + if copy.V1TOMLConfig.Insecure.Registries != nil && len(copy.V1TOMLConfig.Insecure.Registries) == 0 { + copy.V1TOMLConfig.Insecure.Registries = nil + } + if copy.V1TOMLConfig.Block.Registries != nil && len(copy.V1TOMLConfig.Block.Registries) == 0 { + copy.V1TOMLConfig.Block.Registries = nil + } + return !reflect.DeepEqual(copy, V1RegistriesConf{}) } // V2RegistriesConf is the sysregistries v2 configuration format. @@ -203,12 +212,26 @@ type V2RegistriesConf struct { ShortNameMode string `toml:"short-name-mode"` shortNameAliasConf + + // If you add any field, make sure to update Nonempty() below. } // Nonempty returns true if config contains at least one configuration entry. func (config *V2RegistriesConf) Nonempty() bool { - return (len(config.Registries) != 0 || - len(config.UnqualifiedSearchRegistries) != 0) + copy := *config // A shallow copy + if copy.Registries != nil && len(copy.Registries) == 0 { + copy.Registries = nil + } + if copy.UnqualifiedSearchRegistries != nil && len(copy.UnqualifiedSearchRegistries) == 0 { + copy.UnqualifiedSearchRegistries = nil + } + if copy.CredentialHelpers != nil && len(copy.CredentialHelpers) == 0 { + copy.CredentialHelpers = nil + } + if !copy.shortNameAliasConf.nonempty() { + copy.shortNameAliasConf = shortNameAliasConf{} + } + return !reflect.DeepEqual(copy, V2RegistriesConf{}) } // parsedConfig is the result of parsing, and possibly merging, configuration files; @@ -604,7 +627,7 @@ func dropInConfigs(wrapper configWrapper) ([]string, error) { if err != nil && !os.IsNotExist(err) { // Ignore IsNotExist errors: most systems won't have a registries.conf.d // directory. - return nil, errors.Wrapf(err, "error reading registries.conf.d") + return nil, errors.Wrapf(err, "reading registries.conf.d") } } @@ -646,7 +669,7 @@ func tryUpdatingCache(ctx *types.SystemContext, wrapper configWrapper) (*parsedC return nil, err // Should never happen } } else { - return nil, errors.Wrapf(err, "error loading registries configuration %q", wrapper.configPath) + return nil, errors.Wrapf(err, "loading registries configuration %q", wrapper.configPath) } } @@ -659,7 +682,7 @@ func tryUpdatingCache(ctx *types.SystemContext, wrapper configWrapper) (*parsedC // Enforce v2 format for drop-in-configs. dropIn, err := loadConfigFile(path, true) if err != nil { - return nil, errors.Wrapf(err, "error loading drop-in registries configuration %q", path) + return nil, errors.Wrapf(err, "loading drop-in registries configuration %q", path) } config.updateWithConfigurationFrom(dropIn) } @@ -910,7 +933,7 @@ func loadConfigFile(path string, forceV2 bool) (*parsedConfig, error) { // Parse and validate short-name aliases. cache, err := newShortNameAliasCache(path, &res.partialV2.shortNameAliasConf) if err != nil { - return nil, errors.Wrap(err, "error validating short-name aliases") + return nil, errors.Wrap(err, "validating short-name aliases") } res.aliasCache = cache // Clear conf.partialV2.shortNameAliasConf to make it available for garbage collection and diff --git a/vendor/github.com/containers/image/v5/storage/storage_image.go b/vendor/github.com/containers/image/v5/storage/storage_image.go index 7072d6860..6b0fea61a 100644 --- a/vendor/github.com/containers/image/v5/storage/storage_image.go +++ b/vendor/github.com/containers/image/v5/storage/storage_image.go @@ -23,7 +23,9 @@ import ( "github.com/containers/image/v5/pkg/blobinfocache/none" "github.com/containers/image/v5/types" "github.com/containers/storage" + "github.com/containers/storage/drivers" "github.com/containers/storage/pkg/archive" + "github.com/containers/storage/pkg/chunked" "github.com/containers/storage/pkg/ioutils" digest "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" @@ -59,6 +61,7 @@ type storageImageDestination struct { directory string // Temporary directory where we store blobs until Commit() time nextTempFileID int32 // A counter that we use for computing filenames to assign to blobs manifest []byte // Manifest contents, temporary + manifestDigest digest.Digest // Valid if len(manifest) != 0 signatures []byte // Signature contents, temporary signatureses map[digest.Digest][]byte // Instance signature contents, temporary SignatureSizes []int `json:"signature-sizes,omitempty"` // List of sizes of each signature slice @@ -76,12 +79,13 @@ type storageImageDestination struct { indexToStorageID map[int]*string // All accesses to below data are protected by `lock` which is made // *explicit* in the code. - blobDiffIDs map[digest.Digest]digest.Digest // Mapping from layer blobsums to their corresponding DiffIDs - fileSizes map[digest.Digest]int64 // Mapping from layer blobsums to their sizes - filenames map[digest.Digest]string // Mapping from layer blobsums to names of files we used to hold them - currentIndex int // The index of the layer to be committed (i.e., lower indices have already been committed) - indexToPulledLayerInfo map[int]*manifest.LayerInfo // Mapping from layer (by index) to pulled down blob - blobAdditionalLayer map[digest.Digest]storage.AdditionalLayer // Mapping from layer blobsums to their corresponding additional layer + blobDiffIDs map[digest.Digest]digest.Digest // Mapping from layer blobsums to their corresponding DiffIDs + fileSizes map[digest.Digest]int64 // Mapping from layer blobsums to their sizes + filenames map[digest.Digest]string // Mapping from layer blobsums to names of files we used to hold them + currentIndex int // The index of the layer to be committed (i.e., lower indices have already been committed) + indexToPulledLayerInfo map[int]*manifest.LayerInfo // Mapping from layer (by index) to pulled down blob + blobAdditionalLayer map[digest.Digest]storage.AdditionalLayer // Mapping from layer blobsums to their corresponding additional layer + diffOutputs map[digest.Digest]*graphdriver.DriverWithDifferOutput // Mapping from digest to differ output } type storageImageCloser struct { @@ -121,7 +125,7 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, imageRef stor } if img.Metadata != "" { if err := json.Unmarshal([]byte(img.Metadata), image); err != nil { - return nil, errors.Wrap(err, "error decoding metadata for source image") + return nil, errors.Wrap(err, "decoding metadata for source image") } } return image, nil @@ -239,7 +243,7 @@ func (s *storageImageSource) GetManifest(ctx context.Context, instanceDigest *di key := manifestBigDataKey(*instanceDigest) blob, err := s.imageRef.transport.store.ImageBigData(s.image.ID, key) if err != nil { - return nil, "", errors.Wrapf(err, "error reading manifest for image instance %q", *instanceDigest) + return nil, "", errors.Wrapf(err, "reading manifest for image instance %q", *instanceDigest) } return blob, manifest.GuessMIMEType(blob), err } @@ -276,14 +280,14 @@ func (s *storageImageSource) GetManifest(ctx context.Context, instanceDigest *di func (s *storageImageSource) LayerInfosForCopy(ctx context.Context, instanceDigest *digest.Digest) ([]types.BlobInfo, error) { manifestBlob, manifestType, err := s.GetManifest(ctx, instanceDigest) if err != nil { - return nil, errors.Wrapf(err, "error reading image manifest for %q", s.image.ID) + return nil, errors.Wrapf(err, "reading image manifest for %q", s.image.ID) } if manifest.MIMETypeIsMultiImage(manifestType) { return nil, errors.Errorf("can't copy layers for a manifest list (shouldn't be attempted)") } man, err := manifest.FromBlob(manifestBlob, manifestType) if err != nil { - return nil, errors.Wrapf(err, "error parsing image manifest for %q", s.image.ID) + return nil, errors.Wrapf(err, "parsing image manifest for %q", s.image.ID) } uncompressedLayerType := "" @@ -299,7 +303,7 @@ func (s *storageImageSource) LayerInfosForCopy(ctx context.Context, instanceDige for layerID != "" { layer, err := s.imageRef.transport.store.Layer(layerID) if err != nil { - return nil, errors.Wrapf(err, "error reading layer %q in image %q", layerID, s.image.ID) + return nil, errors.Wrapf(err, "reading layer %q in image %q", layerID, s.image.ID) } if layer.UncompressedDigest == "" { return nil, errors.Errorf("uncompressed digest for layer %q is unknown", layerID) @@ -318,7 +322,7 @@ func (s *storageImageSource) LayerInfosForCopy(ctx context.Context, instanceDige res, err := buildLayerInfosForCopy(man.LayerInfos(), physicalBlobInfos) if err != nil { - return nil, errors.Wrapf(err, "error creating LayerInfosForCopy of image %q", s.image.ID) + return nil, errors.Wrapf(err, "creating LayerInfosForCopy of image %q", s.image.ID) } return res, nil } @@ -367,13 +371,13 @@ func (s *storageImageSource) GetSignatures(ctx context.Context, instanceDigest * if len(signatureSizes) > 0 { signatureBlob, err := s.imageRef.transport.store.ImageBigData(s.image.ID, key) if err != nil { - return nil, errors.Wrapf(err, "error looking up signatures data for image %q (%s)", s.image.ID, instance) + return nil, errors.Wrapf(err, "looking up signatures data for image %q (%s)", s.image.ID, instance) } signature = signatureBlob } for _, length := range signatureSizes { if offset+length > len(signature) { - return nil, errors.Wrapf(err, "error looking up signatures data for image %q (%s): expected at least %d bytes, only found %d", s.image.ID, instance, len(signature), offset+length) + return nil, errors.Wrapf(err, "looking up signatures data for image %q (%s): expected at least %d bytes, only found %d", s.image.ID, instance, len(signature), offset+length) } sigslice = append(sigslice, signature[offset:offset+length]) offset += length @@ -389,7 +393,7 @@ func (s *storageImageSource) GetSignatures(ctx context.Context, instanceDigest * func newImageDestination(sys *types.SystemContext, imageRef storageReference) (*storageImageDestination, error) { directory, err := ioutil.TempDir(tmpdir.TemporaryDirectoryForBigFiles(sys), "storage") if err != nil { - return nil, errors.Wrapf(err, "error creating a temporary directory") + return nil, errors.Wrapf(err, "creating a temporary directory") } image := &storageImageDestination{ imageRef: imageRef, @@ -403,6 +407,7 @@ func newImageDestination(sys *types.SystemContext, imageRef storageReference) (* SignaturesSizes: make(map[digest.Digest][]int), indexToStorageID: make(map[int]*string), indexToPulledLayerInfo: make(map[int]*manifest.LayerInfo), + diffOutputs: make(map[digest.Digest]*graphdriver.DriverWithDifferOutput), } return image, nil } @@ -418,6 +423,11 @@ func (s *storageImageDestination) Close() error { for _, al := range s.blobAdditionalLayer { al.Release() } + for _, v := range s.diffOutputs { + if v.Target != "" { + _ = s.imageRef.transport.store.CleanupStagingDirectory(v.Target) + } + } return os.RemoveAll(s.directory) } @@ -483,21 +493,21 @@ func (s *storageImageDestination) PutBlob(ctx context.Context, stream io.Reader, filename := s.computeNextBlobCacheFile() file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { - return errorBlobInfo, errors.Wrapf(err, "error creating temporary file %q", filename) + return errorBlobInfo, errors.Wrapf(err, "creating temporary file %q", filename) } defer file.Close() counter := ioutils.NewWriteCounter(hasher.Hash()) reader := io.TeeReader(io.TeeReader(stream, counter), file) decompressed, err := archive.DecompressStream(reader) if err != nil { - return errorBlobInfo, errors.Wrap(err, "error setting up to decompress blob") + return errorBlobInfo, errors.Wrap(err, "setting up to decompress blob") } // Copy the data to the file. // TODO: This can take quite some time, and should ideally be cancellable using ctx.Done(). _, err = io.Copy(diffID.Hash(), decompressed) decompressed.Close() if err != nil { - return errorBlobInfo, errors.Wrapf(err, "error storing blob to file %q", filename) + return errorBlobInfo, errors.Wrapf(err, "storing blob to file %q", filename) } // Ensure that any information that we were given about the blob is correct. if blobinfo.Digest.Validate() == nil && blobinfo.Digest != hasher.Digest() { @@ -556,7 +566,7 @@ func (s *storageImageDestination) tryReusingBlobWithSrcRef(ctx context.Context, // Check if we have the layer in the underlying additional layer store. aLayer, err := s.imageRef.transport.store.LookupAdditionalLayer(blobinfo.Digest, ref.String()) if err != nil && errors.Cause(err) != storage.ErrLayerUnknown { - return false, types.BlobInfo{}, errors.Wrapf(err, `Error looking for compressed layers with digest %q and labels`, blobinfo.Digest) + return false, types.BlobInfo{}, errors.Wrapf(err, `looking for compressed layers with digest %q and labels`, blobinfo.Digest) } else if err == nil { // Record the uncompressed value so that we can use it to calculate layer IDs. s.blobDiffIDs[blobinfo.Digest] = aLayer.UncompressedDigest() @@ -572,6 +582,61 @@ func (s *storageImageDestination) tryReusingBlobWithSrcRef(ctx context.Context, return s.tryReusingBlobLocked(ctx, blobinfo, cache, canSubstitute) } +type zstdFetcher struct { + stream internalTypes.ImageSourceSeekable + ctx context.Context + blobInfo types.BlobInfo +} + +// GetBlobAt converts from chunked.GetBlobAt to ImageSourceSeekable.GetBlobAt. +func (f *zstdFetcher) GetBlobAt(chunks []chunked.ImageSourceChunk) (chan io.ReadCloser, chan error, error) { + var newChunks []internalTypes.ImageSourceChunk + for _, v := range chunks { + i := internalTypes.ImageSourceChunk{ + Offset: v.Offset, + Length: v.Length, + } + newChunks = append(newChunks, i) + } + rc, errs, err := f.stream.GetBlobAt(f.ctx, f.blobInfo, newChunks) + if _, ok := err.(internalTypes.BadPartialRequestError); ok { + err = chunked.ErrBadRequest{} + } + return rc, errs, err + +} + +// PutBlobPartial attempts to create a blob using the data that is already present at the destination storage. stream is accessed +// in a non-sequential way to retrieve the missing chunks. +func (s *storageImageDestination) PutBlobPartial(ctx context.Context, stream internalTypes.ImageSourceSeekable, srcInfo types.BlobInfo, cache types.BlobInfoCache) (types.BlobInfo, error) { + fetcher := zstdFetcher{ + stream: stream, + ctx: ctx, + blobInfo: srcInfo, + } + + differ, err := chunked.GetDiffer(ctx, s.imageRef.transport.store, srcInfo.Size, srcInfo.Annotations, &fetcher) + if err != nil { + return srcInfo, err + } + + out, err := s.imageRef.transport.store.ApplyDiffWithDiffer("", nil, differ) + if err != nil { + return srcInfo, err + } + + blobDigest := srcInfo.Digest + + s.lock.Lock() + s.blobDiffIDs[blobDigest] = blobDigest + s.fileSizes[blobDigest] = 0 + s.filenames[blobDigest] = "" + s.diffOutputs[blobDigest] = out + s.lock.Unlock() + + return srcInfo, nil +} + // TryReusingBlob checks whether the transport already contains, or can efficiently reuse, a blob, and if so, applies it to the current destination // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. @@ -611,7 +676,7 @@ func (s *storageImageDestination) tryReusingBlobLocked(ctx context.Context, blob // Check if we have a wasn't-compressed layer in storage that's based on that blob. layers, err := s.imageRef.transport.store.LayersByUncompressedDigest(blobinfo.Digest) if err != nil && errors.Cause(err) != storage.ErrLayerUnknown { - return false, types.BlobInfo{}, errors.Wrapf(err, `Error looking for layers with digest %q`, blobinfo.Digest) + return false, types.BlobInfo{}, errors.Wrapf(err, `looking for layers with digest %q`, blobinfo.Digest) } if len(layers) > 0 { // Save this for completeness. @@ -626,7 +691,7 @@ func (s *storageImageDestination) tryReusingBlobLocked(ctx context.Context, blob // Check if we have a was-compressed layer in storage that's based on that blob. layers, err = s.imageRef.transport.store.LayersByCompressedDigest(blobinfo.Digest) if err != nil && errors.Cause(err) != storage.ErrLayerUnknown { - return false, types.BlobInfo{}, errors.Wrapf(err, `Error looking for compressed layers with digest %q`, blobinfo.Digest) + return false, types.BlobInfo{}, errors.Wrapf(err, `looking for compressed layers with digest %q`, blobinfo.Digest) } if len(layers) > 0 { // Record the uncompressed value so that we can use it to calculate layer IDs. @@ -645,7 +710,7 @@ func (s *storageImageDestination) tryReusingBlobLocked(ctx context.Context, blob if uncompressedDigest := cache.UncompressedDigest(blobinfo.Digest); uncompressedDigest != "" && uncompressedDigest != blobinfo.Digest { layers, err := s.imageRef.transport.store.LayersByUncompressedDigest(uncompressedDigest) if err != nil && errors.Cause(err) != storage.ErrLayerUnknown { - return false, types.BlobInfo{}, errors.Wrapf(err, `Error looking for layers with digest %q`, uncompressedDigest) + return false, types.BlobInfo{}, errors.Wrapf(err, `looking for layers with digest %q`, uncompressedDigest) } if len(layers) > 0 { if blobinfo.Size != -1 { @@ -720,7 +785,7 @@ func (s *storageImageDestination) getConfigBlob(info types.BlobInfo) ([]byte, er if filename, ok := s.filenames[info.Digest]; ok { contents, err2 := ioutil.ReadFile(filename) if err2 != nil { - return nil, errors.Wrapf(err2, `error reading blob from file %q`, filename) + return nil, errors.Wrapf(err2, `reading blob from file %q`, filename) } return contents, nil } @@ -822,7 +887,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest // NOTE: use `TryReusingBlob` to prevent recursion. has, _, err := s.TryReusingBlob(ctx, blob.BlobInfo, none.NoCache, false) if err != nil { - return errors.Wrapf(err, "error checking for a layer based on blob %q", blob.Digest.String()) + return errors.Wrapf(err, "checking for a layer based on blob %q", blob.Digest.String()) } if !has { return errors.Errorf("error determining uncompressed digest for blob %q", blob.Digest.String()) @@ -844,6 +909,27 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest } s.lock.Lock() + diffOutput, ok := s.diffOutputs[blob.Digest] + s.lock.Unlock() + if ok { + layer, err := s.imageRef.transport.store.CreateLayer(id, lastLayer, nil, "", false, nil) + if err != nil { + return err + } + + // FIXME: what to do with the uncompressed digest? + diffOutput.UncompressedDigest = blob.Digest + + if err := s.imageRef.transport.store.ApplyDiffFromStagingDirectory(layer.ID, diffOutput.Target, diffOutput, nil); err != nil { + _ = s.imageRef.transport.store.Delete(layer.ID) + return err + } + + s.indexToStorageID[index] = &layer.ID + return nil + } + + s.lock.Lock() al, ok := s.blobAdditionalLayer[blob.Digest] s.lock.Unlock() if ok { @@ -874,7 +960,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest } } if layer == "" { - return errors.Wrapf(err2, "error locating layer for blob %q", blob.Digest) + return errors.Wrapf(err2, "locating layer for blob %q", blob.Digest) } // Read the layer's contents. noCompression := archive.Uncompressed @@ -883,7 +969,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest } diff, err2 := s.imageRef.transport.store.Diff("", layer, diffOptions) if err2 != nil { - return errors.Wrapf(err2, "error reading layer %q for blob %q", layer, blob.Digest) + return errors.Wrapf(err2, "reading layer %q for blob %q", layer, blob.Digest) } // Copy the layer diff to a file. Diff() takes a lock that it holds // until the ReadCloser that it returns is closed, and PutLayer() wants @@ -893,7 +979,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { diff.Close() - return errors.Wrapf(err, "error creating temporary file %q", filename) + return errors.Wrapf(err, "creating temporary file %q", filename) } // Copy the data to the file. // TODO: This can take quite some time, and should ideally be cancellable using @@ -902,7 +988,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest diff.Close() file.Close() if err != nil { - return errors.Wrapf(err, "error storing blob to file %q", filename) + return errors.Wrapf(err, "storing blob to file %q", filename) } // Make sure that we can find this file later, should we need the layer's // contents again. @@ -913,27 +999,34 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest // Read the cached blob and use it as a diff. file, err := os.Open(filename) if err != nil { - return errors.Wrapf(err, "error opening file %q", filename) + return errors.Wrapf(err, "opening file %q", filename) } defer file.Close() // Build the new layer using the diff, regardless of where it came from. // TODO: This can take quite some time, and should ideally be cancellable using ctx.Done(). layer, _, err := s.imageRef.transport.store.PutLayer(id, lastLayer, nil, "", false, nil, file) if err != nil && errors.Cause(err) != storage.ErrDuplicateID { - return errors.Wrapf(err, "error adding layer with blob %q", blob.Digest) + return errors.Wrapf(err, "adding layer with blob %q", blob.Digest) } s.indexToStorageID[index] = &layer.ID return nil } +// Commit marks the process of storing the image as successful and asks for the image to be persisted. +// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list +// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the +// original manifest list digest, if desired. +// WARNING: This does not have any transactional semantics: +// - Uploaded data MAY be visible to others before Commit() is called +// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed) func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel types.UnparsedImage) error { if len(s.manifest) == 0 { return errors.New("Internal error: storageImageDestination.Commit() called without PutManifest()") } toplevelManifest, _, err := unparsedToplevel.Manifest(ctx) if err != nil { - return errors.Wrapf(err, "error retrieving top-level manifest") + return errors.Wrapf(err, "retrieving top-level manifest") } // If the name we're saving to includes a digest, then check that the // manifests that we're about to save all either match the one from the @@ -956,14 +1049,12 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t } } // Find the list of layer blobs. - if len(s.manifest) == 0 { - return errors.New("Internal error: storageImageDestination.Commit() called without PutManifest()") - } man, err := manifest.FromBlob(s.manifest, manifest.GuessMIMEType(s.manifest)) if err != nil { - return errors.Wrapf(err, "error parsing manifest") + return errors.Wrapf(err, "parsing manifest") } layerBlobs := man.LayerInfos() + // Extract, commit, or find the layers. for i, blob := range layerBlobs { if err := s.commitLayer(ctx, blob, i); err != nil { @@ -996,11 +1087,11 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t if err != nil { if errors.Cause(err) != storage.ErrDuplicateID { logrus.Debugf("error creating image: %q", err) - return errors.Wrapf(err, "error creating image %q", intendedID) + return errors.Wrapf(err, "creating image %q", intendedID) } img, err = s.imageRef.transport.store.Image(intendedID) if err != nil { - return errors.Wrapf(err, "error reading image %q", intendedID) + return errors.Wrapf(err, "reading image %q", intendedID) } if img.TopLayer != lastLayer { logrus.Debugf("error creating image: image with ID %q exists, but uses different layers", intendedID) @@ -1011,6 +1102,19 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t } else { logrus.Debugf("created new image ID %q", img.ID) } + + // Clean up the unfinished image on any error. + // (Is this the right thing to do if the image has existed before?) + commitSucceeded := false + defer func() { + if !commitSucceeded { + logrus.Errorf("Updating image %q (old names %v) failed, deleting it", img.ID, oldNames) + if _, err := s.imageRef.transport.store.DeleteImage(img.ID, true); err != nil { + logrus.Errorf("Error deleting incomplete image %q: %v", img.ID, err) + } + } + }() + // Add the non-layer blobs as data items. Since we only share layers, they should all be in files, so // we just need to screen out the ones that are actually layers to get the list of non-layers. dataBlobs := make(map[digest.Digest]struct{}) @@ -1023,90 +1127,62 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t for blob := range dataBlobs { v, err := ioutil.ReadFile(s.filenames[blob]) if err != nil { - return errors.Wrapf(err, "error copying non-layer blob %q to image", blob) + return errors.Wrapf(err, "copying non-layer blob %q to image", blob) } if err := s.imageRef.transport.store.SetImageBigData(img.ID, blob.String(), v, manifest.Digest); err != nil { - if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil { - logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2) - } logrus.Debugf("error saving big data %q for image %q: %v", blob.String(), img.ID, err) - return errors.Wrapf(err, "error saving big data %q for image %q", blob.String(), img.ID) + return errors.Wrapf(err, "saving big data %q for image %q", blob.String(), img.ID) } } - // Save the unparsedToplevel's manifest. - if len(toplevelManifest) != 0 { + // Save the unparsedToplevel's manifest if it differs from the per-platform one, which is saved below. + if len(toplevelManifest) != 0 && !bytes.Equal(toplevelManifest, s.manifest) { manifestDigest, err := manifest.Digest(toplevelManifest) if err != nil { - return errors.Wrapf(err, "error digesting top-level manifest") + return errors.Wrapf(err, "digesting top-level manifest") } key := manifestBigDataKey(manifestDigest) if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, toplevelManifest, manifest.Digest); err != nil { - if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil { - logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2) - } logrus.Debugf("error saving top-level manifest for image %q: %v", img.ID, err) - return errors.Wrapf(err, "error saving top-level manifest for image %q", img.ID) + return errors.Wrapf(err, "saving top-level manifest for image %q", img.ID) } } // Save the image's manifest. Allow looking it up by digest by using the key convention defined by the Store. // Record the manifest twice: using a digest-specific key to allow references to that specific digest instance, // and using storage.ImageDigestBigDataKey for future users that don’t specify any digest and for compatibility with older readers. - manifestDigest, err := manifest.Digest(s.manifest) - if err != nil { - return errors.Wrapf(err, "error computing manifest digest") - } - key := manifestBigDataKey(manifestDigest) + key := manifestBigDataKey(s.manifestDigest) if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, s.manifest, manifest.Digest); err != nil { - if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil { - logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2) - } logrus.Debugf("error saving manifest for image %q: %v", img.ID, err) - return errors.Wrapf(err, "error saving manifest for image %q", img.ID) + return errors.Wrapf(err, "saving manifest for image %q", img.ID) } key = storage.ImageDigestBigDataKey if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, s.manifest, manifest.Digest); err != nil { - if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil { - logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2) - } logrus.Debugf("error saving manifest for image %q: %v", img.ID, err) - return errors.Wrapf(err, "error saving manifest for image %q", img.ID) + return errors.Wrapf(err, "saving manifest for image %q", img.ID) } // Save the signatures, if we have any. if len(s.signatures) > 0 { if err := s.imageRef.transport.store.SetImageBigData(img.ID, "signatures", s.signatures, manifest.Digest); err != nil { - if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil { - logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2) - } logrus.Debugf("error saving signatures for image %q: %v", img.ID, err) - return errors.Wrapf(err, "error saving signatures for image %q", img.ID) + return errors.Wrapf(err, "saving signatures for image %q", img.ID) } } for instanceDigest, signatures := range s.signatureses { key := signatureBigDataKey(instanceDigest) if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, signatures, manifest.Digest); err != nil { - if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil { - logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2) - } logrus.Debugf("error saving signatures for image %q: %v", img.ID, err) - return errors.Wrapf(err, "error saving signatures for image %q", img.ID) + return errors.Wrapf(err, "saving signatures for image %q", img.ID) } } // Save our metadata. metadata, err := json.Marshal(s) if err != nil { - if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil { - logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2) - } logrus.Debugf("error encoding metadata for image %q: %v", img.ID, err) - return errors.Wrapf(err, "error encoding metadata for image %q", img.ID) + return errors.Wrapf(err, "encoding metadata for image %q", img.ID) } if len(metadata) != 0 { if err = s.imageRef.transport.store.SetMetadata(img.ID, string(metadata)); err != nil { - if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil { - logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2) - } logrus.Debugf("error saving metadata for image %q: %v", img.ID, err) - return errors.Wrapf(err, "error saving metadata for image %q", img.ID) + return errors.Wrapf(err, "saving metadata for image %q", img.ID) } logrus.Debugf("saved image metadata %q", string(metadata)) } @@ -1121,14 +1197,13 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t names = append(names, oldNames...) } if err := s.imageRef.transport.store.SetNames(img.ID, names); err != nil { - if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil { - logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2) - } logrus.Debugf("error setting names %v on image %q: %v", names, img.ID, err) - return errors.Wrapf(err, "error setting names %v on image %q", names, img.ID) + return errors.Wrapf(err, "setting names %v on image %q", names, img.ID) } logrus.Debugf("set names of image %q to %v", img.ID, names) } + + commitSucceeded = true return nil } @@ -1145,9 +1220,14 @@ func (s *storageImageDestination) SupportedManifestMIMETypes() []string { // PutManifest writes the manifest to the destination. func (s *storageImageDestination) PutManifest(ctx context.Context, manifestBlob []byte, instanceDigest *digest.Digest) error { + digest, err := manifest.Digest(manifestBlob) + if err != nil { + return err + } newBlob := make([]byte, len(manifestBlob)) copy(newBlob, manifestBlob) s.manifest = newBlob + s.manifestDigest = digest return nil } @@ -1189,13 +1269,10 @@ func (s *storageImageDestination) PutSignatures(ctx context.Context, signatures if instanceDigest == nil { s.signatures = sigblob s.SignatureSizes = sizes - } - if instanceDigest == nil && len(s.manifest) > 0 { - manifestDigest, err := manifest.Digest(s.manifest) - if err != nil { - return err + if len(s.manifest) > 0 { + manifestDigest := s.manifestDigest + instanceDigest = &manifestDigest } - instanceDigest = &manifestDigest } if instanceDigest != nil { s.signatureses[*instanceDigest] = sigblob @@ -1211,12 +1288,12 @@ func (s *storageImageSource) getSize() (int64, error) { // Size up the data blobs. dataNames, err := s.imageRef.transport.store.ListImageBigData(s.image.ID) if err != nil { - return -1, errors.Wrapf(err, "error reading image %q", s.image.ID) + return -1, errors.Wrapf(err, "reading image %q", s.image.ID) } for _, dataName := range dataNames { bigSize, err := s.imageRef.transport.store.ImageBigDataSize(s.image.ID, dataName) if err != nil { - return -1, errors.Wrapf(err, "error reading data blob size %q for %q", dataName, s.image.ID) + return -1, errors.Wrapf(err, "reading data blob size %q for %q", dataName, s.image.ID) } sum += bigSize } diff --git a/vendor/github.com/containers/image/v5/storage/storage_reference.go b/vendor/github.com/containers/image/v5/storage/storage_reference.go index 394557f39..1aafe9068 100644 --- a/vendor/github.com/containers/image/v5/storage/storage_reference.go +++ b/vendor/github.com/containers/image/v5/storage/storage_reference.go @@ -11,7 +11,6 @@ import ( "github.com/containers/image/v5/types" "github.com/containers/storage" digest "github.com/opencontainers/go-digest" - imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -62,18 +61,17 @@ func imageMatchesRepo(image *storage.Image, ref reference.Named) bool { return false } -// imageMatchesSystemContext checks if the passed-in image both contains a -// manifest that matches the passed-in digest, and identifies itself as being -// appropriate for running on the system that matches sys. -// If we somehow ended up sharing the same storage among multiple types of -// systems, and managed to download multiple images from the same manifest -// list, their image records will all contain copies of the manifest list, and -// this check will help us decide which of them we want to return when we've -// been asked to resolve an image reference that uses the list's digest to a -// specific image ID. -func imageMatchesSystemContext(store storage.Store, img *storage.Image, manifestDigest digest.Digest, sys *types.SystemContext) bool { - // First, check if the image record has a manifest that matches the - // specified digest. +// multiArchImageMatchesSystemContext returns true if if the passed-in image both contains a +// multi-arch manifest that matches the passed-in digest, and the image is the per-platform +// image instance that matches sys. +// +// See the comment in storageReference.ResolveImage explaining why +// this check is necessary. +func multiArchImageMatchesSystemContext(store storage.Store, img *storage.Image, manifestDigest digest.Digest, sys *types.SystemContext) bool { + // Load the manifest that matches the specified digest. + // We don't need to care about storage.ImageDigestBigDataKey because + // manifests lists are only stored into storage by c/image versions + // that know about manifestBigDataKey, and only using that key. key := manifestBigDataKey(manifestDigest) manifestBytes, err := store.ImageBigData(img.ID, key) if err != nil { @@ -83,56 +81,22 @@ func imageMatchesSystemContext(store storage.Store, img *storage.Image, manifest // the digest of the instance that matches the current system, and try // to load that manifest from the image record, and use it. manifestType := manifest.GuessMIMEType(manifestBytes) - if manifest.MIMETypeIsMultiImage(manifestType) { - list, err := manifest.ListFromBlob(manifestBytes, manifestType) - if err != nil { - return false - } - manifestDigest, err = list.ChooseInstance(sys) - if err != nil { - return false - } - key = manifestBigDataKey(manifestDigest) - manifestBytes, err = store.ImageBigData(img.ID, key) - if err != nil { - return false - } - manifestType = manifest.GuessMIMEType(manifestBytes) - } - // Load the image's configuration blob. - m, err := manifest.FromBlob(manifestBytes, manifestType) - if err != nil { + if !manifest.MIMETypeIsMultiImage(manifestType) { + // manifestDigest directly specifies a per-platform image, so we aren't + // choosing among different variants. return false } - getConfig := func(blobInfo types.BlobInfo) ([]byte, error) { - return store.ImageBigData(img.ID, blobInfo.Digest.String()) - } - ii, err := m.Inspect(getConfig) + list, err := manifest.ListFromBlob(manifestBytes, manifestType) if err != nil { return false } - // Build a dummy index containing one instance and information about - // the image's target system from the image's configuration. - index := manifest.OCI1IndexFromComponents([]imgspecv1.Descriptor{{ - MediaType: imgspecv1.MediaTypeImageManifest, - Digest: manifestDigest, - Size: int64(len(manifestBytes)), - Platform: &imgspecv1.Platform{ - OS: ii.Os, - Architecture: ii.Architecture, - }, - }}, nil) - // Check that ChooseInstance() would select this image for this system, - // from a list of images. - instanceDigest, err := index.ChooseInstance(sys) + chosenInstance, err := list.ChooseInstance(sys) if err != nil { return false } - // Double-check that we can read the runnable image's manifest from the - // image record. - key = manifestBigDataKey(instanceDigest) + key = manifestBigDataKey(chosenInstance) _, err = store.ImageBigData(img.ID, key) - return err == nil + return err == nil // true if img.ID is based on chosenInstance. } // Resolve the reference's name to an image ID in the store, if there's already @@ -152,11 +116,24 @@ func (s *storageReference) resolveImage(sys *types.SystemContext) (*storage.Imag // Look for an image with the specified digest that has the same name, // though possibly with a different tag or digest, as a Name value, so // that the canonical reference can be implicitly resolved to the image. + // + // Typically there should be at most one such image, because the same + // manifest digest implies the same config, and we choose the storage ID + // based on the config (deduplicating images), except: + // - the user can explicitly specify an ID when creating the image. + // In this case we don't have a preference among the alternatives. + // - when pulling an image from a multi-platform manifest list, we also + // store the manifest list in the image; this allows referencing a + // per-platform image using the manifest list digest, but that also + // means that we can have multiple genuinely different images in the + // storage matching the same manifest list digest (if pulled using different + // SystemContext.{OS,Architecture,Variant}Choice to the same storage). + // In this case we prefer the image matching the current SystemContext. images, err := s.transport.store.ImagesByDigest(digested.Digest()) if err == nil && len(images) > 0 { for _, image := range images { if imageMatchesRepo(image, s.named) { - if loadedImage == nil || imageMatchesSystemContext(s.transport.store, image, digested.Digest(), sys) { + if loadedImage == nil || multiArchImageMatchesSystemContext(s.transport.store, image, digested.Digest(), sys) { loadedImage = image s.id = image.ID } @@ -172,7 +149,7 @@ func (s *storageReference) resolveImage(sys *types.SystemContext) (*storage.Imag if loadedImage == nil { img, err := s.transport.store.Image(s.id) if err != nil { - return nil, errors.Wrapf(err, "error reading image %q", s.id) + return nil, errors.Wrapf(err, "reading image %q", s.id) } loadedImage = img } diff --git a/vendor/github.com/containers/image/v5/storage/storage_transport.go b/vendor/github.com/containers/image/v5/storage/storage_transport.go index c024bee9b..d4c85b725 100644 --- a/vendor/github.com/containers/image/v5/storage/storage_transport.go +++ b/vendor/github.com/containers/image/v5/storage/storage_transport.go @@ -172,7 +172,7 @@ func (s storageTransport) ParseStoreReference(store storage.Store, ref string) ( var err error named, err = reference.ParseNormalizedNamed(ref) if err != nil { - return nil, errors.Wrapf(err, "error parsing named reference %q", ref) + return nil, errors.Wrapf(err, "parsing named reference %q", ref) } named = reference.TagNameOnly(named) } @@ -303,7 +303,7 @@ func (s storageTransport) GetStoreImage(store storage.Store, ref types.ImageRefe } if sref, ok := ref.(*storageReference); ok { tmpRef := *sref - if img, err := tmpRef.resolveImage(&types.SystemContext{}); err == nil { + if img, err := tmpRef.resolveImage(nil); err == nil { return img, nil } } diff --git a/vendor/github.com/containers/image/v5/types/types.go b/vendor/github.com/containers/image/v5/types/types.go index 3e7abd34d..48efa195b 100644 --- a/vendor/github.com/containers/image/v5/types/types.go +++ b/vendor/github.com/containers/image/v5/types/types.go @@ -334,6 +334,9 @@ type ImageDestination interface { // MUST be called after PutManifest (signatures may reference manifest contents). PutSignatures(ctx context.Context, signatures [][]byte, instanceDigest *digest.Digest) error // Commit marks the process of storing the image as successful and asks for the image to be persisted. + // unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list + // if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the + // original manifest list digest, if desired. // WARNING: This does not have any transactional semantics: // - Uploaded data MAY be visible to others before Commit() is called // - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed) @@ -595,12 +598,12 @@ type SystemContext struct { // === docker.Transport overrides === // If not "", a directory containing a CA certificate (ending with ".crt"), // a client certificate (ending with ".cert") and a client certificate key - // (ending with ".key") used when talking to a Docker Registry. + // (ending with ".key") used when talking to a container registry. DockerCertPath string // If not "", overrides the system’s default path for a directory containing host[:port] subdirectories with the same structure as DockerCertPath above. // Ignored if DockerCertPath is non-empty. DockerPerHostCertDirPath string - // Allow contacting docker registries over HTTP, or HTTPS with failed TLS verification. Note that this does not affect other TLS connections. + // Allow contacting container registries over HTTP, or HTTPS with failed TLS verification. Note that this does not affect other TLS connections. DockerInsecureSkipTLSVerify OptionalBool // if nil, the library tries to parse ~/.docker/config.json to retrieve credentials // Ignored if DockerBearerRegistryToken is non-empty. diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go index edf4681de..0a1971535 100644 --- a/vendor/github.com/containers/image/v5/version/version.go +++ b/vendor/github.com/containers/image/v5/version/version.go @@ -6,9 +6,9 @@ const ( // VersionMajor is for an API incompatible changes VersionMajor = 5 // VersionMinor is for functionality in a backwards-compatible manner - VersionMinor = 13 + VersionMinor = 14 // VersionPatch is for backwards-compatible bug fixes - VersionPatch = 2 + VersionPatch = 0 // VersionDev indicates development branch. Releases will be empty string. VersionDev = "" diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION index 949ff3202..7aa332e41 100644 --- a/vendor/github.com/containers/storage/VERSION +++ b/vendor/github.com/containers/storage/VERSION @@ -1 +1 @@ -1.32.5 +1.33.0 diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go index 2fa54a207..ecfbae916 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go +++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go @@ -364,12 +364,12 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error) // Try to enable project quota support over xfs. if d.quotaCtl, err = quota.NewControl(home); err == nil { projectQuotaSupported = true - } else if opts.quota.Size > 0 { - return nil, fmt.Errorf("Storage option overlay.size not supported. Filesystem does not support Project Quota: %v", err) + } else if opts.quota.Size > 0 || opts.quota.Inodes > 0 { + return nil, fmt.Errorf("Storage options overlay.size and overlay.inodes not supported. Filesystem does not support Project Quota: %v", err) } - } else if opts.quota.Size > 0 { + } else if opts.quota.Size > 0 || opts.quota.Inodes > 0 { // if xfs is not the backing fs then error out if the storage-opt overlay.size is used. - return nil, fmt.Errorf("Storage option overlay.size only supported for backingFS XFS. Found %v", backingFs) + return nil, fmt.Errorf("Storage option overlay.size and overlay.inodes only supported for backingFS XFS. Found %v", backingFs) } logrus.Debugf("backingFs=%s, projectQuotaSupported=%v, useNativeDiff=%v, usingMetacopy=%v", backingFs, projectQuotaSupported, !d.useNaiveDiff(), d.usingMetacopy) @@ -400,6 +400,13 @@ func parseOptions(options []string) (*overlayOptions, error) { return nil, err } o.quota.Size = uint64(size) + case "inodes": + logrus.Debugf("overlay: inodes=%s", val) + inodes, err := strconv.ParseUint(val, 10, 64) + if err != nil { + return nil, err + } + o.quota.Inodes = uint64(inodes) case "imagestore", "additionalimagestore": logrus.Debugf("overlay: imagestore=%s", val) // Additional read only image stores to use for lower paths @@ -613,6 +620,10 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI if unshare.IsRootless() { flags = fmt.Sprintf("%s,userxattr", flags) } + if err := syscall.Mknod(filepath.Join(upperDir, "whiteout"), syscall.S_IFCHR|0600, int(unix.Mkdev(0, 0))); err != nil { + logrus.Debugf("unable to create kernel-style whiteout: %v", err) + return supportsDType, errors.Wrapf(err, "unable to create kernel-style whiteout") + } if len(flags) < unix.Getpagesize() { err := unix.Mount("overlay", mergedDir, "overlay", 0, flags) @@ -784,6 +795,13 @@ func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts opts.StorageOpt["size"] = strconv.FormatUint(d.options.quota.Size, 10) } + if _, ok := opts.StorageOpt["inodes"]; !ok { + if opts.StorageOpt == nil { + opts.StorageOpt = map[string]string{} + } + opts.StorageOpt["inodes"] = strconv.FormatUint(d.options.quota.Inodes, 10) + } + return d.create(id, parent, opts) } @@ -794,6 +812,9 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr if _, ok := opts.StorageOpt["size"]; ok { return fmt.Errorf("--storage-opt size is only supported for ReadWrite Layers") } + if _, ok := opts.StorageOpt["inodes"]; ok { + return fmt.Errorf("--storage-opt inodes is only supported for ReadWrite Layers") + } } return d.create(id, parent, opts) @@ -850,7 +871,9 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr if driver.options.quota.Size > 0 { quota.Size = driver.options.quota.Size } - + if driver.options.quota.Inodes > 0 { + quota.Inodes = driver.options.quota.Inodes + } } // Set container disk quota limit // If it is set to 0, we will track the disk usage, but not enforce a limit @@ -922,6 +945,12 @@ func (d *Driver) parseStorageOpt(storageOpt map[string]string, driver *Driver) e return err } driver.options.quota.Size = uint64(size) + case "inodes": + inodes, err := strconv.ParseUint(val, 10, 64) + if err != nil { + return err + } + driver.options.quota.Inodes = uint64(inodes) default: return fmt.Errorf("Unknown option %s", key) } diff --git a/vendor/github.com/containers/storage/drivers/quota/projectquota.go b/vendor/github.com/containers/storage/drivers/quota/projectquota.go index d805623b5..a435f6b82 100644 --- a/vendor/github.com/containers/storage/drivers/quota/projectquota.go +++ b/vendor/github.com/containers/storage/drivers/quota/projectquota.go @@ -38,8 +38,8 @@ struct fsxattr { #ifndef PRJQUOTA #define PRJQUOTA 2 #endif -#ifndef XFS_PROJ_QUOTA -#define XFS_PROJ_QUOTA 2 +#ifndef FS_PROJ_QUOTA +#define FS_PROJ_QUOTA 2 #endif #ifndef Q_XSETPQLIM #define Q_XSETPQLIM QCMD(Q_XSETQLIM, PRJQUOTA) @@ -61,9 +61,10 @@ import ( "golang.org/x/sys/unix" ) -// Quota limit params - currently we only control blocks hard limit +// Quota limit params - currently we only control blocks hard limit and inodes type Quota struct { - Size uint64 + Size uint64 + Inodes uint64 } // Control - Context to be used by storage driver (e.g. overlay) @@ -119,7 +120,8 @@ func NewControl(basePath string) (*Control, error) { // a quota on the first available project id // quota := Quota{ - Size: 0, + Size: 0, + Inodes: 0, } if err := setProjectQuota(backingFsBlockDev, minProjectID, quota); err != nil { return nil, err @@ -166,7 +168,7 @@ func (q *Control) SetQuota(targetPath string, quota Quota) error { // // set the quota limit for the container's project id // - logrus.Debugf("SetQuota(%s, %d): projectID=%d", targetPath, quota.Size, projectID) + logrus.Debugf("SetQuota path=%s, size=%d, inodes=%d, projectID=%d", targetPath, quota.Size, quota.Inodes, projectID) return setProjectQuota(q.backingFsBlockDev, projectID, quota) } @@ -175,11 +177,18 @@ func setProjectQuota(backingFsBlockDev string, projectID uint32, quota Quota) er var d C.fs_disk_quota_t d.d_version = C.FS_DQUOT_VERSION d.d_id = C.__u32(projectID) - d.d_flags = C.XFS_PROJ_QUOTA + d.d_flags = C.FS_PROJ_QUOTA - d.d_fieldmask = C.FS_DQ_BHARD | C.FS_DQ_BSOFT - d.d_blk_hardlimit = C.__u64(quota.Size / 512) - d.d_blk_softlimit = d.d_blk_hardlimit + if quota.Size > 0 { + d.d_fieldmask = C.FS_DQ_BHARD | C.FS_DQ_BSOFT + d.d_blk_hardlimit = C.__u64(quota.Size / 512) + d.d_blk_softlimit = d.d_blk_hardlimit + } + if quota.Inodes > 0 { + d.d_fieldmask = C.FS_DQ_IHARD | C.FS_DQ_ISOFT + d.d_ino_hardlimit = C.__u64(quota.Inodes) + d.d_ino_softlimit = d.d_ino_hardlimit + } var cs = C.CString(backingFsBlockDev) defer C.free(unsafe.Pointer(cs)) @@ -202,6 +211,7 @@ func (q *Control) GetQuota(targetPath string, quota *Quota) error { return err } quota.Size = uint64(d.d_blk_hardlimit) * 512 + quota.Inodes = uint64(d.d_ino_hardlimit) return nil } diff --git a/vendor/github.com/containers/storage/drivers/quota/projectquota_unsupported.go b/vendor/github.com/containers/storage/drivers/quota/projectquota_unsupported.go index be6c75a58..7469138db 100644 --- a/vendor/github.com/containers/storage/drivers/quota/projectquota_unsupported.go +++ b/vendor/github.com/containers/storage/drivers/quota/projectquota_unsupported.go @@ -8,7 +8,8 @@ import ( // Quota limit params - currently we only control blocks hard limit type Quota struct { - Size uint64 + Size uint64 + Inodes uint64 } // Control - Context to be used by storage driver (e.g. overlay) diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod index 93b6b337c..e4f484d6b 100644 --- a/vendor/github.com/containers/storage/go.mod +++ b/vendor/github.com/containers/storage/go.mod @@ -5,7 +5,7 @@ module github.com/containers/storage require ( github.com/BurntSushi/toml v0.3.1 github.com/Microsoft/go-winio v0.5.0 - github.com/Microsoft/hcsshim v0.8.17 + github.com/Microsoft/hcsshim v0.8.20 github.com/docker/go-units v0.4.0 github.com/google/go-intervals v0.0.2 github.com/hashicorp/go-multierror v1.1.1 @@ -16,7 +16,7 @@ require ( github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible github.com/moby/sys/mountinfo v0.4.1 github.com/opencontainers/go-digest v1.0.0 - github.com/opencontainers/runc v1.0.0 + github.com/opencontainers/runc v1.0.1 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 github.com/opencontainers/selinux v1.8.2 github.com/pkg/errors v0.9.1 diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum index e826328ef..2607dbc9b 100644 --- a/vendor/github.com/containers/storage/go.sum +++ b/vendor/github.com/containers/storage/go.sum @@ -54,8 +54,8 @@ github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg3 github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= -github.com/Microsoft/hcsshim v0.8.17 h1:yFHH5bghP9ij5Y34PPaMOE8g//oXZ0uJQeMENVo2zcI= -github.com/Microsoft/hcsshim v0.8.17/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= +github.com/Microsoft/hcsshim v0.8.20 h1:ZTwcx3NS8n07kPf/JZ1qwU6vnjhVPMUWlXBF8r9UxrE= +github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -99,7 +99,7 @@ github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmE github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= -github.com/cilium/ebpf v0.6.1/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -468,8 +468,8 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= -github.com/opencontainers/runc v1.0.0 h1:QOhAQAYUlKeofuyeKdR6ITvOnXLPbEAjPMjz9wCUXcU= -github.com/opencontainers/runc v1.0.0/go.mod h1:MU2S3KEB2ZExnhnAQYbwjdYV6HwKtDlNbA2Z2OeNDeA= +github.com/opencontainers/runc v1.0.1 h1:G18PGckGdAm3yVQRWDVQ1rLSLntiniKJ0cNRT2Tm5gs= +github.com/opencontainers/runc v1.0.1/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go index 50e3e3555..48e846f7c 100644 --- a/vendor/github.com/containers/storage/pkg/archive/archive.go +++ b/vendor/github.com/containers/storage/pkg/archive/archive.go @@ -645,10 +645,13 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L } file.Close() - case tar.TypeBlock, tar.TypeChar, tar.TypeFifo: + case tar.TypeBlock, tar.TypeChar: if inUserns { // cannot create devices in a userns + logrus.Debugf("Tar: Can't create device %v while running in user namespace", path) return nil } + fallthrough + case tar.TypeFifo: // Handle this is an OS-specific way if err := handleTarTypeBlockCharFifo(hdr, path); err != nil { return err diff --git a/vendor/github.com/containers/storage/pkg/archive/archive_unix.go b/vendor/github.com/containers/storage/pkg/archive/archive_unix.go index e257737e7..7c3e442da 100644 --- a/vendor/github.com/containers/storage/pkg/archive/archive_unix.go +++ b/vendor/github.com/containers/storage/pkg/archive/archive_unix.go @@ -11,7 +11,6 @@ import ( "github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/system" - "github.com/opencontainers/runc/libcontainer/userns" "golang.org/x/sys/unix" ) @@ -88,11 +87,6 @@ func minor(device uint64) uint64 { // handleTarTypeBlockCharFifo is an OS-specific helper function used by // createTarFile to handle the following types of header: Block; Char; Fifo func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error { - if userns.RunningInUserNS() { - // cannot create a device if running in user namespace - return nil - } - mode := uint32(hdr.Mode & 07777) switch hdr.Typeflag { case tar.TypeBlock: diff --git a/vendor/github.com/containers/storage/pkg/chunked/compression.go b/vendor/github.com/containers/storage/pkg/chunked/compression.go new file mode 100644 index 000000000..f2811fb9a --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/chunked/compression.go @@ -0,0 +1,169 @@ +package chunked + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + + "github.com/containers/storage/pkg/chunked/compressor" + "github.com/containers/storage/pkg/chunked/internal" + "github.com/klauspost/compress/zstd" + digest "github.com/opencontainers/go-digest" + "github.com/pkg/errors" + "github.com/vbatts/tar-split/archive/tar" +) + +const ( + TypeReg = internal.TypeReg + TypeChunk = internal.TypeChunk + TypeLink = internal.TypeLink + TypeChar = internal.TypeChar + TypeBlock = internal.TypeBlock + TypeDir = internal.TypeDir + TypeFifo = internal.TypeFifo + TypeSymlink = internal.TypeSymlink +) + +var typesToTar = map[string]byte{ + TypeReg: tar.TypeReg, + TypeLink: tar.TypeLink, + TypeChar: tar.TypeChar, + TypeBlock: tar.TypeBlock, + TypeDir: tar.TypeDir, + TypeFifo: tar.TypeFifo, + TypeSymlink: tar.TypeSymlink, +} + +func typeToTarType(t string) (byte, error) { + r, found := typesToTar[t] + if !found { + return 0, fmt.Errorf("unknown type: %v", t) + } + return r, nil +} + +func isZstdChunkedFrameMagic(data []byte) bool { + if len(data) < 8 { + return false + } + return bytes.Equal(internal.ZstdChunkedFrameMagic, data[:8]) +} + +// readZstdChunkedManifest reads the zstd:chunked manifest from the seekable stream blobStream. The blob total size must +// be specified. +// This function uses the io.containers.zstd-chunked. annotations when specified. +func readZstdChunkedManifest(blobStream ImageSourceSeekable, blobSize int64, annotations map[string]string) ([]byte, error) { + footerSize := int64(internal.FooterSizeSupported) + if blobSize <= footerSize { + return nil, errors.New("blob too small") + } + + manifestChecksumAnnotation := annotations[internal.ManifestChecksumKey] + if manifestChecksumAnnotation == "" { + return nil, fmt.Errorf("manifest checksum annotation %q not found", internal.ManifestChecksumKey) + } + + var offset, length, lengthUncompressed, manifestType uint64 + + if offsetMetadata := annotations[internal.ManifestInfoKey]; offsetMetadata != "" { + if _, err := fmt.Sscanf(offsetMetadata, "%d:%d:%d:%d", &offset, &length, &lengthUncompressed, &manifestType); err != nil { + return nil, err + } + } else { + chunk := ImageSourceChunk{ + Offset: uint64(blobSize - footerSize), + Length: uint64(footerSize), + } + parts, errs, err := blobStream.GetBlobAt([]ImageSourceChunk{chunk}) + if err != nil { + return nil, err + } + var reader io.ReadCloser + select { + case r := <-parts: + reader = r + case err := <-errs: + return nil, err + } + footer := make([]byte, footerSize) + if _, err := io.ReadFull(reader, footer); err != nil { + return nil, err + } + + offset = binary.LittleEndian.Uint64(footer[0:8]) + length = binary.LittleEndian.Uint64(footer[8:16]) + lengthUncompressed = binary.LittleEndian.Uint64(footer[16:24]) + manifestType = binary.LittleEndian.Uint64(footer[24:32]) + if !isZstdChunkedFrameMagic(footer[32:40]) { + return nil, errors.New("invalid magic number") + } + } + + if manifestType != internal.ManifestTypeCRFS { + return nil, errors.New("invalid manifest type") + } + + // set a reasonable limit + if length > (1<<20)*50 { + return nil, errors.New("manifest too big") + } + if lengthUncompressed > (1<<20)*50 { + return nil, errors.New("manifest too big") + } + + chunk := ImageSourceChunk{ + Offset: offset, + Length: length, + } + + parts, errs, err := blobStream.GetBlobAt([]ImageSourceChunk{chunk}) + if err != nil { + return nil, err + } + var reader io.ReadCloser + select { + case r := <-parts: + reader = r + case err := <-errs: + return nil, err + } + + manifest := make([]byte, length) + if _, err := io.ReadFull(reader, manifest); err != nil { + return nil, err + } + + manifestDigester := digest.Canonical.Digester() + manifestChecksum := manifestDigester.Hash() + if _, err := manifestChecksum.Write(manifest); err != nil { + return nil, err + } + + d, err := digest.Parse(manifestChecksumAnnotation) + if err != nil { + return nil, err + } + if manifestDigester.Digest() != d { + return nil, errors.New("invalid manifest checksum") + } + + decoder, err := zstd.NewReader(nil) + if err != nil { + return nil, err + } + defer decoder.Close() + + b := make([]byte, 0, lengthUncompressed) + if decoded, err := decoder.DecodeAll(manifest, b); err == nil { + return decoded, nil + } + + return manifest, nil +} + +// ZstdCompressor is a CompressorFunc for the zstd compression algorithm. +// Deprecated: Use pkg/chunked/compressor.ZstdCompressor. +func ZstdCompressor(r io.Writer, metadata map[string]string, level *int) (io.WriteCloser, error) { + return compressor.ZstdCompressor(r, metadata, level) +} diff --git a/vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go b/vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go new file mode 100644 index 000000000..a205b73fd --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go @@ -0,0 +1,220 @@ +package compressor + +// NOTE: This is used from github.com/containers/image by callers that +// don't otherwise use containers/storage, so don't make this depend on any +// larger software like the graph drivers. + +import ( + "encoding/base64" + "io" + "io/ioutil" + + "github.com/containers/storage/pkg/chunked/internal" + "github.com/containers/storage/pkg/ioutils" + "github.com/opencontainers/go-digest" + "github.com/vbatts/tar-split/archive/tar" +) + +func writeZstdChunkedStream(destFile io.Writer, outMetadata map[string]string, reader io.Reader, level int) error { + // total written so far. Used to retrieve partial offsets in the file + dest := ioutils.NewWriteCounter(destFile) + + tr := tar.NewReader(reader) + tr.RawAccounting = true + + buf := make([]byte, 4096) + + zstdWriter, err := internal.ZstdWriterWithLevel(dest, level) + if err != nil { + return err + } + defer func() { + if zstdWriter != nil { + zstdWriter.Close() + zstdWriter.Flush() + } + }() + + restartCompression := func() (int64, error) { + var offset int64 + if zstdWriter != nil { + if err := zstdWriter.Close(); err != nil { + return 0, err + } + if err := zstdWriter.Flush(); err != nil { + return 0, err + } + offset = dest.Count + zstdWriter.Reset(dest) + } + return offset, nil + } + + var metadata []internal.ZstdFileMetadata + for { + hdr, err := tr.Next() + if err != nil { + if err == io.EOF { + break + } + return err + } + + rawBytes := tr.RawBytes() + if _, err := zstdWriter.Write(rawBytes); err != nil { + return err + } + payloadDigester := digest.Canonical.Digester() + payloadChecksum := payloadDigester.Hash() + + payloadDest := io.MultiWriter(payloadChecksum, zstdWriter) + + // Now handle the payload, if any + var startOffset, endOffset int64 + checksum := "" + for { + read, errRead := tr.Read(buf) + if errRead != nil && errRead != io.EOF { + return err + } + + // restart the compression only if there is + // a payload. + if read > 0 { + if startOffset == 0 { + startOffset, err = restartCompression() + if err != nil { + return err + } + } + _, err := payloadDest.Write(buf[:read]) + if err != nil { + return err + } + } + if errRead == io.EOF { + if startOffset > 0 { + endOffset, err = restartCompression() + if err != nil { + return err + } + checksum = payloadDigester.Digest().String() + } + break + } + } + + typ, err := internal.GetType(hdr.Typeflag) + if err != nil { + return err + } + xattrs := make(map[string]string) + for k, v := range hdr.Xattrs { + xattrs[k] = base64.StdEncoding.EncodeToString([]byte(v)) + } + m := internal.ZstdFileMetadata{ + Type: typ, + Name: hdr.Name, + Linkname: hdr.Linkname, + Mode: hdr.Mode, + Size: hdr.Size, + UID: hdr.Uid, + GID: hdr.Gid, + ModTime: hdr.ModTime, + AccessTime: hdr.AccessTime, + ChangeTime: hdr.ChangeTime, + Devmajor: hdr.Devmajor, + Devminor: hdr.Devminor, + Xattrs: xattrs, + Digest: checksum, + Offset: startOffset, + EndOffset: endOffset, + + // ChunkSize is 0 for the last chunk + ChunkSize: 0, + ChunkOffset: 0, + ChunkDigest: checksum, + } + metadata = append(metadata, m) + } + + rawBytes := tr.RawBytes() + if _, err := zstdWriter.Write(rawBytes); err != nil { + return err + } + if err := zstdWriter.Flush(); err != nil { + return err + } + if err := zstdWriter.Close(); err != nil { + return err + } + zstdWriter = nil + + return internal.WriteZstdChunkedManifest(dest, outMetadata, uint64(dest.Count), metadata, level) +} + +type zstdChunkedWriter struct { + tarSplitOut *io.PipeWriter + tarSplitErr chan error +} + +func (w zstdChunkedWriter) Close() error { + err := <-w.tarSplitErr + if err != nil { + w.tarSplitOut.Close() + return err + } + return w.tarSplitOut.Close() +} + +func (w zstdChunkedWriter) Write(p []byte) (int, error) { + select { + case err := <-w.tarSplitErr: + w.tarSplitOut.Close() + return 0, err + default: + return w.tarSplitOut.Write(p) + } +} + +// zstdChunkedWriterWithLevel writes a zstd compressed tarball where each file is +// compressed separately so it can be addressed separately. Idea based on CRFS: +// https://github.com/google/crfs +// The difference with CRFS is that the zstd compression is used instead of gzip. +// The reason for it is that zstd supports embedding metadata ignored by the decoder +// as part of the compressed stream. +// A manifest json file with all the metadata is appended at the end of the tarball +// stream, using zstd skippable frames. +// The final file will look like: +// [FILE_1][FILE_2]..[FILE_N][SKIPPABLE FRAME 1][SKIPPABLE FRAME 2] +// Where: +// [FILE_N]: [ZSTD HEADER][TAR HEADER][PAYLOAD FILE_N][ZSTD FOOTER] +// [SKIPPABLE FRAME 1]: [ZSTD SKIPPABLE FRAME, SIZE=MANIFEST LENGTH][MANIFEST] +// [SKIPPABLE FRAME 2]: [ZSTD SKIPPABLE FRAME, SIZE=16][MANIFEST_OFFSET][MANIFEST_LENGTH][MANIFEST_LENGTH_UNCOMPRESSED][MANIFEST_TYPE][CHUNKED_ZSTD_MAGIC_NUMBER] +// MANIFEST_OFFSET, MANIFEST_LENGTH, MANIFEST_LENGTH_UNCOMPRESSED and CHUNKED_ZSTD_MAGIC_NUMBER are 64 bits unsigned in little endian format. +func zstdChunkedWriterWithLevel(out io.Writer, metadata map[string]string, level int) (io.WriteCloser, error) { + ch := make(chan error, 1) + r, w := io.Pipe() + + go func() { + ch <- writeZstdChunkedStream(out, metadata, r, level) + io.Copy(ioutil.Discard, r) + r.Close() + close(ch) + }() + + return zstdChunkedWriter{ + tarSplitOut: w, + tarSplitErr: ch, + }, nil +} + +// ZstdCompressor is a CompressorFunc for the zstd compression algorithm. +func ZstdCompressor(r io.Writer, metadata map[string]string, level *int) (io.WriteCloser, error) { + if level == nil { + l := 3 + level = &l + } + + return zstdChunkedWriterWithLevel(r, metadata, *level) +} diff --git a/vendor/github.com/containers/storage/pkg/chunked/internal/compression.go b/vendor/github.com/containers/storage/pkg/chunked/internal/compression.go new file mode 100644 index 000000000..af0025c20 --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/chunked/internal/compression.go @@ -0,0 +1,172 @@ +package internal + +// NOTE: This is used from github.com/containers/image by callers that +// don't otherwise use containers/storage, so don't make this depend on any +// larger software like the graph drivers. + +import ( + "archive/tar" + "bytes" + "encoding/binary" + "encoding/json" + "fmt" + "io" + "time" + + "github.com/klauspost/compress/zstd" + "github.com/opencontainers/go-digest" +) + +type ZstdTOC struct { + Version int `json:"version"` + Entries []ZstdFileMetadata `json:"entries"` +} + +type ZstdFileMetadata struct { + Type string `json:"type"` + Name string `json:"name"` + Linkname string `json:"linkName,omitempty"` + Mode int64 `json:"mode,omitempty"` + Size int64 `json:"size"` + UID int `json:"uid"` + GID int `json:"gid"` + ModTime time.Time `json:"modtime"` + AccessTime time.Time `json:"accesstime"` + ChangeTime time.Time `json:"changetime"` + Devmajor int64 `json:"devMajor"` + Devminor int64 `json:"devMinor"` + Xattrs map[string]string `json:"xattrs,omitempty"` + Digest string `json:"digest,omitempty"` + Offset int64 `json:"offset,omitempty"` + EndOffset int64 `json:"endOffset,omitempty"` + + // Currently chunking is not supported. + ChunkSize int64 `json:"chunkSize,omitempty"` + ChunkOffset int64 `json:"chunkOffset,omitempty"` + ChunkDigest string `json:"chunkDigest,omitempty"` +} + +const ( + TypeReg = "reg" + TypeChunk = "chunk" + TypeLink = "hardlink" + TypeChar = "char" + TypeBlock = "block" + TypeDir = "dir" + TypeFifo = "fifo" + TypeSymlink = "symlink" +) + +var TarTypes = map[byte]string{ + tar.TypeReg: TypeReg, + tar.TypeRegA: TypeReg, + tar.TypeLink: TypeLink, + tar.TypeChar: TypeChar, + tar.TypeBlock: TypeBlock, + tar.TypeDir: TypeDir, + tar.TypeFifo: TypeFifo, + tar.TypeSymlink: TypeSymlink, +} + +func GetType(t byte) (string, error) { + r, found := TarTypes[t] + if !found { + return "", fmt.Errorf("unknown tarball type: %v", t) + } + return r, nil +} + +const ( + ManifestChecksumKey = "io.containers.zstd-chunked.manifest-checksum" + ManifestInfoKey = "io.containers.zstd-chunked.manifest-position" + + // ManifestTypeCRFS is a manifest file compatible with the CRFS TOC file. + ManifestTypeCRFS = 1 + + // FooterSizeSupported is the footer size supported by this implementation. + // Newer versions of the image format might increase this value, so reject + // any version that is not supported. + FooterSizeSupported = 40 +) + +var ( + // when the zstd decoder encounters a skippable frame + 1 byte for the size, it + // will ignore it. + // https://tools.ietf.org/html/rfc8478#section-3.1.2 + skippableFrameMagic = []byte{0x50, 0x2a, 0x4d, 0x18} + + ZstdChunkedFrameMagic = []byte{0x47, 0x6e, 0x55, 0x6c, 0x49, 0x6e, 0x55, 0x78} +) + +func appendZstdSkippableFrame(dest io.Writer, data []byte) error { + if _, err := dest.Write(skippableFrameMagic); err != nil { + return err + } + + var size []byte = make([]byte, 4) + binary.LittleEndian.PutUint32(size, uint32(len(data))) + if _, err := dest.Write(size); err != nil { + return err + } + if _, err := dest.Write(data); err != nil { + return err + } + return nil +} + +func WriteZstdChunkedManifest(dest io.Writer, outMetadata map[string]string, offset uint64, metadata []ZstdFileMetadata, level int) error { + // 8 is the size of the zstd skippable frame header + the frame size + manifestOffset := offset + 8 + + toc := ZstdTOC{ + Version: 1, + Entries: metadata, + } + + // Generate the manifest + manifest, err := json.Marshal(toc) + if err != nil { + return err + } + + var compressedBuffer bytes.Buffer + zstdWriter, err := ZstdWriterWithLevel(&compressedBuffer, level) + if err != nil { + return err + } + if _, err := zstdWriter.Write(manifest); err != nil { + zstdWriter.Close() + return err + } + if err := zstdWriter.Close(); err != nil { + return err + } + compressedManifest := compressedBuffer.Bytes() + + manifestDigester := digest.Canonical.Digester() + manifestChecksum := manifestDigester.Hash() + if _, err := manifestChecksum.Write(compressedManifest); err != nil { + return err + } + + outMetadata[ManifestChecksumKey] = manifestDigester.Digest().String() + outMetadata[ManifestInfoKey] = fmt.Sprintf("%d:%d:%d:%d", manifestOffset, len(compressedManifest), len(manifest), ManifestTypeCRFS) + if err := appendZstdSkippableFrame(dest, compressedManifest); err != nil { + return err + } + + // Store the offset to the manifest and its size in LE order + var manifestDataLE []byte = make([]byte, FooterSizeSupported) + binary.LittleEndian.PutUint64(manifestDataLE, manifestOffset) + binary.LittleEndian.PutUint64(manifestDataLE[8:], uint64(len(compressedManifest))) + binary.LittleEndian.PutUint64(manifestDataLE[16:], uint64(len(manifest))) + binary.LittleEndian.PutUint64(manifestDataLE[24:], uint64(ManifestTypeCRFS)) + copy(manifestDataLE[32:], ZstdChunkedFrameMagic) + + return appendZstdSkippableFrame(dest, manifestDataLE) +} + +func ZstdWriterWithLevel(dest io.Writer, level int) (*zstd.Encoder, error) { + el := zstd.EncoderLevelFromZstd(level) + return zstd.NewWriter(dest, zstd.WithEncoderLevel(el)) +} diff --git a/vendor/github.com/containers/storage/pkg/chunked/storage.go b/vendor/github.com/containers/storage/pkg/chunked/storage.go new file mode 100644 index 000000000..9212cbbcf --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/chunked/storage.go @@ -0,0 +1,26 @@ +package chunked + +import ( + "fmt" + "io" +) + +// ImageSourceChunk is a portion of a blob. +type ImageSourceChunk struct { + Offset uint64 + Length uint64 +} + +// ImageSourceSeekable is an image source that permits to fetch chunks of the entire blob. +type ImageSourceSeekable interface { + // GetBlobAt returns a stream for the specified blob. + GetBlobAt([]ImageSourceChunk) (chan io.ReadCloser, chan error, error) +} + +// ErrBadRequest is returned when the request is not valid +type ErrBadRequest struct { +} + +func (e ErrBadRequest) Error() string { + return fmt.Sprintf("bad request") +} diff --git a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go new file mode 100644 index 000000000..0f14d8af9 --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go @@ -0,0 +1,875 @@ +package chunked + +import ( + archivetar "archive/tar" + "context" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "sort" + "strings" + "syscall" + "time" + + storage "github.com/containers/storage" + graphdriver "github.com/containers/storage/drivers" + driversCopy "github.com/containers/storage/drivers/copy" + "github.com/containers/storage/pkg/archive" + "github.com/containers/storage/pkg/chunked/internal" + "github.com/containers/storage/pkg/idtools" + "github.com/containers/storage/types" + "github.com/klauspost/compress/zstd" + digest "github.com/opencontainers/go-digest" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "github.com/vbatts/tar-split/archive/tar" + "golang.org/x/sys/unix" +) + +const ( + maxNumberMissingChunks = 1024 + newFileFlags = (unix.O_CREAT | unix.O_TRUNC | unix.O_WRONLY | unix.O_EXCL) + containersOverrideXattr = "user.containers.override_stat" + bigDataKey = "zstd-chunked-manifest" +) + +type chunkedZstdDiffer struct { + stream ImageSourceSeekable + manifest []byte + layersMetadata map[string][]internal.ZstdFileMetadata + layersTarget map[string]string +} + +func timeToTimespec(time time.Time) (ts unix.Timespec) { + if time.IsZero() { + // Return UTIME_OMIT special value + ts.Sec = 0 + ts.Nsec = ((1 << 30) - 2) + return + } + return unix.NsecToTimespec(time.UnixNano()) +} + +func copyFileContent(src, destFile, root string, dirfd int, missingDirsMode, mode os.FileMode) (*os.File, int64, error) { + st, err := os.Stat(src) + if err != nil { + return nil, -1, err + } + + copyWithFileRange, copyWithFileClone := true, true + + // If the destination file already exists, we shouldn't blow it away + dstFile, err := openFileUnderRoot(destFile, root, dirfd, newFileFlags, mode) + if err != nil { + return nil, -1, err + } + + err = driversCopy.CopyRegularToFile(src, dstFile, st, ©WithFileRange, ©WithFileClone) + if err != nil { + dstFile.Close() + return nil, -1, err + } + return dstFile, st.Size(), err +} + +func prepareOtherLayersCache(layersMetadata map[string][]internal.ZstdFileMetadata) map[string]map[string]*internal.ZstdFileMetadata { + maps := make(map[string]map[string]*internal.ZstdFileMetadata) + + for layerID, v := range layersMetadata { + r := make(map[string]*internal.ZstdFileMetadata) + for i := range v { + r[v[i].Digest] = &v[i] + } + maps[layerID] = r + } + return maps +} + +func getLayersCache(store storage.Store) (map[string][]internal.ZstdFileMetadata, map[string]string, error) { + allLayers, err := store.Layers() + if err != nil { + return nil, nil, err + } + + layersMetadata := make(map[string][]internal.ZstdFileMetadata) + layersTarget := make(map[string]string) + for _, r := range allLayers { + manifestReader, err := store.LayerBigData(r.ID, bigDataKey) + if err != nil { + continue + } + defer manifestReader.Close() + manifest, err := ioutil.ReadAll(manifestReader) + if err != nil { + return nil, nil, err + } + var toc internal.ZstdTOC + if err := json.Unmarshal(manifest, &toc); err != nil { + continue + } + layersMetadata[r.ID] = toc.Entries + target, err := store.DifferTarget(r.ID) + if err != nil { + return nil, nil, err + } + layersTarget[r.ID] = target + } + + return layersMetadata, layersTarget, nil +} + +// GetDiffer returns a differ than can be used with ApplyDiffWithDiffer. +func GetDiffer(ctx context.Context, store storage.Store, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (graphdriver.Differ, error) { + if _, ok := annotations[internal.ManifestChecksumKey]; ok { + return makeZstdChunkedDiffer(ctx, store, blobSize, annotations, iss) + } + return nil, errors.New("blob type not supported for partial retrieval") +} + +func makeZstdChunkedDiffer(ctx context.Context, store storage.Store, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (*chunkedZstdDiffer, error) { + manifest, err := readZstdChunkedManifest(iss, blobSize, annotations) + if err != nil { + return nil, err + } + layersMetadata, layersTarget, err := getLayersCache(store) + if err != nil { + return nil, err + } + + return &chunkedZstdDiffer{ + stream: iss, + manifest: manifest, + layersMetadata: layersMetadata, + layersTarget: layersTarget, + }, nil +} + +func findFileInOtherLayers(file internal.ZstdFileMetadata, root string, dirfd int, layersMetadata map[string]map[string]*internal.ZstdFileMetadata, layersTarget map[string]string, missingDirsMode os.FileMode) (*os.File, int64, error) { + // this is ugly, needs to be indexed + for layerID, checksums := range layersMetadata { + m, found := checksums[file.Digest] + if !found { + continue + } + + source, ok := layersTarget[layerID] + if !ok { + continue + } + + srcDirfd, err := unix.Open(source, unix.O_RDONLY, 0) + if err != nil { + continue + } + defer unix.Close(srcDirfd) + + srcFile, err := openFileUnderRoot(m.Name, source, srcDirfd, unix.O_RDONLY, 0) + if err != nil { + continue + } + defer srcFile.Close() + + srcPath := fmt.Sprintf("/proc/self/fd/%d", srcFile.Fd()) + + dstFile, written, err := copyFileContent(srcPath, file.Name, root, dirfd, missingDirsMode, 0) + if err != nil { + continue + } + return dstFile, written, nil + } + return nil, 0, nil +} + +func getFileDigest(f *os.File) (digest.Digest, error) { + digester := digest.Canonical.Digester() + if _, err := io.Copy(digester.Hash(), f); err != nil { + return "", err + } + return digester.Digest(), nil +} + +// findFileOnTheHost checks whether the requested file already exist on the host and copies the file content from there if possible. +// It is currently implemented to look only at the file with the same path. Ideally it can detect the same content also at different +// paths. +func findFileOnTheHost(file internal.ZstdFileMetadata, root string, dirfd int, missingDirsMode os.FileMode) (*os.File, int64, error) { + sourceFile := filepath.Clean(filepath.Join("/", file.Name)) + if !strings.HasPrefix(sourceFile, "/usr/") { + // limit host deduplication to files under /usr. + return nil, 0, nil + } + + st, err := os.Stat(sourceFile) + if err != nil || !st.Mode().IsRegular() { + return nil, 0, nil + } + + if st.Size() != file.Size { + return nil, 0, nil + } + + fd, err := unix.Open(sourceFile, unix.O_RDONLY|unix.O_NONBLOCK, 0) + if err != nil { + return nil, 0, nil + } + + f := os.NewFile(uintptr(fd), "fd") + defer f.Close() + + manifestChecksum, err := digest.Parse(file.Digest) + if err != nil { + return nil, 0, err + } + + checksum, err := getFileDigest(f) + if err != nil { + return nil, 0, err + } + + if checksum != manifestChecksum { + return nil, 0, nil + } + + dstFile, written, err := copyFileContent(fmt.Sprintf("/proc/self/fd/%d", fd), file.Name, root, dirfd, missingDirsMode, 0) + if err != nil { + return nil, 0, nil + } + + // calculate the checksum again to make sure the file wasn't modified while it was copied + if _, err := f.Seek(0, 0); err != nil { + return nil, 0, err + } + checksum, err = getFileDigest(f) + if err != nil { + return nil, 0, err + } + if checksum != manifestChecksum { + return nil, 0, nil + } + return dstFile, written, nil +} + +func maybeDoIDRemap(manifest []internal.ZstdFileMetadata, options *archive.TarOptions) error { + if options.ChownOpts == nil && len(options.UIDMaps) == 0 || len(options.GIDMaps) == 0 { + return nil + } + + idMappings := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps) + + for i := range manifest { + if options.ChownOpts != nil { + manifest[i].UID = options.ChownOpts.UID + manifest[i].GID = options.ChownOpts.GID + } else { + pair := idtools.IDPair{ + UID: manifest[i].UID, + GID: manifest[i].GID, + } + var err error + manifest[i].UID, manifest[i].GID, err = idMappings.ToContainer(pair) + if err != nil { + return err + } + } + } + return nil +} + +type missingFile struct { + File *internal.ZstdFileMetadata + Gap int64 +} + +func (m missingFile) Length() int64 { + return m.File.EndOffset - m.File.Offset +} + +type missingChunk struct { + RawChunk ImageSourceChunk + Files []missingFile +} + +func setFileAttrs(file *os.File, mode os.FileMode, metadata *internal.ZstdFileMetadata, options *archive.TarOptions) error { + if file == nil || file.Fd() < 0 { + return errors.Errorf("invalid file") + } + fd := int(file.Fd()) + + t, err := typeToTarType(metadata.Type) + if err != nil { + return err + } + if t == tar.TypeSymlink { + return nil + } + + if err := unix.Fchown(fd, metadata.UID, metadata.GID); err != nil { + if !options.IgnoreChownErrors { + return err + } + } + + for k, v := range metadata.Xattrs { + data, err := base64.StdEncoding.DecodeString(v) + if err != nil { + return err + } + if err := unix.Fsetxattr(fd, k, data, 0); err != nil { + return err + } + } + + ts := []unix.Timespec{timeToTimespec(metadata.AccessTime), timeToTimespec(metadata.ModTime)} + if err := unix.UtimesNanoAt(fd, "", ts, 0); err != nil && errors.Is(err, unix.ENOSYS) { + return err + } + + if err := unix.Fchmod(fd, uint32(mode)); err != nil { + return err + } + return nil +} + +func openFileUnderRoot(name, root string, dirfd int, flags uint64, mode os.FileMode) (*os.File, error) { + how := unix.OpenHow{ + Flags: flags, + Mode: uint64(mode & 07777), + Resolve: unix.RESOLVE_IN_ROOT, + } + + fd, err := unix.Openat2(dirfd, name, &how) + if err != nil { + return nil, err + } + return os.NewFile(uintptr(fd), name), nil +} + +func createFileFromZstdStream(dest string, dirfd int, reader io.Reader, missingDirsMode, mode os.FileMode, metadata *internal.ZstdFileMetadata, options *archive.TarOptions) (err error) { + file, err := openFileUnderRoot(metadata.Name, dest, dirfd, newFileFlags, 0) + if err != nil { + return err + } + defer func() { + err2 := file.Close() + if err == nil { + err = err2 + } + }() + + z, err := zstd.NewReader(reader) + if err != nil { + return err + } + defer z.Close() + + digester := digest.Canonical.Digester() + checksum := digester.Hash() + _, err = z.WriteTo(io.MultiWriter(file, checksum)) + if err != nil { + return err + } + manifestChecksum, err := digest.Parse(metadata.Digest) + if err != nil { + return err + } + if digester.Digest() != manifestChecksum { + return fmt.Errorf("checksum mismatch for %q", dest) + } + return setFileAttrs(file, mode, metadata, options) +} + +func storeMissingFiles(streams chan io.ReadCloser, errs chan error, dest string, dirfd int, missingChunks []missingChunk, missingDirsMode os.FileMode, options *archive.TarOptions) error { + for mc := 0; ; mc++ { + var part io.ReadCloser + select { + case p := <-streams: + part = p + case err := <-errs: + return err + } + if part == nil { + if mc == len(missingChunks) { + break + } + return errors.Errorf("invalid stream returned %d %d", mc, len(missingChunks)) + } + if mc == len(missingChunks) { + return errors.Errorf("too many chunks returned") + } + + for _, mf := range missingChunks[mc].Files { + if mf.Gap > 0 { + limitReader := io.LimitReader(part, mf.Gap) + _, err := io.Copy(ioutil.Discard, limitReader) + if err != nil { + return err + } + continue + } + + limitReader := io.LimitReader(part, mf.Length()) + + if err := createFileFromZstdStream(dest, dirfd, limitReader, missingDirsMode, os.FileMode(mf.File.Mode), mf.File, options); err != nil { + part.Close() + return err + } + } + part.Close() + } + return nil +} + +func mergeMissingChunks(missingChunks []missingChunk, target int) []missingChunk { + if len(missingChunks) <= target { + return missingChunks + } + + getGap := func(missingChunks []missingChunk, i int) int { + prev := missingChunks[i-1].RawChunk.Offset + missingChunks[i-1].RawChunk.Length + return int(missingChunks[i].RawChunk.Offset - prev) + } + + // this implementation doesn't account for duplicates, so it could merge + // more than necessary to reach the specified target. Since target itself + // is a heuristic value, it doesn't matter. + var gaps []int + for i := 1; i < len(missingChunks); i++ { + gaps = append(gaps, getGap(missingChunks, i)) + } + sort.Ints(gaps) + + toShrink := len(missingChunks) - target + targetValue := gaps[toShrink-1] + + newMissingChunks := missingChunks[0:1] + for i := 1; i < len(missingChunks); i++ { + gap := getGap(missingChunks, i) + if gap > targetValue { + newMissingChunks = append(newMissingChunks, missingChunks[i]) + } else { + prev := &newMissingChunks[len(newMissingChunks)-1] + gapFile := missingFile{ + Gap: int64(gap), + } + prev.RawChunk.Length += uint64(gap) + missingChunks[i].RawChunk.Length + prev.Files = append(append(prev.Files, gapFile), missingChunks[i].Files...) + } + } + + return newMissingChunks +} + +func retrieveMissingFiles(input *chunkedZstdDiffer, dest string, dirfd int, missingChunks []missingChunk, missingDirsMode os.FileMode, options *archive.TarOptions) error { + var chunksToRequest []ImageSourceChunk + for _, c := range missingChunks { + chunksToRequest = append(chunksToRequest, c.RawChunk) + } + + // There are some missing files. Prepare a multirange request for the missing chunks. + var streams chan io.ReadCloser + var err error + var errs chan error + for { + streams, errs, err = input.stream.GetBlobAt(chunksToRequest) + if err == nil { + break + } + + if _, ok := err.(ErrBadRequest); ok { + requested := len(missingChunks) + // If the server cannot handle at least 64 chunks in a single request, just give up. + if requested < 64 { + return err + } + + // Merge more chunks to request + missingChunks = mergeMissingChunks(missingChunks, requested/2) + continue + } + return err + } + + if err := storeMissingFiles(streams, errs, dest, dirfd, missingChunks, missingDirsMode, options); err != nil { + return err + } + return nil +} + +func safeMkdir(target string, dirfd int, mode os.FileMode, metadata *internal.ZstdFileMetadata, options *archive.TarOptions) error { + parent := filepath.Dir(metadata.Name) + base := filepath.Base(metadata.Name) + + parentFd := dirfd + if parent != "." { + parentFile, err := openFileUnderRoot(parent, target, dirfd, unix.O_DIRECTORY|unix.O_PATH|unix.O_RDONLY, 0) + if err != nil { + return err + } + defer parentFile.Close() + parentFd = int(parentFile.Fd()) + } + + if err := unix.Mkdirat(parentFd, base, uint32(mode)); err != nil { + if !os.IsExist(err) { + return err + } + } + + file, err := openFileUnderRoot(metadata.Name, target, dirfd, unix.O_RDONLY, 0) + if err != nil { + return err + } + defer file.Close() + + return setFileAttrs(file, mode, metadata, options) +} + +func safeLink(target string, dirfd int, mode os.FileMode, metadata *internal.ZstdFileMetadata, options *archive.TarOptions) error { + sourceFile, err := openFileUnderRoot(metadata.Linkname, target, dirfd, unix.O_RDONLY, 0) + if err != nil { + return err + } + defer sourceFile.Close() + + destDir, destBase := filepath.Dir(metadata.Name), filepath.Base(metadata.Name) + destDirFd := dirfd + if destDir != "." { + f, err := openFileUnderRoot(destDir, target, dirfd, unix.O_RDONLY, 0) + if err != nil { + return err + } + defer f.Close() + destDirFd = int(f.Fd()) + } + + err = unix.Linkat(int(sourceFile.Fd()), "", destDirFd, destBase, unix.AT_EMPTY_PATH) + if err != nil { + return err + } + + newFile, err := openFileUnderRoot(metadata.Name, target, dirfd, unix.O_WRONLY, 0) + if err != nil { + return err + } + defer newFile.Close() + + return setFileAttrs(newFile, mode, metadata, options) +} + +func safeSymlink(target string, dirfd int, mode os.FileMode, metadata *internal.ZstdFileMetadata, options *archive.TarOptions) error { + destDir, destBase := filepath.Dir(metadata.Name), filepath.Base(metadata.Name) + destDirFd := dirfd + if destDir != "." { + f, err := openFileUnderRoot(destDir, target, dirfd, unix.O_RDONLY, 0) + if err != nil { + return err + } + defer f.Close() + destDirFd = int(f.Fd()) + } + + return unix.Symlinkat(metadata.Linkname, destDirFd, destBase) +} + +type whiteoutHandler struct { + Dirfd int + Root string +} + +func (d whiteoutHandler) Setxattr(path, name string, value []byte) error { + file, err := openFileUnderRoot(path, d.Root, d.Dirfd, unix.O_RDONLY, 0) + if err != nil { + return err + } + defer file.Close() + + return unix.Fsetxattr(int(file.Fd()), name, value, 0) +} + +func (d whiteoutHandler) Mknod(path string, mode uint32, dev int) error { + dir := filepath.Dir(path) + base := filepath.Base(path) + + dirfd := d.Dirfd + if dir != "" { + dir, err := openFileUnderRoot(dir, d.Root, d.Dirfd, unix.O_RDONLY, 0) + if err != nil { + return err + } + defer dir.Close() + + dirfd = int(dir.Fd()) + } + + return unix.Mknodat(dirfd, base, mode, dev) +} + +func checkChownErr(err error, name string, uid, gid int) error { + if errors.Is(err, syscall.EINVAL) { + return errors.Wrapf(err, "potentially insufficient UIDs or GIDs available in user namespace (requested %d:%d for %s): Check /etc/subuid and /etc/subgid", uid, gid, name) + } + return err +} + +func (d whiteoutHandler) Chown(path string, uid, gid int) error { + file, err := openFileUnderRoot(path, d.Root, d.Dirfd, unix.O_PATH, 0) + if err != nil { + return err + } + defer file.Close() + + if err := unix.Fchownat(int(file.Fd()), "", uid, gid, unix.AT_EMPTY_PATH); err != nil { + var stat unix.Stat_t + if unix.Fstat(int(file.Fd()), &stat) == nil { + if stat.Uid == uint32(uid) && stat.Gid == uint32(gid) { + return nil + } + } + return checkChownErr(err, path, uid, gid) + } + return nil +} + +type hardLinkToCreate struct { + dest string + dirfd int + mode os.FileMode + metadata *internal.ZstdFileMetadata +} + +func (d *chunkedZstdDiffer) ApplyDiff(dest string, options *archive.TarOptions) (graphdriver.DriverWithDifferOutput, error) { + bigData := map[string][]byte{ + bigDataKey: d.manifest, + } + output := graphdriver.DriverWithDifferOutput{ + Differ: d, + BigData: bigData, + } + + storeOpts, err := types.DefaultStoreOptionsAutoDetectUID() + if err != nil { + return output, err + } + + enableHostDedup := false + if value := storeOpts.PullOptions["enable_host_deduplication"]; strings.ToLower(value) == "true" { + enableHostDedup = true + } + + // Generate the manifest + var toc internal.ZstdTOC + if err := json.Unmarshal(d.manifest, &toc); err != nil { + return output, err + } + + whiteoutConverter := archive.GetWhiteoutConverter(options.WhiteoutFormat, options.WhiteoutData) + + var missingChunks []missingChunk + var mergedEntries []internal.ZstdFileMetadata + + if err := maybeDoIDRemap(toc.Entries, options); err != nil { + return output, err + } + + for _, e := range toc.Entries { + if e.Type == TypeChunk { + l := len(mergedEntries) + if l == 0 || mergedEntries[l-1].Type != TypeReg { + return output, errors.New("chunk type without a regular file") + } + mergedEntries[l-1].EndOffset = e.EndOffset + continue + } + mergedEntries = append(mergedEntries, e) + } + + if options.ForceMask != nil { + uid, gid, mode, err := archive.GetFileOwner(dest) + if err == nil { + value := fmt.Sprintf("%d:%d:0%o", uid, gid, mode) + if err := unix.Setxattr(dest, containersOverrideXattr, []byte(value), 0); err != nil { + return output, err + } + } + } + + dirfd, err := unix.Open(dest, unix.O_RDONLY|unix.O_PATH, 0) + if err != nil { + return output, err + } + defer unix.Close(dirfd) + + otherLayersCache := prepareOtherLayersCache(d.layersMetadata) + + missingDirsMode := os.FileMode(0700) + if options.ForceMask != nil { + missingDirsMode = *options.ForceMask + } + + // hardlinks can point to missing files. So create them after all files + // are retrieved + var hardLinks []hardLinkToCreate + + missingChunksSize, totalChunksSize := int64(0), int64(0) + for i, r := range mergedEntries { + if options.ForceMask != nil { + value := fmt.Sprintf("%d:%d:0%o", r.UID, r.GID, r.Mode&07777) + r.Xattrs[containersOverrideXattr] = base64.StdEncoding.EncodeToString([]byte(value)) + r.Mode = int64(*options.ForceMask) + } + + mode := os.FileMode(r.Mode) + + r.Name = filepath.Clean(r.Name) + r.Linkname = filepath.Clean(r.Linkname) + + t, err := typeToTarType(r.Type) + if err != nil { + return output, err + } + if whiteoutConverter != nil { + hdr := archivetar.Header{ + Typeflag: t, + Name: r.Name, + Linkname: r.Linkname, + Size: r.Size, + Mode: r.Mode, + Uid: r.UID, + Gid: r.GID, + } + handler := whiteoutHandler{ + Dirfd: dirfd, + Root: dest, + } + writeFile, err := whiteoutConverter.ConvertReadWithHandler(&hdr, r.Name, &handler) + if err != nil { + return output, err + } + if !writeFile { + continue + } + } + switch t { + case tar.TypeReg: + // Create directly empty files. + if r.Size == 0 { + // Used to have a scope for cleanup. + createEmptyFile := func() error { + file, err := openFileUnderRoot(r.Name, dest, dirfd, newFileFlags, 0) + if err != nil { + return err + } + defer file.Close() + if err := setFileAttrs(file, mode, &r, options); err != nil { + return err + } + return nil + } + if err := createEmptyFile(); err != nil { + return output, err + } + continue + } + + case tar.TypeDir: + if err := safeMkdir(dest, dirfd, mode, &r, options); err != nil { + return output, err + } + continue + + case tar.TypeLink: + dest := dest + dirfd := dirfd + mode := mode + r := r + hardLinks = append(hardLinks, hardLinkToCreate{ + dest: dest, + dirfd: dirfd, + mode: mode, + metadata: &r, + }) + continue + + case tar.TypeSymlink: + if err := safeSymlink(dest, dirfd, mode, &r, options); err != nil { + return output, err + } + continue + + case tar.TypeChar: + case tar.TypeBlock: + case tar.TypeFifo: + /* Ignore. */ + default: + return output, fmt.Errorf("invalid type %q", t) + } + + totalChunksSize += r.Size + + dstFile, _, err := findFileInOtherLayers(r, dest, dirfd, otherLayersCache, d.layersTarget, missingDirsMode) + if err != nil { + return output, err + } + if dstFile != nil { + if err := setFileAttrs(dstFile, mode, &r, options); err != nil { + dstFile.Close() + return output, err + } + dstFile.Close() + continue + } + + if enableHostDedup { + dstFile, _, err = findFileOnTheHost(r, dest, dirfd, missingDirsMode) + if err != nil { + return output, err + } + if dstFile != nil { + if err := setFileAttrs(dstFile, mode, &r, options); err != nil { + dstFile.Close() + return output, err + } + dstFile.Close() + continue + } + } + + missingChunksSize += r.Size + if t == tar.TypeReg { + rawChunk := ImageSourceChunk{ + Offset: uint64(r.Offset), + Length: uint64(r.EndOffset - r.Offset), + } + file := missingFile{ + File: &toc.Entries[i], + } + missingChunks = append(missingChunks, missingChunk{ + RawChunk: rawChunk, + Files: []missingFile{ + file, + }, + }) + } + } + // There are some missing files. Prepare a multirange request for the missing chunks. + if len(missingChunks) > 0 { + missingChunks = mergeMissingChunks(missingChunks, maxNumberMissingChunks) + if err := retrieveMissingFiles(d, dest, dirfd, missingChunks, missingDirsMode, options); err != nil { + return output, err + } + } + + for _, m := range hardLinks { + if err := safeLink(m.dest, m.dirfd, m.mode, m.metadata, options); err != nil { + return output, err + } + } + + if totalChunksSize > 0 { + logrus.Debugf("Missing %d bytes out of %d (%.2f %%)", missingChunksSize, totalChunksSize, float32(missingChunksSize*100.0)/float32(totalChunksSize)) + } + return output, nil +} diff --git a/vendor/github.com/containers/storage/pkg/chunked/storage_unsupported.go b/vendor/github.com/containers/storage/pkg/chunked/storage_unsupported.go new file mode 100644 index 000000000..3a406ba78 --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/chunked/storage_unsupported.go @@ -0,0 +1,16 @@ +// +build !linux + +package chunked + +import ( + "context" + + storage "github.com/containers/storage" + graphdriver "github.com/containers/storage/drivers" + "github.com/pkg/errors" +) + +// GetDiffer returns a differ than can be used with ApplyDiffWithDiffer. +func GetDiffer(ctx context.Context, store storage.Store, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (graphdriver.Differ, error) { + return nil, errors.New("format not supported on this architecture") +} diff --git a/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go b/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go index b3998fb35..5be98165e 100644 --- a/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go +++ b/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go @@ -38,7 +38,7 @@ func NewPatternMatcher(patterns []string) (*PatternMatcher, error) { return nil, errors.New("illegal exclusion pattern: \"!\"") } newp.exclusion = true - p = p[1:] + p = strings.TrimPrefix(filepath.Clean(p[1:]), "/") pm.exclusions = true } // Do some syntax checking on the pattern. diff --git a/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go b/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go index f0e46b6b6..b224e7b5c 100644 --- a/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go +++ b/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go @@ -5,6 +5,7 @@ package lockfile import ( "fmt" "os" + "path/filepath" "sync" "time" @@ -33,11 +34,30 @@ type lockfile struct { // descriptor. Note that the path is opened read-only when ro is set. If ro // is unset, openLock will open the path read-write and create the file if // necessary. -func openLock(path string, ro bool) (int, error) { +func openLock(path string, ro bool) (fd int, err error) { if ro { - return unix.Open(path, os.O_RDONLY|unix.O_CLOEXEC, 0) + fd, err = unix.Open(path, os.O_RDONLY|unix.O_CLOEXEC, 0) + } else { + fd, err = unix.Open(path, + os.O_RDWR|unix.O_CLOEXEC|os.O_CREATE, + unix.S_IRUSR|unix.S_IWUSR|unix.S_IRGRP|unix.S_IROTH, + ) + } + + if err == nil { + return + } + + // the directory of the lockfile seems to be removed, try to create it + if os.IsNotExist(err) { + if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil { + return fd, errors.Wrap(err, "creating locker directory") + } + + return openLock(path, ro) } - return unix.Open(path, os.O_RDWR|unix.O_CLOEXEC|os.O_CREATE, unix.S_IRUSR|unix.S_IWUSR|unix.S_IRGRP|unix.S_IROTH) + + return } // createLockerForPath returns a Locker object, possibly (depending on the platform) diff --git a/vendor/github.com/containers/storage/storage.conf b/vendor/github.com/containers/storage/storage.conf index e70f4f018..722750c0c 100644 --- a/vendor/github.com/containers/storage/storage.conf +++ b/vendor/github.com/containers/storage/storage.conf @@ -69,6 +69,9 @@ additionalimagestores = [ # and vfs drivers. #ignore_chown_errors = "false" +# Inodes is used to set a maximum inodes of the container image. +# inodes = "" + # Path to an helper program to use for mounting the file system instead of mounting it # directly. #mount_program = "/usr/bin/fuse-overlayfs" diff --git a/vendor/github.com/containers/storage/types/options.go b/vendor/github.com/containers/storage/types/options.go index c0e3ea637..f9bf7e6b6 100644 --- a/vendor/github.com/containers/storage/types/options.go +++ b/vendor/github.com/containers/storage/types/options.go @@ -2,7 +2,6 @@ package types import ( "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -272,21 +271,21 @@ func ReloadConfigurationFileIfNeeded(configFile string, storeOptions *StoreOptio // ReloadConfigurationFile parses the specified configuration file and overrides // the configuration in storeOptions. func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) { - data, err := ioutil.ReadFile(configFile) - if err != nil { + config := new(tomlConfig) + + meta, err := toml.DecodeFile(configFile, &config) + if err == nil { + keys := meta.Undecoded() + if len(keys) > 0 { + logrus.Warningf("Failed to decode the keys %q from %q.", keys, configFile) + } + } else { if !os.IsNotExist(err) { fmt.Printf("Failed to read %s %v\n", configFile, err.Error()) return } } - config := new(tomlConfig) - - if _, err := toml.Decode(string(data), config); err != nil { - fmt.Printf("Failed to parse %s %v\n", configFile, err.Error()) - return - } - // Clear storeOptions of previos settings *storeOptions = StoreOptions{} if config.Storage.Driver != "" { diff --git a/vendor/github.com/containers/storage/types/storage_broken.conf b/vendor/github.com/containers/storage/types/storage_broken.conf new file mode 100644 index 000000000..3bca1d978 --- /dev/null +++ b/vendor/github.com/containers/storage/types/storage_broken.conf @@ -0,0 +1,18 @@ +# This file is is a TEST configuration file for all tools +# that use the containers/storage library. +# See man 5 containers-storage.conf for more information +# The "container storage" table contains all of the server options. +foo = "bar" + +[storage] + +# Default Storage Driver +driver = "" + +# Temporary storage location +runroot = "/run/containers/test" + +[storage.options] +# Primary Read/Write location of container storage +graphroot = "/var/lib/containers/storage" + diff --git a/vendor/github.com/google/uuid/null.go b/vendor/github.com/google/uuid/null.go new file mode 100644 index 000000000..d7fcbf286 --- /dev/null +++ b/vendor/github.com/google/uuid/null.go @@ -0,0 +1,118 @@ +// Copyright 2021 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "bytes" + "database/sql/driver" + "encoding/json" + "fmt" +) + +var jsonNull = []byte("null") + +// NullUUID represents a UUID that may be null. +// NullUUID implements the SQL driver.Scanner interface so +// it can be used as a scan destination: +// +// var u uuid.NullUUID +// err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&u) +// ... +// if u.Valid { +// // use u.UUID +// } else { +// // NULL value +// } +// +type NullUUID struct { + UUID UUID + Valid bool // Valid is true if UUID is not NULL +} + +// Scan implements the SQL driver.Scanner interface. +func (nu *NullUUID) Scan(value interface{}) error { + if value == nil { + nu.UUID, nu.Valid = Nil, false + return nil + } + + err := nu.UUID.Scan(value) + if err != nil { + nu.Valid = false + return err + } + + nu.Valid = true + return nil +} + +// Value implements the driver Valuer interface. +func (nu NullUUID) Value() (driver.Value, error) { + if !nu.Valid { + return nil, nil + } + // Delegate to UUID Value function + return nu.UUID.Value() +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (nu NullUUID) MarshalBinary() ([]byte, error) { + if nu.Valid { + return nu.UUID[:], nil + } + + return []byte(nil), nil +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (nu *NullUUID) UnmarshalBinary(data []byte) error { + if len(data) != 16 { + return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) + } + copy(nu.UUID[:], data) + nu.Valid = true + return nil +} + +// MarshalText implements encoding.TextMarshaler. +func (nu NullUUID) MarshalText() ([]byte, error) { + if nu.Valid { + return nu.UUID.MarshalText() + } + + return jsonNull, nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (nu *NullUUID) UnmarshalText(data []byte) error { + id, err := ParseBytes(data) + if err != nil { + nu.Valid = false + return err + } + nu.UUID = id + nu.Valid = true + return nil +} + +// MarshalJSON implements json.Marshaler. +func (nu NullUUID) MarshalJSON() ([]byte, error) { + if nu.Valid { + return json.Marshal(nu.UUID) + } + + return jsonNull, nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (nu *NullUUID) UnmarshalJSON(data []byte) error { + if bytes.Equal(data, jsonNull) { + *nu = NullUUID{} + return nil // valid null UUID + } + err := json.Unmarshal(data, &nu.UUID) + nu.Valid = err == nil + return err +} diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go index 60d26bb50..a57207aeb 100644 --- a/vendor/github.com/google/uuid/uuid.go +++ b/vendor/github.com/google/uuid/uuid.go @@ -12,6 +12,7 @@ import ( "fmt" "io" "strings" + "sync" ) // A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC @@ -33,7 +34,15 @@ const ( Future // Reserved for future definition. ) -var rander = rand.Reader // random function +const randPoolSize = 16 * 16 + +var ( + rander = rand.Reader // random function + poolEnabled = false + poolMu sync.Mutex + poolPos = randPoolSize // protected with poolMu + pool [randPoolSize]byte // protected with poolMu +) type invalidLengthError struct{ len int } @@ -41,6 +50,12 @@ func (err invalidLengthError) Error() string { return fmt.Sprintf("invalid UUID length: %d", err.len) } +// IsInvalidLengthError is matcher function for custom error invalidLengthError +func IsInvalidLengthError(err error) bool { + _, ok := err.(invalidLengthError) + return ok +} + // Parse decodes s into a UUID or returns an error. Both the standard UUID // forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the @@ -249,3 +264,31 @@ func SetRand(r io.Reader) { } rander = r } + +// EnableRandPool enables internal randomness pool used for Random +// (Version 4) UUID generation. The pool contains random bytes read from +// the random number generator on demand in batches. Enabling the pool +// may improve the UUID generation throughput significantly. +// +// Since the pool is stored on the Go heap, this feature may be a bad fit +// for security sensitive applications. +// +// Both EnableRandPool and DisableRandPool are not thread-safe and should +// only be called when there is no possibility that New or any other +// UUID Version 4 generation function will be called concurrently. +func EnableRandPool() { + poolEnabled = true +} + +// DisableRandPool disables the randomness pool if it was previously +// enabled with EnableRandPool. +// +// Both EnableRandPool and DisableRandPool are not thread-safe and should +// only be called when there is no possibility that New or any other +// UUID Version 4 generation function will be called concurrently. +func DisableRandPool() { + poolEnabled = false + defer poolMu.Unlock() + poolMu.Lock() + poolPos = randPoolSize +} diff --git a/vendor/github.com/google/uuid/version4.go b/vendor/github.com/google/uuid/version4.go index 86160fbd0..7697802e4 100644 --- a/vendor/github.com/google/uuid/version4.go +++ b/vendor/github.com/google/uuid/version4.go @@ -27,6 +27,8 @@ func NewString() string { // The strength of the UUIDs is based on the strength of the crypto/rand // package. // +// Uses the randomness pool if it was enabled with EnableRandPool. +// // A note about uniqueness derived from the UUID Wikipedia entry: // // Randomly generated UUIDs have 122 random bits. One's annual risk of being @@ -35,7 +37,10 @@ func NewString() string { // equivalent to the odds of creating a few tens of trillions of UUIDs in a // year and having one duplicate. func NewRandom() (UUID, error) { - return NewRandomFromReader(rander) + if !poolEnabled { + return NewRandomFromReader(rander) + } + return newRandomFromPool() } // NewRandomFromReader returns a UUID based on bytes read from a given io.Reader. @@ -49,3 +54,23 @@ func NewRandomFromReader(r io.Reader) (UUID, error) { uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 return uuid, nil } + +func newRandomFromPool() (UUID, error) { + var uuid UUID + poolMu.Lock() + if poolPos == randPoolSize { + _, err := io.ReadFull(rander, pool[:]) + if err != nil { + poolMu.Unlock() + return Nil, err + } + poolPos = 0 + } + copy(uuid[:], pool[poolPos:(poolPos+16)]) + poolPos += 16 + poolMu.Unlock() + + uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 + uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 + return uuid, nil +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go index d2c16f7fd..cc7a106be 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go @@ -2,6 +2,7 @@ package user import ( "bufio" + "bytes" "errors" "fmt" "io" @@ -55,11 +56,11 @@ type IDMap struct { Count int64 } -func parseLine(line string, v ...interface{}) { - parseParts(strings.Split(line, ":"), v...) +func parseLine(line []byte, v ...interface{}) { + parseParts(bytes.Split(line, []byte(":")), v...) } -func parseParts(parts []string, v ...interface{}) { +func parseParts(parts [][]byte, v ...interface{}) { if len(parts) == 0 { return } @@ -75,16 +76,16 @@ func parseParts(parts []string, v ...interface{}) { // This is legit. switch e := v[i].(type) { case *string: - *e = p + *e = string(p) case *int: // "numbers", with conversion errors ignored because of some misbehaving configuration files. - *e, _ = strconv.Atoi(p) + *e, _ = strconv.Atoi(string(p)) case *int64: - *e, _ = strconv.ParseInt(p, 10, 64) + *e, _ = strconv.ParseInt(string(p), 10, 64) case *[]string: // Comma-separated lists. - if p != "" { - *e = strings.Split(p, ",") + if len(p) != 0 { + *e = strings.Split(string(p), ",") } else { *e = []string{} } @@ -128,8 +129,8 @@ func ParsePasswdFilter(r io.Reader, filter func(User) bool) ([]User, error) { ) for s.Scan() { - line := strings.TrimSpace(s.Text()) - if line == "" { + line := bytes.TrimSpace(s.Bytes()) + if len(line) == 0 { continue } @@ -179,15 +180,53 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) { if r == nil { return nil, fmt.Errorf("nil source for group-formatted data") } + rd := bufio.NewReader(r) + out := []Group{} - var ( - s = bufio.NewScanner(r) - out = []Group{} - ) + // Read the file line-by-line. + for { + var ( + isPrefix bool + wholeLine []byte + err error + ) - for s.Scan() { - text := s.Text() - if text == "" { + // Read the next line. We do so in chunks (as much as reader's + // buffer is able to keep), check if we read enough columns + // already on each step and store final result in wholeLine. + for { + var line []byte + line, isPrefix, err = rd.ReadLine() + + if err != nil { + // We should return no error if EOF is reached + // without a match. + if err == io.EOF { //nolint:errorlint // comparison with io.EOF is legit, https://github.com/polyfloyd/go-errorlint/pull/12 + err = nil + } + return out, err + } + + // Simple common case: line is short enough to fit in a + // single reader's buffer. + if !isPrefix && len(wholeLine) == 0 { + wholeLine = line + break + } + + wholeLine = append(wholeLine, line...) + + // Check if we read the whole line already. + if !isPrefix { + break + } + } + + // There's no spec for /etc/passwd or /etc/group, but we try to follow + // the same rules as the glibc parser, which allows comments and blank + // space at the beginning of a line. + wholeLine = bytes.TrimSpace(wholeLine) + if len(wholeLine) == 0 || wholeLine[0] == '#' { continue } @@ -197,17 +236,12 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) { // root:x:0:root // adm:x:4:root,adm,daemon p := Group{} - parseLine(text, &p.Name, &p.Pass, &p.Gid, &p.List) + parseLine(wholeLine, &p.Name, &p.Pass, &p.Gid, &p.List) if filter == nil || filter(p) { out = append(out, p) } } - if err := s.Err(); err != nil { - return nil, err - } - - return out, nil } type ExecUser struct { @@ -278,7 +312,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( // Allow for userArg to have either "user" syntax, or optionally "user:group" syntax var userArg, groupArg string - parseLine(userSpec, &userArg, &groupArg) + parseLine([]byte(userSpec), &userArg, &groupArg) // Convert userArg and groupArg to be numeric, so we don't have to execute // Atoi *twice* for each iteration over lines. @@ -496,8 +530,8 @@ func ParseSubIDFilter(r io.Reader, filter func(SubID) bool) ([]SubID, error) { ) for s.Scan() { - line := strings.TrimSpace(s.Text()) - if line == "" { + line := bytes.TrimSpace(s.Bytes()) + if len(line) == 0 { continue } @@ -549,14 +583,14 @@ func ParseIDMapFilter(r io.Reader, filter func(IDMap) bool) ([]IDMap, error) { ) for s.Scan() { - line := strings.TrimSpace(s.Text()) - if line == "" { + line := bytes.TrimSpace(s.Bytes()) + if len(line) == 0 { continue } // see: man 7 user_namespaces p := IDMap{} - parseParts(strings.Fields(line), &p.ID, &p.ParentID, &p.Count) + parseParts(bytes.Fields(line), &p.ID, &p.ParentID, &p.Count) if filter == nil || filter(p) { out = append(out, p) diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_zos.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_zos.go new file mode 100644 index 000000000..b7d67fc43 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_zos.go @@ -0,0 +1,7 @@ +// +build zos + +package cwriter + +import "golang.org/x/sys/unix" + +const ioctlReadTermios = unix.TCGETS diff --git a/vendor/github.com/vbauerster/mpb/v7/go.mod b/vendor/github.com/vbauerster/mpb/v7/go.mod index ea22e1eda..22a2c651c 100644 --- a/vendor/github.com/vbauerster/mpb/v7/go.mod +++ b/vendor/github.com/vbauerster/mpb/v7/go.mod @@ -4,7 +4,7 @@ require ( github.com/VividCortex/ewma v1.2.0 github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d github.com/mattn/go-runewidth v0.0.13 - golang.org/x/sys v0.0.0-20210603125802-9665404d3644 + golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 ) go 1.14 diff --git a/vendor/github.com/vbauerster/mpb/v7/go.sum b/vendor/github.com/vbauerster/mpb/v7/go.sum index 0b609b223..59051bd7b 100644 --- a/vendor/github.com/vbauerster/mpb/v7/go.sum +++ b/vendor/github.com/vbauerster/mpb/v7/go.sum @@ -6,5 +6,5 @@ github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4 github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 3f670faba..6e6afcaa1 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -563,6 +563,7 @@ ccflags="$@" $2 ~ /^KEYCTL_/ || $2 ~ /^PERF_/ || $2 ~ /^SECCOMP_MODE_/ || + $2 ~ /^SEEK_/ || $2 ~ /^SPLICE_/ || $2 ~ /^SYNC_FILE_RANGE_/ || $2 !~ /^AUDIT_RECORD_MAGIC/ && diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 9945e5f96..23f6b5760 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -13,6 +13,7 @@ package unix import ( + "fmt" "runtime" "syscall" "unsafe" @@ -398,6 +399,38 @@ func GetsockoptXucred(fd, level, opt int) (*Xucred, error) { return x, err } +func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) { + mib, err := sysctlmib(name) + if err != nil { + return nil, err + } + + // Find size. + n := uintptr(0) + if err := sysctl(mib, nil, &n, nil, 0); err != nil { + return nil, err + } + if n == 0 { + return nil, nil + } + if n%SizeofKinfoProc != 0 { + return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc) + } + + // Read into buffer of that size. + buf := make([]KinfoProc, n/SizeofKinfoProc) + if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil { + return nil, err + } + if n%SizeofKinfoProc != 0 { + return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc) + } + + // The actual call may return less than the original reported required + // size so ensure we deal with that. + return buf[:n/SizeofKinfoProc], nil +} + //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) /* diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go index 991996b60..5bb48ef54 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go @@ -1262,6 +1262,11 @@ const ( SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 SCM_TIMESTAMP_MONOTONIC = 0x4 + SEEK_CUR = 0x1 + SEEK_DATA = 0x4 + SEEK_END = 0x2 + SEEK_HOLE = 0x3 + SEEK_SET = 0x0 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go index e644eaf5e..11e570979 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go @@ -1262,6 +1262,11 @@ const ( SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 SCM_TIMESTAMP_MONOTONIC = 0x4 + SEEK_CUR = 0x1 + SEEK_DATA = 0x4 + SEEK_END = 0x2 + SEEK_HOLE = 0x3 + SEEK_SET = 0x0 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go index 9c7c5e165..440900112 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go @@ -1297,6 +1297,11 @@ const ( SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 SCM_TIME_INFO = 0x7 + SEEK_CUR = 0x1 + SEEK_DATA = 0x3 + SEEK_END = 0x2 + SEEK_HOLE = 0x4 + SEEK_SET = 0x0 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go index b265abb25..64520d312 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go @@ -1298,6 +1298,11 @@ const ( SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 SCM_TIME_INFO = 0x7 + SEEK_CUR = 0x1 + SEEK_DATA = 0x3 + SEEK_END = 0x2 + SEEK_HOLE = 0x4 + SEEK_SET = 0x0 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go index 3df99f285..99e9a0e06 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go @@ -1276,6 +1276,11 @@ const ( SCM_CREDS = 0x3 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 + SEEK_CUR = 0x1 + SEEK_DATA = 0x3 + SEEK_END = 0x2 + SEEK_HOLE = 0x4 + SEEK_SET = 0x0 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go index 218d39906..4c8377114 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go @@ -1298,6 +1298,11 @@ const ( SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 SCM_TIME_INFO = 0x7 + SEEK_CUR = 0x1 + SEEK_DATA = 0x3 + SEEK_END = 0x2 + SEEK_HOLE = 0x4 + SEEK_SET = 0x0 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index c3fa22486..52f5bbc14 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -2284,6 +2284,12 @@ const ( SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 + SEEK_CUR = 0x1 + SEEK_DATA = 0x3 + SEEK_END = 0x2 + SEEK_HOLE = 0x4 + SEEK_MAX = 0x4 + SEEK_SET = 0x0 SELINUX_MAGIC = 0xf97cff8c SHUT_RD = 0x0 SHUT_RDWR = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index 2673e6c59..4c8dc0ba2 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -535,3 +535,107 @@ type CtlInfo struct { Id uint32 Name [96]byte } + +const SizeofKinfoProc = 0x288 + +type Eproc struct { + Paddr uintptr + Sess uintptr + Pcred Pcred + Ucred Ucred + Vm Vmspace + Ppid int32 + Pgid int32 + Jobc int16 + Tdev int32 + Tpgid int32 + Tsess uintptr + Wmesg [8]int8 + Xsize int32 + Xrssize int16 + Xccount int16 + Xswrss int16 + Flag int32 + Login [12]int8 + Spare [4]int32 + _ [4]byte +} + +type ExternProc struct { + P_starttime Timeval + P_vmspace *Vmspace + P_sigacts uintptr + P_flag int32 + P_stat int8 + P_pid int32 + P_oppid int32 + P_dupfd int32 + User_stack *int8 + Exit_thread *byte + P_debugger int32 + Sigwait int32 + P_estcpu uint32 + P_cpticks int32 + P_pctcpu uint32 + P_wchan *byte + P_wmesg *int8 + P_swtime uint32 + P_slptime uint32 + P_realtimer Itimerval + P_rtime Timeval + P_uticks uint64 + P_sticks uint64 + P_iticks uint64 + P_traceflag int32 + P_tracep uintptr + P_siglist int32 + P_textvp uintptr + P_holdcnt int32 + P_sigmask uint32 + P_sigignore uint32 + P_sigcatch uint32 + P_priority uint8 + P_usrpri uint8 + P_nice int8 + P_comm [17]int8 + P_pgrp uintptr + P_addr uintptr + P_xstat uint16 + P_acflag uint16 + P_ru *Rusage +} + +type Itimerval struct { + Interval Timeval + Value Timeval +} + +type KinfoProc struct { + Proc ExternProc + Eproc Eproc +} + +type Vmspace struct { + Dummy int32 + Dummy2 *int8 + Dummy3 [5]int32 + Dummy4 [3]*int8 +} + +type Pcred struct { + Pc_lock [72]int8 + Pc_ucred uintptr + P_ruid uint32 + P_svuid uint32 + P_rgid uint32 + P_svgid uint32 + P_refcnt int32 + _ [4]byte +} + +type Ucred struct { + Ref int32 + Uid uint32 + Ngroups int16 + Groups [16]uint32 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go index 1465cbcff..96f0e6ae2 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go @@ -535,3 +535,107 @@ type CtlInfo struct { Id uint32 Name [96]byte } + +const SizeofKinfoProc = 0x288 + +type Eproc struct { + Paddr uintptr + Sess uintptr + Pcred Pcred + Ucred Ucred + Vm Vmspace + Ppid int32 + Pgid int32 + Jobc int16 + Tdev int32 + Tpgid int32 + Tsess uintptr + Wmesg [8]int8 + Xsize int32 + Xrssize int16 + Xccount int16 + Xswrss int16 + Flag int32 + Login [12]int8 + Spare [4]int32 + _ [4]byte +} + +type ExternProc struct { + P_starttime Timeval + P_vmspace *Vmspace + P_sigacts uintptr + P_flag int32 + P_stat int8 + P_pid int32 + P_oppid int32 + P_dupfd int32 + User_stack *int8 + Exit_thread *byte + P_debugger int32 + Sigwait int32 + P_estcpu uint32 + P_cpticks int32 + P_pctcpu uint32 + P_wchan *byte + P_wmesg *int8 + P_swtime uint32 + P_slptime uint32 + P_realtimer Itimerval + P_rtime Timeval + P_uticks uint64 + P_sticks uint64 + P_iticks uint64 + P_traceflag int32 + P_tracep uintptr + P_siglist int32 + P_textvp uintptr + P_holdcnt int32 + P_sigmask uint32 + P_sigignore uint32 + P_sigcatch uint32 + P_priority uint8 + P_usrpri uint8 + P_nice int8 + P_comm [17]int8 + P_pgrp uintptr + P_addr uintptr + P_xstat uint16 + P_acflag uint16 + P_ru *Rusage +} + +type Itimerval struct { + Interval Timeval + Value Timeval +} + +type KinfoProc struct { + Proc ExternProc + Eproc Eproc +} + +type Vmspace struct { + Dummy int32 + Dummy2 *int8 + Dummy3 [5]int32 + Dummy4 [3]*int8 +} + +type Pcred struct { + Pc_lock [72]int8 + Pc_ucred uintptr + P_ruid uint32 + P_svuid uint32 + P_rgid uint32 + P_svgid uint32 + P_refcnt int32 + _ [4]byte +} + +type Ucred struct { + Ref int32 + Uid uint32 + Ngroups int16 + Groups [16]uint32 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go index 1d049d7a1..d0ba8e9b8 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go @@ -431,6 +431,9 @@ type Winsize struct { const ( AT_FDCWD = 0xfffafdcd AT_SYMLINK_NOFOLLOW = 0x1 + AT_REMOVEDIR = 0x2 + AT_EACCESS = 0x4 + AT_SYMLINK_FOLLOW = 0x8 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go index c51bc88ff..1f99c024a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go @@ -672,9 +672,10 @@ type Winsize struct { const ( AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x800 - AT_SYMLINK_FOLLOW = 0x400 + AT_EACCESS = 0x100 AT_SYMLINK_NOFOLLOW = 0x200 + AT_SYMLINK_FOLLOW = 0x400 + AT_REMOVEDIR = 0x800 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go index 395b69187..ddf0305a5 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go @@ -675,9 +675,10 @@ type Winsize struct { const ( AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x800 - AT_SYMLINK_FOLLOW = 0x400 + AT_EACCESS = 0x100 AT_SYMLINK_NOFOLLOW = 0x200 + AT_SYMLINK_FOLLOW = 0x400 + AT_REMOVEDIR = 0x800 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go index d3f9d2541..dce0a5c80 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go @@ -656,9 +656,10 @@ type Winsize struct { const ( AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x800 - AT_SYMLINK_FOLLOW = 0x400 + AT_EACCESS = 0x100 AT_SYMLINK_NOFOLLOW = 0x200 + AT_SYMLINK_FOLLOW = 0x400 + AT_REMOVEDIR = 0x800 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go index 434d6e8e8..e23244702 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go @@ -653,9 +653,10 @@ type Winsize struct { const ( AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x800 - AT_SYMLINK_FOLLOW = 0x400 + AT_EACCESS = 0x100 AT_SYMLINK_NOFOLLOW = 0x200 + AT_SYMLINK_FOLLOW = 0x400 + AT_REMOVEDIR = 0x800 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go index b10e73abf..2fd2060e6 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go @@ -445,8 +445,10 @@ type Ptmget struct { const ( AT_FDCWD = -0x64 - AT_SYMLINK_FOLLOW = 0x400 + AT_EACCESS = 0x100 AT_SYMLINK_NOFOLLOW = 0x200 + AT_SYMLINK_FOLLOW = 0x400 + AT_REMOVEDIR = 0x800 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go index 28ed6d55a..6a5a1a8ae 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go @@ -453,8 +453,10 @@ type Ptmget struct { const ( AT_FDCWD = -0x64 - AT_SYMLINK_FOLLOW = 0x400 + AT_EACCESS = 0x100 AT_SYMLINK_NOFOLLOW = 0x200 + AT_SYMLINK_FOLLOW = 0x400 + AT_REMOVEDIR = 0x800 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go index 4ba196ebe..84cc8d01e 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go @@ -450,8 +450,10 @@ type Ptmget struct { const ( AT_FDCWD = -0x64 - AT_SYMLINK_FOLLOW = 0x400 + AT_EACCESS = 0x100 AT_SYMLINK_NOFOLLOW = 0x200 + AT_SYMLINK_FOLLOW = 0x400 + AT_REMOVEDIR = 0x800 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go index dd642bd9c..c844e7096 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go @@ -453,8 +453,10 @@ type Ptmget struct { const ( AT_FDCWD = -0x64 - AT_SYMLINK_FOLLOW = 0x400 + AT_EACCESS = 0x100 AT_SYMLINK_NOFOLLOW = 0x200 + AT_SYMLINK_FOLLOW = 0x400 + AT_REMOVEDIR = 0x800 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go index 1fdb0e5fa..2a8b1e6f7 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go @@ -438,8 +438,10 @@ type Winsize struct { const ( AT_FDCWD = -0x64 - AT_SYMLINK_FOLLOW = 0x4 + AT_EACCESS = 0x1 AT_SYMLINK_NOFOLLOW = 0x2 + AT_SYMLINK_FOLLOW = 0x4 + AT_REMOVEDIR = 0x8 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go index e2fc93c7c..b1759cf70 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go @@ -438,8 +438,10 @@ type Winsize struct { const ( AT_FDCWD = -0x64 - AT_SYMLINK_FOLLOW = 0x4 + AT_EACCESS = 0x1 AT_SYMLINK_NOFOLLOW = 0x2 + AT_SYMLINK_FOLLOW = 0x4 + AT_REMOVEDIR = 0x8 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go index 8d34b5a2f..e807de206 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go @@ -439,8 +439,10 @@ type Winsize struct { const ( AT_FDCWD = -0x64 - AT_SYMLINK_FOLLOW = 0x4 + AT_EACCESS = 0x1 AT_SYMLINK_NOFOLLOW = 0x2 + AT_SYMLINK_FOLLOW = 0x4 + AT_REMOVEDIR = 0x8 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go index ea8f1a0d9..ff3aecaee 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go @@ -432,8 +432,10 @@ type Winsize struct { const ( AT_FDCWD = -0x64 - AT_SYMLINK_FOLLOW = 0x4 + AT_EACCESS = 0x1 AT_SYMLINK_NOFOLLOW = 0x2 + AT_SYMLINK_FOLLOW = 0x4 + AT_REMOVEDIR = 0x8 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go index ec6e8bc3f..9ecda6917 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go @@ -432,8 +432,10 @@ type Winsize struct { const ( AT_FDCWD = -0x64 - AT_SYMLINK_FOLLOW = 0x4 + AT_EACCESS = 0x1 AT_SYMLINK_NOFOLLOW = 0x2 + AT_SYMLINK_FOLLOW = 0x4 + AT_REMOVEDIR = 0x8 ) type PollFd struct { diff --git a/vendor/modules.txt b/vendor/modules.txt index 623a40e4c..6b0eb5244 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -9,7 +9,7 @@ github.com/Microsoft/go-winio/backuptar github.com/Microsoft/go-winio/pkg/guid github.com/Microsoft/go-winio/pkg/security github.com/Microsoft/go-winio/vhd -# github.com/Microsoft/hcsshim v0.8.17 +# github.com/Microsoft/hcsshim v0.8.20 github.com/Microsoft/hcsshim github.com/Microsoft/hcsshim/computestorage github.com/Microsoft/hcsshim/internal/cow @@ -46,9 +46,9 @@ github.com/buger/goterm github.com/cespare/xxhash/v2 # github.com/checkpoint-restore/checkpointctl v0.0.0-20210301084134-a2024f5584e7 github.com/checkpoint-restore/checkpointctl/lib -# github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b -github.com/checkpoint-restore/go-criu -github.com/checkpoint-restore/go-criu/rpc +# github.com/checkpoint-restore/go-criu/v5 v5.1.0 +github.com/checkpoint-restore/go-criu/v5 +github.com/checkpoint-restore/go-criu/v5/rpc # github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e github.com/chzyer/readline # github.com/container-orchestrated-devices/container-device-interface v0.0.0-20210325223243-f99e8b6c10b9 @@ -77,7 +77,7 @@ github.com/containernetworking/plugins/pkg/utils/hwaddr github.com/containernetworking/plugins/pkg/utils/sysctl github.com/containernetworking/plugins/plugins/ipam/host-local/backend github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator -# github.com/containers/buildah v1.21.1-0.20210628174543-eadb10a12336 +# github.com/containers/buildah v1.21.1-0.20210721171232-54cafea4c933 github.com/containers/buildah github.com/containers/buildah/bind github.com/containers/buildah/chroot @@ -93,7 +93,7 @@ github.com/containers/buildah/pkg/overlay github.com/containers/buildah/pkg/parse github.com/containers/buildah/pkg/rusage github.com/containers/buildah/util -# github.com/containers/common v0.40.2-0.20210702074932-9d34b37ba77e +# github.com/containers/common v0.41.1-0.20210721172332-291287e9d060 github.com/containers/common/libimage github.com/containers/common/libimage/manifests github.com/containers/common/pkg/apparmor @@ -125,7 +125,7 @@ github.com/containers/common/pkg/umask github.com/containers/common/version # github.com/containers/conmon v2.0.20+incompatible github.com/containers/conmon/runner/config -# github.com/containers/image/v5 v5.13.2 +# github.com/containers/image/v5 v5.14.0 github.com/containers/image/v5/copy github.com/containers/image/v5/directory github.com/containers/image/v5/directory/explicitfilepath @@ -197,7 +197,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.32.5 +# github.com/containers/storage v1.33.0 github.com/containers/storage github.com/containers/storage/drivers github.com/containers/storage/drivers/aufs @@ -213,6 +213,9 @@ github.com/containers/storage/drivers/windows github.com/containers/storage/drivers/zfs github.com/containers/storage/pkg/archive github.com/containers/storage/pkg/chrootarchive +github.com/containers/storage/pkg/chunked +github.com/containers/storage/pkg/chunked/compressor +github.com/containers/storage/pkg/chunked/internal github.com/containers/storage/pkg/config github.com/containers/storage/pkg/devicemapper github.com/containers/storage/pkg/directory @@ -370,7 +373,7 @@ github.com/google/go-intervals/intervalset github.com/google/gofuzz # github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf github.com/google/shlex -# github.com/google/uuid v1.2.0 +# github.com/google/uuid v1.3.0 github.com/google/uuid # github.com/gorilla/mux v1.8.0 github.com/gorilla/mux @@ -503,7 +506,7 @@ github.com/opencontainers/go-digest # github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 -# github.com/opencontainers/runc v1.0.0 +# github.com/opencontainers/runc v1.0.1 github.com/opencontainers/runc/libcontainer/apparmor github.com/opencontainers/runc/libcontainer/cgroups github.com/opencontainers/runc/libcontainer/configs @@ -607,7 +610,7 @@ github.com/vbauerster/mpb/v6 github.com/vbauerster/mpb/v6/cwriter github.com/vbauerster/mpb/v6/decor github.com/vbauerster/mpb/v6/internal -# github.com/vbauerster/mpb/v7 v7.0.2 +# github.com/vbauerster/mpb/v7 v7.0.3 github.com/vbauerster/mpb/v7 github.com/vbauerster/mpb/v7/cwriter github.com/vbauerster/mpb/v7/decor @@ -669,7 +672,7 @@ golang.org/x/net/proxy golang.org/x/net/trace # golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sync/semaphore -# golang.org/x/sys v0.0.0-20210603125802-9665404d3644 +# golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 golang.org/x/sys/cpu golang.org/x/sys/execabs golang.org/x/sys/internal/unsafeheader @@ -793,10 +796,10 @@ gopkg.in/tomb.v1 gopkg.in/yaml.v2 # gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b gopkg.in/yaml.v3 -# k8s.io/api v0.21.2 +# k8s.io/api v0.21.3 k8s.io/api/apps/v1 k8s.io/api/core/v1 -# k8s.io/apimachinery v0.21.2 +# k8s.io/apimachinery v0.21.3 k8s.io/apimachinery/pkg/api/resource k8s.io/apimachinery/pkg/apis/meta/v1 k8s.io/apimachinery/pkg/conversion @@ -820,5 +823,5 @@ k8s.io/apimachinery/pkg/watch k8s.io/apimachinery/third_party/forked/golang/reflect # k8s.io/klog/v2 v2.8.0 k8s.io/klog/v2 -# sigs.k8s.io/structured-merge-diff/v4 v4.1.0 +# sigs.k8s.io/structured-merge-diff/v4 v4.1.2 sigs.k8s.io/structured-merge-diff/v4/value |