summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml11
-rw-r--r--Makefile32
-rw-r--r--RELEASE_NOTES.md340
-rw-r--r--cmd/podman/common/completion.go1
-rw-r--r--cmd/podman/volumes/prune.go52
-rw-r--r--completions/Readme.md2
-rwxr-xr-xcontrib/cirrus/logcollector.sh1
-rw-r--r--docs/source/markdown/podman-create.1.md1
-rw-r--r--docs/source/markdown/podman-network-create.1.md9
-rw-r--r--docs/source/markdown/podman-run.1.md1
-rw-r--r--docs/tutorials/rootless_tutorial.md2
-rw-r--r--go.mod10
-rw-r--r--go.sum25
-rw-r--r--libpod/kube.go21
-rw-r--r--libpod/network/config.go5
-rw-r--r--libpod/network/create.go31
-rw-r--r--libpod/network/netconflist.go22
-rw-r--r--libpod/network/network.go12
-rw-r--r--libpod/networking_linux.go16
-rw-r--r--libpod/options.go29
-rw-r--r--libpod/pod.go1
-rw-r--r--libpod/runtime_pod_infra_linux.go14
-rw-r--r--nix/nixpkgs.json8
-rw-r--r--pkg/api/handlers/compat/containers.go4
-rw-r--r--pkg/api/handlers/compat/resize.go2
-rw-r--r--pkg/api/handlers/libpod/pods.go90
-rw-r--r--pkg/api/handlers/utils/handler.go47
-rw-r--r--pkg/api/server/register_pods.go17
-rw-r--r--pkg/bindings/containers/attach.go2
-rw-r--r--pkg/bindings/containers/types_attach_options.go39
-rw-r--r--pkg/bindings/containers/types_checkpoint_options.go39
-rw-r--r--pkg/bindings/containers/types_commit_options.go39
-rw-r--r--pkg/bindings/containers/types_create_options.go39
-rw-r--r--pkg/bindings/containers/types_diff_options.go39
-rw-r--r--pkg/bindings/containers/types_execinspect_options.go39
-rw-r--r--pkg/bindings/containers/types_execstart_options.go39
-rw-r--r--pkg/bindings/containers/types_execstartandattach_options.go39
-rw-r--r--pkg/bindings/containers/types_exists_options.go39
-rw-r--r--pkg/bindings/containers/types_export_options.go39
-rw-r--r--pkg/bindings/containers/types_healthcheck_options.go39
-rw-r--r--pkg/bindings/containers/types_init_options.go39
-rw-r--r--pkg/bindings/containers/types_inspect_options.go39
-rw-r--r--pkg/bindings/containers/types_kill_options.go39
-rw-r--r--pkg/bindings/containers/types_list_options.go39
-rw-r--r--pkg/bindings/containers/types_log_options.go39
-rw-r--r--pkg/bindings/containers/types_mount_options.go39
-rw-r--r--pkg/bindings/containers/types_mountedcontainerpaths_options.go39
-rw-r--r--pkg/bindings/containers/types_pause_options.go39
-rw-r--r--pkg/bindings/containers/types_prune_options.go39
-rw-r--r--pkg/bindings/containers/types_remove_options.go39
-rw-r--r--pkg/bindings/containers/types_rename_options.go39
-rw-r--r--pkg/bindings/containers/types_resizeexectty_options.go39
-rw-r--r--pkg/bindings/containers/types_resizetty_options.go39
-rw-r--r--pkg/bindings/containers/types_restart_options.go39
-rw-r--r--pkg/bindings/containers/types_restore_options.go39
-rw-r--r--pkg/bindings/containers/types_shouldrestart_options.go39
-rw-r--r--pkg/bindings/containers/types_start_options.go39
-rw-r--r--pkg/bindings/containers/types_stats_options.go39
-rw-r--r--pkg/bindings/containers/types_stop_options.go39
-rw-r--r--pkg/bindings/containers/types_top_options.go39
-rw-r--r--pkg/bindings/containers/types_unmount_options.go39
-rw-r--r--pkg/bindings/containers/types_unpause_options.go39
-rw-r--r--pkg/bindings/containers/types_wait_options.go39
-rw-r--r--pkg/bindings/generate/types_kube_options.go41
-rw-r--r--pkg/bindings/generate/types_systemd_options.go41
-rw-r--r--pkg/bindings/generator/generator.go39
-rw-r--r--pkg/bindings/images/types_diff_options.go39
-rw-r--r--pkg/bindings/images/types_exists_options.go39
-rw-r--r--pkg/bindings/images/types_export_options.go39
-rw-r--r--pkg/bindings/images/types_get_options.go39
-rw-r--r--pkg/bindings/images/types_history_options.go39
-rw-r--r--pkg/bindings/images/types_import_options.go39
-rw-r--r--pkg/bindings/images/types_list_options.go39
-rw-r--r--pkg/bindings/images/types_load_options.go39
-rw-r--r--pkg/bindings/images/types_prune_options.go39
-rw-r--r--pkg/bindings/images/types_pull_options.go39
-rw-r--r--pkg/bindings/images/types_push_options.go39
-rw-r--r--pkg/bindings/images/types_remove_options.go39
-rw-r--r--pkg/bindings/images/types_search_options.go39
-rw-r--r--pkg/bindings/images/types_tag_options.go39
-rw-r--r--pkg/bindings/images/types_tree_options.go39
-rw-r--r--pkg/bindings/images/types_untag_options.go39
-rw-r--r--pkg/bindings/manifests/types_add_options.go41
-rw-r--r--pkg/bindings/manifests/types_create_options.go41
-rw-r--r--pkg/bindings/manifests/types_exists_options.go41
-rw-r--r--pkg/bindings/manifests/types_inspect_options.go41
-rw-r--r--pkg/bindings/manifests/types_remove_options.go41
-rw-r--r--pkg/bindings/network/types_connect_options.go39
-rw-r--r--pkg/bindings/network/types_create_options.go39
-rw-r--r--pkg/bindings/network/types_disconnect_options.go39
-rw-r--r--pkg/bindings/network/types_exists_options.go39
-rw-r--r--pkg/bindings/network/types_inspect_options.go39
-rw-r--r--pkg/bindings/network/types_list_options.go39
-rw-r--r--pkg/bindings/network/types_remove_options.go39
-rw-r--r--pkg/bindings/play/types_kube_options.go41
-rw-r--r--pkg/bindings/pods/types_create_options.go39
-rw-r--r--pkg/bindings/pods/types_exists_options.go39
-rw-r--r--pkg/bindings/pods/types_inspect_options.go39
-rw-r--r--pkg/bindings/pods/types_kill_options.go39
-rw-r--r--pkg/bindings/pods/types_list_options.go39
-rw-r--r--pkg/bindings/pods/types_pause_options.go39
-rw-r--r--pkg/bindings/pods/types_prune_options.go39
-rw-r--r--pkg/bindings/pods/types_remove_options.go39
-rw-r--r--pkg/bindings/pods/types_restart_options.go39
-rw-r--r--pkg/bindings/pods/types_start_options.go39
-rw-r--r--pkg/bindings/pods/types_stats_options.go39
-rw-r--r--pkg/bindings/pods/types_stop_options.go39
-rw-r--r--pkg/bindings/pods/types_top_options.go39
-rw-r--r--pkg/bindings/pods/types_unpause_options.go39
-rw-r--r--pkg/bindings/system/types_disk_options.go39
-rw-r--r--pkg/bindings/system/types_events_options.go39
-rw-r--r--pkg/bindings/system/types_info_options.go39
-rw-r--r--pkg/bindings/system/types_prune_options.go39
-rw-r--r--pkg/bindings/system/types_version_options.go39
-rw-r--r--pkg/bindings/util/util.go30
-rw-r--r--pkg/bindings/volumes/types_create_options.go39
-rw-r--r--pkg/bindings/volumes/types_exists_options.go39
-rw-r--r--pkg/bindings/volumes/types_inspect_options.go39
-rw-r--r--pkg/bindings/volumes/types_list_options.go39
-rw-r--r--pkg/bindings/volumes/types_prune_options.go39
-rw-r--r--pkg/bindings/volumes/types_remove_options.go39
-rw-r--r--pkg/specgen/generate/pod_create.go3
-rw-r--r--pkg/systemd/generate/common.go14
-rw-r--r--pkg/systemd/generate/common_test.go40
-rw-r--r--pkg/systemd/generate/containers.go4
-rw-r--r--pkg/systemd/generate/containers_test.go40
-rw-r--r--pkg/systemd/generate/pods.go4
-rw-r--r--test/apiv2/rest_api/test_rest_v2_0_0.py100
-rw-r--r--test/e2e/common_test.go36
-rw-r--r--test/e2e/exists_test.go6
-rw-r--r--test/e2e/generate_kube_test.go68
-rw-r--r--test/e2e/network_connect_disconnect_test.go20
-rw-r--r--test/e2e/network_test.go68
-rw-r--r--test/e2e/pod_create_test.go30
-rw-r--r--test/e2e/pod_inspect_test.go2
-rw-r--r--test/e2e/pod_kill_test.go16
-rw-r--r--test/e2e/pod_pause_test.go8
-rw-r--r--test/e2e/pod_prune_test.go6
-rw-r--r--test/e2e/pod_ps_test.go59
-rw-r--r--test/e2e/pod_restart_test.go18
-rw-r--r--test/e2e/pod_rm_test.go24
-rw-r--r--test/e2e/pod_start_test.go49
-rw-r--r--test/e2e/pod_stats_test.go16
-rw-r--r--test/e2e/pod_stop_test.go22
-rw-r--r--test/e2e/pod_top_test.go12
-rw-r--r--test/e2e/ps_test.go4
-rw-r--r--test/e2e/restart_test.go4
-rw-r--r--test/e2e/run_networking_test.go7
-rw-r--r--test/python/docker/test_containers.py9
-rw-r--r--test/system/030-run.bats39
-rw-r--r--test/system/140-diff.bats7
-rw-r--r--test/system/160-volumes.bats15
-rw-r--r--test/utils/utils.go5
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/invoke/find.go5
-rw-r--r--vendor/github.com/containers/storage/.cirrus.yml2
-rw-r--r--vendor/github.com/containers/storage/VERSION2
-rw-r--r--vendor/github.com/containers/storage/drivers/aufs/aufs.go15
-rw-r--r--vendor/github.com/containers/storage/drivers/btrfs/btrfs.go7
-rw-r--r--vendor/github.com/containers/storage/drivers/devmapper/driver.go9
-rw-r--r--vendor/github.com/containers/storage/drivers/driver.go3
-rw-r--r--vendor/github.com/containers/storage/drivers/driver_freebsd.go4
-rw-r--r--vendor/github.com/containers/storage/drivers/overlay/overlay.go36
-rw-r--r--vendor/github.com/containers/storage/drivers/quota/projectquota.go32
-rw-r--r--vendor/github.com/containers/storage/drivers/vfs/driver.go7
-rw-r--r--vendor/github.com/containers/storage/drivers/windows/windows.go7
-rw-r--r--vendor/github.com/containers/storage/drivers/zfs/zfs.go7
-rw-r--r--vendor/github.com/containers/storage/go.mod6
-rw-r--r--vendor/github.com/containers/storage/go.sum12
-rw-r--r--vendor/github.com/containers/storage/layers.go100
-rw-r--r--vendor/github.com/containers/storage/layers_ffjson.go111
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/archive_freebsd.go125
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/archive_unix.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/directory/directory.go8
-rw-r--r--vendor/github.com/containers/storage/pkg/directory/directory_unix.go31
-rw-r--r--vendor/github.com/containers/storage/pkg/directory/directory_windows.go15
-rw-r--r--vendor/github.com/containers/storage/pkg/homedir/homedir_others.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/system/mknod.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/system/mknod_freebsd.go22
-rw-r--r--vendor/github.com/containers/storage/store.go125
-rw-r--r--vendor/github.com/mattn/go-shellwords/.travis.yml3
-rw-r--r--vendor/github.com/mattn/go-shellwords/README.md9
-rw-r--r--vendor/github.com/mattn/go-shellwords/shellwords.go166
-rw-r--r--vendor/github.com/mattn/go-shellwords/util_posix.go4
-rw-r--r--vendor/github.com/mattn/go-shellwords/util_windows.go4
-rw-r--r--vendor/github.com/onsi/ginkgo/.travis.yml11
-rw-r--r--vendor/github.com/onsi/ginkgo/CHANGELOG.md11
-rw-r--r--vendor/github.com/onsi/ginkgo/README.md2
-rw-r--r--vendor/github.com/onsi/ginkgo/config/config.go33
-rw-r--r--vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go29
-rw-r--r--vendor/github.com/onsi/ginkgo/ginkgo/main.go6
-rw-r--r--vendor/github.com/onsi/ginkgo/ginkgo/outline/ginkgo.go243
-rw-r--r--vendor/github.com/onsi/ginkgo/ginkgo/outline/import.go65
-rw-r--r--vendor/github.com/onsi/ginkgo/ginkgo/outline/outline.go107
-rw-r--r--vendor/github.com/onsi/ginkgo/ginkgo/outline_command.go95
-rw-r--r--vendor/github.com/onsi/ginkgo/go.mod4
-rw-r--r--vendor/github.com/onsi/ginkgo/go.sum39
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_darwin.go11
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_dragonfly.go11
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_freebsd.go11
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux.go12
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux_mips64le.go12
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_netbsd.go11
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_openbsd.go11
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_solaris.go11
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go7
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/spec/specs.go20
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/suite/suite.go2
-rw-r--r--vendor/github.com/onsi/gomega/CHANGELOG.md7
-rw-r--r--vendor/github.com/onsi/gomega/go.mod1
-rw-r--r--vendor/github.com/onsi/gomega/go.sum6
-rw-r--r--vendor/github.com/onsi/gomega/gomega_dsl.go2
-rw-r--r--vendor/github.com/onsi/gomega/matchers/consist_of.go53
-rw-r--r--vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go4
-rw-r--r--vendor/github.com/onsi/gomega/matchers/match_error_matcher.go4
-rw-r--r--vendor/golang.org/x/tools/AUTHORS3
-rw-r--r--vendor/golang.org/x/tools/CONTRIBUTORS3
-rw-r--r--vendor/golang.org/x/tools/LICENSE (renamed from vendor/golang.org/x/xerrors/LICENSE)2
-rw-r--r--vendor/golang.org/x/tools/PATENTS (renamed from vendor/golang.org/x/xerrors/PATENTS)0
-rw-r--r--vendor/golang.org/x/tools/go/ast/inspector/inspector.go186
-rw-r--r--vendor/golang.org/x/tools/go/ast/inspector/typeof.go216
-rw-r--r--vendor/golang.org/x/xerrors/README2
-rw-r--r--vendor/golang.org/x/xerrors/adaptor.go193
-rw-r--r--vendor/golang.org/x/xerrors/codereview.cfg1
-rw-r--r--vendor/golang.org/x/xerrors/doc.go22
-rw-r--r--vendor/golang.org/x/xerrors/errors.go33
-rw-r--r--vendor/golang.org/x/xerrors/fmt.go187
-rw-r--r--vendor/golang.org/x/xerrors/format.go34
-rw-r--r--vendor/golang.org/x/xerrors/frame.go56
-rw-r--r--vendor/golang.org/x/xerrors/go.mod3
-rw-r--r--vendor/golang.org/x/xerrors/internal/internal.go8
-rw-r--r--vendor/golang.org/x/xerrors/wrap.go106
-rw-r--r--vendor/modules.txt18
233 files changed, 4185 insertions, 3772 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index eda03bf23..a23595712 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -433,7 +433,6 @@ apiv2_test_task:
path: ./*.html
type: text/html
package_versions_script: '$SCRIPT_BASE/logcollector.sh packages'
- ginkgo_node_logs_script: '$SCRIPT_BASE/logcollector.sh ginkgo'
df_script: '$SCRIPT_BASE/logcollector.sh df'
audit_log_script: '$SCRIPT_BASE/logcollector.sh audit'
journal_script: '$SCRIPT_BASE/logcollector.sh journal'
@@ -478,7 +477,11 @@ local_integration_test_task: &local_integration_test_task
gopath_cache: *ro_gopath_cache
setup_script: *setup
main_script: *main
- always: *logs_artifacts
+ always: &int_logs_artifacts
+ <<: *logs_artifacts
+ ginkgo_node_logs_artifacts:
+ path: ./test/e2e/ginkgo-node-*.log
+ type: text/plain
# Nearly identical to `local_integration_test` except all operations
@@ -521,7 +524,7 @@ container_integration_test_task:
gopath_cache: *ro_gopath_cache
setup_script: *setup
main_script: *main
- always: *logs_artifacts
+ always: *int_logs_artifacts
# Execute most integration tests as a regular (non-root) user.
@@ -542,7 +545,7 @@ rootless_integration_test_task:
gopath_cache: *ro_gopath_cache
setup_script: *setup
main_script: *main
- always: *logs_artifacts
+ always: *int_logs_artifacts
# Always run subsequent to integration tests. While parallelism is lost
diff --git a/Makefile b/Makefile
index dfa36e3ef..f9674afe4 100644
--- a/Makefile
+++ b/Makefile
@@ -35,7 +35,11 @@ PKG_MANAGER ?= $(shell command -v dnf yum|head -n1)
# ~/.local/bin is not in PATH on all systems
PRE_COMMIT = $(shell command -v bin/venv/bin/pre-commit ~/.local/bin/pre-commit pre-commit | head -n1)
-SOURCES = $(shell find . -path './.*' -prune -o -name "*.go")
+# This isn't what we actually build; it's a superset, used for target
+# dependencies. Basically: all *.go files, except *_test.go, and except
+# anything in a dot subdirectory. If any of these files is newer than
+# our target (bin/podman{,-remote}), a rebuild is triggered.
+SOURCES = $(shell find . -path './.*' -prune -o \( -name '*.go' -a ! -name '*_test.go' \) -print)
BUILDFLAGS := -mod=vendor $(BUILDFLAGS)
@@ -195,7 +199,6 @@ test/goecho/goecho: .gopathok $(wildcard test/goecho/*.go)
$(GO) build $(BUILDFLAGS) -ldflags '$(LDFLAGS_PODMAN)' -o $@ ./test/goecho
-.PHONY: bin/podman
bin/podman: .gopathok $(SOURCES) go.mod go.sum ## Build with podman
# Make sure to warn in case we're building without the systemd buildtag.
ifeq (,$(findstring systemd,$(BUILDTAGS)))
@@ -207,7 +210,6 @@ endif
.PHONY: podman
podman: bin/podman
-.PHONY: bin/podman-remote
bin/podman-remote: .gopathok $(SOURCES) go.mod go.sum ## Build with podman on remote environment
$(GO) build $(BUILDFLAGS) -gcflags '$(GCFLAGS)' -asmflags '$(ASMFLAGS)' -ldflags '$(LDFLAGS_PODMAN)' -tags "${REMOTETAGS}" -o $@ ./cmd/podman
@@ -303,13 +305,17 @@ localunit: test/goecho/goecho
.PHONY: test
test: localunit localintegration remoteintegration localsystem remotesystem ## Run unit, integration, and system tests.
+.PHONY: ginkgo-run
+ginkgo-run:
+ $(GOBIN)/ginkgo -v $(TESTFLAGS) -tags "$(TAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -nodes 3 -debug test/e2e/. $(HACK)
+
.PHONY: ginkgo
ginkgo:
- $(GOBIN)/ginkgo -v $(TESTFLAGS) -tags "$(BUILDTAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -nodes 3 -debug test/e2e/. hack/.
+ $(MAKE) ginkgo-run TAGS="$(BUILDTAGS)" HACK=hack/.
.PHONY: ginkgo-remote
ginkgo-remote:
- $(GOBIN)/ginkgo -v $(TESTFLAGS) -tags "$(REMOTETAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor test/e2e/.
+ $(MAKE) ginkgo-run TAGS="$(REMOTETAGS)" HACK=
.PHONY: localintegration
localintegration: test-binaries ginkgo
@@ -386,7 +392,7 @@ MANPAGES_DEST ?= $(subst markdown,man, $(subst source,build,$(MANPAGES)))
$(MANPAGES): %: %.md .install.md2man docdir
@sed -e 's/\((podman.*\.md)\)//' -e 's/\[\(podman.*\)\]/\1/' -e 's;<\(/\)\?\(a[^>]*\|sup\)>;;g' $< | $(GOMD2MAN) -in /dev/stdin -out $(subst source/markdown,build/man,$@)
-.PHONY: docs
+.PHONY: docdir
docdir:
mkdir -p docs/build/man
@@ -400,7 +406,7 @@ install-podman-remote-%-docs: podman-remote docs $(MANPAGES)
docs/remote-docs.sh $* docs/build/remote/$* $(if $(findstring windows,$*),docs/source/markdown,docs/build/man)
.PHONY: man-page-check
-man-page-check:
+man-page-check: bin/podman
hack/man-page-checker
hack/xref-helpmsgs-manpages
@@ -639,6 +645,18 @@ install.libseccomp.sudo:
cd ../../seccomp/libseccomp && git checkout --detach $(LIBSECCOMP_COMMIT) && ./autogen.sh && ./configure --prefix=/usr && make all && make install
+.PHONY: completions
+completions: podman podman-remote
+ # key = shell, value = completion filename
+ declare -A outfiles=([bash]=%s [zsh]=_%s [fish]=%s.fish);\
+ for shell in $${!outfiles[*]}; do \
+ for remote in "" "-remote"; do \
+ podman="podman$$remote"; \
+ outfile=$$(printf "completions/$$shell/$${outfiles[$$shell]}" $$podman); \
+ ./bin/$$podman completion $$shell >| $$outfile; \
+ done;\
+ done
+
.PHONY: validate.completions
validate.completions: SHELL:=/usr/bin/env bash # Set shell to bash for this target
validate.completions:
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 5a5d69193..82ecd741a 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -1,207 +1,151 @@
# Release Notes
+
## 3.0.0
### Features
-- Add ability to set system wide options for slirp4netns
-- Add --cidfile to container kill
-- Add commas between mount options
-- Add compose regression to ci
-- Add containerenv information to /run/.containerenv
-- Add default sysctls for pod infra containers
-- Add --filter to podman system prune
-- Adding json formatting to `--list-tags` option in `podman search` command.
-- Add mask and unmask option to --security-opt
-- Add 'MemUsageBytes' format option
-- Add more information and examples on podman and pipes
-- Add network filter for podman ps and pod ps
-- Add Networks format placeholder to podman ps and pod ps
-- Add pod filter for ps
-- Add podman network create option for bridge mtu
-- Add podman network create option for bridge vlan
-- Add pre checkpoint
-- Add Security information to podman info
-- Add support for Gentoo file to package query
-- Add support for network ids
-- Add support for pacman package version query
-- Add support for persistent volume claims in kube files
-- Add support for --platform
-- Add systempaths=unconfined option
-- Add volume filters to system prune
-- Add volume prune --filter support
-- Allow podman push to push manifest lists
-- Allow users to specify TMPDIR in containers.conf
-- Always add the default gateway to the cni config file
-- Drop default log-level from error to warn
-- Enable short-name aliasing
-- Generate kube on multiple containers
-- Generate systemd: do not set `KillMode`
-- Image sign using per user registries.d
-- Implement pod-network-reload
-- Include named volumes in container migration
-- Initial implementation of renaming containers
-- Initial implementation of volume plugins
-- Network connect disconnect on non-running containers
-- Not use local image create/add manifest
-- Podman network label support
-- Prepare support in kube play for other volume types than hostPath
-- Remote copy
-- Remove the ability to use [name:tag] in podman load command
-- Remove varlink support from Podman
-- Sign multi-arch images
-- Support --network=default as if it was private
-- Support Unix timestamps for `podman logs --since`
+- Podman now features initial support for Docker Compose.
+- Added the `podman rename` command, which allows containers to be renamed after they are created ([#1925](https://github.com/containers/podman/issues/1925)).
+- The Podman remote client now supports the `podman copy` command.
+- A new command, `podman network reload`, has been added. This command will re-configure the network of all running containers, and can be used to recreate firewall rules lost when the system firewall was reloaded (e.g. via `firewall-cmd --reload`).
+- Podman networks now have IDs. They can be seen in `podman network ls` and can be used when removing and inspecting networks. Existing networks receive IDs automatically.
+- Podman networks now also support labels. They can be added via the `--label` option to `network create`, and `podman network ls` can filter labels based on them.
+- The `podman network create` command now supports setting bridge MTU and VLAN through the `--opt` option ([#8454](https://github.com/containers/podman/issues/8454)).
+- The `podman container checkpoint` and `podman container restore` commands can now checkpoint and restore containers that include volumes.
+- The `podman container checkpoint` command now supports the `--with-previous` and `--pre-checkpoint` options, and the `podman container restore` command now support the `--import-previous` option. These add support for two-step checkpointing with lowered dump times.
+- The `podman push` command can now push manifest lists. Podman will first attempt to push as an image, then fall back to pushing as a manifest list if that fails.
+- The `podman generate kube` command can now be run on multiple containers at once, and will generate a single pod containing all of them.
+- The `podman kill` command now supports a `--cidfile` option to kill containers given a file containing the container's ID ([#8443](https://github.com/containers/podman/issues/8443)).
+- The `podman volume create` command can now specify volume UID and GID as options with the `UID` and `GID` fields passed to the the `--opt` option.
+- Initial support has been added for Docker Volume Plugins. Podman can now define available plugins in `containers.conf` and use them to create volumes with `podman volume create --driver`.
+- The `podman run` and `podman create` commands now support a new option, `--platform`, to specify the platform of the image to be used when creating the container.
+- The `--security-opt` option to `podman run` and `podman create` now supports the `systempaths=unconfined` option to unrestrict access to all paths in the container, as well as `mask` and `unmask` options to allow more granular restriction of container paths.
+- The `podman stats --format` command now supports a new format specified, `MemUsageBytes`, which prints the raw bytes of memory consumed by a container without human-readable formatting [#8945](https://github.com/containers/podman/issues/8945).
+- The `podman ps` command can now filter containers based on what pod they are joined to via the `pod` filter ([#8512](https://github.com/containers/podman/issues/8512)).
+- The `podman pod ps` command can now filter pods based on what networks they are joined to via the `network` filter.
+- The `podman pod ps` command can now print information on what networks a pod is joined to via the `.Networks` specifier to the `--format` option.
+- The `podman system prune` command now supports filtering what containers, pods, images, and volumes will be pruned.
+- The `podman volume prune` commands now supports filtering what volumes will be pruned.
+- The `podman system prune` command now includes information on space reclaimed ([#8658](https://github.com/containers/podman/issues/8658)).
+- The `podman info` command will now properly print information about packages in use on Gentoo and Arch systems.
+- The `containers.conf` file now contains an option for disabling creation of a new kernel keyring on container creation ([#8384](https://github.com/containers/podman/issues/8384)).
+- The `podman image sign` command can now sign multi-arch images by producing a signature for each image in a given manifest list.
+- The `podman image sign` command, when run as rootless, now supports per-user registry configuration files in `$HOME/.config/containers/registries.d`.
+- Configuration options for `slirp4netns` can now be set system-wide via the `NetworkCmdOptions` configuration option in `containers.conf`.
+
### Changes
-- Add LogSize to container inspect
-- Allow image errors to bubble up from lower level functions.
-- Change name of imageVolumes in container config JSON
-- Cleanup CNI Networks on reboot
-- Consolidate filter logic to pkg subdirectory
-- Make `podman stats` slirp check more robust
-- More /var/run -> /run
-- Prefer read/write images over read/only images
-- Refactor kube.ToSpecGen parameters to struct
-- Rename AutocompletePortCommand func
-- Repeat system pruning until there is nothing removed
-- Switch references of /var/run -> /run
-- Use HTTPProxy settings from containers.conf
-- Use Libpod tmpdir for pause path
-- Use Options as CRImportCheckpoint() argument
-- Use Options as exportCheckpoint() argument
-- Use PasswordCallback instead of Password for ssh
-- Use abi PodPs implementation for libpod/pods/json endpoint
-- Validate that the bridge option is supported
-- archive: move stat-header handling into copy package
-- libpod, conmon: change log level for rootless
-- libpod: change function to accept ExecOptions
-- libpod: handle single user mapped as root
-- make podman play use ENVs from image
-- pkg/copy: introduce a Copier
-- podman events allow future time for --until
-- podman.service should be an exec service not a notify service
-- rewrite podman-cp
-- rootless: add function to retrieve gid/uid mappings
-- rootless: automatically split userns ranges
-- runtime: set XDG_* env variables if missing
-- shell completion for the network flag
-- specgen: improve heuristic for /sys bind mount
-- systemd: make rundir always accessible
+- Shortname aliasing support has now been turned on by default. All Podman commands that must pull an image will, if a TTY is available, prompt the user about what image to pull.
+- The `podman load` command no longer accepts a `NAME[:TAG]` argument. The presence of this argument broke CLI compatibility with Docker by making `docker load` commands unusable with Podman ([#7387](https://github.com/containers/podman/issues/7387)).
+- The Go bindings for the HTTP API have been rewritten with a focus on limiting dependency footprint and improving extensibility. Read more [here](https://github.com/containers/podman/blob/v3.0/pkg/bindings/README.md).
+- The legacy Varlink API has been completely removed from Podman.
+- The default log level for Podman has been changed from Error to Warn.
+- The `podman inspect` command has had the `LogPath` and `LogTag` fields moved into the `LogConfig` structure (from the root of the Inspect structure). The maximum size of the log file is also included.
+- The `podman generate systemd` command no longer generates unit files using the deprecated `KillMode=none` option ([#8615](https://github.com/containers/podman/issues/8615)).
+- The `podman stop` command now releases the container lock while waiting for it to stop - as such, commands like `podman ps` will no longer block until `podman stop` completes ([#8501](https://github.com/containers/podman/issues/8501)).
+- Networks created with `podman network create --internal` no longer use the `dnsname` plugin. This configuration never functioned as expected.
+- Error messages for the remote Podman client have been improved when it cannot connect to a Podman service.
+- Error messages for `podman run` when an invalid SELinux is specified have been improved.
+- Rootless Podman features improved support for containers with a single user mapped into the rootless user namespace.
+- Pod infra containers now respect default sysctls specified in `containers.conf` allowing for advanced configuration of the namespaces they will share.
+- SSH public key handling for remote Podman has been improved.
+
### Bugfixes
-- Close image rawSource when each loop ends
-- Containers should not get inheritable caps by default
-- Correct port range logic for port generation
-- Correct which network commands can be run as rootless
-- Disable CGv1 pod stats on net=host post
-- Do not error on installing duplicate shutdown handler
-- Do not ignore infra command from config files
-- Do not mount sysfs as rootless in more cases
-- Do not pull if image domain is localhost
-- Do not use "true" after "syslog" in exit commands
-- Do not validate the volume source path in specgen
-- Don't accidently remove XDG_RUNTIME_DIR when reseting storage
-- Ensure that `podman play kube` actually reports errors
-- Ensure that user-specified HOSTNAME is honored
-- Ensure we do not edit container config in Exec
-- Exorcise Driver code from libpod/define
-- Expose Height/Width fields to decoder
-- Expose security attribute errors with their own messages
-- Fix Wrong image tag is used when creating a container from an image with multiple tags
-- Fix `podman images...` missing headers in table templates
-- Fix build for mips architecture
-- Fix build for mips architecture follow-up
-- Fix custom mac address with a custom cni network
-- Fix extra quotation mark in manpages.
-- Fix missing options in volumes display while setting uid and gid
-- Fix missing podman-container-rename man page link
-- Fix network ls --filter invalid value flake
-- Fix option names --subuidname and --subgidname
-- Fix panic in libpod images exists endpoint
-- Fix podman build --logfile
-- Fix podman logs read partial log lines
-- Fix problems reported by staticcheck
-- Fix problems with network remove
-- Fix shell completion for ps --filter ancestor
-- Fix some nit
-- Fix spelling mistakes
-- Fix storage.conf to define driver in the VM
-- Fix support for rpmbuild < 4.12.0.
-- Fix: unpause not supported for CGv1 rootless
-- Fxes /etc/hosts duplicated every time after container restarted in a pod
-- Handle --rm when starting a container
-- Handle podman exec capabilities correctly
-- Honor the --layers flag
-- Ignore containers.conf sysctls when sharing namespaces
-- Improve error message when the the podman service is not enabled
-- Make podman generate systemd --new flag parsing more robust
-- Pass down EnableKeyring from containers.conf to conmon
-- Properly handle --cap-add all when running with a --user flag
-- Revert "Allow multiple --network flags for podman run/create"
-- Revert e6fbc15f26b2a609936dfc11732037c70ee14cba
-- Revert the custom cobra vendor
-- Rework pruning to report reclaimed space
-- Set NetNS mode instead of value
-- The slirp4netns sandbox requires pivot_root
-- close journald when reading
-- container create: do not clear image name
-- container stop: release lock before calling the runtime
-- exec: honor --privileged
-- fix: disable seccomp by default when privileged.
-- image list: ignore bare manifest list
-- network: disallow CNI networks with user namespaces
-- oci: keep LC_ env variables to conmon
-- oci: use /proc/self/fd/FD to open unix socket
-- pass full NetworkMode to ParseNetworkNamespace
-- play kube: fix args/command handling
-- play kube: set entrypoint when interpreting Command
-- podman build --force-rm defaults to true in code
-- podman logs honor stderr correctly
-- podman, exec: move conmon to the correct cgroup
-- podman-remote fix sending tar content
-- podman: drop checking valid rootless UID
-- re-open container log files
-- security: honor systempaths=unconfined for ro paths
+- Fixed a bug where the `podman history --no-trunc` command would truncate the `Created By` field ([#9120](https://github.com/containers/podman/issues/9120)).
+- Fixed a bug where root containers that did not explicitly specify a CNI network to join did not generate an entry for the network in use in the `Networks` field of the output of `podman inspect` ([#6618](https://github.com/containers/podman/issues/6618)).
+- Fixed a bug where, under some circumstances, container working directories specified by the image (via the `WORKDIR` instruction) but not present in the image, would not be created ([#9040](https://github.com/containers/podman/issues/9040)).
+- Fixed a bug where the `podman generate systemd` command would generate invalid unit files if the container was creating using a command line that included doubled braces (`{{` and `}}`), e.g. `--log-opt-tag={{.Name}}` ([#9034](https://github.com/containers/podman/issues/9034)).
+- Fixed a bug where the `podman generate systemd --new` command could generate unit files including invalid Podman commands if the container was created using merged short options (e.g. `podman run -dt`) ([#8847](https://github.com/containers/podman/issues/8847)).
+- Fixed a bug where rootless containers joining CNI networks could not set a static IP address ([#7842](https://github.com/containers/podman/issues/7842)).
+- Fixed a bug where rootless containers joining CNI networks could not set network aliases ([#8567](https://github.com/containers/podman/issues/8567)).
+- Fixed a bug where the remote client could, under some circumstances, not include the `Containerfile` when sending build context to the server ([#8374](https://github.com/containers/podman/issues/8374)).
+- Fixed a bug where rootless Podman did not mount `/sys` as a new `sysfs` in some circumstances where it was acceptable.
+- Fixed a bug where rootless containers that both joined a user namespace and a CNI networks would cause a segfault. These options are incompatible and now return an error.
+- Fixed a bug where the `podman play kube` command did not properly handle `CMD` and `ARGS` from images ([#8803](https://github.com/containers/podman/issues/8803)).
+- Fixed a bug where the `podman play kube` command did not properly handle environment variables from images ([#8608](https://github.com/containers/podman/issues/8608)).
+- Fixed a bug where the `podman play kube` command did not properly print errors that occurred when starting containers.
+- Fixed a bug where the `podman play kube` command errored when `hostNetwork` was used ([#8790](https://github.com/containers/podman/issues/8790)).
+- Fixed a bug where the `podman play kube` command would always pull images when the `:latest` tag was specified, even if the image was available locally ([#7838](https://github.com/containers/podman/issues/7838)).
+- Fixed a bug where containers in a pod would create a duplicate entry in the pod's shared `/etc/hosts` file every time the container restarted ([#8921](https://github.com/containers/podman/issues/8921)).
+- Fixed a bug where the `podman search --list-tags` command did not support the `--format` option ([#8740](https://github.com/containers/podman/issues/8740)).
+- Fixed a bug where the `http_proxy` option in `containers.conf` was not being respected, and instead was set unconditionally to true ([#8843](https://github.com/containers/podman/issues/8843)).
+- Fixed a bug where rootless Podman could, on systems with a recent Conmon and users with a long username, fail to attach to containers ([#8798](https://github.com/containers/podman/issues/8798)).
+- Fixed a bug where the `podman images` command would break and fail to display any images if an empty manifest list was present in storage ([#8931](https://github.com/containers/podman/issues/8931)).
+- Fixed a bug where locale environment variables were not properly passed on to Conmon.
+- Fixed a bug where Podman would not build on the MIPS architecture ([#8782](https://github.com/containers/podman/issues/8782)).
+- Fixed a bug where rootless Podman could fail to properly configure user namespaces for rootless containers when the user specified a `--uidmap` option that included a mapping beginning with UID `0`.
+- Fixed a bug where the `podman logs` command using the `k8s-file` backend did not properly handle partial log lines with a length of 1 ([#8879](https://github.com/containers/podman/issues/8879)).
+- Fixed a bug where the `podman logs` command with the `--follow` option did not properly handle log rotation ([#8733](https://github.com/containers/podman/issues/8733)).
+- Fixed a bug where user-specified `HOSTNAME` environment variables were overwritten by Podman ([#8886](https://github.com/containers/podman/issues/8886)).
+- Fixed a bug where Podman would applied default sysctls from `containers.conf` in too many situations (e.g. applying network sysctls when the container shared its network with a pod).
+- Fixed a bug where Podman did not properly handle cases where a secondary image store was in use and an image was present in both the secondary and primary stores ([#8176](https://github.com/containers/podman/issues/8176)).
+- Fixed a bug where systemd-managed rootless Podman containers where the user in the container was not root could fail as the container's PID file was not accessible to systemd on the host ([#8506](https://github.com/containers/podman/issues/8506)).
+- Fixed a bug where the `--privileged` option to `podman run` and `podman create` would, under some circumstances, not disable Seccomp ([#8849](https://github.com/containers/podman/issues/8849)).
+- Fixed a bug where the `podman exec` command did not properly add capabilities when the container or exec session were run with `--privileged`.
+- Fixed a bug where rootless Podman would use the `--enable-sandbox` option to `slirp4netns` unconditionally, even when `pivot_root` was disabled, rendering `slirp4netns` unusable when `pivot_root` was disabled ([#8846](https://github.com/containers/podman/issues/8846)).
+- Fixed a bug where `podman build --logfile` did not actually write the build's log to the logfile.
+- Fixed a bug where the `podman system service` command did not close STDIN, and could display user-interactive prompts ([#8700](https://github.com/containers/podman/issues/8700)).
+- Fixed a bug where the `podman system reset` command could, under some circumstances, remove all the contents of the `XDG_RUNTIME_DIR` directory ([#8680](https://github.com/containers/podman/issues/8680)).
+- Fixed a bug where the `podman network create` command created CNI configurations that did not include a default gateway ([#8748](https://github.com/containers/podman/issues/8748)).
+- Fixed a bug where the `podman.service` systemd unit provided by default used the wrong service type, and would cause systemd to not correctly register the service as started ([#8751](https://github.com/containers/podman/issues/8751)).
+- Fixed a bug where, if the `TMPDIR` environment variable was set for the container engine in `containers.conf`, it was being ignored.
+- Fixed a bug where the `podman events` command did not properly handle future times given to the `--until` option ([#8694](https://github.com/containers/podman/issues/8694)).
+- Fixed a bug where the `podman logs` command wrote container `STDERR` logs to `STDOUT` instead of `STDERR` ([#8683](https://github.com/containers/podman/issues/8683)).
+- Fixed a bug where containers created from an image with multiple tags would report that they were created from the wrong tag ([#8547](https://github.com/containers/podman/issues/8547)).
+- Fixed a bug where container capabilities were not set properly when the `--cap-add=all` and `--user` options to `podman create` and `podman run` were combined.
+- Fixed a bug where the `--layers` option to `podman build` was nonfunctional ([#8643](https://github.com/containers/podman/issues/8643)).
+- Fixed a bug where the `podman system prune` command did not act recursively, and thus would leave images, containers, pods, and volumes present that would be removed by a subsequent call to `podman system prune` ([#7990](https://github.com/containers/podman/issues/7990)).
+- Fixed a bug where the `--publish` option to `podman run` and `podman create` did not properly handle ports specified as a range of ports with no host port specified ([#8650](https://github.com/containers/podman/issues/8650)).
+- Fixed a bug where `--format` did not support JSON output for individual fields ([#8444](https://github.com/containers/podman/issues/8444)).
+- Fixed a bug where the `podman stats` command would fail when run on root containers using the `slirp4netns` network mode ([#7883](https://github.com/containers/podman/issues/7883)).
+- Fixed a bug where the Podman remote client would ask for a password even if the server's SSH daemon did not support password authentication ([#8498](https://github.com/containers/podman/issues/8498)).
+
### API
-- Add API for communicating with Docker volume plugins
-- Change bindings to stop two API calls for ping
-- Close the stdin/tty when using podman as a restAPI.
-- Compat api containers/json add support for filters
-- Container rename bindings
-- Do not pass name argument to Load API
-- Docker compat API - /images/search returns wrong structure (#7857)
-- Docker compat API - containers create ignores the name
-- Fix some network compat api problems
-- Jira RUN-1106 Container handlers updates
-- Jira RUN-1106 Image handlers updates
-- Jira RUN-1106 Network handlers updates
-- Jira RUN-1106 System handlers updates
-- Jira RUN-1106 Volumes handlers updates
-- Makefile: add target to generate bindings
-- More docker compat API fixes
-- Podman image bindings for 3.0
-- REST API v2 - ping - fix typo in header
-- REST API v2 - ping - remove newline from response to improve Docker compatibility
-- Reduce general binding binary size
-- Restore compatible API for prune endpoints
-- compat create should use bindings
-- hack/podman-socat captures the API stream
-- libpod API: pull: fix channel race
-- misc bindings to podman v3
-- pkg/copy: add parsing API
-- podman v3 container bindings
-- podman v3 pod bindings
+- The Compat API for Containers now supports the Rename and Copy APIs.
+- Fixed a bug where the Compat Prune APIs (for volumes, containers, and images) did not return the amount of space reclaimed in their responses.
+- Fixed a bug where the Compat and Libpod Exec APIs for Containers would drop errors that occurred prior to the exec session successfully starting (e.g. a "no such file" error if an invalid executable was passed) ([#8281](https://github.com/containers/podman/issues/8281))
+- Fixed a bug where the Volumes field in the Compat Create API for Containers was being ignored ([#8649](https://github.com/containers/podman/issues/8649)).
+- Fixed a bug where the NetworkMode field in the Compat Create API for Containers was not handling some values, e.g. `container:`, correctly.
+- Fixed a bug where the Compat Create API for Containers did not set container name properly.
+- Fixed a bug where containers created using the Compat Create API unconditionally used Kubernetes file logging (the default specified in `containers.conf` is now used).
+- Fixed a bug where the Compat Inspect API for Containers could include container states not recognized by Docker.
+- Fixed a bug where Podman did not properly clean up after calls to the Events API when the `journald` backend was in use, resulting in a leak of file descriptors ([#8864](https://github.com/containers/podman/issues/8864)).
+- Fixed a bug where the Libpod Pull endpoint for Images could fail with an `index out of range` error under certain circumstances ([#8870](https://github.com/containers/podman/issues/8870)).
+- Fixed a bug where the Libpod Exists endpoint for Images could panic.
+- Fixed a bug where the Compat List API for Containers did not support all filters ([#8860](https://github.com/containers/podman/issues/8860)).
+- Fixed a bug where the Compat and Libpod Resize APIs for Containers ignored the height and width parameters ([#7102](https://github.com/containers/podman/issues/7102)).
+- Fixed a bug where the Compat Search API for Images returned an incorrectly-formatted JSON response ([#8758](https://github.com/containers/podman/pull/8758)).
+- Fixed a bug where the Compat Load API for Images did not properly clean up temporary files.
+- Fixed a bug where the Compat Create API for Networks could panic when an empty IPAM configuration was specified.
+- Fixed a bug where the Compat Inspect and List APIs for Networks did not include Scope.
+
+### Misc
+- Updated Buildah to v1.19.2
+- Updated the containers/storage library to v1.24.5
+- Updated the containers/common library to v0.33.1
+
+## v2.2.1
+### Changes
+- Due to a conflict with a previously-removed field, we were forced to modify the way image volumes (mounting images into containers using `--mount type=image`) were handled in the database. As a result, containers created in Podman 2.2.0 with image volumes will not have them in v2.2.1, and these containers will need to be re-created.
+
+### Bugfixes
+- Fixed a bug where rootless Podman would, on systems without the `XDG_RUNTIME_DIR` environment variable defined, use an incorrect path for the PID file of the Podman pause process, causing Podman to fail to start ([#8539](https://github.com/containers/podman/issues/8539)).
+- Fixed a bug where containers created using Podman v1.7 and earlier were unusable in Podman due to JSON decode errors ([#8613](https://github.com/containers/podman/issues/8613)).
+- Fixed a bug where Podman could retrieve invalid cgroup paths, instead of erroring, for containers that were not running.
+- Fixed a bug where the `podman system reset` command would print a warning about a duplicate shutdown handler being registered.
+- Fixed a bug where rootless Podman would attempt to mount `sysfs` in circumstances where it was not allowed; some OCI runtimes (notably `crun`) would fall back to alternatives and not fail, but others (notably `runc`) would fail to run containers.
+- Fixed a bug where the `podman run` and `podman create` commands would fail to create containers from untagged images ([#8558](https://github.com/containers/podman/issues/8558)).
+- Fixed a bug where remote Podman would prompt for a password even when the server did not support password authentication ([#8498](https://github.com/containers/podman/issues/8498)).
+- Fixed a bug where the `podman exec` command did not move the Conmon process for the exec session into the correct cgroup.
+- Fixed a bug where shell completion for the `ancestor` option to `podman ps --filter` did not work correctly.
+- Fixed a bug where detached containers would not properly clean themselves up (or remove themselves if `--rm` was set) if the Podman command that created them was invoked with `--log-level=debug`.
+
+### API
+- Fixed a bug where the Compat Create endpoint for Containers did not properly handle the `Binds` and `Mounts` parameters in `HostConfig`.
+- Fixed a bug where the Compat Create endpoint for Containers ignored the `Name` query parameter.
+- Fixed a bug where the Compat Create endpoint for Containers did not properly handle the "default" value for `NetworkMode` (this value is used extensively by `docker-compose`) ([#8544](https://github.com/containers/podman/issues/8544)).
+- Fixed a bug where the Compat Build endpoint for Images would sometimes incorrectly use the `target` query parameter as the image's tag.
+
### Misc
-- Bump github.com/containernetworking/plugins from 0.8.7 to 0.9.0
-- Bump github.com/containers/common from 0.30.0 to 0.31.1
-- Bump github.com/containers/image/v5 from 5.8.1 to 5.9.0
-- Bump github.com/containers/storage from 1.24.1 to 1.24.5
-- Bump github.com/cri-o/ocicni to latest master
-- Bump github.com/google/uuid from 1.1.2 to 1.1.5
-- Bump github.com/onsi/gomega from 1.10.3 to 1.10.4
-- Bump github.com/opencontainers/selinux from 1.6.0 to 1.8.0
-- Bump github.com/stretchr/testify from 1.6.1 to 1.7.0
-- Bump k8s.io/apimachinery from 0.19.4 to 0.20.2
-- Bump master to v3.0.0-dev
-- Bump to containers/buildah 1.9.2
-- Bump version in README to v2.2.0
-- vendor containers/psgo@v1.5.2
+- Podman v2.2.0 vendored a non-released, custom version of the `github.com/spf13/cobra` package; this has been reverted to the latest upstream release to aid in packaging.
+- Updated the containers/image library to v5.9.0
## 2.2.0
### Features
@@ -344,7 +288,7 @@
- Fixed a bug where a client disconnecting from the Libpod or Compat events endpoints could result in the server using 100% CPU ([#7946](https://github.com/containers/podman/issues/7946)).
- Fixed a bug where the "no such image" error message sent by the Compat Inspect endpoint for Images returned a 404 status code with an error that was improperly formatted for Docker compatibility.
- Fixed a bug where the Compat Create endpoint for networks did not properly set a default for the `driver` parameter if it was not provided by the client.
-- Fixed a bug where the Compat Inspect endpoint for images did not populate the `RootFS` field of the response.
+- Fixed a bug where the Compat Inspect endpoint for images did not populate the `RootFS`, `VirtualSize`, `ParentId`, `Architecture`, `Os`, and `OsVersion` fields of the response.
- Fixed a bug where the Compat Inspect endpoint for images would omit the `ParentId` field if the image had no parent, and the `Created` field if the image did not have a creation time.
- Fixed a bug where the Compat Remove endpoint for Networks did not support the `Force` query parameter.
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go
index c9a3c5e94..09dd74e20 100644
--- a/cmd/podman/common/completion.go
+++ b/cmd/podman/common/completion.go
@@ -817,6 +817,7 @@ func AutocompleteNetworkFlag(cmd *cobra.Command, args []string, toComplete strin
"allow_host_loopback=": getBoolCompletion,
"cidr=": nil,
"enable_ipv6=": getBoolCompletion,
+ "mtu=": nil,
"outbound_addr=": nil,
"outbound_addr6=": nil,
"port_handler=": func(_ string) ([]string, cobra.ShellCompDirective) {
diff --git a/cmd/podman/volumes/prune.go b/cmd/podman/volumes/prune.go
index 0f3ba9ef6..39ad2735b 100644
--- a/cmd/podman/volumes/prune.go
+++ b/cmd/podman/volumes/prune.go
@@ -49,16 +49,46 @@ func init() {
func prune(cmd *cobra.Command, args []string) error {
var (
- pruneOptions = entities.VolumePruneOptions{}
+ pruneOptions = entities.VolumePruneOptions{}
+ listOptions = entities.VolumeListOptions{}
+ unusedOptions = entities.VolumeListOptions{}
)
// Prompt for confirmation if --force is not set
force, err := cmd.Flags().GetBool("force")
if err != nil {
return err
}
+ pruneOptions.Filters, err = filters.ParseFilterArgumentsIntoFilters(filter)
if !force {
reader := bufio.NewReader(os.Stdin)
- fmt.Println("WARNING! This will remove all volumes not used by at least one container.")
+ fmt.Println("WARNING! This will remove all volumes not used by at least one container. The following volumes will be removed:")
+ if err != nil {
+ return err
+ }
+ listOptions.Filter, err = filters.ParseFilterArgumentsIntoFilters(filter)
+ if err != nil {
+ return err
+ }
+ // filter all the dangling volumes
+ unusedOptions.Filter = make(map[string][]string, 1)
+ unusedOptions.Filter["dangling"] = []string{"true"}
+ unusedVolumes, err := registry.ContainerEngine().VolumeList(context.Background(), unusedOptions)
+ if err != nil {
+ return err
+ }
+ // filter volumes based on user input
+ filteredVolumes, err := registry.ContainerEngine().VolumeList(context.Background(), listOptions)
+ if err != nil {
+ return err
+ }
+ finalVolumes := getIntersection(unusedVolumes, filteredVolumes)
+ if len(finalVolumes) < 1 {
+ fmt.Println("No dangling volumes found")
+ return nil
+ }
+ for _, fv := range finalVolumes {
+ fmt.Println(fv.Name)
+ }
fmt.Print("Are you sure you want to continue? [y/N] ")
answer, err := reader.ReadString('\n')
if err != nil {
@@ -68,13 +98,23 @@ func prune(cmd *cobra.Command, args []string) error {
return nil
}
}
- pruneOptions.Filters, err = filters.ParseFilterArgumentsIntoFilters(filter)
- if err != nil {
- return err
- }
responses, err := registry.ContainerEngine().VolumePrune(context.Background(), pruneOptions)
if err != nil {
return err
}
return utils.PrintVolumePruneResults(responses, false)
}
+
+func getIntersection(a, b []*entities.VolumeListReport) []*entities.VolumeListReport {
+ var intersection []*entities.VolumeListReport
+ hash := make(map[string]bool, len(a))
+ for _, aa := range a {
+ hash[aa.Name] = true
+ }
+ for _, bb := range b {
+ if hash[bb.Name] {
+ intersection = append(intersection, bb)
+ }
+ }
+ return intersection
+}
diff --git a/completions/Readme.md b/completions/Readme.md
index 5c9d16f3c..132a38bbf 100644
--- a/completions/Readme.md
+++ b/completions/Readme.md
@@ -2,6 +2,6 @@
Podman offers shell completion scripts for bash, zsh and fish. The completion scripts are available for both `podman` and `podman-remote`.
-The shell completion scripts are generated by `make completion`, do not edit these files directly. To install them you can run `sudo make install.completions`.
+The shell completion scripts are generated by `make completions`; do not edit these files directly. To install them you can run `sudo make install.completions`.
For information about these scripts see [`man podman-completion`](../docs/source/markdown/podman-completion.1.md)
diff --git a/contrib/cirrus/logcollector.sh b/contrib/cirrus/logcollector.sh
index 323015cef..38a15ded1 100755
--- a/contrib/cirrus/logcollector.sh
+++ b/contrib/cirrus/logcollector.sh
@@ -31,7 +31,6 @@ case $1 in
esac
;;
df) showrun df -lhTx tmpfs ;;
- ginkgo) showrun cat $CIRRUS_WORKING_DIR/test/e2e/ginkgo-node-*.log ;;
journal) showrun journalctl -b ;;
podman) showrun ./bin/podman system info ;;
server)
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index b3ac8b6ee..1d72db065 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -638,6 +638,7 @@ Valid _mode_ values are:
- **private**: create a new namespace for the container (default)
- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options:
- **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
+ - **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`).
- **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`).
- **enable_ipv6=true|false**: Enable IPv6. Default is false. (Required for `outbound_addr6`).
- **outbound_addr=INTERFACE**: Specify the outbound interface slirp should bind to (ipv4 traffic only).
diff --git a/docs/source/markdown/podman-network-create.1.md b/docs/source/markdown/podman-network-create.1.md
index 2fafd1e31..3d5d98055 100644
--- a/docs/source/markdown/podman-network-create.1.md
+++ b/docs/source/markdown/podman-network-create.1.md
@@ -7,8 +7,9 @@ podman\-network-create - Create a Podman CNI network
**podman network create** [*options*] name
## DESCRIPTION
-Create a CNI-network configuration for use with Podman. By default, Podman creates a bridge connection. A
-*Macvlan* connection can be created with the *macvlan* option. In the case of *Macvlan* connections, the
+Create a CNI-network configuration for use with Podman. By default, Podman creates a bridge connection.
+A *Macvlan* connection can be created with the *-d macvlan* option. A parent device for macvlan can
+be designated with the *-o parent=\<device>* option. In the case of *Macvlan* connections, the
CNI *dhcp* plugin needs to be activated or the container image must have a DHCP client to interact
with the host network's DHCP server.
@@ -55,6 +56,8 @@ Set metadata for a network (e.g., --label mykey=value).
#### **--macvlan**
+*This option is being deprecated*
+
Create a *Macvlan* based connection rather than a classic bridge. You must pass an interface name from the host for the
Macvlan connection.
@@ -101,7 +104,7 @@ Create a network that uses a *192.168.55.0/24** subnet and has an IP address ran
Create a Macvlan based network using the host interface eth0
```
-# podman network create --macvlan eth0 newnet
+# podman network create -d macvlan -o parent=eth0 newnet
/etc/cni/net.d/newnet.conflist
```
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index e606c456f..0838dd546 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -674,6 +674,7 @@ Valid _mode_ values are:
- **private**: create a new namespace for the container (default)
- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options:
- **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
+ - **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`).
- **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`).
- **enable_ipv6=true|false**: Enable IPv6. Default is false. (Required for `outbound_addr6`).
- **outbound_addr=INTERFACE**: Specify the outbound interface slirp should bind to (ipv4 traffic only).
diff --git a/docs/tutorials/rootless_tutorial.md b/docs/tutorials/rootless_tutorial.md
index cb73fc519..ea5990833 100644
--- a/docs/tutorials/rootless_tutorial.md
+++ b/docs/tutorials/rootless_tutorial.md
@@ -184,7 +184,7 @@ total 0
We do recognize that this doesn't really match how many people intend to use rootless Podman - they want their UID inside and outside the container to match. Thus, we provide the `--userns=keep-id` flag, which ensures that your user is mapped to its own UID and GID inside the container.
-It is also helpful to distinguish between running Podman as a rootless user, and a container which is built to run rootless. If the container you're trying you run has a `USER` which is not root, then when mounting volumes you **must** use `--userns=keep-id`. This is because the container user would not be able to become `root` and access the mounted volumes.
+It is also helpful to distinguish between running Podman as a rootless user, and a container which is built to run rootless. If the container you're trying to run has a `USER` which is not root, then when mounting volumes you **must** use `--userns=keep-id`. This is because the container user would not be able to become `root` and access the mounted volumes.
Other considerations in regards to volumes:
diff --git a/go.mod b/go.mod
index cd60fb6ec..6847a49c7 100644
--- a/go.mod
+++ b/go.mod
@@ -8,14 +8,14 @@ require (
github.com/buger/goterm v0.0.0-20181115115552-c206103e1f37
github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect
- github.com/containernetworking/cni v0.8.0
+ github.com/containernetworking/cni v0.8.1
github.com/containernetworking/plugins v0.9.0
github.com/containers/buildah v1.19.3
github.com/containers/common v0.33.1
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.10.1
github.com/containers/psgo v1.5.2
- github.com/containers/storage v1.24.5
+ github.com/containers/storage v1.25.0
github.com/coreos/go-systemd/v22 v22.1.0
github.com/cri-o/ocicni v0.2.1-0.20201204103948-b6cbe99b9756
github.com/cyphar/filepath-securejoin v0.2.2
@@ -38,8 +38,8 @@ require (
github.com/kr/text v0.2.0 // indirect
github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618
- github.com/onsi/ginkgo v1.14.2
- github.com/onsi/gomega v1.10.4
+ github.com/onsi/ginkgo v1.15.0
+ github.com/onsi/gomega v1.10.5
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6
github.com/opencontainers/runc v1.0.0-rc91.0.20200708210054-ce54a9d4d79b
@@ -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.12.0
+ github.com/rootless-containers/rootlesskit v0.13.0
github.com/sirupsen/logrus v1.7.0
github.com/spf13/cobra v1.1.1
github.com/spf13/pflag v1.0.5
diff --git a/go.sum b/go.sum
index 064295f31..9eb760693 100644
--- a/go.sum
+++ b/go.sum
@@ -92,6 +92,8 @@ github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kw
github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
github.com/containernetworking/cni v0.8.0 h1:BT9lpgGoH4jw3lFC7Odz2prU5ruiYKcgAjMCbgybcKI=
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
+github.com/containernetworking/cni v0.8.1 h1:7zpDnQ3T3s4ucOuJ/ZCLrYBxzkg0AELFfII3Epo9TmI=
+github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
github.com/containernetworking/plugins v0.8.7/go.mod h1:R7lXeZaBzpfqapcAbHRW8/CYwm0dHzbz0XEjofx0uB0=
github.com/containernetworking/plugins v0.9.0 h1:c+1gegKhR7+d0Caum9pEHugZlyhXPOG6v3V6xJgIGCI=
github.com/containernetworking/plugins v0.9.0/go.mod h1:dbWv4dI0QrBGuVgj+TuVQ6wJRZVOhrCQj91YyC92sxg=
@@ -114,6 +116,8 @@ github.com/containers/psgo v1.5.2/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzP
github.com/containers/storage v1.23.7/go.mod h1:cUT2zHjtx+WlVri30obWmM2gpqpi8jfPsmIzP1TVpEI=
github.com/containers/storage v1.24.5 h1:BusfdU0rCS2/Daa/DPw+0iLfGRlYA7UVF7D0el3N7Vk=
github.com/containers/storage v1.24.5/go.mod h1:YC+2pY8SkfEAcZkwycxYbpK8EiRbx5soPPwz9dxe4IQ=
+github.com/containers/storage v1.25.0 h1:p0PLlQcWmtE+7XLfOCR0WuYyMTby1yozpI4DaKOtWTA=
+github.com/containers/storage v1.25.0/go.mod h1:UxTYd5F4mPVqmDRcRL0PBS8+HP74aBn96eahnhEvPtk=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-iptables v0.4.5 h1:DpHb9vJrZQEFMcVLFKAAGMUVX0XoRC0ptCthinRYm38=
@@ -263,8 +267,6 @@ github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIE
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.5 h1:kxhtnfFVi+rYdOALN0B3k9UT86zVJKfBimRaciULW4I=
-github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
@@ -375,6 +377,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw=
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
+github.com/mattn/go-shellwords v1.0.11 h1:vCoR9VPpsk/TZFW2JwK5I9S0xdrtUq2bph6/YjEPnaw=
+github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y=
@@ -434,6 +438,8 @@ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
+github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4=
+github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@@ -444,6 +450,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U=
github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ=
+github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
+github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
@@ -513,8 +521,8 @@ github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa
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/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rootless-containers/rootlesskit v0.12.0 h1:nEVacjGda4wBYnPLWsmZSeA+mFwajGorCuA4VHmu2OE=
-github.com/rootless-containers/rootlesskit v0.12.0/go.mod h1:swXXhX7XMmJQvgqYlaezs6M6vkHN851uPXRStsFr8ug=
+github.com/rootless-containers/rootlesskit v0.13.0 h1:41nnfB7yFxtHSeQHYupSvVxAJWh/hjmn03w6UjH7nv8=
+github.com/rootless-containers/rootlesskit v0.13.0/go.mod h1:DwE/9ASct8sj7bueOXqKiwcdzyZ+yV6qhTAtJUO7988=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
@@ -606,6 +614,7 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
@@ -629,6 +638,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -652,6 +662,7 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -679,6 +690,7 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@@ -753,6 +765,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
@@ -791,7 +804,11 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/libpod/kube.go b/libpod/kube.go
index bf314b9a3..f9ead027d 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -353,22 +353,21 @@ func containerToV1Container(c *Container) (v1.Container, []v1.Volume, *v1.PodDNS
return kubeContainer, kubeVolumes, nil, err
}
- containerCommands := c.Command()
- kubeContainer.Name = removeUnderscores(c.Name())
+ // Handle command and arguments.
+ if ep := c.Entrypoint(); len(ep) > 0 {
+ // If we have an entrypoint, set the container's command as
+ // arguments.
+ kubeContainer.Command = ep
+ kubeContainer.Args = c.Command()
+ } else {
+ kubeContainer.Command = c.Command()
+ }
+ kubeContainer.Name = removeUnderscores(c.Name())
_, image := c.Image()
kubeContainer.Image = image
kubeContainer.Stdin = c.Stdin()
- // prepend the entrypoint of the container to command
- if ep := c.Entrypoint(); len(c.Entrypoint()) > 0 {
- ep = append(ep, containerCommands...)
- containerCommands = ep
- }
- kubeContainer.Command = containerCommands
- // TODO need to figure out how we handle command vs entry point. Kube appears to prefer entrypoint.
- // right now we just take the container's command
- //container.Args = args
kubeContainer.WorkingDir = c.WorkingDir()
kubeContainer.Ports = ports
// This should not be applicable
diff --git a/libpod/network/config.go b/libpod/network/config.go
index ce351129e..294e23509 100644
--- a/libpod/network/config.go
+++ b/libpod/network/config.go
@@ -103,7 +103,9 @@ func (p PortMapConfig) Bytes() ([]byte, error) {
// IPAMDHCP describes the ipamdhcp config
type IPAMDHCP struct {
- DHCP string `json:"type"`
+ DHCP string `json:"type"`
+ Routes []IPAMRoute `json:"routes,omitempty"`
+ Ranges [][]IPAMLocalHostRangeConf `json:"ranges,omitempty"`
}
// MacVLANConfig describes the macvlan config
@@ -111,6 +113,7 @@ type MacVLANConfig struct {
PluginType string `json:"type"`
Master string `json:"master"`
IPAM IPAMDHCP `json:"ipam"`
+ MTU int `json:"mtu,omitempty"`
}
// Bytes outputs the configuration as []byte
diff --git a/libpod/network/create.go b/libpod/network/create.go
index a8f985af9..deacf487a 100644
--- a/libpod/network/create.go
+++ b/libpod/network/create.go
@@ -29,7 +29,7 @@ func Create(name string, options entities.NetworkCreateOptions, runtimeConfig *c
return nil, err
}
defer l.releaseCNILock()
- if len(options.MacVLAN) > 0 {
+ if len(options.MacVLAN) > 0 || options.Driver == MacVLANNetworkDriver {
fileName, err = createMacVLAN(name, options, runtimeConfig)
} else {
fileName, err = createBridge(name, options, runtimeConfig)
@@ -249,6 +249,7 @@ func createBridge(name string, options entities.NetworkCreateOptions, runtimeCon
func createMacVLAN(name string, options entities.NetworkCreateOptions, runtimeConfig *config.Config) (string, error) {
var (
+ mtu int
plugins []CNIPlugins
)
liveNetNames, err := GetLiveNetworkNames()
@@ -256,9 +257,17 @@ func createMacVLAN(name string, options entities.NetworkCreateOptions, runtimeCo
return "", err
}
- // Make sure the host-device exists
- if !util.StringInSlice(options.MacVLAN, liveNetNames) {
- return "", errors.Errorf("failed to find network interface %q", options.MacVLAN)
+ // The parent can be defined with --macvlan or as an option (-o parent:device)
+ parentNetworkDevice := options.MacVLAN
+ if len(parentNetworkDevice) < 1 {
+ if parent, ok := options.Options["parent"]; ok {
+ parentNetworkDevice = parent
+ }
+ }
+
+ // Make sure the host-device exists if provided
+ if len(parentNetworkDevice) > 0 && !util.StringInSlice(parentNetworkDevice, liveNetNames) {
+ return "", errors.Errorf("failed to find network interface %q", parentNetworkDevice)
}
if len(name) > 0 {
netNames, err := GetNetworkNamesFromFileSystem(runtimeConfig)
@@ -275,7 +284,19 @@ func createMacVLAN(name string, options entities.NetworkCreateOptions, runtimeCo
}
}
ncList := NewNcList(name, version.Current(), options.Labels)
- macvlan := NewMacVLANPlugin(options.MacVLAN)
+ if val, ok := options.Options["mtu"]; ok {
+ intVal, err := strconv.Atoi(val)
+ if err != nil {
+ return "", err
+ }
+ if intVal > 0 {
+ mtu = intVal
+ }
+ }
+ macvlan, err := NewMacVLANPlugin(parentNetworkDevice, options.Gateway, &options.Range, &options.Subnet, mtu)
+ if err != nil {
+ return "", err
+ }
plugins = append(plugins, macvlan)
ncList["plugins"] = plugins
b, err := json.MarshalIndent(ncList, "", " ")
diff --git a/libpod/network/netconflist.go b/libpod/network/netconflist.go
index 165a9067b..9be98e78f 100644
--- a/libpod/network/netconflist.go
+++ b/libpod/network/netconflist.go
@@ -172,15 +172,31 @@ func HasDNSNamePlugin(paths []string) bool {
}
// NewMacVLANPlugin creates a macvlanconfig with a given device name
-func NewMacVLANPlugin(device string) MacVLANConfig {
+func NewMacVLANPlugin(device string, gateway net.IP, ipRange *net.IPNet, subnet *net.IPNet, mtu int) (MacVLANConfig, error) {
i := IPAMDHCP{DHCP: "dhcp"}
+ if gateway != nil || ipRange != nil || subnet != nil {
+ ipam, err := NewIPAMLocalHostRange(subnet, ipRange, gateway)
+ if err != nil {
+ return MacVLANConfig{}, err
+ }
+ ranges := make([][]IPAMLocalHostRangeConf, 0)
+ ranges = append(ranges, ipam)
+ i.Ranges = ranges
+ }
m := MacVLANConfig{
PluginType: "macvlan",
- Master: device,
IPAM: i,
}
- return m
+ if mtu > 0 {
+ m.MTU = mtu
+ }
+ // CNI is supposed to use the default route if a
+ // parent device is not provided
+ if len(device) > 0 {
+ m.Master = device
+ }
+ return m, nil
}
// IfPassesFilter filters NetworkListReport and returns true if the filter match the given config
diff --git a/libpod/network/network.go b/libpod/network/network.go
index 0fb878b18..0ff14c1f7 100644
--- a/libpod/network/network.go
+++ b/libpod/network/network.go
@@ -17,11 +17,17 @@ import (
"github.com/sirupsen/logrus"
)
-// DefaultNetworkDriver is the default network type used
-var DefaultNetworkDriver = "bridge"
+var (
+ // BridgeNetworkDriver defines the bridge cni driver
+ BridgeNetworkDriver = "bridge"
+ // DefaultNetworkDriver is the default network type used
+ DefaultNetworkDriver = BridgeNetworkDriver
+ // MacVLANNetworkDriver defines the macvlan cni driver
+ MacVLANNetworkDriver = "macvlan"
+)
// SupportedNetworkDrivers describes the list of supported drivers
-var SupportedNetworkDrivers = []string{DefaultNetworkDriver}
+var SupportedNetworkDrivers = []string{BridgeNetworkDriver, MacVLANNetworkDriver}
// isSupportedDriver checks if the user provided driver is supported
func isSupportedDriver(driver string) error {
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 737dbf935..55d338e7d 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -15,6 +15,7 @@ import (
"path/filepath"
"regexp"
"sort"
+ "strconv"
"strings"
"syscall"
"time"
@@ -42,6 +43,9 @@ const (
// slirp4netnsDNS is the IP for the built-in DNS server in the slirp network
slirp4netnsDNS = "10.0.2.3"
+
+ // slirp4netnsMTU the default MTU override
+ slirp4netnsMTU = 65520
)
// Get an OCICNI network config
@@ -282,6 +286,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error {
enableIPv6 := false
outboundAddr := ""
outboundAddr6 := ""
+ mtu := slirp4netnsMTU
if ctr.config.NetworkOptions != nil {
slirpOptions = append(slirpOptions, ctr.config.NetworkOptions["slirp4netns"]...)
@@ -345,6 +350,11 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error {
}
}
outboundAddr6 = value
+ case "mtu":
+ mtu, err = strconv.Atoi(value)
+ if mtu < 68 || err != nil {
+ return errors.Errorf("invalid mtu %q", value)
+ }
default:
return errors.Errorf("unknown option for slirp4netns: %q", o)
}
@@ -358,8 +368,8 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error {
if disableHostLoopback && slirpFeatures.HasDisableHostLoopback {
cmdArgs = append(cmdArgs, "--disable-host-loopback")
}
- if slirpFeatures.HasMTU {
- cmdArgs = append(cmdArgs, "--mtu", "65520")
+ if mtu > -1 && slirpFeatures.HasMTU {
+ cmdArgs = append(cmdArgs, fmt.Sprintf("--mtu=%d", mtu))
}
if !noPivotRoot && slirpFeatures.HasEnableSandbox {
cmdArgs = append(cmdArgs, "--enable-sandbox")
@@ -1170,7 +1180,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
// update network status if container is not running
networkStatus := c.state.NetworkStatus
// clip out the index of the network
- tmpNetworkStatus := make([]*cnitypes.Result, len(networkStatus)-1)
+ tmpNetworkStatus := make([]*cnitypes.Result, 0, len(networkStatus)-1)
for k, v := range networkStatus {
if index != k {
tmpNetworkStatus = append(tmpNetworkStatus, v)
diff --git a/libpod/options.go b/libpod/options.go
index c7bac7e1f..20f62ee37 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -2190,13 +2190,37 @@ func WithPodNetworks(networks []string) PodCreateOption {
}
}
+// WithPodNoNetwork tells the pod to disable external networking.
+func WithPodNoNetwork() PodCreateOption {
+ return func(pod *Pod) error {
+ if pod.valid {
+ return define.ErrPodFinalized
+ }
+
+ if !pod.config.InfraContainer.HasInfraContainer {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot disable pod networking as no infra container is being created")
+ }
+
+ if len(pod.config.InfraContainer.PortBindings) > 0 ||
+ pod.config.InfraContainer.StaticIP != nil ||
+ pod.config.InfraContainer.StaticMAC != nil ||
+ len(pod.config.InfraContainer.Networks) > 0 ||
+ pod.config.InfraContainer.HostNetwork {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot disable pod network if network-related configuration is specified")
+ }
+
+ pod.config.InfraContainer.NoNetwork = true
+
+ return nil
+ }
+}
+
// WithPodHostNetwork tells the pod to use the host's network namespace.
func WithPodHostNetwork() PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
-
if !pod.config.InfraContainer.HasInfraContainer {
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod host networking as no infra container is being created")
}
@@ -2204,7 +2228,8 @@ func WithPodHostNetwork() PodCreateOption {
if len(pod.config.InfraContainer.PortBindings) > 0 ||
pod.config.InfraContainer.StaticIP != nil ||
pod.config.InfraContainer.StaticMAC != nil ||
- len(pod.config.InfraContainer.Networks) > 0 {
+ len(pod.config.InfraContainer.Networks) > 0 ||
+ pod.config.InfraContainer.NoNetwork {
return errors.Wrapf(define.ErrInvalidArg, "cannot set host network if network-related configuration is specified")
}
diff --git a/libpod/pod.go b/libpod/pod.go
index c8f62ca18..784c2cf5e 100644
--- a/libpod/pod.go
+++ b/libpod/pod.go
@@ -93,6 +93,7 @@ type podState struct {
type InfraContainerConfig struct {
ConmonPidFile string `json:"conmonPidFile"`
HasInfraContainer bool `json:"makeInfraContainer"`
+ NoNetwork bool `json:"noNetwork,omitempty"`
HostNetwork bool `json:"infraHostNetwork,omitempty"`
PortBindings []ocicni.PortMapping `json:"infraPortBindings"`
StaticIP net.IP `json:"staticIP,omitempty"`
diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go
index dd957527d..564851f4e 100644
--- a/libpod/runtime_pod_infra_linux.go
+++ b/libpod/runtime_pod_infra_linux.go
@@ -94,8 +94,16 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
}
}
- // Since user namespace sharing is not implemented, we only need to check if it's rootless
- if !p.config.InfraContainer.HostNetwork {
+ switch {
+ case p.config.InfraContainer.HostNetwork:
+ if err := g.RemoveLinuxNamespace(string(spec.NetworkNamespace)); err != nil {
+ return nil, errors.Wrapf(err, "error removing network namespace from pod %s infra container", p.ID())
+ }
+ case p.config.InfraContainer.NoNetwork:
+ // Do nothing - we have a network namespace by default,
+ // but should not configure slirp.
+ default:
+ // Since user namespace sharing is not implemented, we only need to check if it's rootless
netmode := "bridge"
if isRootless || p.config.InfraContainer.Slirp4netns {
netmode = "slirp4netns"
@@ -106,8 +114,6 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
// PostConfigureNetNS should not be set since user namespace sharing is not implemented
// and rootless networking no longer supports post configuration setup
options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, false, netmode, p.config.InfraContainer.Networks))
- } else if err := g.RemoveLinuxNamespace(string(spec.NetworkNamespace)); err != nil {
- return nil, errors.Wrapf(err, "error removing network namespace from pod %s infra container", p.ID())
}
// For each option in InfraContainerConfig - if set, pass into
diff --git a/nix/nixpkgs.json b/nix/nixpkgs.json
index 0cfb251f2..459fb28f8 100644
--- a/nix/nixpkgs.json
+++ b/nix/nixpkgs.json
@@ -1,9 +1,9 @@
{
"url": "https://github.com/nixos/nixpkgs",
- "rev": "ce7b327a52d1b82f82ae061754545b1c54b06c66",
- "date": "2021-01-25T11:28:05+01:00",
- "path": "/nix/store/dpsa6a1sy8hwhwjkklc52brs9z1k5fx9-nixpkgs",
- "sha256": "1rc4if8nmy9lrig0ddihdwpzg2s8y36vf20hfywb8hph5hpsg4vj",
+ "rev": "30c2fb65feaf1068b1c413a0b75470afd351c291",
+ "date": "2021-01-28T21:27:34-05:00",
+ "path": "/nix/store/zk71rlw37vg9hqc5j0vqi9x8qzb2ir0m-nixpkgs",
+ "sha256": "0b1y1lgzbagpgh9cvi9szkm162laifz0q2ss4pibns3j3gqpf5gl",
"fetchSubmodules": false,
"deepClone": false,
"leaveDotGit": false
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index b41987800..86508f938 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -233,8 +233,8 @@ func KillContainer(w http.ResponseWriter, r *http.Request) {
return
}
if sig == 0 || syscall.Signal(sig) == syscall.SIGKILL {
- var opts entities.WaitOptions
- if _, err := containerEngine.ContainerWait(r.Context(), []string{name}, opts); err != nil {
+ if _, err := utils.WaitContainer(w, r); err != nil {
+
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
}
diff --git a/pkg/api/handlers/compat/resize.go b/pkg/api/handlers/compat/resize.go
index cc8c6ef0a..a769ae1b5 100644
--- a/pkg/api/handlers/compat/resize.go
+++ b/pkg/api/handlers/compat/resize.go
@@ -84,5 +84,5 @@ func ResizeTTY(w http.ResponseWriter, r *http.Request) {
// reasons.
status = http.StatusCreated
}
- utils.WriteResponse(w, status, "")
+ w.WriteHeader(status)
}
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go
index 2409d3a20..2c35dd191 100644
--- a/pkg/api/handlers/libpod/pods.go
+++ b/pkg/api/handlers/libpod/pods.go
@@ -139,19 +139,20 @@ func PodStop(w http.ResponseWriter, r *http.Request) {
logrus.Errorf("Error cleaning up pod %s container %s: %v", pod.ID(), id, err)
}
}
- var errs []error //nolint
+
+ report := entities.PodStopReport{Id: pod.ID()}
for id, err := range responses {
- errs = append(errs, errors.Wrapf(err, "error stopping container %s", id))
+ report.Errs = append(report.Errs, errors.Wrapf(err, "error stopping container %s", id))
}
- report := entities.PodStopReport{
- Errs: errs,
- Id: pod.ID(),
+
+ code := http.StatusOK
+ if len(report.Errs) > 0 {
+ code = http.StatusConflict
}
- utils.WriteResponse(w, http.StatusOK, report)
+ utils.WriteResponse(w, code, report)
}
func PodStart(w http.ResponseWriter, r *http.Request) {
- var errs []error //nolint
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
@@ -168,19 +169,23 @@ func PodStart(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusNotModified, "")
return
}
+
responses, err := pod.Start(r.Context())
if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
- utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
+ utils.Error(w, "Something went wrong", http.StatusConflict, err)
return
}
+
+ report := entities.PodStartReport{Id: pod.ID()}
for id, err := range responses {
- errs = append(errs, errors.Wrapf(err, "error starting container %s", id))
+ report.Errs = append(report.Errs, errors.Wrapf(err, "error starting container "+id))
}
- report := entities.PodStartReport{
- Errs: errs,
- Id: pod.ID(),
+
+ code := http.StatusOK
+ if len(report.Errs) > 0 {
+ code = http.StatusConflict
}
- utils.WriteResponse(w, http.StatusOK, report)
+ utils.WriteResponse(w, code, report)
}
func PodDelete(w http.ResponseWriter, r *http.Request) {
@@ -209,14 +214,11 @@ func PodDelete(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
- report := entities.PodRmReport{
- Id: pod.ID(),
- }
+ report := entities.PodRmReport{Id: pod.ID()}
utils.WriteResponse(w, http.StatusOK, report)
}
func PodRestart(w http.ResponseWriter, r *http.Request) {
- var errs []error //nolint
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
@@ -229,14 +231,17 @@ func PodRestart(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
+
+ report := entities.PodRestartReport{Id: pod.ID()}
for id, err := range responses {
- errs = append(errs, errors.Wrapf(err, "error restarting container %s", id))
+ report.Errs = append(report.Errs, errors.Wrapf(err, "error restarting container %s", id))
}
- report := entities.PodRestartReport{
- Errs: errs,
- Id: pod.ID(),
+
+ code := http.StatusOK
+ if len(report.Errs) > 0 {
+ code = http.StatusConflict
}
- utils.WriteResponse(w, http.StatusOK, report)
+ utils.WriteResponse(w, code, report)
}
func PodPrune(w http.ResponseWriter, r *http.Request) {
@@ -267,7 +272,6 @@ func PodPruneHelper(r *http.Request) ([]*entities.PodPruneReport, error) {
}
func PodPause(w http.ResponseWriter, r *http.Request) {
- var errs []error //nolint
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
@@ -280,18 +284,20 @@ func PodPause(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
+
+ report := entities.PodPauseReport{Id: pod.ID()}
for id, v := range responses {
- errs = append(errs, errors.Wrapf(v, "error pausing container %s", id))
+ report.Errs = append(report.Errs, errors.Wrapf(v, "error pausing container %s", id))
}
- report := entities.PodPauseReport{
- Errs: errs,
- Id: pod.ID(),
+
+ code := http.StatusOK
+ if len(report.Errs) > 0 {
+ code = http.StatusConflict
}
- utils.WriteResponse(w, http.StatusOK, report)
+ utils.WriteResponse(w, code, report)
}
func PodUnpause(w http.ResponseWriter, r *http.Request) {
- var errs []error //nolint
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
@@ -304,14 +310,17 @@ func PodUnpause(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "failed to pause pod", http.StatusInternalServerError, err)
return
}
+
+ report := entities.PodUnpauseReport{Id: pod.ID()}
for id, v := range responses {
- errs = append(errs, errors.Wrapf(v, "error unpausing container %s", id))
+ report.Errs = append(report.Errs, errors.Wrapf(v, "error unpausing container %s", id))
}
- report := entities.PodUnpauseReport{
- Errs: errs,
- Id: pod.ID(),
+
+ code := http.StatusOK
+ if len(report.Errs) > 0 {
+ code = http.StatusConflict
}
- utils.WriteResponse(w, http.StatusOK, &report)
+ utils.WriteResponse(w, code, &report)
}
func PodTop(w http.ResponseWriter, r *http.Request) {
@@ -361,7 +370,6 @@ func PodKill(w http.ResponseWriter, r *http.Request) {
runtime = r.Context().Value("runtime").(*libpod.Runtime)
decoder = r.Context().Value("decoder").(*schema.Decoder)
signal = "SIGKILL"
- errs []error //nolint
)
query := struct {
Signal string `schema:"signal"`
@@ -413,16 +421,18 @@ func PodKill(w http.ResponseWriter, r *http.Request) {
return
}
+ report := &entities.PodKillReport{Id: pod.ID()}
for _, v := range responses {
if v != nil {
- errs = append(errs, v)
+ report.Errs = append(report.Errs, v)
}
}
- report := &entities.PodKillReport{
- Errs: errs,
- Id: pod.ID(),
+
+ code := http.StatusOK
+ if len(report.Errs) > 0 {
+ code = http.StatusConflict
}
- utils.WriteResponse(w, http.StatusOK, report)
+ utils.WriteResponse(w, code, report)
}
func PodExists(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/api/handlers/utils/handler.go b/pkg/api/handlers/utils/handler.go
index 4bab1c93f..b3c674788 100644
--- a/pkg/api/handlers/utils/handler.go
+++ b/pkg/api/handlers/utils/handler.go
@@ -1,16 +1,17 @@
package utils
import (
- "encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
+ "unsafe"
"github.com/blang/semver"
"github.com/gorilla/mux"
+ jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -144,6 +145,50 @@ func WriteResponse(w http.ResponseWriter, code int, value interface{}) {
}
}
+func init() {
+ jsoniter.RegisterTypeEncoderFunc("error", MarshalErrorJSON, MarshalErrorJSONIsEmpty)
+ jsoniter.RegisterTypeEncoderFunc("[]error", MarshalErrorSliceJSON, MarshalErrorSliceJSONIsEmpty)
+}
+
+var json = jsoniter.ConfigCompatibleWithStandardLibrary
+
+// MarshalErrorJSON writes error to stream as string
+func MarshalErrorJSON(ptr unsafe.Pointer, stream *jsoniter.Stream) {
+ p := *((*error)(ptr))
+ if p == nil {
+ stream.WriteNil()
+ } else {
+ stream.WriteString(p.Error())
+ }
+}
+
+// MarshalErrorSliceJSON writes []error to stream as []string JSON blob
+func MarshalErrorSliceJSON(ptr unsafe.Pointer, stream *jsoniter.Stream) {
+ a := *((*[]error)(ptr))
+ switch {
+ case len(a) == 0:
+ stream.WriteNil()
+ default:
+ stream.WriteArrayStart()
+ for i, e := range a {
+ if i > 0 {
+ stream.WriteMore()
+ }
+ stream.WriteString(e.Error())
+ }
+ stream.WriteArrayEnd()
+ }
+}
+
+func MarshalErrorJSONIsEmpty(_ unsafe.Pointer) bool {
+ return false
+}
+
+func MarshalErrorSliceJSONIsEmpty(_ unsafe.Pointer) bool {
+ return false
+}
+
+// WriteJSON writes an interface value encoded as JSON to w
func WriteJSON(w http.ResponseWriter, code int, value interface{}) {
// FIXME: we don't need to write the header in all/some circumstances.
w.Header().Set("Content-Type", "application/json")
diff --git a/pkg/api/server/register_pods.go b/pkg/api/server/register_pods.go
index 105de4ee7..4873eb926 100644
--- a/pkg/api/server/register_pods.go
+++ b/pkg/api/server/register_pods.go
@@ -43,6 +43,11 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
// $ref: "#/definitions/IdResponse"
// 400:
// $ref: "#/responses/BadParamError"
+ // 409:
+ // description: status conflict
+ // schema:
+ // type: string
+ // description: message describing error
// 500:
// $ref: "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/pods/create"), s.APIHandler(libpod.PodCreate)).Methods(http.MethodPost)
@@ -149,7 +154,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
// 404:
// $ref: "#/responses/NoSuchPod"
// 409:
- // $ref: "#/responses/ConflictError"
+ // $ref: "#/responses/PodKillReport"
// 500:
// $ref: "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/pods/{name}/kill"), s.APIHandler(libpod.PodKill)).Methods(http.MethodPost)
@@ -170,6 +175,8 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
// $ref: '#/responses/PodPauseReport'
// 404:
// $ref: "#/responses/NoSuchPod"
+ // 409:
+ // $ref: '#/responses/PodPauseReport'
// 500:
// $ref: "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/pods/{name}/pause"), s.APIHandler(libpod.PodPause)).Methods(http.MethodPost)
@@ -189,6 +196,8 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
// $ref: '#/responses/PodRestartReport'
// 404:
// $ref: "#/responses/NoSuchPod"
+ // 409:
+ // $ref: "#/responses/PodRestartReport"
// 500:
// $ref: "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/pods/{name}/restart"), s.APIHandler(libpod.PodRestart)).Methods(http.MethodPost)
@@ -210,6 +219,8 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
// $ref: "#/responses/PodAlreadyStartedError"
// 404:
// $ref: "#/responses/NoSuchPod"
+ // 409:
+ // $ref: '#/responses/PodStartReport'
// 500:
// $ref: "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/pods/{name}/start"), s.APIHandler(libpod.PodStart)).Methods(http.MethodPost)
@@ -237,6 +248,8 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
// $ref: "#/responses/BadParamError"
// 404:
// $ref: "#/responses/NoSuchPod"
+ // 409:
+ // $ref: "#/responses/PodStopReport"
// 500:
// $ref: "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/pods/{name}/stop"), s.APIHandler(libpod.PodStop)).Methods(http.MethodPost)
@@ -256,6 +269,8 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
// $ref: '#/responses/PodUnpauseReport'
// 404:
// $ref: "#/responses/NoSuchPod"
+ // 409:
+ // $ref: '#/responses/PodUnpauseReport'
// 500:
// $ref: "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/pods/{name}/unpause"), s.APIHandler(libpod.PodUnpause)).Methods(http.MethodPost)
diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go
index 69ae7a32f..586cdec8c 100644
--- a/pkg/bindings/containers/attach.go
+++ b/pkg/bindings/containers/attach.go
@@ -348,7 +348,7 @@ func attachHandleResize(ctx, winCtx context.Context, winChange chan os.Signal, i
resizeErr = ResizeContainerTTY(ctx, id, new(ResizeTTYOptions).WithHeight(h).WithWidth(w))
}
if resizeErr != nil {
- logrus.Warnf("failed to resize TTY: %v", err)
+ logrus.Warnf("failed to resize TTY: %v", resizeErr)
}
}
}
diff --git a/pkg/bindings/containers/types_attach_options.go b/pkg/bindings/containers/types_attach_options.go
index 6d8c1cb01..ab5a1615c 100644
--- a/pkg/bindings/containers/types_attach_options.go
+++ b/pkg/bindings/containers/types_attach_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *AttachOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *AttachOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_checkpoint_options.go b/pkg/bindings/containers/types_checkpoint_options.go
index ec766de4a..d239c476f 100644
--- a/pkg/bindings/containers/types_checkpoint_options.go
+++ b/pkg/bindings/containers/types_checkpoint_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *CheckpointOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *CheckpointOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_commit_options.go b/pkg/bindings/containers/types_commit_options.go
index b745bebe2..061f16e25 100644
--- a/pkg/bindings/containers/types_commit_options.go
+++ b/pkg/bindings/containers/types_commit_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *CommitOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *CommitOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_create_options.go b/pkg/bindings/containers/types_create_options.go
index 4b9574cf1..8cde11335 100644
--- a/pkg/bindings/containers/types_create_options.go
+++ b/pkg/bindings/containers/types_create_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_diff_options.go b/pkg/bindings/containers/types_diff_options.go
index 55fa6930d..e912bf041 100644
--- a/pkg/bindings/containers/types_diff_options.go
+++ b/pkg/bindings/containers/types_diff_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *DiffOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *DiffOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_execinspect_options.go b/pkg/bindings/containers/types_execinspect_options.go
index c5d1f931a..b870db46b 100644
--- a/pkg/bindings/containers/types_execinspect_options.go
+++ b/pkg/bindings/containers/types_execinspect_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ExecInspectOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ExecInspectOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_execstart_options.go b/pkg/bindings/containers/types_execstart_options.go
index 9ecb70a3e..95f97b1d7 100644
--- a/pkg/bindings/containers/types_execstart_options.go
+++ b/pkg/bindings/containers/types_execstart_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ExecStartOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ExecStartOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_execstartandattach_options.go b/pkg/bindings/containers/types_execstartandattach_options.go
index a5a691e35..1981c319a 100644
--- a/pkg/bindings/containers/types_execstartandattach_options.go
+++ b/pkg/bindings/containers/types_execstartandattach_options.go
@@ -5,9 +5,9 @@ import (
"io"
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -45,33 +45,19 @@ func (o *ExecStartAndAttachOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -85,6 +71,7 @@ func (o *ExecStartAndAttachOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_exists_options.go b/pkg/bindings/containers/types_exists_options.go
index f0d8885b2..a52777600 100644
--- a/pkg/bindings/containers/types_exists_options.go
+++ b/pkg/bindings/containers/types_exists_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ExistsOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ExistsOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_export_options.go b/pkg/bindings/containers/types_export_options.go
index 55e413c72..3943a5a3b 100644
--- a/pkg/bindings/containers/types_export_options.go
+++ b/pkg/bindings/containers/types_export_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ExportOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ExportOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_healthcheck_options.go b/pkg/bindings/containers/types_healthcheck_options.go
index 9d8b25bf4..a548232cd 100644
--- a/pkg/bindings/containers/types_healthcheck_options.go
+++ b/pkg/bindings/containers/types_healthcheck_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *HealthCheckOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *HealthCheckOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_init_options.go b/pkg/bindings/containers/types_init_options.go
index 6fb5795c0..92e8a6c17 100644
--- a/pkg/bindings/containers/types_init_options.go
+++ b/pkg/bindings/containers/types_init_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *InitOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *InitOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_inspect_options.go b/pkg/bindings/containers/types_inspect_options.go
index 722372414..fdb84bda8 100644
--- a/pkg/bindings/containers/types_inspect_options.go
+++ b/pkg/bindings/containers/types_inspect_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_kill_options.go b/pkg/bindings/containers/types_kill_options.go
index c5d5a3c6a..45bd790a4 100644
--- a/pkg/bindings/containers/types_kill_options.go
+++ b/pkg/bindings/containers/types_kill_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *KillOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *KillOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_list_options.go b/pkg/bindings/containers/types_list_options.go
index c363dcd32..3293320ec 100644
--- a/pkg/bindings/containers/types_list_options.go
+++ b/pkg/bindings/containers/types_list_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ListOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ListOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_log_options.go b/pkg/bindings/containers/types_log_options.go
index 364f29de4..e78eb7bd0 100644
--- a/pkg/bindings/containers/types_log_options.go
+++ b/pkg/bindings/containers/types_log_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *LogOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *LogOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_mount_options.go b/pkg/bindings/containers/types_mount_options.go
index 6f4349b73..cc8df1255 100644
--- a/pkg/bindings/containers/types_mount_options.go
+++ b/pkg/bindings/containers/types_mount_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *MountOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *MountOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_mountedcontainerpaths_options.go b/pkg/bindings/containers/types_mountedcontainerpaths_options.go
index 0d8b69654..78fa2fca0 100644
--- a/pkg/bindings/containers/types_mountedcontainerpaths_options.go
+++ b/pkg/bindings/containers/types_mountedcontainerpaths_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *MountedContainerPathsOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *MountedContainerPathsOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_pause_options.go b/pkg/bindings/containers/types_pause_options.go
index 0cc65f64e..55f14bef0 100644
--- a/pkg/bindings/containers/types_pause_options.go
+++ b/pkg/bindings/containers/types_pause_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *PauseOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *PauseOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_prune_options.go b/pkg/bindings/containers/types_prune_options.go
index 10adf0a2a..000c7c0bd 100644
--- a/pkg/bindings/containers/types_prune_options.go
+++ b/pkg/bindings/containers/types_prune_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_remove_options.go b/pkg/bindings/containers/types_remove_options.go
index ffe1488c1..dfb5367eb 100644
--- a/pkg/bindings/containers/types_remove_options.go
+++ b/pkg/bindings/containers/types_remove_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_rename_options.go b/pkg/bindings/containers/types_rename_options.go
index b7a723f7a..f4f5d1426 100644
--- a/pkg/bindings/containers/types_rename_options.go
+++ b/pkg/bindings/containers/types_rename_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *RenameOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *RenameOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_resizeexectty_options.go b/pkg/bindings/containers/types_resizeexectty_options.go
index 0212adeb2..e63d965eb 100644
--- a/pkg/bindings/containers/types_resizeexectty_options.go
+++ b/pkg/bindings/containers/types_resizeexectty_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ResizeExecTTYOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ResizeExecTTYOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_resizetty_options.go b/pkg/bindings/containers/types_resizetty_options.go
index cee607902..3170f4053 100644
--- a/pkg/bindings/containers/types_resizetty_options.go
+++ b/pkg/bindings/containers/types_resizetty_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ResizeTTYOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ResizeTTYOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_restart_options.go b/pkg/bindings/containers/types_restart_options.go
index 8dcc6b5b7..d59176e67 100644
--- a/pkg/bindings/containers/types_restart_options.go
+++ b/pkg/bindings/containers/types_restart_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *RestartOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *RestartOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_restore_options.go b/pkg/bindings/containers/types_restore_options.go
index 491d678a5..e9f14fc47 100644
--- a/pkg/bindings/containers/types_restore_options.go
+++ b/pkg/bindings/containers/types_restore_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *RestoreOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *RestoreOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_shouldrestart_options.go b/pkg/bindings/containers/types_shouldrestart_options.go
index 30ab618c7..49f943460 100644
--- a/pkg/bindings/containers/types_shouldrestart_options.go
+++ b/pkg/bindings/containers/types_shouldrestart_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ShouldRestartOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ShouldRestartOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_start_options.go b/pkg/bindings/containers/types_start_options.go
index 4050a8993..a0f0b3077 100644
--- a/pkg/bindings/containers/types_start_options.go
+++ b/pkg/bindings/containers/types_start_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *StartOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *StartOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_stats_options.go b/pkg/bindings/containers/types_stats_options.go
index 74f419913..79e35ba62 100644
--- a/pkg/bindings/containers/types_stats_options.go
+++ b/pkg/bindings/containers/types_stats_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *StatsOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *StatsOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_stop_options.go b/pkg/bindings/containers/types_stop_options.go
index 940ec5832..f221b16e8 100644
--- a/pkg/bindings/containers/types_stop_options.go
+++ b/pkg/bindings/containers/types_stop_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *StopOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *StopOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_top_options.go b/pkg/bindings/containers/types_top_options.go
index 5f2717c28..570dd4e90 100644
--- a/pkg/bindings/containers/types_top_options.go
+++ b/pkg/bindings/containers/types_top_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *TopOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *TopOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_unmount_options.go b/pkg/bindings/containers/types_unmount_options.go
index 060327c4a..24249073e 100644
--- a/pkg/bindings/containers/types_unmount_options.go
+++ b/pkg/bindings/containers/types_unmount_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *UnmountOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *UnmountOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_unpause_options.go b/pkg/bindings/containers/types_unpause_options.go
index e02bf2c95..3b1d75001 100644
--- a/pkg/bindings/containers/types_unpause_options.go
+++ b/pkg/bindings/containers/types_unpause_options.go
@@ -3,9 +3,9 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *UnpauseOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *UnpauseOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/containers/types_wait_options.go b/pkg/bindings/containers/types_wait_options.go
index 2f5aa983e..005cc38cb 100644
--- a/pkg/bindings/containers/types_wait_options.go
+++ b/pkg/bindings/containers/types_wait_options.go
@@ -3,10 +3,10 @@ package containers
import (
"net/url"
"reflect"
- "strconv"
"strings"
"github.com/containers/podman/v2/libpod/define"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -44,33 +44,19 @@ func (o *WaitOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -84,6 +70,7 @@ func (o *WaitOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/generate/types_kube_options.go b/pkg/bindings/generate/types_kube_options.go
index 5fb965c9f..218d308e1 100644
--- a/pkg/bindings/generate/types_kube_options.go
+++ b/pkg/bindings/generate/types_kube_options.go
@@ -1,13 +1,13 @@
package generate
import (
+ "errors"
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
- "github.com/pkg/errors"
)
/*
@@ -43,33 +43,19 @@ func (o *KubeOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *KubeOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/generate/types_systemd_options.go b/pkg/bindings/generate/types_systemd_options.go
index ce7286b3a..faf981d1b 100644
--- a/pkg/bindings/generate/types_systemd_options.go
+++ b/pkg/bindings/generate/types_systemd_options.go
@@ -1,13 +1,13 @@
package generate
import (
+ "errors"
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
- "github.com/pkg/errors"
)
/*
@@ -43,33 +43,19 @@ func (o *SystemdOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *SystemdOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/generator/generator.go b/pkg/bindings/generator/generator.go
index 6a7f600a8..dad154166 100644
--- a/pkg/bindings/generator/generator.go
+++ b/pkg/bindings/generator/generator.go
@@ -54,33 +54,19 @@ func (o *{{.StructName}}) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -94,6 +80,7 @@ func (o *{{.StructName}}) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
@@ -144,7 +131,7 @@ func main() {
panic(err)
}
// always add reflect
- imports := []string{"\"reflect\""}
+ imports := []string{"\"reflect\"", "\"github.com/containers/podman/v2/pkg/bindings/util\""}
for _, imp := range f.Imports {
imports = append(imports, imp.Path.Value)
}
diff --git a/pkg/bindings/images/types_diff_options.go b/pkg/bindings/images/types_diff_options.go
index 34a5bf2df..edfc7bfa2 100644
--- a/pkg/bindings/images/types_diff_options.go
+++ b/pkg/bindings/images/types_diff_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *DiffOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *DiffOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_exists_options.go b/pkg/bindings/images/types_exists_options.go
index f0d4be6ce..649be4862 100644
--- a/pkg/bindings/images/types_exists_options.go
+++ b/pkg/bindings/images/types_exists_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ExistsOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ExistsOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_export_options.go b/pkg/bindings/images/types_export_options.go
index 172cb2b5c..ebd053165 100644
--- a/pkg/bindings/images/types_export_options.go
+++ b/pkg/bindings/images/types_export_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ExportOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ExportOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_get_options.go b/pkg/bindings/images/types_get_options.go
index c91ddb170..33ebe2611 100644
--- a/pkg/bindings/images/types_get_options.go
+++ b/pkg/bindings/images/types_get_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *GetOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *GetOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_history_options.go b/pkg/bindings/images/types_history_options.go
index bd4224cd8..b2c37acea 100644
--- a/pkg/bindings/images/types_history_options.go
+++ b/pkg/bindings/images/types_history_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *HistoryOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *HistoryOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_import_options.go b/pkg/bindings/images/types_import_options.go
index 81eda946e..e2aed0866 100644
--- a/pkg/bindings/images/types_import_options.go
+++ b/pkg/bindings/images/types_import_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ImportOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ImportOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_list_options.go b/pkg/bindings/images/types_list_options.go
index 5dc4242fc..e194474b9 100644
--- a/pkg/bindings/images/types_list_options.go
+++ b/pkg/bindings/images/types_list_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ListOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ListOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_load_options.go b/pkg/bindings/images/types_load_options.go
index 7bbd56c09..7e15d4e03 100644
--- a/pkg/bindings/images/types_load_options.go
+++ b/pkg/bindings/images/types_load_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *LoadOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *LoadOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_prune_options.go b/pkg/bindings/images/types_prune_options.go
index c290bb379..f86676d53 100644
--- a/pkg/bindings/images/types_prune_options.go
+++ b/pkg/bindings/images/types_prune_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_pull_options.go b/pkg/bindings/images/types_pull_options.go
index 5452560fb..59e2b6354 100644
--- a/pkg/bindings/images/types_pull_options.go
+++ b/pkg/bindings/images/types_pull_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *PullOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *PullOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_push_options.go b/pkg/bindings/images/types_push_options.go
index b7d8a6f2d..85f1ffee5 100644
--- a/pkg/bindings/images/types_push_options.go
+++ b/pkg/bindings/images/types_push_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *PushOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *PushOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_remove_options.go b/pkg/bindings/images/types_remove_options.go
index 66a6bea7d..d79186565 100644
--- a/pkg/bindings/images/types_remove_options.go
+++ b/pkg/bindings/images/types_remove_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_search_options.go b/pkg/bindings/images/types_search_options.go
index 299d27505..a55c9ac89 100644
--- a/pkg/bindings/images/types_search_options.go
+++ b/pkg/bindings/images/types_search_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *SearchOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *SearchOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_tag_options.go b/pkg/bindings/images/types_tag_options.go
index 40cd4a35b..b323ea41c 100644
--- a/pkg/bindings/images/types_tag_options.go
+++ b/pkg/bindings/images/types_tag_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *TagOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *TagOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_tree_options.go b/pkg/bindings/images/types_tree_options.go
index a671fa4e0..8e1b16c5c 100644
--- a/pkg/bindings/images/types_tree_options.go
+++ b/pkg/bindings/images/types_tree_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *TreeOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *TreeOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/images/types_untag_options.go b/pkg/bindings/images/types_untag_options.go
index e38c5f18e..b28670134 100644
--- a/pkg/bindings/images/types_untag_options.go
+++ b/pkg/bindings/images/types_untag_options.go
@@ -3,9 +3,9 @@ package images
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *UntagOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *UntagOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/manifests/types_add_options.go b/pkg/bindings/manifests/types_add_options.go
index 1e588c668..61314c479 100644
--- a/pkg/bindings/manifests/types_add_options.go
+++ b/pkg/bindings/manifests/types_add_options.go
@@ -1,13 +1,13 @@
package manifests
import (
+ "errors"
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
- "github.com/pkg/errors"
)
/*
@@ -43,33 +43,19 @@ func (o *AddOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *AddOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/manifests/types_create_options.go b/pkg/bindings/manifests/types_create_options.go
index 3a564a92b..4c7c1397a 100644
--- a/pkg/bindings/manifests/types_create_options.go
+++ b/pkg/bindings/manifests/types_create_options.go
@@ -1,13 +1,13 @@
package manifests
import (
+ "errors"
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
- "github.com/pkg/errors"
)
/*
@@ -43,33 +43,19 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/manifests/types_exists_options.go b/pkg/bindings/manifests/types_exists_options.go
index fd2cd3ee9..2a4962ae6 100644
--- a/pkg/bindings/manifests/types_exists_options.go
+++ b/pkg/bindings/manifests/types_exists_options.go
@@ -1,13 +1,13 @@
package manifests
import (
+ "errors"
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
- "github.com/pkg/errors"
)
/*
@@ -43,33 +43,19 @@ func (o *ExistsOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ExistsOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/manifests/types_inspect_options.go b/pkg/bindings/manifests/types_inspect_options.go
index 2af4190d4..0b82fc3cf 100644
--- a/pkg/bindings/manifests/types_inspect_options.go
+++ b/pkg/bindings/manifests/types_inspect_options.go
@@ -1,13 +1,13 @@
package manifests
import (
+ "errors"
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
- "github.com/pkg/errors"
)
/*
@@ -43,33 +43,19 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/manifests/types_remove_options.go b/pkg/bindings/manifests/types_remove_options.go
index 3b35c38b8..6ed0fd329 100644
--- a/pkg/bindings/manifests/types_remove_options.go
+++ b/pkg/bindings/manifests/types_remove_options.go
@@ -1,13 +1,13 @@
package manifests
import (
+ "errors"
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
- "github.com/pkg/errors"
)
/*
@@ -43,33 +43,19 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/network/types_connect_options.go b/pkg/bindings/network/types_connect_options.go
index b6081ba57..4440bbed4 100644
--- a/pkg/bindings/network/types_connect_options.go
+++ b/pkg/bindings/network/types_connect_options.go
@@ -3,9 +3,9 @@ package network
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ConnectOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ConnectOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/network/types_create_options.go b/pkg/bindings/network/types_create_options.go
index 5b0abe870..5fbdce93a 100644
--- a/pkg/bindings/network/types_create_options.go
+++ b/pkg/bindings/network/types_create_options.go
@@ -4,9 +4,9 @@ import (
"net"
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -44,33 +44,19 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -84,6 +70,7 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/network/types_disconnect_options.go b/pkg/bindings/network/types_disconnect_options.go
index 8b2a9cb71..947f2f114 100644
--- a/pkg/bindings/network/types_disconnect_options.go
+++ b/pkg/bindings/network/types_disconnect_options.go
@@ -3,9 +3,9 @@ package network
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *DisconnectOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *DisconnectOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/network/types_exists_options.go b/pkg/bindings/network/types_exists_options.go
index 8076a18e8..2fad34789 100644
--- a/pkg/bindings/network/types_exists_options.go
+++ b/pkg/bindings/network/types_exists_options.go
@@ -3,9 +3,9 @@ package network
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ExistsOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ExistsOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/network/types_inspect_options.go b/pkg/bindings/network/types_inspect_options.go
index cec5ef7b2..144ccbfae 100644
--- a/pkg/bindings/network/types_inspect_options.go
+++ b/pkg/bindings/network/types_inspect_options.go
@@ -3,9 +3,9 @@ package network
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/network/types_list_options.go b/pkg/bindings/network/types_list_options.go
index 6a33fb7b6..60632ce33 100644
--- a/pkg/bindings/network/types_list_options.go
+++ b/pkg/bindings/network/types_list_options.go
@@ -3,9 +3,9 @@ package network
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ListOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ListOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/network/types_remove_options.go b/pkg/bindings/network/types_remove_options.go
index 861fe1f2c..4ad4a2301 100644
--- a/pkg/bindings/network/types_remove_options.go
+++ b/pkg/bindings/network/types_remove_options.go
@@ -3,9 +3,9 @@ package network
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/play/types_kube_options.go b/pkg/bindings/play/types_kube_options.go
index 5aec4b479..ea3872aae 100644
--- a/pkg/bindings/play/types_kube_options.go
+++ b/pkg/bindings/play/types_kube_options.go
@@ -1,13 +1,13 @@
package play
import (
+ "errors"
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
- "github.com/pkg/errors"
)
/*
@@ -43,33 +43,19 @@ func (o *KubeOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *KubeOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_create_options.go b/pkg/bindings/pods/types_create_options.go
index b501d1151..cfa29c6be 100644
--- a/pkg/bindings/pods/types_create_options.go
+++ b/pkg/bindings/pods/types_create_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_exists_options.go b/pkg/bindings/pods/types_exists_options.go
index 7221afe74..6149ab1cc 100644
--- a/pkg/bindings/pods/types_exists_options.go
+++ b/pkg/bindings/pods/types_exists_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ExistsOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ExistsOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_inspect_options.go b/pkg/bindings/pods/types_inspect_options.go
index a2eb25fef..281717ff1 100644
--- a/pkg/bindings/pods/types_inspect_options.go
+++ b/pkg/bindings/pods/types_inspect_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_kill_options.go b/pkg/bindings/pods/types_kill_options.go
index f9cad3579..4c310d50c 100644
--- a/pkg/bindings/pods/types_kill_options.go
+++ b/pkg/bindings/pods/types_kill_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *KillOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *KillOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_list_options.go b/pkg/bindings/pods/types_list_options.go
index 02e7adf2d..20f3229e5 100644
--- a/pkg/bindings/pods/types_list_options.go
+++ b/pkg/bindings/pods/types_list_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ListOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ListOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_pause_options.go b/pkg/bindings/pods/types_pause_options.go
index 2e4fdb4a6..0f0f5bd97 100644
--- a/pkg/bindings/pods/types_pause_options.go
+++ b/pkg/bindings/pods/types_pause_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *PauseOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *PauseOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_prune_options.go b/pkg/bindings/pods/types_prune_options.go
index 616ad6dc9..ef8aae17f 100644
--- a/pkg/bindings/pods/types_prune_options.go
+++ b/pkg/bindings/pods/types_prune_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_remove_options.go b/pkg/bindings/pods/types_remove_options.go
index 6960d8839..f51f67129 100644
--- a/pkg/bindings/pods/types_remove_options.go
+++ b/pkg/bindings/pods/types_remove_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_restart_options.go b/pkg/bindings/pods/types_restart_options.go
index 427833044..ec05e9fc9 100644
--- a/pkg/bindings/pods/types_restart_options.go
+++ b/pkg/bindings/pods/types_restart_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *RestartOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *RestartOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_start_options.go b/pkg/bindings/pods/types_start_options.go
index e98798459..ec9f5b1de 100644
--- a/pkg/bindings/pods/types_start_options.go
+++ b/pkg/bindings/pods/types_start_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *StartOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *StartOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_stats_options.go b/pkg/bindings/pods/types_stats_options.go
index 845a534a3..8be7d175d 100644
--- a/pkg/bindings/pods/types_stats_options.go
+++ b/pkg/bindings/pods/types_stats_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *StatsOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *StatsOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_stop_options.go b/pkg/bindings/pods/types_stop_options.go
index 86000eb57..fa3577e72 100644
--- a/pkg/bindings/pods/types_stop_options.go
+++ b/pkg/bindings/pods/types_stop_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *StopOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *StopOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_top_options.go b/pkg/bindings/pods/types_top_options.go
index ada0b1e25..c3c701dad 100644
--- a/pkg/bindings/pods/types_top_options.go
+++ b/pkg/bindings/pods/types_top_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *TopOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *TopOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/pods/types_unpause_options.go b/pkg/bindings/pods/types_unpause_options.go
index 6a9ee8fcd..281f0ea8d 100644
--- a/pkg/bindings/pods/types_unpause_options.go
+++ b/pkg/bindings/pods/types_unpause_options.go
@@ -3,9 +3,9 @@ package pods
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *UnpauseOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *UnpauseOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/system/types_disk_options.go b/pkg/bindings/system/types_disk_options.go
index c5eb2f94c..6f0c3735a 100644
--- a/pkg/bindings/system/types_disk_options.go
+++ b/pkg/bindings/system/types_disk_options.go
@@ -3,9 +3,9 @@ package system
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *DiskOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *DiskOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/system/types_events_options.go b/pkg/bindings/system/types_events_options.go
index 2e95339e6..401a9807e 100644
--- a/pkg/bindings/system/types_events_options.go
+++ b/pkg/bindings/system/types_events_options.go
@@ -3,9 +3,9 @@ package system
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *EventsOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *EventsOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/system/types_info_options.go b/pkg/bindings/system/types_info_options.go
index 263513b0f..7c07b5081 100644
--- a/pkg/bindings/system/types_info_options.go
+++ b/pkg/bindings/system/types_info_options.go
@@ -3,9 +3,9 @@ package system
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *InfoOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *InfoOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/system/types_prune_options.go b/pkg/bindings/system/types_prune_options.go
index a9a6a6cda..c677ccca6 100644
--- a/pkg/bindings/system/types_prune_options.go
+++ b/pkg/bindings/system/types_prune_options.go
@@ -3,9 +3,9 @@ package system
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/system/types_version_options.go b/pkg/bindings/system/types_version_options.go
index be07581fa..60ebfced9 100644
--- a/pkg/bindings/system/types_version_options.go
+++ b/pkg/bindings/system/types_version_options.go
@@ -3,9 +3,9 @@ package system
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *VersionOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *VersionOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/util/util.go b/pkg/bindings/util/util.go
new file mode 100644
index 000000000..403846355
--- /dev/null
+++ b/pkg/bindings/util/util.go
@@ -0,0 +1,30 @@
+package util
+
+import (
+ "reflect"
+ "strconv"
+)
+
+func IsSimpleType(f reflect.Value) bool {
+ switch f.Kind() {
+ case reflect.Bool, reflect.Int, reflect.Int64, reflect.Uint, reflect.Uint64, reflect.String:
+ return true
+ }
+ return false
+}
+
+func SimpleTypeToParam(f reflect.Value) string {
+ switch f.Kind() {
+ case reflect.Bool:
+ return strconv.FormatBool(f.Bool())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ return strconv.FormatInt(f.Int(), 10)
+ case reflect.Uint, reflect.Uint64:
+ // f.Uint() is always an uint64
+ return strconv.FormatUint(f.Uint(), 10)
+ case reflect.String:
+ return f.String()
+ }
+ panic("the input parameter is not a simple type")
+}
diff --git a/pkg/bindings/volumes/types_create_options.go b/pkg/bindings/volumes/types_create_options.go
index 171090afe..2254f8c13 100644
--- a/pkg/bindings/volumes/types_create_options.go
+++ b/pkg/bindings/volumes/types_create_options.go
@@ -3,9 +3,9 @@ package volumes
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *CreateOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/volumes/types_exists_options.go b/pkg/bindings/volumes/types_exists_options.go
index c66586a23..9840b1bcd 100644
--- a/pkg/bindings/volumes/types_exists_options.go
+++ b/pkg/bindings/volumes/types_exists_options.go
@@ -3,9 +3,9 @@ package volumes
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ExistsOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ExistsOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/volumes/types_inspect_options.go b/pkg/bindings/volumes/types_inspect_options.go
index 3a1d396a7..51ac2d348 100644
--- a/pkg/bindings/volumes/types_inspect_options.go
+++ b/pkg/bindings/volumes/types_inspect_options.go
@@ -3,9 +3,9 @@ package volumes
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *InspectOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/volumes/types_list_options.go b/pkg/bindings/volumes/types_list_options.go
index 56033a575..c96e647b0 100644
--- a/pkg/bindings/volumes/types_list_options.go
+++ b/pkg/bindings/volumes/types_list_options.go
@@ -3,9 +3,9 @@ package volumes
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *ListOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *ListOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/volumes/types_prune_options.go b/pkg/bindings/volumes/types_prune_options.go
index c043d69d0..06d16b659 100644
--- a/pkg/bindings/volumes/types_prune_options.go
+++ b/pkg/bindings/volumes/types_prune_options.go
@@ -3,9 +3,9 @@ package volumes
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *PruneOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/bindings/volumes/types_remove_options.go b/pkg/bindings/volumes/types_remove_options.go
index 1f8ba4e22..4b0037234 100644
--- a/pkg/bindings/volumes/types_remove_options.go
+++ b/pkg/bindings/volumes/types_remove_options.go
@@ -3,9 +3,9 @@ package volumes
import (
"net/url"
"reflect"
- "strconv"
"strings"
+ "github.com/containers/podman/v2/pkg/bindings/util"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -43,33 +43,19 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
if reflect.Ptr == f.Kind() {
f = f.Elem()
}
- switch f.Kind() {
- case reflect.Bool:
- params.Set(fieldName, strconv.FormatBool(f.Bool()))
- case reflect.String:
- params.Set(fieldName, f.String())
- case reflect.Int, reflect.Int64:
- // f.Int() is always an int64
- params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
- case reflect.Uint, reflect.Uint64:
- // f.Uint() is always an uint64
- params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
- case reflect.Slice:
- typ := reflect.TypeOf(f.Interface()).Elem()
- switch typ.Kind() {
- case reflect.String:
- sl := f.Slice(0, f.Len())
- s, ok := sl.Interface().([]string)
- if !ok {
- return nil, errors.New("failed to convert to string slice")
+ switch {
+ case util.IsSimpleType(f):
+ params.Set(fieldName, util.SimpleTypeToParam(f))
+ case f.Kind() == reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ elem := f.Index(i)
+ if util.IsSimpleType(elem) {
+ params.Add(fieldName, util.SimpleTypeToParam(elem))
+ } else {
+ return nil, errors.New("slices must contain only simple types")
}
- for _, val := range s {
- params.Add(fieldName, val)
- }
- default:
- return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
}
- case reflect.Map:
+ case f.Kind() == reflect.Map:
lowerCaseKeys := make(map[string][]string)
iter := f.MapRange()
for iter.Next() {
@@ -83,6 +69,7 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
params.Set(fieldName, s)
}
+
}
return params, nil
}
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index 43caf0fe9..645bf7a47 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -102,6 +102,9 @@ func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime) ([]libpod
case specgen.Slirp:
logrus.Debugf("Pod will use slirp4netns")
options = append(options, libpod.WithPodSlirp4netns(p.NetworkOptions))
+ case specgen.NoNetwork:
+ logrus.Debugf("Pod will not use networking")
+ options = append(options, libpod.WithPodNoNetwork())
default:
return nil, errors.Errorf("pods presently do not support network mode %s", p.NetNS.NSMode)
}
diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go
index de6751a17..e9902319c 100644
--- a/pkg/systemd/generate/common.go
+++ b/pkg/systemd/generate/common.go
@@ -60,13 +60,21 @@ func filterPodFlags(command []string) []string {
return processed
}
-// quoteArguments makes sure that all arguments with at least one whitespace
+// escapeSystemdArguments makes sure that all arguments with at least one whitespace
// are quoted to make sure those are interpreted as one argument instead of
-// multiple ones.
-func quoteArguments(command []string) []string {
+// multiple ones. Also make sure to escape all characters which have a special
+// meaning to systemd -> $,% and \
+// see: https://www.freedesktop.org/software/systemd/man/systemd.service.html#Command%20lines
+func escapeSystemdArguments(command []string) []string {
for i := range command {
+ command[i] = strings.ReplaceAll(command[i], "$", "$$")
+ command[i] = strings.ReplaceAll(command[i], "%", "%%")
if strings.ContainsAny(command[i], " \t") {
command[i] = strconv.Quote(command[i])
+ } else if strings.Contains(command[i], `\`) {
+ // strconv.Quote also escapes backslashes so
+ // we should replace only if strconv.Quote was not used
+ command[i] = strings.ReplaceAll(command[i], `\`, `\\`)
}
}
return command
diff --git a/pkg/systemd/generate/common_test.go b/pkg/systemd/generate/common_test.go
index d0ec5637c..a0691d1ad 100644
--- a/pkg/systemd/generate/common_test.go
+++ b/pkg/systemd/generate/common_test.go
@@ -29,7 +29,7 @@ func TestFilterPodFlags(t *testing.T) {
}
}
-func TestQuoteArguments(t *testing.T) {
+func TestEscapeSystemdArguments(t *testing.T) {
tests := []struct {
input []string
output []string
@@ -46,10 +46,46 @@ func TestQuoteArguments(t *testing.T) {
[]string{"foo", "bar=\"arg with\ttab\""},
[]string{"foo", "\"bar=\\\"arg with\\ttab\\\"\""},
},
+ {
+ []string{"$"},
+ []string{"$$"},
+ },
+ {
+ []string{"foo", "command with dollar sign $"},
+ []string{"foo", "\"command with dollar sign $$\""},
+ },
+ {
+ []string{"foo", "command with two dollar signs $$"},
+ []string{"foo", "\"command with two dollar signs $$$$\""},
+ },
+ {
+ []string{"%"},
+ []string{"%%"},
+ },
+ {
+ []string{"foo", "command with percent sign %"},
+ []string{"foo", "\"command with percent sign %%\""},
+ },
+ {
+ []string{"foo", "command with two percent signs %%"},
+ []string{"foo", "\"command with two percent signs %%%%\""},
+ },
+ {
+ []string{`\`},
+ []string{`\\`},
+ },
+ {
+ []string{"foo", `command with backslash \`},
+ []string{"foo", `"command with backslash \\"`},
+ },
+ {
+ []string{"foo", `command with two backslashs \\`},
+ []string{"foo", `"command with two backslashs \\\\"`},
+ },
}
for _, test := range tests {
- quoted := quoteArguments(test.input)
+ quoted := escapeSystemdArguments(test.input)
assert.Equal(t, test.output, quoted)
}
}
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index 5f52b0a77..abe159812 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -204,7 +204,7 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
startCommand := []string{info.Executable}
if index > 2 {
// include root flags
- info.RootFlags = strings.Join(quoteArguments(info.CreateCommand[1:index-1]), " ")
+ info.RootFlags = strings.Join(escapeSystemdArguments(info.CreateCommand[1:index-1]), " ")
startCommand = append(startCommand, info.CreateCommand[1:index-1]...)
}
startCommand = append(startCommand,
@@ -279,7 +279,7 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
}
}
startCommand = append(startCommand, remainingCmd...)
- startCommand = quoteArguments(startCommand)
+ startCommand = escapeSystemdArguments(startCommand)
info.ExecStartPre = "/bin/rm -f {{{{.PIDFile}}}} {{{{.ContainerIDFile}}}}"
info.ExecStart = strings.Join(startCommand, " ")
diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go
index 96d95644b..be14e4c28 100644
--- a/pkg/systemd/generate/containers_test.go
+++ b/pkg/systemd/generate/containers_test.go
@@ -352,6 +352,30 @@ Type=forking
[Install]
WantedBy=multi-user.target default.target
`
+
+ goodNewWithSpecialChars := `# jadda-jadda.service
+# autogenerated by Podman CI
+
+[Unit]
+Description=Podman jadda-jadda.service
+Documentation=man:podman-generate-systemd(1)
+Wants=network.target
+After=network-online.target
+
+[Service]
+Environment=PODMAN_SYSTEMD_UNIT=%n
+Restart=always
+TimeoutStopSec=70
+ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id
+ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d --replace --name test awesome-image:latest sh -c "kill $$$$ && echo %%\\"
+ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 10
+ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id
+PIDFile=%t/jadda-jadda.pid
+Type=forking
+
+[Install]
+WantedBy=multi-user.target default.target
+`
tests := []struct {
name string
info containerInfo
@@ -647,6 +671,22 @@ WantedBy=multi-user.target default.target
true,
false,
},
+ {"good with special chars",
+ containerInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "jadda-jadda",
+ ContainerNameOrID: "jadda-jadda",
+ RestartPolicy: "always",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 10,
+ PodmanVersion: "CI",
+ CreateCommand: []string{"I'll get stripped", "create", "--name", "test", "awesome-image:latest", "sh", "-c", "kill $$ && echo %\\"},
+ EnvVariable: EnvVariable,
+ },
+ goodNewWithSpecialChars,
+ true,
+ false,
+ },
}
for _, tt := range tests {
test := tt
diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go
index c7e3aa955..d6ede19af 100644
--- a/pkg/systemd/generate/pods.go
+++ b/pkg/systemd/generate/pods.go
@@ -269,7 +269,7 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
return "", errors.Errorf("pod does not appear to be created via `podman pod create`: %v", info.CreateCommand)
}
podRootArgs = info.CreateCommand[1 : podCreateIndex-1]
- info.RootFlags = strings.Join(quoteArguments(podRootArgs), " ")
+ info.RootFlags = strings.Join(escapeSystemdArguments(podRootArgs), " ")
podCreateArgs = filterPodFlags(info.CreateCommand[podCreateIndex+1:])
}
// We're hard-coding the first five arguments and append the
@@ -306,7 +306,7 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
}
startCommand = append(startCommand, podCreateArgs...)
- startCommand = quoteArguments(startCommand)
+ startCommand = escapeSystemdArguments(startCommand)
info.ExecStartPre1 = "/bin/rm -f {{{{.PIDFile}}}} {{{{.PodIDFile}}}}"
info.ExecStartPre2 = strings.Join(startCommand, " ")
diff --git a/test/apiv2/rest_api/test_rest_v2_0_0.py b/test/apiv2/rest_api/test_rest_v2_0_0.py
index c4faa1548..9ce0803fb 100644
--- a/test/apiv2/rest_api/test_rest_v2_0_0.py
+++ b/test/apiv2/rest_api/test_rest_v2_0_0.py
@@ -162,7 +162,7 @@ class TestApi(unittest.TestCase):
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)
+ self.assertEqual(r.text, "", r.text)
def test_attach_containers(self):
self.skipTest("FIXME: Test timeouts")
@@ -359,14 +359,14 @@ class TestApi(unittest.TestCase):
# Had issues with this test hanging when repositories not happy
def do_search1():
- payload = {'term': 'alpine'}
+ payload = {"term": "alpine"}
r = requests.get(url, params=payload, timeout=5)
self.assertEqual(r.status_code, 200, r.text)
objs = json.loads(r.text)
self.assertIn(type(objs), (list,))
def do_search2():
- payload = {'term': 'alpine', 'limit': 1}
+ payload = {"term": "alpine", "limit": 1}
r = requests.get(url, params=payload, timeout=5)
self.assertEqual(r.status_code, 200, r.text)
objs = json.loads(r.text)
@@ -374,7 +374,7 @@ class TestApi(unittest.TestCase):
self.assertEqual(len(objs), 1)
def do_search3():
- payload = {'term': 'alpine', 'filters': '{"is-official":["true"]}'}
+ payload = {"term": "alpine", "filters": '{"is-official":["true"]}'}
r = requests.get(url, params=payload, timeout=5)
self.assertEqual(r.status_code, 200, r.text)
objs = json.loads(r.text)
@@ -383,14 +383,14 @@ class TestApi(unittest.TestCase):
self.assertEqual(len(objs), 1)
def do_search4():
- headers = {'X-Registry-Auth': 'null'}
- payload = {'term': 'alpine'}
+ headers = {"X-Registry-Auth": "null"}
+ payload = {"term": "alpine"}
r = requests.get(url, params=payload, headers=headers, timeout=5)
self.assertEqual(r.status_code, 200, r.text)
def do_search5():
- headers = {'X-Registry-Auth': 'invalid value'}
- payload = {'term': 'alpine'}
+ headers = {"X-Registry-Auth": "invalid value"}
+ payload = {"term": "alpine"}
r = requests.get(url, params=payload, headers=headers, timeout=5)
self.assertEqual(r.status_code, 400, r.text)
@@ -620,15 +620,19 @@ class TestApi(unittest.TestCase):
self.assertIsNotNone(prune_payload["ImagesDeleted"][1]["Deleted"])
def test_status_compat(self):
- r = requests.post(PODMAN_URL + "/v1.40/containers/create?name=topcontainer",
- json={"Cmd": ["top"], "Image": "alpine:latest"})
+ r = requests.post(
+ PODMAN_URL + "/v1.40/containers/create?name=topcontainer",
+ json={"Cmd": ["top"], "Image": "alpine:latest"},
+ )
self.assertEqual(r.status_code, 201, r.text)
payload = json.loads(r.text)
container_id = payload["Id"]
self.assertIsNotNone(container_id)
- r = requests.get(PODMAN_URL + "/v1.40/containers/json",
- params={'all': 'true', 'filters': f'{{"id":["{container_id}"]}}'})
+ r = requests.get(
+ PODMAN_URL + "/v1.40/containers/json",
+ params={"all": "true", "filters": f'{{"id":["{container_id}"]}}'},
+ )
self.assertEqual(r.status_code, 200, r.text)
payload = json.loads(r.text)
self.assertEqual(payload[0]["Status"], "Created")
@@ -636,8 +640,10 @@ class TestApi(unittest.TestCase):
r = requests.post(PODMAN_URL + f"/v1.40/containers/{container_id}/start")
self.assertEqual(r.status_code, 204, r.text)
- r = requests.get(PODMAN_URL + "/v1.40/containers/json",
- params={'all': 'true', 'filters': f'{{"id":["{container_id}"]}}'})
+ r = requests.get(
+ PODMAN_URL + "/v1.40/containers/json",
+ params={"all": "true", "filters": f'{{"id":["{container_id}"]}}'},
+ )
self.assertEqual(r.status_code, 200, r.text)
payload = json.loads(r.text)
self.assertTrue(str(payload[0]["Status"]).startswith("Up"))
@@ -645,8 +651,10 @@ class TestApi(unittest.TestCase):
r = requests.post(PODMAN_URL + f"/v1.40/containers/{container_id}/pause")
self.assertEqual(r.status_code, 204, r.text)
- r = requests.get(PODMAN_URL + "/v1.40/containers/json",
- params={'all': 'true', 'filters': f'{{"id":["{container_id}"]}}'})
+ r = requests.get(
+ PODMAN_URL + "/v1.40/containers/json",
+ params={"all": "true", "filters": f'{{"id":["{container_id}"]}}'},
+ )
self.assertEqual(r.status_code, 200, r.text)
payload = json.loads(r.text)
self.assertTrue(str(payload[0]["Status"]).startswith("Up"))
@@ -657,8 +665,10 @@ class TestApi(unittest.TestCase):
r = requests.post(PODMAN_URL + f"/v1.40/containers/{container_id}/stop")
self.assertEqual(r.status_code, 204, r.text)
- r = requests.get(PODMAN_URL + "/v1.40/containers/json",
- params={'all': 'true', 'filters': f'{{"id":["{container_id}"]}}'})
+ r = requests.get(
+ PODMAN_URL + "/v1.40/containers/json",
+ params={"all": "true", "filters": f'{{"id":["{container_id}"]}}'},
+ )
self.assertEqual(r.status_code, 200, r.text)
payload = json.loads(r.text)
self.assertTrue(str(payload[0]["Status"]).startswith("Exited"))
@@ -666,6 +676,60 @@ class TestApi(unittest.TestCase):
r = requests.delete(PODMAN_URL + f"/v1.40/containers/{container_id}")
self.assertEqual(r.status_code, 204, r.text)
+ def test_pod_start_conflict(self):
+ """Verify issue #8865"""
+
+ pod_name = list()
+ pod_name.append("Pod_" + "".join(random.choice(string.ascii_letters) for i in range(10)))
+ pod_name.append("Pod_" + "".join(random.choice(string.ascii_letters) for i in range(10)))
+
+ r = requests.post(
+ _url("/pods/create"),
+ json={
+ "name": pod_name[0],
+ "no_infra": False,
+ "portmappings": [{"host_ip": "127.0.0.1", "host_port": 8889, "container_port": 89}],
+ },
+ )
+ self.assertEqual(r.status_code, 201, r.text)
+ r = requests.post(
+ _url("/containers/create"),
+ json={
+ "pod": pod_name[0],
+ "image": "docker.io/alpine:latest",
+ "command": ["top"],
+ },
+ )
+ self.assertEqual(r.status_code, 201, r.text)
+
+ r = requests.post(
+ _url("/pods/create"),
+ json={
+ "name": pod_name[1],
+ "no_infra": False,
+ "portmappings": [{"host_ip": "127.0.0.1", "host_port": 8889, "container_port": 89}],
+ },
+ )
+ self.assertEqual(r.status_code, 201, r.text)
+ r = requests.post(
+ _url("/containers/create"),
+ json={
+ "pod": pod_name[1],
+ "image": "docker.io/alpine:latest",
+ "command": ["top"],
+ },
+ )
+ self.assertEqual(r.status_code, 201, r.text)
+
+ r = requests.post(_url(f"/pods/{pod_name[0]}/start"))
+ self.assertEqual(r.status_code, 200, r.text)
+
+ r = requests.post(_url(f"/pods/{pod_name[1]}/start"))
+ self.assertEqual(r.status_code, 409, r.text)
+
+ start = json.loads(r.text)
+ self.assertGreater(len(start["Errs"]), 0, r.text)
+
if __name__ == "__main__":
unittest.main()
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index 781bbb6d2..61c0cb4fe 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -1,6 +1,7 @@
package integration
import (
+ "bytes"
"fmt"
"io/ioutil"
"math/rand"
@@ -517,27 +518,15 @@ func (s *PodmanSessionIntegration) InspectPodArrToJSON() []define.InspectPodData
// CreatePod creates a pod with no infra container
// it optionally takes a pod name
-func (p *PodmanTestIntegration) CreatePod(name string) (*PodmanSessionIntegration, int, string) {
- var podmanArgs = []string{"pod", "create", "--infra=false", "--share", ""}
- if name != "" {
- podmanArgs = append(podmanArgs, "--name", name)
+func (p *PodmanTestIntegration) CreatePod(options map[string][]string) (*PodmanSessionIntegration, int, string) {
+ var args = []string{"pod", "create", "--infra=false", "--share", ""}
+ for k, values := range options {
+ for _, v := range values {
+ args = append(args, k+"="+v)
+ }
}
- session := p.Podman(podmanArgs)
- session.WaitWithDefaultTimeout()
- return session, session.ExitCode(), session.OutputToString()
-}
-// CreatePod creates a pod with no infra container and some labels.
-// it optionally takes a pod name
-func (p *PodmanTestIntegration) CreatePodWithLabels(name string, labels map[string]string) (*PodmanSessionIntegration, int, string) {
- var podmanArgs = []string{"pod", "create", "--infra=false", "--share", ""}
- if name != "" {
- podmanArgs = append(podmanArgs, "--name", name)
- }
- for labelKey, labelValue := range labels {
- podmanArgs = append(podmanArgs, "--label", fmt.Sprintf("%s=%s", labelKey, labelValue))
- }
- session := p.Podman(podmanArgs)
+ session := p.Podman(args)
session.WaitWithDefaultTimeout()
return session, session.ExitCode(), session.OutputToString()
}
@@ -794,3 +783,12 @@ func (p *PodmanTestIntegration) removeCNINetwork(name string) {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeNumerically("<=", 1))
}
+
+func (p *PodmanSessionIntegration) jq(jqCommand string) (string, error) {
+ var out bytes.Buffer
+ cmd := exec.Command("jq", jqCommand)
+ cmd.Stdin = strings.NewReader(p.OutputToString())
+ cmd.Stdout = &out
+ err := cmd.Run()
+ return strings.TrimRight(out.String(), "\n"), err
+}
diff --git a/test/e2e/exists_test.go b/test/e2e/exists_test.go
index 480bfe5fc..306e8c250 100644
--- a/test/e2e/exists_test.go
+++ b/test/e2e/exists_test.go
@@ -83,7 +83,7 @@ var _ = Describe("Podman image|container exists", func() {
})
It("podman pod exists in local storage by name", func() {
- setup, _, _ := podmanTest.CreatePod("foobar")
+ setup, _, _ := podmanTest.CreatePod(map[string][]string{"--name": {"foobar"}})
setup.WaitWithDefaultTimeout()
Expect(setup).Should(Exit(0))
@@ -92,7 +92,7 @@ var _ = Describe("Podman image|container exists", func() {
Expect(session).Should(Exit(0))
})
It("podman pod exists in local storage by container ID", func() {
- setup, _, podID := podmanTest.CreatePod("")
+ setup, _, podID := podmanTest.CreatePod(nil)
setup.WaitWithDefaultTimeout()
Expect(setup).Should(Exit(0))
@@ -101,7 +101,7 @@ var _ = Describe("Podman image|container exists", func() {
Expect(session).Should(Exit(0))
})
It("podman pod exists in local storage by short container ID", func() {
- setup, _, podID := podmanTest.CreatePod("")
+ setup, _, podID := podmanTest.CreatePod(nil)
setup.WaitWithDefaultTimeout()
Expect(setup).Should(Exit(0))
diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go
index 83b9cfb14..bcfab0f68 100644
--- a/test/e2e/generate_kube_test.go
+++ b/test/e2e/generate_kube_test.go
@@ -1,6 +1,7 @@
package integration
import (
+ "io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -131,7 +132,7 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman generate kube on pod", func() {
- _, rc, _ := podmanTest.CreatePod("toppod")
+ _, rc, _ := podmanTest.CreatePod(map[string][]string{"--name": {"toppod"}})
Expect(rc).To(Equal(0))
session := podmanTest.RunTopContainerInPod("topcontainer", "toppod")
@@ -221,7 +222,7 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman generate service kube on pod", func() {
- _, rc, _ := podmanTest.CreatePod("toppod")
+ _, rc, _ := podmanTest.CreatePod(map[string][]string{"--name": {"toppod"}})
Expect(rc).To(Equal(0))
session := podmanTest.RunTopContainerInPod("topcontainer", "toppod")
@@ -373,7 +374,7 @@ var _ = Describe("Podman generate kube", func() {
It("podman generate and reimport kube on pod", func() {
podName := "toppod"
- _, rc, _ := podmanTest.CreatePod(podName)
+ _, rc, _ := podmanTest.CreatePod(map[string][]string{"--name": {podName}})
Expect(rc).To(Equal(0))
session := podmanTest.Podman([]string{"create", "--pod", podName, "--name", "test1", ALPINE, "top"})
@@ -412,7 +413,7 @@ var _ = Describe("Podman generate kube", func() {
It("podman generate with user and reimport kube on pod", func() {
podName := "toppod"
- _, rc, _ := podmanTest.CreatePod(podName)
+ _, rc, _ := podmanTest.CreatePod(map[string][]string{"--name": {podName}})
Expect(rc).To(Equal(0))
session := podmanTest.Podman([]string{"create", "--pod", podName, "--name", "test1", "--user", "100:200", ALPINE, "top"})
@@ -639,4 +640,63 @@ var _ = Describe("Podman generate kube", func() {
Expect(pod.Spec.DNSConfig.Options[0].Name).To(Equal("color"))
Expect(*pod.Spec.DNSConfig.Options[0].Value).To(Equal("blue"))
})
+
+ It("podman generate kube - set entrypoint as command", func() {
+ session := podmanTest.Podman([]string{"create", "--pod", "new:testpod", "--entrypoint", "/bin/sleep", ALPINE, "10s"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ kube := podmanTest.Podman([]string{"generate", "kube", "testpod"})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube.ExitCode()).To(Equal(0))
+
+ // Now make sure that the container's command is set to the
+ // entrypoint and it's arguments to "10s".
+ pod := new(v1.Pod)
+ err := yaml.Unmarshal(kube.Out.Contents(), pod)
+ Expect(err).To(BeNil())
+
+ containers := pod.Spec.Containers
+ Expect(len(containers)).To(Equal(1))
+
+ Expect(containers[0].Command).To(Equal([]string{"/bin/sleep"}))
+ Expect(containers[0].Args).To(Equal([]string{"10s"}))
+ })
+
+ It("podman generate kube - use entrypoint from image", func() {
+ // Build an image with an entrypoint.
+ containerfile := `FROM quay.io/libpod/alpine:latest
+ENTRYPOINT /bin/sleep`
+
+ targetPath, err := CreateTempDirInTempDir()
+ Expect(err).To(BeNil())
+ containerfilePath := filepath.Join(targetPath, "Containerfile")
+ err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644)
+ Expect(err).To(BeNil())
+
+ image := "generatekube:test"
+ session := podmanTest.Podman([]string{"build", "-f", containerfilePath, "-t", image})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"create", "--pod", "new:testpod", image, "10s"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ kube := podmanTest.Podman([]string{"generate", "kube", "testpod"})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube.ExitCode()).To(Equal(0))
+
+ // Now make sure that the container's command is set to the
+ // entrypoint and it's arguments to "10s".
+ pod := new(v1.Pod)
+ err = yaml.Unmarshal(kube.Out.Contents(), pod)
+ Expect(err).To(BeNil())
+
+ containers := pod.Spec.Containers
+ Expect(len(containers)).To(Equal(1))
+
+ Expect(containers[0].Command).To(Equal([]string{"/bin/sh", "-c", "/bin/sleep"}))
+ Expect(containers[0].Args).To(Equal([]string{"10s"}))
+ })
})
diff --git a/test/e2e/network_connect_disconnect_test.go b/test/e2e/network_connect_disconnect_test.go
index dd94bd7ca..cc23b10c1 100644
--- a/test/e2e/network_connect_disconnect_test.go
+++ b/test/e2e/network_connect_disconnect_test.go
@@ -74,6 +74,11 @@ var _ = Describe("Podman network connect and disconnect", func() {
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).To(BeZero())
+ inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(BeZero())
+ Expect(inspect.OutputToString()).To(Equal("0"))
+
exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"})
exec.WaitWithDefaultTimeout()
Expect(exec.ExitCode()).ToNot(BeZero())
@@ -146,6 +151,11 @@ var _ = Describe("Podman network connect and disconnect", func() {
connect.WaitWithDefaultTimeout()
Expect(connect.ExitCode()).To(BeZero())
+ inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(BeZero())
+ Expect(inspect.OutputToString()).To(Equal("2"))
+
exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth1"})
exec.WaitWithDefaultTimeout()
Expect(exec.ExitCode()).To(BeZero())
@@ -167,6 +177,11 @@ var _ = Describe("Podman network connect and disconnect", func() {
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).To(BeZero())
+ inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(BeZero())
+ Expect(inspect.OutputToString()).To(Equal("2"))
+
start := podmanTest.Podman([]string{"start", "test"})
start.WaitWithDefaultTimeout()
Expect(start.ExitCode()).To(BeZero())
@@ -202,6 +217,11 @@ var _ = Describe("Podman network connect and disconnect", func() {
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).To(BeZero())
+ inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(BeZero())
+ Expect(inspect.OutputToString()).To(Equal("1"))
+
start := podmanTest.Podman([]string{"start", "test"})
start.WaitWithDefaultTimeout()
Expect(start.ExitCode()).To(BeZero())
diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go
index 2f5290c76..c6010ba43 100644
--- a/test/e2e/network_test.go
+++ b/test/e2e/network_test.go
@@ -457,6 +457,46 @@ var _ = Describe("Podman network", func() {
Expect(nc.ExitCode()).To(Equal(0))
})
+ It("podman network create/remove macvlan as driver (-d) no device name", func() {
+ net := "macvlan" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", "-d", "macvlan", net})
+ nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(net)
+ Expect(nc.ExitCode()).To(Equal(0))
+
+ inspect := podmanTest.Podman([]string{"network", "inspect", net})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(BeZero())
+
+ out, err := inspect.jq(".[0].plugins[0].master")
+ Expect(err).To(BeNil())
+ Expect(out).To(Equal("\"\""))
+
+ nc = podmanTest.Podman([]string{"network", "rm", net})
+ nc.WaitWithDefaultTimeout()
+ Expect(nc.ExitCode()).To(Equal(0))
+ })
+
+ It("podman network create/remove macvlan as driver (-d) with device name", func() {
+ net := "macvlan" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", "-d", "macvlan", "-o", "parent=lo", net})
+ nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(net)
+ Expect(nc.ExitCode()).To(Equal(0))
+
+ inspect := podmanTest.Podman([]string{"network", "inspect", net})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(BeZero())
+
+ out, err := inspect.jq(".[0].plugins[0].master")
+ Expect(err).To(BeNil())
+ Expect(out).To(Equal("\"lo\""))
+
+ nc = podmanTest.Podman([]string{"network", "rm", net})
+ nc.WaitWithDefaultTimeout()
+ Expect(nc.ExitCode()).To(Equal(0))
+ })
+
It("podman network exists", func() {
net := "net" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", net})
@@ -472,4 +512,32 @@ var _ = Describe("Podman network", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(1))
})
+
+ It("podman network create macvlan with network info and options", func() {
+ net := "macvlan" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", "-d", "macvlan", "-o", "parent=lo", "-o", "mtu=1500", "--gateway", "192.168.1.254", "--subnet", "192.168.1.0/24", net})
+ nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(net)
+ Expect(nc.ExitCode()).To(Equal(0))
+
+ inspect := podmanTest.Podman([]string{"network", "inspect", net})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(BeZero())
+
+ mtu, err := inspect.jq(".[0].plugins[0].mtu")
+ Expect(err).To(BeNil())
+ Expect(mtu).To(Equal("1500"))
+
+ gw, err := inspect.jq(".[0].plugins[0].ipam.ranges[0][0].gateway")
+ Expect(err).To(BeNil())
+ Expect(gw).To(Equal("\"192.168.1.254\""))
+
+ subnet, err := inspect.jq(".[0].plugins[0].ipam.ranges[0][0].subnet")
+ Expect(err).To(BeNil())
+ Expect(subnet).To(Equal("\"192.168.1.0/24\""))
+
+ nc = podmanTest.Podman([]string{"network", "rm", net})
+ nc.WaitWithDefaultTimeout()
+ Expect(nc.ExitCode()).To(Equal(0))
+ })
})
diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go
index 575f9df68..e57712f62 100644
--- a/test/e2e/pod_create_test.go
+++ b/test/e2e/pod_create_test.go
@@ -38,7 +38,7 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod", func() {
- _, ec, podID := podmanTest.CreatePod("")
+ _, ec, podID := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
check := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc"})
@@ -50,7 +50,7 @@ var _ = Describe("Podman pod create", func() {
It("podman create pod with name", func() {
name := "test"
- _, ec, _ := podmanTest.CreatePod(name)
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {name}})
Expect(ec).To(Equal(0))
check := podmanTest.Podman([]string{"pod", "ps", "--no-trunc"})
@@ -61,10 +61,10 @@ var _ = Describe("Podman pod create", func() {
It("podman create pod with doubled name", func() {
name := "test"
- _, ec, _ := podmanTest.CreatePod(name)
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {name}})
Expect(ec).To(Equal(0))
- _, ec2, _ := podmanTest.CreatePod(name)
+ _, ec2, _ := podmanTest.CreatePod(map[string][]string{"--name": {name}})
Expect(ec2).To(Not(Equal(0)))
check := podmanTest.Podman([]string{"pod", "ps", "-q"})
@@ -78,7 +78,7 @@ var _ = Describe("Podman pod create", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec, _ := podmanTest.CreatePod(name)
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {name}})
Expect(ec).To(Not(Equal(0)))
check := podmanTest.Podman([]string{"pod", "ps", "-q"})
@@ -478,12 +478,7 @@ entrypoint ["/fromimage"]
})
It("podman create with unsupported network options", func() {
- podCreate := podmanTest.Podman([]string{"pod", "create", "--network", "none"})
- podCreate.WaitWithDefaultTimeout()
- Expect(podCreate.ExitCode()).To(Equal(125))
- Expect(podCreate.ErrorToString()).To(ContainSubstring("pods presently do not support network mode none"))
-
- podCreate = podmanTest.Podman([]string{"pod", "create", "--network", "container:doesnotmatter"})
+ podCreate := podmanTest.Podman([]string{"pod", "create", "--network", "container:doesnotmatter"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate.ExitCode()).To(Equal(125))
Expect(podCreate.ErrorToString()).To(ContainSubstring("pods presently do not support network mode container"))
@@ -493,4 +488,17 @@ entrypoint ["/fromimage"]
Expect(podCreate.ExitCode()).To(Equal(125))
Expect(podCreate.ErrorToString()).To(ContainSubstring("pods presently do not support network mode path"))
})
+
+ It("podman pod create with --net=none", func() {
+ podName := "testPod"
+ podCreate := podmanTest.Podman([]string{"pod", "create", "--network", "none", "--name", podName})
+ podCreate.WaitWithDefaultTimeout()
+ Expect(podCreate.ExitCode()).To(Equal(0))
+
+ session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "ip", "-o", "-4", "addr"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring("inet 127.0.0.1/8 scope host lo"))
+ Expect(len(session.OutputToStringArray())).To(Equal(1))
+ })
})
diff --git a/test/e2e/pod_inspect_test.go b/test/e2e/pod_inspect_test.go
index fd9589afe..d9c4a393a 100644
--- a/test/e2e/pod_inspect_test.go
+++ b/test/e2e/pod_inspect_test.go
@@ -41,7 +41,7 @@ var _ = Describe("Podman pod inspect", func() {
})
It("podman inspect a pod", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
diff --git a/test/e2e/pod_kill_test.go b/test/e2e/pod_kill_test.go
index 710147893..06d244f99 100644
--- a/test/e2e/pod_kill_test.go
+++ b/test/e2e/pod_kill_test.go
@@ -40,7 +40,7 @@ var _ = Describe("Podman pod kill", func() {
})
It("podman pod kill a pod by id", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -58,7 +58,7 @@ var _ = Describe("Podman pod kill", func() {
})
It("podman pod kill a pod by id with TERM", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -72,7 +72,7 @@ var _ = Describe("Podman pod kill", func() {
})
It("podman pod kill a pod by name", func() {
- _, ec, podid := podmanTest.CreatePod("test1")
+ _, ec, podid := podmanTest.CreatePod(map[string][]string{"--name": {"test1"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -86,7 +86,7 @@ var _ = Describe("Podman pod kill", func() {
})
It("podman pod kill a pod by id with a bogus signal", func() {
- _, ec, podid := podmanTest.CreatePod("test1")
+ _, ec, podid := podmanTest.CreatePod(map[string][]string{"--name": {"test1"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -100,14 +100,14 @@ var _ = Describe("Podman pod kill", func() {
})
It("podman pod kill latest pod", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec, podid2 := podmanTest.CreatePod("")
+ _, ec, podid2 := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session = podmanTest.RunTopContainerInPod("", podid2)
@@ -128,7 +128,7 @@ var _ = Describe("Podman pod kill", func() {
It("podman pod kill all", func() {
SkipIfRootlessCgroupsV1("Not supported for rootless + CGroupsV1")
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -139,7 +139,7 @@ var _ = Describe("Podman pod kill", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec, podid2 := podmanTest.CreatePod("")
+ _, ec, podid2 := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session = podmanTest.RunTopContainerInPod("", podid2)
diff --git a/test/e2e/pod_pause_test.go b/test/e2e/pod_pause_test.go
index 3dabf7b4a..0c1b39f38 100644
--- a/test/e2e/pod_pause_test.go
+++ b/test/e2e/pod_pause_test.go
@@ -48,7 +48,7 @@ var _ = Describe("Podman pod pause", func() {
})
It("podman pod pause a created pod by id", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
result := podmanTest.Podman([]string{"pod", "pause", podid})
@@ -57,7 +57,7 @@ var _ = Describe("Podman pod pause", func() {
})
It("podman pod pause a running pod by id", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -78,7 +78,7 @@ var _ = Describe("Podman pod pause", func() {
})
It("podman unpause a running pod by id", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -93,7 +93,7 @@ var _ = Describe("Podman pod pause", func() {
})
It("podman pod pause a running pod by name", func() {
- _, ec, _ := podmanTest.CreatePod("test1")
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"test1"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", "test1")
diff --git a/test/e2e/pod_prune_test.go b/test/e2e/pod_prune_test.go
index 0346cfdc8..d1ebf7249 100644
--- a/test/e2e/pod_prune_test.go
+++ b/test/e2e/pod_prune_test.go
@@ -33,7 +33,7 @@ var _ = Describe("Podman pod prune", func() {
})
It("podman pod prune empty pod", func() {
- _, ec, _ := podmanTest.CreatePod("")
+ _, ec, _ := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
result := podmanTest.Podman([]string{"pod", "prune", "--force"})
@@ -42,7 +42,7 @@ var _ = Describe("Podman pod prune", func() {
})
It("podman pod prune doesn't remove a pod with a running container", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
ec2 := podmanTest.RunTopContainerInPod("", podid)
@@ -59,7 +59,7 @@ var _ = Describe("Podman pod prune", func() {
})
It("podman pod prune removes a pod with a stopped container", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
_, ec2, _ := podmanTest.RunLsContainerInPod("", podid)
diff --git a/test/e2e/pod_ps_test.go b/test/e2e/pod_ps_test.go
index 9f63c1d5d..c20cb44e7 100644
--- a/test/e2e/pod_ps_test.go
+++ b/test/e2e/pod_ps_test.go
@@ -43,7 +43,7 @@ var _ = Describe("Podman ps", func() {
})
It("podman pod ps default", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -57,7 +57,7 @@ var _ = Describe("Podman ps", func() {
})
It("podman pod ps quiet flag", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
_, ec, _ = podmanTest.RunLsContainerInPod("", podid)
@@ -71,7 +71,7 @@ var _ = Describe("Podman ps", func() {
})
It("podman pod ps no-trunc", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
_, ec2, _ := podmanTest.RunLsContainerInPod("", podid)
@@ -86,10 +86,10 @@ var _ = Describe("Podman ps", func() {
It("podman pod ps latest", func() {
SkipIfRemote("--latest flag n/a")
- _, ec, podid1 := podmanTest.CreatePod("")
+ _, ec, podid1 := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
- _, ec2, podid2 := podmanTest.CreatePod("")
+ _, ec2, podid2 := podmanTest.CreatePod(nil)
Expect(ec2).To(Equal(0))
result := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--latest"})
@@ -100,7 +100,7 @@ var _ = Describe("Podman ps", func() {
})
It("podman pod ps id filter flag", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
result := podmanTest.Podman([]string{"pod", "ps", "--filter", fmt.Sprintf("id=%s", podid)})
@@ -109,9 +109,9 @@ var _ = Describe("Podman ps", func() {
})
It("podman pod ps filter name regexp", func() {
- _, ec, podid := podmanTest.CreatePod("mypod")
+ _, ec, podid := podmanTest.CreatePod(map[string][]string{"--name": {"mypod"}})
Expect(ec).To(Equal(0))
- _, ec2, _ := podmanTest.CreatePod("mypod1")
+ _, ec2, _ := podmanTest.CreatePod(map[string][]string{"--name": {"mypod1"}})
Expect(ec2).To(Equal(0))
result := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "name=mypod"})
@@ -138,13 +138,13 @@ var _ = Describe("Podman ps", func() {
})
It("podman pod ps --sort by name", func() {
- _, ec, _ := podmanTest.CreatePod("")
+ _, ec, _ := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
- _, ec2, _ := podmanTest.CreatePod("")
+ _, ec2, _ := podmanTest.CreatePod(nil)
Expect(ec2).To(Equal(0))
- _, ec3, _ := podmanTest.CreatePod("")
+ _, ec3, _ := podmanTest.CreatePod(nil)
Expect(ec3).To(Equal(0))
session := podmanTest.Podman([]string{"pod", "ps", "--sort=name", "--format", "{{.Name}}"})
@@ -159,7 +159,7 @@ var _ = Describe("Podman ps", func() {
It("podman pod ps --ctr-names", func() {
SkipIfRootlessCgroupsV1("Not supported for rootless + CGroupsV1")
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("test1", podid)
@@ -177,14 +177,14 @@ var _ = Describe("Podman ps", func() {
})
It("podman pod ps filter ctr attributes", func() {
- _, ec, podid1 := podmanTest.CreatePod("")
+ _, ec, podid1 := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("test1", podid1)
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec2, podid2 := podmanTest.CreatePod("")
+ _, ec2, podid2 := podmanTest.CreatePod(nil)
Expect(ec2).To(Equal(0))
_, ec3, cid := podmanTest.RunLsContainerInPod("test2", podid2)
@@ -214,7 +214,7 @@ var _ = Describe("Podman ps", func() {
Expect(session.OutputToString()).To(ContainSubstring(podid2))
Expect(session.OutputToString()).To(Not(ContainSubstring(podid1)))
- _, ec3, podid3 := podmanTest.CreatePod("")
+ _, ec3, podid3 := podmanTest.CreatePod(nil)
Expect(ec3).To(Equal(0))
session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "ctr-number=1"})
@@ -259,23 +259,20 @@ var _ = Describe("Podman ps", func() {
})
It("podman pod ps filter labels", func() {
- _, ec, podid1 := podmanTest.CreatePod("")
- Expect(ec).To(Equal(0))
+ s, _, podid1 := podmanTest.CreatePod(nil)
+ Expect(s).To(Exit(0))
- _, ec, podid2 := podmanTest.CreatePodWithLabels("", map[string]string{
- "app": "myapp",
- "io.podman.test.key": "irrelevant-value",
+ s, _, podid2 := podmanTest.CreatePod(map[string][]string{
+ "--label": {"app=myapp", "io.podman.test.key=irrelevant-value"},
})
- Expect(ec).To(Equal(0))
+ Expect(s).To(Exit(0))
- _, ec, podid3 := podmanTest.CreatePodWithLabels("", map[string]string{
- "app": "test",
- })
- Expect(ec).To(Equal(0))
+ s, _, podid3 := podmanTest.CreatePod(map[string][]string{"--label": {"app=test"}})
+ Expect(s).To(Exit(0))
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).To(Exit(0))
Expect(session.OutputToString()).To(Not(ContainSubstring(podid1)))
Expect(session.OutputToString()).To(ContainSubstring(podid2))
Expect(session.OutputToString()).To(Not(ContainSubstring(podid3)))
@@ -359,13 +356,13 @@ var _ = Describe("Podman ps", func() {
})
It("podman pod ps format with labels", func() {
- _, ec, _ := podmanTest.CreatePod("")
+ _, ec, _ := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
- _, ec1, _ := podmanTest.CreatePodWithLabels("", map[string]string{
- "io.podman.test.label": "value1",
- "io.podman.test.key": "irrelevant-value",
- })
+ _, ec1, _ := podmanTest.CreatePod(map[string][]string{"--label": {
+ "io.podman.test.label=value1",
+ "io.podman.test.key=irrelevant-value",
+ }})
Expect(ec1).To(Equal(0))
session := podmanTest.Podman([]string{"pod", "ps", "--format", "{{.Labels}}"})
diff --git a/test/e2e/pod_restart_test.go b/test/e2e/pod_restart_test.go
index b358c2c7a..c6b1a0d46 100644
--- a/test/e2e/pod_restart_test.go
+++ b/test/e2e/pod_restart_test.go
@@ -39,7 +39,7 @@ var _ = Describe("Podman pod restart", func() {
})
It("podman pod restart single empty pod", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"pod", "restart", podid})
@@ -48,7 +48,7 @@ var _ = Describe("Podman pod restart", func() {
})
It("podman pod restart single pod by name", func() {
- _, ec, _ := podmanTest.CreatePod("foobar99")
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("test1", "foobar99")
@@ -68,14 +68,14 @@ var _ = Describe("Podman pod restart", func() {
})
It("podman pod restart multiple pods", func() {
- _, ec, _ := podmanTest.CreatePod("foobar99")
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("test1", "foobar99")
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec, _ = podmanTest.CreatePod("foobar100")
+ _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}})
Expect(ec).To(Equal(0))
session = podmanTest.RunTopContainerInPod("test2", "foobar100")
@@ -106,14 +106,14 @@ var _ = Describe("Podman pod restart", func() {
})
It("podman pod restart all pods", func() {
- _, ec, _ := podmanTest.CreatePod("foobar99")
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("test1", "foobar99")
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec, _ = podmanTest.CreatePod("foobar100")
+ _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}})
Expect(ec).To(Equal(0))
session = podmanTest.RunTopContainerInPod("test2", "foobar100")
@@ -134,14 +134,14 @@ var _ = Describe("Podman pod restart", func() {
})
It("podman pod restart latest pod", func() {
- _, ec, _ := podmanTest.CreatePod("foobar99")
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("test1", "foobar99")
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec, _ = podmanTest.CreatePod("foobar100")
+ _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}})
Expect(ec).To(Equal(0))
session = podmanTest.RunTopContainerInPod("test2", "foobar100")
@@ -166,7 +166,7 @@ var _ = Describe("Podman pod restart", func() {
})
It("podman pod restart multiple pods with bogus", func() {
- _, ec, podid1 := podmanTest.CreatePod("foobar99")
+ _, ec, podid1 := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", "foobar99")
diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go
index 24e945d5a..40a903cd0 100644
--- a/test/e2e/pod_rm_test.go
+++ b/test/e2e/pod_rm_test.go
@@ -37,7 +37,7 @@ var _ = Describe("Podman pod rm", func() {
})
It("podman pod rm empty pod", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
result := podmanTest.Podman([]string{"pod", "rm", podid})
@@ -61,10 +61,10 @@ var _ = Describe("Podman pod rm", func() {
})
It("podman pod rm latest pod", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
- _, ec2, podid2 := podmanTest.CreatePod("pod2")
+ _, ec2, podid2 := podmanTest.CreatePod(map[string][]string{"--name": {"pod2"}})
Expect(ec2).To(Equal(0))
latest := "--latest"
@@ -83,7 +83,7 @@ var _ = Describe("Podman pod rm", func() {
})
It("podman pod rm removes a pod with a container", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
_, ec2, _ := podmanTest.RunLsContainerInPod("", podid)
@@ -99,7 +99,7 @@ var _ = Describe("Podman pod rm", func() {
})
It("podman pod rm -f does remove a running container", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -117,10 +117,10 @@ var _ = Describe("Podman pod rm", func() {
It("podman pod rm -a doesn't remove a running container", func() {
fmt.Printf("To start, there are %d pods\n", podmanTest.NumberOfPods())
- _, ec, podid1 := podmanTest.CreatePod("")
+ _, ec, podid1 := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
- _, ec, _ = podmanTest.CreatePod("")
+ _, ec, _ = podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
fmt.Printf("Started %d pods\n", podmanTest.NumberOfPods())
@@ -154,13 +154,13 @@ var _ = Describe("Podman pod rm", func() {
})
It("podman pod rm -fa removes everything", func() {
- _, ec, podid1 := podmanTest.CreatePod("")
+ _, ec, podid1 := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
- _, ec, podid2 := podmanTest.CreatePod("")
+ _, ec, podid2 := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
- _, ec, _ = podmanTest.CreatePod("")
+ _, ec, _ = podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid1)
@@ -199,7 +199,7 @@ var _ = Describe("Podman pod rm", func() {
})
It("podman rm bogus pod and a running pod", func() {
- _, ec, podid1 := podmanTest.CreatePod("")
+ _, ec, podid1 := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("test1", podid1)
@@ -217,7 +217,7 @@ var _ = Describe("Podman pod rm", func() {
It("podman rm --ignore bogus pod and a running pod", func() {
- _, ec, podid1 := podmanTest.CreatePod("")
+ _, ec, podid1 := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("test1", podid1)
diff --git a/test/e2e/pod_start_test.go b/test/e2e/pod_start_test.go
index 63a915548..e14796ab3 100644
--- a/test/e2e/pod_start_test.go
+++ b/test/e2e/pod_start_test.go
@@ -10,6 +10,7 @@ import (
. "github.com/containers/podman/v2/test/utils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
)
var _ = Describe("Podman pod start", func() {
@@ -43,7 +44,7 @@ var _ = Describe("Podman pod start", func() {
})
It("podman pod start single empty pod", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"pod", "start", podid})
@@ -52,7 +53,7 @@ var _ = Describe("Podman pod start", func() {
})
It("podman pod start single pod by name", func() {
- _, ec, _ := podmanTest.CreatePod("foobar99")
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "ls"})
@@ -65,14 +66,14 @@ var _ = Describe("Podman pod start", func() {
})
It("podman pod start multiple pods", func() {
- _, ec, podid1 := podmanTest.CreatePod("foobar99")
+ _, ec, podid1 := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec2, podid2 := podmanTest.CreatePod("foobar100")
+ _, ec2, podid2 := podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}})
Expect(ec2).To(Equal(0))
session = podmanTest.Podman([]string{"create", "--pod", "foobar100", ALPINE, "top"})
@@ -85,15 +86,45 @@ var _ = Describe("Podman pod start", func() {
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2))
})
+ It("multiple pods in conflict", func() {
+ podName := []string{"Pod_" + RandomString(10), "Pod_" + RandomString(10)}
+
+ pod, _, podid1 := podmanTest.CreatePod(map[string][]string{
+ "--infra": {"true"},
+ "--name": {podName[0]},
+ "--publish": {"127.0.0.1:8080:80"},
+ })
+ Expect(pod).To(Exit(0))
+
+ session := podmanTest.Podman([]string{"create", "--pod", podName[0], ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).To(Exit(0))
+
+ pod, _, podid2 := podmanTest.CreatePod(map[string][]string{
+ "--infra": {"true"},
+ "--name": {podName[1]},
+ "--publish": {"127.0.0.1:8080:80"},
+ })
+ Expect(pod).To(Exit(0))
+
+ session = podmanTest.Podman([]string{"create", "--pod", podName[1], ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).To(Exit(0))
+
+ session = podmanTest.Podman([]string{"pod", "start", podid1, podid2})
+ session.WaitWithDefaultTimeout()
+ Expect(session).To(Exit(125))
+ })
+
It("podman pod start all pods", func() {
- _, ec, _ := podmanTest.CreatePod("foobar99")
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec, _ = podmanTest.CreatePod("foobar100")
+ _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}})
Expect(ec).To(Equal(0))
session = podmanTest.Podman([]string{"create", "--pod", "foobar100", ALPINE, "top"})
@@ -107,14 +138,14 @@ var _ = Describe("Podman pod start", func() {
})
It("podman pod start latest pod", func() {
- _, ec, _ := podmanTest.CreatePod("foobar99")
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec, _ = podmanTest.CreatePod("foobar100")
+ _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}})
Expect(ec).To(Equal(0))
session = podmanTest.Podman([]string{"create", "--pod", "foobar100", ALPINE, "top"})
@@ -132,7 +163,7 @@ var _ = Describe("Podman pod start", func() {
})
It("podman pod start multiple pods with bogus", func() {
- _, ec, podid := podmanTest.CreatePod("foobar99")
+ _, ec, podid := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"})
diff --git a/test/e2e/pod_stats_test.go b/test/e2e/pod_stats_test.go
index 1709b4f81..073d4752b 100644
--- a/test/e2e/pod_stats_test.go
+++ b/test/e2e/pod_stats_test.go
@@ -50,7 +50,7 @@ var _ = Describe("Podman pod stats", func() {
})
It("podman stats on a specific running pod", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -67,7 +67,7 @@ var _ = Describe("Podman pod stats", func() {
})
It("podman stats on a specific running pod with shortID", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -84,7 +84,7 @@ var _ = Describe("Podman pod stats", func() {
})
It("podman stats on a specific running pod with name", func() {
- _, ec, podid := podmanTest.CreatePod("test")
+ _, ec, podid := podmanTest.CreatePod(map[string][]string{"--name": {"test"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -101,7 +101,7 @@ var _ = Describe("Podman pod stats", func() {
})
It("podman stats on running pods", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -118,7 +118,7 @@ var _ = Describe("Podman pod stats", func() {
})
It("podman stats on all pods", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -135,7 +135,7 @@ var _ = Describe("Podman pod stats", func() {
})
It("podman stats with json output", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -152,7 +152,7 @@ var _ = Describe("Podman pod stats", func() {
Expect(stats.IsJSONOutputValid()).To(BeTrue())
})
It("podman stats with GO template", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -164,7 +164,7 @@ var _ = Describe("Podman pod stats", func() {
})
It("podman stats with invalid GO template", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
diff --git a/test/e2e/pod_stop_test.go b/test/e2e/pod_stop_test.go
index 4eb897786..30a5632d0 100644
--- a/test/e2e/pod_stop_test.go
+++ b/test/e2e/pod_stop_test.go
@@ -47,7 +47,7 @@ var _ = Describe("Podman pod stop", func() {
})
It("podman stop bogus pod and a running pod", func() {
- _, ec, podid1 := podmanTest.CreatePod("")
+ _, ec, podid1 := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("test1", podid1)
@@ -61,7 +61,7 @@ var _ = Describe("Podman pod stop", func() {
It("podman stop --ignore bogus pod and a running pod", func() {
- _, ec, podid1 := podmanTest.CreatePod("")
+ _, ec, podid1 := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("test1", podid1)
@@ -78,7 +78,7 @@ var _ = Describe("Podman pod stop", func() {
})
It("podman pod stop single empty pod", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"pod", "stop", podid})
@@ -87,7 +87,7 @@ var _ = Describe("Podman pod stop", func() {
})
It("podman pod stop single pod by name", func() {
- _, ec, _ := podmanTest.CreatePod("foobar99")
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", "foobar99")
@@ -101,14 +101,14 @@ var _ = Describe("Podman pod stop", func() {
})
It("podman pod stop multiple pods", func() {
- _, ec, podid1 := podmanTest.CreatePod("foobar99")
+ _, ec, podid1 := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", "foobar99")
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec2, podid2 := podmanTest.CreatePod("foobar100")
+ _, ec2, podid2 := podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}})
Expect(ec2).To(Equal(0))
session = podmanTest.RunTopContainerInPod("", "foobar100")
@@ -122,14 +122,14 @@ var _ = Describe("Podman pod stop", func() {
})
It("podman pod stop all pods", func() {
- _, ec, _ := podmanTest.CreatePod("foobar99")
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", "foobar99")
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec, _ = podmanTest.CreatePod("foobar100")
+ _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}})
Expect(ec).To(Equal(0))
session = podmanTest.RunTopContainerInPod("", "foobar100")
@@ -143,14 +143,14 @@ var _ = Describe("Podman pod stop", func() {
})
It("podman pod stop latest pod", func() {
- _, ec, _ := podmanTest.CreatePod("foobar99")
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", "foobar99")
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- _, ec, _ = podmanTest.CreatePod("foobar100")
+ _, ec, _ = podmanTest.CreatePod(map[string][]string{"--name": {"foobar100"}})
Expect(ec).To(Equal(0))
session = podmanTest.RunTopContainerInPod("", "foobar100")
@@ -168,7 +168,7 @@ var _ = Describe("Podman pod stop", func() {
})
It("podman pod stop multiple pods with bogus", func() {
- _, ec, podid1 := podmanTest.CreatePod("foobar99")
+ _, ec, podid1 := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", "foobar99")
diff --git a/test/e2e/pod_top_test.go b/test/e2e/pod_top_test.go
index 9e3570360..e191b44fc 100644
--- a/test/e2e/pod_top_test.go
+++ b/test/e2e/pod_top_test.go
@@ -47,7 +47,7 @@ var _ = Describe("Podman top", func() {
})
It("podman pod top on non-running pod", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
result := podmanTest.Podman([]string{"top", podid})
@@ -56,7 +56,7 @@ var _ = Describe("Podman top", func() {
})
It("podman pod top on pod", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"run", "-d", "--pod", podid, ALPINE, "top", "-d", "2"})
@@ -73,7 +73,7 @@ var _ = Describe("Podman top", func() {
})
It("podman pod top with options", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"run", "-d", "--pod", podid, ALPINE, "top", "-d", "2"})
@@ -87,7 +87,7 @@ var _ = Describe("Podman top", func() {
})
It("podman pod top on pod invalid options", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"run", "-d", "--pod", podid, ALPINE, "top", "-d", "2"})
@@ -104,7 +104,7 @@ var _ = Describe("Podman top", func() {
})
It("podman pod top on pod with containers in same pid namespace", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"run", "-d", "--pod", podid, ALPINE, "top", "-d", "2"})
@@ -123,7 +123,7 @@ var _ = Describe("Podman top", func() {
})
It("podman pod top on pod with containers in different namespace", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.Podman([]string{"run", "-d", "--pod", podid, ALPINE, "top", "-d", "2"})
diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go
index d12534219..db3f7a36b 100644
--- a/test/e2e/ps_test.go
+++ b/test/e2e/ps_test.go
@@ -389,7 +389,7 @@ var _ = Describe("Podman ps", func() {
})
It("podman --pod", func() {
- _, ec, podid := podmanTest.CreatePod("")
+ _, ec, podid := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podid)
@@ -409,7 +409,7 @@ var _ = Describe("Podman ps", func() {
It("podman --pod with a non-empty pod name", func() {
podName := "testPodName"
- _, ec, podid := podmanTest.CreatePod(podName)
+ _, ec, podid := podmanTest.CreatePod(map[string][]string{"--name": {podName}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("", podName)
diff --git a/test/e2e/restart_test.go b/test/e2e/restart_test.go
index bcaab8947..bfe9563ea 100644
--- a/test/e2e/restart_test.go
+++ b/test/e2e/restart_test.go
@@ -197,10 +197,10 @@ var _ = Describe("Podman restart", func() {
Expect(restartTime.OutputToStringArray()[1]).To(Not(Equal(startTime.OutputToStringArray()[1])))
})
- It("Podman restart a container in a pod and hosts shouln't duplicated", func() {
+ It("Podman restart a container in a pod and hosts should not duplicated", func() {
// Fixes: https://github.com/containers/podman/issues/8921
- _, ec, _ := podmanTest.CreatePod("foobar99")
+ _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"foobar99"}})
Expect(ec).To(Equal(0))
session := podmanTest.RunTopContainerInPod("host-restart-test", "foobar99")
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index ebea2132a..676f24e5d 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -376,6 +376,13 @@ var _ = Describe("Podman run networking", func() {
Expect(session.ExitCode()).To(Equal(0))
})
+ It("podman run slirp4netns network with mtu", func() {
+ session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:mtu=9000", ALPINE, "ip", "addr"})
+ session.Wait(30)
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring("mtu 9000"))
+ })
+
It("podman run slirp4netns network with different cidr", func() {
slirp4netnsHelp := SystemExec("slirp4netns", []string{"--help"})
Expect(slirp4netnsHelp.ExitCode()).To(Equal(0))
diff --git a/test/python/docker/test_containers.py b/test/python/docker/test_containers.py
index 01e049ed4..5c2a5fef2 100644
--- a/test/python/docker/test_containers.py
+++ b/test/python/docker/test_containers.py
@@ -95,6 +95,15 @@ class TestContainers(unittest.TestCase):
top.reload()
self.assertIn(top.status, ("stopped", "exited"))
+ def test_kill_container(self):
+ top = self.client.containers.get(TestContainers.topContainerId)
+ self.assertEqual(top.status, "running")
+
+ # Kill a running container and validate the state
+ top.kill()
+ top.reload()
+ self.assertIn(top.status, ("stopped", "exited"))
+
def test_restart_container(self):
# Validate the container state
top = self.client.containers.get(TestContainers.topContainerId)
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index dcf1da370..6c3812dce 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -610,4 +610,43 @@ json-file | f
is "$output" "$randomcontent" "cat random content"
}
+# https://github.com/containers/podman/issues/9096
+# podman exec may truncate stdout/stderr; actually a bug in conmon:
+# https://github.com/containers/conmon/issues/236
+@test "podman run - does not truncate or hang with big output" {
+ # Size, in bytes, to dd and to expect in return
+ char_count=700000
+
+ # Container name; primarily needed when running podman-remote
+ cname=mybigdatacontainer
+
+ # This is one of those cases where BATS is not the best test framework.
+ # We can't do any output redirection, because 'run' overrides it so
+ # as to preserve $output. We can't _not_ do redirection, because BATS
+ # doesn't like NULs in $output (and neither would humans who might
+ # have to read them in an error log).
+ # Workaround: write to a log file, and don't attach stdout.
+ run_podman run --name $cname --attach stderr --log-driver k8s-file \
+ $IMAGE dd if=/dev/zero count=$char_count bs=1
+ is "${lines[0]}" "$char_count+0 records in" "dd: number of records in"
+ is "${lines[1]}" "$char_count+0 records out" "dd: number of records out"
+
+ # We don't have many tests for '-l'. This is as good a place as any
+ if ! is_remote; then
+ cname=-l
+ fi
+
+ # Now find that log file, and count the NULs in it.
+ # The log file is of the form '<timestamp> <P|F> <data>', where P|F
+ # is Partial/Full; I think that's called "kubernetes log format"?
+ run_podman inspect $cname --format '{{.HostConfig.LogConfig.Path}}'
+ logfile="$output"
+
+ count_zero=$(tr -cd '\0' <$logfile | wc -c)
+ is "$count_zero" "$char_count" "count of NULL characters in log"
+
+ # Clean up
+ run_podman rm $cname
+}
+
# vim: filetype=sh
diff --git a/test/system/140-diff.bats b/test/system/140-diff.bats
index 1277f9bbe..02b3a86ca 100644
--- a/test/system/140-diff.bats
+++ b/test/system/140-diff.bats
@@ -25,7 +25,12 @@ load helpers
)
for field in ${!expect[@]}; do
- result=$(jq -r -c ".${field}[]" <<<"$output")
+ # ARGH! The /sys/fs kludgery is for RHEL8 rootless, which mumble mumble
+ # does some sort of magic muckery with /sys - I think the relevant
+ # PR is https://github.com/containers/podman/pull/8561
+ # Anyhow, without the egrep below, this test fails about 50% of the
+ # time on rootless RHEL8. (No, I don't know why it's not 100%).
+ result=$(jq -r -c ".${field}[]" <<<"$output" | egrep -v '^/sys/fs')
is "$result" "${expect[$field]}" "$field"
done
diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats
index 0b7aab2fb..4952eafc2 100644
--- a/test/system/160-volumes.bats
+++ b/test/system/160-volumes.bats
@@ -214,6 +214,13 @@ EOF
run_podman volume create $vol
done
+ # Create two additional labeled volumes
+ for i in 5 6; do
+ vol=myvol${i}$(random_string)
+ v[$i]=$vol
+ run_podman volume create $vol --label "mylabel"
+ done
+
# (Assert that output is formatted, not a one-line blob: #8011)
run_podman volume inspect ${v[1]}
if [[ "${#lines[*]}" -lt 10 ]]; then
@@ -225,6 +232,14 @@ EOF
run_podman run --name c2 --volume ${v[2]}:/vol2 -v ${v[3]}:/vol3 \
$IMAGE date
+ # List available volumes for pruning after using 1,2,3
+ run_podman volume prune <<< N
+ is "$(echo $(sort <<<${lines[@]:1:3}))" "${v[4]} ${v[5]} ${v[6]}" "volume prune, with 1,2,3 in use, lists 4,5,6"
+
+ # List available volumes for pruning after using 1,2,3 and filtering; see #8913
+ run_podman volume prune --filter label=mylabel <<< N
+ is "$(echo $(sort <<<${lines[@]:1:2}))" "${v[5]} ${v[6]}" "volume prune, with 1,2,3 in use and 4 filtered out, lists 5,6"
+
# prune should remove v4
run_podman volume prune --force
is "$output" "${v[4]}" "volume prune, with 1, 2, 3 in use, deletes only 4"
diff --git a/test/utils/utils.go b/test/utils/utils.go
index f21584537..6790f31cd 100644
--- a/test/utils/utils.go
+++ b/test/utils/utils.go
@@ -467,11 +467,14 @@ func Containerized() bool {
return false
}
+func init() {
+ rand.Seed(GinkgoRandomSeed())
+}
+
var randomLetters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
// RandomString returns a string of given length composed of random characters
func RandomString(n int) string {
- rand.Seed(GinkgoRandomSeed())
b := make([]rune, n)
for i := range b {
diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/find.go b/vendor/github.com/containernetworking/cni/pkg/invoke/find.go
index e815404c8..e62029eb7 100644
--- a/vendor/github.com/containernetworking/cni/pkg/invoke/find.go
+++ b/vendor/github.com/containernetworking/cni/pkg/invoke/find.go
@@ -18,6 +18,7 @@ import (
"fmt"
"os"
"path/filepath"
+ "strings"
)
// FindInPath returns the full path of the plugin by searching in the provided path
@@ -26,6 +27,10 @@ func FindInPath(plugin string, paths []string) (string, error) {
return "", fmt.Errorf("no plugin name provided")
}
+ if strings.ContainsRune(plugin, os.PathSeparator) {
+ return "", fmt.Errorf("invalid plugin name: %s", plugin)
+ }
+
if len(paths) == 0 {
return "", fmt.Errorf("no paths provided")
}
diff --git a/vendor/github.com/containers/storage/.cirrus.yml b/vendor/github.com/containers/storage/.cirrus.yml
index cc2dd7952..836bf659a 100644
--- a/vendor/github.com/containers/storage/.cirrus.yml
+++ b/vendor/github.com/containers/storage/.cirrus.yml
@@ -25,7 +25,7 @@ env:
# GCE project where images live
IMAGE_PROJECT: "libpod-218412"
# VM Image built in containers/automation_images
- _BUILT_IMAGE_SUFFIX: "c6233039174893568"
+ _BUILT_IMAGE_SUFFIX: "c5744859501821952"
FEDORA_CACHE_IMAGE_NAME: "fedora-${_BUILT_IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${_BUILT_IMAGE_SUFFIX}"
UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${_BUILT_IMAGE_SUFFIX}"
diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION
index 6521720b4..ad2191947 100644
--- a/vendor/github.com/containers/storage/VERSION
+++ b/vendor/github.com/containers/storage/VERSION
@@ -1 +1 @@
-1.24.5
+1.25.0
diff --git a/vendor/github.com/containers/storage/drivers/aufs/aufs.go b/vendor/github.com/containers/storage/drivers/aufs/aufs.go
index c4ced0488..5310b5ccc 100644
--- a/vendor/github.com/containers/storage/drivers/aufs/aufs.go
+++ b/vendor/github.com/containers/storage/drivers/aufs/aufs.go
@@ -482,6 +482,21 @@ func (a *Driver) Put(id string) error {
return err
}
+// ReadWriteDiskUsage returns the disk usage of the writable directory for the ID.
+// For AUFS, it queries the mountpoint for this ID.
+func (a *Driver) ReadWriteDiskUsage(id string) (*directory.DiskUsage, error) {
+ a.locker.Lock(id)
+ defer a.locker.Unlock(id)
+ a.pathCacheLock.Lock()
+ m, exists := a.pathCache[id]
+ if !exists {
+ m = a.getMountpoint(id)
+ a.pathCache[id] = m
+ }
+ a.pathCacheLock.Unlock()
+ return directory.Usage(m)
+}
+
// isParent returns if the passed in parent is the direct parent of the passed in layer
func (a *Driver) isParent(id, parent string) bool {
parents, _ := getParentIDs(a.rootPath(), id)
diff --git a/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go b/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
index e71ad69e2..7aba695ff 100644
--- a/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
+++ b/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
@@ -27,6 +27,7 @@ import (
"unsafe"
graphdriver "github.com/containers/storage/drivers"
+ "github.com/containers/storage/pkg/directory"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/parsers"
@@ -687,6 +688,12 @@ func (d *Driver) Put(id string) error {
return nil
}
+// ReadWriteDiskUsage returns the disk usage of the writable directory for the ID.
+// For BTRFS, it queries the subvolumes path for this ID.
+func (d *Driver) ReadWriteDiskUsage(id string) (*directory.DiskUsage, error) {
+ return directory.Usage(d.subvolumesDirID(id))
+}
+
// Exists checks if the id exists in the filesystem.
func (d *Driver) Exists(id string) bool {
dir := d.subvolumesDirID(id)
diff --git a/vendor/github.com/containers/storage/drivers/devmapper/driver.go b/vendor/github.com/containers/storage/drivers/devmapper/driver.go
index 4149979a5..e0bef1301 100644
--- a/vendor/github.com/containers/storage/drivers/devmapper/driver.go
+++ b/vendor/github.com/containers/storage/drivers/devmapper/driver.go
@@ -11,6 +11,7 @@ import (
graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/devicemapper"
+ "github.com/containers/storage/pkg/directory"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/locker"
"github.com/containers/storage/pkg/mount"
@@ -251,6 +252,14 @@ func (d *Driver) Put(id string) error {
return err
}
+// ReadWriteDiskUsage returns the disk usage of the writable directory for the ID.
+// For devmapper, it queries the mnt path for this ID.
+func (d *Driver) ReadWriteDiskUsage(id string) (*directory.DiskUsage, error) {
+ d.locker.Lock(id)
+ defer d.locker.Unlock(id)
+ return directory.Usage(path.Join(d.home, "mnt", id))
+}
+
// Exists checks to see if the device exists.
func (d *Driver) Exists(id string) bool {
return d.DeviceSet.HasDevice(id)
diff --git a/vendor/github.com/containers/storage/drivers/driver.go b/vendor/github.com/containers/storage/drivers/driver.go
index 2d6485e80..0a676f6ac 100644
--- a/vendor/github.com/containers/storage/drivers/driver.go
+++ b/vendor/github.com/containers/storage/drivers/driver.go
@@ -12,6 +12,7 @@ import (
"github.com/vbatts/tar-split/tar/storage"
"github.com/containers/storage/pkg/archive"
+ "github.com/containers/storage/pkg/directory"
"github.com/containers/storage/pkg/idtools"
)
@@ -105,6 +106,8 @@ type ProtoDriver interface {
// Returns a set of key-value pairs which give low level information
// about the image/container driver is managing.
Metadata(id string) (map[string]string, error)
+ // ReadWriteDiskUsage returns the disk usage of the writable directory for the specified ID.
+ ReadWriteDiskUsage(id string) (*directory.DiskUsage, error)
// Cleanup performs necessary tasks to release resources
// held by the driver, e.g., unmounting all layered filesystems
// known to this driver.
diff --git a/vendor/github.com/containers/storage/drivers/driver_freebsd.go b/vendor/github.com/containers/storage/drivers/driver_freebsd.go
index 53394b738..e1320ee07 100644
--- a/vendor/github.com/containers/storage/drivers/driver_freebsd.go
+++ b/vendor/github.com/containers/storage/drivers/driver_freebsd.go
@@ -1,8 +1,6 @@
package graphdriver
import (
- "syscall"
-
"golang.org/x/sys/unix"
)
@@ -16,7 +14,7 @@ var (
// Mounted checks if the given path is mounted as the fs type
func Mounted(fsType FsMagic, mountPath string) (bool, error) {
var buf unix.Statfs_t
- if err := syscall.Statfs(mountPath, &buf); err != nil {
+ if err := unix.Statfs(mountPath, &buf); err != nil {
return false, err
}
return FsMagic(buf.Type) == fsType, nil
diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
index 6e5a76cf3..864e0af12 100644
--- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go
+++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
@@ -521,6 +521,18 @@ func (d *Driver) Metadata(id string) (map[string]string, error) {
return metadata, nil
}
+// ReadWriteDiskUsage returns the disk usage of the writable directory for the ID.
+// For Overlay, it attempts to check the XFS quota for size, and falls back to
+// finding the size of the "diff" directory.
+func (d *Driver) ReadWriteDiskUsage(id string) (*directory.DiskUsage, error) {
+ usage := &directory.DiskUsage{}
+ if d.quotaCtl != nil {
+ err := d.quotaCtl.GetDiskUsage(d.dir(id), usage)
+ return usage, err
+ }
+ return directory.Usage(path.Join(d.dir(id), "diff"))
+}
+
// Cleanup any state created by overlay which should be cleaned when daemon
// is being shutdown. For now, we just have to unmount the bind mounted
// we had created.
@@ -612,17 +624,22 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
}
}()
- if opts != nil && len(opts.StorageOpt) > 0 {
- driver := &Driver{}
- if err := d.parseStorageOpt(opts.StorageOpt, driver); err != nil {
- return err
- }
-
- if driver.options.quota.Size > 0 {
- // Set container disk quota limit
- if err := d.quotaCtl.SetQuota(dir, driver.options.quota); err != nil {
+ if d.quotaCtl != nil {
+ quota := quota.Quota{}
+ if opts != nil && len(opts.StorageOpt) > 0 {
+ driver := &Driver{}
+ if err := d.parseStorageOpt(opts.StorageOpt, driver); err != nil {
return err
}
+ if driver.options.quota.Size > 0 {
+ quota.Size = driver.options.quota.Size
+ }
+
+ }
+ // Set container disk quota limit
+ // If it is set to 0, we will track the disk usage, but not enforce a limit
+ if err := d.quotaCtl.SetQuota(dir, quota); err != nil {
+ return err
}
}
@@ -1221,6 +1238,7 @@ func (d *Driver) DiffSize(id string, idMappings *idtools.IDMappings, parent stri
if d.useNaiveDiff() || !d.isParent(id, parent) {
return d.naiveDiff.DiffSize(id, idMappings, parent, parentMappings, mountLabel)
}
+
return directory.Size(d.getDiffPath(id))
}
diff --git a/vendor/github.com/containers/storage/drivers/quota/projectquota.go b/vendor/github.com/containers/storage/drivers/quota/projectquota.go
index d5aa0f891..d805623b5 100644
--- a/vendor/github.com/containers/storage/drivers/quota/projectquota.go
+++ b/vendor/github.com/containers/storage/drivers/quota/projectquota.go
@@ -56,6 +56,7 @@ import (
"path/filepath"
"unsafe"
+ "github.com/containers/storage/pkg/directory"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@@ -196,17 +197,37 @@ func setProjectQuota(backingFsBlockDev string, projectID uint32, quota Quota) er
// GetQuota - get the quota limits of a directory that was configured with SetQuota
func (q *Control) GetQuota(targetPath string, quota *Quota) error {
+ d, err := q.fsDiskQuotaFromPath(targetPath)
+ if err != nil {
+ return err
+ }
+ quota.Size = uint64(d.d_blk_hardlimit) * 512
+ return nil
+}
+
+// GetDiskUsage - get the current disk usage of a directory that was configured with SetQuota
+func (q *Control) GetDiskUsage(targetPath string, usage *directory.DiskUsage) error {
+ d, err := q.fsDiskQuotaFromPath(targetPath)
+ if err != nil {
+ return err
+ }
+ usage.Size = int64(d.d_bcount) * 512
+ usage.InodeCount = int64(d.d_icount)
+
+ return nil
+}
+
+func (q *Control) fsDiskQuotaFromPath(targetPath string) (C.fs_disk_quota_t, error) {
+ var d C.fs_disk_quota_t
projectID, ok := q.quotas[targetPath]
if !ok {
- return fmt.Errorf("quota not found for path : %s", targetPath)
+ return d, fmt.Errorf("quota not found for path : %s", targetPath)
}
//
// get the quota limit for the container's project id
//
- var d C.fs_disk_quota_t
-
var cs = C.CString(q.backingFsBlockDev)
defer C.free(unsafe.Pointer(cs))
@@ -214,12 +235,11 @@ func (q *Control) GetQuota(targetPath string, quota *Quota) error {
uintptr(unsafe.Pointer(cs)), uintptr(C.__u32(projectID)),
uintptr(unsafe.Pointer(&d)), 0, 0)
if errno != 0 {
- return fmt.Errorf("Failed to get quota limit for projid %d on %s: %v",
+ return d, fmt.Errorf("Failed to get quota limit for projid %d on %s: %v",
projectID, q.backingFsBlockDev, errno.Error())
}
- quota.Size = uint64(d.d_blk_hardlimit) * 512
- return nil
+ return d, nil
}
// getProjectID - get the project id of path on xfs
diff --git a/vendor/github.com/containers/storage/drivers/vfs/driver.go b/vendor/github.com/containers/storage/drivers/vfs/driver.go
index 679d89112..ec437e14e 100644
--- a/vendor/github.com/containers/storage/drivers/vfs/driver.go
+++ b/vendor/github.com/containers/storage/drivers/vfs/driver.go
@@ -10,6 +10,7 @@ import (
graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/archive"
+ "github.com/containers/storage/pkg/directory"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/parsers"
"github.com/containers/storage/pkg/system"
@@ -243,6 +244,12 @@ func (d *Driver) Put(id string) error {
return nil
}
+// ReadWriteDiskUsage returns the disk usage of the writable directory for the ID.
+// For VFS, it queries the directory for this ID.
+func (d *Driver) ReadWriteDiskUsage(id string) (*directory.DiskUsage, error) {
+ return directory.Usage(d.dir(id))
+}
+
// Exists checks to see if the directory exists for the given id.
func (d *Driver) Exists(id string) bool {
_, err := os.Stat(d.dir(id))
diff --git a/vendor/github.com/containers/storage/drivers/windows/windows.go b/vendor/github.com/containers/storage/drivers/windows/windows.go
index 1fd84e3b4..c8a340801 100644
--- a/vendor/github.com/containers/storage/drivers/windows/windows.go
+++ b/vendor/github.com/containers/storage/drivers/windows/windows.go
@@ -26,6 +26,7 @@ import (
"github.com/Microsoft/hcsshim"
"github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/archive"
+ "github.com/containers/storage/pkg/directory"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/ioutils"
"github.com/containers/storage/pkg/longpath"
@@ -436,6 +437,12 @@ func (d *Driver) Get(id string, options graphdriver.MountOpts) (string, error) {
return dir, nil
}
+// ReadWriteDiskUsage returns the disk usage of the writable directory for the ID.
+// For VFS, it queries the directory for this ID.
+func (d *Driver) ReadWriteDiskUsage(id string) (*directory.DiskUsage, error) {
+ return directory.Usage(d.dir(id))
+}
+
// Put adds a new layer to the driver.
func (d *Driver) Put(id string) error {
panicIfUsedByLcow()
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs.go b/vendor/github.com/containers/storage/drivers/zfs/zfs.go
index 4e7290efc..185a8b074 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs.go
@@ -13,6 +13,7 @@ import (
"time"
graphdriver "github.com/containers/storage/drivers"
+ "github.com/containers/storage/pkg/directory"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/parsers"
@@ -455,6 +456,12 @@ func (d *Driver) Put(id string) error {
return nil
}
+// ReadWriteDiskUsage returns the disk usage of the writable directory for the ID.
+// For ZFS, it queries the full mount path for this ID.
+func (d *Driver) ReadWriteDiskUsage(id string) (*directory.DiskUsage, error) {
+ return directory.Usage(d.mountPath(id))
+}
+
// Exists checks to see if the cache entry exists for the given id.
func (d *Driver) Exists(id string) bool {
d.Lock()
diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod
index 8af8ceddb..78f6e71d3 100644
--- a/vendor/github.com/containers/storage/go.mod
+++ b/vendor/github.com/containers/storage/go.mod
@@ -8,9 +8,9 @@ require (
github.com/Microsoft/hcsshim v0.8.14
github.com/docker/go-units v0.4.0
github.com/hashicorp/go-multierror v1.1.0
- github.com/klauspost/compress v1.11.5
+ github.com/klauspost/compress v1.11.7
github.com/klauspost/pgzip v1.2.5
- github.com/mattn/go-shellwords v1.0.10
+ github.com/mattn/go-shellwords v1.0.11
github.com/mistifyio/go-zfs v2.1.1+incompatible
github.com/moby/sys/mountinfo v0.4.0
github.com/opencontainers/go-digest v1.0.0
@@ -20,7 +20,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7
github.com/sirupsen/logrus v1.7.0
- github.com/stretchr/testify v1.6.1
+ github.com/stretchr/testify v1.7.0
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
github.com/tchap/go-patricia v2.3.0+incompatible
github.com/vbatts/tar-split v0.11.1
diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum
index c786686bc..233191548 100644
--- a/vendor/github.com/containers/storage/go.sum
+++ b/vendor/github.com/containers/storage/go.sum
@@ -58,8 +58,8 @@ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
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.11.5 h1:xNCE0uE6yvTPRS+0wGNMHPo3NIpwnk6aluQZ6R6kRcc=
-github.com/klauspost/compress v1.11.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg=
+github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -71,8 +71,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
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/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw=
-github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
+github.com/mattn/go-shellwords v1.0.11 h1:vCoR9VPpsk/TZFW2JwK5I9S0xdrtUq2bph6/YjEPnaw=
+github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJdNZo6oqSENd4eW8=
github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/moby/sys/mountinfo v0.1.3 h1:KIrhRO14+AkwKvG/g2yIpNMOUVZ02xNhOw8KY1WsLOI=
@@ -118,8 +118,8 @@ github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-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/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs=
diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go
index 72f00b8d6..ce059318d 100644
--- a/vendor/github.com/containers/storage/layers.go
+++ b/vendor/github.com/containers/storage/layers.go
@@ -117,6 +117,11 @@ type Layer struct {
// ReadOnly is true if this layer resides in a read-only layer store.
ReadOnly bool `json:"-"`
+
+ // BigDataNames is a list of names of data items that we keep for the
+ // convenience of the caller. They can be large, and are only in
+ // memory when being read from or written to disk.
+ BigDataNames []string `json:"big-data-names,omitempty"`
}
type layerMountPoint struct {
@@ -137,6 +142,7 @@ type DiffOptions struct {
type ROLayerStore interface {
ROFileBasedStore
ROMetadataStore
+ ROLayerBigDataStore
// Exists checks if a layer with the specified name or ID is known.
Exists(id string) bool
@@ -194,6 +200,7 @@ type LayerStore interface {
RWFileBasedStore
RWMetadataStore
FlaggableStore
+ RWLayerBigDataStore
// Create creates a new layer, optionally giving it a specified ID rather than
// a randomly-generated one, either inheriting data from another specified
@@ -278,6 +285,7 @@ func copyLayer(l *Layer) *Layer {
UncompressedSize: l.UncompressedSize,
CompressionType: l.CompressionType,
ReadOnly: l.ReadOnly,
+ BigDataNames: copyStringSlice(l.BigDataNames),
Flags: copyStringInterfaceMap(l.Flags),
UIDMap: copyIDMap(l.UIDMap),
GIDMap: copyIDMap(l.GIDMap),
@@ -694,14 +702,15 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
}
if err == nil {
layer = &Layer{
- ID: id,
- Parent: parent,
- Names: names,
- MountLabel: mountLabel,
- Created: time.Now().UTC(),
- Flags: make(map[string]interface{}),
- UIDMap: copyIDMap(moreOptions.UIDMap),
- GIDMap: copyIDMap(moreOptions.GIDMap),
+ ID: id,
+ Parent: parent,
+ Names: names,
+ MountLabel: mountLabel,
+ Created: time.Now().UTC(),
+ Flags: make(map[string]interface{}),
+ UIDMap: copyIDMap(moreOptions.UIDMap),
+ GIDMap: copyIDMap(moreOptions.GIDMap),
+ BigDataNames: []string{},
}
r.layers = append(r.layers, layer)
r.idindex.Add(id)
@@ -970,6 +979,80 @@ func (r *layerStore) SetNames(id string, names []string) error {
return ErrLayerUnknown
}
+func (r *layerStore) datadir(id string) string {
+ return filepath.Join(r.layerdir, id)
+}
+
+func (r *layerStore) datapath(id, key string) string {
+ return filepath.Join(r.datadir(id), makeBigDataBaseName(key))
+}
+
+func (r *layerStore) BigData(id, key string) (io.ReadCloser, error) {
+ if key == "" {
+ return nil, errors.Wrapf(ErrInvalidBigDataName, "can't retrieve layer big data value for empty name")
+ }
+ layer, ok := r.lookup(id)
+ if !ok {
+ return nil, errors.Wrapf(ErrLayerUnknown, "error locating layer with ID %q", id)
+ }
+ return os.Open(r.datapath(layer.ID, key))
+}
+
+func (r *layerStore) SetBigData(id, key string, data io.Reader) error {
+ if key == "" {
+ return errors.Wrapf(ErrInvalidBigDataName, "can't set empty name for layer big data item")
+ }
+ if !r.IsReadWrite() {
+ return errors.Wrapf(ErrStoreIsReadOnly, "not allowed to save data items associated with layers at %q", r.layerspath())
+ }
+ layer, ok := r.lookup(id)
+ if !ok {
+ return errors.Wrapf(ErrLayerUnknown, "error locating layer with ID %q to write bigdata", id)
+ }
+ err := os.MkdirAll(r.datadir(layer.ID), 0700)
+ if err != nil {
+ return err
+ }
+
+ // NewAtomicFileWriter doesn't overwrite/truncate the existing inode.
+ // BigData() relies on this behaviour when opening the file for read
+ // so that it is either accessing the old data or the new one.
+ writer, err := ioutils.NewAtomicFileWriter(r.datapath(layer.ID, key), 0600)
+ if err != nil {
+ return errors.Wrapf(err, "error opening bigdata file")
+ }
+
+ if _, err := io.Copy(writer, data); err != nil {
+ writer.Close()
+ return errors.Wrapf(err, "error copying bigdata for the layer")
+
+ }
+ if err := writer.Close(); err != nil {
+ return errors.Wrapf(err, "error closing bigdata file for the layer")
+ }
+
+ addName := true
+ for _, name := range layer.BigDataNames {
+ if name == key {
+ addName = false
+ break
+ }
+ }
+ if addName {
+ layer.BigDataNames = append(layer.BigDataNames, key)
+ return r.Save()
+ }
+ return nil
+}
+
+func (r *layerStore) BigDataNames(id string) ([]string, error) {
+ layer, ok := r.lookup(id)
+ if !ok {
+ return nil, errors.Wrapf(ErrImageUnknown, "error locating layer with ID %q to retrieve bigdata names", id)
+ }
+ return copyStringSlice(layer.BigDataNames), nil
+}
+
func (r *layerStore) Metadata(id string) (string, error) {
if layer, ok := r.lookup(id); ok {
return layer.Metadata, nil
@@ -1004,6 +1087,7 @@ func (r *layerStore) deleteInternal(id string) error {
err := r.driver.Remove(id)
if err == nil {
os.Remove(r.tspath(id))
+ os.RemoveAll(r.datadir(id))
delete(r.byid, id)
for _, name := range layer.Names {
delete(r.byname, name)
diff --git a/vendor/github.com/containers/storage/layers_ffjson.go b/vendor/github.com/containers/storage/layers_ffjson.go
index 3a1095226..f61e68a21 100644
--- a/vendor/github.com/containers/storage/layers_ffjson.go
+++ b/vendor/github.com/containers/storage/layers_ffjson.go
@@ -396,6 +396,22 @@ func (j *Layer) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
}
buf.WriteByte(',')
}
+ if len(j.BigDataNames) != 0 {
+ buf.WriteString(`"big-data-names":`)
+ if j.BigDataNames != nil {
+ buf.WriteString(`[`)
+ for i, v := range j.BigDataNames {
+ if i != 0 {
+ buf.WriteString(`,`)
+ }
+ fflib.WriteJsonString(buf, string(v))
+ }
+ buf.WriteString(`]`)
+ } else {
+ buf.WriteString(`null`)
+ }
+ buf.WriteByte(',')
+ }
buf.Rewind(1)
buf.WriteByte('}')
return nil
@@ -436,6 +452,8 @@ const (
ffjtLayerUIDMap
ffjtLayerGIDMap
+
+ ffjtLayerBigDataNames
)
var ffjKeyLayerID = []byte("id")
@@ -470,6 +488,8 @@ var ffjKeyLayerUIDMap = []byte("uidmap")
var ffjKeyLayerGIDMap = []byte("gidmap")
+var ffjKeyLayerBigDataNames = []byte("big-data-names")
+
// UnmarshalJSON umarshall json - template of ffjson
func (j *Layer) UnmarshalJSON(input []byte) error {
fs := fflib.NewFFLexer(input)
@@ -531,6 +551,14 @@ mainparse:
} else {
switch kn[0] {
+ case 'b':
+
+ if bytes.Equal(ffjKeyLayerBigDataNames, kn) {
+ currentKey = ffjtLayerBigDataNames
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
case 'c':
if bytes.Equal(ffjKeyLayerCreated, kn) {
@@ -640,6 +668,12 @@ mainparse:
}
+ if fflib.EqualFoldRight(ffjKeyLayerBigDataNames, kn) {
+ currentKey = ffjtLayerBigDataNames
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
if fflib.SimpleLetterEqualFold(ffjKeyLayerGIDMap, kn) {
currentKey = ffjtLayerGIDMap
state = fflib.FFParse_want_colon
@@ -801,6 +835,9 @@ mainparse:
case ffjtLayerGIDMap:
goto handle_GIDMap
+ case ffjtLayerBigDataNames:
+ goto handle_BigDataNames
+
case ffjtLayernosuchkey:
err = fs.SkipField(tok)
if err != nil {
@@ -1551,6 +1588,80 @@ handle_GIDMap:
state = fflib.FFParse_after_value
goto mainparse
+handle_BigDataNames:
+
+ /* handler: j.BigDataNames type=[]string kind=slice quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_left_brace && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for ", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+ j.BigDataNames = nil
+ } else {
+
+ j.BigDataNames = []string{}
+
+ wantVal := true
+
+ for {
+
+ var tmpJBigDataNames string
+
+ tok = fs.Scan()
+ if tok == fflib.FFTok_error {
+ goto tokerror
+ }
+ if tok == fflib.FFTok_right_brace {
+ break
+ }
+
+ if tok == fflib.FFTok_comma {
+ if wantVal == true {
+ // TODO(pquerna): this isn't an ideal error message, this handles
+ // things like [,,,] as an array value.
+ return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
+ }
+ continue
+ } else {
+ wantVal = true
+ }
+
+ /* handler: tmpJBigDataNames type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ tmpJBigDataNames = string(string(outBuf))
+
+ }
+ }
+
+ j.BigDataNames = append(j.BigDataNames, tmpJBigDataNames)
+
+ wantVal = false
+ }
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
wantedvalue:
return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
wrongtokenerror:
diff --git a/vendor/github.com/containers/storage/pkg/archive/archive_freebsd.go b/vendor/github.com/containers/storage/pkg/archive/archive_freebsd.go
new file mode 100644
index 000000000..1953b4051
--- /dev/null
+++ b/vendor/github.com/containers/storage/pkg/archive/archive_freebsd.go
@@ -0,0 +1,125 @@
+// +build freebsd
+
+package archive
+
+import (
+ "archive/tar"
+ "errors"
+ "os"
+ "path/filepath"
+ "syscall"
+
+ "github.com/containers/storage/pkg/idtools"
+ "github.com/containers/storage/pkg/system"
+ rsystem "github.com/opencontainers/runc/libcontainer/system"
+ "golang.org/x/sys/unix"
+)
+
+// fixVolumePathPrefix does platform specific processing to ensure that if
+// the path being passed in is not in a volume path format, convert it to one.
+func fixVolumePathPrefix(srcPath string) string {
+ return srcPath
+}
+
+// getWalkRoot calculates the root path when performing a TarWithOptions.
+// We use a separate function as this is platform specific. On Linux, we
+// can't use filepath.Join(srcPath,include) because this will clean away
+// a trailing "." or "/" which may be important.
+func getWalkRoot(srcPath string, include string) string {
+ return srcPath + string(filepath.Separator) + include
+}
+
+// CanonicalTarNameForPath returns platform-specific filepath
+// to canonical posix-style path for tar archival. p is relative
+// path.
+func CanonicalTarNameForPath(p string) (string, error) {
+ return p, nil // already unix-style
+}
+
+// chmodTarEntry is used to adjust the file permissions used in tar header based
+// on the platform the archival is done.
+func chmodTarEntry(perm os.FileMode) os.FileMode {
+ return perm // noop for unix as golang APIs provide perm bits correctly
+}
+
+func setHeaderForSpecialDevice(hdr *tar.Header, name string, stat interface{}) (err error) {
+ s, ok := stat.(*syscall.Stat_t)
+
+ if ok {
+ // Currently go does not fill in the major/minors
+ if s.Mode&unix.S_IFBLK != 0 ||
+ s.Mode&unix.S_IFCHR != 0 {
+ hdr.Devmajor = int64(major(uint64(s.Rdev))) // nolint: unconvert
+ hdr.Devminor = int64(minor(uint64(s.Rdev))) // nolint: unconvert
+ }
+ }
+
+ return
+}
+
+func getInodeFromStat(stat interface{}) (inode uint64, err error) {
+ s, ok := stat.(*syscall.Stat_t)
+
+ if ok {
+ inode = s.Ino
+ }
+
+ return
+}
+
+func getFileUIDGID(stat interface{}) (idtools.IDPair, error) {
+ s, ok := stat.(*syscall.Stat_t)
+
+ if !ok {
+ return idtools.IDPair{}, errors.New("cannot convert stat value to syscall.Stat_t")
+ }
+ return idtools.IDPair{UID: int(s.Uid), GID: int(s.Gid)}, nil
+}
+
+func major(device uint64) uint64 {
+ return (device >> 8) & 0xfff
+}
+
+func minor(device uint64) uint64 {
+ return (device & 0xff) | ((device >> 12) & 0xfff00)
+}
+
+// handleTarTypeBlockCharFifo is an OS-specific helper function used by
+// createTarFile to handle the following types of header: Block; Char; Fifo
+func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
+ if rsystem.RunningInUserNS() {
+ // cannot create a device if running in user namespace
+ return nil
+ }
+
+ mode := uint32(hdr.Mode & 07777)
+ switch hdr.Typeflag {
+ case tar.TypeBlock:
+ mode |= unix.S_IFBLK
+ case tar.TypeChar:
+ mode |= unix.S_IFCHR
+ case tar.TypeFifo:
+ mode |= unix.S_IFIFO
+ }
+
+ return system.Mknod(path, mode, uint64(system.Mkdev(hdr.Devmajor, hdr.Devminor)))
+}
+
+func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo, forceMask *os.FileMode) error {
+ permissionsMask := hdrInfo.Mode()
+ if forceMask != nil {
+ permissionsMask = *forceMask
+ }
+ if hdr.Typeflag == tar.TypeLink {
+ if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
+ if err := os.Chmod(path, permissionsMask); err != nil {
+ return err
+ }
+ }
+ } else if hdr.Typeflag != tar.TypeSymlink {
+ if err := os.Chmod(path, permissionsMask); err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/containers/storage/pkg/archive/archive_unix.go b/vendor/github.com/containers/storage/pkg/archive/archive_unix.go
index ecb704b64..5438700ab 100644
--- a/vendor/github.com/containers/storage/pkg/archive/archive_unix.go
+++ b/vendor/github.com/containers/storage/pkg/archive/archive_unix.go
@@ -1,4 +1,4 @@
-// +build !windows
+// +build !windows,!freebsd
package archive
diff --git a/vendor/github.com/containers/storage/pkg/directory/directory.go b/vendor/github.com/containers/storage/pkg/directory/directory.go
index 1715ef45d..b0ce706e5 100644
--- a/vendor/github.com/containers/storage/pkg/directory/directory.go
+++ b/vendor/github.com/containers/storage/pkg/directory/directory.go
@@ -6,9 +6,15 @@ import (
"path/filepath"
)
+// DiskUsage is a structure that describes the disk usage (size and inode count)
+// of a particular directory.
+type DiskUsage struct {
+ Size int64
+ InodeCount int64
+}
+
// MoveToSubdir moves all contents of a directory to a subdirectory underneath the original path
func MoveToSubdir(oldpath, subdir string) error {
-
infos, err := ioutil.ReadDir(oldpath)
if err != nil {
return err
diff --git a/vendor/github.com/containers/storage/pkg/directory/directory_unix.go b/vendor/github.com/containers/storage/pkg/directory/directory_unix.go
index 05522d68b..245a70c00 100644
--- a/vendor/github.com/containers/storage/pkg/directory/directory_unix.go
+++ b/vendor/github.com/containers/storage/pkg/directory/directory_unix.go
@@ -10,37 +10,50 @@ import (
// Size walks a directory tree and returns its total size in bytes.
func Size(dir string) (size int64, err error) {
+ usage, err := Usage(dir)
+ if err != nil {
+ return 0, err
+ }
+ return usage.Size, nil
+}
+
+// Usage walks a directory tree and returns its total size in bytes and the number of inodes.
+func Usage(dir string) (usage *DiskUsage, err error) {
+ usage = &DiskUsage{}
data := make(map[uint64]struct{})
err = filepath.Walk(dir, func(d string, fileInfo os.FileInfo, err error) error {
if err != nil {
- // if dir does not exist, Size() returns the error.
- // if dir/x disappeared while walking, Size() ignores dir/x.
+ // if dir does not exist, Usage() returns the error.
+ // if dir/x disappeared while walking, Usage() ignores dir/x.
if os.IsNotExist(err) && d != dir {
return nil
}
return err
}
- // Ignore directory sizes
if fileInfo == nil {
return nil
}
- s := fileInfo.Size()
- if fileInfo.IsDir() || s == 0 {
- return nil
- }
-
// Check inode to handle hard links correctly
inode := fileInfo.Sys().(*syscall.Stat_t).Ino
// inode is not a uint64 on all platforms. Cast it to avoid issues.
if _, exists := data[uint64(inode)]; exists {
return nil
}
+
// inode is not a uint64 on all platforms. Cast it to avoid issues.
data[uint64(inode)] = struct{}{}
- size += s
+ // Count the unique inode
+ usage.InodeCount++
+
+ // Ignore directory sizes
+ if fileInfo.IsDir() {
+ return nil
+ }
+
+ usage.Size += fileInfo.Size()
return nil
})
diff --git a/vendor/github.com/containers/storage/pkg/directory/directory_windows.go b/vendor/github.com/containers/storage/pkg/directory/directory_windows.go
index 6fb0917c4..4ff98ddf4 100644
--- a/vendor/github.com/containers/storage/pkg/directory/directory_windows.go
+++ b/vendor/github.com/containers/storage/pkg/directory/directory_windows.go
@@ -7,8 +7,18 @@ import (
"path/filepath"
)
-// Size walks a directory tree and returns its total size in bytes.
+// Size walks a directory tree and returns its total size in bytes
func Size(dir string) (size int64, err error) {
+ usage, err := Usage(dir)
+ if err != nil {
+ return 0, nil
+ }
+ return usage.Size, nil
+}
+
+// Usage walks a directory tree and returns its total size in bytes and the number of inodes.
+func Usage(dir string) (usage *DiskUsage, err error) {
+ usage = &DiskUsage{}
err = filepath.Walk(dir, func(d string, fileInfo os.FileInfo, err error) error {
if err != nil {
// if dir does not exist, Size() returns the error.
@@ -29,7 +39,8 @@ func Size(dir string) (size int64, err error) {
return nil
}
- size += s
+ usage.Size += s
+ usage.InodeCount++
return nil
})
diff --git a/vendor/github.com/containers/storage/pkg/homedir/homedir_others.go b/vendor/github.com/containers/storage/pkg/homedir/homedir_others.go
index 4f778c858..607c5feb5 100644
--- a/vendor/github.com/containers/storage/pkg/homedir/homedir_others.go
+++ b/vendor/github.com/containers/storage/pkg/homedir/homedir_others.go
@@ -1,4 +1,4 @@
-// +build !linux,!darwin
+// +build !linux,!darwin,!freebsd
package homedir
diff --git a/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go b/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go
index 42d1d422c..9d20cfbf8 100644
--- a/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go
+++ b/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go
@@ -1,4 +1,4 @@
-// +build !linux
+// +build !linux,!freebsd
package mount
diff --git a/vendor/github.com/containers/storage/pkg/system/mknod.go b/vendor/github.com/containers/storage/pkg/system/mknod.go
index af79a6538..c276ce8e8 100644
--- a/vendor/github.com/containers/storage/pkg/system/mknod.go
+++ b/vendor/github.com/containers/storage/pkg/system/mknod.go
@@ -1,4 +1,4 @@
-// +build !windows
+// +build !windows,!freebsd
package system
diff --git a/vendor/github.com/containers/storage/pkg/system/mknod_freebsd.go b/vendor/github.com/containers/storage/pkg/system/mknod_freebsd.go
new file mode 100644
index 000000000..d09005589
--- /dev/null
+++ b/vendor/github.com/containers/storage/pkg/system/mknod_freebsd.go
@@ -0,0 +1,22 @@
+// +build freebsd
+
+package system
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+// Mknod creates a filesystem node (file, device special file or named pipe) named path
+// with attributes specified by mode and dev.
+func Mknod(path string, mode uint32, dev uint64) error {
+ return unix.Mknod(path, mode, dev)
+}
+
+// Mkdev is used to build the value of linux devices (in /dev/) which specifies major
+// and minor number of the newly created device special file.
+// Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes.
+// They are, from low to high: the lower 8 bits of the minor, then 12 bits of the major,
+// then the top 12 bits of the minor.
+func Mkdev(major int64, minor int64) uint32 {
+ return uint32(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff))
+}
diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go
index fa595355d..e9c3de5fa 100644
--- a/vendor/github.com/containers/storage/store.go
+++ b/vendor/github.com/containers/storage/store.go
@@ -122,6 +122,30 @@ type ContainerBigDataStore interface {
SetBigData(id, key string, data []byte) error
}
+// A ROLayerBigDataStore wraps up how we store RO big-data associated with layers.
+type ROLayerBigDataStore interface {
+ // SetBigData stores a (potentially large) piece of data associated
+ // with this ID.
+ BigData(id, key string) (io.ReadCloser, error)
+
+ // BigDataNames() returns a list of the names of previously-stored pieces of
+ // data.
+ BigDataNames(id string) ([]string, error)
+}
+
+// A RWLayerBigDataStore wraps up how we store big-data associated with layers.
+type RWLayerBigDataStore interface {
+ // SetBigData stores a (potentially large) piece of data associated
+ // with this ID.
+ SetBigData(id, key string, data io.Reader) error
+}
+
+// A LayerBigDataStore wraps up how we store big-data associated with layers.
+type LayerBigDataStore interface {
+ ROLayerBigDataStore
+ RWLayerBigDataStore
+}
+
// A FlaggableStore can have flags set and cleared on items which it manages.
type FlaggableStore interface {
// ClearFlag removes a named flag from an item in the store.
@@ -385,6 +409,18 @@ type Store interface {
// allow ImagesByDigest to find images by their correct digests.
SetImageBigData(id, key string, data []byte, digestManifest func([]byte) (digest.Digest, error)) error
+ // ListLayerBigData retrieves a list of the (possibly large) chunks of
+ // named data associated with an layer.
+ ListLayerBigData(id string) ([]string, error)
+
+ // LayerBigData retrieves a (possibly large) chunk of named data
+ // associated with a layer.
+ LayerBigData(id, key string) (io.ReadCloser, error)
+
+ // SetLayerBigData stores a (possibly large) chunk of named data
+ // associated with a layer.
+ SetLayerBigData(id, key string, data io.Reader) error
+
// ImageSize computes the size of the image's layers and ancillary data.
ImageSize(id string) (int64, error)
@@ -1627,6 +1663,95 @@ func (s *store) ImageBigData(id, key string) ([]byte, error) {
return nil, errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
+// ListLayerBigData retrieves a list of the (possibly large) chunks of
+// named data associated with an layer.
+func (s *store) ListLayerBigData(id string) ([]string, error) {
+ lstore, err := s.LayerStore()
+ if err != nil {
+ return nil, err
+ }
+ lstores, err := s.ROLayerStores()
+ if err != nil {
+ return nil, err
+ }
+ foundLayer := false
+ for _, s := range append([]ROLayerStore{lstore}, lstores...) {
+ store := s
+ store.RLock()
+ defer store.Unlock()
+ if modified, err := store.Modified(); modified || err != nil {
+ if err = store.Load(); err != nil {
+ return nil, err
+ }
+ }
+ data, err := store.BigDataNames(id)
+ if err == nil {
+ return data, nil
+ }
+ if store.Exists(id) {
+ foundLayer = true
+ }
+ }
+ if foundLayer {
+ return nil, errors.Wrapf(os.ErrNotExist, "error locating big data for layer with ID %q", id)
+ }
+ return nil, errors.Wrapf(ErrLayerUnknown, "error locating layer with ID %q", id)
+}
+
+// LayerBigData retrieves a (possibly large) chunk of named data
+// associated with a layer.
+func (s *store) LayerBigData(id, key string) (io.ReadCloser, error) {
+ lstore, err := s.LayerStore()
+ if err != nil {
+ return nil, err
+ }
+ lstores, err := s.ROLayerStores()
+ if err != nil {
+ return nil, err
+ }
+ foundLayer := false
+ for _, s := range append([]ROLayerStore{lstore}, lstores...) {
+ store := s
+ store.RLock()
+ defer store.Unlock()
+ if modified, err := store.Modified(); modified || err != nil {
+ if err = store.Load(); err != nil {
+ return nil, err
+ }
+ }
+ data, err := store.BigData(id, key)
+ if err == nil {
+ return data, nil
+ }
+ if store.Exists(id) {
+ foundLayer = true
+ }
+ }
+ if foundLayer {
+ return nil, errors.Wrapf(os.ErrNotExist, "error locating item named %q for layer with ID %q", key, id)
+ }
+ return nil, errors.Wrapf(ErrLayerUnknown, "error locating layer with ID %q", id)
+}
+
+// SetLayerBigData stores a (possibly large) chunk of named data
+// associated with a layer.
+func (s *store) SetLayerBigData(id, key string, data io.Reader) error {
+ store, err := s.LayerStore()
+ if err != nil {
+ return err
+ }
+
+ store.Lock()
+ defer store.Unlock()
+ if modified, err := store.Modified(); modified || err != nil {
+ if err = store.Load(); err != nil {
+ return nil
+ }
+ }
+
+ return store.SetBigData(id, key, data)
+}
+
func (s *store) SetImageBigData(id, key string, data []byte, digestManifest func([]byte) (digest.Digest, error)) error {
ristore, err := s.ImageStore()
if err != nil {
diff --git a/vendor/github.com/mattn/go-shellwords/.travis.yml b/vendor/github.com/mattn/go-shellwords/.travis.yml
index b2904bffc..ebd5edd89 100644
--- a/vendor/github.com/mattn/go-shellwords/.travis.yml
+++ b/vendor/github.com/mattn/go-shellwords/.travis.yml
@@ -1,3 +1,6 @@
+arch:
+ - amd64
+ - ppc64le
language: go
sudo: false
go:
diff --git a/vendor/github.com/mattn/go-shellwords/README.md b/vendor/github.com/mattn/go-shellwords/README.md
index e91902f40..bdd531918 100644
--- a/vendor/github.com/mattn/go-shellwords/README.md
+++ b/vendor/github.com/mattn/go-shellwords/README.md
@@ -2,7 +2,8 @@
[![codecov](https://codecov.io/gh/mattn/go-shellwords/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-shellwords)
[![Build Status](https://travis-ci.org/mattn/go-shellwords.svg?branch=master)](https://travis-ci.org/mattn/go-shellwords)
-[![GoDoc](https://godoc.org/github.com/mattn/go-shellwords?status.svg)](http://godoc.org/github.com/mattn/go-shellwords)
+[![PkgGoDev](https://pkg.go.dev/badge/github.com/mattn/go-shellwords)](https://pkg.go.dev/github.com/mattn/go-shellwords)
+[![ci](https://github.com/mattn/go-shellwords/ci/badge.svg)](https://github.com/mattn/go-shellwords/actions)
Parse line as shell words.
@@ -14,6 +15,12 @@ args, err := shellwords.Parse("./foo --bar=baz")
```
```go
+envs, args, err := shellwords.ParseWithEnvs("FOO=foo BAR=baz ./foo --bar=baz")
+// envs should be ["FOO=foo", "BAR=baz"]
+// args should be ["./foo", "--bar=baz"]
+```
+
+```go
os.Setenv("FOO", "bar")
p := shellwords.NewParser()
p.ParseEnv = true
diff --git a/vendor/github.com/mattn/go-shellwords/shellwords.go b/vendor/github.com/mattn/go-shellwords/shellwords.go
index ef080861a..01afd94d1 100644
--- a/vendor/github.com/mattn/go-shellwords/shellwords.go
+++ b/vendor/github.com/mattn/go-shellwords/shellwords.go
@@ -1,10 +1,11 @@
package shellwords
import (
+ "bytes"
"errors"
"os"
- "regexp"
"strings"
+ "unicode"
)
var (
@@ -12,8 +13,6 @@ var (
ParseBacktick bool = false
)
-var envRe = regexp.MustCompile(`\$({[a-zA-Z0-9_]+}|[a-zA-Z0-9_]+)`)
-
func isSpace(r rune) bool {
switch r {
case ' ', '\t', '\r', '\n':
@@ -27,13 +26,72 @@ func replaceEnv(getenv func(string) string, s string) string {
getenv = os.Getenv
}
- return envRe.ReplaceAllStringFunc(s, func(s string) string {
- s = s[1:]
- if s[0] == '{' {
- s = s[1 : len(s)-1]
+ var buf bytes.Buffer
+ rs := []rune(s)
+ for i := 0; i < len(rs); i++ {
+ r := rs[i]
+ if r == '\\' {
+ i++
+ if i == len(rs) {
+ break
+ }
+ buf.WriteRune(rs[i])
+ continue
+ } else if r == '$' {
+ i++
+ if i == len(rs) {
+ buf.WriteRune(r)
+ break
+ }
+ if rs[i] == 0x7b {
+ i++
+ p := i
+ for ; i < len(rs); i++ {
+ r = rs[i]
+ if r == '\\' {
+ i++
+ if i == len(rs) {
+ return s
+ }
+ continue
+ }
+ if r == 0x7d || (!unicode.IsLetter(r) && r != '_' && !unicode.IsDigit(r)) {
+ break
+ }
+ }
+ if r != 0x7d {
+ return s
+ }
+ if i > p {
+ buf.WriteString(getenv(s[p:i]))
+ }
+ } else {
+ p := i
+ for ; i < len(rs); i++ {
+ r := rs[i]
+ if r == '\\' {
+ i++
+ if i == len(rs) {
+ return s
+ }
+ continue
+ }
+ if !unicode.IsLetter(r) && r != '_' && !unicode.IsDigit(r) {
+ break
+ }
+ }
+ if i > p {
+ buf.WriteString(getenv(s[p:i]))
+ i--
+ } else {
+ buf.WriteString(s[p:])
+ }
+ }
+ } else {
+ buf.WriteRune(r)
}
- return getenv(s)
- })
+ }
+ return buf.String()
}
type Parser struct {
@@ -56,6 +114,14 @@ func NewParser() *Parser {
}
}
+type argType int
+
+const (
+ argNo argType = iota
+ argSingle
+ argQuoted
+)
+
func (p *Parser) Parse(line string) ([]string, error) {
args := []string{}
buf := ""
@@ -63,13 +129,16 @@ func (p *Parser) Parse(line string) ([]string, error) {
backtick := ""
pos := -1
- got := false
+ got := argNo
+ i := -1
loop:
- for i, r := range line {
+ for _, r := range line {
+ i++
if escaped {
buf += string(r)
escaped = false
+ got = argSingle
continue
}
@@ -86,21 +155,23 @@ loop:
if singleQuoted || doubleQuoted || backQuote || dollarQuote {
buf += string(r)
backtick += string(r)
- } else if got {
+ } else if got != argNo {
if p.ParseEnv {
- parser := &Parser{ParseEnv: false, ParseBacktick: false, Position: 0, Dir: p.Dir}
- strs, err := parser.Parse(replaceEnv(p.Getenv, buf))
- if err != nil {
- return nil, err
- }
- for _, str := range strs {
- args = append(args, str)
+ if got == argSingle {
+ parser := &Parser{ParseEnv: false, ParseBacktick: false, Position: 0, Dir: p.Dir}
+ strs, err := parser.Parse(replaceEnv(p.Getenv, buf))
+ if err != nil {
+ return nil, err
+ }
+ args = append(args, strs...)
+ } else {
+ args = append(args, replaceEnv(p.Getenv, buf))
}
} else {
args = append(args, buf)
}
buf = ""
- got = false
+ got = argNo
}
continue
}
@@ -153,7 +224,7 @@ loop:
case '"':
if !singleQuoted && !dollarQuote {
if doubleQuoted {
- got = true
+ got = argQuoted
}
doubleQuoted = !doubleQuoted
continue
@@ -161,7 +232,7 @@ loop:
case '\'':
if !doubleQuoted && !dollarQuote {
if singleQuoted {
- got = true
+ got = argSingle
}
singleQuoted = !singleQuoted
continue
@@ -171,7 +242,7 @@ loop:
if r == '>' && len(buf) > 0 {
if c := buf[0]; '0' <= c && c <= '9' {
i -= 1
- got = false
+ got = argNo
}
}
pos = i
@@ -179,22 +250,24 @@ loop:
}
}
- got = true
+ got = argSingle
buf += string(r)
if backQuote || dollarQuote {
backtick += string(r)
}
}
- if got {
+ if got != argNo {
if p.ParseEnv {
- parser := &Parser{ParseEnv: false, ParseBacktick: false, Position: 0, Dir: p.Dir}
- strs, err := parser.Parse(replaceEnv(p.Getenv, buf))
- if err != nil {
- return nil, err
- }
- for _, str := range strs {
- args = append(args, str)
+ if got == argSingle {
+ parser := &Parser{ParseEnv: false, ParseBacktick: false, Position: 0, Dir: p.Dir}
+ strs, err := parser.Parse(replaceEnv(p.Getenv, buf))
+ if err != nil {
+ return nil, err
+ }
+ args = append(args, strs...)
+ } else {
+ args = append(args, replaceEnv(p.Getenv, buf))
}
} else {
args = append(args, buf)
@@ -210,6 +283,35 @@ loop:
return args, nil
}
+func (p *Parser) ParseWithEnvs(line string) (envs []string, args []string, err error) {
+ _args, err := p.Parse(line)
+ if err != nil {
+ return nil, nil, err
+ }
+ envs = []string{}
+ args = []string{}
+ parsingEnv := true
+ for _, arg := range _args {
+ if parsingEnv && isEnv(arg) {
+ envs = append(envs, arg)
+ } else {
+ if parsingEnv {
+ parsingEnv = false
+ }
+ args = append(args, arg)
+ }
+ }
+ return envs, args, nil
+}
+
+func isEnv(arg string) bool {
+ return len(strings.Split(arg, "=")) == 2
+}
+
func Parse(line string) ([]string, error) {
return NewParser().Parse(line)
}
+
+func ParseWithEnvs(line string) (envs []string, args []string, err error) {
+ return NewParser().ParseWithEnvs(line)
+}
diff --git a/vendor/github.com/mattn/go-shellwords/util_posix.go b/vendor/github.com/mattn/go-shellwords/util_posix.go
index 988fc9ed2..b56a90120 100644
--- a/vendor/github.com/mattn/go-shellwords/util_posix.go
+++ b/vendor/github.com/mattn/go-shellwords/util_posix.go
@@ -3,7 +3,7 @@
package shellwords
import (
- "errors"
+ "fmt"
"os"
"os/exec"
"strings"
@@ -23,7 +23,7 @@ func shellRun(line, dir string) (string, error) {
if eerr, ok := err.(*exec.ExitError); ok {
b = eerr.Stderr
}
- return "", errors.New(err.Error() + ":" + string(b))
+ return "", fmt.Errorf("%s: %w", string(b), err)
}
return strings.TrimSpace(string(b)), nil
}
diff --git a/vendor/github.com/mattn/go-shellwords/util_windows.go b/vendor/github.com/mattn/go-shellwords/util_windows.go
index 20546737c..fd738a721 100644
--- a/vendor/github.com/mattn/go-shellwords/util_windows.go
+++ b/vendor/github.com/mattn/go-shellwords/util_windows.go
@@ -3,7 +3,7 @@
package shellwords
import (
- "errors"
+ "fmt"
"os"
"os/exec"
"strings"
@@ -23,7 +23,7 @@ func shellRun(line, dir string) (string, error) {
if eerr, ok := err.(*exec.ExitError); ok {
b = eerr.Stderr
}
- return "", errors.New(err.Error() + ":" + string(b))
+ return "", fmt.Errorf("%s: %w", string(b), err)
}
return strings.TrimSpace(string(b)), nil
}
diff --git a/vendor/github.com/onsi/ginkgo/.travis.yml b/vendor/github.com/onsi/ginkgo/.travis.yml
index 079af2431..8b2883f97 100644
--- a/vendor/github.com/onsi/ginkgo/.travis.yml
+++ b/vendor/github.com/onsi/ginkgo/.travis.yml
@@ -1,7 +1,7 @@
language: go
go:
- - 1.13.x
- 1.14.x
+ - 1.15.x
- tip
cache:
@@ -16,10 +16,9 @@ install:
- GO111MODULE="off" go get golang.org/x/tools/cmd/cover
- GO111MODULE="off" go get github.com/onsi/gomega
- GO111MODULE="off" go install github.com/onsi/ginkgo/ginkgo
- - export PATH=$PATH:$HOME/gopath/bin
+ - export PATH=$GOPATH/bin:$PATH
script:
- - GO111MODULE="on" go mod tidy
- - diff -u <(echo -n) <(git diff go.mod)
- - diff -u <(echo -n) <(git diff go.sum)
- - $HOME/gopath/bin/ginkgo -r --randomizeAllSpecs --randomizeSuites --race --trace && go vet
+ - GO111MODULE="on" go mod tidy && git diff --exit-code go.mod go.sum
+ - go vet
+ - ginkgo -r --randomizeAllSpecs --randomizeSuites --race --trace
diff --git a/vendor/github.com/onsi/ginkgo/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/CHANGELOG.md
index a733f95fc..bf51fe9cd 100644
--- a/vendor/github.com/onsi/ginkgo/CHANGELOG.md
+++ b/vendor/github.com/onsi/ginkgo/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 1.15.0
+
+### Features
+- Adds 'outline' command to print the outline of specs/containers in a file (#754) [071c369] [6803cc3] [935b538] [06744e8] [0c40583]
+- Add support for using template to generate tests (#752) [efb9e69]
+- Add a Chinese Doc #755 (#756) [5207632]
+- cli: allow multiple -focus and -skip flags (#736) [9a782fb]
+
+### Fixes
+- Add _internal to filename of tests created with internal flag (#751) [43c12da]
+
## 1.14.2
### Fixes
diff --git a/vendor/github.com/onsi/ginkgo/README.md b/vendor/github.com/onsi/ginkgo/README.md
index 475e04994..64e85eee0 100644
--- a/vendor/github.com/onsi/ginkgo/README.md
+++ b/vendor/github.com/onsi/ginkgo/README.md
@@ -2,7 +2,7 @@
[![Build Status](https://travis-ci.org/onsi/ginkgo.svg?branch=master)](https://travis-ci.org/onsi/ginkgo)
-Jump to the [docs](https://onsi.github.io/ginkgo/) to learn more. To start rolling your Ginkgo tests *now* [keep reading](#set-me-up)!
+Jump to the [docs](https://onsi.github.io/ginkgo/) | [中文文档](https://ke-chain.github.io/ginkgodoc) to learn more. To start rolling your Ginkgo tests *now* [keep reading](#set-me-up)!
If you have a question, comment, bug report, feature request, etc. please open a GitHub issue, or visit the [Ginkgo Slack channel](https://app.slack.com/client/T029RQSE6/CQQ50BBNW).
diff --git a/vendor/github.com/onsi/ginkgo/config/config.go b/vendor/github.com/onsi/ginkgo/config/config.go
index 3220c095c..8c177811e 100644
--- a/vendor/github.com/onsi/ginkgo/config/config.go
+++ b/vendor/github.com/onsi/ginkgo/config/config.go
@@ -20,14 +20,14 @@ import (
"fmt"
)
-const VERSION = "1.14.2"
+const VERSION = "1.15.0"
type GinkgoConfigType struct {
RandomSeed int64
RandomizeAllSpecs bool
RegexScansFilePath bool
- FocusString string
- SkipString string
+ FocusStrings []string
+ SkipStrings []string
SkipMeasurements bool
FailOnPending bool
FailFast bool
@@ -65,6 +65,11 @@ func processPrefix(prefix string) string {
return prefix
}
+type flagFunc func(string)
+
+func (f flagFunc) String() string { return "" }
+func (f flagFunc) Set(s string) error { f(s); return nil }
+
func Flags(flagSet *flag.FlagSet, prefix string, includeParallelFlags bool) {
prefix = processPrefix(prefix)
flagSet.Int64Var(&(GinkgoConfig.RandomSeed), prefix+"seed", time.Now().Unix(), "The seed used to randomize the spec suite.")
@@ -75,8 +80,8 @@ func Flags(flagSet *flag.FlagSet, prefix string, includeParallelFlags bool) {
flagSet.BoolVar(&(GinkgoConfig.DryRun), prefix+"dryRun", false, "If set, ginkgo will walk the test hierarchy without actually running anything. Best paired with -v.")
- flagSet.StringVar(&(GinkgoConfig.FocusString), prefix+"focus", "", "If set, ginkgo will only run specs that match this regular expression.")
- flagSet.StringVar(&(GinkgoConfig.SkipString), prefix+"skip", "", "If set, ginkgo will only run specs that do not match this regular expression.")
+ flagSet.Var(flagFunc(flagFocus), prefix+"focus", "If set, ginkgo will only run specs that match this regular expression. Can be specified multiple times, values are ORed.")
+ flagSet.Var(flagFunc(flagSkip), prefix+"skip", "If set, ginkgo will only run specs that do not match this regular expression. Can be specified multiple times, values are ORed.")
flagSet.BoolVar(&(GinkgoConfig.RegexScansFilePath), prefix+"regexScansFilePath", false, "If set, ginkgo regex matching also will look at the file path (code location).")
@@ -133,12 +138,12 @@ func BuildFlagArgs(prefix string, ginkgo GinkgoConfigType, reporter DefaultRepor
result = append(result, fmt.Sprintf("--%sdryRun", prefix))
}
- if ginkgo.FocusString != "" {
- result = append(result, fmt.Sprintf("--%sfocus=%s", prefix, ginkgo.FocusString))
+ for _, s := range ginkgo.FocusStrings {
+ result = append(result, fmt.Sprintf("--%sfocus=%s", prefix, s))
}
- if ginkgo.SkipString != "" {
- result = append(result, fmt.Sprintf("--%sskip=%s", prefix, ginkgo.SkipString))
+ for _, s := range ginkgo.SkipStrings {
+ result = append(result, fmt.Sprintf("--%sskip=%s", prefix, s))
}
if ginkgo.FlakeAttempts > 1 {
@@ -211,3 +216,13 @@ func BuildFlagArgs(prefix string, ginkgo GinkgoConfigType, reporter DefaultRepor
return result
}
+
+// flagFocus implements the -focus flag.
+func flagFocus(arg string) {
+ GinkgoConfig.FocusStrings = append(GinkgoConfig.FocusStrings, arg)
+}
+
+// flagSkip implements the -skip flag.
+func flagSkip(arg string) {
+ GinkgoConfig.SkipStrings = append(GinkgoConfig.SkipStrings, arg)
+}
diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go b/vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go
index 99557048a..288df7797 100644
--- a/vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go
+++ b/vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go
@@ -4,6 +4,7 @@ import (
"bytes"
"flag"
"fmt"
+ "io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -12,11 +13,15 @@ import (
)
func BuildGenerateCommand() *Command {
- var agouti, noDot, internal bool
+ var (
+ agouti, noDot, internal bool
+ customTestFile string
+ )
flagSet := flag.NewFlagSet("generate", flag.ExitOnError)
flagSet.BoolVar(&agouti, "agouti", false, "If set, generate will generate a test file for writing Agouti tests")
flagSet.BoolVar(&noDot, "nodot", false, "If set, generate will generate a test file that does not . import ginkgo and gomega")
flagSet.BoolVar(&internal, "internal", false, "If set, generate will generate a test file that uses the regular package name")
+ flagSet.StringVar(&customTestFile, "template", "", "If specified, generate will use the contents of the file passed as the test file template")
return &Command{
Name: "generate",
@@ -28,7 +33,7 @@ func BuildGenerateCommand() *Command {
"Accepts the following flags:",
},
Command: func(args []string, additionalArgs []string) {
- generateSpec(args, agouti, noDot, internal)
+ generateSpec(args, agouti, noDot, internal, customTestFile)
},
}
}
@@ -81,9 +86,9 @@ type specData struct {
ImportPackage bool
}
-func generateSpec(args []string, agouti, noDot, internal bool) {
+func generateSpec(args []string, agouti, noDot, internal bool, customTestFile string) {
if len(args) == 0 {
- err := generateSpecForSubject("", agouti, noDot, internal)
+ err := generateSpecForSubject("", agouti, noDot, internal, customTestFile)
if err != nil {
fmt.Println(err.Error())
fmt.Println("")
@@ -95,7 +100,7 @@ func generateSpec(args []string, agouti, noDot, internal bool) {
var failed bool
for _, arg := range args {
- err := generateSpecForSubject(arg, agouti, noDot, internal)
+ err := generateSpecForSubject(arg, agouti, noDot, internal, customTestFile)
if err != nil {
failed = true
fmt.Println(err.Error())
@@ -107,13 +112,17 @@ func generateSpec(args []string, agouti, noDot, internal bool) {
}
}
-func generateSpecForSubject(subject string, agouti, noDot, internal bool) error {
+func generateSpecForSubject(subject string, agouti, noDot, internal bool, customTestFile string) error {
packageName, specFilePrefix, formattedName := getPackageAndFormattedName()
if subject != "" {
specFilePrefix = formatSubject(subject)
formattedName = prettifyPackageName(specFilePrefix)
}
+ if internal {
+ specFilePrefix = specFilePrefix + "_internal"
+ }
+
data := specData{
Package: determinePackageName(packageName, internal),
Subject: formattedName,
@@ -136,7 +145,13 @@ func generateSpecForSubject(subject string, agouti, noDot, internal bool) error
defer f.Close()
var templateText string
- if agouti {
+ if customTestFile != "" {
+ tpl, err := ioutil.ReadFile(customTestFile)
+ if err != nil {
+ panic(err.Error())
+ }
+ templateText = string(tpl)
+ } else if agouti {
templateText = agoutiSpecText
} else {
templateText = specText
diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/main.go b/vendor/github.com/onsi/ginkgo/ginkgo/main.go
index f60c48a72..ac725bf40 100644
--- a/vendor/github.com/onsi/ginkgo/ginkgo/main.go
+++ b/vendor/github.com/onsi/ginkgo/ginkgo/main.go
@@ -111,6 +111,11 @@ will output an executable file named `package.test`. This can be run directly o
ginkgo <path-to-package.test>
+
+To print an outline of Ginkgo specs and containers in a file:
+
+ gingko outline <filename>
+
To print out Ginkgo's version:
ginkgo version
@@ -172,6 +177,7 @@ func init() {
Commands = append(Commands, BuildUnfocusCommand())
Commands = append(Commands, BuildVersionCommand())
Commands = append(Commands, BuildHelpCommand())
+ Commands = append(Commands, BuildOutlineCommand())
}
func main() {
diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/outline/ginkgo.go b/vendor/github.com/onsi/ginkgo/ginkgo/outline/ginkgo.go
new file mode 100644
index 000000000..ce6b7fcd7
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/ginkgo/outline/ginkgo.go
@@ -0,0 +1,243 @@
+package outline
+
+import (
+ "go/ast"
+ "go/token"
+ "strconv"
+)
+
+const (
+ // undefinedTextAlt is used if the spec/container text cannot be derived
+ undefinedTextAlt = "undefined"
+)
+
+// ginkgoMetadata holds useful bits of information for every entry in the outline
+type ginkgoMetadata struct {
+ // Name is the spec or container function name, e.g. `Describe` or `It`
+ Name string `json:"name"`
+
+ // Text is the `text` argument passed to specs, and some containers
+ Text string `json:"text"`
+
+ // Start is the position of first character of the spec or container block
+ Start int `json:"start"`
+
+ // End is the position of first character immediately after the spec or container block
+ End int `json:"end"`
+
+ Spec bool `json:"spec"`
+ Focused bool `json:"focused"`
+ Pending bool `json:"pending"`
+}
+
+// ginkgoNode is used to construct the outline as a tree
+type ginkgoNode struct {
+ ginkgoMetadata
+ Nodes []*ginkgoNode `json:"nodes"`
+}
+
+type walkFunc func(n *ginkgoNode)
+
+func (n *ginkgoNode) PreOrder(f walkFunc) {
+ f(n)
+ for _, m := range n.Nodes {
+ m.PreOrder(f)
+ }
+}
+
+func (n *ginkgoNode) PostOrder(f walkFunc) {
+ for _, m := range n.Nodes {
+ m.PostOrder(f)
+ }
+ f(n)
+}
+
+func (n *ginkgoNode) Walk(pre, post walkFunc) {
+ pre(n)
+ for _, m := range n.Nodes {
+ m.Walk(pre, post)
+ }
+ post(n)
+}
+
+// PropagateInheritedProperties propagates the Pending and Focused properties
+// through the subtree rooted at n.
+func (n *ginkgoNode) PropagateInheritedProperties() {
+ n.PreOrder(func(thisNode *ginkgoNode) {
+ for _, descendantNode := range thisNode.Nodes {
+ if thisNode.Pending {
+ descendantNode.Pending = true
+ descendantNode.Focused = false
+ }
+ if thisNode.Focused && !descendantNode.Pending {
+ descendantNode.Focused = true
+ }
+ }
+ })
+}
+
+// BackpropagateUnfocus propagates the Focused property through the subtree
+// rooted at n. It applies the rule described in the Ginkgo docs:
+// > Nested programmatically focused specs follow a simple rule: if a
+// > leaf-node is marked focused, any of its ancestor nodes that are marked
+// > focus will be unfocused.
+func (n *ginkgoNode) BackpropagateUnfocus() {
+ focusedSpecInSubtreeStack := []bool{}
+ n.PostOrder(func(thisNode *ginkgoNode) {
+ if thisNode.Spec {
+ focusedSpecInSubtreeStack = append(focusedSpecInSubtreeStack, thisNode.Focused)
+ return
+ }
+ focusedSpecInSubtree := false
+ for range thisNode.Nodes {
+ focusedSpecInSubtree = focusedSpecInSubtree || focusedSpecInSubtreeStack[len(focusedSpecInSubtreeStack)-1]
+ focusedSpecInSubtreeStack = focusedSpecInSubtreeStack[0 : len(focusedSpecInSubtreeStack)-1]
+ }
+ focusedSpecInSubtreeStack = append(focusedSpecInSubtreeStack, focusedSpecInSubtree)
+ if focusedSpecInSubtree {
+ thisNode.Focused = false
+ }
+ })
+
+}
+
+func packageAndIdentNamesFromCallExpr(ce *ast.CallExpr) (string, string, bool) {
+ switch ex := ce.Fun.(type) {
+ case *ast.Ident:
+ return "", ex.Name, true
+ case *ast.SelectorExpr:
+ pkgID, ok := ex.X.(*ast.Ident)
+ if !ok {
+ return "", "", false
+ }
+ // A package identifier is top-level, so Obj must be nil
+ if pkgID.Obj != nil {
+ return "", "", false
+ }
+ if ex.Sel == nil {
+ return "", "", false
+ }
+ return pkgID.Name, ex.Sel.Name, true
+ default:
+ return "", "", false
+ }
+}
+
+// absoluteOffsetsForNode derives the absolute character offsets of the node start and
+// end positions.
+func absoluteOffsetsForNode(fset *token.FileSet, n ast.Node) (start, end int) {
+ return fset.PositionFor(n.Pos(), false).Offset, fset.PositionFor(n.End(), false).Offset
+}
+
+// ginkgoNodeFromCallExpr derives an outline entry from a go AST subtree
+// corresponding to a Ginkgo container or spec.
+func ginkgoNodeFromCallExpr(fset *token.FileSet, ce *ast.CallExpr, ginkgoPackageName, tablePackageName *string) (*ginkgoNode, bool) {
+ packageName, identName, ok := packageAndIdentNamesFromCallExpr(ce)
+ if !ok {
+ return nil, false
+ }
+
+ n := ginkgoNode{}
+ n.Name = identName
+ n.Start, n.End = absoluteOffsetsForNode(fset, ce)
+ n.Nodes = make([]*ginkgoNode, 0)
+ switch identName {
+ case "It", "Measure", "Specify":
+ n.Spec = true
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
+ case "Entry":
+ n.Spec = true
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, tablePackageName != nil && *tablePackageName == packageName
+ case "FIt", "FMeasure", "FSpecify":
+ n.Spec = true
+ n.Focused = true
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
+ case "FEntry":
+ n.Spec = true
+ n.Focused = true
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, tablePackageName != nil && *tablePackageName == packageName
+ case "PIt", "PMeasure", "PSpecify", "XIt", "XMeasure", "XSpecify":
+ n.Spec = true
+ n.Pending = true
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
+ case "PEntry", "XEntry":
+ n.Spec = true
+ n.Pending = true
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, tablePackageName != nil && *tablePackageName == packageName
+ case "Context", "Describe", "When":
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
+ case "DescribeTable":
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, tablePackageName != nil && *tablePackageName == packageName
+ case "FContext", "FDescribe", "FWhen":
+ n.Focused = true
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
+ case "FDescribeTable":
+ n.Focused = true
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, tablePackageName != nil && *tablePackageName == packageName
+ case "PContext", "PDescribe", "PWhen", "XContext", "XDescribe", "XWhen":
+ n.Pending = true
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
+ case "PDescribeTable", "XDescribeTable":
+ n.Pending = true
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, tablePackageName != nil && *tablePackageName == packageName
+ case "By":
+ n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
+ return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
+ case "AfterEach", "BeforeEach":
+ return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
+ case "JustAfterEach", "JustBeforeEach":
+ return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
+ case "AfterSuite", "BeforeSuite":
+ return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
+ case "SynchronizedAfterSuite", "SynchronizedBeforeSuite":
+ return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
+ default:
+ return nil, false
+ }
+}
+
+// textOrAltFromCallExpr tries to derive the "text" of a Ginkgo spec or
+// container. If it cannot derive it, it returns the alt text.
+func textOrAltFromCallExpr(ce *ast.CallExpr, alt string) string {
+ text, defined := textFromCallExpr(ce)
+ if !defined {
+ return alt
+ }
+ return text
+}
+
+// textFromCallExpr tries to derive the "text" of a Ginkgo spec or container. If
+// it cannot derive it, it returns false.
+func textFromCallExpr(ce *ast.CallExpr) (string, bool) {
+ if len(ce.Args) < 1 {
+ return "", false
+ }
+ text, ok := ce.Args[0].(*ast.BasicLit)
+ if !ok {
+ return "", false
+ }
+ switch text.Kind {
+ case token.CHAR, token.STRING:
+ // For token.CHAR and token.STRING, Value is quoted
+ unquoted, err := strconv.Unquote(text.Value)
+ if err != nil {
+ // If unquoting fails, just use the raw Value
+ return text.Value, true
+ }
+ return unquoted, true
+ default:
+ return text.Value, true
+ }
+}
diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/outline/import.go b/vendor/github.com/onsi/ginkgo/ginkgo/outline/import.go
new file mode 100644
index 000000000..4328ab391
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/ginkgo/outline/import.go
@@ -0,0 +1,65 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Most of the required functions were available in the
+// "golang.org/x/tools/go/ast/astutil" package, but not exported.
+// They were copied from https://github.com/golang/tools/blob/2b0845dc783e36ae26d683f4915a5840ef01ab0f/go/ast/astutil/imports.go
+
+package outline
+
+import (
+ "go/ast"
+ "strconv"
+ "strings"
+)
+
+// packageNameForImport returns the package name for the package. If the package
+// is not imported, it returns nil. "Package name" refers to `pkgname` in the
+// call expression `pkgname.ExportedIdentifier`. Examples:
+// (import path not found) -> nil
+// "import example.com/pkg/foo" -> "foo"
+// "import fooalias example.com/pkg/foo" -> "fooalias"
+// "import . example.com/pkg/foo" -> ""
+func packageNameForImport(f *ast.File, path string) *string {
+ spec := importSpec(f, path)
+ if spec == nil {
+ return nil
+ }
+ name := spec.Name.String()
+ if name == "<nil>" {
+ // If the package name is not explicitly specified,
+ // make an educated guess. This is not guaranteed to be correct.
+ lastSlash := strings.LastIndex(path, "/")
+ if lastSlash == -1 {
+ name = path
+ } else {
+ name = path[lastSlash+1:]
+ }
+ }
+ if name == "." {
+ name = ""
+ }
+ return &name
+}
+
+// importSpec returns the import spec if f imports path,
+// or nil otherwise.
+func importSpec(f *ast.File, path string) *ast.ImportSpec {
+ for _, s := range f.Imports {
+ if importPath(s) == path {
+ return s
+ }
+ }
+ return nil
+}
+
+// importPath returns the unquoted import path of s,
+// or "" if the path is not properly quoted.
+func importPath(s *ast.ImportSpec) string {
+ t, err := strconv.Unquote(s.Path.Value)
+ if err != nil {
+ return ""
+ }
+ return t
+}
diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/outline/outline.go b/vendor/github.com/onsi/ginkgo/ginkgo/outline/outline.go
new file mode 100644
index 000000000..242e6a109
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/ginkgo/outline/outline.go
@@ -0,0 +1,107 @@
+package outline
+
+import (
+ "encoding/json"
+ "fmt"
+ "go/ast"
+ "go/token"
+ "strings"
+
+ "golang.org/x/tools/go/ast/inspector"
+)
+
+const (
+ // ginkgoImportPath is the well-known ginkgo import path
+ ginkgoImportPath = "github.com/onsi/ginkgo"
+
+ // tableImportPath is the well-known table extension import path
+ tableImportPath = "github.com/onsi/ginkgo/extensions/table"
+)
+
+// FromASTFile returns an outline for a Ginkgo test source file
+func FromASTFile(fset *token.FileSet, src *ast.File) (*outline, error) {
+ ginkgoPackageName := packageNameForImport(src, ginkgoImportPath)
+ tablePackageName := packageNameForImport(src, tableImportPath)
+ if ginkgoPackageName == nil && tablePackageName == nil {
+ return nil, fmt.Errorf("file does not import %q or %q", ginkgoImportPath, tableImportPath)
+ }
+
+ root := ginkgoNode{}
+ stack := []*ginkgoNode{&root}
+ ispr := inspector.New([]*ast.File{src})
+ ispr.Nodes([]ast.Node{(*ast.CallExpr)(nil)}, func(node ast.Node, push bool) bool {
+ if push {
+ // Pre-order traversal
+ ce, ok := node.(*ast.CallExpr)
+ if !ok {
+ // Because `Nodes` calls this function only when the node is an
+ // ast.CallExpr, this should never happen
+ panic(fmt.Errorf("node starting at %d, ending at %d is not an *ast.CallExpr", node.Pos(), node.End()))
+ }
+ gn, ok := ginkgoNodeFromCallExpr(fset, ce, ginkgoPackageName, tablePackageName)
+ if !ok {
+ // Node is not a Ginkgo spec or container, continue
+ return true
+ }
+ parent := stack[len(stack)-1]
+ parent.Nodes = append(parent.Nodes, gn)
+ stack = append(stack, gn)
+ return true
+ }
+ // Post-order traversal
+ start, end := absoluteOffsetsForNode(fset, node)
+ lastVisitedGinkgoNode := stack[len(stack)-1]
+ if start != lastVisitedGinkgoNode.Start || end != lastVisitedGinkgoNode.End {
+ // Node is not a Ginkgo spec or container, so it was not pushed onto the stack, continue
+ return true
+ }
+ stack = stack[0 : len(stack)-1]
+ return true
+ })
+ if len(root.Nodes) == 0 {
+ return &outline{[]*ginkgoNode{}}, nil
+ }
+
+ // Derive the final focused property for all nodes. This must be done
+ // _before_ propagating the inherited focused property.
+ root.BackpropagateUnfocus()
+ // Now, propagate inherited properties, including focused and pending.
+ root.PropagateInheritedProperties()
+
+ return &outline{root.Nodes}, nil
+}
+
+type outline struct {
+ Nodes []*ginkgoNode `json:"nodes"`
+}
+
+func (o *outline) MarshalJSON() ([]byte, error) {
+ return json.Marshal(o.Nodes)
+}
+
+// String returns a CSV-formatted outline. Spec or container are output in
+// depth-first order.
+func (o *outline) String() string {
+ return o.StringIndent(0)
+}
+
+// StringIndent returns a CSV-formated outline, but every line is indented by
+// one 'width' of spaces for every level of nesting.
+func (o *outline) StringIndent(width int) string {
+ var b strings.Builder
+ b.WriteString("Name,Text,Start,End,Spec,Focused,Pending\n")
+
+ currentIndent := 0
+ pre := func(n *ginkgoNode) {
+ b.WriteString(fmt.Sprintf("%*s", currentIndent, ""))
+ b.WriteString(fmt.Sprintf("%s,%s,%d,%d,%t,%t,%t\n", n.Name, n.Text, n.Start, n.End, n.Spec, n.Focused, n.Pending))
+ currentIndent += width
+ }
+ post := func(n *ginkgoNode) {
+ currentIndent -= width
+ }
+ for _, n := range o.Nodes {
+ n.Walk(pre, post)
+ }
+ return b.String()
+}
diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/outline_command.go b/vendor/github.com/onsi/ginkgo/ginkgo/outline_command.go
new file mode 100644
index 000000000..96ca7ad27
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/ginkgo/outline_command.go
@@ -0,0 +1,95 @@
+package main
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "go/parser"
+ "go/token"
+ "os"
+
+ "github.com/onsi/ginkgo/ginkgo/outline"
+)
+
+const (
+ // indentWidth is the width used by the 'indent' output
+ indentWidth = 4
+ // stdinAlias is a portable alias for stdin. This convention is used in
+ // other CLIs, e.g., kubectl.
+ stdinAlias = "-"
+ usageCommand = "ginkgo outline <filename>"
+)
+
+func BuildOutlineCommand() *Command {
+ const defaultFormat = "csv"
+ var format string
+ flagSet := flag.NewFlagSet("outline", flag.ExitOnError)
+ flagSet.StringVar(&format, "format", defaultFormat, "Format of outline. Accepted: 'csv', 'indent', 'json'")
+ return &Command{
+ Name: "outline",
+ FlagSet: flagSet,
+ UsageCommand: usageCommand,
+ Usage: []string{
+ "Create an outline of Ginkgo symbols for a file",
+ "To read from stdin, use: `ginkgo outline -`",
+ "Accepts the following flags:",
+ },
+ Command: func(args []string, additionalArgs []string) {
+ outlineFile(args, format)
+ },
+ }
+}
+
+func outlineFile(args []string, format string) {
+ if len(args) != 1 {
+ println(fmt.Sprintf("usage: %s", usageCommand))
+ os.Exit(1)
+ }
+
+ filename := args[0]
+ var src *os.File
+ if filename == stdinAlias {
+ src = os.Stdin
+ } else {
+ var err error
+ src, err = os.Open(filename)
+ if err != nil {
+ println(fmt.Sprintf("error opening file: %s", err))
+ os.Exit(1)
+ }
+ }
+
+ fset := token.NewFileSet()
+
+ parsedSrc, err := parser.ParseFile(fset, filename, src, 0)
+ if err != nil {
+ println(fmt.Sprintf("error parsing source: %s", err))
+ os.Exit(1)
+ }
+
+ o, err := outline.FromASTFile(fset, parsedSrc)
+ if err != nil {
+ println(fmt.Sprintf("error creating outline: %s", err))
+ os.Exit(1)
+ }
+
+ var oerr error
+ switch format {
+ case "csv":
+ _, oerr = fmt.Print(o)
+ case "indent":
+ _, oerr = fmt.Print(o.StringIndent(indentWidth))
+ case "json":
+ b, err := json.Marshal(o)
+ if err != nil {
+ println(fmt.Sprintf("error marshalling to json: %s", err))
+ }
+ _, oerr = fmt.Println(string(b))
+ default:
+ complainAndQuit(fmt.Sprintf("format %s not accepted", format))
+ }
+ if oerr != nil {
+ println(fmt.Sprintf("error writing outline: %s", oerr))
+ os.Exit(1)
+ }
+}
diff --git a/vendor/github.com/onsi/ginkgo/go.mod b/vendor/github.com/onsi/ginkgo/go.mod
index 1f7125228..655060cf7 100644
--- a/vendor/github.com/onsi/ginkgo/go.mod
+++ b/vendor/github.com/onsi/ginkgo/go.mod
@@ -4,8 +4,8 @@ require (
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/nxadm/tail v1.4.4
github.com/onsi/gomega v1.10.1
- golang.org/x/sys v0.0.0-20200519105757-fe76b779f299
- golang.org/x/text v0.3.2 // indirect
+ golang.org/x/sys v0.0.0-20210112080510-489259a85091
+ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e
)
go 1.13
diff --git a/vendor/github.com/onsi/ginkgo/go.sum b/vendor/github.com/onsi/ginkgo/go.sum
index 2b774f3e8..56a493f9d 100644
--- a/vendor/github.com/onsi/ginkgo/go.sum
+++ b/vendor/github.com/onsi/ginkgo/go.sum
@@ -1,8 +1,6 @@
-github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
@@ -15,39 +13,50 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
-github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
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/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
-golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -57,11 +66,9 @@ google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyz
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
-gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_darwin.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_darwin.go
deleted file mode 100644
index e3d09eadb..000000000
--- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_darwin.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build darwin
-
-package remote
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func interceptorDupx(oldfd int, newfd int) {
- unix.Dup2(oldfd, newfd)
-}
diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_dragonfly.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_dragonfly.go
deleted file mode 100644
index 72d38686a..000000000
--- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_dragonfly.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build dragonfly
-
-package remote
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func interceptorDupx(oldfd int, newfd int) {
- unix.Dup2(oldfd, newfd)
-}
diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_freebsd.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_freebsd.go
deleted file mode 100644
index 497d548d9..000000000
--- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_freebsd.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build freebsd
-
-package remote
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func interceptorDupx(oldfd int, newfd int) {
- unix.Dup2(oldfd, newfd)
-}
diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux.go
deleted file mode 100644
index 29add0d33..000000000
--- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// +build linux
-// +build !mips64le
-
-package remote
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func interceptorDupx(oldfd int, newfd int) {
- unix.Dup2(oldfd, newfd)
-}
diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux_mips64le.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux_mips64le.go
deleted file mode 100644
index 09bd06260..000000000
--- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux_mips64le.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// +build linux
-// +build mips64le
-
-package remote
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func interceptorDupx(oldfd int, newfd int) {
- unix.Dup3(oldfd, newfd, 0)
-}
diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_netbsd.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_netbsd.go
deleted file mode 100644
index 16ad6aeb2..000000000
--- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_netbsd.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build netbsd
-
-package remote
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func interceptorDupx(oldfd int, newfd int) {
- unix.Dup2(oldfd, newfd)
-}
diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_openbsd.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_openbsd.go
deleted file mode 100644
index 4275f8421..000000000
--- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_openbsd.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build openbsd
-
-package remote
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func interceptorDupx(oldfd int, newfd int) {
- unix.Dup2(oldfd, newfd)
-}
diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_solaris.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_solaris.go
deleted file mode 100644
index 882a38a9e..000000000
--- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_solaris.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build solaris
-
-package remote
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func interceptorDupx(oldfd int, newfd int) {
- unix.Dup2(oldfd, newfd)
-}
diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go
index 80614d0ce..774967db6 100644
--- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go
+++ b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go
@@ -8,6 +8,7 @@ import (
"os"
"github.com/nxadm/tail"
+ "golang.org/x/sys/unix"
)
func NewOutputInterceptor() OutputInterceptor {
@@ -35,8 +36,10 @@ func (interceptor *outputInterceptor) StartInterceptingOutput() error {
return err
}
- interceptorDupx(int(interceptor.redirectFile.Fd()), 1)
- interceptorDupx(int(interceptor.redirectFile.Fd()), 2)
+ // This might call Dup3 if the dup2 syscall is not available, e.g. on
+ // linux/arm64 or linux/riscv64
+ unix.Dup2(int(interceptor.redirectFile.Fd()), 1)
+ unix.Dup2(int(interceptor.redirectFile.Fd()), 2)
if interceptor.streamTarget != nil {
interceptor.tailer, _ = tail.TailFile(interceptor.redirectFile.Name(), tail.Config{Follow: true})
diff --git a/vendor/github.com/onsi/ginkgo/internal/spec/specs.go b/vendor/github.com/onsi/ginkgo/internal/spec/specs.go
index 8a2007137..0a24139fb 100644
--- a/vendor/github.com/onsi/ginkgo/internal/spec/specs.go
+++ b/vendor/github.com/onsi/ginkgo/internal/spec/specs.go
@@ -4,6 +4,7 @@ import (
"math/rand"
"regexp"
"sort"
+ "strings"
)
type Specs struct {
@@ -46,11 +47,11 @@ func (e *Specs) Shuffle(r *rand.Rand) {
e.names = names
}
-func (e *Specs) ApplyFocus(description string, focusString string, skipString string) {
- if focusString == "" && skipString == "" {
+func (e *Specs) ApplyFocus(description string, focus, skip []string) {
+ if len(focus)+len(skip) == 0 {
e.applyProgrammaticFocus()
} else {
- e.applyRegExpFocusAndSkip(description, focusString, skipString)
+ e.applyRegExpFocusAndSkip(description, focus, skip)
}
}
@@ -90,14 +91,13 @@ func (e *Specs) toMatch(description string, i int) []byte {
}
}
-func (e *Specs) applyRegExpFocusAndSkip(description string, focusString string, skipString string) {
- var focusFilter *regexp.Regexp
- if focusString != "" {
- focusFilter = regexp.MustCompile(focusString)
+func (e *Specs) applyRegExpFocusAndSkip(description string, focus, skip []string) {
+ var focusFilter, skipFilter *regexp.Regexp
+ if len(focus) > 0 {
+ focusFilter = regexp.MustCompile(strings.Join(focus, "|"))
}
- var skipFilter *regexp.Regexp
- if skipString != "" {
- skipFilter = regexp.MustCompile(skipString)
+ if len(skip) > 0 {
+ skipFilter = regexp.MustCompile(strings.Join(skip, "|"))
}
for i, spec := range e.specs {
diff --git a/vendor/github.com/onsi/ginkgo/internal/suite/suite.go b/vendor/github.com/onsi/ginkgo/internal/suite/suite.go
index e75da1f89..b4a83c432 100644
--- a/vendor/github.com/onsi/ginkgo/internal/suite/suite.go
+++ b/vendor/github.com/onsi/ginkgo/internal/suite/suite.go
@@ -97,7 +97,7 @@ func (suite *Suite) generateSpecsIterator(description string, config config.Gink
specs.Shuffle(rand.New(rand.NewSource(config.RandomSeed)))
}
- specs.ApplyFocus(description, config.FocusString, config.SkipString)
+ specs.ApplyFocus(description, config.FocusStrings, config.SkipStrings)
if config.SkipMeasurements {
specs.SkipMeasurements()
diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md
index 0f1765d84..16095fa3c 100644
--- a/vendor/github.com/onsi/gomega/CHANGELOG.md
+++ b/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 1.10.5
+
+### Fixes
+- fix: collections matchers should display type of expectation (#408) [6b4eb5a]
+- fix(ContainElements): consistently flatten expected values [073b880]
+- fix(ConsistOf): consistently flatten expected values [7266efe]
+
## 1.10.4
### Fixes
diff --git a/vendor/github.com/onsi/gomega/go.mod b/vendor/github.com/onsi/gomega/go.mod
index 02b99ab60..6f853a579 100644
--- a/vendor/github.com/onsi/gomega/go.mod
+++ b/vendor/github.com/onsi/gomega/go.mod
@@ -6,6 +6,5 @@ require (
github.com/golang/protobuf v1.4.2
github.com/onsi/ginkgo v1.12.1
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
- golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
gopkg.in/yaml.v2 v2.3.0
)
diff --git a/vendor/github.com/onsi/gomega/go.sum b/vendor/github.com/onsi/gomega/go.sum
index fc230153b..54eeacd2b 100644
--- a/vendor/github.com/onsi/gomega/go.sum
+++ b/vendor/github.com/onsi/gomega/go.sum
@@ -27,10 +27,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
-golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M=
-golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
@@ -42,8 +38,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go
index a8529f1ca..1bc5288b8 100644
--- a/vendor/github.com/onsi/gomega/gomega_dsl.go
+++ b/vendor/github.com/onsi/gomega/gomega_dsl.go
@@ -24,7 +24,7 @@ import (
"github.com/onsi/gomega/types"
)
-const GOMEGA_VERSION = "1.10.4"
+const GOMEGA_VERSION = "1.10.5"
const nilFailHandlerPanic = `You are trying to make an assertion, but Gomega's fail handler is nil.
If you're using Ginkgo then you probably forgot to put your assertion in an It().
diff --git a/vendor/github.com/onsi/gomega/matchers/consist_of.go b/vendor/github.com/onsi/gomega/matchers/consist_of.go
index e453b22d1..e8ef0dee1 100644
--- a/vendor/github.com/onsi/gomega/matchers/consist_of.go
+++ b/vendor/github.com/onsi/gomega/matchers/consist_of.go
@@ -57,17 +57,21 @@ func equalMatchersToElements(matchers []interface{}) (elements []interface{}) {
return
}
-func matchers(expectedElems []interface{}) (matchers []interface{}) {
- elems := expectedElems
- if len(expectedElems) == 1 && isArrayOrSlice(expectedElems[0]) {
- elems = []interface{}{}
- value := reflect.ValueOf(expectedElems[0])
- for i := 0; i < value.Len(); i++ {
- elems = append(elems, value.Index(i).Interface())
- }
+func flatten(elems []interface{}) []interface{} {
+ if len(elems) != 1 || !isArrayOrSlice(elems[0]) {
+ return elems
}
- for _, e := range elems {
+ value := reflect.ValueOf(elems[0])
+ flattened := make([]interface{}, value.Len())
+ for i := 0; i < value.Len(); i++ {
+ flattened[i] = value.Index(i).Interface()
+ }
+ return flattened
+}
+
+func matchers(expectedElems []interface{}) (matchers []interface{}) {
+ for _, e := range flatten(expectedElems) {
matcher, isMatcher := e.(omegaMatcher)
if !isMatcher {
matcher = &EqualMatcher{Expected: e}
@@ -77,6 +81,29 @@ func matchers(expectedElems []interface{}) (matchers []interface{}) {
return
}
+func presentable(elems []interface{}) interface{} {
+ elems = flatten(elems)
+
+ if len(elems) == 0 {
+ return []interface{}{}
+ }
+
+ sv := reflect.ValueOf(elems)
+ tt := sv.Index(0).Elem().Type()
+ for i := 1; i < sv.Len(); i++ {
+ if sv.Index(i).Elem().Type() != tt {
+ return elems
+ }
+ }
+
+ ss := reflect.MakeSlice(reflect.SliceOf(tt), sv.Len(), sv.Len())
+ for i := 0; i < sv.Len(); i++ {
+ ss.Index(i).Set(sv.Index(i).Elem())
+ }
+
+ return ss.Interface()
+}
+
func valuesOf(actual interface{}) []interface{} {
value := reflect.ValueOf(actual)
values := []interface{}{}
@@ -95,11 +122,11 @@ func valuesOf(actual interface{}) []interface{} {
}
func (matcher *ConsistOfMatcher) FailureMessage(actual interface{}) (message string) {
- message = format.Message(actual, "to consist of", matcher.Elements)
+ message = format.Message(actual, "to consist of", presentable(matcher.Elements))
message = appendMissingElements(message, matcher.missingElements)
if len(matcher.extraElements) > 0 {
message = fmt.Sprintf("%s\nthe extra elements were\n%s", message,
- format.Object(matcher.extraElements, 1))
+ format.Object(presentable(matcher.extraElements), 1))
}
return
}
@@ -109,9 +136,9 @@ func appendMissingElements(message string, missingElements []interface{}) string
return message
}
return fmt.Sprintf("%s\nthe missing elements were\n%s", message,
- format.Object(missingElements, 1))
+ format.Object(presentable(missingElements), 1))
}
func (matcher *ConsistOfMatcher) NegatedFailureMessage(actual interface{}) (message string) {
- return format.Message(actual, "not to consist of", matcher.Elements)
+ return format.Message(actual, "not to consist of", presentable(matcher.Elements))
}
diff --git a/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go b/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go
index 19a9e78f8..946cd8bea 100644
--- a/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go
+++ b/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go
@@ -35,10 +35,10 @@ func (matcher *ContainElementsMatcher) Match(actual interface{}) (success bool,
}
func (matcher *ContainElementsMatcher) FailureMessage(actual interface{}) (message string) {
- message = format.Message(actual, "to contain elements", matcher.Elements)
+ message = format.Message(actual, "to contain elements", presentable(matcher.Elements))
return appendMissingElements(message, matcher.missingElements)
}
func (matcher *ContainElementsMatcher) NegatedFailureMessage(actual interface{}) (message string) {
- return format.Message(actual, "not to contain elements", matcher.Elements)
+ return format.Message(actual, "not to contain elements", presentable(matcher.Elements))
}
diff --git a/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go b/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go
index 4e09239ff..c8993a86d 100644
--- a/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go
+++ b/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go
@@ -1,11 +1,11 @@
package matchers
import (
+ "errors"
"fmt"
"reflect"
"github.com/onsi/gomega/format"
- "golang.org/x/xerrors"
)
type MatchErrorMatcher struct {
@@ -25,7 +25,7 @@ func (matcher *MatchErrorMatcher) Match(actual interface{}) (success bool, err e
expected := matcher.Expected
if isError(expected) {
- return reflect.DeepEqual(actualErr, expected) || xerrors.Is(actualErr, expected.(error)), nil
+ return reflect.DeepEqual(actualErr, expected) || errors.Is(actualErr, expected.(error)), nil
}
if isString(expected) {
diff --git a/vendor/golang.org/x/tools/AUTHORS b/vendor/golang.org/x/tools/AUTHORS
new file mode 100644
index 000000000..15167cd74
--- /dev/null
+++ b/vendor/golang.org/x/tools/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/tools/CONTRIBUTORS b/vendor/golang.org/x/tools/CONTRIBUTORS
new file mode 100644
index 000000000..1c4577e96
--- /dev/null
+++ b/vendor/golang.org/x/tools/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/xerrors/LICENSE b/vendor/golang.org/x/tools/LICENSE
index e4a47e17f..6a66aea5e 100644
--- a/vendor/golang.org/x/xerrors/LICENSE
+++ b/vendor/golang.org/x/tools/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019 The Go Authors. All rights reserved.
+Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
diff --git a/vendor/golang.org/x/xerrors/PATENTS b/vendor/golang.org/x/tools/PATENTS
index 733099041..733099041 100644
--- a/vendor/golang.org/x/xerrors/PATENTS
+++ b/vendor/golang.org/x/tools/PATENTS
diff --git a/vendor/golang.org/x/tools/go/ast/inspector/inspector.go b/vendor/golang.org/x/tools/go/ast/inspector/inspector.go
new file mode 100644
index 000000000..af5e17fee
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ast/inspector/inspector.go
@@ -0,0 +1,186 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package inspector provides helper functions for traversal over the
+// syntax trees of a package, including node filtering by type, and
+// materialization of the traversal stack.
+//
+// During construction, the inspector does a complete traversal and
+// builds a list of push/pop events and their node type. Subsequent
+// method calls that request a traversal scan this list, rather than walk
+// the AST, and perform type filtering using efficient bit sets.
+//
+// Experiments suggest the inspector's traversals are about 2.5x faster
+// than ast.Inspect, but it may take around 5 traversals for this
+// benefit to amortize the inspector's construction cost.
+// If efficiency is the primary concern, do not use Inspector for
+// one-off traversals.
+package inspector
+
+// There are four orthogonal features in a traversal:
+// 1 type filtering
+// 2 pruning
+// 3 postorder calls to f
+// 4 stack
+// Rather than offer all of them in the API,
+// only a few combinations are exposed:
+// - Preorder is the fastest and has fewest features,
+// but is the most commonly needed traversal.
+// - Nodes and WithStack both provide pruning and postorder calls,
+// even though few clients need it, because supporting two versions
+// is not justified.
+// More combinations could be supported by expressing them as
+// wrappers around a more generic traversal, but this was measured
+// and found to degrade performance significantly (30%).
+
+import (
+ "go/ast"
+)
+
+// An Inspector provides methods for inspecting
+// (traversing) the syntax trees of a package.
+type Inspector struct {
+ events []event
+}
+
+// New returns an Inspector for the specified syntax trees.
+func New(files []*ast.File) *Inspector {
+ return &Inspector{traverse(files)}
+}
+
+// An event represents a push or a pop
+// of an ast.Node during a traversal.
+type event struct {
+ node ast.Node
+ typ uint64 // typeOf(node)
+ index int // 1 + index of corresponding pop event, or 0 if this is a pop
+}
+
+// Preorder visits all the nodes of the files supplied to New in
+// depth-first order. It calls f(n) for each node n before it visits
+// n's children.
+//
+// The types argument, if non-empty, enables type-based filtering of
+// events. The function f if is called only for nodes whose type
+// matches an element of the types slice.
+func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) {
+ // Because it avoids postorder calls to f, and the pruning
+ // check, Preorder is almost twice as fast as Nodes. The two
+ // features seem to contribute similar slowdowns (~1.4x each).
+
+ mask := maskOf(types)
+ for i := 0; i < len(in.events); {
+ ev := in.events[i]
+ if ev.typ&mask != 0 {
+ if ev.index > 0 {
+ f(ev.node)
+ }
+ }
+ i++
+ }
+}
+
+// Nodes visits the nodes of the files supplied to New in depth-first
+// order. It calls f(n, true) for each node n before it visits n's
+// children. If f returns true, Nodes invokes f recursively for each
+// of the non-nil children of the node, followed by a call of
+// f(n, false).
+//
+// The types argument, if non-empty, enables type-based filtering of
+// events. The function f if is called only for nodes whose type
+// matches an element of the types slice.
+func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proceed bool)) {
+ mask := maskOf(types)
+ for i := 0; i < len(in.events); {
+ ev := in.events[i]
+ if ev.typ&mask != 0 {
+ if ev.index > 0 {
+ // push
+ if !f(ev.node, true) {
+ i = ev.index // jump to corresponding pop + 1
+ continue
+ }
+ } else {
+ // pop
+ f(ev.node, false)
+ }
+ }
+ i++
+ }
+}
+
+// WithStack visits nodes in a similar manner to Nodes, but it
+// supplies each call to f an additional argument, the current
+// traversal stack. The stack's first element is the outermost node,
+// an *ast.File; its last is the innermost, n.
+func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (proceed bool)) {
+ mask := maskOf(types)
+ var stack []ast.Node
+ for i := 0; i < len(in.events); {
+ ev := in.events[i]
+ if ev.index > 0 {
+ // push
+ stack = append(stack, ev.node)
+ if ev.typ&mask != 0 {
+ if !f(ev.node, true, stack) {
+ i = ev.index
+ stack = stack[:len(stack)-1]
+ continue
+ }
+ }
+ } else {
+ // pop
+ if ev.typ&mask != 0 {
+ f(ev.node, false, stack)
+ }
+ stack = stack[:len(stack)-1]
+ }
+ i++
+ }
+}
+
+// traverse builds the table of events representing a traversal.
+func traverse(files []*ast.File) []event {
+ // Preallocate approximate number of events
+ // based on source file extent.
+ // This makes traverse faster by 4x (!).
+ var extent int
+ for _, f := range files {
+ extent += int(f.End() - f.Pos())
+ }
+ // This estimate is based on the net/http package.
+ capacity := extent * 33 / 100
+ if capacity > 1e6 {
+ capacity = 1e6 // impose some reasonable maximum
+ }
+ events := make([]event, 0, capacity)
+
+ var stack []event
+ for _, f := range files {
+ ast.Inspect(f, func(n ast.Node) bool {
+ if n != nil {
+ // push
+ ev := event{
+ node: n,
+ typ: typeOf(n),
+ index: len(events), // push event temporarily holds own index
+ }
+ stack = append(stack, ev)
+ events = append(events, ev)
+ } else {
+ // pop
+ ev := stack[len(stack)-1]
+ stack = stack[:len(stack)-1]
+
+ events[ev.index].index = len(events) + 1 // make push refer to pop
+
+ ev.index = 0 // turn ev into a pop event
+ events = append(events, ev)
+ }
+ return true
+ })
+ }
+
+ return events
+}
diff --git a/vendor/golang.org/x/tools/go/ast/inspector/typeof.go b/vendor/golang.org/x/tools/go/ast/inspector/typeof.go
new file mode 100644
index 000000000..d61301b13
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ast/inspector/typeof.go
@@ -0,0 +1,216 @@
+package inspector
+
+// This file defines func typeOf(ast.Node) uint64.
+//
+// The initial map-based implementation was too slow;
+// see https://go-review.googlesource.com/c/tools/+/135655/1/go/ast/inspector/inspector.go#196
+
+import "go/ast"
+
+const (
+ nArrayType = iota
+ nAssignStmt
+ nBadDecl
+ nBadExpr
+ nBadStmt
+ nBasicLit
+ nBinaryExpr
+ nBlockStmt
+ nBranchStmt
+ nCallExpr
+ nCaseClause
+ nChanType
+ nCommClause
+ nComment
+ nCommentGroup
+ nCompositeLit
+ nDeclStmt
+ nDeferStmt
+ nEllipsis
+ nEmptyStmt
+ nExprStmt
+ nField
+ nFieldList
+ nFile
+ nForStmt
+ nFuncDecl
+ nFuncLit
+ nFuncType
+ nGenDecl
+ nGoStmt
+ nIdent
+ nIfStmt
+ nImportSpec
+ nIncDecStmt
+ nIndexExpr
+ nInterfaceType
+ nKeyValueExpr
+ nLabeledStmt
+ nMapType
+ nPackage
+ nParenExpr
+ nRangeStmt
+ nReturnStmt
+ nSelectStmt
+ nSelectorExpr
+ nSendStmt
+ nSliceExpr
+ nStarExpr
+ nStructType
+ nSwitchStmt
+ nTypeAssertExpr
+ nTypeSpec
+ nTypeSwitchStmt
+ nUnaryExpr
+ nValueSpec
+)
+
+// typeOf returns a distinct single-bit value that represents the type of n.
+//
+// Various implementations were benchmarked with BenchmarkNewInspector:
+// GOGC=off
+// - type switch 4.9-5.5ms 2.1ms
+// - binary search over a sorted list of types 5.5-5.9ms 2.5ms
+// - linear scan, frequency-ordered list 5.9-6.1ms 2.7ms
+// - linear scan, unordered list 6.4ms 2.7ms
+// - hash table 6.5ms 3.1ms
+// A perfect hash seemed like overkill.
+//
+// The compiler's switch statement is the clear winner
+// as it produces a binary tree in code,
+// with constant conditions and good branch prediction.
+// (Sadly it is the most verbose in source code.)
+// Binary search suffered from poor branch prediction.
+//
+func typeOf(n ast.Node) uint64 {
+ // Fast path: nearly half of all nodes are identifiers.
+ if _, ok := n.(*ast.Ident); ok {
+ return 1 << nIdent
+ }
+
+ // These cases include all nodes encountered by ast.Inspect.
+ switch n.(type) {
+ case *ast.ArrayType:
+ return 1 << nArrayType
+ case *ast.AssignStmt:
+ return 1 << nAssignStmt
+ case *ast.BadDecl:
+ return 1 << nBadDecl
+ case *ast.BadExpr:
+ return 1 << nBadExpr
+ case *ast.BadStmt:
+ return 1 << nBadStmt
+ case *ast.BasicLit:
+ return 1 << nBasicLit
+ case *ast.BinaryExpr:
+ return 1 << nBinaryExpr
+ case *ast.BlockStmt:
+ return 1 << nBlockStmt
+ case *ast.BranchStmt:
+ return 1 << nBranchStmt
+ case *ast.CallExpr:
+ return 1 << nCallExpr
+ case *ast.CaseClause:
+ return 1 << nCaseClause
+ case *ast.ChanType:
+ return 1 << nChanType
+ case *ast.CommClause:
+ return 1 << nCommClause
+ case *ast.Comment:
+ return 1 << nComment
+ case *ast.CommentGroup:
+ return 1 << nCommentGroup
+ case *ast.CompositeLit:
+ return 1 << nCompositeLit
+ case *ast.DeclStmt:
+ return 1 << nDeclStmt
+ case *ast.DeferStmt:
+ return 1 << nDeferStmt
+ case *ast.Ellipsis:
+ return 1 << nEllipsis
+ case *ast.EmptyStmt:
+ return 1 << nEmptyStmt
+ case *ast.ExprStmt:
+ return 1 << nExprStmt
+ case *ast.Field:
+ return 1 << nField
+ case *ast.FieldList:
+ return 1 << nFieldList
+ case *ast.File:
+ return 1 << nFile
+ case *ast.ForStmt:
+ return 1 << nForStmt
+ case *ast.FuncDecl:
+ return 1 << nFuncDecl
+ case *ast.FuncLit:
+ return 1 << nFuncLit
+ case *ast.FuncType:
+ return 1 << nFuncType
+ case *ast.GenDecl:
+ return 1 << nGenDecl
+ case *ast.GoStmt:
+ return 1 << nGoStmt
+ case *ast.Ident:
+ return 1 << nIdent
+ case *ast.IfStmt:
+ return 1 << nIfStmt
+ case *ast.ImportSpec:
+ return 1 << nImportSpec
+ case *ast.IncDecStmt:
+ return 1 << nIncDecStmt
+ case *ast.IndexExpr:
+ return 1 << nIndexExpr
+ case *ast.InterfaceType:
+ return 1 << nInterfaceType
+ case *ast.KeyValueExpr:
+ return 1 << nKeyValueExpr
+ case *ast.LabeledStmt:
+ return 1 << nLabeledStmt
+ case *ast.MapType:
+ return 1 << nMapType
+ case *ast.Package:
+ return 1 << nPackage
+ case *ast.ParenExpr:
+ return 1 << nParenExpr
+ case *ast.RangeStmt:
+ return 1 << nRangeStmt
+ case *ast.ReturnStmt:
+ return 1 << nReturnStmt
+ case *ast.SelectStmt:
+ return 1 << nSelectStmt
+ case *ast.SelectorExpr:
+ return 1 << nSelectorExpr
+ case *ast.SendStmt:
+ return 1 << nSendStmt
+ case *ast.SliceExpr:
+ return 1 << nSliceExpr
+ case *ast.StarExpr:
+ return 1 << nStarExpr
+ case *ast.StructType:
+ return 1 << nStructType
+ case *ast.SwitchStmt:
+ return 1 << nSwitchStmt
+ case *ast.TypeAssertExpr:
+ return 1 << nTypeAssertExpr
+ case *ast.TypeSpec:
+ return 1 << nTypeSpec
+ case *ast.TypeSwitchStmt:
+ return 1 << nTypeSwitchStmt
+ case *ast.UnaryExpr:
+ return 1 << nUnaryExpr
+ case *ast.ValueSpec:
+ return 1 << nValueSpec
+ }
+ return 0
+}
+
+func maskOf(nodes []ast.Node) uint64 {
+ if nodes == nil {
+ return 1<<64 - 1 // match all node types
+ }
+ var mask uint64
+ for _, n := range nodes {
+ mask |= typeOf(n)
+ }
+ return mask
+}
diff --git a/vendor/golang.org/x/xerrors/README b/vendor/golang.org/x/xerrors/README
deleted file mode 100644
index aac7867a5..000000000
--- a/vendor/golang.org/x/xerrors/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This repository holds the transition packages for the new Go 1.13 error values.
-See golang.org/design/29934-error-values.
diff --git a/vendor/golang.org/x/xerrors/adaptor.go b/vendor/golang.org/x/xerrors/adaptor.go
deleted file mode 100644
index 4317f2483..000000000
--- a/vendor/golang.org/x/xerrors/adaptor.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package xerrors
-
-import (
- "bytes"
- "fmt"
- "io"
- "reflect"
- "strconv"
-)
-
-// FormatError calls the FormatError method of f with an errors.Printer
-// configured according to s and verb, and writes the result to s.
-func FormatError(f Formatter, s fmt.State, verb rune) {
- // Assuming this function is only called from the Format method, and given
- // that FormatError takes precedence over Format, it cannot be called from
- // any package that supports errors.Formatter. It is therefore safe to
- // disregard that State may be a specific printer implementation and use one
- // of our choice instead.
-
- // limitations: does not support printing error as Go struct.
-
- var (
- sep = " " // separator before next error
- p = &state{State: s}
- direct = true
- )
-
- var err error = f
-
- switch verb {
- // Note that this switch must match the preference order
- // for ordinary string printing (%#v before %+v, and so on).
-
- case 'v':
- if s.Flag('#') {
- if stringer, ok := err.(fmt.GoStringer); ok {
- io.WriteString(&p.buf, stringer.GoString())
- goto exit
- }
- // proceed as if it were %v
- } else if s.Flag('+') {
- p.printDetail = true
- sep = "\n - "
- }
- case 's':
- case 'q', 'x', 'X':
- // Use an intermediate buffer in the rare cases that precision,
- // truncation, or one of the alternative verbs (q, x, and X) are
- // specified.
- direct = false
-
- default:
- p.buf.WriteString("%!")
- p.buf.WriteRune(verb)
- p.buf.WriteByte('(')
- switch {
- case err != nil:
- p.buf.WriteString(reflect.TypeOf(f).String())
- default:
- p.buf.WriteString("<nil>")
- }
- p.buf.WriteByte(')')
- io.Copy(s, &p.buf)
- return
- }
-
-loop:
- for {
- switch v := err.(type) {
- case Formatter:
- err = v.FormatError((*printer)(p))
- case fmt.Formatter:
- v.Format(p, 'v')
- break loop
- default:
- io.WriteString(&p.buf, v.Error())
- break loop
- }
- if err == nil {
- break
- }
- if p.needColon || !p.printDetail {
- p.buf.WriteByte(':')
- p.needColon = false
- }
- p.buf.WriteString(sep)
- p.inDetail = false
- p.needNewline = false
- }
-
-exit:
- width, okW := s.Width()
- prec, okP := s.Precision()
-
- if !direct || (okW && width > 0) || okP {
- // Construct format string from State s.
- format := []byte{'%'}
- if s.Flag('-') {
- format = append(format, '-')
- }
- if s.Flag('+') {
- format = append(format, '+')
- }
- if s.Flag(' ') {
- format = append(format, ' ')
- }
- if okW {
- format = strconv.AppendInt(format, int64(width), 10)
- }
- if okP {
- format = append(format, '.')
- format = strconv.AppendInt(format, int64(prec), 10)
- }
- format = append(format, string(verb)...)
- fmt.Fprintf(s, string(format), p.buf.String())
- } else {
- io.Copy(s, &p.buf)
- }
-}
-
-var detailSep = []byte("\n ")
-
-// state tracks error printing state. It implements fmt.State.
-type state struct {
- fmt.State
- buf bytes.Buffer
-
- printDetail bool
- inDetail bool
- needColon bool
- needNewline bool
-}
-
-func (s *state) Write(b []byte) (n int, err error) {
- if s.printDetail {
- if len(b) == 0 {
- return 0, nil
- }
- if s.inDetail && s.needColon {
- s.needNewline = true
- if b[0] == '\n' {
- b = b[1:]
- }
- }
- k := 0
- for i, c := range b {
- if s.needNewline {
- if s.inDetail && s.needColon {
- s.buf.WriteByte(':')
- s.needColon = false
- }
- s.buf.Write(detailSep)
- s.needNewline = false
- }
- if c == '\n' {
- s.buf.Write(b[k:i])
- k = i + 1
- s.needNewline = true
- }
- }
- s.buf.Write(b[k:])
- if !s.inDetail {
- s.needColon = true
- }
- } else if !s.inDetail {
- s.buf.Write(b)
- }
- return len(b), nil
-}
-
-// printer wraps a state to implement an xerrors.Printer.
-type printer state
-
-func (s *printer) Print(args ...interface{}) {
- if !s.inDetail || s.printDetail {
- fmt.Fprint((*state)(s), args...)
- }
-}
-
-func (s *printer) Printf(format string, args ...interface{}) {
- if !s.inDetail || s.printDetail {
- fmt.Fprintf((*state)(s), format, args...)
- }
-}
-
-func (s *printer) Detail() bool {
- s.inDetail = true
- return s.printDetail
-}
diff --git a/vendor/golang.org/x/xerrors/codereview.cfg b/vendor/golang.org/x/xerrors/codereview.cfg
deleted file mode 100644
index 3f8b14b64..000000000
--- a/vendor/golang.org/x/xerrors/codereview.cfg
+++ /dev/null
@@ -1 +0,0 @@
-issuerepo: golang/go
diff --git a/vendor/golang.org/x/xerrors/doc.go b/vendor/golang.org/x/xerrors/doc.go
deleted file mode 100644
index eef99d9d5..000000000
--- a/vendor/golang.org/x/xerrors/doc.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package xerrors implements functions to manipulate errors.
-//
-// This package is based on the Go 2 proposal for error values:
-// https://golang.org/design/29934-error-values
-//
-// These functions were incorporated into the standard library's errors package
-// in Go 1.13:
-// - Is
-// - As
-// - Unwrap
-//
-// Also, Errorf's %w verb was incorporated into fmt.Errorf.
-//
-// Use this package to get equivalent behavior in all supported Go versions.
-//
-// No other features of this package were included in Go 1.13, and at present
-// there are no plans to include any of them.
-package xerrors // import "golang.org/x/xerrors"
diff --git a/vendor/golang.org/x/xerrors/errors.go b/vendor/golang.org/x/xerrors/errors.go
deleted file mode 100644
index e88d3772d..000000000
--- a/vendor/golang.org/x/xerrors/errors.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package xerrors
-
-import "fmt"
-
-// errorString is a trivial implementation of error.
-type errorString struct {
- s string
- frame Frame
-}
-
-// New returns an error that formats as the given text.
-//
-// The returned error contains a Frame set to the caller's location and
-// implements Formatter to show this information when printed with details.
-func New(text string) error {
- return &errorString{text, Caller(1)}
-}
-
-func (e *errorString) Error() string {
- return e.s
-}
-
-func (e *errorString) Format(s fmt.State, v rune) { FormatError(e, s, v) }
-
-func (e *errorString) FormatError(p Printer) (next error) {
- p.Print(e.s)
- e.frame.Format(p)
- return nil
-}
diff --git a/vendor/golang.org/x/xerrors/fmt.go b/vendor/golang.org/x/xerrors/fmt.go
deleted file mode 100644
index 829862ddf..000000000
--- a/vendor/golang.org/x/xerrors/fmt.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package xerrors
-
-import (
- "fmt"
- "strings"
- "unicode"
- "unicode/utf8"
-
- "golang.org/x/xerrors/internal"
-)
-
-const percentBangString = "%!"
-
-// Errorf formats according to a format specifier and returns the string as a
-// value that satisfies error.
-//
-// The returned error includes the file and line number of the caller when
-// formatted with additional detail enabled. If the last argument is an error
-// the returned error's Format method will return it if the format string ends
-// with ": %s", ": %v", or ": %w". If the last argument is an error and the
-// format string ends with ": %w", the returned error implements an Unwrap
-// method returning it.
-//
-// If the format specifier includes a %w verb with an error operand in a
-// position other than at the end, the returned error will still implement an
-// Unwrap method returning the operand, but the error's Format method will not
-// return the wrapped error.
-//
-// It is invalid to include more than one %w verb or to supply it with an
-// operand that does not implement the error interface. The %w verb is otherwise
-// a synonym for %v.
-func Errorf(format string, a ...interface{}) error {
- format = formatPlusW(format)
- // Support a ": %[wsv]" suffix, which works well with xerrors.Formatter.
- wrap := strings.HasSuffix(format, ": %w")
- idx, format2, ok := parsePercentW(format)
- percentWElsewhere := !wrap && idx >= 0
- if !percentWElsewhere && (wrap || strings.HasSuffix(format, ": %s") || strings.HasSuffix(format, ": %v")) {
- err := errorAt(a, len(a)-1)
- if err == nil {
- return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)}
- }
- // TODO: this is not entirely correct. The error value could be
- // printed elsewhere in format if it mixes numbered with unnumbered
- // substitutions. With relatively small changes to doPrintf we can
- // have it optionally ignore extra arguments and pass the argument
- // list in its entirety.
- msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...)
- frame := Frame{}
- if internal.EnableTrace {
- frame = Caller(1)
- }
- if wrap {
- return &wrapError{msg, err, frame}
- }
- return &noWrapError{msg, err, frame}
- }
- // Support %w anywhere.
- // TODO: don't repeat the wrapped error's message when %w occurs in the middle.
- msg := fmt.Sprintf(format2, a...)
- if idx < 0 {
- return &noWrapError{msg, nil, Caller(1)}
- }
- err := errorAt(a, idx)
- if !ok || err == nil {
- // Too many %ws or argument of %w is not an error. Approximate the Go
- // 1.13 fmt.Errorf message.
- return &noWrapError{fmt.Sprintf("%sw(%s)", percentBangString, msg), nil, Caller(1)}
- }
- frame := Frame{}
- if internal.EnableTrace {
- frame = Caller(1)
- }
- return &wrapError{msg, err, frame}
-}
-
-func errorAt(args []interface{}, i int) error {
- if i < 0 || i >= len(args) {
- return nil
- }
- err, ok := args[i].(error)
- if !ok {
- return nil
- }
- return err
-}
-
-// formatPlusW is used to avoid the vet check that will barf at %w.
-func formatPlusW(s string) string {
- return s
-}
-
-// Return the index of the only %w in format, or -1 if none.
-// Also return a rewritten format string with %w replaced by %v, and
-// false if there is more than one %w.
-// TODO: handle "%[N]w".
-func parsePercentW(format string) (idx int, newFormat string, ok bool) {
- // Loosely copied from golang.org/x/tools/go/analysis/passes/printf/printf.go.
- idx = -1
- ok = true
- n := 0
- sz := 0
- var isW bool
- for i := 0; i < len(format); i += sz {
- if format[i] != '%' {
- sz = 1
- continue
- }
- // "%%" is not a format directive.
- if i+1 < len(format) && format[i+1] == '%' {
- sz = 2
- continue
- }
- sz, isW = parsePrintfVerb(format[i:])
- if isW {
- if idx >= 0 {
- ok = false
- } else {
- idx = n
- }
- // "Replace" the last character, the 'w', with a 'v'.
- p := i + sz - 1
- format = format[:p] + "v" + format[p+1:]
- }
- n++
- }
- return idx, format, ok
-}
-
-// Parse the printf verb starting with a % at s[0].
-// Return how many bytes it occupies and whether the verb is 'w'.
-func parsePrintfVerb(s string) (int, bool) {
- // Assume only that the directive is a sequence of non-letters followed by a single letter.
- sz := 0
- var r rune
- for i := 1; i < len(s); i += sz {
- r, sz = utf8.DecodeRuneInString(s[i:])
- if unicode.IsLetter(r) {
- return i + sz, r == 'w'
- }
- }
- return len(s), false
-}
-
-type noWrapError struct {
- msg string
- err error
- frame Frame
-}
-
-func (e *noWrapError) Error() string {
- return fmt.Sprint(e)
-}
-
-func (e *noWrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) }
-
-func (e *noWrapError) FormatError(p Printer) (next error) {
- p.Print(e.msg)
- e.frame.Format(p)
- return e.err
-}
-
-type wrapError struct {
- msg string
- err error
- frame Frame
-}
-
-func (e *wrapError) Error() string {
- return fmt.Sprint(e)
-}
-
-func (e *wrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) }
-
-func (e *wrapError) FormatError(p Printer) (next error) {
- p.Print(e.msg)
- e.frame.Format(p)
- return e.err
-}
-
-func (e *wrapError) Unwrap() error {
- return e.err
-}
diff --git a/vendor/golang.org/x/xerrors/format.go b/vendor/golang.org/x/xerrors/format.go
deleted file mode 100644
index 1bc9c26b9..000000000
--- a/vendor/golang.org/x/xerrors/format.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package xerrors
-
-// A Formatter formats error messages.
-type Formatter interface {
- error
-
- // FormatError prints the receiver's first error and returns the next error in
- // the error chain, if any.
- FormatError(p Printer) (next error)
-}
-
-// A Printer formats error messages.
-//
-// The most common implementation of Printer is the one provided by package fmt
-// during Printf (as of Go 1.13). Localization packages such as golang.org/x/text/message
-// typically provide their own implementations.
-type Printer interface {
- // Print appends args to the message output.
- Print(args ...interface{})
-
- // Printf writes a formatted string.
- Printf(format string, args ...interface{})
-
- // Detail reports whether error detail is requested.
- // After the first call to Detail, all text written to the Printer
- // is formatted as additional detail, or ignored when
- // detail has not been requested.
- // If Detail returns false, the caller can avoid printing the detail at all.
- Detail() bool
-}
diff --git a/vendor/golang.org/x/xerrors/frame.go b/vendor/golang.org/x/xerrors/frame.go
deleted file mode 100644
index 0de628ec5..000000000
--- a/vendor/golang.org/x/xerrors/frame.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package xerrors
-
-import (
- "runtime"
-)
-
-// A Frame contains part of a call stack.
-type Frame struct {
- // Make room for three PCs: the one we were asked for, what it called,
- // and possibly a PC for skipPleaseUseCallersFrames. See:
- // https://go.googlesource.com/go/+/032678e0fb/src/runtime/extern.go#169
- frames [3]uintptr
-}
-
-// Caller returns a Frame that describes a frame on the caller's stack.
-// The argument skip is the number of frames to skip over.
-// Caller(0) returns the frame for the caller of Caller.
-func Caller(skip int) Frame {
- var s Frame
- runtime.Callers(skip+1, s.frames[:])
- return s
-}
-
-// location reports the file, line, and function of a frame.
-//
-// The returned function may be "" even if file and line are not.
-func (f Frame) location() (function, file string, line int) {
- frames := runtime.CallersFrames(f.frames[:])
- if _, ok := frames.Next(); !ok {
- return "", "", 0
- }
- fr, ok := frames.Next()
- if !ok {
- return "", "", 0
- }
- return fr.Function, fr.File, fr.Line
-}
-
-// Format prints the stack as error detail.
-// It should be called from an error's Format implementation
-// after printing any other error detail.
-func (f Frame) Format(p Printer) {
- if p.Detail() {
- function, file, line := f.location()
- if function != "" {
- p.Printf("%s\n ", function)
- }
- if file != "" {
- p.Printf("%s:%d\n", file, line)
- }
- }
-}
diff --git a/vendor/golang.org/x/xerrors/go.mod b/vendor/golang.org/x/xerrors/go.mod
deleted file mode 100644
index 870d4f612..000000000
--- a/vendor/golang.org/x/xerrors/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module golang.org/x/xerrors
-
-go 1.11
diff --git a/vendor/golang.org/x/xerrors/internal/internal.go b/vendor/golang.org/x/xerrors/internal/internal.go
deleted file mode 100644
index 89f4eca5d..000000000
--- a/vendor/golang.org/x/xerrors/internal/internal.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package internal
-
-// EnableTrace indicates whether stack information should be recorded in errors.
-var EnableTrace = true
diff --git a/vendor/golang.org/x/xerrors/wrap.go b/vendor/golang.org/x/xerrors/wrap.go
deleted file mode 100644
index 9a3b51037..000000000
--- a/vendor/golang.org/x/xerrors/wrap.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package xerrors
-
-import (
- "reflect"
-)
-
-// A Wrapper provides context around another error.
-type Wrapper interface {
- // Unwrap returns the next error in the error chain.
- // If there is no next error, Unwrap returns nil.
- Unwrap() error
-}
-
-// Opaque returns an error with the same error formatting as err
-// but that does not match err and cannot be unwrapped.
-func Opaque(err error) error {
- return noWrapper{err}
-}
-
-type noWrapper struct {
- error
-}
-
-func (e noWrapper) FormatError(p Printer) (next error) {
- if f, ok := e.error.(Formatter); ok {
- return f.FormatError(p)
- }
- p.Print(e.error)
- return nil
-}
-
-// Unwrap returns the result of calling the Unwrap method on err, if err implements
-// Unwrap. Otherwise, Unwrap returns nil.
-func Unwrap(err error) error {
- u, ok := err.(Wrapper)
- if !ok {
- return nil
- }
- return u.Unwrap()
-}
-
-// Is reports whether any error in err's chain matches target.
-//
-// An error is considered to match a target if it is equal to that target or if
-// it implements a method Is(error) bool such that Is(target) returns true.
-func Is(err, target error) bool {
- if target == nil {
- return err == target
- }
-
- isComparable := reflect.TypeOf(target).Comparable()
- for {
- if isComparable && err == target {
- return true
- }
- if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
- return true
- }
- // TODO: consider supporing target.Is(err). This would allow
- // user-definable predicates, but also may allow for coping with sloppy
- // APIs, thereby making it easier to get away with them.
- if err = Unwrap(err); err == nil {
- return false
- }
- }
-}
-
-// As finds the first error in err's chain that matches the type to which target
-// points, and if so, sets the target to its value and returns true. An error
-// matches a type if it is assignable to the target type, or if it has a method
-// As(interface{}) bool such that As(target) returns true. As will panic if target
-// is not a non-nil pointer to a type which implements error or is of interface type.
-//
-// The As method should set the target to its value and return true if err
-// matches the type to which target points.
-func As(err error, target interface{}) bool {
- if target == nil {
- panic("errors: target cannot be nil")
- }
- val := reflect.ValueOf(target)
- typ := val.Type()
- if typ.Kind() != reflect.Ptr || val.IsNil() {
- panic("errors: target must be a non-nil pointer")
- }
- if e := typ.Elem(); e.Kind() != reflect.Interface && !e.Implements(errorType) {
- panic("errors: *target must be interface or implement error")
- }
- targetType := typ.Elem()
- for err != nil {
- if reflect.TypeOf(err).AssignableTo(targetType) {
- val.Elem().Set(reflect.ValueOf(err))
- return true
- }
- if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) {
- return true
- }
- err = Unwrap(err)
- }
- return false
-}
-
-var errorType = reflect.TypeOf((*error)(nil)).Elem()
diff --git a/vendor/modules.txt b/vendor/modules.txt
index b55515db1..ef33a0dcc 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -55,7 +55,7 @@ github.com/containerd/containerd/sys
# github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb
github.com/containerd/continuity/fs
github.com/containerd/continuity/sysx
-# github.com/containernetworking/cni v0.8.0
+# github.com/containernetworking/cni v0.8.1
github.com/containernetworking/cni/libcni
github.com/containernetworking/cni/pkg/invoke
github.com/containernetworking/cni/pkg/types
@@ -173,7 +173,7 @@ github.com/containers/psgo/internal/dev
github.com/containers/psgo/internal/host
github.com/containers/psgo/internal/proc
github.com/containers/psgo/internal/process
-# github.com/containers/storage v1.24.5
+# github.com/containers/storage v1.25.0
github.com/containers/storage
github.com/containers/storage/drivers
github.com/containers/storage/drivers/aufs
@@ -370,7 +370,7 @@ github.com/mattn/go-colorable
github.com/mattn/go-isatty
# github.com/mattn/go-runewidth v0.0.9
github.com/mattn/go-runewidth
-# github.com/mattn/go-shellwords v1.0.10
+# github.com/mattn/go-shellwords v1.0.11
github.com/mattn/go-shellwords
# github.com/matttproud/golang_protobuf_extensions v1.0.1
github.com/matttproud/golang_protobuf_extensions/pbutil
@@ -399,7 +399,7 @@ github.com/nxadm/tail/ratelimiter
github.com/nxadm/tail/util
github.com/nxadm/tail/watch
github.com/nxadm/tail/winfile
-# github.com/onsi/ginkgo v1.14.2
+# github.com/onsi/ginkgo v1.15.0
github.com/onsi/ginkgo
github.com/onsi/ginkgo/config
github.com/onsi/ginkgo/extensions/table
@@ -407,6 +407,7 @@ github.com/onsi/ginkgo/ginkgo
github.com/onsi/ginkgo/ginkgo/convert
github.com/onsi/ginkgo/ginkgo/interrupthandler
github.com/onsi/ginkgo/ginkgo/nodot
+github.com/onsi/ginkgo/ginkgo/outline
github.com/onsi/ginkgo/ginkgo/testrunner
github.com/onsi/ginkgo/ginkgo/testsuite
github.com/onsi/ginkgo/ginkgo/watch
@@ -427,7 +428,7 @@ github.com/onsi/ginkgo/reporters/stenographer
github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable
github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty
github.com/onsi/ginkgo/types
-# github.com/onsi/gomega v1.10.4
+# github.com/onsi/gomega v1.10.5
github.com/onsi/gomega
github.com/onsi/gomega/format
github.com/onsi/gomega/gbytes
@@ -503,7 +504,7 @@ github.com/prometheus/common/model
# github.com/prometheus/procfs v0.0.3
github.com/prometheus/procfs
github.com/prometheus/procfs/internal/fs
-# github.com/rootless-containers/rootlesskit v0.12.0
+# github.com/rootless-containers/rootlesskit v0.13.0
github.com/rootless-containers/rootlesskit/pkg/msgutil
github.com/rootless-containers/rootlesskit/pkg/port
github.com/rootless-containers/rootlesskit/pkg/port/builtin
@@ -663,9 +664,8 @@ golang.org/x/text/unicode/bidi
golang.org/x/text/unicode/norm
# golang.org/x/time v0.0.0-20191024005414-555d28b269f0
golang.org/x/time/rate
-# golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
-golang.org/x/xerrors
-golang.org/x/xerrors/internal
+# golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e
+golang.org/x/tools/go/ast/inspector
# google.golang.org/appengine v1.6.6
google.golang.org/appengine/internal
google.golang.org/appengine/internal/base