summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml3
-rw-r--r--.github/workflows/stale.yml1
-rw-r--r--CONTRIBUTING.md12
-rw-r--r--Makefile5
-rw-r--r--README.md2
-rw-r--r--RELEASE_NOTES.md11
-rw-r--r--changelog.txt29
-rw-r--r--cmd/podman/common/create.go2
-rw-r--r--cmd/podman/containers/stats.go56
-rw-r--r--cmd/podman/images/build.go1
-rw-r--r--cmd/podman/images/save.go7
-rw-r--r--cmd/podman/pods/ps.go2
-rw-r--r--cmd/podman/root.go2
-rw-r--r--cmd/podman/system/version.go2
-rw-r--r--contrib/rootless-cni-infra/Containerfile2
-rwxr-xr-xcontrib/rootless-cni-infra/rootless-cni-infra18
-rw-r--r--contrib/spec/podman.spec.in2
-rw-r--r--docs/source/markdown/podman-create.1.md13
-rw-r--r--docs/source/markdown/podman-load.1.md4
-rw-r--r--docs/source/markdown/podman-run.1.md14
-rw-r--r--go.mod8
-rw-r--r--go.sum47
-rwxr-xr-xhack/release.sh2
-rw-r--r--libpod/define/info.go1
-rw-r--r--libpod/define/version.go10
-rw-r--r--libpod/info.go1
-rw-r--r--libpod/oci_conmon_exec_linux.go27
-rw-r--r--libpod/oci_conmon_linux.go31
-rw-r--r--libpod/rootless_cni_linux.go2
-rw-r--r--pkg/api/handlers/compat/containers.go25
-rw-r--r--pkg/api/handlers/compat/containers_create.go2
-rw-r--r--pkg/api/handlers/compat/containers_stats.go43
-rw-r--r--pkg/api/handlers/libpod/containers_stats.go72
-rw-r--r--pkg/api/handlers/libpod/images_pull.go9
-rw-r--r--pkg/api/handlers/types.go2
-rw-r--r--pkg/api/server/handler_api.go17
-rw-r--r--pkg/api/server/register_containers.go31
-rw-r--r--pkg/bindings/bindings.go2
-rw-r--r--pkg/bindings/containers/containers.go51
-rw-r--r--pkg/bindings/images/pull.go1
-rw-r--r--pkg/bindings/system/system.go10
-rw-r--r--pkg/bindings/test/images_test.go8
-rw-r--r--pkg/domain/entities/containers.go19
-rw-r--r--pkg/domain/entities/engine_container.go2
-rw-r--r--pkg/domain/entities/images.go2
-rw-r--r--pkg/domain/infra/abi/containers.go116
-rw-r--r--pkg/domain/infra/abi/images.go9
-rw-r--r--pkg/domain/infra/abi/system_varlink.go2
-rw-r--r--pkg/domain/infra/tunnel/containers.go108
-rw-r--r--pkg/domain/infra/tunnel/events.go32
-rw-r--r--pkg/domain/infra/tunnel/helpers.go4
-rw-r--r--pkg/domain/infra/tunnel/images.go7
-rw-r--r--pkg/hooks/1.0.0/hook.go9
-rw-r--r--pkg/hooks/hooks.go6
-rw-r--r--pkg/specgen/generate/storage.go4
-rw-r--r--pkg/systemd/generate/containers.go2
-rw-r--r--pkg/systemd/generate/pods.go2
-rw-r--r--pkg/varlinkapi/system.go8
-rw-r--r--test/apiv2/20-containers.at25
-rw-r--r--test/apiv2/rest_api/test_rest_v2_0_0.py246
-rw-r--r--test/e2e/attach_test.go10
-rw-r--r--test/e2e/build_test.go6
-rw-r--r--test/e2e/commit_test.go2
-rw-r--r--test/e2e/common_test.go1
-rw-r--r--test/e2e/config.go4
-rw-r--r--test/e2e/cp_test.go2
-rw-r--r--test/e2e/create_test.go7
-rw-r--r--test/e2e/exec_test.go17
-rw-r--r--test/e2e/healthcheck_run_test.go1
-rw-r--r--test/e2e/images_test.go8
-rw-r--r--test/e2e/info_test.go2
-rw-r--r--test/e2e/init_test.go2
-rw-r--r--test/e2e/inspect_test.go4
-rw-r--r--test/e2e/kill_test.go9
-rw-r--r--test/e2e/libpod_suite_remote_test.go11
-rw-r--r--test/e2e/libpod_suite_test.go12
-rw-r--r--test/e2e/libpod_suite_varlink_test.go11
-rw-r--r--test/e2e/load_test.go20
-rw-r--r--test/e2e/logs_test.go2
-rw-r--r--test/e2e/manifest_test.go5
-rw-r--r--test/e2e/mount_test.go23
-rw-r--r--test/e2e/namespace_test.go2
-rw-r--r--test/e2e/network_create_test.go3
-rw-r--r--test/e2e/play_kube_test.go10
-rw-r--r--test/e2e/pod_create_test.go13
-rw-r--r--test/e2e/pod_infra_container_test.go7
-rw-r--r--test/e2e/pod_kill_test.go7
-rw-r--r--test/e2e/pod_pod_namespaces.go2
-rw-r--r--test/e2e/pod_ps_test.go10
-rw-r--r--test/e2e/pod_restart_test.go7
-rw-r--r--test/e2e/pod_rm_test.go9
-rw-r--r--test/e2e/pod_start_test.go7
-rw-r--r--test/e2e/pod_stop_test.go7
-rw-r--r--test/e2e/pod_top_test.go6
-rw-r--r--test/e2e/port_test.go20
-rw-r--r--test/e2e/prune_test.go6
-rw-r--r--test/e2e/ps_test.go2
-rw-r--r--test/e2e/pull_test.go8
-rw-r--r--test/e2e/restart_test.go7
-rw-r--r--test/e2e/rm_test.go11
-rw-r--r--test/e2e/rmi_test.go4
-rw-r--r--test/e2e/run_cleanup_test.go2
-rw-r--r--test/e2e/run_entrypoint_test.go7
-rw-r--r--test/e2e/run_env_test.go4
-rw-r--r--test/e2e/run_networking_test.go2
-rw-r--r--test/e2e/run_passwd_test.go2
-rw-r--r--test/e2e/run_restart_test.go2
-rw-r--r--test/e2e/run_security_labels.go2
-rw-r--r--test/e2e/run_test.go190
-rw-r--r--test/e2e/run_volume_test.go9
-rw-r--r--test/e2e/run_working_dir.go2
-rw-r--r--test/e2e/runlabel_test.go3
-rw-r--r--test/e2e/search_test.go9
-rw-r--r--test/e2e/start_test.go7
-rw-r--r--test/e2e/stats_test.go2
-rw-r--r--test/e2e/stop_test.go13
-rw-r--r--test/e2e/system_df_test.go2
-rw-r--r--test/e2e/system_reset_test.go2
-rw-r--r--test/e2e/systemd_test.go2
-rw-r--r--test/e2e/unshare_test.go2
-rw-r--r--test/e2e/untag_test.go2
-rw-r--r--test/e2e/version_test.go6
-rw-r--r--test/system/005-info.bats4
-rw-r--r--test/system/030-run.bats55
-rw-r--r--test/system/120-load.bats41
-rw-r--r--test/system/helpers.bash7
-rwxr-xr-xtest/system/helpers.t9
-rw-r--r--vendor/github.com/containers/buildah/CHANGELOG.md3
-rw-r--r--vendor/github.com/containers/buildah/add.go14
-rw-r--r--vendor/github.com/containers/buildah/buildah.go2
-rw-r--r--vendor/github.com/containers/buildah/changelog.txt2
-rw-r--r--vendor/github.com/containers/image/v5/oci/archive/oci_transport.go7
-rw-r--r--vendor/github.com/containers/image/v5/version/version.go6
-rw-r--r--vendor/github.com/moby/sys/mountinfo/doc.go47
-rw-r--r--vendor/github.com/moby/sys/mountinfo/go.mod2
-rw-r--r--vendor/github.com/moby/sys/mountinfo/go.sum2
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mounted_linux.go58
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mounted_unix.go66
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mountinfo.go23
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go4
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go12
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go76
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go8
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go4
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux.go6
-rw-r--r--vendor/golang.org/x/sys/unix/zsyscall_linux.go16
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux.go16
-rw-r--r--vendor/golang.org/x/sys/windows/syscall_windows.go1
-rw-r--r--vendor/golang.org/x/sys/windows/types_windows.go12
-rw-r--r--vendor/golang.org/x/sys/windows/types_windows_386.go13
-rw-r--r--vendor/golang.org/x/sys/windows/types_windows_amd64.go12
-rw-r--r--vendor/golang.org/x/sys/windows/types_windows_arm.go13
-rw-r--r--vendor/golang.org/x/sys/windows/zsyscall_windows.go13
-rw-r--r--vendor/modules.txt10
-rw-r--r--version/version.go8
155 files changed, 1823 insertions, 521 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index a11bbbe61..d2a8cb660 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -39,7 +39,7 @@ env:
UBUNTU_NAME: "ubuntu"
PRIOR_UBUNTU_NAME: "prior-ubuntu"
- _BUILT_IMAGE_SUFFIX: "c5809900649447424"
+ _BUILT_IMAGE_SUFFIX: "c6110627968057344"
FEDORA_CACHE_IMAGE_NAME: "${FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "${PRIOR_FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}"
UBUNTU_CACHE_IMAGE_NAME: "${UBUNTU_NAME}-${_BUILT_IMAGE_SUFFIX}"
@@ -123,6 +123,7 @@ gating_task:
# N/B: need 'clean' so some committed files are re-generated.
- '/usr/local/bin/entrypoint.sh clean podman-remote |& ${TIMESTAMP}'
- '/usr/local/bin/entrypoint.sh clean podman xref_helpmsgs_manpages BUILDTAGS="exclude_graphdriver_devicemapper selinux seccomp" |& ${TIMESTAMP}'
+ - '/usr/local/bin/entrypoint.sh clean BUILDTAGS="varlink" binaries |& ${TIMESTAMP}'
- '/usr/local/bin/entrypoint.sh local-cross |& ${TIMESTAMP}'
# Verify some aspects of ci/related scripts
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 5e5a75713..8fd51b5e9 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -22,3 +22,4 @@ jobs:
stale-pr-label: 'stale-pr'
days-before-stale: 30
days-before-close: 365
+ remove-stale-when-updated: true
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index dc48b389e..ba321921c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -7,6 +7,7 @@ that we follow.
## Topics
* [Reporting Issues](#reporting-issues)
+* [Working On Issues](#working-on-issues)
* [Contributing to Podman](#contributing-to-podman)
* [Continuous Integration](#continuous-integration) [![Build Status](https://api.cirrus-ci.com/github/containers/podman.svg)](https://cirrus-ci.com/github/containers/podman/master)
* [Submitting Pull Requests](#submitting-pull-requests)
@@ -28,6 +29,17 @@ The easier it is for us to reproduce it, the faster it'll be fixed!
Please don't include any private/sensitive information in your issue!
+## Working On Issues
+
+Once you have decided to contribute to Podman by working on an issue, check our
+backlog of [open issues](https://github.com/containers/podman/issues) looking
+for any that do not have an "In Progress" label attached to it. Often issues
+will be assigned to someone, to be worked on at a later time. If you have the
+time to work on the issue now add yourself as an assignee, and set the
+"In Progress" label if you’re a member of the “Containers” GitHub organization.
+If you can not set the label, just add a quick comment in the issue asking that
+the “In Progress” label be set and a member will do so for you.
+
## Contributing to Podman
This section describes how to start a contribution to Podman.
diff --git a/Makefile b/Makefile
index 253207f49..8a75c11fb 100644
--- a/Makefile
+++ b/Makefile
@@ -135,8 +135,13 @@ export PRINT_HELP_PYSCRIPT
err_if_empty = $(if $(strip $($(1))),$(strip $($(1))),$(error Required variable $(1) value is undefined, whitespace, or empty))
.PHONY: help
+ifneq (, ${PYTHON})
help:
@$(PYTHON) -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)
+else
+help:
+ $(error python required for 'make help', executable not found)
+endif
.gopathok:
ifeq ("$(wildcard $(GOPKGDIR))","")
diff --git a/README.md b/README.md
index 5a316f170..891d712c8 100644
--- a/README.md
+++ b/README.md
@@ -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: 2.0.6](https://github.com/containers/podman/releases/latest)
+* [Latest Version: 2.1.0](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 f3ac50a59..cabfafabb 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -15,6 +15,7 @@
- The `podman play kube` command now supports the Socket HostPath type ([#7112](https://github.com/containers/podman/issues/7112)).
- The `podman play kube` command now supports read-only mounts.
- The `podman play kube` command now supports setting labels on pods from Kubernetes metadata labels.
+- The `podman play kube` command now supports setting container restart policy ([#7656](https://github.com/containers/podman/issues/7656)).
- The `podman play kube` command now properly handles `HostAlias` entries.
- The `podman generate kube` command now adds entries to `/etc/hosts` from `--host-add` generated YAML as `HostAlias` entries.
- The `podman play kube` and `podman generate kube` commands now properly support `shareProcessNamespace` to share the PID namespace in pods.
@@ -29,6 +30,9 @@
- A new global option has been added to Podman, `--runtime-flags`, which allows for setting flags to use when the OCI runtime is called.
- The `podman manifest add` command now supports the `--cert-dir`, `--auth-file`, `--creds`, and `--tls-verify` options.
+### Security
+- This release resolves CVE-2020-14370, in which environment variables could be leaked between containers created using the Varlink API.
+
### Changes
- Podman will now retry pulling an image 3 times if a pull fails due to network errors.
- The `podman exec` command would previously print error messages (e.g. `exec session exited with non-zero exit code -1`) when the command run exited with a non-0 exit code. It no longer does this. The `podman exec` command will still exit with the same exit code as the command run in the container did.
@@ -72,8 +76,12 @@
- Fixed a bug where the `--infra-command` parameter to `podman pod create` was nonfunctional.
- Fixed a bug where `podman auto-update` would fail for any container started with `--pull=always` ([#7407](https://github.com/containers/podman/issues/7407)).
- Fixed a bug where the `podman wait` command would only accept a single argument.
+- Fixed a bug where the parsing of the `--volumes-from` option to `podman run` and `podman create` was broken, making it impossible to use multiple mount options at the same time ([#7701](https://github.com/containers/podman/issues/7701)).
+- Fixed a bug where the `podman exec` command would not join executed processes to the container's supplemental groups if the container was started with both the `--user` and `--group-add` options.
+- Fixed a bug where the `--iidfile` option to `podman-remote build` was nonfunctional.
### API
+- The Libpod API version has been bumped to v2.0.0 due to a breaking change in the Image List API.
- Docker-compatible Volume Endpoints (Create, Inspect, List, Remove, Prune) are now available!
- Added an endpoint for generating systemd unit files for containers.
- The `last` parameter to the Libpod container list endpoint now has an alias, `limit` ([#6413](https://github.com/containers/podman/issues/6413)).
@@ -96,6 +104,9 @@
- All non-hijacking responses to API requests should not include headers with the version of the server.
- Fixed a bug where Libpod and Compat Events endpoints did not send response headers until the first event occurred ([#7263](https://github.com/containers/podman/issues/7263)).
- Fixed a bug where the Build endpoints (Compat and Libpod) did not stream progress to the client.
+- Fixed a bug where the Stats endpoints (Compat and Libpod) did not properly handle clients disconnecting.
+- Fixed a bug where the Ignore parameter to the Libpod Stop endpoint was not performing properly.
+- Fixed a bug where the Compat Logs endpoint for containers did not stream its output in the correct format ([#7196](https://github.com/containers/podman/issues/7196)).
### Misc
- Updated Buildah to v1.16.1
diff --git a/changelog.txt b/changelog.txt
index b98e91d63..0ec721996 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,32 @@
+- Changelog for v2.1.0 (2020-09-22):
+ * Update release notes for v2.1.0 Final Release
+ * Fix up attach tests for podman remote
+ * update stale bot
+ * [CI:DOCS] Add 'In Progress' note to CONTRIBUTING.md
+ * Restore 'id' stanza in pull results
+ * Fix podman image unmount to only report images unmounted
+ * libpod: bumps up rootless-cni-infra to 2
+ * stats: log errors instead of sending 500
+ * Fix incorrect parsing of create/run --volumes-from
+ * rootless-cni-infra: fix flakiness during bringing up lo interface
+ * Fix handling of podman-remote stop --ignore
+ * Refactor version handling in cmd tree
+ * Preserve groups in exec sessions in ctrs with --user
+ * Install bats as root
+ * Makefile: Fix broken libpodimage targets
+ * stats: detect closed client connection
+ * stats endpoint: write OK header once
+ * handle the play kube and generate kube for with restartPolicy
+ * fix the .Path and .Args when use the infra-command
+ * Update nix pin with `make nixpkgs`
+ * fix a typo of login.1.md
+ * Bump github.com/rootless-containers/rootlesskit from 0.10.0 to 0.10.1
+ * enable --iidfile for podman-remote build
+ * update github.com/docker/docker and relevant deps
+ * Make Go builds more consistent
+ * dependabot-dance: new tool for managing revendor PRs
+ * WIP: Fix remote logs
+
- Changelog for v2.1.0-rc2 (2020-09-17)
* Update release notes for Podman v2.1.0-RC2
* Fix play_kube_test deployment template
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index cfbcf6140..7e3dc7fb4 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -509,7 +509,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
"volume", "v", containerConfig.Volumes(),
"Bind mount a volume into the container",
)
- createFlags.StringSliceVar(
+ createFlags.StringArrayVar(
&cf.VolumesFrom,
"volumes-from", []string{},
"Mount volumes from the specified container(s)",
diff --git a/cmd/podman/containers/stats.go b/cmd/podman/containers/stats.go
index ddb5f32ef..bbd389bbf 100644
--- a/cmd/podman/containers/stats.go
+++ b/cmd/podman/containers/stats.go
@@ -4,7 +4,6 @@ import (
"fmt"
"os"
"strings"
- "sync"
"text/tabwriter"
"text/template"
@@ -48,8 +47,18 @@ var (
}
)
+// statsOptionsCLI is used for storing CLI arguments. Some fields are later
+// used in the backend.
+type statsOptionsCLI struct {
+ All bool
+ Format string
+ Latest bool
+ NoReset bool
+ NoStream bool
+}
+
var (
- statsOptions entities.ContainerStatsOptions
+ statsOptions statsOptionsCLI
defaultStatsRow = "{{.ID}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDS}}\n"
defaultStatsHeader = "ID\tNAME\tCPU %\tMEM USAGE / LIMIT\tMEM %\tNET IO\tBLOCK IO\tPIDS\n"
)
@@ -107,32 +116,37 @@ func stats(cmd *cobra.Command, args []string) error {
return errors.New("stats is not supported in rootless mode without cgroups v2")
}
}
- statsOptions.StatChan = make(chan []*define.ContainerStats, 1)
- wg := sync.WaitGroup{}
- wg.Add(1)
- go func() {
- for reports := range statsOptions.StatChan {
- if err := outputStats(reports); err != nil {
- logrus.Error(err)
- }
- }
- wg.Done()
- }()
- err := registry.ContainerEngine().ContainerStats(registry.Context(), args, statsOptions)
- wg.Wait()
- return err
+ // Convert to the entities options. We should not leak CLI-only
+ // options into the backend and separate concerns.
+ opts := entities.ContainerStatsOptions{
+ Latest: statsOptions.Latest,
+ Stream: !statsOptions.NoStream,
+ }
+ statsChan, err := registry.ContainerEngine().ContainerStats(registry.Context(), args, opts)
+ if err != nil {
+ return err
+ }
+ for report := range statsChan {
+ if report.Error != nil {
+ return report.Error
+ }
+ if err := outputStats(report.Stats); err != nil {
+ logrus.Error(err)
+ }
+ }
+ return nil
}
-func outputStats(reports []*define.ContainerStats) error {
+func outputStats(reports []define.ContainerStats) error {
if len(statsOptions.Format) < 1 && !statsOptions.NoReset {
tm.Clear()
tm.MoveCursor(1, 1)
tm.Flush()
}
- stats := make([]*containerStats, 0, len(reports))
+ stats := make([]containerStats, 0, len(reports))
for _, r := range reports {
- stats = append(stats, &containerStats{r})
+ stats = append(stats, containerStats{r})
}
if statsOptions.Format == "json" {
return outputJSON(stats)
@@ -163,7 +177,7 @@ func outputStats(reports []*define.ContainerStats) error {
}
type containerStats struct {
- *define.ContainerStats
+ define.ContainerStats
}
func (s *containerStats) ID() string {
@@ -213,7 +227,7 @@ func combineHumanValues(a, b uint64) string {
return fmt.Sprintf("%s / %s", units.HumanSize(float64(a)), units.HumanSize(float64(b)))
}
-func outputJSON(stats []*containerStats) error {
+func outputJSON(stats []containerStats) error {
type jstat struct {
Id string `json:"id"` //nolint
Name string `json:"name"`
diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go
index 00777c48c..d24bb18b6 100644
--- a/cmd/podman/images/build.go
+++ b/cmd/podman/images/build.go
@@ -436,6 +436,7 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil
Quiet: flags.Quiet,
RemoveIntermediateCtrs: flags.Rm,
ReportWriter: reporter,
+ Runtime: containerConfig.RuntimePath,
RuntimeArgs: runtimeFlags,
SignBy: flags.SignBy,
SignaturePolicyPath: flags.SignaturePolicy,
diff --git a/cmd/podman/images/save.go b/cmd/podman/images/save.go
index c57f61221..b164a2534 100644
--- a/cmd/podman/images/save.go
+++ b/cmd/podman/images/save.go
@@ -94,6 +94,7 @@ func save(cmd *cobra.Command, args []string) (finalErr error) {
return errors.Errorf("--compress can only be set when --format is either 'oci-dir' or 'docker-dir'")
}
if len(saveOpts.Output) == 0 {
+ saveOpts.Quiet = true
fi := os.Stdout
if terminal.IsTerminal(int(fi.Fd())) {
return errors.Errorf("refusing to save to terminal. Use -o flag or redirect")
@@ -122,12 +123,6 @@ func save(cmd *cobra.Command, args []string) (finalErr error) {
tags = args[1:]
}
- // Decide whether c/image's progress bars should use stderr or stdout.
- // If the output is set of stdout, any log message there would corrupt
- // the tarfile.
- if saveOpts.Output == os.Stdout.Name() {
- saveOpts.Quiet = true
- }
err := registry.ImageEngine().Save(context.Background(), args[0], tags, saveOpts)
if err == nil {
succeeded = true
diff --git a/cmd/podman/pods/ps.go b/cmd/podman/pods/ps.go
index 97e528c7c..7b755cb22 100644
--- a/cmd/podman/pods/ps.go
+++ b/cmd/podman/pods/ps.go
@@ -73,7 +73,7 @@ func pods(cmd *cobra.Command, _ []string) error {
if cmd.Flag("filter").Changed {
psInput.Filters = make(map[string][]string)
for _, f := range inputFilters {
- split := strings.Split(f, "=")
+ split := strings.SplitN(f, "=", 2)
if len(split) < 2 {
return errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f)
}
diff --git a/cmd/podman/root.go b/cmd/podman/root.go
index 8def7112f..6424ec12e 100644
--- a/cmd/podman/root.go
+++ b/cmd/podman/root.go
@@ -63,7 +63,7 @@ var (
PersistentPreRunE: persistentPreRunE,
RunE: validate.SubCommandExists,
PersistentPostRunE: persistentPostRunE,
- Version: version.Version,
+ Version: version.Version.String(),
}
logLevels = []string{"debug", "info", "warn", "error", "fatal", "panic"}
diff --git a/cmd/podman/system/version.go b/cmd/podman/system/version.go
index 5f39b4820..9da7da54a 100644
--- a/cmd/podman/system/version.go
+++ b/cmd/podman/system/version.go
@@ -83,7 +83,7 @@ func version(cmd *cobra.Command, args []string) error {
func formatVersion(writer io.Writer, version *define.Version) {
fmt.Fprintf(writer, "Version:\t%s\n", version.Version)
- fmt.Fprintf(writer, "API Version:\t%d\n", version.APIVersion)
+ fmt.Fprintf(writer, "API Version:\t%s\n", version.APIVersion)
fmt.Fprintf(writer, "Go Version:\t%s\n", version.GoVersion)
if version.GitCommit != "" {
fmt.Fprintf(writer, "Git Commit:\t%s\n", version.GitCommit)
diff --git a/contrib/rootless-cni-infra/Containerfile b/contrib/rootless-cni-infra/Containerfile
index 5be30ccc9..6bf70d644 100644
--- a/contrib/rootless-cni-infra/Containerfile
+++ b/contrib/rootless-cni-infra/Containerfile
@@ -34,4 +34,4 @@ COPY rootless-cni-infra /usr/local/bin
ENV CNI_PATH=/opt/cni/bin
CMD ["sleep", "infinity"]
-ENV ROOTLESS_CNI_INFRA_VERSION=1
+ENV ROOTLESS_CNI_INFRA_VERSION=2
diff --git a/contrib/rootless-cni-infra/rootless-cni-infra b/contrib/rootless-cni-infra/rootless-cni-infra
index f6622b23c..5cb43621d 100755
--- a/contrib/rootless-cni-infra/rootless-cni-infra
+++ b/contrib/rootless-cni-infra/rootless-cni-infra
@@ -4,6 +4,23 @@ set -eu
ARG0="$0"
BASE="/run/rootless-cni-infra"
+wait_unshare_net() {
+ pid="$1"
+ # NOTE: busybox shell doesn't support the `for ((i=0; i < $MAX; i++)); do foo; done` statement
+ i=0
+ while :; do
+ if [ "$(readlink /proc/self/ns/net)" != "$(readlink /proc/${pid}/ns/net)" ]; then
+ break
+ fi
+ sleep 0.1
+ if [ $i -ge 10 ]; then
+ echo >&2 "/proc/${pid}/ns/net cannot be unshared"
+ exit 1
+ fi
+ i=$((i + 1))
+ done
+}
+
# CLI subcommand: "alloc $CONTAINER_ID $NETWORK_NAME $POD_NAME"
cmd_entrypoint_alloc() {
if [ "$#" -ne 3 ]; then
@@ -24,6 +41,7 @@ cmd_entrypoint_alloc() {
else
unshare -n sleep infinity &
pid="$!"
+ wait_unshare_net "${pid}"
echo "${pid}" >"${dir}/pid"
nsenter -t "${pid}" -n ip link set lo up
fi
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index 363aa60d7..2e266b59f 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -42,7 +42,7 @@ Epoch: 99
%else
Epoch: 0
%endif
-Version: 2.1.0
+Version: 2.2.0
Release: #COMMITDATE#.git%{shortcommit0}%{?dist}
Summary: Manage Pods, Containers and Container Images
License: ASL 2.0
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index 9049ffb9f..4a8b311f0 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -1070,11 +1070,11 @@ change propagation properties of source mount. Say `/` is source mount for
**--volumes-from**[=*CONTAINER*[:*OPTIONS*]]
-Mount volumes from the specified container(s).
-*OPTIONS* is a comma delimited list with the following available elements:
+Mount volumes from the specified container(s). Used to share volumes between
+containers. The *options* is a comma delimited list with the following available elements:
-* [rw|ro]
-* z
+* **rw**|**ro**
+* **z**
Mounts already mounted volumes from a source container onto another
container. You must supply the source's container-id or container-name.
@@ -1083,9 +1083,8 @@ the target container. You can share volumes even if the source container
is not running.
By default, Podman mounts the volumes in the same mode (read-write or
-read-only) as it is mounted in the source container. Optionally, you
-can change this by suffixing the container-id with either the `ro` or
-`rw` keyword.
+read-only) as it is mounted in the source container.
+You can change this by adding a `ro` or `rw` _option_.
Labeling systems like SELinux require that proper labels are placed on volume
content mounted into a container. Without a label, the security system might
diff --git a/docs/source/markdown/podman-load.1.md b/docs/source/markdown/podman-load.1.md
index 917f102f6..308a3493b 100644
--- a/docs/source/markdown/podman-load.1.md
+++ b/docs/source/markdown/podman-load.1.md
@@ -9,9 +9,11 @@ podman\-load - Load an image from a container image archive into container stora
**podman image load** [*options*] [*name*[:*tag*]]
## DESCRIPTION
-**podman load** loads an image from either an **oci-archive** or **docker-archive** stored on the local machine into container storage. **podman load** reads from stdin by default or a file if the **input** option is set.
+**podman load** loads an image from either an **oci-archive** or a **docker-archive** stored on the local machine into container storage. **podman load** reads from stdin by default or a file if the **input** option is set.
You can also specify a name for the image if the archive does not contain a named reference, of if you want an additional name for the local image.
+The local client further supports loading an **oci-dir** or a **docker-dir** as created with **podman save** (1).
+
The **quiet** option suppresses the progress output when set.
Note: `:` is a restricted character and cannot be part of the file name.
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 1a7b36a5e..47aa8827f 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -1100,7 +1100,7 @@ will convert /foo into a shared mount point. Alternatively, one can directly
change propagation properties of source mount. Say, if _/_ is source mount for
_/foo_, then use **mount --make-shared /** to convert _/_ into a shared mount.
-**--volumes-from**[=*container-id*[:*options*]]
+**--volumes-from**[=*CONTAINER*[:*OPTIONS*]]
Mount volumes from the specified container(s). Used to share volumes between
containers. The *options* is a comma delimited list with the following available elements:
@@ -1108,19 +1108,23 @@ containers. The *options* is a comma delimited list with the following available
* **rw**|**ro**
* **z**
-You can share volumes even if the source container is not running.
+Mounts already mounted volumes from a source container onto another
+container. You must supply the source's container-id or container-name.
+To share a volume, use the --volumes-from option when running
+the target container. You can share volumes even if the source container
+is not running.
By default, Podman mounts the volumes in the same mode (read-write or
read-only) as it is mounted in the source container.
-You can change this by adding a **ro** or **rw** _option_.
+You can change this by adding a `ro` or `rw` _option_.
Labeling systems like SELinux require that proper labels are placed on volume
content mounted into a container. Without a label, the security system might
prevent the processes running inside the container from using the content. By
default, Podman does not change the labels set by the OS.
-To change a label in the container context, you can add **z** to the volume mount.
-This suffix tells Podman to relabel file objects on the shared volumes. The **z**
+To change a label in the container context, you can add `z` to the volume mount.
+This suffix tells Podman to relabel file objects on the shared volumes. The `z`
option tells Podman that two containers share the volume content. As a result,
podman labels the content with a shared content label. Shared volume labels allow
all containers to read/write content.
diff --git a/go.mod b/go.mod
index ce01ba5dc..9ef04fe28 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
github.com/containerd/containerd v1.4.1 // indirect
github.com/containernetworking/cni v0.8.0
github.com/containernetworking/plugins v0.8.7
- github.com/containers/buildah v1.16.1
+ github.com/containers/buildah v1.16.2
github.com/containers/common v0.22.0
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.6.0
@@ -49,7 +49,7 @@ require (
github.com/opentracing/opentracing-go v1.2.0
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.0
- github.com/rootless-containers/rootlesskit v0.10.0
+ github.com/rootless-containers/rootlesskit v0.10.1
github.com/sirupsen/logrus v1.6.0
github.com/spf13/cobra v0.0.7
github.com/spf13/pflag v1.0.5
@@ -63,10 +63,8 @@ require (
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
golang.org/x/net v0.0.0-20200707034311-ab3426394381
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
- golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a
+ golang.org/x/sys v0.0.0-20200909081042-eff7692f9009
k8s.io/api v0.0.0-20190620084959-7cf5895f2711
k8s.io/apimachinery v0.19.2
k8s.io/client-go v0.0.0-20190620085101-78d2af792bab
)
-
-replace github.com/containers/image/v5 => github.com/containers/image/v5 v5.5.2-0.20200902171422-1c313b2d23e0
diff --git a/go.sum b/go.sum
index 42024929d..8f109a329 100644
--- a/go.sum
+++ b/go.sum
@@ -52,9 +52,9 @@ github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmY
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
+github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.3.2 h1:ForxmXkA6tPIvffbrDAcPUIB32QgXkt2XFj+F0UxetA=
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.4.1 h1:pASeJT3R3YyVn+94qEPk0SnU1OQ20Jd/T+SPKy9xehY=
github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
@@ -70,21 +70,24 @@ github.com/containernetworking/cni v0.8.0 h1:BT9lpgGoH4jw3lFC7Odz2prU5ruiYKcgAjM
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
github.com/containernetworking/plugins v0.8.7 h1:bU7QieuAp+sACI2vCzESJ3FoT860urYP+lThyZkb/2M=
github.com/containernetworking/plugins v0.8.7/go.mod h1:R7lXeZaBzpfqapcAbHRW8/CYwm0dHzbz0XEjofx0uB0=
-github.com/containers/buildah v1.16.1 h1:kxxZbW0in7cFv/AEQtSPNQ06aemYN5fsya31IS9xd2g=
-github.com/containers/buildah v1.16.1/go.mod h1:i1XqXgpCROnfcq4oNtfrFEk7UzNDxLJ/PZ+CnPyoIq8=
+github.com/containers/buildah v1.16.2 h1:u8RA0r9sp3d5df/QRm0glG7L6ZN40UVJcYedwcZGt8w=
+github.com/containers/buildah v1.16.2/go.mod h1:i1XqXgpCROnfcq4oNtfrFEk7UzNDxLJ/PZ+CnPyoIq8=
github.com/containers/common v0.21.0/go.mod h1:8w8SVwc+P2p1MOnRMbSKNWXt1Iwd2bKFu2LLZx55DTM=
github.com/containers/common v0.22.0 h1:MjJIMka4pJddHsfZpQCF7jOmX6vXqMs0ojDeYmPKoSk=
github.com/containers/common v0.22.0/go.mod h1:qsLcLHM7ha5Nc+JDp5duBwfwEfrnlfjXL/K8HO96QHw=
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.5.2-0.20200902171422-1c313b2d23e0 h1:MJ0bKRn2I5I2NJlVzMU7/eP/9yfMCeWaUskl6zgY/nc=
-github.com/containers/image/v5 v5.5.2-0.20200902171422-1c313b2d23e0/go.mod h1:pBnp9KTyDqM84XTHwmk2lXRvTL6jayAQS47GC6PaPGM=
+github.com/containers/image/v5 v5.5.2/go.mod h1:4PyNYR0nwlGq/ybVJD9hWlhmIsNra4Q8uOQX2s6E2uM=
+github.com/containers/image/v5 v5.6.0 h1:r4AqIX4NO/X7OJkqX574zITV3fq0ZPn0pSlLsxWF6ww=
+github.com/containers/image/v5 v5.6.0/go.mod h1:iUSWo3SOLqJo0CkZkKrHxqR6YWqrT98mkXFpE0MceE8=
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.2/go.mod h1:nsOhbP19flrX6rE7ieGFvBlr7modwmNjsqWarIUce4M=
github.com/containers/ocicrypt v1.0.3 h1:vYgl+RZ9Q3DPMuTfxmN+qp0X2Bj52uuY2vnt6GzVe1c=
github.com/containers/ocicrypt v1.0.3/go.mod h1:CUBa+8MRNL/VkpxYIpaMtgn1WgXGyvPQj8jcy0EVG6g=
github.com/containers/psgo v1.5.1 h1:MQNb7FLbXqBdqz6u4lI2QWizVz4RSTzs1+Nk9XT1iVA=
github.com/containers/psgo v1.5.1/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzPUWfawVU=
+github.com/containers/storage v1.20.2/go.mod h1:oOB9Ie8OVPojvoaKWEGSEtHbXUAs+tSyr7RO7ZGteMc=
github.com/containers/storage v1.23.3/go.mod h1:0azTMiuBhArp/VUmH1o4DJAGaaH+qLtEu17pJ/iKJCg=
github.com/containers/storage v1.23.5 h1:He9I6y1vRVXYoQg4v2Q9HFAcX4dI3V5MCCrjeBcjkCY=
github.com/containers/storage v1.23.5/go.mod h1:ha26Q6ngehFNhf3AWoXldvAvwI4jFe3ETQAf/CeZPyM=
@@ -121,7 +124,6 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v1.4.2-0.20191219165747-a9416c67da9f h1:Sm8iD2lifO31DwXfkGzq8VgA7rwxPjRsYmeo0K/dF9Y=
github.com/docker/docker v1.4.2-0.20191219165747-a9416c67da9f/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v17.12.0-ce-rc1.0.20200917150144-3956a86b6235+incompatible h1:t8R9cQEpiP5dvTS73SdsVoRl34INIUHRSW3oL6SEUHU=
github.com/docker/docker v17.12.0-ce-rc1.0.20200917150144-3956a86b6235+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
@@ -154,6 +156,7 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsouza/go-dockerclient v1.6.5 h1:vuFDnPcds3LvTWGYb9h0Rty14FLgkjHZdwLDROCdgsw=
github.com/fsouza/go-dockerclient v1.6.5/go.mod h1:GOdftxWLWIbIWKbIMDroKFJzPdg6Iw7r+jX1DDZdVsA=
+github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -173,7 +176,7 @@ github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68Fp
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
+github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
@@ -232,6 +235,7 @@ github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FK
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -241,11 +245,12 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
+github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
-github.com/insomniacslk/dhcp v0.0.0-20200420235442-ed3125c2efe7/go.mod h1:CfMdguCK66I5DAUJgGKyNz8aB6vO5dZzkm9Xep6WGvw=
+github.com/insomniacslk/dhcp v0.0.0-20200806210722-3f14f7f8bd9c/go.mod h1:CfMdguCK66I5DAUJgGKyNz8aB6vO5dZzkm9Xep6WGvw=
github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07 h1:rw3IAne6CDuVFlZbPOkA7bhxlqawFh7RJJ+CejfMaxE=
github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
@@ -260,7 +265,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.10.11 h1:K9z59aO18Aywg2b/WSgBaUX99mHy2BES18Cr5lBKZHk=
+github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.10.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.10.11/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.0 h1:wJbzvpYMVGG9iTI9VxpnNZfd4DzMPoCWze3GgSqz8yg=
github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
@@ -278,6 +284,7 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
@@ -292,8 +299,9 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/moby/sys/mount v0.1.1 h1:mdhBytJ1SMmMat0gtzWWjFX/87K5j6E/7Q5z7rR0cZY=
github.com/moby/sys/mount v0.1.1/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74=
github.com/moby/sys/mountinfo v0.1.0/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o=
-github.com/moby/sys/mountinfo v0.1.3 h1:KIrhRO14+AkwKvG/g2yIpNMOUVZ02xNhOw8KY1WsLOI=
github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o=
+github.com/moby/sys/mountinfo v0.2.0 h1:HgYSHMWCj8D7w7TE/cQJfWrY6W3TUxs3pwGFyC5qCvE=
+github.com/moby/sys/mountinfo v0.2.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/term v0.0.0-20200915141129-7f0af18e79f2 h1:SPoLlS9qUUnXcIY4pvA4CTwYjk0Is5f4UPEkeESr53k=
github.com/moby/term v0.0.0-20200915141129-7f0af18e79f2/go.mod h1:TjQg8pa4iejrUrjiz0MCtMV38jdMNW4doKSiBrEvCQQ=
github.com/moby/vpnkit v0.4.0/go.mod h1:KyjUrL9cb6ZSNNAUwZfqRjhwwgJ3BJN+kXh0t43WTUQ=
@@ -333,7 +341,6 @@ github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuB
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
@@ -347,6 +354,7 @@ github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/go.mod
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.0.0-20190425234816-dae70e8efea4/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/opencontainers/runc v1.0.0-rc90/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc91/go.mod h1:3Sm6Dt7OT8z88EbdQqqcRN2oCT54jbi72tT/HqgflT8=
github.com/opencontainers/runc v1.0.0-rc91.0.20200708210054-ce54a9d4d79b h1:wjSgG2Z5xWv1wpAI7JbwKR9aJH0p4HJ+ROZ7ViKh9qU=
github.com/opencontainers/runc v1.0.0-rc91.0.20200708210054-ce54a9d4d79b/go.mod h1:ZuXhqlr4EiRYgDrBDNfSbE4+n9JX4+V107NwAmF7sZA=
@@ -359,6 +367,7 @@ github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mo
github.com/opencontainers/runtime-tools v0.9.0 h1:FYgwVsKRI/H9hU32MJ/4MLOzXWodKK5zsQavY8NPMkU=
github.com/opencontainers/runtime-tools v0.9.0/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
+github.com/opencontainers/selinux v1.5.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/opencontainers/selinux v1.6.0 h1:+bIAS/Za3q5FTwWym4fTB0vObnfCf3G/NC7K6Jx62mY=
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
github.com/openshift/imagebuilder v1.1.6 h1:1+YzRxIIefY4QqtCImx6rg+75QrKNfBoPAKxgMo/khM=
@@ -403,8 +412,8 @@ github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQl
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
-github.com/rootless-containers/rootlesskit v0.10.0 h1:62HHP8s8qYYcolEtAsuo4GU6qau6pWmcQ1Te+TZTFds=
-github.com/rootless-containers/rootlesskit v0.10.0/go.mod h1:OZQfuRPb+2MA1p+hmjHmSmDRv9SdTzlQ3taNA/0d7XM=
+github.com/rootless-containers/rootlesskit v0.10.1 h1:WkkDeXAFR+meR9k+h5gPhnrDia4U781QqdGvV5BZ0E4=
+github.com/rootless-containers/rootlesskit v0.10.1/go.mod h1:m3LmCklz+LfrwgABaRYi/Yjym/DAG0z/Wc6Oa05WlVM=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8 h1:2c1EFnZHIPCW8qKWgHMH/fX2PkSabFc5mrVzfUNdg5U=
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
@@ -442,6 +451,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
@@ -456,6 +466,7 @@ github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMW
github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ=
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
@@ -465,6 +476,7 @@ github.com/varlink/go v0.0.0-20190502142041-0f1d566d194b h1:hdDRrn9OP/roL8a/e/5Z
github.com/varlink/go v0.0.0-20190502142041-0f1d566d194b/go.mod h1:YHaw8N660ESgMgLOZfLQqT1htFItynAUxMesFBho52s=
github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE=
github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g=
+github.com/vbauerster/mpb/v5 v5.2.2/go.mod h1:W5Fvgw4dm3/0NhqzV8j6EacfuTe5SvnzBRwiXxDR9ww=
github.com/vbauerster/mpb/v5 v5.3.0 h1:vgrEJjUzHaSZKDRRxul5Oh4C72Yy/5VEMb0em+9M0mQ=
github.com/vbauerster/mpb/v5 v5.3.0/go.mod h1:4yTkvAb8Cm4eylAp6t0JRq6pXDkFJ4krUlDqWYkakAs=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
@@ -486,6 +498,7 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ
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=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 h1:A/5uWzF44DlIgdm/PQFwfMkW0JX+cIcQi/SwLAmZP5M=
@@ -526,7 +539,6 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/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-20191004110552-13f9640d40b9/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-20200506145744-7e3656a0809f/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-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
@@ -560,19 +572,19 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/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-20200810151505-1b9f1253b3ed h1:WBkVNH1zd9jg/dK4HCM4lNANnmd12EHC9z+LmcCG4ns=
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a h1:i47hUS795cOydZI4AwJQCKXOr4BvxzvikwDoDtHhP2Y=
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM=
+golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -608,6 +620,7 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
diff --git a/hack/release.sh b/hack/release.sh
index 465fa6cd9..56cd04079 100755
--- a/hack/release.sh
+++ b/hack/release.sh
@@ -27,7 +27,7 @@ LAST_TAG=$(git describe --tags --abbrev=0)
write_go_version()
{
LOCAL_VERSION="$1"
- sed -i "s/^\(const Version = \"\).*/\1${LOCAL_VERSION}\"/" version/version.go
+ sed -i "s/^\(var Version = semver.MustParse\( \"\).*/\1${LOCAL_VERSION}\"\)/" version/version.go
}
write_spec_version()
diff --git a/libpod/define/info.go b/libpod/define/info.go
index 47c53d067..f0e05801c 100644
--- a/libpod/define/info.go
+++ b/libpod/define/info.go
@@ -15,6 +15,7 @@ type Info struct {
type HostInfo struct {
Arch string `json:"arch"`
BuildahVersion string `json:"buildahVersion"`
+ CgroupManager string `json:"cgroupManager"`
CGroupsVersion string `json:"cgroupVersion"`
Conmon *ConmonInfo `json:"conmon"`
CPUs int `json:"cpus"`
diff --git a/libpod/define/version.go b/libpod/define/version.go
index daa5cf7b2..d4cdd539d 100644
--- a/libpod/define/version.go
+++ b/libpod/define/version.go
@@ -18,9 +18,9 @@ var (
buildInfo string
)
-// Version is an output struct for varlink
+// Version is an output struct for API
type Version struct {
- APIVersion int64
+ APIVersion string
Version string
GoVersion string
GitCommit string
@@ -29,7 +29,7 @@ type Version struct {
OsArch string
}
-// GetVersion returns a VersionOutput struct for varlink and podman
+// GetVersion returns a VersionOutput struct for API and podman
func GetVersion() (Version, error) {
var err error
var buildTime int64
@@ -42,8 +42,8 @@ func GetVersion() (Version, error) {
}
}
return Version{
- APIVersion: podmanVersion.APIVersion,
- Version: podmanVersion.Version,
+ APIVersion: podmanVersion.APIVersion.String(),
+ Version: podmanVersion.Version.String(),
GoVersion: runtime.Version(),
GitCommit: gitCommit,
BuiltTime: time.Unix(buildTime, 0).Format(time.ANSIC),
diff --git a/libpod/info.go b/libpod/info.go
index 153000b6f..dd7a521c1 100644
--- a/libpod/info.go
+++ b/libpod/info.go
@@ -87,6 +87,7 @@ func (r *Runtime) hostInfo() (*define.HostInfo, error) {
info := define.HostInfo{
Arch: runtime.GOARCH,
BuildahVersion: buildah.Version,
+ CgroupManager: r.config.Engine.CgroupManager,
Linkmode: linkmode.Linkmode(),
CPUs: runtime.NumCPU(),
Distribution: hostDistributionInfo,
diff --git a/libpod/oci_conmon_exec_linux.go b/libpod/oci_conmon_exec_linux.go
index c18da68fe..8651c1dc5 100644
--- a/libpod/oci_conmon_exec_linux.go
+++ b/libpod/oci_conmon_exec_linux.go
@@ -537,9 +537,6 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
}
}()
- // Make a channel to pass errors back
- errChan := make(chan error)
-
attachStdout := true
attachStderr := true
attachStdin := true
@@ -580,13 +577,16 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
hijackWriteErrorAndClose(deferredErr, c.ID(), isTerminal, httpCon, httpBuf)
}()
+ stdoutChan := make(chan error)
+ stdinChan := make(chan error)
+
// Next, STDIN. Avoid entirely if attachStdin unset.
if attachStdin {
go func() {
logrus.Debugf("Beginning STDIN copy")
_, err := utils.CopyDetachable(conn, httpBuf, detachKeys)
logrus.Debugf("STDIN copy completed")
- errChan <- err
+ stdinChan <- err
}()
}
@@ -613,19 +613,24 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
logrus.Debugf("Performing non-terminal HTTP attach for container %s", c.ID())
err = httpAttachNonTerminalCopy(conn, httpBuf, c.ID(), attachStdin, attachStdout, attachStderr)
}
- errChan <- err
+ stdoutChan <- err
logrus.Debugf("STDOUT/ERR copy completed")
}()
- if cancel != nil {
+ for {
select {
- case err := <-errChan:
- return err
+ case err := <-stdoutChan:
+ if err != nil {
+ return err
+ }
+
+ return nil
+ case err := <-stdinChan:
+ if err != nil {
+ return err
+ }
case <-cancel:
return nil
}
- } else {
- var connErr error = <-errChan
- return connErr
}
}
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 5769e5580..1d4f33794 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -555,9 +555,6 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
return err
}
- // Make a channel to pass errors back
- errChan := make(chan error)
-
attachStdout := true
attachStderr := true
attachStdin := true
@@ -672,6 +669,9 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
logrus.Debugf("Forwarding attach output for container %s", ctr.ID())
+ stdoutChan := make(chan error)
+ stdinChan := make(chan error)
+
// Handle STDOUT/STDERR
go func() {
var err error
@@ -690,7 +690,7 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
logrus.Debugf("Performing non-terminal HTTP attach for container %s", ctr.ID())
err = httpAttachNonTerminalCopy(conn, httpBuf, ctr.ID(), attachStdin, attachStdout, attachStderr)
}
- errChan <- err
+ stdoutChan <- err
logrus.Debugf("STDOUT/ERR copy completed")
}()
// Next, STDIN. Avoid entirely if attachStdin unset.
@@ -698,20 +698,25 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
go func() {
_, err := utils.CopyDetachable(conn, httpBuf, detach)
logrus.Debugf("STDIN copy completed")
- errChan <- err
+ stdinChan <- err
}()
}
- if cancel != nil {
+ for {
select {
- case err := <-errChan:
- return err
+ case err := <-stdoutChan:
+ if err != nil {
+ return err
+ }
+
+ return nil
+ case err := <-stdinChan:
+ if err != nil {
+ return err
+ }
case <-cancel:
return nil
}
- } else {
- var connErr error = <-errChan
- return connErr
}
}
@@ -1330,10 +1335,10 @@ func (r *ConmonOCIRuntime) sharedConmonArgs(ctr *Container, cuuid, bundlePath, p
switch logDriver {
case define.JournaldLogging:
logDriverArg = define.JournaldLogging
- case define.JSONLogging:
- fallthrough
case define.NoLogging:
logDriverArg = define.NoLogging
+ case define.JSONLogging:
+ fallthrough
default: //nolint-stylecheck
// No case here should happen except JSONLogging, but keep this here in case the options are extended
logrus.Errorf("%s logging specified but not supported. Choosing k8s-file logging instead", ctr.LogDriver())
diff --git a/libpod/rootless_cni_linux.go b/libpod/rootless_cni_linux.go
index 7feec6b44..2877191e5 100644
--- a/libpod/rootless_cni_linux.go
+++ b/libpod/rootless_cni_linux.go
@@ -25,7 +25,7 @@ import (
// Built from ../contrib/rootless-cni-infra.
var rootlessCNIInfraImage = map[string]string{
- "amd64": "quay.io/libpod/rootless-cni-infra@sha256:8aa681c4c08dee3ec5d46ff592fddd0259a35626717006d6b77ee786b1d02967", // 1-amd64
+ "amd64": "quay.io/libpod/rootless-cni-infra@sha256:e92c3a6367f8e554121b96d39af1f19f0f9ac5a32922b290112e13bc661d3a29", // 2-amd64
}
const (
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index b1ef08cda..3a904ba87 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -17,6 +17,7 @@ import (
"github.com/docker/go-connections/nat"
"github.com/gorilla/schema"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
func RemoveContainer(w http.ResponseWriter, r *http.Request) {
@@ -44,8 +45,25 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := utils.GetName(r)
con, err := runtime.LookupContainer(name)
- if err != nil {
- utils.ContainerNotFound(w, name, err)
+ if err != nil && errors.Cause(err) == define.ErrNoSuchCtr {
+ // Failed to get container. If force is specified, get the container's ID
+ // and evict it
+ if !query.Force {
+ utils.ContainerNotFound(w, name, err)
+ return
+ }
+
+ if _, err := runtime.EvictContainer(r.Context(), name, query.Vols); err != nil {
+ if errors.Cause(err) == define.ErrNoSuchCtr {
+ logrus.Debugf("Ignoring error (--allow-missing): %q", err)
+ w.WriteHeader(http.StatusNoContent)
+ return
+ }
+ logrus.Warn(errors.Wrapf(err, "Failed to evict container: %q", name))
+ utils.InternalServerError(w, err)
+ return
+ }
+ w.WriteHeader(http.StatusNoContent)
return
}
@@ -85,7 +103,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
- if _, found := r.URL.Query()["limit"]; found && query.Limit != -1 {
+ if _, found := r.URL.Query()["limit"]; found && query.Limit > 0 {
last := query.Limit
if len(containers) > last {
containers = containers[len(containers)-last:]
@@ -175,6 +193,7 @@ func KillContainer(w http.ResponseWriter, r *http.Request) {
err = con.Kill(signal)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "unable to kill Container %s", name))
+ return
}
// Docker waits for the container to stop if the signal is 0 or
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go
index 93e4fe540..1d0b4c45d 100644
--- a/pkg/api/handlers/compat/containers_create.go
+++ b/pkg/api/handlers/compat/containers_create.go
@@ -210,7 +210,7 @@ func makeCreateConfig(ctx context.Context, containerConfig *config.Config, input
ImageID: newImage.ID(),
BuiltinImgVolumes: nil, // podman
ImageVolumeType: "", // podman
- Interactive: false,
+ Interactive: input.OpenStdin,
// IpcMode: input.HostConfig.IpcMode,
Labels: input.Labels,
LogDriver: input.HostConfig.LogConfig.Type, // is this correct
diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go
index 3d7d49ad3..16bd0518a 100644
--- a/pkg/api/handlers/compat/containers_stats.go
+++ b/pkg/api/handlers/compat/containers_stats.go
@@ -75,32 +75,48 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
}
}
- for ok := true; ok; ok = query.Stream {
+ // Write header and content type.
+ w.WriteHeader(http.StatusOK)
+ w.Header().Add("Content-Type", "application/json")
+ if flusher, ok := w.(http.Flusher); ok {
+ flusher.Flush()
+ }
+
+ // Setup JSON encoder for streaming.
+ coder := json.NewEncoder(w)
+ coder.SetEscapeHTML(true)
+
+streamLabel: // A label to flatten the scope
+ select {
+ case <-r.Context().Done():
+ logrus.Debugf("Client connection (container stats) cancelled")
+
+ default:
// Container stats
stats, err := ctnr.GetContainerStats(stats)
if err != nil {
- utils.InternalServerError(w, err)
+ logrus.Errorf("Unable to get container stats: %v", err)
return
}
inspect, err := ctnr.Inspect(false)
if err != nil {
- utils.InternalServerError(w, err)
+ logrus.Errorf("Unable to inspect container: %v", err)
return
}
// Cgroup stats
cgroupPath, err := ctnr.CGroupPath()
if err != nil {
- utils.InternalServerError(w, err)
+ logrus.Errorf("Unable to get cgroup path of container: %v", err)
return
}
cgroup, err := cgroups.Load(cgroupPath)
if err != nil {
- utils.InternalServerError(w, err)
+ logrus.Errorf("Unable to load cgroup: %v", err)
return
}
cgroupStat, err := cgroup.Stat()
if err != nil {
- utils.InternalServerError(w, err)
+ logrus.Errorf("Unable to get cgroup stats: %v", err)
return
}
@@ -175,11 +191,18 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
Networks: net,
}
- utils.WriteJSON(w, http.StatusOK, s)
+ if err := coder.Encode(s); err != nil {
+ logrus.Errorf("Unable to encode stats: %v", err)
+ return
+ }
if flusher, ok := w.(http.Flusher); ok {
flusher.Flush()
}
+ if !query.Stream {
+ return
+ }
+
preRead = s.Read
bits, err := json.Marshal(s.CPUStats)
if err != nil {
@@ -189,10 +212,8 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
logrus.Errorf("Unable to unmarshal previous stats: %q", err)
}
- // Only sleep when we're streaming.
- if query.Stream {
- time.Sleep(DefaultStatsPeriod)
- }
+ time.Sleep(DefaultStatsPeriod)
+ goto streamLabel
}
}
diff --git a/pkg/api/handlers/libpod/containers_stats.go b/pkg/api/handlers/libpod/containers_stats.go
new file mode 100644
index 000000000..4d5abe118
--- /dev/null
+++ b/pkg/api/handlers/libpod/containers_stats.go
@@ -0,0 +1,72 @@
+package libpod
+
+import (
+ "encoding/json"
+ "net/http"
+ "time"
+
+ "github.com/containers/podman/v2/libpod"
+ "github.com/containers/podman/v2/pkg/api/handlers/utils"
+ "github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/infra/abi"
+ "github.com/gorilla/schema"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+const DefaultStatsPeriod = 5 * time.Second
+
+func StatsContainer(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+
+ query := struct {
+ Containers []string `schema:"containers"`
+ Stream bool `schema:"stream"`
+ }{
+ Stream: true,
+ }
+ if err := decoder.Decode(&query, r.URL.Query()); err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
+ return
+ }
+
+ // Reduce code duplication and use the local/abi implementation of
+ // container stats.
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
+
+ statsOptions := entities.ContainerStatsOptions{
+ Stream: query.Stream,
+ }
+
+ // Stats will stop if the connection is closed.
+ statsChan, err := containerEngine.ContainerStats(r.Context(), query.Containers, statsOptions)
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+
+ // Write header and content type.
+ w.WriteHeader(http.StatusOK)
+ w.Header().Add("Content-Type", "application/json")
+ if flusher, ok := w.(http.Flusher); ok {
+ flusher.Flush()
+ }
+
+ // Setup JSON encoder for streaming.
+ coder := json.NewEncoder(w)
+ coder.SetEscapeHTML(true)
+
+ for stats := range statsChan {
+ if err := coder.Encode(stats); err != nil {
+ // Note: even when streaming, the stats goroutine will
+ // be notified (and stop) as the connection will be
+ // closed.
+ logrus.Errorf("Unable to encode stats: %v", err)
+ return
+ }
+ if flusher, ok := w.(http.Flusher); ok {
+ flusher.Flush()
+ }
+ }
+}
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go
index 8a2f4f4cf..ad8d1f38e 100644
--- a/pkg/api/handlers/libpod/images_pull.go
+++ b/pkg/api/handlers/libpod/images_pull.go
@@ -178,10 +178,19 @@ loop: // break out of for/select infinite loop
flush()
case <-runCtx.Done():
if !failed {
+ // Send all image id's pulled in 'images' stanza
report.Images = images
if err := enc.Encode(report); err != nil {
logrus.Warnf("Failed to json encode error %q", err.Error())
}
+
+ report.Images = nil
+ // Pull last ID from list and publish in 'id' stanza. This maintains previous API contract
+ report.ID = images[len(images)-1]
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to json encode error %q", err.Error())
+ }
+
flush()
}
break loop // break out of for/select infinite loop
diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go
index 0ccaa95bb..9e503dbb0 100644
--- a/pkg/api/handlers/types.go
+++ b/pkg/api/handlers/types.go
@@ -33,7 +33,7 @@ type LibpodImagesLoadReport struct {
}
type LibpodImagesPullReport struct {
- ID string `json:"id"`
+ entities.ImagePullReport
}
// LibpodImagesRemoveReport is the return type for image removal via the rest
diff --git a/pkg/api/server/handler_api.go b/pkg/api/server/handler_api.go
index f2ce0301b..920811c51 100644
--- a/pkg/api/server/handler_api.go
+++ b/pkg/api/server/handler_api.go
@@ -34,15 +34,18 @@ func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc {
}
// TODO: Use r.ConnContext when ported to go 1.13
- c := context.WithValue(r.Context(), "decoder", s.Decoder) //nolint
- c = context.WithValue(c, "runtime", s.Runtime) //nolint
- c = context.WithValue(c, "shutdownFunc", s.Shutdown) //nolint
- c = context.WithValue(c, "idletracker", s.idleTracker) //nolint
+ c := context.WithValue(r.Context(), "decoder", s.Decoder) // nolint
+ c = context.WithValue(c, "runtime", s.Runtime) // nolint
+ c = context.WithValue(c, "shutdownFunc", s.Shutdown) // nolint
+ c = context.WithValue(c, "idletracker", s.idleTracker) // nolint
r = r.WithContext(c)
- v := utils.APIVersion[utils.CompatTree][utils.CurrentAPIVersion]
- w.Header().Set("API-Version", fmt.Sprintf("%d.%d", v.Major, v.Minor))
- w.Header().Set("Libpod-API-Version", utils.APIVersion[utils.LibpodTree][utils.CurrentAPIVersion].String())
+ cv := utils.APIVersion[utils.CompatTree][utils.CurrentAPIVersion]
+ w.Header().Set("API-Version", fmt.Sprintf("%d.%d", cv.Major, cv.Minor))
+
+ lv := utils.APIVersion[utils.LibpodTree][utils.CurrentAPIVersion].String()
+ w.Header().Set("Libpod-API-Version", lv)
+ w.Header().Set("Server", "Libpod/"+lv+" ("+runtime.GOOS+")")
h(w, r)
}
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index 0ad5d29ea..870c6a90c 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -1013,7 +1013,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// tags:
// - containers
// summary: Get stats for a container
- // description: This returns a live stream of a container’s resource usage statistics.
+ // description: DEPRECATED. This endpoint will be removed with the next major release. Please use /libpod/containers/stats instead.
// parameters:
// - in: path
// name: name
@@ -1035,6 +1035,35 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name}/stats"), s.APIHandler(compat.StatsContainer)).Methods(http.MethodGet)
+ // swagger:operation GET /libpod/containers/stats libpod libpodStatsContainers
+ // ---
+ // tags:
+ // - containers
+ // summary: Get stats for one or more containers
+ // description: Return a live stream of resource usage statistics of one or more container. If no container is specified, the statistics of all containers are returned.
+ // parameters:
+ // - in: query
+ // name: containers
+ // description: names or IDs of containers
+ // type: array
+ // items:
+ // type: string
+ // - in: query
+ // name: stream
+ // type: boolean
+ // default: true
+ // description: Stream the output
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: no error
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/libpod/containers/stats"), s.APIHandler(libpod.StatsContainer)).Methods(http.MethodGet)
+
// swagger:operation GET /libpod/containers/{name}/top libpod libpodTopContainer
// ---
// tags:
diff --git a/pkg/bindings/bindings.go b/pkg/bindings/bindings.go
index ae5610b0f..14f306910 100644
--- a/pkg/bindings/bindings.go
+++ b/pkg/bindings/bindings.go
@@ -22,5 +22,5 @@ var (
PFalse = &pFalse
// APIVersion - podman will fail to run if this value is wrong
- APIVersion = semver.MustParse("1.0.0")
+ APIVersion = semver.MustParse("2.0.0")
)
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index 981912665..46e4df1d2 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -197,7 +197,56 @@ func Start(ctx context.Context, nameOrID string, detachKeys *string) error {
return response.Process(nil)
}
-func Stats() {}
+func Stats(ctx context.Context, containers []string, stream *bool) (chan entities.ContainerStatsReport, error) {
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return nil, err
+ }
+ params := url.Values{}
+ if stream != nil {
+ params.Set("stream", strconv.FormatBool(*stream))
+ }
+ for _, c := range containers {
+ params.Add("containers", c)
+ }
+
+ response, err := conn.DoRequest(nil, http.MethodGet, "/containers/stats", params, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ statsChan := make(chan entities.ContainerStatsReport)
+
+ go func() {
+ defer close(statsChan)
+
+ dec := json.NewDecoder(response.Body)
+ doStream := true
+ if stream != nil {
+ doStream = *stream
+ }
+
+ streamLabel: // label to flatten the scope
+ select {
+ case <-response.Request.Context().Done():
+ return // lost connection - maybe the server quit
+ default:
+ // fall through and do some work
+ }
+ var report entities.ContainerStatsReport
+ if err := dec.Decode(&report); err != nil {
+ report = entities.ContainerStatsReport{Error: err}
+ }
+ statsChan <- report
+
+ if report.Error != nil || !doStream {
+ return
+ }
+ goto streamLabel
+ }()
+
+ return statsChan, nil
+}
// Top gathers statistics about the running processes in a container. The nameOrID can be a container name
// or a partial/full ID. The descriptors allow for specifying which data to collect from the process.
diff --git a/pkg/bindings/images/pull.go b/pkg/bindings/images/pull.go
index 261a481a2..2bfbbb2ac 100644
--- a/pkg/bindings/images/pull.go
+++ b/pkg/bindings/images/pull.go
@@ -89,6 +89,7 @@ func Pull(ctx context.Context, rawImage string, options entities.ImagePullOption
mErr = multierror.Append(mErr, errors.New(report.Error))
case len(report.Images) > 0:
images = report.Images
+ case report.ID != "":
default:
return images, errors.New("failed to parse pull results stream, unexpected input")
}
diff --git a/pkg/bindings/system/system.go b/pkg/bindings/system/system.go
index e995770ba..1203f5c3c 100644
--- a/pkg/bindings/system/system.go
+++ b/pkg/bindings/system/system.go
@@ -118,10 +118,10 @@ func Version(ctx context.Context) (*entities.SystemVersionReport, error) {
if err = response.Process(&component); err != nil {
return nil, err
}
- f, _ := strconv.ParseFloat(component.APIVersion, 64)
+
b, _ := time.Parse(time.RFC3339, component.BuildTime)
report.Server = &define.Version{
- APIVersion: int64(f),
+ APIVersion: component.APIVersion,
Version: component.Version.Version,
GoVersion: component.GoVersion,
GitCommit: component.GitCommit,
@@ -129,6 +129,12 @@ func Version(ctx context.Context) (*entities.SystemVersionReport, error) {
Built: b.Unix(),
OsArch: fmt.Sprintf("%s/%s", component.Os, component.Arch),
}
+
+ for _, c := range component.Components {
+ if c.Name == "Podman Engine" {
+ report.Server.APIVersion = c.Details["APIVersion"]
+ }
+ }
return &report, err
}
diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go
index e0dd28d7a..681855293 100644
--- a/pkg/bindings/test/images_test.go
+++ b/pkg/bindings/test/images_test.go
@@ -360,19 +360,19 @@ var _ = Describe("Podman images", func() {
rawImage := "docker.io/library/busybox:latest"
pulledImages, err := images.Pull(bt.conn, rawImage, entities.ImagePullOptions{})
- Expect(err).To(BeNil())
+ Expect(err).NotTo(HaveOccurred())
Expect(len(pulledImages)).To(Equal(1))
exists, err := images.Exists(bt.conn, rawImage)
- Expect(err).To(BeNil())
+ Expect(err).NotTo(HaveOccurred())
Expect(exists).To(BeTrue())
// Make sure the normalization AND the full-transport reference works.
_, err = images.Pull(bt.conn, "docker://"+rawImage, entities.ImagePullOptions{})
- Expect(err).To(BeNil())
+ Expect(err).NotTo(HaveOccurred())
// The v2 endpoint only supports the docker transport. Let's see if that's really true.
_, err = images.Pull(bt.conn, "bogus-transport:bogus.com/image:reference", entities.ImagePullOptions{})
- Expect(err).To(Not(BeNil()))
+ Expect(err).To(HaveOccurred())
})
})
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index 16997cdd1..7b272f01e 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -411,10 +411,17 @@ type ContainerCpReport struct {
// ContainerStatsOptions describes input options for getting
// stats on containers
type ContainerStatsOptions struct {
- All bool
- Format string
- Latest bool
- NoReset bool
- NoStream bool
- StatChan chan []*define.ContainerStats
+ // Operate on the latest known container. Only supported for local
+ // clients.
+ Latest bool
+ // Stream stats.
+ Stream bool
+}
+
+// ContainerStatsReport is used for streaming container stats.
+type ContainerStatsReport struct {
+ // Error from reading stats.
+ Error error
+ // Results, set when there is no error.
+ Stats []define.ContainerStats
}
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 6c85c9267..f105dc333 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -38,7 +38,7 @@ type ContainerEngine interface {
ContainerRun(ctx context.Context, opts ContainerRunOptions) (*ContainerRunReport, error)
ContainerRunlabel(ctx context.Context, label string, image string, args []string, opts ContainerRunlabelOptions) error
ContainerStart(ctx context.Context, namesOrIds []string, options ContainerStartOptions) ([]*ContainerStartReport, error)
- ContainerStats(ctx context.Context, namesOrIds []string, options ContainerStatsOptions) error
+ ContainerStats(ctx context.Context, namesOrIds []string, options ContainerStatsOptions) (chan ContainerStatsReport, error)
ContainerStop(ctx context.Context, namesOrIds []string, options StopOptions) ([]*StopReport, error)
ContainerTop(ctx context.Context, options TopOptions) (*StringSliceReport, error)
ContainerUnmount(ctx context.Context, nameOrIDs []string, options ContainerUnmountOptions) ([]*ContainerUnmountReport, error)
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index d0b738934..cad6693fa 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -156,6 +156,8 @@ type ImagePullReport struct {
Error string `json:"error,omitempty"`
// Images contains the ID's of the images pulled
Images []string `json:"images,omitempty"`
+ // ID contains image id (retained for backwards compatibility)
+ ID string `json:"id,omitempty"`
}
// ImagePushOptions are the arguments for pushing images.
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 21618f555..8b0d53940 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -1142,12 +1142,12 @@ func (ic *ContainerEngine) Shutdown(_ context.Context) {
})
}
-func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []string, options entities.ContainerStatsOptions) error {
- defer close(options.StatChan)
+func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []string, options entities.ContainerStatsOptions) (statsChan chan entities.ContainerStatsReport, err error) {
+ statsChan = make(chan entities.ContainerStatsReport, 1)
+
containerFunc := ic.Libpod.GetRunningContainers
+ queryAll := false
switch {
- case len(namesOrIds) > 0:
- containerFunc = func() ([]*libpod.Container, error) { return ic.Libpod.GetContainersByList(namesOrIds) }
case options.Latest:
containerFunc = func() ([]*libpod.Container, error) {
lastCtr, err := ic.Libpod.GetLatestContainer()
@@ -1156,62 +1156,76 @@ func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []stri
}
return []*libpod.Container{lastCtr}, nil
}
- case options.All:
+ case len(namesOrIds) > 0:
+ containerFunc = func() ([]*libpod.Container, error) { return ic.Libpod.GetContainersByList(namesOrIds) }
+ default:
+ // No containers, no latest -> query all!
+ queryAll = true
containerFunc = ic.Libpod.GetAllContainers
}
- ctrs, err := containerFunc()
- if err != nil {
- return errors.Wrapf(err, "unable to get list of containers")
- }
- containerStats := map[string]*define.ContainerStats{}
- for _, ctr := range ctrs {
- initialStats, err := ctr.GetContainerStats(&define.ContainerStats{})
- if err != nil {
- // when doing "all", don't worry about containers that are not running
- cause := errors.Cause(err)
- if options.All && (cause == define.ErrCtrRemoved || cause == define.ErrNoSuchCtr || cause == define.ErrCtrStateInvalid) {
- continue
- }
- if cause == cgroups.ErrCgroupV1Rootless {
- err = cause
- }
- return err
+ go func() {
+ defer close(statsChan)
+ var (
+ err error
+ containers []*libpod.Container
+ containerStats map[string]*define.ContainerStats
+ )
+ containerStats = make(map[string]*define.ContainerStats)
+
+ stream: // label to flatten the scope
+ select {
+ case <-ctx.Done():
+ // client cancelled
+ logrus.Debugf("Container stats stopped: context cancelled")
+ return
+ default:
+ // just fall through and do work
}
- containerStats[ctr.ID()] = initialStats
- }
- for {
- reportStats := []*define.ContainerStats{}
- for _, ctr := range ctrs {
- id := ctr.ID()
- if _, ok := containerStats[ctr.ID()]; !ok {
- initialStats, err := ctr.GetContainerStats(&define.ContainerStats{})
- if errors.Cause(err) == define.ErrCtrRemoved || errors.Cause(err) == define.ErrNoSuchCtr || errors.Cause(err) == define.ErrCtrStateInvalid {
- // skip dealing with a container that is gone
- continue
+
+ // Anonymous func to easily use the return values for streaming.
+ computeStats := func() ([]define.ContainerStats, error) {
+ containers, err = containerFunc()
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to get list of containers")
+ }
+
+ reportStats := []define.ContainerStats{}
+ for _, ctr := range containers {
+ prev, ok := containerStats[ctr.ID()]
+ if !ok {
+ prev = &define.ContainerStats{}
}
+
+ stats, err := ctr.GetContainerStats(prev)
if err != nil {
- return err
+ cause := errors.Cause(err)
+ if queryAll && (cause == define.ErrCtrRemoved || cause == define.ErrNoSuchCtr || cause == define.ErrCtrStateInvalid) {
+ continue
+ }
+ if cause == cgroups.ErrCgroupV1Rootless {
+ err = cause
+ }
+ return nil, err
}
- containerStats[id] = initialStats
- }
- stats, err := ctr.GetContainerStats(containerStats[id])
- if err != nil && errors.Cause(err) != define.ErrNoSuchCtr {
- return err
+
+ containerStats[ctr.ID()] = stats
+ reportStats = append(reportStats, *stats)
}
- // replace the previous measurement with the current one
- containerStats[id] = stats
- reportStats = append(reportStats, stats)
+ return reportStats, nil
}
- ctrs, err = containerFunc()
- if err != nil {
- return err
- }
- options.StatChan <- reportStats
- if options.NoStream {
- break
+
+ report := entities.ContainerStatsReport{}
+ report.Stats, report.Error = computeStats()
+ statsChan <- report
+
+ if report.Error != nil || !options.Stream {
+ return
}
+
time.Sleep(time.Second)
- }
- return nil
+ goto stream
+ }()
+
+ return statsChan, nil
}
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index cc62c3f27..25c0c184f 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -191,6 +191,15 @@ func (ir *ImageEngine) Unmount(ctx context.Context, nameOrIDs []string, options
reports := []*entities.ImageUnmountReport{}
for _, img := range images {
report := entities.ImageUnmountReport{Id: img.ID()}
+ mounted, _, err := img.Mounted()
+ if err != nil {
+ // Errors will be caught in Unmount call below
+ // Default assumption to mounted
+ mounted = true
+ }
+ if !mounted {
+ continue
+ }
if err := img.Unmount(options.Force); err != nil {
if options.All && errors.Cause(err) == storage.ErrLayerNotMounted {
logrus.Debugf("Error umounting image %s, storage.ErrLayerNotMounted", img.ID())
diff --git a/pkg/domain/infra/abi/system_varlink.go b/pkg/domain/infra/abi/system_varlink.go
index d0a5c5407..ead84fc84 100644
--- a/pkg/domain/infra/abi/system_varlink.go
+++ b/pkg/domain/infra/abi/system_varlink.go
@@ -22,7 +22,7 @@ func (ic *ContainerEngine) VarlinkService(_ context.Context, opts entities.Servi
service, err := varlink.NewService(
"Atomic",
"podman",
- version.Version,
+ version.Version.String(),
"https://github.com/containers/podman",
)
if err != nil {
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 35550b9be..9b03503c6 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -35,7 +35,7 @@ func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string)
}
func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []string, options entities.WaitOptions) ([]entities.WaitReport, error) {
- cons, err := getContainersByContext(ic.ClientCxt, false, namesOrIds)
+ cons, err := getContainersByContext(ic.ClientCxt, false, false, namesOrIds)
if err != nil {
return nil, err
}
@@ -54,7 +54,7 @@ func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []strin
}
func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
- ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, false, namesOrIds)
if err != nil {
return nil, err
}
@@ -67,7 +67,7 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
}
func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
- ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, false, namesOrIds)
if err != nil {
return nil, err
}
@@ -89,8 +89,8 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
id := strings.Split(string(content), "\n")[0]
namesOrIds = append(namesOrIds, id)
}
- ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
- if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr) {
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, options.Ignore, namesOrIds)
+ if err != nil {
return nil, err
}
for _, c := range ctrs {
@@ -120,7 +120,7 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
}
func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []string, options entities.KillOptions) ([]*entities.KillReport, error) {
- ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, false, namesOrIds)
if err != nil {
return nil, err
}
@@ -144,7 +144,7 @@ func (ic *ContainerEngine) ContainerRestart(ctx context.Context, namesOrIds []st
timeout = &t
}
- ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, false, namesOrIds)
if err != nil {
return nil, err
}
@@ -169,8 +169,8 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
id := strings.Split(string(content), "\n")[0]
namesOrIds = append(namesOrIds, id)
}
- ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
- if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr) {
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, options.Ignore, namesOrIds)
+ if err != nil {
return nil, err
}
// TODO there is no endpoint for container eviction. Need to discuss
@@ -283,7 +283,7 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [
)
if options.All {
- allCtrs, err := getContainersByContext(ic.ClientCxt, true, []string{})
+ allCtrs, err := getContainersByContext(ic.ClientCxt, true, false, []string{})
if err != nil {
return nil, err
}
@@ -295,7 +295,7 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [
}
} else {
- ctrs, err = getContainersByContext(ic.ClientCxt, false, namesOrIds)
+ ctrs, err = getContainersByContext(ic.ClientCxt, false, false, namesOrIds)
if err != nil {
return nil, err
}
@@ -317,7 +317,7 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st
ctrs = []entities.ListContainer{}
)
if options.All {
- allCtrs, err := getContainersByContext(ic.ClientCxt, true, []string{})
+ allCtrs, err := getContainersByContext(ic.ClientCxt, true, false, []string{})
if err != nil {
return nil, err
}
@@ -329,7 +329,7 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st
}
} else {
- ctrs, err = getContainersByContext(ic.ClientCxt, false, namesOrIds)
+ ctrs, err = getContainersByContext(ic.ClientCxt, false, false, namesOrIds)
if err != nil {
return nil, err
}
@@ -389,6 +389,15 @@ func (ic *ContainerEngine) ContainerLogs(_ context.Context, nameOrIDs []string,
}
func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrID string, options entities.AttachOptions) error {
+ ctrs, err := getContainersByContext(ic.ClientCxt, false, false, []string{nameOrID})
+ if err != nil {
+ return err
+ }
+ ctr := ctrs[0]
+ if ctr.State != define.ContainerStateRunning.String() {
+ return errors.Errorf("you can only attach to running containers")
+ }
+
return containers.Attach(ic.ClientCxt, nameOrID, &options.DetachKeys, nil, bindings.PTrue, options.Stdin, options.Stdout, options.Stderr, nil)
}
@@ -472,27 +481,67 @@ func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input,
func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) {
reports := []*entities.ContainerStartReport{}
- for _, name := range namesOrIds {
+ var exitCode = define.ExecErrorCodeGeneric
+ ctrs, err := getContainersByContext(ic.ClientCxt, false, false, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ // There can only be one container if attach was used
+ for i, ctr := range ctrs {
+ name := ctr.ID
report := entities.ContainerStartReport{
Id: name,
- RawInput: name,
- ExitCode: 125,
+ RawInput: namesOrIds[i],
+ ExitCode: exitCode,
}
+ ctrRunning := ctr.State == define.ContainerStateRunning.String()
if options.Attach {
- report.Err = startAndAttach(ic, name, &options.DetachKeys, options.Stdin, options.Stdout, options.Stderr)
- if report.Err == nil {
- exitCode, err := containers.Wait(ic.ClientCxt, name, nil)
- if err == nil {
- report.ExitCode = int(exitCode)
+ err = startAndAttach(ic, name, &options.DetachKeys, options.Stdin, options.Stdout, options.Stderr)
+ if err == define.ErrDetach {
+ // User manually detached
+ // Exit cleanly immediately
+ report.Err = err
+ reports = append(reports, &report)
+ return reports, nil
+ }
+ if ctrRunning {
+ reports = append(reports, &report)
+ return reports, nil
+ }
+
+ if err != nil {
+ report.ExitCode = define.ExitCode(report.Err)
+ report.Err = err
+ reports = append(reports, &report)
+ return reports, errors.Wrapf(report.Err, "unable to start container %s", name)
+ }
+ exitCode, err := containers.Wait(ic.ClientCxt, name, nil)
+ if err == define.ErrNoSuchCtr {
+ // Check events
+ event, err := ic.GetLastContainerEvent(ctx, name, events.Exited)
+ if err != nil {
+ logrus.Errorf("Cannot get exit code: %v", err)
+ report.ExitCode = define.ExecErrorCodeNotFound
+ } else {
+ report.ExitCode = event.ContainerExitCode
}
} else {
- report.ExitCode = define.ExitCode(report.Err)
+ report.ExitCode = int(exitCode)
}
reports = append(reports, &report)
return reports, nil
}
- report.Err = containers.Start(ic.ClientCxt, name, &options.DetachKeys)
- report.ExitCode = define.ExitCode(report.Err)
+ // Start the container if it's not running already.
+ if !ctrRunning {
+ err = containers.Start(ic.ClientCxt, name, &options.DetachKeys)
+ if err != nil {
+ report.Err = errors.Wrapf(err, "unable to start container %q", name)
+ report.ExitCode = define.ExitCode(err)
+ reports = append(reports, &report)
+ continue
+ }
+ }
+ report.ExitCode = 0
reports = append(reports, &report)
}
return reports, nil
@@ -607,7 +656,7 @@ func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []st
}
func (ic *ContainerEngine) ContainerInit(ctx context.Context, namesOrIds []string, options entities.ContainerInitOptions) ([]*entities.ContainerInitReport, error) {
- ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, false, namesOrIds)
if err != nil {
return nil, err
}
@@ -647,7 +696,7 @@ func (ic *ContainerEngine) ContainerPort(ctx context.Context, nameOrID string, o
if len(nameOrID) > 0 {
namesOrIds = append(namesOrIds, nameOrID)
}
- ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, false, namesOrIds)
if err != nil {
return nil, err
}
@@ -673,6 +722,9 @@ func (ic *ContainerEngine) ContainerCp(ctx context.Context, source, dest string,
func (ic *ContainerEngine) Shutdown(_ context.Context) {
}
-func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []string, options entities.ContainerStatsOptions) error {
- return errors.New("not implemented")
+func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []string, options entities.ContainerStatsOptions) (statsChan chan entities.ContainerStatsReport, err error) {
+ if options.Latest {
+ return nil, errors.New("latest is not supported for the remote client")
+ }
+ return containers.Stats(ic.ClientCxt, namesOrIds, &options.Stream)
}
diff --git a/pkg/domain/infra/tunnel/events.go b/pkg/domain/infra/tunnel/events.go
index e6f4834b9..53bae6cef 100644
--- a/pkg/domain/infra/tunnel/events.go
+++ b/pkg/domain/infra/tunnel/events.go
@@ -2,8 +2,10 @@ package tunnel
import (
"context"
+ // "fmt"
"strings"
+ "github.com/containers/podman/v2/libpod/events"
"github.com/containers/podman/v2/pkg/bindings/system"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/pkg/errors"
@@ -29,3 +31,33 @@ func (ic *ContainerEngine) Events(ctx context.Context, opts entities.EventsOptio
}()
return system.Events(ic.ClientCxt, binChan, nil, &opts.Since, &opts.Until, filters, &opts.Stream)
}
+
+// GetLastContainerEvent takes a container name or ID and an event status and returns
+// the last occurrence of the container event
+func (ic *ContainerEngine) GetLastContainerEvent(ctx context.Context, nameOrID string, containerEvent events.Status) (*events.Event, error) {
+ // check to make sure the event.Status is valid
+ if _, err := events.StringToStatus(containerEvent.String()); err != nil {
+ return nil, err
+ }
+ var event events.Event
+ return &event, nil
+
+ /*
+ FIXME: We need new bindings for this section
+ filters := []string{
+ fmt.Sprintf("container=%s", nameOrID),
+ fmt.Sprintf("event=%s", containerEvent),
+ "type=container",
+ }
+
+ containerEvents, err := system.GetEvents(ctx, entities.EventsOptions{Filter: filters})
+ if err != nil {
+ return nil, err
+ }
+ if len(containerEvents) < 1 {
+ return nil, errors.Wrapf(events.ErrEventNotFound, "%s not found", containerEvent.String())
+ }
+ // return the last element in the slice
+ return containerEvents[len(containerEvents)-1], nil
+ */
+}
diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go
index 0c38a3326..5944f855a 100644
--- a/pkg/domain/infra/tunnel/helpers.go
+++ b/pkg/domain/infra/tunnel/helpers.go
@@ -13,7 +13,7 @@ import (
"github.com/pkg/errors"
)
-func getContainersByContext(contextWithConnection context.Context, all bool, namesOrIDs []string) ([]entities.ListContainer, error) {
+func getContainersByContext(contextWithConnection context.Context, all, ignore bool, namesOrIDs []string) ([]entities.ListContainer, error) {
var (
cons []entities.ListContainer
)
@@ -36,7 +36,7 @@ func getContainersByContext(contextWithConnection context.Context, all bool, nam
break
}
}
- if !found {
+ if !found && !ignore {
return nil, errors.Wrapf(define.ErrNoSuchCtr, "unable to find container %q", id)
}
}
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 332a7c2eb..981884109 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -199,6 +199,13 @@ func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions)
return nil, err
}
defer f.Close()
+ fInfo, err := f.Stat()
+ if err != nil {
+ return nil, err
+ }
+ if fInfo.IsDir() {
+ return nil, errors.Errorf("remote client supports archives only but %q is a directory", opts.Input)
+ }
ref := opts.Name
if len(opts.Tag) > 0 {
ref += ":" + opts.Tag
diff --git a/pkg/hooks/1.0.0/hook.go b/pkg/hooks/1.0.0/hook.go
index 77fbab5aa..244e8800f 100644
--- a/pkg/hooks/1.0.0/hook.go
+++ b/pkg/hooks/1.0.0/hook.go
@@ -67,7 +67,14 @@ func (hook *Hook) Validate(extensionStages []string) (err error) {
return errors.New("missing required property: stages")
}
- validStages := map[string]bool{"prestart": true, "poststart": true, "poststop": true}
+ validStages := map[string]bool{
+ "createContainer": true,
+ "createRuntime": true,
+ "prestart": true,
+ "poststart": true,
+ "poststop": true,
+ "startContainer": true,
+ }
for _, stage := range extensionStages {
validStages[stage] = true
}
diff --git a/pkg/hooks/hooks.go b/pkg/hooks/hooks.go
index 2a12eceac..6257529ab 100644
--- a/pkg/hooks/hooks.go
+++ b/pkg/hooks/hooks.go
@@ -120,12 +120,18 @@ func (m *Manager) Hooks(config *rspec.Spec, annotations map[string]string, hasBi
extensionStageHooks[stage] = append(extensionStageHooks[stage], namedHook.hook.Hook)
} else {
switch stage {
+ case "createContainer":
+ config.Hooks.CreateContainer = append(config.Hooks.CreateContainer, namedHook.hook.Hook)
+ case "createRuntime":
+ config.Hooks.CreateRuntime = append(config.Hooks.CreateRuntime, namedHook.hook.Hook)
case "prestart":
config.Hooks.Prestart = append(config.Hooks.Prestart, namedHook.hook.Hook)
case "poststart":
config.Hooks.Poststart = append(config.Hooks.Poststart, namedHook.hook.Hook)
case "poststop":
config.Hooks.Poststop = append(config.Hooks.Poststop, namedHook.hook.Hook)
+ case "startContainer":
+ config.Hooks.StartContainer = append(config.Hooks.StartContainer, namedHook.hook.Hook)
default:
return extensionStageHooks, fmt.Errorf("hook %q: unknown stage %q", namedHook.name, stage)
}
diff --git a/pkg/specgen/generate/storage.go b/pkg/specgen/generate/storage.go
index 7f55317ff..b225f79ee 100644
--- a/pkg/specgen/generate/storage.go
+++ b/pkg/specgen/generate/storage.go
@@ -195,9 +195,9 @@ func getVolumesFrom(volumesFrom []string, runtime *libpod.Runtime) (map[string]s
splitVol := strings.SplitN(volume, ":", 2)
if len(splitVol) == 2 {
splitOpts := strings.Split(splitVol[1], ",")
+ setRORW := false
+ setZ := false
for _, opt := range splitOpts {
- setRORW := false
- setZ := false
switch opt {
case "z":
if setZ {
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index a4fdae46e..8090bcd3d 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -256,7 +256,7 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
}
if info.PodmanVersion == "" {
- info.PodmanVersion = version.Version
+ info.PodmanVersion = version.Version.String()
}
if info.GenerateTimestamp {
info.TimeStamp = fmt.Sprintf("%v", time.Now().Format(time.UnixDate))
diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go
index c41eedd17..c0acba37d 100644
--- a/pkg/systemd/generate/pods.go
+++ b/pkg/systemd/generate/pods.go
@@ -299,7 +299,7 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
info.ExecStopPost = "{{.Executable}} pod rm --ignore -f --pod-id-file {{.PodIDFile}}"
}
if info.PodmanVersion == "" {
- info.PodmanVersion = version.Version
+ info.PodmanVersion = version.Version.String()
}
if info.GenerateTimestamp {
info.TimeStamp = fmt.Sprintf("%v", time.Now().Format(time.UnixDate))
diff --git a/pkg/varlinkapi/system.go b/pkg/varlinkapi/system.go
index 9e4db2611..e5c766a6d 100644
--- a/pkg/varlinkapi/system.go
+++ b/pkg/varlinkapi/system.go
@@ -7,6 +7,7 @@ import (
"fmt"
"os"
goruntime "runtime"
+ "strconv"
"time"
"github.com/containers/image/v5/pkg/sysregistriesv2"
@@ -22,13 +23,18 @@ func (i *VarlinkAPI) GetVersion(call iopodman.VarlinkCall) error {
return err
}
+ int64APIVersion, err := strconv.ParseInt(versionInfo.APIVersion, 10, 64)
+ if err != nil {
+ return err
+ }
+
return call.ReplyGetVersion(
versionInfo.Version,
versionInfo.GoVersion,
versionInfo.GitCommit,
time.Unix(versionInfo.Built, 0).Format(time.RFC3339),
versionInfo.OsArch,
- versionInfo.APIVersion,
+ int64APIVersion,
)
}
diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at
index 9ea3cb7ed..187073fb9 100644
--- a/test/apiv2/20-containers.at
+++ b/test/apiv2/20-containers.at
@@ -176,6 +176,31 @@ t GET containers/$cid/json 200 \
.Config.Cmd='[]' \
.Path="echo" \
.Args[0]="param1"
+
+# create a running container for after
+t POST containers/create '"Image":"'$IMAGE'","Entrypoint":["top"]' 201 \
+ .Id~[0-9a-f]\\{64\\}
+cid_top=$(jq -r '.Id' <<<"$output")
+t GET containers/${cid_top}/json 200 \
+ .Config.Entrypoint[0]="top" \
+ .Config.Cmd='[]' \
+ .Path="top"
+t POST containers/${cid_top}/start '' 204
+# make sure the container is running
+t GET containers/${cid_top}/json 200 \
+ .State.Status="running"
+
+# 0 means unlimited, need same with docker
+t GET containers/json?limit=0 200 \
+ .[0].Id~[0-9a-f]\\{64\\}
+
+t GET 'containers/json?limit=0&all=1' 200 \
+ .[0].Id~[0-9a-f]\\{64\\} \
+ .[1].Id~[0-9a-f]\\{64\\}
+
+t POST containers/${cid_top}/stop "" 204
+
t DELETE containers/$cid 204
+t DELETE containers/$cid_top 204
# vim: filetype=sh
diff --git a/test/apiv2/rest_api/test_rest_v2_0_0.py b/test/apiv2/rest_api/test_rest_v2_0_0.py
new file mode 100644
index 000000000..3376f8402
--- /dev/null
+++ b/test/apiv2/rest_api/test_rest_v2_0_0.py
@@ -0,0 +1,246 @@
+import json
+import os
+import subprocess
+import sys
+import time
+import unittest
+from multiprocessing import Process
+
+import requests
+from dateutil.parser import parse
+
+PODMAN_URL = "http://localhost:8080"
+
+
+def _url(path):
+ return PODMAN_URL + "/v1.0.0/libpod" + path
+
+
+def podman():
+ binary = os.getenv("PODMAN_BINARY")
+ if binary is None:
+ binary = "bin/podman"
+ return binary
+
+
+def ctnr(path):
+ r = requests.get(_url("/containers/json?all=true"))
+ try:
+ ctnrs = json.loads(r.text)
+ except Exception as e:
+ sys.stderr.write("Bad container response: {}/{}".format(r.text, e))
+ raise e
+ return path.format(ctnrs[0]["Id"])
+
+
+def validateObjectFields(buffer):
+ objs = json.loads(buffer)
+ if not isinstance(objs, dict):
+ for o in objs:
+ _ = o["Id"]
+ else:
+ _ = objs["Id"]
+ return objs
+
+
+class TestApi(unittest.TestCase):
+ podman = None
+
+ def setUp(self):
+ super().setUp()
+ if TestApi.podman.poll() is not None:
+ sys.stderr.write(f"podman service returned {TestApi.podman.returncode}\n")
+ sys.exit(2)
+ requests.get(
+ _url("/images/create?fromSrc=docker.io%2Falpine%3Alatest"))
+ # calling out to podman is easier than the API for running a container
+ subprocess.run([podman(), "run", "alpine", "/bin/ls"],
+ check=True,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL)
+
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+
+ TestApi.podman = subprocess.Popen(
+ [
+ podman(), "system", "service", "tcp:localhost:8080",
+ "--log-level=debug", "--time=0"
+ ],
+ shell=False,
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ )
+ time.sleep(2)
+
+ @classmethod
+ def tearDownClass(cls):
+ TestApi.podman.terminate()
+ stdout, stderr = TestApi.podman.communicate(timeout=0.5)
+ if stdout:
+ print("\nService Stdout:\n" + stdout.decode('utf-8'))
+ if stderr:
+ print("\nService Stderr:\n" + stderr.decode('utf-8'))
+
+ if TestApi.podman.returncode > 0:
+ sys.stderr.write(f"podman exited with error code {TestApi.podman.returncode}\n")
+ sys.exit(2)
+
+ return super().tearDownClass()
+
+ def test_info(self):
+ r = requests.get(_url("/info"))
+ self.assertEqual(r.status_code, 200)
+ self.assertIsNotNone(r.content)
+ _ = json.loads(r.text)
+
+ def test_events(self):
+ r = requests.get(_url("/events?stream=false"))
+ self.assertEqual(r.status_code, 200, r.text)
+ self.assertIsNotNone(r.content)
+ for line in r.text.splitlines():
+ obj = json.loads(line)
+ # Actor.ID is uppercase for compatibility
+ _ = obj["Actor"]["ID"]
+
+ def test_containers(self):
+ r = requests.get(_url("/containers/json"), timeout=5)
+ self.assertEqual(r.status_code, 200, r.text)
+ obj = json.loads(r.text)
+ self.assertEqual(len(obj), 0)
+
+ def test_containers_all(self):
+ r = requests.get(_url("/containers/json?all=true"))
+ self.assertEqual(r.status_code, 200, r.text)
+ validateObjectFields(r.text)
+
+ def test_inspect_container(self):
+ r = requests.get(_url(ctnr("/containers/{}/json")))
+ self.assertEqual(r.status_code, 200, r.text)
+ obj = validateObjectFields(r.content)
+ _ = parse(obj["Created"])
+
+ def test_stats(self):
+ r = requests.get(_url(ctnr("/containers/{}/stats?stream=false")))
+ self.assertIn(r.status_code, (200, 409), r.text)
+ if r.status_code == 200:
+ validateObjectFields(r.text)
+
+ def test_delete_containers(self):
+ r = requests.delete(_url(ctnr("/containers/{}")))
+ self.assertEqual(r.status_code, 204, r.text)
+
+ def test_stop_containers(self):
+ r = requests.post(_url(ctnr("/containers/{}/start")))
+ self.assertIn(r.status_code, (204, 304), r.text)
+
+ r = requests.post(_url(ctnr("/containers/{}/stop")))
+ self.assertIn(r.status_code, (204, 304), r.text)
+
+ def test_start_containers(self):
+ r = requests.post(_url(ctnr("/containers/{}/stop")))
+ self.assertIn(r.status_code, (204, 304), r.text)
+
+ r = requests.post(_url(ctnr("/containers/{}/start")))
+ self.assertIn(r.status_code, (204, 304), r.text)
+
+ def test_restart_containers(self):
+ r = requests.post(_url(ctnr("/containers/{}/start")))
+ self.assertIn(r.status_code, (204, 304), r.text)
+
+ r = requests.post(_url(ctnr("/containers/{}/restart")), timeout=5)
+ self.assertEqual(r.status_code, 204, r.text)
+
+ def test_resize(self):
+ r = requests.post(_url(ctnr("/containers/{}/resize?h=43&w=80")))
+ self.assertIn(r.status_code, (200, 409), r.text)
+ if r.status_code == 200:
+ self.assertIsNone(r.text)
+
+ def test_attach_containers(self):
+ r = requests.post(_url(ctnr("/containers/{}/attach")), timeout=5)
+ self.assertIn(r.status_code, (101, 500), r.text)
+
+ def test_logs_containers(self):
+ r = requests.get(_url(ctnr("/containers/{}/logs?stdout=true")))
+ self.assertEqual(r.status_code, 200, r.text)
+
+ def test_post_create(self):
+ self.skipTest("TODO: create request body")
+ r = requests.post(_url("/containers/create?args=True"))
+ self.assertEqual(r.status_code, 200, r.text)
+ json.loads(r.text)
+
+ def test_commit(self):
+ r = requests.post(_url(ctnr("/commit?container={}")))
+ self.assertEqual(r.status_code, 200, r.text)
+ validateObjectFields(r.text)
+
+ def test_images(self):
+ r = requests.get(_url("/images/json"))
+ self.assertEqual(r.status_code, 200, r.text)
+ validateObjectFields(r.content)
+
+ def test_inspect_image(self):
+ r = requests.get(_url("/images/alpine/json"))
+ self.assertEqual(r.status_code, 200, r.text)
+ obj = validateObjectFields(r.content)
+ _ = parse(obj["Created"])
+
+ def test_delete_image(self):
+ r = requests.delete(_url("/images/alpine?force=true"))
+ self.assertEqual(r.status_code, 200, r.text)
+ json.loads(r.text)
+
+ def test_pull(self):
+ r = requests.post(_url("/images/pull?reference=alpine"), timeout=15)
+ self.assertEqual(r.status_code, 200, r.status_code)
+ text = r.text
+ keys = {
+ "error": False,
+ "id": False,
+ "images": False,
+ "stream": False,
+ }
+ # Read and record stanza's from pull
+ for line in str.splitlines(text):
+ obj = json.loads(line)
+ key_list = list(obj.keys())
+ for k in key_list:
+ keys[k] = True
+
+ self.assertFalse(keys["error"], "Expected no errors")
+ self.assertTrue(keys["id"], "Expected to find id stanza")
+ self.assertTrue(keys["images"], "Expected to find images stanza")
+ self.assertTrue(keys["stream"], "Expected to find stream progress stanza's")
+
+ def test_search(self):
+ # Had issues with this test hanging when repositories not happy
+ def do_search():
+ r = requests.get(_url("/images/search?term=alpine"), timeout=5)
+ self.assertEqual(r.status_code, 200, r.text)
+ json.loads(r.text)
+
+ search = Process(target=do_search)
+ search.start()
+ search.join(timeout=10)
+ self.assertFalse(search.is_alive(), "/images/search took too long")
+
+ def test_ping(self):
+ r = requests.get(PODMAN_URL + "/_ping")
+ self.assertEqual(r.status_code, 200, r.text)
+
+ r = requests.head(PODMAN_URL + "/_ping")
+ self.assertEqual(r.status_code, 200, r.text)
+
+ r = requests.get(_url("/_ping"))
+ self.assertEqual(r.status_code, 200, r.text)
+
+ r = requests.get(_url("/_ping"))
+ self.assertEqual(r.status_code, 200, r.text)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test/e2e/attach_test.go b/test/e2e/attach_test.go
index 7b18f71ac..8065f6298 100644
--- a/test/e2e/attach_test.go
+++ b/test/e2e/attach_test.go
@@ -40,7 +40,6 @@ var _ = Describe("Podman attach", func() {
})
It("podman attach to non-running container", func() {
- SkipIfRemote()
session := podmanTest.Podman([]string{"create", "--name", "test1", "-d", "-i", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -51,8 +50,8 @@ var _ = Describe("Podman attach", func() {
})
It("podman container attach to non-running container", func() {
- SkipIfRemote()
session := podmanTest.Podman([]string{"container", "create", "--name", "test1", "-d", "-i", ALPINE, "ls"})
+
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -87,7 +86,6 @@ var _ = Describe("Podman attach", func() {
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
})
It("podman attach to the latest container", func() {
- SkipIfRemote()
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))
@@ -96,7 +94,11 @@ var _ = Describe("Podman attach", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- results := podmanTest.Podman([]string{"attach", "-l"})
+ cid := "-l"
+ if IsRemote() {
+ cid = "test2"
+ }
+ results := podmanTest.Podman([]string{"attach", cid})
time.Sleep(2 * time.Second)
results.Signal(syscall.SIGTSTP)
Expect(results.OutputToString()).To(ContainSubstring("test2"))
diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go
index 06054bcb4..e3e1044aa 100644
--- a/test/e2e/build_test.go
+++ b/test/e2e/build_test.go
@@ -38,7 +38,6 @@ var _ = Describe("Podman build", func() {
// Let's first do the most simple build possible to make sure stuff is
// happy and then clean up after ourselves to make sure that works too.
It("podman build and remove basic alpine", func() {
- SkipIfRemote()
session := podmanTest.PodmanNoCache([]string{"build", "build/basicalpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -58,7 +57,6 @@ var _ = Describe("Podman build", func() {
})
It("podman build with logfile", func() {
- SkipIfRemote()
logfile := filepath.Join(podmanTest.TempDir, "logfile")
session := podmanTest.PodmanNoCache([]string{"build", "--tag", "test", "--logfile", logfile, "build/basicalpine"})
session.WaitWithDefaultTimeout()
@@ -91,7 +89,7 @@ var _ = Describe("Podman build", func() {
// Check that builds with different values for the squash options
// create the appropriate number of layers, then clean up after.
It("podman build basic alpine with squash", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME: This is broken should be fixed")
session := podmanTest.PodmanNoCache([]string{"build", "-f", "build/squash/Dockerfile.squash-a", "-t", "test-squash-a:latest", "build/squash"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -223,7 +221,7 @@ var _ = Describe("Podman build", func() {
})
It("podman build --http_proxy flag", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME: This is broken should be fixed")
os.Setenv("http_proxy", "1.2.3.4")
podmanTest.RestoreAllArtifacts()
dockerfile := `FROM docker.io/library/alpine:latest
diff --git a/test/e2e/commit_test.go b/test/e2e/commit_test.go
index c1a213c00..3c7bbca66 100644
--- a/test/e2e/commit_test.go
+++ b/test/e2e/commit_test.go
@@ -210,7 +210,7 @@ var _ = Describe("Podman commit", func() {
It("podman commit with volume mounts and --include-volumes", func() {
// We need to figure out how volumes are going to work correctly with the remote
// client. This does not currently work.
- SkipIfRemote()
+ SkipIfRemote("--testing Remote Volumes")
s := podmanTest.Podman([]string{"run", "--name", "test1", "-v", "/tmp:/foo", "alpine", "date"})
s.WaitWithDefaultTimeout()
Expect(s.ExitCode()).To(Equal(0))
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index 2ce3f9760..1943020c3 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -39,6 +39,7 @@ var (
ARTIFACT_DIR = "/tmp/.artifacts"
RESTORE_IMAGES = []string{ALPINE, BB, nginx}
defaultWaitTimeout = 90
+ CGROUPSV2, _ = cgroups.IsCgroup2UnifiedMode()
)
// PodmanTestIntegration struct for command line options
diff --git a/test/e2e/config.go b/test/e2e/config.go
index 71c4dee31..0e1850614 100644
--- a/test/e2e/config.go
+++ b/test/e2e/config.go
@@ -27,8 +27,4 @@ var (
// v2fail is a temporary variable to help us track
// tests that fail in v2
v2fail = "does not pass integration tests with v2 podman"
-
- // v2remotefail is a temporary variable to help us track
- // tests that fail in v2 remote
- v2remotefail = "does not pass integration tests with v2 podman remote"
)
diff --git a/test/e2e/cp_test.go b/test/e2e/cp_test.go
index df43c1b87..a53485fa4 100644
--- a/test/e2e/cp_test.go
+++ b/test/e2e/cp_test.go
@@ -141,7 +141,7 @@ var _ = Describe("Podman cp", func() {
})
It("podman cp stdin/stdout", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME: podman-remote cp not implemented yet")
session := podmanTest.Podman([]string{"create", ALPINE, "ls", "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go
index 6022be5f6..3fce536e2 100644
--- a/test/e2e/create_test.go
+++ b/test/e2e/create_test.go
@@ -108,13 +108,12 @@ var _ = Describe("Podman create", func() {
})
It("podman create --entrypoint \"\"", func() {
- Skip(v2remotefail)
session := podmanTest.Podman([]string{"create", "--entrypoint", "", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(podmanTest.NumberOfContainers()).To(Equal(1))
- result := podmanTest.Podman([]string{"inspect", "-l", "--format", "{{.Config.Entrypoint}}"})
+ result := podmanTest.Podman([]string{"inspect", session.OutputToString(), "--format", "{{.Config.Entrypoint}}"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(result.OutputToString()).To(Equal(""))
@@ -134,7 +133,6 @@ var _ = Describe("Podman create", func() {
})
It("podman create --mount flag with multiple mounts", func() {
- Skip(v2remotefail)
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
err := os.MkdirAll(vol1, 0755)
Expect(err).To(BeNil())
@@ -160,7 +158,6 @@ var _ = Describe("Podman create", func() {
if podmanTest.Host.Arch == "ppc64le" {
Skip("skip failing test on ppc64le")
}
- Skip(v2remotefail)
mountPath := filepath.Join(podmanTest.TempDir, "secrets")
os.Mkdir(mountPath, 0755)
session := podmanTest.Podman([]string{"create", "--name", "test", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"})
@@ -346,7 +343,7 @@ var _ = Describe("Podman create", func() {
})
It("podman create --signature-policy", func() {
- SkipIfRemote() // SigPolicy not handled by remote
+ 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)))
diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go
index 6841aa5a2..7d50c02b2 100644
--- a/test/e2e/exec_test.go
+++ b/test/e2e/exec_test.go
@@ -67,13 +67,14 @@ var _ = Describe("Podman exec", func() {
})
It("podman exec simple command using latest", func() {
- // the remote client doesn't use latest
- SkipIfRemote()
setup := podmanTest.RunTopContainer("test1")
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
-
- session := podmanTest.Podman([]string{"exec", "-l", "ls"})
+ cid := "-l"
+ if IsRemote() {
+ cid = "test1"
+ }
+ session := podmanTest.Podman([]string{"exec", cid, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
@@ -122,13 +123,12 @@ var _ = Describe("Podman exec", func() {
})
It("podman exec terminal doesn't hang", func() {
- Skip(v2remotefail)
- setup := podmanTest.Podman([]string{"run", "-dti", fedoraMinimal, "sleep", "+Inf"})
+ setup := podmanTest.Podman([]string{"run", "-dti", "--name", "test1", fedoraMinimal, "sleep", "+Inf"})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
for i := 0; i < 5; i++ {
- session := podmanTest.Podman([]string{"exec", "-lti", "true"})
+ session := podmanTest.Podman([]string{"exec", "-ti", "test1", "true"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
}
@@ -284,7 +284,8 @@ var _ = Describe("Podman exec", func() {
})
It("podman exec preserves container groups with --user and --group-add", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME: This is broken SECCOMP Failues?")
+
dockerfile := `FROM fedora-minimal
RUN groupadd -g 4000 first
RUN groupadd -g 4001 second
diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go
index c020860ea..71e73af9c 100644
--- a/test/e2e/healthcheck_run_test.go
+++ b/test/e2e/healthcheck_run_test.go
@@ -174,7 +174,6 @@ var _ = Describe("Podman healthcheck run", func() {
})
It("podman healthcheck single healthy result changes failed to healthy", func() {
- Skip(v2remotefail)
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))
diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go
index ddf2e20b8..d9ad10fe9 100644
--- a/test/e2e/images_test.go
+++ b/test/e2e/images_test.go
@@ -176,7 +176,7 @@ var _ = Describe("Podman images", func() {
})
It("podman images filter before image", func() {
- Skip(v2remotefail)
+ SkipIfRemote("FIXME This should work on podman-remote")
dockerfile := `FROM docker.io/library/alpine:latest
RUN apk update && apk add strace
`
@@ -189,7 +189,6 @@ RUN apk update && apk add strace
})
It("podman images workingdir from image", func() {
- Skip(v2remotefail)
dockerfile := `FROM docker.io/library/alpine:latest
WORKDIR /test
`
@@ -341,7 +340,7 @@ WORKDIR /test
})
It("podman images --all flag", func() {
- Skip(v2remotefail)
+ SkipIfRemote("FIXME This should work on podman-remote")
podmanTest.RestoreAllArtifacts()
dockerfile := `FROM docker.io/library/alpine:latest
RUN mkdir hello
@@ -361,7 +360,6 @@ ENV foo=bar
})
It("podman images filter by label", func() {
- Skip(v2remotefail)
dockerfile := `FROM docker.io/library/alpine:latest
LABEL version="1.0"
LABEL "com.example.vendor"="Example Vendor"
@@ -374,7 +372,7 @@ LABEL "com.example.vendor"="Example Vendor"
})
It("podman with images with no layers", func() {
- Skip(v2remotefail)
+ SkipIfRemote("FIXME This should work on podman-remote")
dockerfile := strings.Join([]string{
`FROM scratch`,
`LABEL org.opencontainers.image.authors="<somefolks@example.org>"`,
diff --git a/test/e2e/info_test.go b/test/e2e/info_test.go
index 6ca75848c..bcbfdd80a 100644
--- a/test/e2e/info_test.go
+++ b/test/e2e/info_test.go
@@ -79,7 +79,7 @@ var _ = Describe("Podman Info", func() {
if !rootless.IsRootless() {
Skip("test of rootless_storage_path is only meaningful as rootless")
}
- SkipIfRemote()
+ SkipIfRemote("Only tests storage on local client")
oldHOME, hasHOME := os.LookupEnv("HOME")
defer func() {
if hasHOME {
diff --git a/test/e2e/init_test.go b/test/e2e/init_test.go
index 068da5f2a..baa5c5717 100644
--- a/test/e2e/init_test.go
+++ b/test/e2e/init_test.go
@@ -75,7 +75,7 @@ var _ = Describe("Podman init", func() {
})
It("podman init latest container", func() {
- SkipIfRemote()
+ SkipIfRemote("--latest flag n/a")
session := podmanTest.Podman([]string{"create", "-d", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/inspect_test.go b/test/e2e/inspect_test.go
index f7b953356..d4de7a65c 100644
--- a/test/e2e/inspect_test.go
+++ b/test/e2e/inspect_test.go
@@ -126,7 +126,7 @@ var _ = Describe("Podman inspect", func() {
})
It("podman inspect -l with additional input should fail", func() {
- SkipIfRemote()
+ SkipIfRemote("--latest flag n/a")
result := podmanTest.Podman([]string{"inspect", "-l", "1234foobar"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(125))
@@ -173,7 +173,7 @@ var _ = Describe("Podman inspect", func() {
})
It("podman inspect --latest with no container fails", func() {
- SkipIfRemote()
+ SkipIfRemote("testing --latest flag")
session := podmanTest.Podman([]string{"inspect", "--latest"})
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/kill_test.go b/test/e2e/kill_test.go
index 3984c3414..10976fd83 100644
--- a/test/e2e/kill_test.go
+++ b/test/e2e/kill_test.go
@@ -100,12 +100,15 @@ var _ = Describe("Podman kill", func() {
})
It("podman kill latest container", func() {
- SkipIfRemote()
- session := podmanTest.RunTopContainer("")
+ session := podmanTest.RunTopContainer("test1")
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"kill", "-l"})
+ cid := "-l"
+ if IsRemote() {
+ cid = "test1"
+ }
+ result := podmanTest.Podman([]string{"kill", cid})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
diff --git a/test/e2e/libpod_suite_remote_test.go b/test/e2e/libpod_suite_remote_test.go
index 874789b5e..0a0b2799b 100644
--- a/test/e2e/libpod_suite_remote_test.go
+++ b/test/e2e/libpod_suite_remote_test.go
@@ -19,8 +19,15 @@ import (
"github.com/onsi/ginkgo"
)
-func SkipIfRemote() {
- ginkgo.Skip("This function is not enabled for remote podman")
+func IsRemote() bool {
+ return true
+}
+
+func SkipIfRemote(reason string) {
+ ginkgo.Skip("[remote]: " + reason)
+}
+
+func SkipIfRootlessCgroupsV1() {
}
func SkipIfRootless() {
diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go
index bfd898108..00d066fea 100644
--- a/test/e2e/libpod_suite_test.go
+++ b/test/e2e/libpod_suite_test.go
@@ -12,7 +12,17 @@ import (
. "github.com/onsi/ginkgo"
)
-func SkipIfRemote() {
+func IsRemote() bool {
+ return false
+}
+
+func SkipIfRemote(string) {
+}
+
+func SkipIfRootlessCgroupsV1() {
+ if os.Geteuid() != 0 && !CGROUPSV2 {
+ Skip("Rooless requires cgroupsV2 to set limits")
+ }
}
func SkipIfRootless() {
diff --git a/test/e2e/libpod_suite_varlink_test.go b/test/e2e/libpod_suite_varlink_test.go
index 750c8cd09..f901cbec9 100644
--- a/test/e2e/libpod_suite_varlink_test.go
+++ b/test/e2e/libpod_suite_varlink_test.go
@@ -19,8 +19,15 @@ import (
"github.com/onsi/ginkgo"
)
-func SkipIfRemote() {
- ginkgo.Skip("This function is not enabled for remote podman")
+func IsRemote() bool {
+ return true
+}
+
+func SkipIfRootlessCgroupsV1() {
+}
+
+func SkipIfRemote(reason string) {
+ ginkgo.Skip("[remote]: " + reason)
}
func SkipIfRootless() {
diff --git a/test/e2e/load_test.go b/test/e2e/load_test.go
index 2b401a09d..ddffadac0 100644
--- a/test/e2e/load_test.go
+++ b/test/e2e/load_test.go
@@ -123,7 +123,7 @@ var _ = Describe("Podman load", func() {
})
It("podman load directory", func() {
- SkipIfRemote()
+ SkipIfRemote("Remote does not support loading directories")
outdir := filepath.Join(podmanTest.TempDir, "alpine")
save := podmanTest.PodmanNoCache([]string{"save", "--format", "oci-dir", "-o", outdir, ALPINE})
@@ -139,6 +139,22 @@ var _ = Describe("Podman load", func() {
Expect(result.ExitCode()).To(Equal(0))
})
+ It("podman-remote load directory", func() {
+ // Remote-only test looking for the specific remote error
+ // message when trying to load a directory.
+ if !IsRemote() {
+ Skip("Remote only test")
+ }
+
+ result := podmanTest.Podman([]string{"load", "-i", podmanTest.TempDir})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(125))
+
+ errMsg := fmt.Sprintf("remote client supports archives only but %q is a directory", podmanTest.TempDir)
+ found, _ := result.ErrorGrepString(errMsg)
+ Expect(found).Should(BeTrue())
+ })
+
It("podman load bogus file", func() {
save := podmanTest.PodmanNoCache([]string{"load", "-i", "foobar.tar"})
save.WaitWithDefaultTimeout()
@@ -227,7 +243,7 @@ var _ = Describe("Podman load", func() {
})
It("podman load localhost registry from dir", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME: podman-remote load is currently broken.")
outfile := filepath.Join(podmanTest.TempDir, "load")
setup := podmanTest.PodmanNoCache([]string{"tag", BB, "hello:world"})
diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go
index e63bce3fe..3aa3cf409 100644
--- a/test/e2e/logs_test.go
+++ b/test/e2e/logs_test.go
@@ -127,7 +127,7 @@ var _ = Describe("Podman logs", func() {
})
It("two containers showing short container IDs", func() {
- SkipIfRemote() // remote does not support multiple containers
+ SkipIfRemote("FIXME: remote does not support multiple containers")
log1 := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
log1.WaitWithDefaultTimeout()
Expect(log1.ExitCode()).To(Equal(0))
diff --git a/test/e2e/manifest_test.go b/test/e2e/manifest_test.go
index 69b7b771b..33aac48d5 100644
--- a/test/e2e/manifest_test.go
+++ b/test/e2e/manifest_test.go
@@ -102,7 +102,7 @@ var _ = Describe("Podman manifest", func() {
})
It("podman manifest annotate", func() {
- SkipIfRemote()
+ SkipIfRemote("Not supporting annotate on remote connections")
session := podmanTest.Podman([]string{"manifest", "create", "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -184,8 +184,7 @@ var _ = Describe("Podman manifest", func() {
})
It("podman manifest push purge", func() {
- // remote does not support --purge
- SkipIfRemote()
+ SkipIfRemote("remote does not support --purge")
session := podmanTest.Podman([]string{"manifest", "create", "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/mount_test.go b/test/e2e/mount_test.go
index a2b448337..1fbb92b09 100644
--- a/test/e2e/mount_test.go
+++ b/test/e2e/mount_test.go
@@ -348,6 +348,25 @@ var _ = Describe("Podman mount", func() {
Expect(umount.ExitCode()).To(Equal(0))
})
+ It("podman umount --all", func() {
+ setup := podmanTest.PodmanNoCache([]string{"pull", fedoraMinimal})
+ setup.WaitWithDefaultTimeout()
+ Expect(setup.ExitCode()).To(Equal(0))
+
+ setup = podmanTest.PodmanNoCache([]string{"pull", ALPINE})
+ setup.WaitWithDefaultTimeout()
+ Expect(setup.ExitCode()).To(Equal(0))
+
+ mount := podmanTest.Podman([]string{"image", "mount", fedoraMinimal})
+ mount.WaitWithDefaultTimeout()
+ Expect(mount.ExitCode()).To(Equal(0))
+
+ umount := podmanTest.Podman([]string{"image", "umount", "--all"})
+ umount.WaitWithDefaultTimeout()
+ Expect(umount.ExitCode()).To(Equal(0))
+ Expect(len(umount.OutputToStringArray())).To(Equal(1))
+ })
+
It("podman mount many", func() {
setup := podmanTest.PodmanNoCache([]string{"pull", fedoraMinimal})
setup.WaitWithDefaultTimeout()
@@ -402,6 +421,10 @@ var _ = Describe("Podman mount", func() {
Expect(mount.ExitCode()).To(Equal(0))
Expect(mount.OutputToString()).To(Equal(""))
+ umount = podmanTest.PodmanNoCache([]string{"image", "umount", fedoraMinimal, ALPINE})
+ umount.WaitWithDefaultTimeout()
+ Expect(umount.ExitCode()).To(Equal(0))
+
mount1 = podmanTest.PodmanNoCache([]string{"image", "mount", "--all"})
mount1.WaitWithDefaultTimeout()
Expect(mount1.ExitCode()).To(Equal(0))
diff --git a/test/e2e/namespace_test.go b/test/e2e/namespace_test.go
index 916ceada0..92df3df48 100644
--- a/test/e2e/namespace_test.go
+++ b/test/e2e/namespace_test.go
@@ -33,7 +33,7 @@ var _ = Describe("Podman namespaces", func() {
})
It("podman namespace test", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on Remote")
podman1 := podmanTest.Podman([]string{"--namespace", "test1", "run", "-d", ALPINE, "echo", "hello"})
podman1.WaitWithDefaultTimeout()
Expect(podman1.ExitCode()).To(Equal(0))
diff --git a/test/e2e/network_create_test.go b/test/e2e/network_create_test.go
index 13d515d8e..8d289d6e6 100644
--- a/test/e2e/network_create_test.go
+++ b/test/e2e/network_create_test.go
@@ -137,7 +137,7 @@ var _ = Describe("Podman network create", func() {
})
It("podman network create with name and subnet", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME, this should work on --remote")
var (
results []network.NcList
)
@@ -178,7 +178,6 @@ var _ = Describe("Podman network create", func() {
})
It("podman network create with name and IPv6 subnet", func() {
- SkipIfRemote()
SkipIfRootless()
var (
results []network.NcList
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index 7a5aebcc2..d771860d8 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -591,7 +591,6 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman play kube test correct command", func() {
- SkipIfRemote()
pod := getPod()
err := generatePodKubeYaml(pod, kubeYaml)
Expect(err).To(BeNil())
@@ -609,7 +608,6 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman play kube test correct command with only set command in yaml file", func() {
- SkipIfRemote()
pod := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"}), withArg(nil))))
err := generatePodKubeYaml(pod, kubeYaml)
Expect(err).To(BeNil())
@@ -644,7 +642,6 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman play kube test correct output", func() {
- SkipIfRemote()
p := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"}), withArg([]string{"world"}))))
err := generatePodKubeYaml(p, kubeYaml)
@@ -796,7 +793,7 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman play kube seccomp container level", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This is broken")
// expect play kube is expected to set a seccomp label if it's applied as an annotation
jsonFile, err := podmanTest.CreateSeccompJson(seccompPwdEPERM)
if err != nil {
@@ -823,7 +820,7 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman play kube seccomp pod level", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME: This should work with --remote")
// expect play kube is expected to set a seccomp label if it's applied as an annotation
jsonFile, err := podmanTest.CreateSeccompJson(seccompPwdEPERM)
if err != nil {
@@ -975,7 +972,6 @@ spec:
// Deployment related tests
It("podman play kube deployment 1 replica test correct command", func() {
- SkipIfRemote()
deployment := getDeployment()
err := generateDeploymentKubeYaml(deployment, kubeYaml)
Expect(err).To(BeNil())
@@ -994,7 +990,6 @@ spec:
})
It("podman play kube deployment more than 1 replica test correct command", func() {
- SkipIfRemote()
var i, numReplicas int32
numReplicas = 5
deployment := getDeployment(withReplicas(numReplicas))
@@ -1160,7 +1155,6 @@ spec:
})
It("podman play kube applies labels to pods", func() {
- SkipIfRemote()
var numReplicas int32 = 5
expectedLabelKey := "key1"
expectedLabelValue := "value1"
diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go
index 168150bff..ce0b51517 100644
--- a/test/e2e/pod_create_test.go
+++ b/test/e2e/pod_create_test.go
@@ -124,7 +124,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with --no-hosts", func() {
- SkipIfRemote()
name := "test"
podCreate := podmanTest.Podman([]string{"pod", "create", "--no-hosts", "--name", name})
podCreate.WaitWithDefaultTimeout()
@@ -141,7 +140,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with --no-hosts and no infra should fail", func() {
- SkipIfRemote()
name := "test"
podCreate := podmanTest.Podman([]string{"pod", "create", "--no-hosts", "--name", name, "--infra=false"})
podCreate.WaitWithDefaultTimeout()
@@ -149,7 +147,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with --add-host", func() {
- SkipIfRemote()
name := "test"
podCreate := podmanTest.Podman([]string{"pod", "create", "--add-host", "test.example.com:12.34.56.78", "--name", name})
podCreate.WaitWithDefaultTimeout()
@@ -162,7 +159,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with --add-host and no infra should fail", func() {
- SkipIfRemote()
name := "test"
podCreate := podmanTest.Podman([]string{"pod", "create", "--add-host", "test.example.com:12.34.56.78", "--name", name, "--infra=false"})
podCreate.WaitWithDefaultTimeout()
@@ -170,7 +166,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with DNS server set", func() {
- SkipIfRemote()
name := "test"
server := "12.34.56.78"
podCreate := podmanTest.Podman([]string{"pod", "create", "--dns", server, "--name", name})
@@ -184,7 +179,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with DNS server set and no infra should fail", func() {
- SkipIfRemote()
name := "test"
server := "12.34.56.78"
podCreate := podmanTest.Podman([]string{"pod", "create", "--dns", server, "--name", name, "--infra=false"})
@@ -193,7 +187,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with DNS option set", func() {
- SkipIfRemote()
name := "test"
option := "attempts:5"
podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-opt", option, "--name", name})
@@ -207,7 +200,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with DNS option set and no infra should fail", func() {
- SkipIfRemote()
name := "test"
option := "attempts:5"
podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-opt", option, "--name", name, "--infra=false"})
@@ -216,7 +208,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with DNS search domain set", func() {
- SkipIfRemote()
name := "test"
search := "example.com"
podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-search", search, "--name", name})
@@ -230,7 +221,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with DNS search domain set and no infra should fail", func() {
- SkipIfRemote()
name := "test"
search := "example.com"
podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-search", search, "--name", name, "--infra=false"})
@@ -256,7 +246,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with IP address and no infra should fail", func() {
- SkipIfRemote()
name := "test"
ip := GetRandomIPAddress()
podCreate := podmanTest.Podman([]string{"pod", "create", "--ip", ip, "--name", name, "--infra=false"})
@@ -265,7 +254,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with MAC address", func() {
- SkipIfRemote()
name := "test"
mac := "92:d0:c6:0a:29:35"
podCreate := podmanTest.Podman([]string{"pod", "create", "--mac-address", mac, "--name", name})
@@ -283,7 +271,6 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with MAC address and no infra should fail", func() {
- SkipIfRemote()
name := "test"
mac := "92:d0:c6:0a:29:35"
podCreate := podmanTest.Podman([]string{"pod", "create", "--mac-address", mac, "--name", name, "--infra=false"})
diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go
index 98f1b5174..515391f92 100644
--- a/test/e2e/pod_infra_container_test.go
+++ b/test/e2e/pod_infra_container_test.go
@@ -225,7 +225,7 @@ var _ = Describe("Podman pod create", func() {
})
It("podman pod container can override pod pid NS", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
session := podmanTest.Podman([]string{"pod", "create", "--share", "pid"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -257,7 +257,7 @@ var _ = Describe("Podman pod create", func() {
})
It("podman pod container can override pod not sharing pid", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
session := podmanTest.Podman([]string{"pod", "create", "--share", "net"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -283,7 +283,7 @@ var _ = Describe("Podman pod create", func() {
})
It("podman pod container can override pod ipc NS", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
session := podmanTest.Podman([]string{"pod", "create", "--share", "ipc"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -380,6 +380,7 @@ var _ = Describe("Podman pod create", func() {
})
It("podman run --add-host in pod", func() {
+ SkipIfRemote("FIXME This should work on podman-remote")
session := podmanTest.Podman([]string{"pod", "create"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/pod_kill_test.go b/test/e2e/pod_kill_test.go
index d7462e16d..f968f73a6 100644
--- a/test/e2e/pod_kill_test.go
+++ b/test/e2e/pod_kill_test.go
@@ -100,7 +100,6 @@ var _ = Describe("Podman pod kill", func() {
})
It("podman pod kill latest pod", func() {
- SkipIfRemote()
_, ec, podid := podmanTest.CreatePod("")
Expect(ec).To(Equal(0))
@@ -118,8 +117,10 @@ var _ = Describe("Podman pod kill", func() {
session = podmanTest.RunTopContainerInPod("", podid2)
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
-
- result := podmanTest.Podman([]string{"pod", "kill", "-l"})
+ if !IsRemote() {
+ podid2 = "-l"
+ }
+ result := podmanTest.Podman([]string{"pod", "kill", podid2})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
diff --git a/test/e2e/pod_pod_namespaces.go b/test/e2e/pod_pod_namespaces.go
index f72f98b5f..3139bf561 100644
--- a/test/e2e/pod_pod_namespaces.go
+++ b/test/e2e/pod_pod_namespaces.go
@@ -61,7 +61,7 @@ var _ = Describe("Podman pod create", func() {
})
It("podman pod container dontshare PIDNS", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
session := podmanTest.Podman([]string{"pod", "create"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/pod_ps_test.go b/test/e2e/pod_ps_test.go
index 602d9d577..17ed6a9c0 100644
--- a/test/e2e/pod_ps_test.go
+++ b/test/e2e/pod_ps_test.go
@@ -83,7 +83,7 @@ var _ = Describe("Podman ps", func() {
})
It("podman pod ps latest", func() {
- SkipIfRemote()
+ SkipIfRemote("--latest flag n/a")
_, ec, podid1 := podmanTest.CreatePod("")
Expect(ec).To(Equal(0))
@@ -212,17 +212,17 @@ var _ = Describe("Podman ps", func() {
Expect(ec).To(Equal(0))
_, ec, podid2 := podmanTest.CreatePodWithLabels("", map[string]string{
- "io.podman.test.label": "value1",
- "io.podman.test.key": "irrelevant-value",
+ "app": "myapp",
+ "io.podman.test.key": "irrelevant-value",
})
Expect(ec).To(Equal(0))
_, ec, podid3 := podmanTest.CreatePodWithLabels("", map[string]string{
- "io.podman.test.label": "value2",
+ "app": "test",
})
Expect(ec).To(Equal(0))
- session := podmanTest.Podman([]string{"pod", "ps", "--no-trunc", "--filter", "label=io.podman.test.key", "--filter", "label=io.podman.test.label=value1"})
+ session := podmanTest.Podman([]string{"pod", "ps", "--no-trunc", "--filter", "label=app", "--filter", "label=app=myapp"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Not(ContainSubstring(podid1)))
diff --git a/test/e2e/pod_restart_test.go b/test/e2e/pod_restart_test.go
index 9fe6c1a85..b358c2c7a 100644
--- a/test/e2e/pod_restart_test.go
+++ b/test/e2e/pod_restart_test.go
@@ -134,7 +134,6 @@ var _ = Describe("Podman pod restart", func() {
})
It("podman pod restart latest pod", func() {
- SkipIfRemote()
_, ec, _ := podmanTest.CreatePod("foobar99")
Expect(ec).To(Equal(0))
@@ -152,7 +151,11 @@ var _ = Describe("Podman pod restart", func() {
startTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"})
startTime.WaitWithDefaultTimeout()
- session = podmanTest.Podman([]string{"pod", "restart", "-l"})
+ podid := "-l"
+ if IsRemote() {
+ podid = "foobar100"
+ }
+ session = podmanTest.Podman([]string{"pod", "restart", podid})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go
index 918d0eb32..cb9b93a15 100644
--- a/test/e2e/pod_rm_test.go
+++ b/test/e2e/pod_rm_test.go
@@ -61,14 +61,17 @@ var _ = Describe("Podman pod rm", func() {
})
It("podman pod rm latest pod", func() {
- SkipIfRemote()
_, ec, podid := podmanTest.CreatePod("")
Expect(ec).To(Equal(0))
- _, ec2, podid2 := podmanTest.CreatePod("")
+ _, ec2, podid2 := podmanTest.CreatePod("pod2")
Expect(ec2).To(Equal(0))
- result := podmanTest.Podman([]string{"pod", "rm", "--latest"})
+ latest := "--latest"
+ if IsRemote() {
+ latest = "pod2"
+ }
+ result := podmanTest.Podman([]string{"pod", "rm", latest})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
diff --git a/test/e2e/pod_start_test.go b/test/e2e/pod_start_test.go
index 2f0160e99..63a915548 100644
--- a/test/e2e/pod_start_test.go
+++ b/test/e2e/pod_start_test.go
@@ -107,7 +107,6 @@ var _ = Describe("Podman pod start", func() {
})
It("podman pod start latest pod", func() {
- SkipIfRemote()
_, ec, _ := podmanTest.CreatePod("foobar99")
Expect(ec).To(Equal(0))
@@ -122,7 +121,11 @@ var _ = Describe("Podman pod start", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"pod", "start", "--latest"})
+ podid := "--latest"
+ if IsRemote() {
+ podid = "foobar100"
+ }
+ session = podmanTest.Podman([]string{"pod", "start", podid})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
diff --git a/test/e2e/pod_stop_test.go b/test/e2e/pod_stop_test.go
index 2363974cc..4eb897786 100644
--- a/test/e2e/pod_stop_test.go
+++ b/test/e2e/pod_stop_test.go
@@ -143,7 +143,6 @@ var _ = Describe("Podman pod stop", func() {
})
It("podman pod stop latest pod", func() {
- SkipIfRemote()
_, ec, _ := podmanTest.CreatePod("foobar99")
Expect(ec).To(Equal(0))
@@ -158,7 +157,11 @@ var _ = Describe("Podman pod stop", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.Podman([]string{"pod", "stop", "--latest"})
+ podid := "--latest"
+ if IsRemote() {
+ podid = "foobar100"
+ }
+ session = podmanTest.Podman([]string{"pod", "stop", podid})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
diff --git a/test/e2e/pod_top_test.go b/test/e2e/pod_top_test.go
index 2cb7a623e..9e3570360 100644
--- a/test/e2e/pod_top_test.go
+++ b/test/e2e/pod_top_test.go
@@ -56,7 +56,6 @@ var _ = Describe("Podman top", func() {
})
It("podman pod top on pod", func() {
- SkipIfRemote()
_, ec, podid := podmanTest.CreatePod("")
Expect(ec).To(Equal(0))
@@ -64,7 +63,10 @@ var _ = Describe("Podman top", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"pod", "top", "-l"})
+ if !IsRemote() {
+ podid = "-l"
+ }
+ result := podmanTest.Podman([]string{"pod", "top", podid})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1))
diff --git a/test/e2e/port_test.go b/test/e2e/port_test.go
index fce092e2d..a3ce8bd69 100644
--- a/test/e2e/port_test.go
+++ b/test/e2e/port_test.go
@@ -47,15 +47,17 @@ var _ = Describe("Podman port", func() {
})
It("podman port -l nginx", func() {
- SkipIfRemote()
- session, cid := podmanTest.RunNginxWithHealthCheck("")
+ session, cid := podmanTest.RunNginxWithHealthCheck("test1")
Expect(session.ExitCode()).To(Equal(0))
if err := podmanTest.RunHealthCheck(cid); err != nil {
Fail(err.Error())
}
- result := podmanTest.Podman([]string{"port", "-l"})
+ if !IsRemote() {
+ cid = "-l"
+ }
+ result := podmanTest.Podman([]string{"port", cid})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
port := strings.Split(result.OutputToStringArray()[0], ":")[1]
@@ -63,7 +65,6 @@ var _ = Describe("Podman port", func() {
})
It("podman container port -l nginx", func() {
- SkipIfRemote()
session, cid := podmanTest.RunNginxWithHealthCheck("")
Expect(session.ExitCode()).To(Equal(0))
@@ -71,7 +72,10 @@ var _ = Describe("Podman port", func() {
Fail(err.Error())
}
- result := podmanTest.Podman([]string{"container", "port", "-l"})
+ if !IsRemote() {
+ cid = "-l"
+ }
+ result := podmanTest.Podman([]string{"container", "port", cid})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
port := strings.Split(result.OutputToStringArray()[0], ":")[1]
@@ -79,7 +83,6 @@ var _ = Describe("Podman port", func() {
})
It("podman port -l port nginx", func() {
- SkipIfRemote()
session, cid := podmanTest.RunNginxWithHealthCheck("")
Expect(session.ExitCode()).To(Equal(0))
@@ -87,7 +90,10 @@ var _ = Describe("Podman port", func() {
Fail(err.Error())
}
- result := podmanTest.Podman([]string{"port", "-l", "80"})
+ if !IsRemote() {
+ cid = "-l"
+ }
+ result := podmanTest.Podman([]string{"port", cid, "80"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
port := strings.Split(result.OutputToStringArray()[0], ":")[1]
diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go
index 9c9d85194..24b88bfdd 100644
--- a/test/e2e/prune_test.go
+++ b/test/e2e/prune_test.go
@@ -88,7 +88,7 @@ var _ = Describe("Podman prune", func() {
})
It("podman image prune skip cache images", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME should work on podman --remote")
podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true")
none := podmanTest.Podman([]string{"images", "-a"})
@@ -110,7 +110,7 @@ var _ = Describe("Podman prune", func() {
})
It("podman image prune dangling images", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true")
podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true")
@@ -147,7 +147,7 @@ var _ = Describe("Podman prune", func() {
})
It("podman system image prune unused images", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
podmanTest.RestoreAllArtifacts()
podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true")
prune := podmanTest.PodmanNoCache([]string{"system", "prune", "-a", "--force"})
diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go
index 66233412c..f6640906a 100644
--- a/test/e2e/ps_test.go
+++ b/test/e2e/ps_test.go
@@ -101,7 +101,7 @@ var _ = Describe("Podman ps", func() {
})
It("podman ps latest flag", func() {
- SkipIfRemote()
+ SkipIfRemote("--latest is not supported on podman-remote")
_, ec, _ := podmanTest.RunLsContainer("")
Expect(ec).To(Equal(0))
_, ec, _ = podmanTest.RunLsContainer("")
diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go
index 98b81876a..2280d16cc 100644
--- a/test/e2e/pull_test.go
+++ b/test/e2e/pull_test.go
@@ -235,7 +235,7 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull from docker-archive", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
podmanTest.RestoreArtifact(ALPINE)
tarfn := filepath.Join(podmanTest.TempDir, "alp.tar")
session := podmanTest.PodmanNoCache([]string{"save", "-o", tarfn, "alpine"})
@@ -297,7 +297,7 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull from oci-archive", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
podmanTest.RestoreArtifact(ALPINE)
tarfn := filepath.Join(podmanTest.TempDir, "oci-alp.tar")
session := podmanTest.PodmanNoCache([]string{"save", "--format", "oci-archive", "-o", tarfn, "alpine"})
@@ -316,7 +316,7 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull from local directory", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
podmanTest.RestoreArtifact(ALPINE)
dirpath := filepath.Join(podmanTest.TempDir, "alpine")
os.MkdirAll(dirpath, os.ModePerm)
@@ -341,7 +341,7 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull from local OCI directory", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
podmanTest.RestoreArtifact(ALPINE)
dirpath := filepath.Join(podmanTest.TempDir, "alpine")
os.MkdirAll(dirpath, os.ModePerm)
diff --git a/test/e2e/restart_test.go b/test/e2e/restart_test.go
index 4348eae3b..789b4dee5 100644
--- a/test/e2e/restart_test.go
+++ b/test/e2e/restart_test.go
@@ -122,7 +122,6 @@ var _ = Describe("Podman restart", func() {
})
It("Podman restart the latest container", func() {
- SkipIfRemote()
_, exitCode, _ := podmanTest.RunLsContainer("test1")
Expect(exitCode).To(Equal(0))
@@ -132,7 +131,11 @@ var _ = Describe("Podman restart", func() {
startTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"})
startTime.WaitWithDefaultTimeout()
- session := podmanTest.Podman([]string{"restart", "-l"})
+ cid := "-l"
+ if IsRemote() {
+ cid = "test2"
+ }
+ session := podmanTest.Podman([]string{"restart", cid})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
restartTime := podmanTest.Podman([]string{"inspect", "--format='{{.State.StartedAt}}'", "test1", "test2"})
diff --git a/test/e2e/rm_test.go b/test/e2e/rm_test.go
index 764d25ba5..cc2f7daf1 100644
--- a/test/e2e/rm_test.go
+++ b/test/e2e/rm_test.go
@@ -123,15 +123,18 @@ var _ = Describe("Podman rm", func() {
})
It("podman rm the latest container", func() {
- SkipIfRemote()
session := podmanTest.Podman([]string{"create", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec, cid := podmanTest.RunLsContainer("")
+ _, ec, cid := podmanTest.RunLsContainer("test1")
Expect(ec).To(Equal(0))
- result := podmanTest.Podman([]string{"rm", "-l"})
+ latest := "-l"
+ if IsRemote() {
+ latest = "test1"
+ }
+ result := podmanTest.Podman([]string{"rm", latest})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
output := result.OutputToString()
@@ -193,7 +196,7 @@ var _ = Describe("Podman rm", func() {
})
It("podman rm invalid --latest and --cidfile and --all", func() {
- SkipIfRemote()
+ SkipIfRemote("Verifying --latest flag")
result := podmanTest.Podman([]string{"rm", "--cidfile", "foobar", "--latest"})
result.WaitWithDefaultTimeout()
diff --git a/test/e2e/rmi_test.go b/test/e2e/rmi_test.go
index 4db6a1962..8a5014899 100644
--- a/test/e2e/rmi_test.go
+++ b/test/e2e/rmi_test.go
@@ -185,7 +185,7 @@ var _ = Describe("Podman rmi", func() {
})
It("podman rmi with cached images", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
session := podmanTest.PodmanNoCache([]string{"rmi", "-fa"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
@@ -255,7 +255,7 @@ var _ = Describe("Podman rmi", func() {
})
It("podman rmi -a with parent|child images", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
dockerfile := `FROM docker.io/library/alpine:latest AS base
RUN touch /1
ENV LOCAL=/1
diff --git a/test/e2e/run_cleanup_test.go b/test/e2e/run_cleanup_test.go
index f293e709a..153bc53ad 100644
--- a/test/e2e/run_cleanup_test.go
+++ b/test/e2e/run_cleanup_test.go
@@ -33,7 +33,7 @@ var _ = Describe("Podman run exit", func() {
})
It("podman run -d mount cleanup test", func() {
- SkipIfRemote()
+ SkipIfRemote("podman-remote does not support mount")
SkipIfRootless()
result := podmanTest.Podman([]string{"run", "-dt", ALPINE, "top"})
diff --git a/test/e2e/run_entrypoint_test.go b/test/e2e/run_entrypoint_test.go
index c1061be85..13a9abf9b 100644
--- a/test/e2e/run_entrypoint_test.go
+++ b/test/e2e/run_entrypoint_test.go
@@ -44,7 +44,6 @@ CMD []
})
It("podman run entrypoint", func() {
- SkipIfRemote()
dockerfile := `FROM docker.io/library/alpine:latest
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
@@ -56,7 +55,6 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run entrypoint with cmd", func() {
- SkipIfRemote()
dockerfile := `FROM docker.io/library/alpine:latest
CMD [ "-v"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
@@ -69,7 +67,6 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run entrypoint with user cmd overrides image cmd", func() {
- SkipIfRemote()
dockerfile := `FROM docker.io/library/alpine:latest
CMD [ "-v"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
@@ -82,7 +79,6 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run entrypoint with user cmd no image cmd", func() {
- SkipIfRemote()
dockerfile := `FROM docker.io/library/alpine:latest
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
@@ -94,7 +90,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run user entrypoint overrides image entrypoint and image cmd", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
dockerfile := `FROM docker.io/library/alpine:latest
CMD ["-i"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
@@ -112,7 +108,6 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run user entrypoint with command overrides image entrypoint and image cmd", func() {
- SkipIfRemote()
dockerfile := `FROM docker.io/library/alpine:latest
CMD ["-i"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
diff --git a/test/e2e/run_env_test.go b/test/e2e/run_env_test.go
index 801a3d014..3f488ada5 100644
--- a/test/e2e/run_env_test.go
+++ b/test/e2e/run_env_test.go
@@ -90,7 +90,7 @@ var _ = Describe("Podman run", func() {
})
It("podman run --env-host environment test", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME, We should check that --env-host reports correct error on podman-remote")
env := append(os.Environ(), "FOO=BAR")
session := podmanTest.PodmanAsUser([]string{"run", "--rm", "--env-host", ALPINE, "/bin/printenv", "FOO"}, 0, 0, "", env)
@@ -108,7 +108,7 @@ var _ = Describe("Podman run", func() {
})
It("podman run --http-proxy test", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME: Should report proper error when http-proxy is not supported")
os.Setenv("http_proxy", "1.2.3.4")
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "printenv", "http_proxy"})
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index c20bfe631..12f5018b8 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -528,7 +528,6 @@ var _ = Describe("Podman run networking", func() {
})
It("podman run in custom CNI network with --static-ip", func() {
- SkipIfRemote()
SkipIfRootless()
netName := "podmantestnetwork"
ipAddr := "10.25.30.128"
@@ -544,7 +543,6 @@ var _ = Describe("Podman run networking", func() {
})
It("podman run with new:pod and static-ip", func() {
- SkipIfRemote()
SkipIfRootless()
netName := "podmantestnetwork2"
ipAddr := "10.25.40.128"
diff --git a/test/e2e/run_passwd_test.go b/test/e2e/run_passwd_test.go
index dfb8c72a1..e7b86c68b 100644
--- a/test/e2e/run_passwd_test.go
+++ b/test/e2e/run_passwd_test.go
@@ -60,7 +60,6 @@ var _ = Describe("Podman run passwd", func() {
})
It("podman can run container without /etc/passwd", func() {
- SkipIfRemote()
dockerfile := `FROM alpine
RUN rm -f /etc/passwd /etc/shadow /etc/group
USER 1000`
@@ -114,7 +113,6 @@ USER 1000`
})
It("podman run numeric group from image and no group file", func() {
- SkipIfRemote()
dockerfile := `FROM alpine
RUN rm -f /etc/passwd /etc/shadow /etc/group
USER 1000`
diff --git a/test/e2e/run_restart_test.go b/test/e2e/run_restart_test.go
index 6150d63e5..1bef3f954 100644
--- a/test/e2e/run_restart_test.go
+++ b/test/e2e/run_restart_test.go
@@ -33,7 +33,7 @@ var _ = Describe("Podman run restart containers", func() {
})
It("Podman start after successful run", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
session := podmanTest.Podman([]string{"run", "--name", "test", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/run_security_labels.go b/test/e2e/run_security_labels.go
index e907607b5..7c8597866 100644
--- a/test/e2e/run_security_labels.go
+++ b/test/e2e/run_security_labels.go
@@ -127,7 +127,7 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman container runlabel (podman --version)", func() {
- SkipIfRemote()
+ SkipIfRemote("runlabel not supported on podman-remote")
PodmanDockerfile := `
FROM alpine:latest
LABEL io.containers.capabilities=chown,mknod`
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index cbfb6bf59..0bb3fe772 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -11,7 +11,6 @@ import (
"syscall"
"time"
- "github.com/containers/podman/v2/pkg/cgroups"
. "github.com/containers/podman/v2/test/utils"
"github.com/containers/storage/pkg/stringid"
"github.com/mrunalp/fileutils"
@@ -50,7 +49,6 @@ var _ = Describe("Podman run", func() {
})
It("podman run a container based on a complex local image name", func() {
- SkipIfRootless()
imageName := strings.TrimPrefix(nginx, "quay.io/")
session := podmanTest.Podman([]string{"run", imageName, "ls"})
session.WaitWithDefaultTimeout()
@@ -59,7 +57,7 @@ var _ = Describe("Podman run", func() {
})
It("podman run --signature-policy", func() {
- SkipIfRemote() // SigPolicy not handled by remote
+ 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)))
@@ -295,7 +293,7 @@ var _ = Describe("Podman run", func() {
})
It("podman run user capabilities test with image", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
dockerfile := `FROM busybox
USER bin`
podmanTest.BuildImage(dockerfile, "test", "false")
@@ -311,12 +309,15 @@ USER bin`
})
It("podman run limits test", func() {
- SkipIfRootless()
- 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))
+ SkipIfRootlessCgroupsV1()
- session = podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=2048:2048", fedoraMinimal, "ulimit", "-n"})
+ 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))
+ }
+
+ session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=2048:2048", fedoraMinimal, "ulimit", "-n"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("2048"))
@@ -326,10 +327,7 @@ USER bin`
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("1024"))
- cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
- Expect(err).To(BeNil())
-
- if !cgroupsv2 {
+ 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()
@@ -343,7 +341,7 @@ USER bin`
})
It("podman run limits host test", func() {
- SkipIfRemote()
+ SkipIfRemote("This can only be used for local tests")
var l syscall.Rlimit
@@ -370,7 +368,7 @@ USER bin`
})
It("podman run sysctl test", func() {
- SkipIfRootless()
+ SkipIfRootless() // Network sysclts are not avalable 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))
@@ -378,17 +376,15 @@ USER bin`
})
It("podman run blkio-weight test", func() {
- SkipIfRootless()
- cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
- Expect(err).To(BeNil())
-
- if !cgroupsv2 {
+ SkipIfRootless() // FIXME: This is blowing up because of no /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control file
+ // SkipIfRootlessCgroupsV1()
+ if !CGROUPSV2 {
if _, err := os.Stat("/sys/fs/cgroup/blkio/blkio.weight"); os.IsNotExist(err) {
Skip("Kernel does not support blkio.weight")
}
}
- if cgroupsv2 {
+ if CGROUPSV2 {
// convert linearly from [10-1000] to [1-10000]
session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.bfq.weight"})
session.WaitWithDefaultTimeout()
@@ -403,14 +399,11 @@ USER bin`
})
It("podman run device-read-bps test", func() {
- SkipIfRootless()
-
- cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
- Expect(err).To(BeNil())
-
+ SkipIfRootless() // FIXME: Missing /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control
+ SkipIfRootlessCgroupsV1()
var session *PodmanSessionIntegration
- if cgroupsv2 {
+ if CGROUPSV2 {
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
} else {
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"})
@@ -418,40 +411,34 @@ USER bin`
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- if !cgroupsv2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
+ if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
Expect(session.OutputToString()).To(ContainSubstring("1048576"))
}
})
It("podman run device-write-bps test", func() {
- SkipIfRootless()
-
- cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
- Expect(err).To(BeNil())
-
+ SkipIfRootless() // FIXME /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control does not exist
+ SkipIfRootlessCgroupsV1()
var session *PodmanSessionIntegration
- if cgroupsv2 {
+ if CGROUPSV2 {
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
} else {
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))
- if !cgroupsv2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
+ if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
Expect(session.OutputToString()).To(ContainSubstring("1048576"))
}
})
It("podman run device-read-iops test", func() {
- SkipIfRootless()
-
- cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
- Expect(err).To(BeNil())
-
+ SkipIfRootless() // FIXME /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control does not exist
+ SkipIfRootlessCgroupsV1()
var session *PodmanSessionIntegration
- if cgroupsv2 {
+ if CGROUPSV2 {
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
} else {
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_iops_device"})
@@ -459,20 +446,17 @@ USER bin`
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- if !cgroupsv2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
+ if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
Expect(session.OutputToString()).To(ContainSubstring("100"))
}
})
It("podman run device-write-iops test", func() {
- SkipIfRootless()
-
- cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
- Expect(err).To(BeNil())
-
+ SkipIfRootless() // FIXME /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control does not exist
+ SkipIfRootlessCgroupsV1()
var session *PodmanSessionIntegration
- if cgroupsv2 {
+ if CGROUPSV2 {
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
} else {
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_iops_device"})
@@ -480,13 +464,13 @@ USER bin`
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- if !cgroupsv2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
+ if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
Expect(session.OutputToString()).To(ContainSubstring("100"))
}
})
It("podman run notify_socket", func() {
- SkipIfRemote()
+ SkipIfRemote("This can only be used for local tests")
host := GetHostDistributionInfo()
if host.Distribution != "rhel" && host.Distribution != "centos" && host.Distribution != "fedora" {
@@ -546,7 +530,7 @@ USER bin`
})
It("podman run with secrets", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
containersDir := filepath.Join(podmanTest.TempDir, "containers")
err := os.MkdirAll(containersDir, 0755)
Expect(err).To(BeNil())
@@ -586,7 +570,7 @@ USER bin`
})
It("podman run with FIPS mode secrets", func() {
- SkipIfRootless()
+ SkipIfRootless() // rootless can not manipulate system-fips file
fipsFile := "/etc/system-fips"
err = ioutil.WriteFile(fipsFile, []byte{}, 0755)
Expect(err).To(BeNil())
@@ -601,27 +585,24 @@ USER bin`
})
It("podman run without group-add", func() {
- SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- Expect(session.OutputToString()).To(Equal("uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)"))
+ Expect(session.LineInOutputContains("27(video),777,65533(nogroup)")).To(BeFalse())
})
It("podman run with group-add", func() {
- SkipIfRootless()
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.OutputToString()).To(Equal("uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),18(audio),20(dialout),26(tape),27(video),777,65533(nogroup)"))
+ Expect(session.LineInOutputContains("777,65533(nogroup)")).To(BeTrue())
})
It("podman run with user (default)", func() {
- SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- Expect(session.OutputToString()).To(Equal("uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)"))
+ Expect(session.LineInOutputContains("uid=0(root) gid=0(root)")).To(BeTrue())
})
It("podman run with user (integer, not in /etc/passwd)", func() {
@@ -632,19 +613,17 @@ USER bin`
})
It("podman run with user (integer, in /etc/passwd)", func() {
- SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--rm", "--user=8", ALPINE, "id"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=12(mail) groups=12(mail)"))
+ Expect(session.LineInOutputContains("uid=8(mail) gid=12(mail)")).To(BeTrue())
})
It("podman run with user (username)", func() {
- SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--rm", "--user=mail", ALPINE, "id"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=12(mail) groups=12(mail)"))
+ Expect(session.LineInOutputContains("uid=8(mail) gid=12(mail)")).To(BeTrue())
})
It("podman run with user:group (username:integer)", func() {
@@ -711,7 +690,7 @@ USER bin`
})
It("podman run with built-in volume image", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
session := podmanTest.Podman([]string{"run", "--rm", redis, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -733,23 +712,85 @@ USER mail`
err := os.MkdirAll(vol, 0755)
Expect(err).To(BeNil())
- volFile := filepath.Join(vol, "test.txt")
+ filename := "test.txt"
+ volFile := filepath.Join(vol, filename)
+ data := "Testing --volumes-from!!!"
+ err = ioutil.WriteFile(volFile, []byte(data), 0755)
+ Expect(err).To(BeNil())
+ mountpoint := "/myvol/"
+
+ session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint, ALPINE, "cat", mountpoint + filename})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(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.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))
+
+ session = podmanTest.Podman([]string{"start", "--attach", ctrID})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal(data + "test"))
+ })
+
+ It("podman run --volumes-from flag options", func() {
+ vol := filepath.Join(podmanTest.TempDir, "vol-test")
+ err := os.MkdirAll(vol, 0755)
+ Expect(err).To(BeNil())
+
+ filename := "test.txt"
+ volFile := filepath.Join(vol, filename)
data := "Testing --volumes-from!!!"
err = ioutil.WriteFile(volFile, []byte(data), 0755)
Expect(err).To(BeNil())
+ mountpoint := "/myvol/"
- session := podmanTest.Podman([]string{"create", "--volume", vol + ":/myvol", redis, "sh"})
+ session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint, ALPINE, "cat", mountpoint + filename})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
ctrID := session.OutputToString()
- session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "echo", "'testing read-write!' >> myvol/test.txt"})
+ // 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.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.OutputToString()).To(Equal(data))
- session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":z", ALPINE, "ls"})
+ // 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.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.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))
+ 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.ErrorToString()).To(ContainSubstring("Read-only file system"))
})
It("podman run --volumes-from flag with built-in volumes", func() {
@@ -848,7 +889,7 @@ USER mail`
})
It("podman run --mount type=bind,bind-nonrecursive", func() {
- SkipIfRootless()
+ SkipIfRootless() // 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))
@@ -856,7 +897,6 @@ USER mail`
})
It("podman run --mount type=devpts,target=/foo/bar", func() {
- SkipIfRootless()
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))
@@ -966,7 +1006,7 @@ USER mail`
})
It("podman run with restart-policy always restarts containers", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
testDir := filepath.Join(podmanTest.RunRoot, "restart-test")
err := os.MkdirAll(testDir, 0755)
Expect(err).To(BeNil())
@@ -1009,8 +1049,8 @@ USER mail`
})
It("podman run with cgroups=disabled runs without cgroups", func() {
- SkipIfRemote()
- SkipIfRootless()
+ SkipIfRootless() // FIXME: I believe this should work but need to fix this test
+ SkipIfRootlessCgroupsV1()
// Only works on crun
if !strings.Contains(podmanTest.OCIRuntime, "crun") {
Skip("Test only works on crun")
@@ -1042,8 +1082,7 @@ USER mail`
})
It("podman run with cgroups=enabled makes cgroups", func() {
- SkipIfRemote()
- SkipIfRootless()
+ SkipIfRootlessCgroupsV1()
// Only works on crun
if !strings.Contains(podmanTest.OCIRuntime, "crun") {
Skip("Test only works on crun")
@@ -1086,7 +1125,7 @@ USER mail`
})
It("podman run --device-cgroup-rule", func() {
- SkipIfRootless()
+ SkipIfRootless() // rootless users are not allowed to mknod
deviceCgroupRule := "c 42:* rwm"
session := podmanTest.Podman([]string{"run", "--name", "test", "-d", "--device-cgroup-rule", deviceCgroupRule, ALPINE, "top"})
session.WaitWithDefaultTimeout()
@@ -1205,7 +1244,6 @@ USER mail`
It("podman run makes workdir from image", func() {
// BuildImage does not seem to work remote
- SkipIfRemote()
dockerfile := `FROM busybox
WORKDIR /madethis`
podmanTest.BuildImage(dockerfile, "test", "false")
diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go
index c4ee05af9..0e0195c9f 100644
--- a/test/e2e/run_volume_test.go
+++ b/test/e2e/run_volume_test.go
@@ -197,7 +197,7 @@ var _ = Describe("Podman run with volumes", func() {
})
It("podman run with volumes and suid/dev/exec options", func() {
- SkipIfRemote()
+ SkipIfRemote("podman-remote does not support --volumes")
mountPath := filepath.Join(podmanTest.TempDir, "secrets")
os.Mkdir(mountPath, 0755)
@@ -227,7 +227,7 @@ var _ = Describe("Podman run with volumes", func() {
})
It("podman run with tmpfs named volume mounts and unmounts", func() {
- SkipIfRemote()
+ SkipIfRemote("podman-remote does not support --volumes this test could be simplified to be tested on Remote.")
SkipIfRootless()
volName := "testvol"
mkVolume := podmanTest.Podman([]string{"volume", "create", "--opt", "type=tmpfs", "--opt", "device=tmpfs", "--opt", "o=nodev", "testvol"})
@@ -315,7 +315,6 @@ var _ = Describe("Podman run with volumes", func() {
})
It("podman run with anonymous volume", func() {
- SkipIfRemote()
list1 := podmanTest.Podman([]string{"volume", "list", "--quiet"})
list1.WaitWithDefaultTimeout()
Expect(list1.ExitCode()).To(Equal(0))
@@ -334,7 +333,6 @@ var _ = Describe("Podman run with volumes", func() {
})
It("podman rm -v removes anonymous volume", func() {
- SkipIfRemote()
list1 := podmanTest.Podman([]string{"volume", "list", "--quiet"})
list1.WaitWithDefaultTimeout()
Expect(list1.ExitCode()).To(Equal(0))
@@ -436,7 +434,6 @@ var _ = Describe("Podman run with volumes", func() {
})
It("Podman mount over image volume with trailing /", func() {
- SkipIfRemote()
image := "podman-volume-test:trailing"
dockerfile := `
FROM alpine:latest
@@ -456,7 +453,7 @@ VOLUME /test/`
})
It("podman run with overlay volume flag", func() {
- SkipIfRemote()
+ SkipIfRemote("Overlay volumes only work locally")
if os.Getenv("container") != "" {
Skip("Overlay mounts not supported when running in a container")
}
diff --git a/test/e2e/run_working_dir.go b/test/e2e/run_working_dir.go
index 93330deba..85aa0cffe 100644
--- a/test/e2e/run_working_dir.go
+++ b/test/e2e/run_working_dir.go
@@ -50,7 +50,7 @@ var _ = Describe("Podman run", func() {
})
It("podman run a container on an image with a workdir", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
dockerfile := `FROM alpine
RUN mkdir -p /home/foobar
WORKDIR /etc/foobar`
diff --git a/test/e2e/runlabel_test.go b/test/e2e/runlabel_test.go
index 0eb679fbf..81a746b86 100644
--- a/test/e2e/runlabel_test.go
+++ b/test/e2e/runlabel_test.go
@@ -29,8 +29,7 @@ var _ = Describe("podman container runlabel", func() {
)
BeforeEach(func() {
- // runlabel is not supported for remote connections
- SkipIfRemote()
+ SkipIfRemote("runlabel is not supported for remote connections")
tempdir, err = CreateTempDirInTempDir()
if err != nil {
os.Exit(1)
diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go
index c6766fe2a..a3d56ad89 100644
--- a/test/e2e/search_test.go
+++ b/test/e2e/search_test.go
@@ -237,7 +237,7 @@ registries = ['{{.Host}}:{{.Port}}']`
})
It("podman search attempts HTTP if registry is in registries.insecure and force secure is false", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
if podmanTest.Host.Arch == "ppc64le" {
Skip("No registry image for ppc64le")
}
@@ -278,7 +278,7 @@ registries = ['{{.Host}}:{{.Port}}']`
})
It("podman search doesn't attempt HTTP if force secure is true", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
if podmanTest.Host.Arch == "ppc64le" {
Skip("No registry image for ppc64le")
}
@@ -317,7 +317,7 @@ registries = ['{{.Host}}:{{.Port}}']`
})
It("podman search doesn't attempt HTTP if registry is not listed as insecure", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
if podmanTest.Host.Arch == "ppc64le" {
Skip("No registry image for ppc64le")
}
@@ -356,7 +356,7 @@ registries = ['{{.Host}}:{{.Port}}']`
})
It("podman search doesn't attempt HTTP if one registry is not listed as insecure", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
if podmanTest.Host.Arch == "ppc64le" {
Skip("No registry image for ppc64le")
}
@@ -407,7 +407,6 @@ registries = ['{{.Host}}:{{.Port}}']`
// search should fail with nonexist authfile
It("podman search fail with nonexist --authfile", func() {
- SkipIfRemote()
search := podmanTest.Podman([]string{"search", "--authfile", "/tmp/nonexist", ALPINE})
search.WaitWithDefaultTimeout()
Expect(search.ExitCode()).To(Not(Equal(0)))
diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go
index aef5ca001..35b5cab6e 100644
--- a/test/e2e/start_test.go
+++ b/test/e2e/start_test.go
@@ -87,7 +87,6 @@ var _ = Describe("Podman start", func() {
})
It("podman start single container with attach and test the signal", func() {
- SkipIfRemote()
session := podmanTest.Podman([]string{"create", "--entrypoint", "sh", ALPINE, "-c", "exit 1"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -132,14 +131,16 @@ var _ = Describe("Podman start", func() {
})
It("podman failed to start with --rm should delete the container", func() {
- Skip(v2remotefail)
session := podmanTest.Podman([]string{"create", "--name", "test1", "-it", "--rm", ALPINE, "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
start := podmanTest.Podman([]string{"start", "test1"})
start.WaitWithDefaultTimeout()
- Expect(start).To(ExitWithError())
+
+ wait := podmanTest.Podman([]string{"wait", "test1"})
+ wait.WaitWithDefaultTimeout()
+ Expect(wait).To(ExitWithError())
Eventually(podmanTest.NumberOfContainers(), defaultWaitTimeout, 3.0).Should(BeZero())
})
diff --git a/test/e2e/stats_test.go b/test/e2e/stats_test.go
index ff6ddce7e..7ab435007 100644
--- a/test/e2e/stats_test.go
+++ b/test/e2e/stats_test.go
@@ -1,4 +1,4 @@
-// +build !remote
+// +build
package integration
diff --git a/test/e2e/stop_test.go b/test/e2e/stop_test.go
index 22cd2e7ae..1437fd066 100644
--- a/test/e2e/stop_test.go
+++ b/test/e2e/stop_test.go
@@ -41,8 +41,6 @@ var _ = Describe("Podman stop", func() {
})
It("podman stop --ignore bogus container", func() {
- SkipIfRemote()
-
session := podmanTest.RunTopContainer("")
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -184,7 +182,7 @@ var _ = Describe("Podman stop", func() {
})
It("podman stop latest containers", func() {
- SkipIfRemote()
+ SkipIfRemote("--latest flag n/a")
session := podmanTest.RunTopContainer("test1")
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -198,14 +196,17 @@ var _ = Describe("Podman stop", func() {
})
It("podman stop all containers with one stopped", func() {
- Skip(v2remotefail)
session := podmanTest.RunTopContainer("test1")
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session2 := podmanTest.RunTopContainer("test2")
session2.WaitWithDefaultTimeout()
Expect(session2.ExitCode()).To(Equal(0))
- session3 := podmanTest.Podman([]string{"stop", "-l", "-t", "1"})
+ cid := "-l"
+ if IsRemote() {
+ cid = "test2"
+ }
+ session3 := podmanTest.Podman([]string{"stop", cid, "-t", "1"})
session3.WaitWithDefaultTimeout()
Expect(session3.ExitCode()).To(Equal(0))
session4 := podmanTest.Podman([]string{"stop", "-a", "-t", "1"})
@@ -288,7 +289,7 @@ var _ = Describe("Podman stop", func() {
})
It("podman stop invalid --latest and --cidfile and --all", func() {
- SkipIfRemote()
+ SkipIfRemote("--latest flag n/a")
result := podmanTest.Podman([]string{"stop", "--cidfile", "foobar", "--latest"})
result.WaitWithDefaultTimeout()
diff --git a/test/e2e/system_df_test.go b/test/e2e/system_df_test.go
index c184e1d01..aee5dafb8 100644
--- a/test/e2e/system_df_test.go
+++ b/test/e2e/system_df_test.go
@@ -35,7 +35,7 @@ var _ = Describe("podman system df", func() {
})
It("podman system df", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
session := podmanTest.Podman([]string{"create", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/system_reset_test.go b/test/e2e/system_reset_test.go
index 1c174e690..1a030216f 100644
--- a/test/e2e/system_reset_test.go
+++ b/test/e2e/system_reset_test.go
@@ -34,7 +34,7 @@ var _ = Describe("podman system reset", func() {
})
It("podman system reset", func() {
- SkipIfRemote()
+ SkipIfRemote("system reset not supported on podman --remote")
// system reset will not remove additional store images, so need to grab length
session := podmanTest.Podman([]string{"rmi", "--force", "--all"})
diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go
index 9a3247b77..5580f61f4 100644
--- a/test/e2e/systemd_test.go
+++ b/test/e2e/systemd_test.go
@@ -20,7 +20,6 @@ var _ = Describe("Podman systemd", func() {
)
BeforeEach(func() {
- SkipIfRootless()
tempdir, err = CreateTempDirInTempDir()
if err != nil {
os.Exit(1)
@@ -48,6 +47,7 @@ WantedBy=multi-user.target
})
It("podman start container by systemd", func() {
+ SkipIfRootless()
if os.Getenv("SKIP_USERNS") != "" {
Skip("Skip userns tests.")
}
diff --git a/test/e2e/unshare_test.go b/test/e2e/unshare_test.go
index a0c41b6f3..182a65775 100644
--- a/test/e2e/unshare_test.go
+++ b/test/e2e/unshare_test.go
@@ -15,7 +15,7 @@ var _ = Describe("Podman unshare", func() {
podmanTest *PodmanTestIntegration
)
BeforeEach(func() {
- SkipIfRemote()
+ SkipIfRemote("podman-remote unshare is not supported")
if _, err := os.Stat("/proc/self/uid_map"); err != nil {
Skip("User namespaces not supported.")
}
diff --git a/test/e2e/untag_test.go b/test/e2e/untag_test.go
index 4e6dd6462..7766ce634 100644
--- a/test/e2e/untag_test.go
+++ b/test/e2e/untag_test.go
@@ -33,7 +33,7 @@ var _ = Describe("Podman untag", func() {
})
It("podman untag all", func() {
- SkipIfRemote()
+ SkipIfRemote("FIXME This should work on podman-remote")
setup := podmanTest.PodmanNoCache([]string{"pull", ALPINE})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
diff --git a/test/e2e/version_test.go b/test/e2e/version_test.go
index 9ddbcc58f..695cccc11 100644
--- a/test/e2e/version_test.go
+++ b/test/e2e/version_test.go
@@ -37,21 +37,21 @@ var _ = Describe("Podman version", func() {
session := podmanTest.Podman([]string{"version"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- Expect(session.Out.Contents()).Should(ContainSubstring(version.Version))
+ Expect(session.Out.Contents()).Should(ContainSubstring(version.Version.String()))
})
It("podman -v", func() {
session := podmanTest.Podman([]string{"-v"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- Expect(session.Out.Contents()).Should(ContainSubstring(version.Version))
+ Expect(session.Out.Contents()).Should(ContainSubstring(version.Version.String()))
})
It("podman --version", func() {
session := podmanTest.Podman([]string{"--version"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- Expect(session.Out.Contents()).Should(ContainSubstring(version.Version))
+ Expect(session.Out.Contents()).Should(ContainSubstring(version.Version.String()))
})
It("podman version --format json", func() {
diff --git a/test/system/005-info.bats b/test/system/005-info.bats
index 3f1efd364..7452c1901 100644
--- a/test/system/005-info.bats
+++ b/test/system/005-info.bats
@@ -19,6 +19,8 @@ graphRoot:
graphStatus:
imageStore:\\\s\\\+number: 1
runRoot:
+cgroupManager: \\\(systemd\\\|cgroupfs\\\)
+cgroupVersion: v[12]
"
while read expect; do
is "$output" ".*$expect" "output includes '$expect'"
@@ -34,6 +36,8 @@ runRoot:
tests="
host.buildahVersion | [0-9.]
host.conmon.path | $expr_path
+host.cgroupManager | \\\(systemd\\\|cgroupfs\\\)
+host.cgroupVersion | v[12]
host.ociRuntime.path | $expr_path
store.configFile | $expr_path
store.graphDriverName | [a-z0-9]\\\+\\\$
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index 518d902a7..11edaf11c 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -61,8 +61,8 @@ echo $rand | 0 | $rand
is "$tests_run" "$(grep . <<<$tests | wc -l)" "Ran the full set of tests"
}
-@test "podman run - globle runtime option" {
- skip_if_remote "runtime flag is not passing over remote"
+@test "podman run - global runtime option" {
+ skip_if_remote "runtime flag is not passed over remote"
run_podman 126 --runtime-flag invalidflag run --rm $IMAGE
is "$output" ".*invalidflag" "failed when passing undefined flags to the runtime"
}
@@ -337,4 +337,55 @@ echo $rand | 0 | $rand
run_podman wait $cid
}
+# For #7754: json-file was equating to 'none'
+@test "podman run --log-driver" {
+ # '-' means that LogPath will be blank and there's no easy way to test
+ tests="
+none | -
+journald | -
+k8s-file | y
+json-file | f
+"
+ while read driver do_check; do
+ msg=$(random_string 15)
+ run_podman run --name myctr --log-driver $driver $IMAGE echo $msg
+
+ # Simple output check
+ # Special case: 'json-file' emits a warning, the rest do not
+ # ...but with podman-remote the warning is on the server only
+ if [[ $do_check == 'f' ]] && ! is_remote; then # 'f' for 'fallback'
+ is "${lines[0]}" ".* level=error msg=\"json-file logging specified but not supported. Choosing k8s-file logging instead\"" \
+ "Fallback warning emitted"
+ is "${lines[1]}" "$msg" "basic output sanity check (driver=$driver)"
+ else
+ is "$output" "$msg" "basic output sanity check (driver=$driver)"
+ fi
+
+ # Simply confirm that podman preserved our argument as-is
+ run_podman inspect --format '{{.HostConfig.LogConfig.Type}}' myctr
+ is "$output" "$driver" "podman inspect: driver"
+
+ # If LogPath is non-null, check that it exists and has a valid log
+ run_podman inspect --format '{{.LogPath}}' myctr
+ if [[ $do_check != '-' ]]; then
+ is "$output" "/.*" "LogPath (driver=$driver)"
+ if ! test -e "$output"; then
+ die "LogPath (driver=$driver) does not exist: $output"
+ fi
+ # eg 2020-09-23T13:34:58.644824420-06:00 stdout F 7aiYtvrqFGJWpak
+ is "$(< $output)" "[0-9T:.+-]\+ stdout F $msg" \
+ "LogPath contents (driver=$driver)"
+ else
+ is "$output" "" "LogPath (driver=$driver)"
+ fi
+ run_podman rm myctr
+ done < <(parse_table "$tests")
+
+ # Invalid log-driver argument
+ run_podman 125 run --log-driver=InvalidDriver $IMAGE true
+ is "$output" "Error: error running container create option: invalid log driver: invalid argument" \
+ "--log-driver InvalidDriver"
+}
+
+
# vim: filetype=sh
diff --git a/test/system/120-load.bats b/test/system/120-load.bats
index d7aa16d95..8ea9b1c69 100644
--- a/test/system/120-load.bats
+++ b/test/system/120-load.bats
@@ -147,4 +147,45 @@ verify_iid_and_name() {
"Diagnostic from 'podman load' without redirection or -i"
}
+@test "podman load - multi-image archive" {
+ img1="quay.io/libpod/testimage:00000000"
+ img2="quay.io/libpod/testimage:20200902"
+ archive=$PODMAN_TMPDIR/myimage-$(random_string 8).tar
+
+ run_podman pull $img1
+ run_podman pull $img2
+
+ run_podman save -m -o $archive $img1 $img2
+ run_podman rmi -f $img1 $img2
+ run_podman load -i $archive
+
+ run_podman image exists $img1
+ run_podman image exists $img2
+ run_podman rmi -f $img1 $img2
+}
+
+@test "podman load - multi-image archive with redirect" {
+ img1="quay.io/libpod/testimage:00000000"
+ img2="quay.io/libpod/testimage:20200902"
+ archive=$PODMAN_TMPDIR/myimage-$(random_string 8).tar
+
+ run_podman pull $img1
+ run_podman pull $img2
+
+ # We can't use run_podman because that uses the BATS 'run' function
+ # which redirects stdout and stderr. Here we need to guarantee
+ # that podman's stdout is a pipe, not any other form of redirection
+ $PODMAN save -m $img1 $img2 | cat >$archive
+ if [ "$status" -ne 0 ]; then
+ die "Command failed: podman save ... | cat"
+ fi
+
+ run_podman rmi -f $img1 $img2
+ run_podman load -i $archive
+
+ run_podman image exists $img1
+ run_podman image exists $img2
+ run_podman rmi -f $img1 $img2
+}
+
# vim: filetype=sh
diff --git a/test/system/helpers.bash b/test/system/helpers.bash
index c361e23ff..78571901d 100644
--- a/test/system/helpers.bash
+++ b/test/system/helpers.bash
@@ -376,7 +376,12 @@ function parse_table() {
while read col; do
dprint "col=<<$col>>"
row+=("$col")
- done < <(echo "$line" | tr '|' '\012' | sed -e 's/^ *//' -e 's/\\/\\\\/g')
+ done < <(echo "$line" | sed -E -e 's/(^|\s)\|(\s|$)/\n /g' | sed -e 's/^ *//' -e 's/\\/\\\\/g')
+ # the above seds:
+ # 1) Convert '|' to newline, but only if bracketed by spaces or
+ # at beginning/end of line (this allows 'foo|bar' in tests);
+ # 2) then remove leading whitespace;
+ # 3) then double-escape all backslashes
printf "%q " "${row[@]}"
printf "\n"
diff --git a/test/system/helpers.t b/test/system/helpers.t
index 7a331174b..190e8ba35 100755
--- a/test/system/helpers.t
+++ b/test/system/helpers.t
@@ -85,7 +85,7 @@ while read x y z; do
check_result "$x" "''" "empty string - left-hand"
check_result "$y" "''" "empty string - middle"
check_result "$z" "''" "empty string - right"
-done < <(parse_table " | |")
+done < <(parse_table " | |")
# Quotes
while read x y z;do
@@ -108,6 +108,13 @@ while read x y z;do
check_result "$3" "g" "double quotes - token split - 3"
done < <(parse_table "a 'b c' | d \"e f\" g | h")
+# Split on '|' only when bracketed by spaces or at beginning/end of line
+while read x y z;do
+ check_result "$x" "|x" "pipe in strings - pipe at start"
+ check_result "$y" "y|y1" "pipe in strings - pipe in middle"
+ check_result "$z" "z|" "pipe in strings - pipe at end"
+done < <(parse_table "|x | y|y1 | z|")
+
# END test the parse_table helper
###############################################################################
# BEGIN dprint
diff --git a/vendor/github.com/containers/buildah/CHANGELOG.md b/vendor/github.com/containers/buildah/CHANGELOG.md
index ecbd0540e..6168dc317 100644
--- a/vendor/github.com/containers/buildah/CHANGELOG.md
+++ b/vendor/github.com/containers/buildah/CHANGELOG.md
@@ -2,6 +2,9 @@
# Changelog
+## v1.16.2 (2020-09-21)
+ Add(): fix handling of relative paths with no ContextDir
+
## v1.16.1 (2020-09-10)
copier.Get(): hard link targets shouldn't be relative paths
diff --git a/vendor/github.com/containers/buildah/add.go b/vendor/github.com/containers/buildah/add.go
index 1c1f116da..bbfdda9c1 100644
--- a/vendor/github.com/containers/buildah/add.go
+++ b/vendor/github.com/containers/buildah/add.go
@@ -151,18 +151,26 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
}()
contextDir := options.ContextDir
- if contextDir == "" {
+ currentDir := options.ContextDir
+ if options.ContextDir == "" {
contextDir = string(os.PathSeparator)
+ currentDir, err = os.Getwd()
+ if err != nil {
+ return errors.Wrapf(err, "error determining current working directory")
+ }
}
// Figure out what sorts of sources we have.
var localSources, remoteSources []string
- for _, src := range sources {
+ for i, src := range sources {
if sourceIsRemote(src) {
remoteSources = append(remoteSources, src)
continue
}
- localSources = append(localSources, src)
+ if !filepath.IsAbs(src) && options.ContextDir == "" {
+ sources[i] = filepath.Join(currentDir, src)
+ }
+ localSources = append(localSources, sources[i])
}
// Check how many items our local source specs matched. Each spec
diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go
index d001b8a10..e63cfff3a 100644
--- a/vendor/github.com/containers/buildah/buildah.go
+++ b/vendor/github.com/containers/buildah/buildah.go
@@ -28,7 +28,7 @@ const (
Package = "buildah"
// Version for the Package. Bump version in contrib/rpm/buildah.spec
// too.
- Version = "1.16.1"
+ Version = "1.16.2"
// The value we use to identify what type of information, currently a
// serialized Builder structure, we are using as per-container state.
// This should only be changed when we make incompatible changes to
diff --git a/vendor/github.com/containers/buildah/changelog.txt b/vendor/github.com/containers/buildah/changelog.txt
index ec5db6eac..d34ede417 100644
--- a/vendor/github.com/containers/buildah/changelog.txt
+++ b/vendor/github.com/containers/buildah/changelog.txt
@@ -1,3 +1,5 @@
+- Changelog for v1.16.2 (2020-09-21)
+ * Add(): fix handling of relative paths with no ContextDir
- Changelog for v1.16.1 (2020-09-10)
* copier.Get(): hard link targets shouldn't be relative paths
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 3033b4a27..c808539d2 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
@@ -183,7 +183,12 @@ func createUntarTempDir(sys *types.SystemContext, ref ociArchiveReference) (temp
src := ref.resolvedFile
dst := tempDirRef.tempDirectory
// TODO: This can take quite some time, and should ideally be cancellable using a context.Context.
- if err := archive.UntarPath(src, dst); err != nil {
+ arch, err := os.Open(src)
+ if err != nil {
+ return tempDirOCIRef{}, err
+ }
+ 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)
}
diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go
index f4f902386..9c0ddcaed 100644
--- a/vendor/github.com/containers/image/v5/version/version.go
+++ b/vendor/github.com/containers/image/v5/version/version.go
@@ -6,12 +6,12 @@ const (
// VersionMajor is for an API incompatible changes
VersionMajor = 5
// VersionMinor is for functionality in a backwards-compatible manner
- VersionMinor = 5
+ VersionMinor = 6
// VersionPatch is for backwards-compatible bug fixes
- VersionPatch = 2
+ VersionPatch = 0
// VersionDev indicates development branch. Releases will be empty string.
- VersionDev = "-dev"
+ VersionDev = ""
)
// Version is the specification version that the package types support.
diff --git a/vendor/github.com/moby/sys/mountinfo/doc.go b/vendor/github.com/moby/sys/mountinfo/doc.go
new file mode 100644
index 000000000..21aa8dd59
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/doc.go
@@ -0,0 +1,47 @@
+// Package mountinfo provides a set of functions to retrieve information about OS mounts.
+// Currently it supports Linux. For historical reasons, there is also some support for FreeBSD,
+// and a shallow implementation for Windows, but in general this is Linux-only package, so
+// the rest of the document only applies to Linux, unless explicitly specified otherwise.
+//
+// In Linux, information about mounts seen by the current process is available from
+// /proc/self/mountinfo. Note that due to mount namespaces, different processes can
+// see different mounts. A per-process mountinfo table is available from /proc/<PID>/mountinfo,
+// where <PID> is a numerical process identifier.
+//
+// In general, /proc is not a very effective interface, and mountinfo is not an exception.
+// For example, there is no way to get information about a specific mount point (i.e. it
+// is all-or-nothing). This package tries to hide the /proc ineffectiveness by using
+// parse filters while reading mountinfo. A filter can skip some entries, or stop
+// processing the rest of the file once the needed information is found.
+//
+// For mountinfo filters that accept path as an argument, the path must be:
+// - absolute;
+// - having all symlinks resolved;
+// - being cleaned.
+//
+// One way to achieve all of the above is to employ filepath.Abs followed by
+// filepath.EvalSymlinks (the latter calls filepath.Clean on the result so
+// there is no need to explicitly call filepath.Clean).
+//
+// NOTE that in many cases there is no need to consult mountinfo at all. Here are some
+// of the cases where mountinfo should not be parsed:
+//
+// 1. Before performing a mount. Usually, this is not needed, but if required (say to
+// prevent overmounts), to check whether a directory is mounted, call os.Lstat
+// on it and its parent directory, and compare their st.Sys().(*syscall.Stat_t).Dev
+// fields -- if they differ, then the directory is the mount point. NOTE this does
+// not work for bind mounts. Optionally, the filesystem type can also be checked
+// by calling unix.Statfs and checking the Type field (i.e. filesystem type).
+//
+// 2. After performing a mount. If there is no error returned, the mount succeeded;
+// checking the mount table for a new mount is redundant and expensive.
+//
+// 3. Before performing an unmount. It is more efficient to do an unmount and ignore
+// a specific error (EINVAL) which tells the directory is not mounted.
+//
+// 4. After performing an unmount. If there is no error returned, the unmount succeeded.
+//
+// 5. To find the mount point root of a specific directory. You can perform os.Stat()
+// on the directory and traverse up until the Dev field of a parent directory differs.
+
+package mountinfo
diff --git a/vendor/github.com/moby/sys/mountinfo/go.mod b/vendor/github.com/moby/sys/mountinfo/go.mod
index 10d9a15a6..9749ea96d 100644
--- a/vendor/github.com/moby/sys/mountinfo/go.mod
+++ b/vendor/github.com/moby/sys/mountinfo/go.mod
@@ -1,3 +1,5 @@
module github.com/moby/sys/mountinfo
go 1.14
+
+require golang.org/x/sys v0.0.0-20200909081042-eff7692f9009
diff --git a/vendor/github.com/moby/sys/mountinfo/go.sum b/vendor/github.com/moby/sys/mountinfo/go.sum
new file mode 100644
index 000000000..2a5be7ea8
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/go.sum
@@ -0,0 +1,2 @@
+golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM=
+golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/vendor/github.com/moby/sys/mountinfo/mounted_linux.go b/vendor/github.com/moby/sys/mountinfo/mounted_linux.go
new file mode 100644
index 000000000..bc9f6b2ad
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mounted_linux.go
@@ -0,0 +1,58 @@
+package mountinfo
+
+import (
+ "os"
+ "path/filepath"
+
+ "golang.org/x/sys/unix"
+)
+
+// mountedByOpenat2 is a method of detecting a mount that works for all kinds
+// of mounts (incl. bind mounts), but requires a recent (v5.6+) linux kernel.
+func mountedByOpenat2(path string) (bool, error) {
+ dir, last := filepath.Split(path)
+
+ dirfd, err := unix.Openat2(unix.AT_FDCWD, dir, &unix.OpenHow{
+ Flags: unix.O_PATH | unix.O_CLOEXEC,
+ })
+ if err != nil {
+ if err == unix.ENOENT { // not a mount
+ return false, nil
+ }
+ return false, &os.PathError{Op: "openat2", Path: dir, Err: err}
+ }
+ fd, err := unix.Openat2(dirfd, last, &unix.OpenHow{
+ Flags: unix.O_PATH | unix.O_CLOEXEC | unix.O_NOFOLLOW,
+ Resolve: unix.RESOLVE_NO_XDEV,
+ })
+ _ = unix.Close(dirfd)
+ switch err {
+ case nil: // definitely not a mount
+ _ = unix.Close(fd)
+ return false, nil
+ case unix.EXDEV: // definitely a mount
+ return true, nil
+ case unix.ENOENT: // not a mount
+ return false, nil
+ }
+ // not sure
+ return false, &os.PathError{Op: "openat2", Path: path, Err: err}
+}
+
+func mounted(path string) (bool, error) {
+ // Try a fast path, using openat2() with RESOLVE_NO_XDEV.
+ mounted, err := mountedByOpenat2(path)
+ if err == nil {
+ return mounted, nil
+ }
+ // Another fast path: compare st.st_dev fields.
+ mounted, err = mountedByStat(path)
+ // This does not work for bind mounts, so false negative
+ // is possible, therefore only trust if return is true.
+ if mounted && err == nil {
+ return mounted, nil
+ }
+
+ // Fallback to parsing mountinfo
+ return mountedByMountinfo(path)
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mounted_unix.go b/vendor/github.com/moby/sys/mountinfo/mounted_unix.go
new file mode 100644
index 000000000..c4d66b2f4
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mounted_unix.go
@@ -0,0 +1,66 @@
+// +build linux freebsd,cgo
+
+package mountinfo
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "golang.org/x/sys/unix"
+)
+
+func mountedByStat(path string) (bool, error) {
+ var st unix.Stat_t
+
+ if err := unix.Lstat(path, &st); err != nil {
+ if err == unix.ENOENT {
+ // Treat ENOENT as "not mounted".
+ return false, nil
+ }
+ return false, &os.PathError{Op: "stat", Path: path, Err: err}
+ }
+ dev := st.Dev
+ parent := filepath.Dir(path)
+ if err := unix.Lstat(parent, &st); err != nil {
+ return false, &os.PathError{Op: "stat", Path: parent, Err: err}
+ }
+ if dev != st.Dev {
+ // Device differs from that of parent,
+ // so definitely a mount point.
+ return true, nil
+ }
+ // NB: this does not detect bind mounts on Linux.
+ return false, nil
+}
+
+func normalizePath(path string) (realPath string, err error) {
+ if realPath, err = filepath.Abs(path); err != nil {
+ return "", fmt.Errorf("unable to get absolute path for %q: %w", path, err)
+ }
+ if realPath, err = filepath.EvalSymlinks(realPath); err != nil {
+ return "", fmt.Errorf("failed to canonicalise path for %q: %w", path, err)
+ }
+ if _, err := os.Stat(realPath); err != nil {
+ return "", fmt.Errorf("failed to stat target of %q: %w", path, err)
+ }
+ return realPath, nil
+}
+
+func mountedByMountinfo(path string) (bool, error) {
+ path, err := normalizePath(path)
+ if err != nil {
+ if errors.Is(err, unix.ENOENT) {
+ // treat ENOENT as "not mounted"
+ return false, nil
+ }
+ return false, err
+ }
+ entries, err := GetMounts(SingleEntryFilter(path))
+ if err != nil {
+ return false, err
+ }
+
+ return len(entries) > 0, nil
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo.go b/vendor/github.com/moby/sys/mountinfo/mountinfo.go
index 136b14167..1987fcbb2 100644
--- a/vendor/github.com/moby/sys/mountinfo/mountinfo.go
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo.go
@@ -1,6 +1,9 @@
package mountinfo
-import "io"
+import (
+ "io"
+ "os"
+)
// GetMounts retrieves a list of mounts for the current running process,
// with an optional filter applied (use nil for no filter).
@@ -16,15 +19,17 @@ func GetMountsFromReader(reader io.Reader, f FilterFunc) ([]*Info, error) {
return parseInfoFile(reader, f)
}
-// Mounted determines if a specified mountpoint has been mounted.
-// On Linux it looks at /proc/self/mountinfo.
-func Mounted(mountpoint string) (bool, error) {
- entries, err := GetMounts(SingleEntryFilter(mountpoint))
- if err != nil {
- return false, err
+// Mounted determines if a specified path is a mount point.
+//
+// The argument must be an absolute path, with all symlinks resolved, and clean.
+// One way to ensure it is to process the path using filepath.Abs followed by
+// filepath.EvalSymlinks before calling this function.
+func Mounted(path string) (bool, error) {
+ // root is always mounted
+ if path == string(os.PathSeparator) {
+ return true, nil
}
-
- return len(entries) > 0, nil
+ return mounted(path)
}
// Info reveals information about a particular mounted filesystem. This
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go
index 795026465..8aebe1ad4 100644
--- a/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go
@@ -15,7 +15,7 @@ import "strings"
type FilterFunc func(*Info) (skip, stop bool)
// PrefixFilter discards all entries whose mount points
-// do not start with a specific prefix
+// do not start with a specific prefix.
func PrefixFilter(prefix string) FilterFunc {
return func(m *Info) (bool, bool) {
skip := !strings.HasPrefix(m.Mountpoint, prefix)
@@ -23,7 +23,7 @@ func PrefixFilter(prefix string) FilterFunc {
}
}
-// SingleEntryFilter looks for a specific entry
+// SingleEntryFilter looks for a specific entry.
func SingleEntryFilter(mp string) FilterFunc {
return func(m *Info) (bool, bool) {
if m.Mountpoint == mp {
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go
index a7dbb1b46..b30dc1625 100644
--- a/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go
@@ -51,3 +51,15 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) {
}
return out, nil
}
+
+func mounted(path string) (bool, error) {
+ // Fast path: compare st.st_dev fields.
+ // This should always work for FreeBSD.
+ mounted, err := mountedByStat(path)
+ if err == nil {
+ return mounted, nil
+ }
+
+ // Fallback to parsing mountinfo
+ return mountedByMountinfo(path)
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go
index 2d630c8dc..cdfd37da5 100644
--- a/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go
@@ -71,12 +71,18 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) {
p := &Info{}
// Fill in the fields that a filter might check
- p.Mountpoint, err = strconv.Unquote(`"` + fields[4] + `"`)
+ p.Mountpoint, err = unescape(fields[4])
if err != nil {
- return nil, fmt.Errorf("Parsing '%s' failed: unable to unquote mount point field: %w", fields[4], err)
+ return nil, fmt.Errorf("Parsing '%s' failed: mount point: %w", fields[4], err)
+ }
+ p.Fstype, err = unescape(fields[sepIdx+1])
+ if err != nil {
+ return nil, fmt.Errorf("Parsing '%s' failed: fstype: %w", fields[sepIdx+1], err)
+ }
+ p.Source, err = unescape(fields[sepIdx+2])
+ if err != nil {
+ return nil, fmt.Errorf("Parsing '%s' failed: source: %w", fields[sepIdx+2], err)
}
- p.Fstype = fields[sepIdx+1]
- p.Source = fields[sepIdx+2]
p.VfsOpts = fields[sepIdx+3]
// Run a filter soon so we can skip parsing/adding entries
@@ -101,9 +107,9 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) {
p.Major, _ = strconv.Atoi(mm[0])
p.Minor, _ = strconv.Atoi(mm[1])
- p.Root, err = strconv.Unquote(`"` + fields[3] + `"`)
+ p.Root, err = unescape(fields[3])
if err != nil {
- return nil, fmt.Errorf("Parsing '%s' failed: unable to unquote root field: %w", fields[3], err)
+ return nil, fmt.Errorf("Parsing '%s' failed: root: %w", fields[3], err)
}
p.Opts = fields[5]
@@ -150,3 +156,61 @@ func PidMountInfo(pid int) ([]*Info, error) {
return parseInfoFile(f, nil)
}
+
+// A few specific characters in mountinfo path entries (root and mountpoint)
+// are escaped using a backslash followed by a character's ascii code in octal.
+//
+// space -- as \040
+// tab (aka \t) -- as \011
+// newline (aka \n) -- as \012
+// backslash (aka \\) -- as \134
+//
+// This function converts path from mountinfo back, i.e. it unescapes the above sequences.
+func unescape(path string) (string, error) {
+ // try to avoid copying
+ if strings.IndexByte(path, '\\') == -1 {
+ return path, nil
+ }
+
+ // The following code is UTF-8 transparent as it only looks for some
+ // specific characters (backslach and 0..7) with values < utf8.RuneSelf,
+ // and everything else is passed through as is.
+ buf := make([]byte, len(path))
+ bufLen := 0
+ for i := 0; i < len(path); i++ {
+ if path[i] != '\\' {
+ buf[bufLen] = path[i]
+ bufLen++
+ continue
+ }
+ s := path[i:]
+ if len(s) < 4 {
+ // too short
+ return "", fmt.Errorf("bad escape sequence %q: too short", s)
+ }
+ c := s[1]
+ switch c {
+ case '0', '1', '2', '3', '4', '5', '6', '7':
+ v := c - '0'
+ for j := 2; j < 4; j++ { // one digit already; two more
+ if s[j] < '0' || s[j] > '7' {
+ return "", fmt.Errorf("bad escape sequence %q: not a digit", s[:3])
+ }
+ x := s[j] - '0'
+ v = (v << 3) | x
+ }
+ if v > 255 {
+ return "", fmt.Errorf("bad escape sequence %q: out of range" + s[:3])
+ }
+ buf[bufLen] = v
+ bufLen++
+ i += 3
+ continue
+ default:
+ return "", fmt.Errorf("bad escape sequence %q: not a digit" + s[:3])
+
+ }
+ }
+
+ return string(buf[:bufLen]), nil
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go
index dc1869211..1eb8558c8 100644
--- a/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go
@@ -8,10 +8,16 @@ import (
"runtime"
)
+var errNotImplemented = fmt.Errorf("not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+
func parseMountTable(_ FilterFunc) ([]*Info, error) {
- return nil, fmt.Errorf("mount.parseMountTable is not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+ return nil, errNotImplemented
}
func parseInfoFile(_ io.Reader, f FilterFunc) ([]*Info, error) {
return parseMountTable(f)
}
+
+func mounted(path string) (bool, error) {
+ return false, errNotImplemented
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go
index 69ffdc52b..5659c1b0f 100644
--- a/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go
@@ -10,3 +10,7 @@ func parseMountTable(_ FilterFunc) ([]*Info, error) {
func parseInfoFile(_ io.Reader, f FilterFunc) ([]*Info, error) {
return parseMountTable(f)
}
+
+func mounted(_ string) (bool, error) {
+ return false, nil
+}
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index 5b3af2e6a..ec7e4c4d3 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -136,6 +136,12 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
return openat(dirfd, path, flags|O_LARGEFILE, mode)
}
+//sys openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error)
+
+func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
+ return openat2(dirfd, path, how, SizeofOpenHow)
+}
+
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go
index 4eec7a795..2fbbbe5a8 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go
@@ -83,6 +83,22 @@ func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_OPENAT2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(open_how)), uintptr(size), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go
index 1879d5789..68e4974a9 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go
@@ -752,6 +752,22 @@ const (
AT_EACCESS = 0x200
)
+type OpenHow struct {
+ Flags uint64
+ Mode uint64
+ Resolve uint64
+}
+
+const SizeofOpenHow = 0x18
+
+const (
+ RESOLVE_BENEATH = 0x8
+ RESOLVE_IN_ROOT = 0x10
+ RESOLVE_NO_MAGICLINKS = 0x2
+ RESOLVE_NO_SYMLINKS = 0x4
+ RESOLVE_NO_XDEV = 0x1
+)
+
type PollFd struct {
Fd int32
Events int16
diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go
index 62cf70e9f..2aa29e839 100644
--- a/vendor/golang.org/x/sys/windows/syscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/syscall_windows.go
@@ -303,6 +303,7 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys ResumeThread(thread Handle) (ret uint32, err error) [failretval==0xffffffff] = kernel32.ResumeThread
//sys SetPriorityClass(process Handle, priorityClass uint32) (err error) = kernel32.SetPriorityClass
//sys GetPriorityClass(process Handle) (ret uint32, err error) = kernel32.GetPriorityClass
+//sys QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobObjectInformation uintptr, JobObjectInformationLength uint32, retlen *uint32) (err error) = kernel32.QueryInformationJobObject
//sys SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error)
//sys GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err error)
//sys GetProcessId(process Handle) (id uint32, err error)
diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go
index 809fff0b4..da1652e74 100644
--- a/vendor/golang.org/x/sys/windows/types_windows.go
+++ b/vendor/golang.org/x/sys/windows/types_windows.go
@@ -1584,18 +1584,6 @@ const (
JOB_OBJECT_LIMIT_WORKINGSET = 0x00000001
)
-type JOBOBJECT_BASIC_LIMIT_INFORMATION struct {
- PerProcessUserTimeLimit int64
- PerJobUserTimeLimit int64
- LimitFlags uint32
- MinimumWorkingSetSize uintptr
- MaximumWorkingSetSize uintptr
- ActiveProcessLimit uint32
- Affinity uintptr
- PriorityClass uint32
- SchedulingClass uint32
-}
-
type IO_COUNTERS struct {
ReadOperationCount uint64
WriteOperationCount uint64
diff --git a/vendor/golang.org/x/sys/windows/types_windows_386.go b/vendor/golang.org/x/sys/windows/types_windows_386.go
index fe0ddd031..8bce3e2fc 100644
--- a/vendor/golang.org/x/sys/windows/types_windows_386.go
+++ b/vendor/golang.org/x/sys/windows/types_windows_386.go
@@ -20,3 +20,16 @@ type Servent struct {
Port uint16
Proto *byte
}
+
+type JOBOBJECT_BASIC_LIMIT_INFORMATION struct {
+ PerProcessUserTimeLimit int64
+ PerJobUserTimeLimit int64
+ LimitFlags uint32
+ MinimumWorkingSetSize uintptr
+ MaximumWorkingSetSize uintptr
+ ActiveProcessLimit uint32
+ Affinity uintptr
+ PriorityClass uint32
+ SchedulingClass uint32
+ _ uint32 // pad to 8 byte boundary
+}
diff --git a/vendor/golang.org/x/sys/windows/types_windows_amd64.go b/vendor/golang.org/x/sys/windows/types_windows_amd64.go
index 7e154c2df..fdddc0c70 100644
--- a/vendor/golang.org/x/sys/windows/types_windows_amd64.go
+++ b/vendor/golang.org/x/sys/windows/types_windows_amd64.go
@@ -20,3 +20,15 @@ type Servent struct {
Proto *byte
Port uint16
}
+
+type JOBOBJECT_BASIC_LIMIT_INFORMATION struct {
+ PerProcessUserTimeLimit int64
+ PerJobUserTimeLimit int64
+ LimitFlags uint32
+ MinimumWorkingSetSize uintptr
+ MaximumWorkingSetSize uintptr
+ ActiveProcessLimit uint32
+ Affinity uintptr
+ PriorityClass uint32
+ SchedulingClass uint32
+}
diff --git a/vendor/golang.org/x/sys/windows/types_windows_arm.go b/vendor/golang.org/x/sys/windows/types_windows_arm.go
index 74571e360..321872c3e 100644
--- a/vendor/golang.org/x/sys/windows/types_windows_arm.go
+++ b/vendor/golang.org/x/sys/windows/types_windows_arm.go
@@ -20,3 +20,16 @@ type Servent struct {
Port uint16
Proto *byte
}
+
+type JOBOBJECT_BASIC_LIMIT_INFORMATION struct {
+ PerProcessUserTimeLimit int64
+ PerJobUserTimeLimit int64
+ LimitFlags uint32
+ MinimumWorkingSetSize uintptr
+ MaximumWorkingSetSize uintptr
+ ActiveProcessLimit uint32
+ Affinity uintptr
+ PriorityClass uint32
+ SchedulingClass uint32
+ _ uint32 // pad to 8 byte boundary
+}
diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
index 8a562feed..347f13dbf 100644
--- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
@@ -212,6 +212,7 @@ var (
procResumeThread = modkernel32.NewProc("ResumeThread")
procSetPriorityClass = modkernel32.NewProc("SetPriorityClass")
procGetPriorityClass = modkernel32.NewProc("GetPriorityClass")
+ procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject")
procSetInformationJobObject = modkernel32.NewProc("SetInformationJobObject")
procGenerateConsoleCtrlEvent = modkernel32.NewProc("GenerateConsoleCtrlEvent")
procGetProcessId = modkernel32.NewProc("GetProcessId")
@@ -2341,6 +2342,18 @@ func GetPriorityClass(process Handle) (ret uint32, err error) {
return
}
+func QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobObjectInformation uintptr, JobObjectInformationLength uint32, retlen *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procQueryInformationJobObject.Addr(), 5, uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), uintptr(unsafe.Pointer(retlen)), 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
func SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error) {
r0, _, e1 := syscall.Syscall6(procSetInformationJobObject.Addr(), 4, uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), 0, 0)
ret = int(r0)
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 90f5a27cc..0d89425ab 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -67,7 +67,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.16.1
+# github.com/containers/buildah v1.16.2
github.com/containers/buildah
github.com/containers/buildah/bind
github.com/containers/buildah/chroot
@@ -100,7 +100,7 @@ github.com/containers/common/pkg/sysinfo
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.6.0 => github.com/containers/image/v5 v5.5.2-0.20200902171422-1c313b2d23e0
+# github.com/containers/image/v5 v5.6.0
github.com/containers/image/v5/copy
github.com/containers/image/v5/directory
github.com/containers/image/v5/directory/explicitfilepath
@@ -351,7 +351,7 @@ github.com/matttproud/golang_protobuf_extensions/pbutil
github.com/mistifyio/go-zfs
# github.com/moby/sys/mount v0.1.1
github.com/moby/sys/mount
-# github.com/moby/sys/mountinfo v0.1.3
+# github.com/moby/sys/mountinfo v0.2.0
github.com/moby/sys/mountinfo
# github.com/moby/term v0.0.0-20200915141129-7f0af18e79f2
github.com/moby/term
@@ -477,7 +477,7 @@ github.com/prometheus/common/model
github.com/prometheus/procfs
github.com/prometheus/procfs/internal/fs
github.com/prometheus/procfs/internal/util
-# github.com/rootless-containers/rootlesskit v0.10.0
+# github.com/rootless-containers/rootlesskit v0.10.1
github.com/rootless-containers/rootlesskit/pkg/msgutil
github.com/rootless-containers/rootlesskit/pkg/port
github.com/rootless-containers/rootlesskit/pkg/port/builtin
@@ -609,7 +609,7 @@ golang.org/x/oauth2/internal
# golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
golang.org/x/sync/errgroup
golang.org/x/sync/semaphore
-# golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a
+# golang.org/x/sys v0.0.0-20200909081042-eff7692f9009
golang.org/x/sys/cpu
golang.org/x/sys/internal/unsafeheader
golang.org/x/sys/unix
diff --git a/version/version.go b/version/version.go
index 2e1335d2d..e6b1425ef 100644
--- a/version/version.go
+++ b/version/version.go
@@ -1,12 +1,16 @@
package version
+import (
+ "github.com/blang/semver"
+)
+
// Version is the version of the build.
// NOTE: remember to bump the version at the top
// of the top-level README.md file when this is
// bumped.
-const Version = "2.1.0-dev"
+var Version = semver.MustParse("2.2.0-dev")
// APIVersion is the version for the remote
// client API. It is used to determine compatibility
// between a remote podman client and its backend
-const APIVersion = 1
+var APIVersion = semver.MustParse("2.0.0")