diff options
234 files changed, 2290 insertions, 2057 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 692282d61..5ec35cccb 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -34,11 +34,16 @@ env: #### #### Cache-image names to test with (double-quotes around names are critical) ### + FEDORA_NAME: "fedora-31" + PRIOR_FEDORA_NAME: "fedora-30" + UBUNTU_NAME: "ubuntu-19" + PRIOR_UBUNTU_NAME: "ubuntu-18" + _BUILT_IMAGE_SUFFIX: "libpod-5940307564953600" - FEDORA_CACHE_IMAGE_NAME: "fedora-31-${_BUILT_IMAGE_SUFFIX}" - PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-30-${_BUILT_IMAGE_SUFFIX}" - UBUNTU_CACHE_IMAGE_NAME: "ubuntu-19-${_BUILT_IMAGE_SUFFIX}" - PRIOR_UBUNTU_CACHE_IMAGE_NAME: "ubuntu-18-${_BUILT_IMAGE_SUFFIX}" + FEDORA_CACHE_IMAGE_NAME: "${FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}" + PRIOR_FEDORA_CACHE_IMAGE_NAME: "${PRIOR_FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}" + UBUNTU_CACHE_IMAGE_NAME: "${UBUNTU_NAME}-${_BUILT_IMAGE_SUFFIX}" + PRIOR_UBUNTU_CACHE_IMAGE_NAME: "${PRIOR_UBUNTU_NAME}-${_BUILT_IMAGE_SUFFIX}" #### #### Variables for composing new cache-images (used in PR testing) from @@ -102,7 +107,7 @@ gating_task: # The entrypoint.sh script ensures a prestine copy of $SRCPATH is # available at $GOSRC before executing make instructions. image: "quay.io/libpod/gate:master" - cpu: 4 + cpu: 8 memory: 12 timeout_in: 20m @@ -133,6 +138,7 @@ gating_task: # N/B: need 'clean' so some committed files are re-generated. - '/usr/local/bin/entrypoint.sh clean podman-remote |& ${TIMESTAMP}' - '/usr/local/bin/entrypoint.sh clean podman BUILDTAGS="exclude_graphdriver_devicemapper selinux seccomp" |& ${TIMESTAMP}' + - '/usr/local/bin/entrypoint.sh local-cross |& ${TIMESTAMP}' - '/usr/local/bin/entrypoint.sh podman-remote-darwin |& ${TIMESTAMP}' - '/usr/local/bin/entrypoint.sh podman-remote-windows |& ${TIMESTAMP}' @@ -370,7 +376,7 @@ image_prune_task: # This task does the unit and integration testing for every platform testing_task: - + alias: "testing" depends_on: - "gating" - "vendor" @@ -383,21 +389,30 @@ testing_task: $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' - gce_instance: - matrix: - image_name: "${FEDORA_CACHE_IMAGE_NAME}" - image_name: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" - # Multiple test failures on Ubuntu 19 - Fixes TBD in future PR - # TODO: image_name: "${UBUNTU_CACHE_IMAGE_NAME}" - image_name: "${PRIOR_UBUNTU_CACHE_IMAGE_NAME}" + matrix: + - name: "test ${FEDORA_NAME}" + gce_instance: + image_name: "${FEDORA_CACHE_IMAGE_NAME}" + - name: "test ${PRIOR_FEDORA_NAME}" + gce_instance: + image_name: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" + # Multiple test failures on Ubuntu 19 - Fixes TBD in future PR + # TODO: image_name: "${UBUNTU_CACHE_IMAGE_NAME}" + - name: "test ${PRIOR_UBUNTU_NAME}" + gce_instance: + image_name: "${PRIOR_UBUNTU_CACHE_IMAGE_NAME}" timeout_in: 120m env: ADD_SECOND_PARTITION: 'true' matrix: - TEST_REMOTE_CLIENT: 'true' - TEST_REMOTE_CLIENT: 'false' + - name: remote + env: + TEST_REMOTE_CLIENT: 'true' + - name: local + env: + TEST_REMOTE_CLIENT: 'false' networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh' setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}' @@ -448,8 +463,12 @@ special_testing_rootless_task: ADD_SECOND_PARTITION: 'true' SPECIALMODE: 'rootless' # See docs matrix: - TEST_REMOTE_CLIENT: 'true' - TEST_REMOTE_CLIENT: 'false' + - name: remote + env: + TEST_REMOTE_CLIENT: 'true' + - name: local + env: + TEST_REMOTE_CLIENT: 'false' timeout_in: 60m @@ -467,7 +486,7 @@ special_testing_rootless_task: special_testing_in_podman_task: - + alias: "special_testing_in_podman" depends_on: - "gating" - "varlink_api" @@ -479,12 +498,13 @@ special_testing_in_podman_task: $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' - gce_instance: - matrix: - # FIXME: Integration testing currently broken for F31 hosts - # Error: container_linux.go:345: starting container process caused "process_linux.go:281: applying cgroup configuration for process caused \"mountpoint for cgroup not found\"": OCI runtime error - # image_name: "${FEDORA_CACHE_IMAGE_NAME}" - image_name: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" + matrix: + # FIXME: Integration testing currently broken for F31 hosts + # Error: container_linux.go:345: starting container process caused "process_linux.go:281: applying cgroup configuration for process caused \"mountpoint for cgroup not found\"": OCI runtime error + # image_name: "${FEDORA_CACHE_IMAGE_NAME}" + - name: "in-podman ${PRIOR_FEDORA_NAME}" + gce_instance: + image_name: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" env: ADD_SECOND_PARTITION: 'true' @@ -509,7 +529,7 @@ special_testing_in_podman_task: special_testing_cross_task: - + alias: "special_testing_cross" depends_on: - "gating" - "varlink_api" @@ -519,10 +539,13 @@ special_testing_cross_task: $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' - env: - matrix: - CROSS_PLATFORM: 'windows' - CROSS_PLATFORM: 'darwin' + matrix: + - name: 'cross-platform: windows' + env: + CROSS_PLATFORM: 'windows' + - name: 'cross-platform: darwin' + env: + CROSS_PLATFORM: 'darwin' timeout_in: 20m @@ -649,15 +672,19 @@ verify_test_built_images_task: env: ADD_SECOND_PARTITION: 'true' matrix: - TEST_REMOTE_CLIENT: 'true' - TEST_REMOTE_CLIENT: 'false' + - name: remote + env: + TEST_REMOTE_CLIENT: 'true' + - name: local + env: + TEST_REMOTE_CLIENT: 'false' matrix: # Required env. var. by check_image_script - PACKER_BUILDER_NAME: "fedora-30" - PACKER_BUILDER_NAME: "fedora-31" - PACKER_BUILDER_NAME: "ubuntu-18" + PACKER_BUILDER_NAME: "${FEDORA_NAME}" + PACKER_BUILDER_NAME: "${PRIOR_FEDORA_NAME}" + PACKER_BUILDER_NAME: "${PRIOR_UBUNTU_NAME}" # Multiple test failures on ${UBUNTU_CACHE_IMAGE_NAME} - # PACKER_BUILDER_NAME: "ubuntu-19" + # PACKER_BUILDER_NAME: "${UBUNTU_NAME}" networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh' installed_packages_script: '$SCRIPT_BASE/logcollector.sh packages' diff --git a/.golangci.yml b/.golangci.yml index dda1cc7ec..8b1062b4c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -24,7 +24,6 @@ linters: - goconst - gocyclo - golint - - goimports - gosec - lll - maligned @@ -108,8 +108,9 @@ endif GOMD2MAN ?= $(shell command -v go-md2man || echo '$(GOBIN)/go-md2man') CROSS_BUILD_TARGETS := \ - bin/podman.cross.darwin.amd64 \ - bin/podman.cross.linux.amd64 + bin/podman.cross.linux.amd64 \ + bin/podman.cross.linux.ppc64le \ + bin/podman.cross.linux.arm .PHONY: all all: binaries docs @@ -394,7 +395,7 @@ man-page-check: .PHONY: codespell codespell: - codespell -S bin,vendor,.git,go.sum,changelog.txt,seccomp.json,.cirrus.yml,"*.xz,*.gz,*.tar,*.tgz,bin2img,*ico,*.png,*.1,*.5,copyimg,*.orig,apidoc.go" -L uint,iff,od,seeked + codespell -S bin,vendor,.git,go.sum,changelog.txt,seccomp.json,.cirrus.yml,"*.xz,*.gz,*.tar,*.tgz,bin2img,*ico,*.png,*.1,*.5,copyimg,*.orig,apidoc.go" -L uint,iff,od,seeked,splitted,marge,ERRO,hist -w # When publishing releases include critical build-time details .PHONY: release.txt @@ -5,7 +5,7 @@ Libpod provides a library for applications looking to use the Container Pod concept, popularized by Kubernetes. Libpod also contains the Pod Manager tool `(Podman)`. Podman manages pods, containers, container images, and container volumes. -* [Latest Version: 1.8.0](https://github.com/containers/libpod/releases/latest) +* [Latest Version: 1.8.1](https://github.com/containers/libpod/releases/latest) * [Continuous Integration:](contrib/cirrus/README.md) [![Build Status](https://api.cirrus-ci.com/github/containers/libpod.svg)](https://cirrus-ci.com/github/containers/libpod/master) * [GoDoc: ![GoDoc](https://godoc.org/github.com/containers/libpod/libpod?status.svg)](https://godoc.org/github.com/containers/libpod/libpod) * Automated continuous release downloads (including remote-client): diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f813b494f..78e13c227 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -4,9 +4,12 @@ ### Features - Many networking-related flags have been added to `podman pod create` to enable customization of pod networks, including `--add-host`, `--dns`, `--dns-opt`, `--dns-search`, `--ip`, `--mac-address`, `--network`, and `--no-hosts` - The `podman ps --format=json` command now includes the ID of the image containers were created with +- The `podman run` and `podman create` commands now feature an `--rmi` flag to remove the image the container was using after it exits (if no other containers are using said image) ([#4628](https://github.com/containers/libpod/issues/4628)) - The `podman create` and `podman run` commands now support the `--device-cgroup-rule` flag ([#4876](https://github.com/containers/libpod/issues/4876)) - While the HTTP API remains in alpha, many fixes and additions have landed. These are documented in a separate subsection below - The `podman create` and `podman run` commands now feature a `--no-healthcheck` flag to disable healthchecks for a container ([#5299](https://github.com/containers/libpod/issues/5299)) +- Containers now recognize the `io.containers.capabilities` label, which specifies a list of capabilities required by the image to run. These capabilities will be used as long as they are more restrictive than the default capabilities used +- YAML produced by the `podman generate kube` command now includes SELinux configuration passed into the container via `--security-opt label=...` ([#4950](https://github.com/containers/libpod/issues/4950)) ### Bugfixes - Fixed CVE-2020-1726, a security issue where volumes manually populated before first being mounted into a container could have those contents overwritten on first being mounted into a container @@ -33,6 +36,9 @@ - Fixed a bug where the `--uts` flag to `podman create` and `podman run` would only allow specifying containers by full ID ([#5289](https://github.com/containers/libpod/issues/5289)) - Fixed a bug where rootless Podman could segfault when passed a large number of file descriptors - Fixed a bug where the `podman port` command was incorrectly interpreting additional arguments as container names, instead of port numbers +- Fixed a bug where units created by `podman generate systemd` did not depend on network targets, and so could start before the system network was ready ([#4130](https://github.com/containers/libpod/issues/4130)) +- Fixed a bug where exec sessions in containers which did not specify a user would not inherit supplemental groups added to the container via `--group-add` +- Fixed a bug where Podman would not respect the `$TMPDIR` environment variable for placing large temporary files during some operations (e.g. `podman pull`) ([#5411](https://github.com/containers/libpod/issues/5411)) ### HTTP API - Initial support for secure connections to servers via SSH tunneling has been added @@ -47,8 +53,8 @@ - Many fixes have been made to API documentation to ensure it matches the code ### Misc -- Updated vendored Buildah to v1.14.1 -- Updated vendored containers/storage to v1.16.0 +- Updated vendored Buildah to v1.14.2 +- Updated vendored containers/storage to v1.16.2 - The `Created` field to `podman images --format=json` has been renamed to `CreatedSince` as part of the fix for ([#5110](https://github.com/containers/libpod/issues/5110)). Go templates using the old name should still work - The `CreatedTime` field to `podman images --format=json` has been renamed to `CreatedAt` as part of the fix for ([#5110](https://github.com/containers/libpod/issues/5110)). Go templates using the old name should still work - The `before` filter to `podman images` has been renamed to `since` for Docker compatibility. Using `before` will still work, but documentation has been changed to use the new `since` filter diff --git a/changelog.txt b/changelog.txt index 84d6dcea0..651ef89b8 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,86 @@ +- Changelog for v1.8.1 (2020-03-11) + * man pages: fix inconsistencies + * Update release notes for v1.8.1 final release + * build for amd64|arm|ppc64le + * update systemd & dbus dependencies + * Refactor handler packages + * Remove nonexistent --set arg from runlabel documentation + * hide --trace flag + * podman --help: mention defaults of bools + * docs: clarify that --syslog expects an argument + * Bump to v1.8.1-dev + * commands: rename file and add likns to readthedocs + +- Changelog for v1.8.1-rc4 (2020-03-09) + * Revert "exec: get the exit code from sync pipe instead of file" + * Revert "Exec: use ErrorConmonRead" + * Revert "exec: fix error code when conmon fails" + * rootles tutorial: remove systemd unit example + * generate systemd: add `default.target` to INSTALL + * Bump github.com/containers/storage from 1.16.1 to 1.16.2 + * use storage/pkg/ioutils + * use storage/pkg/homedir + * Fix spelling mistakes in code found by codespell + * add default network for apiv2 create + * Bump to v1.8.1-dev + * Allow users to set TMPDIR environment + * Fix upstream dockerfile and add 'by hand' ctrfile + * Cirrus: Fix fedora-minimal mirroring + * fix security-opt generate kube + +- Changelog for v1.8.1-rc3 (2020-03-06) + * Update release notes for v1.8.1-RC3 + * Part 2: try to clean up the long image instance names + * WIP: Try renaming long cirrus job names + * vendor: update github.com/containernetworking/cni to v0.7.2-0.20200304161608-4fae32b84921 + * Removed extraneous comments and defaults plus amended variable declaration + * Removed the unnecessary code + * Implemented size parameter on GetContainer + * Implement size parameter on ListContainers + * Map configured status to created to match docker API states + * Fix to remove null entry from end of images json + * Register handlers without version to align with docker API + * golangci: enable goimports + * generate systemd: remove leading slashes + * exec: fix error code when conmon fails + * Vendor buildah 1.14.2 + * env: don't set "container" env + * Fix podman image sign help output + * avoid adding to nil map + * Exec: use ErrorConmonRead + * exec: get the exit code from sync pipe instead of file + * generate systemd: add network dependencies + * Bump to Buildah v1.14.1 + * APIv2 tests: add tests for stop + * Add the rmi flag to podman-run to delete container image + * consolidate env handling into pkg/env + * CI: format cirrus logs + * Update docs/source/markdown/podman-build.1.md + * Allow devs to set labels in container images for default capabilities. + * CI: add API v2 tests + * more swagger fixes + * Bump github.com/opencontainers/selinux from 1.3.2 to 1.3.3 + * Add validate() for containers + * Cirrus: Fix gate image & false-positive exits + * Update pod bindings and Add test to validate prune pod apiv2 binding. + * Fix wrong condition in bindings test + * Ensure that exec sessions inherit supplemental groups + * Cirrus: Update VM images + * Cirrus: Force runc use in F30 + * rework apiv2 wait endpoint|binding + * build: specify input fd to buildah + * Cirrus: Remove unnecessary handle_crun workaround + * Cirrus: Print env. vars at end of setup. + * Cirrus: Fix not growing Fedora root + * network create should use firewall plugin + * add firewall plugin (no backend) to default cni config + * binding tests for volumes + * Bump to v1.8.1-dev + * container Exists: fix URL + * CI: package_versions: include hostinfo, kernel + * Review comments + * [WIP] Add cmd flag to show container name in log + - Changelog for v1.8.1-rc2 (2020-02-27) * Update release notes for v1.8.1-rc2 * Vendor in latest containers/buildah diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go index f052b510d..c15512360 100644 --- a/cmd/podman/diff.go +++ b/cmd/podman/diff.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/pkg/adapter" diff --git a/cmd/podman/load.go b/cmd/podman/load.go index ed6a4e5fa..318b5b5fb 100644 --- a/cmd/podman/load.go +++ b/cmd/podman/load.go @@ -10,6 +10,7 @@ import ( "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/shared/parse" "github.com/containers/libpod/pkg/adapter" + "github.com/containers/libpod/pkg/util" "github.com/pkg/errors" "github.com/spf13/cobra" "golang.org/x/crypto/ssh/terminal" @@ -75,7 +76,7 @@ func loadCmd(c *cliconfig.LoadValues) error { if terminal.IsTerminal(int(os.Stdin.Fd())) { return errors.Errorf("cannot read from terminal. Use command-line redirection or the --input flag.") } - outFile, err := ioutil.TempFile("/var/tmp", "podman") + outFile, err := ioutil.TempFile(util.Tmpdir(), "podman") if err != nil { return errors.Errorf("error creating file %v", err) } diff --git a/cmd/podman/main.go b/cmd/podman/main.go index 3320ab72f..a2acbbf53 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -138,6 +138,7 @@ func before(cmd *cobra.Command, args []string) error { logrus.Info("running as rootless") } setUMask() + return profileOn(cmd) } diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go index e5b87754b..79b5e5af7 100644 --- a/cmd/podman/main_local.go +++ b/cmd/podman/main_local.go @@ -67,10 +67,11 @@ func init() { // -s is deprecated due to conflict with -s on subcommands rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.StorageDriver, "storage-driver", "", "Select which storage driver is used to manage storage of images and containers (default is overlay)") rootCmd.PersistentFlags().StringArrayVar(&MainGlobalOpts.StorageOpts, "storage-opt", []string{}, "Used to pass an option to the storage driver") - rootCmd.PersistentFlags().BoolVar(&MainGlobalOpts.Syslog, "syslog", false, "Output logging information to syslog as well as the console") + rootCmd.PersistentFlags().BoolVar(&MainGlobalOpts.Syslog, "syslog", false, "Output logging information to syslog as well as the console (default false)") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.TmpDir, "tmpdir", "", "Path to the tmp directory for libpod state content.\n\nNote: use the environment variable 'TMPDIR' to change the temporary storage location for container images, '/var/tmp'.\n") - rootCmd.PersistentFlags().BoolVar(&MainGlobalOpts.Trace, "trace", false, "Enable opentracing output") + rootCmd.PersistentFlags().BoolVar(&MainGlobalOpts.Trace, "trace", false, "Enable opentracing output (default false)") + markFlagHidden(rootCmd.PersistentFlags(), "trace") } func setSyslog() error { diff --git a/cmd/podman/network_list.go b/cmd/podman/network_list.go index 16edf743b..4f2380067 100644 --- a/cmd/podman/network_list.go +++ b/cmd/podman/network_list.go @@ -4,6 +4,7 @@ package main import ( "errors" + "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/pkg/adapter" "github.com/containers/libpod/pkg/rootless" diff --git a/cmd/podman/pod_pause.go b/cmd/podman/pod_pause.go index 320072919..24fcee6b9 100644 --- a/cmd/podman/pod_pause.go +++ b/cmd/podman/pod_pause.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/pkg/adapter" "github.com/pkg/errors" diff --git a/cmd/podman/pod_top.go b/cmd/podman/pod_top.go index fcd9c4f3c..734472817 100644 --- a/cmd/podman/pod_top.go +++ b/cmd/podman/pod_top.go @@ -42,7 +42,7 @@ func init() { podTopCommand.SetHelpTemplate(HelpTemplate()) podTopCommand.SetUsageTemplate(UsageTemplate()) flags := podTopCommand.Flags() - flags.BoolVarP(&podTopCommand.Latest, "latest,", "l", false, "Act on the latest pod podman is aware of") + flags.BoolVarP(&podTopCommand.Latest, "latest", "l", false, "Act on the latest pod podman is aware of") flags.BoolVar(&podTopCommand.ListDescriptors, "list-descriptors", false, "") markFlagHidden(flags, "list-descriptors") } diff --git a/cmd/podman/remoteclientconfig/config_darwin.go b/cmd/podman/remoteclientconfig/config_darwin.go index b94941381..dddb217ac 100644 --- a/cmd/podman/remoteclientconfig/config_darwin.go +++ b/cmd/podman/remoteclientconfig/config_darwin.go @@ -3,7 +3,7 @@ package remoteclientconfig import ( "path/filepath" - "github.com/docker/docker/pkg/homedir" + "github.com/containers/storage/pkg/homedir" ) func getConfigFilePath() string { diff --git a/cmd/podman/remoteclientconfig/config_linux.go b/cmd/podman/remoteclientconfig/config_linux.go index 5d27f19f2..afcf73e6d 100644 --- a/cmd/podman/remoteclientconfig/config_linux.go +++ b/cmd/podman/remoteclientconfig/config_linux.go @@ -4,7 +4,7 @@ import ( "os" "path/filepath" - "github.com/docker/docker/pkg/homedir" + "github.com/containers/storage/pkg/homedir" ) func getConfigFilePath() string { diff --git a/cmd/podman/remoteclientconfig/config_windows.go b/cmd/podman/remoteclientconfig/config_windows.go index fa6ffca63..3a8f3bc7a 100644 --- a/cmd/podman/remoteclientconfig/config_windows.go +++ b/cmd/podman/remoteclientconfig/config_windows.go @@ -3,7 +3,7 @@ package remoteclientconfig import ( "path/filepath" - "github.com/docker/docker/pkg/homedir" + "github.com/containers/storage/pkg/homedir" ) func getConfigFilePath() string { diff --git a/cmd/podman/runlabel.go b/cmd/podman/runlabel.go index 358538155..1ec4da650 100644 --- a/cmd/podman/runlabel.go +++ b/cmd/podman/runlabel.go @@ -49,7 +49,7 @@ func init() { flags.StringVar(&runlabelCommand.Creds, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry") flags.BoolVar(&runlabelCommand.Display, "display", false, "Preview the command that the label would run") flags.BoolVar(&runlabelCommand.Replace, "replace", false, "Replace existing container with a new one from the image") - flags.StringVar(&runlabelCommand.Name, "name", "", "Assign a name to the container") + flags.StringVarP(&runlabelCommand.Name, "name", "n", "", "Assign a name to the container") flags.StringVar(&runlabelCommand.Opt1, "opt1", "", "Optional parameter to pass for install") flags.StringVar(&runlabelCommand.Opt2, "opt2", "", "Optional parameter to pass for install") diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go index 5adac7e1f..8968f10e8 100644 --- a/cmd/podman/shared/create.go +++ b/cmd/podman/shared/create.go @@ -494,7 +494,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. if data != nil { configEnv, err := envLib.ParseSlice(data.Config.Env) if err != nil { - return nil, errors.Wrap(err, "error pasing image environment variables") + return nil, errors.Wrap(err, "error passing image environment variables") } env = envLib.Join(env, configEnv) } diff --git a/commands-demo.md b/commands-demo.md new file mode 100644 index 000000000..bf02a5be0 --- /dev/null +++ b/commands-demo.md @@ -0,0 +1,101 @@ +![PODMAN logo](logo/podman-logo-source.svg) + +# libpod - library for running OCI-based containers in Pods + +## Podman Commands + +| Command | Description | Demo | Script | +| :----------------------------------------------------------------------- | :------------------------------------------------------------------------- | :-------------------------------------------------------------------------- | :---------------------------------------------------------------------------------- | +| [podman-attach(1)](https://podman.readthedocs.io/en/latest/markdown/podman-attach.1.html) | Attach to a running container | +| [podman-build(1)](https://podman.readthedocs.io/en/latest/markdown/podman-build.1.html) | Build a container image using a Containerfile | +| [podman-commit(1)](https://podman.readthedocs.io/en/latest/markdown/podman-commit.1.html) | Create new image based on the changed container | +| [podman-container(1)](https://podman.readthedocs.io/en/latest/managecontainers.html) | Manage Containers | +| [podman-container-checkpoint(1)](https://podman.readthedocs.io/en/latest/markdown/podman-container-checkpoint.1.html) | Checkpoints one or more running containers | +| [podman-container-cleanup(1)](https://podman.readthedocs.io/en/latest/markdown/podman-container-cleanup.1.html) | Cleanup the container's network and mountpoints | +| [podman-container-exists(1)](https://podman.readthedocs.io/en/latest/markdown/podman-container-exists.1.html) | Check if an container exists in local storage | +| [podman-container-prune(1)](https://podman.readthedocs.io/en/latest/markdown/podman-container-prune.1.html) | Remove all stopped containers from local storage | +| [podman-container-restore(1)](https://podman.readthedocs.io/en/latest/markdown/podman-container-restore.1.html) | Restores one or more containers from a checkpoint | +| [podman-container-runlabel(1)](https://podman.readthedocs.io/en/latest/markdown/podman-container-runlabel.1.html) | Executes a command as described by a container image label | +| [podman-cp(1)](https://podman.readthedocs.io/en/latest/markdown/podman-cp.1.html) | Copy files/folders between a container and the local filesystem | +| [podman-create(1)](https://podman.readthedocs.io/en/latest/markdown/podman-create.1.html) | Create a new container | +| [podman-diff(1)](https://podman.readthedocs.io/en/latest/markdown/podman-diff.1.html) | Inspect changes on a container or image's filesystem | +| [podman-events(1)](https://podman.readthedocs.io/en/latest/markdown/podman-events.1.html) | Monitor Podman events | +| [podman-exec(1)](https://podman.readthedocs.io/en/latest/markdown/podman-exec.1.html) | Execute a command in a running container | +| [podman-export(1)](https://podman.readthedocs.io/en/latest/markdown/podman-export.1.html) | Export container's filesystem contents as a tar archive | +| [podman-generate(1)](https://podman.readthedocs.io/en/latest/generate.html) | Generate structured output based on Podman containers and pods | +| [podman-generate-kube(1)](https://podman.readthedocs.io/en/latest/markdown/podman-generate-kube.1.html) | Generate Kubernetes YAML based on a pod or container | +| [podman-generate-systemd(1)](https://podman.readthedocs.io/en/latest/markdown/podman-generate-systemd.1.html) | Generate systemd unit file(s) for a container. Not supported for the remote client | +| [podman-history(1)](https://podman.readthedocs.io/en/latest/markdown/podman-history.1.html) | Shows the history of an image | +| [podman-image(1)](https://podman.readthedocs.io/en/latest/image.html) | Manage Images | +| [podman-image-exists(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-exists.1.html) | Check if an image exists in local storage | +| [podman-image-prune(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-prune.1.html) | Remove all unused images from the local store | +| [podman-image-sign(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-sign.1.html) | Create a signature for an image | +| [podman-image-tree(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-tree.1.html) | Prints layer hierarchy of an image in a tree format | +| [podman-image-trust(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-trust.1.html) | Manage container registry image trust policy | +| [podman-images(1)](https://podman.readthedocs.io/en/latest/markdown/podman-images.1.html) | List images in local storage | [![...](/docs/source/markdown/play.png)](https://podman.io/asciinema/podman/images/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_images.sh) | +| [podman-import(1)](https://podman.readthedocs.io/en/latest/markdown/podman-import.1.html) | Import a tarball and save it as a filesystem image | +| [podman-info(1)](https://podman.readthedocs.io/en/latest/markdown/podman-info.1.html) | Displays Podman related system information | +| [podman-init(1)](https://podman.readthedocs.io/en/latest/markdown/podman-init.1.html) | Initialize one or more containers | +| [podman-inspect(1)](https://podman.readthedocs.io/en/latest/markdown/podman-inspect.1.html) | Display a container or image's configuration | [![...](/docs/source/markdown/play.png)](https://podman.io/asciinema/podman/inspect/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_inspect.sh) | +| [podman-kill(1)](https://podman.readthedocs.io/en/latest/markdown/podman-kill.1.html) | Kill the main process in one or more running containers | +| [podman-load(1)](https://podman.readthedocs.io/en/latest/markdown/podman-load.1.html) | Load an image from a container image archive into container storage | +| [podman-login(1)](https://podman.readthedocs.io/en/latest/markdown/podman-login.1.html) | Login to a container registry | +| [podman-logout(1)](https://podman.readthedocs.io/en/latest/markdown/podman-logout.1.html) | Logout of a container registry | +| [podman-logs(1)](https://podman.readthedocs.io/en/latest/markdown/podman-logs.1.html) | Display the logs of one or more containers | +| [podman-mount(1)](https://podman.readthedocs.io/en/latest/markdown/podman-mount.1.html) | Mount a working container's root filesystem | +| [podman-network(1)](https://podman.readthedocs.io/en/latest/network.html) | Manage Podman CNI networks | +| [podman-network-create(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-create.1.html) | Create a CNI network | +| [podman-network-inspect(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-inspect.1.html) | Displays the raw CNI network configuration for one or more networks | +| [podman-network-ls(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-ls.1.html) | Display a summary of CNI networks | +| [podman-network-rm(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-rm.1.html) | Remove one or more CNI networks | +| [podman-pause(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pause.1.html) | Pause one or more running containers | [![...](/docs/source/markdown/play.png)](https://podman.io/asciinema/podman/pause_unpause/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_pause_unpause.sh) | +| [podman-play(1)](https://podman.readthedocs.io/en/latest/play.html) | Play a pod | +| [podman-play-kube(1)](https://podman.readthedocs.io/en/latest/markdown/podman-play-kube.1.html) | Create pods and containers based on Kubernetes YAML | +| [podman-pod(1)](https://podman.readthedocs.io/en/latest/pod.html) | Manage pods | +| [podman-pod-create(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-create.1.html) | Create a new pod | +| [podman-pod-exists(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-exists.1.html) | Check if a pod exists in local storage | +| [podman-pod-inspect(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-inspect.1.html) | Displays information describing a pod | +| [podman-pod-kill(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-kill.1.html) | Kill the main process of each container in one or more pods | +| [podman-pod-ps(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-ps.1.html) | Prints out information about pods | +| [podman-pod-pause(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pause.1.html) | Pause one or more containers | +| [podman-pod-prune(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-prune.1.html) | Remove all stopped pods and their containers | +| [podman-pod-restart](https://podman.readthedocs.io/en/latest/markdown/podman-pod-restart.1.html) | Restart one or more pods | +| [podman-pod-rm(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-rm.1.html) | Remove one or more stopped pods and containers | +| [podman-pod-start(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-start.1.html) | Start one or more pods | +| [podman-pod-stats(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-stats.1.html) | Display a live stream of resource usage stats for containers in one or more pods | | | +| [podman-pod-stop(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-stop.1.html) | Stop one or more pods | +| [podman-pod-top(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-top.1.html) | Display the running processes of containers in a pod | +| [podman-pod-unpause(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-unpause.1.html) | Unpause one or more pods. | +| [podman-port(1)](https://podman.readthedocs.io/en/latest/markdown/podman-port.1.html) | List port mappings for a container | +| [podman-ps(1)](https://podman.readthedocs.io/en/latest/markdown/podman-ps.1.html) | Prints out information about containers | +| [podman-pull(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pull.1.html) | Pull an image from a registry | +| [podman-push(1)](https://podman.readthedocs.io/en/latest/markdown/podman-push.1.html) | Push an image from local storage to elsewhere | [![...](/docs/source/markdown/play.png)](https://asciinema.org/a/133276) | +| [podman-restart(1)](https://podman.readthedocs.io/en/latest/markdown/podman-restart.1.html) | Restarts one or more containers | [![...](/docs/source/markdown/play.png)](https://asciinema.org/a/jiqxJAxcVXw604xdzMLTkQvHM) | +| [podman-rm(1)](https://podman.readthedocs.io/en/latest/markdown/podman-rm.1.html) | Removes one or more containers | +| [podman-rmi(1)](https://podman.readthedocs.io/en/latest/markdown/podman-rmi.1.html) | Removes one or more locally stored images | +| [podman-run(1)](https://podman.readthedocs.io/en/latest/markdown/podman-run.1.html) | Run a command in a new container | +| [podman-save(1)](https://podman.readthedocs.io/en/latest/markdown/podman-save.1.html) | Save an image to a container archive | +| [podman-search(1)](https://podman.readthedocs.io/en/latest/markdown/podman-search.1.html) | Search a registry for an image | +| [podman-start(1)](https://podman.readthedocs.io/en/latest/markdown/podman-start.1.html) | Start one or more containers | +| [podman-stats(1)](https://podman.readthedocs.io/en/latest/markdown/podman-stats.1.html) | Display a live stream of one or more container's resource usage statistics | +| [podman-stop(1)](https://podman.readthedocs.io/en/latest/markdown/podman-stop.1.html) | Stops one or more running containers | +| [podman-system(1)](https://podman.readthedocs.io/en/latest/system.html) | Manage podman | +| [podman-system-df(1)](https://podman.readthedocs.io/en/latest/markdown/podman-system-df.1.html) | Show podman disk usage. | +| [podman-system-info(1)](https://podman.readthedocs.io/en/latest/markdown/podman-info.1.html) | Displays Podman related system information. | +| [podman-system-migrate(1)](https://podman.readthedocs.io/en/latest/markdown/podman-system-migrate.1.html) | Migrate existing containers to a new podman version | +| [podman-system-prune(1)](https://podman.readthedocs.io/en/latest/markdown/podman-system-prune.1.html) | Remove all unused container, image and volume data | +| [podman-system-renumber(1)](https://podman.readthedocs.io/en/latest/markdown/podman-system-renumber.1.html) | Migrate lock numbers to handle a change in maximum number of locks | +| [podman-tag(1)](https://podman.readthedocs.io/en/latest/markdown/podman-tag.1.html) | Add an additional name to a local image | [![...](/docs/source/markdown/play.png)](https://asciinema.org/a/133803) | +| [podman-top(1)](https://podman.readthedocs.io/en/latest/markdown/podman-top.1.html) | Display the running processes of a container | +| [podman-umount(1)](https://podman.readthedocs.io/en/latest/markdown/podman-umount.1.html) | Unmount a working container's root filesystem | +| [podman-unpause(1)](https://podman.readthedocs.io/en/latest/markdown/podman-unpause.1.html) | Unpause one or more containers | [![...](/docs/source/markdown/play.png)](https://podman.io/asciinema/podman/pause_unpause/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_pause_unpause.sh) | +| [podman-unshare(1)](https://podman.readthedocs.io/en/latest/markdown/podman-unshare.1.html) | Run a command inside of a modified user namespace | +| [podman-varlink(1)](https://podman.readthedocs.io/en/latest/markdown/podman-varlink.1.html) | Runs the varlink backend interface | +| [podman-version(1)](https://podman.readthedocs.io/en/latest/markdown/podman-version.1.html) | Display the Podman version information | +| [podman-volume(1)](https://podman.readthedocs.io/en/latest/volume.html) | Manage Volumes | +| [podman-volume-create(1)](https://podman.readthedocs.io/en/latest/markdown/podman-volume-create.1.html) | Create a new volume | +| [podman-volume-inspect(1)](https://podman.readthedocs.io/en/latest/markdown/podman-volume-inspect.1.html) | Get detailed information on one or more volumes | +| [podman-volume-ls(1)](https://podman.readthedocs.io/en/latest/markdown/podman-volume-ls.1.html) | List all the available volumes | +| [podman-volume-prune(1)](https://podman.readthedocs.io/en/latest/markdown/podman-volume-prune.1.html) | Remove all unused volumes | +| [podman-volume-rm(1)](https://podman.readthedocs.io/en/latest/markdown/podman-volume-rm.1.html) | Remove one or more volumes | +| [podman-wait(1)](https://podman.readthedocs.io/en/latest/markdown/podman-wait.1.html) | Wait on one or more containers to stop and print their exit codes | diff --git a/commands.md b/commands.md index 17e069cb1..97b4c69a9 100644 --- a/commands.md +++ b/commands.md @@ -2,100 +2,4 @@ # libpod - library for running OCI-based containers in Pods -## Podman Commands - -| Command | Description | Demo | Script | -| :----------------------------------------------------------------------- | :------------------------------------------------------------------------- | :-------------------------------------------------------------------------- | :---------------------------------------------------------------------------------- | -| [podman(1)](/docs/source/markdown/podman.1.md) | Simple management tool for pods and images | -| [podman-attach(1)](/docs/source/markdown/podman-attach.1.md) | Attach to a running container | -| [podman-build(1)](/docs/source/markdown/podman-build.1.md) | Build an image using instructions from Dockerfiles | -| [podman-commit(1)](/docs/source/markdown/podman-commit.1.md) | Create new image based on the changed container | -| [podman-container(1)](/docs/source/markdown/podman-container.1.md) | Manage Containers | -| [podman-container-checkpoint(1)](/docs/source/markdown/podman-container-checkpoint.1.md) | Checkpoints one or more running containers | -| [podman-container-cleanup(1)](/docs/source/markdown/podman-container-cleanup.1.md) | Cleanup Container storage and networks | -| [podman-container-exists(1)](/docs/source/markdown/podman-container-exists.1.md) | Check if an container exists in local storage | -| [podman-container-prune(1)](/docs/source/markdown/podman-container-prune.1.md) | Remove all stopped containers | -| [podman-container-refresh(1)](/docs/source/markdown/podman-container-refresh.1.md) | Refresh all containers state in database | -| [podman-container-restore(1)](/docs/source/markdown/podman-container-restore.1.md) | Restores one or more running containers | -| [podman-container-runlabel(1)](/docs/source/markdown/podman-container-runlabel.1.md) | Execute Image Label Method | -| [podman-cp(1)](/docs/source/markdown/podman-cp.1.md) | Copy files/folders between a container and the local filesystem | -| [podman-create(1)](/docs/source/markdown/podman-create.1.md) | Create a new container | -| [podman-diff(1)](/docs/source/markdown/podman-diff.1.md) | Inspect changes on a container or image's filesystem | -| [podman-events(1)](/docs/source/markdown/podman-events.1.md) | Monitor Podman events | -| [podman-exec(1)](/docs/source/markdown/podman-exec.1.md) | Execute a command in a running container | -| [podman-export(1)](/docs/source/markdown/podman-export.1.md) | Export container's filesystem contents as a tar archive | -| [podman-generate(1)](/docs/source/markdown/podman-generate.1.md) | Generate structured output based on Podman containers and pods | -| [podman-generate-kube(1)](/docs/source/markdown/podman-generate-kube.1.md) | Generate Kubernetes YAML based on a container or Pod | -| [podman-generate-systemd(1)](/docs/source/markdown/podman-generate-systemd.1.md) | Generate a Systemd unit file for a container | -| [podman-history(1)](/docs/source/markdown/podman-history.1.md) | Shows the history of an image | -| [podman-image(1)](/docs/source/markdown/podman-image.1.md) | Manage Images | -| [podman-image-exists(1)](/docs/source/markdown/podman-image-exists.1.md) | Check if an image exists in local storage | -| [podman-image-prune(1)](/docs/source/markdown/podman-image-prune.1.md) | Remove all unused images | -| [podman-image-sign(1)](/docs/source/markdown/podman-image-sign.1.md) | Create a signature for an image | -| [podman-image-trust(1)](/docs/source/markdown/podman-image-trust.1.md) | Manage container registry image trust policy | -| [podman-images(1)](/docs/source/markdown/podman-images.1.md) | List images in local storage | [![...](/docs/source/markdown/play.png)](https://podman.io/asciinema/podman/images/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_images.sh) | -| [podman-import(1)](/docs/source/markdown/podman-import.1.md) | Import a tarball and save it as a filesystem image | -| [podman-info(1)](/docs/source/markdown/podman-info.1.md) | Display system information | -| [podman-init(1)](/docs/source/markdown/podman-init.1.md) | Initialize a container | -| [podman-inspect(1)](/docs/source/markdown/podman-inspect.1.md) | Display the configuration of a container or image | [![...](/docs/source/markdown/play.png)](https://podman.io/asciinema/podman/inspect/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_inspect.sh) | -| [podman-kill(1)](/docs/source/markdown/podman-kill.1.md) | Kill the main process in one or more running containers | -| [podman-load(1)](/docs/source/markdown/podman-load.1.md) | Load an image from a container image archive | -| [podman-login(1)](/docs/source/markdown/podman-login.1.md) | Login to a container registry | -| [podman-logout(1)](/docs/source/markdown/podman-logout.1.md) | Logout of a container registry | -| [podman-logs(1)](/docs/source/markdown/podman-logs.1.md) | Display the logs of a container | -| [podman-mount(1)](/docs/source/markdown/podman-mount.1.md) | Mount a working container's root filesystem | -| [podman-network(1)](/docs/source/markdown/podman-network.1.md) | Manage Podman CNI networks | -| [podman-network-create(1)](/docs/source/markdown/podman-network-create.1.md) | Create a CNI network | -| [podman-network-inspect(1)](/docs/source/markdown/podman-network-inspect.1.md) | Inspect one or more Podman networks | -| [podman-network-ls(1)](/docs/source/markdown/podman-network-ls.1.md) | Display a summary of Podman networks | -| [podman-network-rm(1)](/docs/source/markdown/podman-network-rm.1.md) | Remove one or more Podman networks | -| [podman-pause(1)](/docs/source/markdown/podman-pause.1.md) | Pause one or more running containers | [![...](/docs/source/markdown/play.png)](https://podman.io/asciinema/podman/pause_unpause/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_pause_unpause.sh) | -| [podman-play(1)](/docs/source/markdown/podman-play.1.md) | Play pods and containers based on a structured input file | -| [podman-pod(1)](/docs/source/markdown/podman-pod.1.md) | Simple management tool for groups of containers, called pods | -| [podman-pod-create(1)](/docs/source/markdown/podman-pod-create.1.md) | Create a new pod | -| [podman-pod-inspect(1)](/docs/source/markdown/podman-pod-inspect.1.md) | Inspect a pod | -| [podman-pod-kill(1)](podman-pod-kill.1.md) | Kill the main process of each container in pod. | -| [podman-pod-ps(1)](/docs/source/markdown/podman-pod-ps.1.md) | List the pods on the system | -| [podman-pod-pause(1)](podman-pod-pause.1.md) | Pause one or more pods. | -| [podman-pod-restart](/docs/source/markdown/podman-pod-restart.1.md) | Restart one or more pods | -| [podman-pod-rm(1)](/docs/source/markdown/podman-pod-rm.1.md) | Remove one or more pods | -| [podman-pod-start(1)](/docs/source/markdown/podman-pod-start.1.md) | Start one or more pods | -| [podman-pod-stats(1)](/docs/source/markdown/podman-pod-stats.1.md) | Display a live stream of one or more pods' resource usage statistics | | | -| [podman-pod-stop(1)](/docs/source/markdown/podman-pod-stop.1.md) | Stop one or more pods | -| [podman-pod-top(1)](/docs/source/markdown/podman-pod-top.1.md) | Display the running processes of a pod | -| [podman-pod-unpause(1)](podman-pod-unpause.1.md) | Unpause one or more pods. | -| [podman-port(1)](/docs/source/markdown/podman-port.1.md) | List port mappings for running containers | -| [podman-ps(1)](/docs/source/markdown/podman-ps.1.md) | Prints out information about containers | -| [podman-pull(1)](/docs/source/markdown/podman-pull.1.md) | Pull an image from a registry | -| [podman-push(1)](/docs/source/markdown/podman-push.1.md) | Push an image to a specified destination | [![...](/docs/source/markdown/play.png)](https://asciinema.org/a/133276) | -| [podman-restart](/docs/source/markdown/podman-restart.1.md) | Restarts one or more containers | [![...](/docs/source/markdown/play.png)](https://asciinema.org/a/jiqxJAxcVXw604xdzMLTkQvHM) | -| [podman-rm(1)](/docs/source/markdown/podman-rm.1.md) | Removes one or more containers | -| [podman-rmi(1)](/docs/source/markdown/podman-rmi.1.md) | Removes one or more images | -| [podman-run(1)](/docs/source/markdown/podman-run.1.md) | Run a command in a container | -| [podman-save(1)](/docs/source/markdown/podman-save.1.md) | Saves an image to an archive | -| [podman-service(1)](/docs/source/markdown/podman-service.1.md) | Run an API listening service | -| [podman-search(1)](/docs/source/markdown/podman-search.1.md) | Search a registry for an image | -| [podman-start(1)](/docs/source/markdown/podman-start.1.md) | Starts one or more containers | -| [podman-stats(1)](/docs/source/markdown/podman-stats.1.md) | Display a live stream of one or more containers' resource usage statistics | -| [podman-stop(1)](/docs/source/markdown/podman-stop.1.md) | Stops one or more running containers | -| [podman-system(1)](/docs/source/markdown/podman-system.1.md) | Manage podman | -| [podman-system-df(1)](/docs/source/markdown/podman-system-df.1.md) | Show podman disk usage. | -| [podman-system-info(1)](/docs/source/markdown/podman-info.1.md) | Displays Podman related system information. | -| [podman-system-migrate(1)](/docs/source/markdown/podman-system-migrate.1.md) | Migrate existing containers to a new podman version. | -| [podman-system-prune(1)](/docs/source/markdown/podman-system-prune.1.md) | Remove all unused container, image and volume data. | -| [podman-system-renumber(1)](/docs/source/markdown/podman-system-renumber.1.md) | Migrate lock numbers to handle a change in maximum number of locks. | -| [podman-system-reset(1)](/docs/source/markdown/podman-system-reset.1.md) | Reset storage back to original state. Remove all pods, containers, images, volumes. | -| [podman-tag(1)](/docs/source/markdown/podman-tag.1.md) | Add an additional name to a local image | [![...](/docs/source/markdown/play.png)](https://asciinema.org/a/133803) | -| [podman-top(1)](/docs/source/markdown/podman-top.1.md) | Display the running processes of a container | -| [podman-umount(1)](/docs/source/markdown/podman-umount.1.md) | Unmount a working container's root filesystem | -| [podman-unpause(1)](/docs/source/markdown/podman-unpause.1.md) | Unpause one or more running containers | [![...](/docs/source/markdown/play.png)](https://podman.io/asciinema/podman/pause_unpause/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_pause_unpause.sh) | -| [podman-unshare(1)](/docs/source/markdown/podman-unshare.1.md) | Run a command inside of a modified user namespace. | -| [podman-varlink(1)](/docs/source/markdown/podman-varlink.1.md) | Run the varlink backend | -| [podman-version(1)](/docs/source/markdown/podman-version.1.md) | Display the version information | -| [podman-volume(1)](/docs/source/markdown/podman-volume.1.md) | Manage Volumes | -| [podman-volume-create(1)](/docs/source/markdown/podman-volume-create.1.md) | Create a volume | -| [podman-volume-inspect(1)](/docs/source/markdown/podman-volume-inspect.1.md) | Get detailed information on one or more volumes | -| [podman-volume-ls(1)](/docs/source/markdown/podman-volume-ls.1.md) | List all the available volumes | -| [podman-volume-rm(1)](/docs/source/markdown/podman-volume-rm.1.md) | Remove one or more volumes | -| [podman-volume-prune(1)](/docs/source/markdown/podman-volume-prune.1.md) | Remove all unused volumes | -| [podman-wait(1)](/docs/source/markdown/podman-wait.1.md) | Wait on one or more containers to stop and print their exit codes | +This page has moved [here](commands-demo.md) diff --git a/contrib/cirrus/packer/libpod_base_images.yml b/contrib/cirrus/packer/libpod_base_images.yml index 21f3795f1..255723d57 100644 --- a/contrib/cirrus/packer/libpod_base_images.yml +++ b/contrib/cirrus/packer/libpod_base_images.yml @@ -12,7 +12,7 @@ variables: # Required for output from qemu builders TTYDEV: - # Ubuntu releases are mearly copied to this project for control purposes + # Ubuntu releases are merely copied to this project for control purposes UBUNTU_BASE_IMAGE: PRIOR_UBUNTU_BASE_IMAGE: diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index d2e1b8767..5001ef4dd 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -18,7 +18,7 @@ exithandler() { echo "$(basename $0) exit status: $RET" [[ "$RET" -eq "0" ]] && date +%s >> "$SETUP_MARKER_FILEPATH" show_env_vars - [ "$RET" -eq "0" ]] || warn "Non-zero exit caused by error ABOVE env. var. display." + [[ "$RET" -eq "0" ]] || warn "Non-zero exit caused by error ABOVE env. var. display." } trap exithandler EXIT diff --git a/contrib/fedora-minimal/Dockerfile b/contrib/fedora-minimal/Dockerfile index 8ea4e6765..a051b3204 100644 --- a/contrib/fedora-minimal/Dockerfile +++ b/contrib/fedora-minimal/Dockerfile @@ -1 +1 @@ -FROM fedora-minimal:latest +FROM registry.fedoraproject.org/fedora-minimal:latest diff --git a/contrib/podmanimage/README.md b/contrib/podmanimage/README.md index ab55f3189..9d841cdba 100644 --- a/contrib/podmanimage/README.md +++ b/contrib/podmanimage/README.md @@ -10,10 +10,10 @@ the images live are public and can be pulled without credentials. These contain resulting containers can run safely with privileges within the container. The container images are built using the latest Fedora and then Podman is installed into them: - * quay.io/podman/stable - This image is built using the latest stable version of Podman in a Fedora based container. Built with podman/stable/Dockerfile. - * quay.io/podman/upstream - This image is built using the latest code found in this GitHub repository. When someone creates a commit and pushes it, the image is created. Due to that the image changes frequently and is not guaranteed to be stable. Built with podmanimage/upstream/Dockerfile. - * quay.io/podman/testing - This image is built using the latest version of Podman that is or was in updates testing for Fedora. At times this may be the same as the stable image. This container image will primarily be used by the development teams for verification testing when a new package is created. Built with podmanimage/testing/Dockerfile. - + * quay.io/podman/stable - This image is built using the latest stable version of Podman in a Fedora based container. Built with [podmanimage/stable/Dockerfile](stable/Dockerfile). + * quay.io/podman/upstream - This image is built using the latest code found in this GitHub repository. When someone creates a commit and pushes it, the image is created. Due to that the image changes frequently and is not guaranteed to be stable. Built with [podmanimage/upstream/Dockerfile](upstream/Dockerfile). + * quay.io/podman/testing - This image is built using the latest version of Podman that is or was in updates testing for Fedora. At times this may be the same as the stable image. This container image will primarily be used by the development teams for verification testing when a new package is created. Built with [podmanimage/testing/Dockerfile](testing/Dockerfile). + * quay.io/podman/stable:version - This image is built manually using a Fedora based container. An RPM is first pulled from the [Fedora Updates System](https://bodhi.fedoraproject.org/) and the image is built from there. For more details, see the Containerfile used to build it, [podmanimage/stable/manual/Containerfile](stable/manual/Containerfile). ## Sample Usage diff --git a/contrib/podmanimage/stable/manual/Containerfile b/contrib/podmanimage/stable/manual/Containerfile new file mode 100644 index 000000000..d76d6d9b4 --- /dev/null +++ b/contrib/podmanimage/stable/manual/Containerfile @@ -0,0 +1,39 @@ +# stable/manual/Containerfile +# +# Build a Podman container image from the latest +# stable version of Podman on the Fedora Updates System. +# https://bodhi.fedoraproject.org/updates/?search=podman +# This image can be used to create a secured container +# that runs safely with privileges within the container. +# This Containerfile builds version 1.7.0, the version and +# the RPM name would need to be adjusted before a run as +# appropriate. +# +# To use, first copy an rpm file from bohdi to `/root/tmp` +# and then run: +# 'podman build -f ./Containerfile -t quay.io/podman/stable:v1.7.0 .' +# +# Once complete run: +# `podman push quay.io/stable:v1.7.0 docker://quay.io/podman/stable:v1.7.0` +# +# Start Build Process using the latest Fedora +FROM fedora:latest + +# Don't include container-selinux and remove +# directories used by dnf that are just taking +# up space. +# +COPY /tmp/podman-1.7.0-3.fc30.x86_64.rpm /tmp +RUN yum -y install /tmp/podman-1.7.0-3.fc30.x86_64.rpm fuse-overlayfs --exclude container-selinux; rm -rf /var/cache /var/log/dnf* /var/log/yum.* /tmp/podman*.rpm + +# Adjust storage.conf to enable Fuse storage. +RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf +RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock + +# Adjust libpod.conf to write logging to a file +RUN sed -i 's/events_logger = "journald"/events_logger = "file"/g' /usr/share/containers/libpod.conf; mkdir -p /run/systemd/journal + +# Set up environment variables to note that this is +# not starting with usernamespace and default to +# isolate the filesystem with chroot. +ENV _BUILDAH_STARTED_IN_USERNS="" BUILDAH_ISOLATION=chroot diff --git a/contrib/podmanimage/upstream/Dockerfile b/contrib/podmanimage/upstream/Dockerfile index 7c9434fa6..847097920 100644 --- a/contrib/podmanimage/upstream/Dockerfile +++ b/contrib/podmanimage/upstream/Dockerfile @@ -19,16 +19,16 @@ ENV GOPATH=/root/podman # that are needed for building but not running Podman RUN useradd build; yum -y update; yum -y reinstall shadow-utils; yum -y install --exclude container-selinux \ --enablerepo=updates-testing \ - atomic-registries \ btrfs-progs-devel \ containernetworking-cni \ + conmon \ device-mapper-devel \ git \ glib2-devel \ glibc-devel \ glibc-static \ go \ - golang-github-cpuguy83-go-md2man \ + golang-github-cpuguy83-md2man \ gpgme-devel \ iptables \ libassuan-devel \ diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in index a9c3bc3be..0222be7ba 100644 --- a/contrib/spec/podman.spec.in +++ b/contrib/spec/podman.spec.in @@ -48,7 +48,7 @@ Epoch: 99 %else Epoch: 0 %endif -Version: 1.8.1 +Version: 1.8.2 Release: #COMMITDATE#.git%{shortcommit0}%{?dist} Summary: Manage Pods, Containers and Container Images License: ASL 2.0 diff --git a/docs/source/markdown/podman-build.1.md b/docs/source/markdown/podman-build.1.md index 3f0bfc57b..dc38caac0 100644 --- a/docs/source/markdown/podman-build.1.md +++ b/docs/source/markdown/podman-build.1.md @@ -37,6 +37,10 @@ Add an image *annotation* (e.g. annotation=*value*) to the image metadata. Can b Note: this information is not present in Docker image formats, so it is discarded when writing images in Docker formats. +**--arch**=*arch* + +Set the ARCH of the image to the provided value instead of the architecture of the host. + **--authfile**=*path* Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`. @@ -187,7 +191,7 @@ Note: if the user only has access rights via a group, accessing the device from inside a rootless container will fail. The **crun**(1) runtime offers a workaround for this by adding the option **--annotation run.oci.keep_original_groups=1**. -**--disable-compression, -D** +**--disable-compression**, **-D** Don't compress filesystem layers when building the image unless it is required by the location where the image is being written. This is the default setting, @@ -248,6 +252,10 @@ environment variable. `export BUILDAH_FORMAT=docker` Print usage statement +**--http-proxy** + +Pass through HTTP Proxy environment variables. + **--iidfile**=*ImageIDfile* Write the image ID to the file. @@ -282,8 +290,8 @@ Add an image *label* (e.g. label=*value*) to the image metadata. Can be used mul Users can set a special LABEL **io.containers.capabilities=CAP1,CAP2,CAP3** in a Containerfile that specified the list of Linux capabilities required for the container to run properly. This label specified in a container image tells -Podman to run the container with just these capabilties. Podman launches the -container with just the specified capabilties, as long as this list of +Podman to run the container with just these capabilities. Podman launches the +container with just the specified capabilities, as long as this list of capabilities is a subset of the default list. If the specified capabilities are not in the default set, Podman will @@ -340,6 +348,10 @@ another process. Do not use existing cached images for the container build. Build from the start with a new set of cached layers. +**--os**=*string* + +Set the OS to the provided value instead of the current operating system of the host. + **--pid**=*pid* Sets the configuration for PID namespaces when handling `RUN` instructions. @@ -429,6 +441,10 @@ Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater tha Unit is optional and can be `b` (bytes), `k` (kilobytes), `m`(megabytes), or `g` (gigabytes). If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses `64m`. +**--sign-by**=*fingerprint* + +Sign the image using a GPG key with the specified FINGERPRINT. + **--squash** Squash all of the image's new layers into a single new layer; any preexisting layers diff --git a/docs/source/markdown/podman-commit.1.md b/docs/source/markdown/podman-commit.1.md index 13e46a899..2f1369847 100644 --- a/docs/source/markdown/podman-commit.1.md +++ b/docs/source/markdown/podman-commit.1.md @@ -38,10 +38,6 @@ Can be set multiple times Set the format of the image manifest and metadata. The currently supported formats are _oci_ and _docker_. If not specifically set, the default format used is _oci_. -**--iidfile**=*ImageIDfile* - -Write the image ID to the file. - **--include-volumes** Include in the committed image any volumes added to the container by the `--volume` or `--mount` options to the `podman create` and `podman run` commands. diff --git a/docs/source/markdown/podman-container-checkpoint.1.md b/docs/source/markdown/podman-container-checkpoint.1.md index 034d338bb..1bac477c8 100644 --- a/docs/source/markdown/podman-container-checkpoint.1.md +++ b/docs/source/markdown/podman-container-checkpoint.1.md @@ -38,7 +38,7 @@ image contains established TCP connections, this options is required during restore. Defaults to not checkpointing containers with established TCP connections. -**--export, -e** +**--export**, **-e** Export the checkpoint to a tar.gz file. The exported checkpoint can be used to import the container on another system and thus enabling container live diff --git a/docs/source/markdown/podman-container-cleanup.1.md b/docs/source/markdown/podman-container-cleanup.1.md index 86e6b4316..66a6cff62 100644 --- a/docs/source/markdown/podman-container-cleanup.1.md +++ b/docs/source/markdown/podman-container-cleanup.1.md @@ -12,7 +12,7 @@ Sometimes container's mount points and network stacks can remain if the podman c ## OPTIONS -**--all**, **a** +**--all**, **-a** Cleanup all containers. diff --git a/docs/source/markdown/podman-container-prune.1.md b/docs/source/markdown/podman-container-prune.1.md index eaecee304..8c05eeafe 100644 --- a/docs/source/markdown/podman-container-prune.1.md +++ b/docs/source/markdown/podman-container-prune.1.md @@ -11,7 +11,12 @@ podman-container-prune - Remove all stopped containers from local storage ## OPTIONS +**--filter**=*filters* + +Provide filter values. + **--force**, **-f** + Do not provide an interactive prompt for container removal. **-h**, **--help** diff --git a/docs/source/markdown/podman-container-restore.1.md b/docs/source/markdown/podman-container-restore.1.md index d71daf4af..a7b0f199b 100644 --- a/docs/source/markdown/podman-container-restore.1.md +++ b/docs/source/markdown/podman-container-restore.1.md @@ -42,13 +42,13 @@ If the checkpoint image does not contain established TCP connections this option is ignored. Defaults to not restoring containers with established TCP connections. -**--import, -i** +**--import**, **-i** Import a checkpoint tar.gz file, which was exported by Podman. This can be used to import a checkpointed container from another host. Do not specify a *container* argument when using this option. -**--name, -n** +**--name**, **-n** This is only available in combination with **--import, -i**. If a container is restored from a checkpoint tar.gz file it is possible to rename it with **--name, -n**. This diff --git a/docs/source/markdown/podman-container-runlabel.1.md b/docs/source/markdown/podman-container-runlabel.1.md index 8511dd5cd..2abbf0b7f 100644 --- a/docs/source/markdown/podman-container-runlabel.1.md +++ b/docs/source/markdown/podman-container-runlabel.1.md @@ -81,17 +81,6 @@ Suppress output information when pulling images If a container exists of the default or given name, as needed it will be stopped, deleted and a new container will be created from this image. -**--rootfs**=*ROOTFS* - -Set rootfs - -**--set**=*NAME*=*VALUE* - -Set name & value - -**--storage** -Use storage - **--tls-verify** Require HTTPS and verify certificates when contacting registries (default: true). If explicitly set to true, diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md index 3c5f81764..aa2456836 100644 --- a/docs/source/markdown/podman-create.1.md +++ b/docs/source/markdown/podman-create.1.md @@ -94,14 +94,6 @@ Write the container ID to the file Write the pid of the `conmon` process to a file. `conmon` runs in a separate process than Podman, so this is necessary when using systemd to restart Podman containers. -**--cpu-count**=*limit* - -Limit the number of CPUs available for execution by the container. - -On Windows Server containers, this is approximated as a percentage of total CPU usage. - -On Windows Server containers, the processor resource controls are mutually exclusive, the order of precedence is CPUCount first, then CPUShares, and CPUPercent last. - **--cpu-period**=*limit* Limit the CPU CFS (Completely Fair Scheduler) period @@ -251,9 +243,9 @@ is the case the **--dns** flags is necessary for every run. The special value **none** can be specified to disable creation of **/etc/resolv.conf** in the container by Podman. The **/etc/resolv.conf** file in the image will be used without changes. -**--dns-option**=*option* +**--dns-opt**=*option* -Set custom DNS options. Invalid if using **--dns-option** and **--network** that is set to 'none' or 'container:<name|id>'. +Set custom DNS options. Invalid if using **--dns-opt** and **--network** that is set to 'none' or 'container:<name|id>'. **--dns-search**=*domain* @@ -334,7 +326,7 @@ The initialization time needed for a container to bootstrap. The value can be ex The maximum time allowed to complete the healthcheck before an interval is considered failed. Like start-period, the value can be expressed in a time format such as `1m22s`. The default value is `30s`. -**--hostname**=*name* +**-h**, **--hostname**=*name* Container host name @@ -381,7 +373,7 @@ Run an init inside the container that forwards signals and reaps processes. Path to the container-init binary. -**--interactive**, **i**=*true|false* +**--interactive**, **-i**=*true|false* Keep STDIN open even if not attached. The default is *false*. @@ -548,7 +540,7 @@ This works for both background and foreground containers. **--network**, **--net**="*bridge*" -Set the Network mode for the container. Invalid if using **--dns**, **--dns-option**, or **--dns-search** with **--network** that is set to 'none' or 'container:<name|id>'. +Set the Network mode for the container. Invalid if using **--dns**, **--dns-opt**, or **--dns-search** with **--network** that is set to 'none' or 'container:<name|id>'. Valid values are: @@ -1066,6 +1058,8 @@ b **/etc/subuid** **/etc/subgid** +NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`. + ## SEE ALSO subgid(5), subuid(5), libpod.conf(5), systemd.unit(5), setsebool(8), slirp4netns(1), fuse-overlayfs(1) diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md index 4d3f9ba48..2bcfdb954 100644 --- a/docs/source/markdown/podman-generate-systemd.1.md +++ b/docs/source/markdown/podman-generate-systemd.1.md @@ -42,8 +42,8 @@ Create and print a systemd unit file for a container running nginx with an *alwa $ podman create --name nginx nginx:latest $ podman generate systemd --restart-policy=always -t 1 nginx # container-de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6.service -# autogenerated by Podman 1.5.2 -# Wed Aug 21 09:46:45 CEST 2019 +# autogenerated by Podman 1.8.0 +# Wed Mar 09 09:46:45 CEST 2020 [Unit] Description=Podman container-de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6.service @@ -58,7 +58,7 @@ Type=forking PIDFile=/run/user/1000/overlay-containers/de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6/userdata/conmon.pid [Install] -WantedBy=multi-user.target +WantedBy=multi-user.target default.target ``` Create systemd unit files for a pod with two simple alpine containers. Note that these container services cannot be started or stopped individually via `systemctl`; they are managed by the pod service. You can still use `systemctl status` or journalctl to examine them. @@ -72,8 +72,8 @@ $ podman generate systemd --files --name systemd-pod /home/user/container-jolly_shtern.service $ cat pod-systemd-pod.service # pod-systemd-pod.service -# autogenerated by Podman 1.5.2 -# Wed Aug 21 09:52:37 CEST 2019 +# autogenerated by Podman 1.8.0 +# Wed Mar 09 09:52:37 CEST 2020 [Unit] Description=Podman pod-systemd-pod.service @@ -90,7 +90,7 @@ Type=forking PIDFile=/run/user/1000/overlay-containers/ccfd5c71a088768774ca7bd05888d55cc287698dde06f475c8b02f696a25adcd/userdata/conmon.pid [Install] -WantedBy=multi-user.target +WantedBy=multi-user.target default.target ``` ## SEE ALSO diff --git a/docs/source/markdown/podman-image-prune.1.md b/docs/source/markdown/podman-image-prune.1.md index 0155ebcd1..c76e9bd3f 100644 --- a/docs/source/markdown/podman-image-prune.1.md +++ b/docs/source/markdown/podman-image-prune.1.md @@ -16,6 +16,14 @@ does not have any containers based on it. Remove dangling images and images that have no associated containers. +**--filter**=*filters* + +Provide filter values. + +**--force**, **-f** + +Do not provide an interactive prompt for container removal. + **--help**, **-h** Print usage statement diff --git a/docs/source/markdown/podman-images.1.md b/docs/source/markdown/podman-images.1.md index 09778e3c2..379f7573e 100644 --- a/docs/source/markdown/podman-images.1.md +++ b/docs/source/markdown/podman-images.1.md @@ -72,7 +72,7 @@ Display the history of image names. If an image gets re-tagged or untagged, the Omit the table headings from the listing of images. -**--no-trunc**, **--notruncate** +**--no-trunc** Do not truncate output. diff --git a/docs/source/markdown/podman-kill.1.md b/docs/source/markdown/podman-kill.1.md index 617d25b85..010c04edc 100644 --- a/docs/source/markdown/podman-kill.1.md +++ b/docs/source/markdown/podman-kill.1.md @@ -23,7 +23,7 @@ to run containers such as CRI-O, the last started container could be from either The latest option is not supported on the remote client. -**--signal**, **s** +**--signal**, **-s** Signal to send to the container. For more information on Linux signals, refer to *man signal(7)*. diff --git a/docs/source/markdown/podman-load.1.md b/docs/source/markdown/podman-load.1.md index deb4fb5ec..917f102f6 100644 --- a/docs/source/markdown/podman-load.1.md +++ b/docs/source/markdown/podman-load.1.md @@ -30,6 +30,8 @@ Read from archive file, default is STDIN. The remote client requires the use of this option. +NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of container images. Podman defaults to use `/var/tmp`. + **--quiet**, **-q** Suppress the progress output diff --git a/docs/source/markdown/podman-logs.1.md b/docs/source/markdown/podman-logs.1.md index 66308c2b5..bcfc0bae8 100644 --- a/docs/source/markdown/podman-logs.1.md +++ b/docs/source/markdown/podman-logs.1.md @@ -30,6 +30,10 @@ to run containers such as CRI-O, the last started container could be from either The latest option is not supported on the remote client. +**-n**, **--names** + +Output the container name in the log + **--since**=*TIMESTAMP* Show logs since TIMESTAMP. The --since option can be Unix timestamps, date formatted timestamps, or Go duration diff --git a/docs/source/markdown/podman-mount.1.md b/docs/source/markdown/podman-mount.1.md index 8f4deeca6..c7bfedb48 100644 --- a/docs/source/markdown/podman-mount.1.md +++ b/docs/source/markdown/podman-mount.1.md @@ -21,7 +21,7 @@ returned. ## OPTIONS -**--all**, **a** +**--all**, **-a** Mount all containers. diff --git a/docs/source/markdown/podman-network-create.1.md b/docs/source/markdown/podman-network-create.1.md index 2eca93adb..cbdfee4d0 100644 --- a/docs/source/markdown/podman-network-create.1.md +++ b/docs/source/markdown/podman-network-create.1.md @@ -22,7 +22,7 @@ Upon completion of creating the network, Podman will display the path to the new Disables the DNS plugin for this network which if enabled, can perform container to container name resolution. -**-d**, , **--driver** +**-d**, **--driver** Driver to manage the network (default "bridge"). Currently on `bridge` is supported. diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md index dba31f681..489c9b32e 100644 --- a/docs/source/markdown/podman-pod-create.1.md +++ b/docs/source/markdown/podman-pod-create.1.md @@ -39,6 +39,10 @@ Set custom DNS search domains in the /etc/resolv.conf file that will be shared b Print usage statement. +**--hostname**=name + +Set a hostname to the pod + **--infra**=**true**|**false** Create an infra container and associate it with the pod. An infra container is a lightweight container used to coordinate the shared kernel namespace of a pod. Default: true. @@ -79,7 +83,7 @@ Set network mode for the pod. Supported values are *bridge* (the default), *host Disable creation of /etc/hosts for the pod. -**--podidfile**=*podid* +**--pod-id-file**=*path* Write the pod ID to the file. diff --git a/docs/source/markdown/podman-pod-prune.1.md b/docs/source/markdown/podman-pod-prune.1.md index 478f563c3..5b74adade 100644 --- a/docs/source/markdown/podman-pod-prune.1.md +++ b/docs/source/markdown/podman-pod-prune.1.md @@ -11,7 +11,7 @@ podman-pod-prune - Remove all stopped pods and their containers ## OPTIONS -**--force** **-f** +**--force**, **-f** Force removal of all running pods and their containers. The default is false. ## EXAMPLES diff --git a/docs/source/markdown/podman-pod-ps.1.md b/docs/source/markdown/podman-pod-ps.1.md index 887682f19..035c20c7f 100644 --- a/docs/source/markdown/podman-pod-ps.1.md +++ b/docs/source/markdown/podman-pod-ps.1.md @@ -38,7 +38,7 @@ Includes the container IDs in the container info field Includes the container statuses in the container info field -**--latest**,**-l** +**--latest**, **-l** Show the latest pod created (all states) @@ -48,6 +48,10 @@ The latest option is not supported on the remote client. Display the extended information +**--ns** + +Display namespace information of the pod + **--quiet**, **-q** Print the numeric IDs of the pods only diff --git a/docs/source/markdown/podman-pod-stop.1.md b/docs/source/markdown/podman-pod-stop.1.md index 73c347cec..42d2a2d3f 100644 --- a/docs/source/markdown/podman-pod-stop.1.md +++ b/docs/source/markdown/podman-pod-stop.1.md @@ -27,7 +27,7 @@ Instead of providing the pod name or ID, stop the last created pod. The latest option is not supported on the remote client. -**--timeout**, **--time**, **-t**=*time* +**--timeout**, **-t**=*time* Timeout to wait before forcibly stopping the containers in the pod. diff --git a/docs/source/markdown/podman-pull.1.md b/docs/source/markdown/podman-pull.1.md index a22d2db42..b3e35c672 100644 --- a/docs/source/markdown/podman-pull.1.md +++ b/docs/source/markdown/podman-pull.1.md @@ -156,6 +156,8 @@ Storing signatures registries.conf is the configuration file which specifies which container registries should be consulted when completing image names which do not include a registry or domain portion. +NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`. + ## SEE ALSO podman(1), podman-push(1), podman-login(1), containers-registries.conf(5) diff --git a/docs/source/markdown/podman-restart.1.md b/docs/source/markdown/podman-restart.1.md index 08fa29244..6507530e1 100644 --- a/docs/source/markdown/podman-restart.1.md +++ b/docs/source/markdown/podman-restart.1.md @@ -26,7 +26,7 @@ The latest option is not supported on the remote client. **--running** Restart all containers that are already in the *running* state. -**--timeout**=*time* +**-t**, **--time**, **--timeout**=*time* Timeout to wait before forcibly stopping the container. diff --git a/docs/source/markdown/podman-rmi.1.md b/docs/source/markdown/podman-rmi.1.md index 78ef2b157..2e093e9c8 100644 --- a/docs/source/markdown/podman-rmi.1.md +++ b/docs/source/markdown/podman-rmi.1.md @@ -13,7 +13,7 @@ Removes one or more locally stored images. ## OPTIONS -**-all**, **-a** +**--all**, **-a** Remove all images in the local storage. diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index bc99a83ca..3225654b6 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -225,6 +225,10 @@ Note: if the user only has access rights via a group, accessing the device from inside a rootless container will fail. The **crun**(1) runtime offers a workaround for this by adding the option **--annotation run.oci.keep_original_groups=1**. +**--device-cgroup-rule**=rule + +Add a rule to the cgroup allowed devices list + **--device-read-bps**=_path_:_rate_ Limit read rate (in bytes per second) from a device (e.g. **--device-read-bps=/dev/sda:1mb**). @@ -253,9 +257,9 @@ is the case the **--dns** flags is necessary for every run. The special value **none** can be specified to disable creation of _/etc/resolv.conf_ in the container by Podman. The _/etc/resolv.conf_ file in the image will be used without changes. -**--dns-option**=*option* +**--dns-opt**=*option* -Set custom DNS options. Invalid if using **--dns-option** with **--network** that is set to **none** or **container:**_id_. +Set custom DNS options. Invalid if using **--dns-opt** with **--network** that is set to **none** or **container:**_id_. **--dns-search**=*domain* @@ -342,7 +346,7 @@ value can be expressed in a time format such as **1m22s**. The default value is Print usage statement -**--hostname**=*name* +**-h**, **--hostname**=*name* Container host name @@ -547,7 +551,7 @@ This works for both background and foreground containers. **--network**, **--net**=*mode* -Set the network mode for the container. Invalid if using **--dns**, **--dns-option**, or **--dns-search** with **--network** that is set to **none** or **container:**_id_. +Set the network mode for the container. Invalid if using **--dns**, **--dns-opt**, or **--dns-search** with **--network** that is set to **none** or **container:**_id_. Valid _mode_ values are: @@ -1335,6 +1339,8 @@ b **/etc/subgid** +NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`. + ## SEE ALSO **subgid**(5), **subuid**(5), **libpod.conf**(5), **systemd.unit**(5), **setsebool**(8), **slirp4netns**(1), **fuse-overlayfs**(1). diff --git a/docs/source/markdown/podman-volume-create.1.md b/docs/source/markdown/podman-volume-create.1.md index b354f396f..5672a80a5 100644 --- a/docs/source/markdown/podman-volume-create.1.md +++ b/docs/source/markdown/podman-volume-create.1.md @@ -23,7 +23,7 @@ Specify the volume driver name (default local). Print usage statement -**-l**, **-label**=*label* +**-l**, **--label**=*label* Set metadata for a volume (e.g., --label mykey=value). diff --git a/docs/source/markdown/podman-volume-inspect.1.md b/docs/source/markdown/podman-volume-inspect.1.md index ac5b6c977..b889383b1 100644 --- a/docs/source/markdown/podman-volume-inspect.1.md +++ b/docs/source/markdown/podman-volume-inspect.1.md @@ -20,7 +20,7 @@ Volumes can be queried individually by providing their full name or a unique par Inspect all volumes. -**--format**=*format* +**-f**, **--format**=*format* Format volume output using Go template diff --git a/docs/source/markdown/podman-volume-ls.1.md b/docs/source/markdown/podman-volume-ls.1.md index d431c7c6e..a4fb925f8 100644 --- a/docs/source/markdown/podman-volume-ls.1.md +++ b/docs/source/markdown/podman-volume-ls.1.md @@ -14,7 +14,7 @@ flag. Use the **--quiet** flag to print only the volume names. ## OPTIONS -**--filter**=*filter* +**-f**, **--filter**=*filter* Filter volume output. diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/podman.1.md index 853b5ecec..86d246e87 100644 --- a/docs/source/markdown/podman.1.md +++ b/docs/source/markdown/podman.1.md @@ -104,11 +104,11 @@ specify additional options via the `--storage-opt` flag. Storage driver option, Default storage driver options are configured in /etc/containers/storage.conf (`$HOME/.config/containers/storage.conf` in rootless mode). The `STORAGE_OPTS` environment variable overrides the default. The --storage-opt specified options overrides all. -**--syslog** +**--syslog**=*true|false* -Output logging information to syslog as well as the console. +Output logging information to syslog as well as the console (default *false*). -On remote clients, logging is directed to the file $HOME/.config/containers/podman.log +On remote clients, logging is directed to the file $HOME/.config/containers/podman.log. **--tmpdir** diff --git a/docs/tutorials/rootless_tutorial.md b/docs/tutorials/rootless_tutorial.md index 5978d1210..8e048c746 100644 --- a/docs/tutorials/rootless_tutorial.md +++ b/docs/tutorials/rootless_tutorial.md @@ -110,34 +110,6 @@ The Podman configuration files for root reside in `/usr/share/containers` with o The default authorization file used by the `podman login` and `podman logout` commands reside in `${XDG_RUNTIME_DIR}/containers/auth.json`. -## Systemd unit for rootless container - -``` -[Unit] -Description=nginx -Requires=user@1001.service -After=user@1001.service -[Service] -Type=simple -KillMode=none -MemoryMax=200M -ExecStartPre=-/usr/bin/podman rm -f nginx -ExecStartPre=/usr/bin/podman pull nginx -ExecStart=/usr/bin/podman run --name=nginx -p 8080:80 -v /home/nginx/html:/usr/share/nginx/html:Z nginx -ExecStop=/usr/bin/podman stop nginx -Restart=always -User=nginx -Group=nginx -[Install] -WantedBy=multi-user.target -``` - -This example unit will launch a nginx container using the existing user nginx with id 1001, serving static content from /home/nginx/html and limited to 200MB of RAM. - -You can use all the usual systemd flags to control the process, including capabilities and cgroup directives to limit memory or CPU. - -See #3866 for more details. - ## More information If you are still experiencing problems running Podman in a rootless environment, please refer to the [Shortcomings of Rootless Podman](https://github.com/containers/libpod/blob/master/rootless.md) page which lists known issues and solutions to known issues in this environment. @@ -6,15 +6,16 @@ require ( github.com/BurntSushi/toml v0.3.1 github.com/buger/goterm v0.0.0-20181115115552-c206103e1f37 github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b - github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 + github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect + github.com/containernetworking/cni v0.7.2-0.20200304161608-4fae32b84921 github.com/containernetworking/plugins v0.8.5 github.com/containers/buildah v1.14.2 github.com/containers/common v0.4.2 github.com/containers/conmon v2.0.10+incompatible github.com/containers/image/v5 v5.2.1 github.com/containers/psgo v1.4.0 - github.com/containers/storage v1.16.1 - github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f + github.com/containers/storage v1.16.2 + github.com/coreos/go-systemd/v22 v22.0.0 github.com/cri-o/ocicni v0.1.1-0.20190920040751-deac903fd99b github.com/cyphar/filepath-securejoin v0.2.2 github.com/davecgh/go-spew v1.1.1 @@ -26,7 +27,7 @@ require ( github.com/etcd-io/bbolt v1.3.3 github.com/fsnotify/fsnotify v1.4.7 github.com/ghodss/yaml v1.0.0 - github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e + github.com/godbus/dbus/v5 v5.0.3 github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf github.com/google/uuid v1.1.1 github.com/gorilla/mux v1.7.4 @@ -61,7 +62,6 @@ require ( golang.org/x/sync v0.0.0-20190423024810-112230192c58 golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2 gopkg.in/yaml.v2 v2.2.8 - gotest.tools/v3 v3.0.2 // indirect k8s.io/api v0.17.3 k8s.io/apimachinery v0.17.3 k8s.io/client-go v0.0.0-20190620085101-78d2af792bab @@ -1,5 +1,6 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg= github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= @@ -9,8 +10,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= @@ -37,9 +36,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver v3.1.0+incompatible h1:7hqmJYuaEK3qwVjWubYiht3j93YI0WQBuysxHIfUriU= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= -github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/buger/goterm v0.0.0-20181115115552-c206103e1f37 h1:uxxtrnACqI9zK4ENDMf0WpXfUsHP5V8liuq5QdgDISU= github.com/buger/goterm v0.0.0-20181115115552-c206103e1f37/go.mod h1:u9UyCz2eTrSGy6fbupqJ54eY5c4IC8gREQ1053dK12U= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= @@ -56,7 +52,6 @@ github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtM github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.0 h1:xjvXQWABwS2uiv3TWgQt5Uth60Gu86LTGZXMJkjc7rY= github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/continuity v0.0.0-20180216233310-d8fb8589b0e8/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= @@ -66,27 +61,12 @@ github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kw github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 h1:rqUVLD8I859xRgUx/WMC3v7QAFqbLKZbs+0kqYboRJc= github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.7.2-0.20200304161608-4fae32b84921 h1:eUMd8hlGasYcg1tBqETZtxaW3a7EIxqY7Z1g65gcKQg= +github.com/containernetworking/cni v0.7.2-0.20200304161608-4fae32b84921/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/plugins v0.8.5 h1:pCvEMrFf7yzJI8+/D/7jkvE96KD52b7/Eu+jpahihy8= github.com/containernetworking/plugins v0.8.5/go.mod h1:UZ2539umj8djuRQmBxuazHeJbYrLV8BSBejkk+she6o= -github.com/containers/buildah v1.13.1 h1:EdhllQxXmOZ56mGFf68AkrpIj9XtEkkGq0WaPWFuGM0= -github.com/containers/buildah v1.13.1/go.mod h1:U0LcOzSqoYdyQC5L2hMeLbtCDuCCLxmZV1eb+SWY4GA= -github.com/containers/buildah v1.14.1-0.20200219125159-7cd6f7d04842 h1:OM/a/RYfWe721ZjDJf4RyGhyvEGJIdmx9tYZl1bq5jY= -github.com/containers/buildah v1.14.1-0.20200219125159-7cd6f7d04842/go.mod h1:dmPZHakxkaCVu5oefZaLVAZXNGva9PqVSMVK3hkarvA= -github.com/containers/buildah v1.14.1-0.20200222102502-002dffb8d2cb h1:FvrlxHKZoo8PYpzev0pM8S+lPBj+p7yK4yVgK95uJ1U= -github.com/containers/buildah v1.14.1-0.20200222102502-002dffb8d2cb/go.mod h1:tsos+87us4LpjyPwtgXQmDkOj5SYrpsMyRVcDTOQ5aA= -github.com/containers/buildah v1.14.1-0.20200225113533-39bd7e0a7a73 h1:TyGEOd0O6oigg1WA+bprBTgeHH8815fNgOUYhh1I2Vs= -github.com/containers/buildah v1.14.1-0.20200225113533-39bd7e0a7a73/go.mod h1:sdMVVcCTvvAj9o9dk/j6EnNJJadjxqjcI4Yy9WoWxSg= -github.com/containers/buildah v1.14.1-0.20200227103754-f0c3fd7c3d34 h1:SaK9ADT5JdVL29Z8snwl+bqmi1usnNyis+7Hd5+jJjw= -github.com/containers/buildah v1.14.1-0.20200227103754-f0c3fd7c3d34/go.mod h1:sdMVVcCTvvAj9o9dk/j6EnNJJadjxqjcI4Yy9WoWxSg= -github.com/containers/buildah v1.14.1 h1:H0uubyWJN98xRFmwzJeJDb5NIypx+sPcJu5kCzO6hGs= -github.com/containers/buildah v1.14.1/go.mod h1:sdMVVcCTvvAj9o9dk/j6EnNJJadjxqjcI4Yy9WoWxSg= github.com/containers/buildah v1.14.2 h1:rzrOVqWL3C3xA3MBmkDgWntRsBgkI3FGKODluBO+svU= github.com/containers/buildah v1.14.2/go.mod h1:HZ6MuZfHYq6ZMeoV9o3k9GwoCk1p3RWZOYbBXZtR7wE= -github.com/containers/common v0.0.7 h1:eKYZLKfJ2d/RNDgecLDFv45cHb4imYzIcrQHx1Y029M= -github.com/containers/common v0.0.7/go.mod h1:lhWV3MLhO1+KGE2x6v9+K38MxpjXGso+edmpkFnCOqI= -github.com/containers/common v0.3.0 h1:9ysL/OfPcMls1Ac3jzFA4XZJVSD/JG7Dst3uQSwQtwA= -github.com/containers/common v0.3.0/go.mod h1:AiPCv0ZcBOVshnup/X6MuaqkySZQZ3iBWfInjJFIl40= -github.com/containers/common v0.4.1/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys= github.com/containers/common v0.4.2 h1:O5d1gj/xdpQdZi0MEivRQ/7AeRaVeHdbSP/bvShw458= github.com/containers/common v0.4.2/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys= github.com/containers/conmon v2.0.10+incompatible h1:EiwL41r5vx8SxG+dyUmbJ3baV9GUWjijPOdCkzM6gWU= @@ -104,15 +84,18 @@ github.com/containers/storage v1.16.0 h1:sD+s7BmiNBh61CuHN3j8PXGCwMtV9zPVJETAlsh github.com/containers/storage v1.16.0/go.mod h1:nqN09JSi1/RSI1UAUwDYXPRiGSlq5FPbNkN/xb0TfG0= github.com/containers/storage v1.16.1 h1:gVLVqbqaoyopLJbcQ9PQdsnm8SzVy6Vw24fofwMgkE0= github.com/containers/storage v1.16.1/go.mod h1:toFp72SLn/iyJ6YbrnrZ0bW63aH2Qw3dA8JVwL4ADPo= +github.com/containers/storage v1.16.2 h1:S77Y+lmJcnGoPEZB2OOrTrRGyjT8viDCGyhVNNz78h8= +github.com/containers/storage v1.16.2/go.mod h1:/RNmsK01ajCL+VtMSi3W8kHzpBwN+Q5gLYWgfw5wlMg= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-iptables v0.4.5 h1:DpHb9vJrZQEFMcVLFKAAGMUVX0XoRC0ptCthinRYm38= github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28= +github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -151,9 +134,11 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316 h1:moehPjPiGUaWdwgOl92xRyFHJyaqXDHcCyW9M6nmCK4= github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8= +github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -190,12 +175,15 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -209,6 +197,7 @@ github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/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/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= @@ -283,9 +272,11 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -432,6 +423,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -480,6 +472,7 @@ github.com/xeipuuv/gojsonschema v0.0.0-20190816131739-be0936907f66/go.mod h1:anY github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -576,7 +569,6 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= @@ -601,6 +593,7 @@ gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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= @@ -620,8 +613,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.0.0-20190620084959-7cf5895f2711/go.mod h1:TBhBqb1AWbBQbW3XRusr7n7E4v2+5ZY8r8sAMnyFC5A= diff --git a/libpod/config/config.go b/libpod/config/config.go index c72a0efc7..5d59f1bf2 100644 --- a/libpod/config/config.go +++ b/libpod/config/config.go @@ -437,7 +437,7 @@ func probeConmon(conmonBinary string) error { // with cgroupsv2. Other OCI runtimes are not yet supporting cgroupsv2. This // might change in the future. func NewConfig(userConfigPath string) (*Config, error) { - // Start with the default config and interatively merge fields in the system + // Start with the default config and iteratively merge fields in the system // configs. config, err := defaultConfigFromMemory() if err != nil { diff --git a/libpod/container_api.go b/libpod/container_api.go index dc7470f1a..039619ea6 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -282,24 +282,13 @@ func (c *Container) Exec(tty, privileged bool, env map[string]string, cmd []stri opts.Resize = resize opts.DetachKeys = detachKeys - pid := 0 - pipeDataChan, attachChan, err := c.ociRuntime.ExecContainer(c, sessionID, opts) - // if pipeDataChan isn't nil, we should set the err - if pipeDataChan != nil { - pidData := <-pipeDataChan - if pidData.err != nil { - err = pidData.err - } - pid = pidData.data - } + pid, attachChan, err := c.ociRuntime.ExecContainer(c, sessionID, opts) if err != nil { ec := define.ExecErrorCodeGeneric // Conmon will pass a non-zero exit code from the runtime as a pid here. // we differentiate a pid with an exit code by sending it as negative, so reverse // that change and return the exit code the runtime failed with. - // Make sure the value is not ErrorConmonRead, as that is a podman set bogus value - // and not sent by conmon (and thus has no special meaning) - if pid < 0 && pid != define.ErrorConmonRead { + if pid < 0 { ec = -1 * pid } return ec, err @@ -329,24 +318,18 @@ func (c *Container) Exec(tty, privileged bool, env map[string]string, cmd []stri lastErr := <-attachChan - exitCodeData := <-pipeDataChan - if exitCodeData.err != nil { + exitCode, err := c.readExecExitCode(sessionID) + if err != nil { if lastErr != nil { logrus.Errorf(lastErr.Error()) } - lastErr = exitCodeData.err + lastErr = err } - if exitCodeData.data != 0 { + if exitCode != 0 { if lastErr != nil { logrus.Errorf(lastErr.Error()) } - // ErrorConmonRead is a bogus value set by podman to indicate reading a value from - // conmon failed. Since it is specifically not a valid exit code, we should set - // a generic error here - if exitCodeData.data == define.ErrorConmonRead { - exitCodeData.data = define.ExecErrorCodeGeneric - } - lastErr = errors.Wrapf(define.ErrOCIRuntime, "non zero exit code: %d", exitCodeData.data) + lastErr = errors.Wrapf(define.ErrOCIRuntime, "non zero exit code: %d", exitCode) } // Lock again @@ -357,7 +340,7 @@ func (c *Container) Exec(tty, privileged bool, env map[string]string, cmd []stri // Sync the container again to pick up changes in state if err := c.syncContainer(); err != nil { logrus.Errorf("error syncing container %s state to remove exec session %s", c.ID(), sessionID) - return exitCodeData.data, lastErr + return exitCode, lastErr } // Remove the exec session from state @@ -365,7 +348,7 @@ func (c *Container) Exec(tty, privileged bool, env map[string]string, cmd []stri if err := c.save(); err != nil { logrus.Errorf("Error removing exec session %s from container %s state: %v", sessionID, c.ID(), err) } - return exitCodeData.data, lastErr + return exitCode, lastErr } // AttachStreams contains streams that will be attached to the container @@ -412,7 +395,7 @@ func (c *Container) Attach(streams *AttachStreams, keys string, resize <-chan re // HTTPAttach forwards an attach session over a hijacked HTTP session. // HTTPAttach will consume and close the included httpCon, which is expected to // be sourced from a hijacked HTTP connection. -// The cancel channel is optional, and can be used to asyncronously cancel the +// The cancel channel is optional, and can be used to asynchronously cancel the // attach session. // The streams variable is only supported if the container was not a terminal, // and allows specifying which of the container's standard streams will be diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index a543a19c0..50ae72499 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -670,8 +670,8 @@ type InspectAdditionalNetwork struct { // DriverOpts is presently unused and maintained exclusively for // compatibility. DriverOpts map[string]string `json:"DriverOpts"` - // IPAMConfig is presently unused and maintained exlusively for - // compabitility. + // IPAMConfig is presently unused and maintained exclusively for + // compatibility. IPAMConfig map[string]string `json:"IPAMConfig"` // Links is presently unused and maintained exclusively for // compatibility. diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 67e02cc31..a0805c1fa 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -206,6 +206,28 @@ func (c *Container) execOCILog(sessionID string) string { return filepath.Join(c.execBundlePath(sessionID), "oci-log") } +// readExecExitCode reads the exit file for an exec session and returns +// the exit code +func (c *Container) readExecExitCode(sessionID string) (int, error) { + exitFile := filepath.Join(c.execExitFileDir(sessionID), c.ID()) + chWait := make(chan error) + defer close(chWait) + + _, err := WaitForFile(exitFile, chWait, time.Second*5) + if err != nil { + return -1, err + } + ec, err := ioutil.ReadFile(exitFile) + if err != nil { + return -1, err + } + ecInt, err := strconv.Atoi(string(ec)) + if err != nil { + return -1, err + } + return ecInt, nil +} + // Wait for the container's exit file to appear. // When it does, update our state based on it. func (c *Container) waitForExitFileAndSync() error { @@ -929,7 +951,7 @@ func (c *Container) completeNetworkSetup() error { return err } for _, line := range strings.Split(string(b), "\n") { - // only keep things that dont start with nameserver from the old + // only keep things that don't start with nameserver from the old // resolv.conf file if !strings.HasPrefix(line, "nameserver") { outResolvConf = append([]string{line}, outResolvConf...) diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go index 748715ed3..03010d8ed 100644 --- a/libpod/container_log_linux.go +++ b/libpod/container_log_linux.go @@ -11,7 +11,7 @@ import ( "time" "github.com/containers/libpod/libpod/logs" - journal "github.com/coreos/go-systemd/sdjournal" + journal "github.com/coreos/go-systemd/v22/sdjournal" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) diff --git a/libpod/define/exec_codes.go b/libpod/define/exec_codes.go index c2ec08666..f94616b33 100644 --- a/libpod/define/exec_codes.go +++ b/libpod/define/exec_codes.go @@ -1,7 +1,6 @@ package define import ( - "math" "strings" "github.com/pkg/errors" @@ -18,11 +17,6 @@ const ( ExecErrorCodeCannotInvoke = 126 // ExecErrorCodeNotFound is the error code to return when a command cannot be found ExecErrorCodeNotFound = 127 - // ErrorConmonRead is a bogus value that can neither be a valid PID or exit code. It is - // used because conmon will send a negative value when sending a PID back over a pipe FD - // to signify something went wrong in the runtime. We need to differentiate between that - // value and a failure on the podman side of reading that value. Thus, we use ErrorConmonRead - ErrorConmonRead = math.MinInt32 - 1 ) // TranslateExecErrorToExitCode takes an error and checks whether it diff --git a/libpod/events/journal_linux.go b/libpod/events/journal_linux.go index 9e6fffc29..482435038 100644 --- a/libpod/events/journal_linux.go +++ b/libpod/events/journal_linux.go @@ -7,8 +7,8 @@ import ( "strconv" "time" - "github.com/coreos/go-systemd/journal" - "github.com/coreos/go-systemd/sdjournal" + "github.com/coreos/go-systemd/v22/journal" + "github.com/coreos/go-systemd/v22/sdjournal" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) diff --git a/libpod/healthcheck_linux.go b/libpod/healthcheck_linux.go index dca72430d..5da2d311b 100644 --- a/libpod/healthcheck_linux.go +++ b/libpod/healthcheck_linux.go @@ -9,8 +9,8 @@ import ( "strings" "github.com/containers/libpod/pkg/rootless" - "github.com/coreos/go-systemd/dbus" - godbus "github.com/godbus/dbus" + "github.com/coreos/go-systemd/v22/dbus" + godbus "github.com/godbus/dbus/v5" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) diff --git a/libpod/image/filters.go b/libpod/image/filters.go index c54ca6333..8ca3526a0 100644 --- a/libpod/image/filters.go +++ b/libpod/image/filters.go @@ -3,13 +3,13 @@ package image import ( "context" "fmt" - "github.com/pkg/errors" "path/filepath" "strconv" "strings" "time" "github.com/containers/libpod/pkg/inspect" + "github.com/pkg/errors" "github.com/sirupsen/logrus" ) diff --git a/libpod/kube.go b/libpod/kube.go index 7a5ab670d..5511d303d 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -468,11 +468,26 @@ func generateKubeSecurityContext(c *Container) (*v1.SecurityContext, error) { return nil, err } + var selinuxOpts v1.SELinuxOptions + opts := strings.SplitN(c.config.Spec.Annotations[InspectAnnotationLabel], ":", 2) + if len(opts) == 2 { + switch opts[0] { + case "type": + selinuxOpts.Type = opts[1] + case "level": + selinuxOpts.Level = opts[1] + } + } + if len(opts) == 1 { + if opts[0] == "disable" { + selinuxOpts.Type = "spc_t" + } + } + sc := v1.SecurityContext{ - Capabilities: newCaps, - Privileged: &priv, - // TODO How do we know if selinux were passed into podman - //SELinuxOptions: + Capabilities: newCaps, + Privileged: &priv, + SELinuxOptions: &selinuxOpts, // RunAsNonRoot is an optional parameter; our first implementations should be root only; however // I'm leaving this as a bread-crumb for later //RunAsNonRoot: &nonRoot, diff --git a/libpod/logs/log.go b/libpod/logs/log.go index 200ef3e99..6ad2a305f 100644 --- a/libpod/logs/log.go +++ b/libpod/logs/log.go @@ -167,8 +167,7 @@ func (l *LogLine) String(options *LogOptions) string { var out string if options.Multi { if options.UseName { - cname := l.CName - out = fmt.Sprintf("%s ", cname) + out = l.CName + " " } else { cid := l.CID if len(cid) > 12 { diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index d57b1a8eb..5a27a2abb 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -117,10 +117,10 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re networkStatus := make([]*cnitypes.Result, 0) for idx, r := range results { - logrus.Debugf("[%d] CNI result: %v", idx, r.Result.String()) + logrus.Debugf("[%d] CNI result: %v", idx, r.Result) resultCurrent, err := cnitypes.GetResult(r.Result) if err != nil { - return nil, errors.Wrapf(err, "error parsing CNI plugin result %q: %v", r.Result.String(), err) + return nil, errors.Wrapf(err, "error parsing CNI plugin result %q: %v", r.Result, err) } networkStatus = append(networkStatus, resultCurrent) } diff --git a/libpod/oci.go b/libpod/oci.go index e5f9b2135..27edebefc 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -55,7 +55,7 @@ type OCIRuntime interface { // to output; otherwise, STDOUT and STDERR will be multiplexed, with // a header prepended as follows: 1-byte STREAM (0, 1, 2 for STDIN, // STDOUT, STDERR), 3 null (0x00) bytes, 4-byte big endian length. - // If a cancel channel is provided, it can be used to asyncronously + // If a cancel channel is provided, it can be used to asynchronously // termninate the attach session. Detach keys, if given, will also cause // the attach session to be terminated if provided via the STDIN // channel. If they are not provided, the default detach keys will be @@ -70,7 +70,7 @@ type OCIRuntime interface { // ExecContainer executes a command in a running container. // Returns an int (exit code), error channel (errors from attach), and // error (errors that occurred attempting to start the exec session). - ExecContainer(ctr *Container, sessionID string, options *ExecOptions) (chan DataAndErr, chan error, error) + ExecContainer(ctr *Container, sessionID string, options *ExecOptions) (int, chan error, error) // ExecStopContainer stops a given exec session in a running container. // SIGTERM with be sent initially, then SIGKILL after the given timeout. // If timeout is 0, SIGKILL will be sent immediately, and SIGTERM will @@ -159,10 +159,3 @@ type HTTPAttachStreams struct { Stdout bool Stderr bool } - -// DataAndErr is a generic structure for passing around an int and an error -// it is especially useful for getting information from conmon -type DataAndErr struct { - data int - err error -} diff --git a/libpod/oci_attach_linux.go b/libpod/oci_attach_linux.go index 5a8198d05..46c70e7eb 100644 --- a/libpod/oci_attach_linux.go +++ b/libpod/oci_attach_linux.go @@ -119,8 +119,8 @@ func (c *Container) attachToExec(streams *AttachStreams, keys string, resize <-c socketPath := buildSocketPath(sockPath) // 2: read from attachFd that the parent process has set up the console socket - if pipeData := readConmonPipeData(attachFd, ""); pipeData.err != nil { - return pipeData.err + if _, err := readConmonPipeData(attachFd, ""); err != nil { + return err } // 2: then attach diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index f260e3a39..a5530e448 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -30,7 +30,7 @@ import ( "github.com/containers/libpod/pkg/util" "github.com/containers/libpod/utils" pmount "github.com/containers/storage/pkg/mount" - "github.com/coreos/go-systemd/activation" + "github.com/coreos/go-systemd/v22/activation" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/selinux/go-selinux" "github.com/opencontainers/selinux/go-selinux/label" @@ -595,29 +595,31 @@ func (r *ConmonOCIRuntime) AttachResize(ctr *Container, newSize remotecommand.Te // ExecContainer executes a command in a running container // TODO: Split into Create/Start/Attach/Wait -func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options *ExecOptions) (chan DataAndErr, chan error, error) { +func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options *ExecOptions) (int, chan error, error) { if options == nil { - return nil, nil, errors.Wrapf(define.ErrInvalidArg, "must provide an ExecOptions struct to ExecContainer") + return -1, nil, errors.Wrapf(define.ErrInvalidArg, "must provide an ExecOptions struct to ExecContainer") } if len(options.Cmd) == 0 { - return nil, nil, errors.Wrapf(define.ErrInvalidArg, "must provide a command to execute") + return -1, nil, errors.Wrapf(define.ErrInvalidArg, "must provide a command to execute") } if sessionID == "" { - return nil, nil, errors.Wrapf(define.ErrEmptyID, "must provide a session ID for exec") + return -1, nil, errors.Wrapf(define.ErrEmptyID, "must provide a session ID for exec") } // create sync pipe to receive the pid parentSyncPipe, childSyncPipe, err := newPipe() if err != nil { - return nil, nil, errors.Wrapf(err, "error creating socket pair") + return -1, nil, errors.Wrapf(err, "error creating socket pair") } + defer errorhandling.CloseQuiet(parentSyncPipe) + // create start pipe to set the cgroup before running // attachToExec is responsible for closing parentStartPipe childStartPipe, parentStartPipe, err := newPipe() if err != nil { - return nil, nil, errors.Wrapf(err, "error creating socket pair") + return -1, nil, errors.Wrapf(err, "error creating socket pair") } // We want to make sure we close the parent{Start,Attach}Pipes if we fail @@ -636,7 +638,7 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options // attachToExec is responsible for closing parentAttachPipe parentAttachPipe, childAttachPipe, err := newPipe() if err != nil { - return nil, nil, errors.Wrapf(err, "error creating socket pair") + return -1, nil, errors.Wrapf(err, "error creating socket pair") } defer func() { @@ -656,7 +658,7 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options runtimeDir, err := util.GetRuntimeDir() if err != nil { - return nil, nil, err + return -1, nil, err } finalEnv := make([]string, 0, len(options.Env)) @@ -666,7 +668,7 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options processFile, err := prepareProcessExec(c, options.Cmd, finalEnv, options.Terminal, options.Cwd, options.User, sessionID) if err != nil { - return nil, nil, err + return -1, nil, err } var ociLog string @@ -715,7 +717,7 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options conmonEnv, extraFiles, err := r.configureConmonEnv(runtimeDir) if err != nil { - return nil, nil, err + return -1, nil, err } if options.PreserveFDs > 0 { @@ -746,10 +748,10 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options childrenClosed = true if err != nil { - return nil, nil, errors.Wrapf(err, "cannot start container %s", c.ID()) + return -1, nil, errors.Wrapf(err, "cannot start container %s", c.ID()) } if err := r.moveConmonToCgroupAndSignal(c, execCmd, parentStartPipe); err != nil { - return nil, nil, err + return -1, nil, err } if options.PreserveFDs > 0 { @@ -772,16 +774,9 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options }() attachToExecCalled = true - dataChan := make(chan DataAndErr) - go func() { - // read the exec pid - dataChan <- readConmonPipeData(parentSyncPipe, ociLog) - // read the exec exit code - dataChan <- readConmonPipeData(parentSyncPipe, ociLog) - errorhandling.CloseQuiet(parentSyncPipe) - }() + pid, err := readConmonPipeData(parentSyncPipe, ociLog) - return dataChan, attachChan, err + return pid, attachChan, err } // ExecStopContainer stops a given exec session in a running container. @@ -1211,14 +1206,14 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co return err } - pipeData := readConmonPipeData(parentSyncPipe, ociLog) - if pipeData.err != nil { + pid, err := readConmonPipeData(parentSyncPipe, ociLog) + if err != nil { if err2 := r.DeleteContainer(ctr); err2 != nil { logrus.Errorf("Error removing container %s from runtime after creation failed", ctr.ID()) } - return pipeData.err + return err } - ctr.state.PID = pipeData.data + ctr.state.PID = pid conmonPID, err := readConmonPidFile(ctr.config.ConmonPidFile) if err != nil { @@ -1530,7 +1525,7 @@ func readConmonPidFile(pidFile string) (int, error) { } // readConmonPipeData attempts to read a syncInfo struct from the pipe -func readConmonPipeData(pipe *os.File, ociLog string) DataAndErr { +func readConmonPipeData(pipe *os.File, ociLog string) (int, error) { // syncInfo is used to return data from monitor process to daemon type syncInfo struct { Data int `json:"data"` @@ -1557,7 +1552,7 @@ func readConmonPipeData(pipe *os.File, ociLog string) DataAndErr { ch <- syncStruct{si: si} }() - data := define.ErrorConmonRead + data := -1 select { case ss := <-ch: if ss.err != nil { @@ -1566,17 +1561,11 @@ func readConmonPipeData(pipe *os.File, ociLog string) DataAndErr { if err == nil { var ociErr ociError if err := json.Unmarshal(ociLogData, &ociErr); err == nil { - return DataAndErr{ - data: data, - err: getOCIRuntimeError(ociErr.Msg), - } + return -1, getOCIRuntimeError(ociErr.Msg) } } } - return DataAndErr{ - data: data, - err: errors.Wrapf(ss.err, "container create failed (no logs from conmon)"), - } + return -1, errors.Wrapf(ss.err, "container create failed (no logs from conmon)") } logrus.Debugf("Received: %d", ss.si.Data) if ss.si.Data < 0 { @@ -1585,36 +1574,21 @@ func readConmonPipeData(pipe *os.File, ociLog string) DataAndErr { if err == nil { var ociErr ociError if err := json.Unmarshal(ociLogData, &ociErr); err == nil { - return DataAndErr{ - data: ss.si.Data, - err: getOCIRuntimeError(ociErr.Msg), - } + return ss.si.Data, getOCIRuntimeError(ociErr.Msg) } } } // If we failed to parse the JSON errors, then print the output as it is if ss.si.Message != "" { - return DataAndErr{ - data: ss.si.Data, - err: getOCIRuntimeError(ss.si.Message), - } - } - return DataAndErr{ - data: ss.si.Data, - err: errors.Wrapf(define.ErrInternal, "container create failed"), + return ss.si.Data, getOCIRuntimeError(ss.si.Message) } + return ss.si.Data, errors.Wrapf(define.ErrInternal, "container create failed") } data = ss.si.Data case <-time.After(define.ContainerCreateTimeout): - return DataAndErr{ - data: data, - err: errors.Wrapf(define.ErrInternal, "container creation timeout"), - } - } - return DataAndErr{ - data: data, - err: nil, + return -1, errors.Wrapf(define.ErrInternal, "container creation timeout") } + return data, nil } // writeConmonPipeData writes nonse data to a pipe diff --git a/libpod/oci_missing.go b/libpod/oci_missing.go index 1b7c1979d..ff7eea625 100644 --- a/libpod/oci_missing.go +++ b/libpod/oci_missing.go @@ -121,8 +121,8 @@ func (r *MissingRuntime) AttachResize(ctr *Container, newSize remotecommand.Term } // ExecContainer is not available as the runtime is missing -func (r *MissingRuntime) ExecContainer(ctr *Container, sessionID string, options *ExecOptions) (chan DataAndErr, chan error, error) { - return nil, nil, r.printError() +func (r *MissingRuntime) ExecContainer(ctr *Container, sessionID string, options *ExecOptions) (int, chan error, error) { + return -1, nil, r.printError() } // ExecStopContainer is not available as the runtime is missing. diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index de93fdce7..ba2a6b93e 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -10,6 +10,7 @@ import ( "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" + "github.com/containers/libpod/pkg/cgroups" "github.com/containers/libpod/pkg/rootless" "github.com/containers/storage/pkg/stringid" spec "github.com/opencontainers/runtime-spec/specs-go" @@ -438,9 +439,16 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool, if err := c.ociRuntime.KillContainer(c, 9, false); err != nil { return err } - if err := c.unpause(); err != nil { + isV2, err := cgroups.IsCgroup2UnifiedMode() + if err != nil { return err } + // cgroups v1 and v2 handle signals on paused processes differently + if !isV2 { + if err := c.unpause(); err != nil { + return err + } + } // Need to update container state to make sure we know it's stopped if err := c.waitForExitFileAndSync(); err != nil { return err diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index bae1c1ed8..6ac32878b 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -21,7 +21,7 @@ import ( "github.com/containers/image/v5/directory" dockerarchive "github.com/containers/image/v5/docker/archive" ociarchive "github.com/containers/image/v5/oci/archive" - "github.com/opencontainers/image-spec/specs-go/v1" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // Runtime API @@ -209,11 +209,11 @@ func (r *Runtime) Import(ctx context.Context, source string, reference string, c } // donwloadFromURL downloads an image in the format "https:/example.com/myimage.tar" -// and temporarily saves in it /var/tmp/importxyz, which is deleted after the image is imported +// and temporarily saves in it $TMPDIR/importxyz, which is deleted after the image is imported func downloadFromURL(source string) (string, error) { fmt.Printf("Downloading from %q\n", source) - outFile, err := ioutil.TempFile("/var/tmp", "import") + outFile, err := ioutil.TempFile(util.Tmpdir(), "import") if err != nil { return "", errors.Wrap(err, "error creating file") } @@ -234,9 +234,9 @@ func downloadFromURL(source string) (string, error) { } // DownloadFromFile reads all of the content from the reader and temporarily -// saves in it /var/tmp/importxyz, which is deleted after the image is imported +// saves in it $TMPDIR/importxyz, which is deleted after the image is imported func DownloadFromFile(reader *os.File) (string, error) { - outFile, err := ioutil.TempFile("/var/tmp", "import") + outFile, err := ioutil.TempFile(util.Tmpdir(), "import") if err != nil { return "", errors.Wrap(err, "error creating file") } diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go index be590a5c8..279cafa39 100644 --- a/libpod/runtime_pod_infra_linux.go +++ b/libpod/runtime_pod_infra_linux.go @@ -10,7 +10,7 @@ import ( "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/util" - "github.com/opencontainers/image-spec/specs-go/v1" + v1 "github.com/opencontainers/image-spec/specs-go/v1" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" "github.com/pkg/errors" diff --git a/libpod/storage.go b/libpod/storage.go index 6375d031b..d675f4ffe 100644 --- a/libpod/storage.go +++ b/libpod/storage.go @@ -8,7 +8,7 @@ import ( "github.com/containers/image/v5/types" "github.com/containers/libpod/libpod/define" "github.com/containers/storage" - "github.com/opencontainers/image-spec/specs-go/v1" + v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" diff --git a/pkg/api/handlers/compat/container_start.go b/pkg/api/handlers/compat/container_start.go new file mode 100644 index 000000000..d26ef2c82 --- /dev/null +++ b/pkg/api/handlers/compat/container_start.go @@ -0,0 +1,60 @@ +package compat + +import ( + "net/http" + + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/gorilla/schema" + "github.com/pkg/errors" +) + +func StopContainer(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + + // /{version}/containers/(name)/stop + query := struct { + Timeout int `schema:"t"` + }{ + // override any golang type defaults + } + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) + return + } + + name := utils.GetName(r) + con, err := runtime.LookupContainer(name) + if err != nil { + utils.ContainerNotFound(w, name, err) + return + } + + state, err := con.State() + if err != nil { + utils.InternalServerError(w, errors.Wrapf(err, "unable to get state for Container %s", name)) + return + } + // If the Container is stopped already, send a 304 + if state == define.ContainerStateStopped || state == define.ContainerStateExited { + utils.WriteResponse(w, http.StatusNotModified, "") + return + } + + var stopError error + if query.Timeout > 0 { + stopError = con.StopWithTimeout(uint(query.Timeout)) + } else { + stopError = con.Stop() + } + if stopError != nil { + utils.InternalServerError(w, errors.Wrapf(stopError, "failed to stop %s", name)) + return + } + + // Success + utils.WriteResponse(w, http.StatusNoContent, "") +} diff --git a/pkg/api/handlers/generic/containers.go b/pkg/api/handlers/compat/containers.go index ab587ded4..1298e7fa4 100644 --- a/pkg/api/handlers/generic/containers.go +++ b/pkg/api/handlers/compat/containers.go @@ -1,4 +1,4 @@ -package generic +package compat import ( "encoding/binary" @@ -7,9 +7,11 @@ import ( "strconv" "strings" "sync" + "syscall" "time" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/logs" "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" @@ -34,12 +36,26 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) { errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) return } - if query.Link { + + if query.Link && !utils.IsLibpodRequest(r) { utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, utils.ErrLinkNotSupport) return } - utils.RemoveContainer(w, r, query.Force, query.Vols) + + runtime := r.Context().Value("runtime").(*libpod.Runtime) + name := utils.GetName(r) + con, err := runtime.LookupContainer(name) + if err != nil { + utils.ContainerNotFound(w, name, err) + return + } + + if err := runtime.RemoveContainer(r.Context(), con, query.Force, query.Vols); err != nil { + utils.InternalServerError(w, err) + return + } + utils.WriteResponse(w, http.StatusNoContent, "") } func ListContainers(w http.ResponseWriter, r *http.Request) { @@ -57,6 +73,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) { }{ // override any golang type defaults } + if err := decoder.Decode(&query, r.URL.Query()); err != nil { utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) return @@ -85,7 +102,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) { var list = make([]*handlers.Container, len(containers)) for i, ctnr := range containers { - api, err := handlers.LibpodToContainer(ctnr, infoData) + api, err := handlers.LibpodToContainer(ctnr, infoData, query.Size) if err != nil { utils.InternalServerError(w, err) return @@ -97,6 +114,17 @@ func ListContainers(w http.ResponseWriter, r *http.Request) { func GetContainer(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + Size bool `schema:"size"` + }{ + // override any golang type defaults + } + + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) + return + } name := utils.GetName(r) ctnr, err := runtime.LookupContainer(name) @@ -104,7 +132,7 @@ func GetContainer(w http.ResponseWriter, r *http.Request) { utils.ContainerNotFound(w, name, err) return } - api, err := handlers.LibpodToContainerJSON(ctnr) + api, err := handlers.LibpodToContainerJSON(ctnr, query.Size) if err != nil { utils.InternalServerError(w, err) return @@ -114,18 +142,51 @@ func GetContainer(w http.ResponseWriter, r *http.Request) { func KillContainer(w http.ResponseWriter, r *http.Request) { // /{version}/containers/(name)/kill - con, err := utils.KillContainer(w, r) + runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + Signal syscall.Signal `schema:"signal"` + }{ + Signal: syscall.SIGKILL, + } + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) + return + } + name := utils.GetName(r) + con, err := runtime.LookupContainer(name) + if err != nil { + utils.ContainerNotFound(w, name, err) + return + } + + state, err := con.State() if err != nil { + utils.InternalServerError(w, err) return } - // the kill behavior for docker differs from podman in that they appear to wait - // for the Container to croak so the exit code is accurate immediately after the - // kill is sent. libpod does not. but we can add a wait here only for the docker - // side of things and mimic that behavior - if _, err = con.Wait(); err != nil { - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to wait for Container %s", con.ID())) + + // If the Container is stopped already, send a 409 + if state == define.ContainerStateStopped || state == define.ContainerStateExited { + utils.Error(w, fmt.Sprintf("Container %s is not running", name), http.StatusConflict, errors.New(fmt.Sprintf("Cannot kill Container %s, it is not running", name))) return } + + err = con.Kill(uint(query.Signal)) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "unable to kill Container %s", name)) + } + + if utils.IsLibpodRequest(r) { + // the kill behavior for docker differs from podman in that they appear to wait + // for the Container to croak so the exit code is accurate immediately after the + // kill is sent. libpod does not. but we can add a wait here only for the docker + // side of things and mimic that behavior + if _, err = con.Wait(); err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to wait for Container %s", con.ID())) + return + } + } // Success utils.WriteResponse(w, http.StatusNoContent, "") } diff --git a/pkg/api/handlers/containers_attach.go b/pkg/api/handlers/compat/containers_attach.go index 5a799a20c..da7b5bb0c 100644 --- a/pkg/api/handlers/containers_attach.go +++ b/pkg/api/handlers/compat/containers_attach.go @@ -1,4 +1,4 @@ -package handlers +package compat import ( "net/http" diff --git a/pkg/api/handlers/generic/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 7e542752f..6b8440fc2 100644 --- a/pkg/api/handlers/generic/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -1,4 +1,4 @@ -package generic +package compat import ( "encoding/json" diff --git a/pkg/api/handlers/compat/containers_pause.go b/pkg/api/handlers/compat/containers_pause.go new file mode 100644 index 000000000..060bdbaeb --- /dev/null +++ b/pkg/api/handlers/compat/containers_pause.go @@ -0,0 +1,28 @@ +package compat + +import ( + "net/http" + + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers/utils" +) + +func PauseContainer(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + + // /{version}/containers/(name)/pause + name := utils.GetName(r) + con, err := runtime.LookupContainer(name) + if err != nil { + utils.ContainerNotFound(w, name, err) + return + } + + // the api does not error if the Container is already paused, so just into it + if err := con.Pause(); err != nil { + utils.InternalServerError(w, err) + return + } + // Success + utils.WriteResponse(w, http.StatusNoContent, "") +} diff --git a/pkg/api/handlers/compat/containers_prune.go b/pkg/api/handlers/compat/containers_prune.go new file mode 100644 index 000000000..a56c3903d --- /dev/null +++ b/pkg/api/handlers/compat/containers_prune.go @@ -0,0 +1,64 @@ +package compat + +import ( + "net/http" + + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/docker/docker/api/types" + "github.com/gorilla/schema" + "github.com/pkg/errors" +) + +func PruneContainers(w http.ResponseWriter, r *http.Request) { + var ( + delContainers []string + space int64 + ) + runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + + query := struct { + Filters map[string][]string `schema:"filters"` + }{} + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) + return + } + + filterFuncs, err := utils.GenerateFilterFuncsFromMap(runtime, query.Filters) + if err != nil { + utils.InternalServerError(w, err) + return + } + prunedContainers, pruneErrors, err := runtime.PruneContainers(filterFuncs) + if err != nil { + utils.InternalServerError(w, err) + return + } + + // Libpod response differs + if utils.IsLibpodRequest(r) { + var response []handlers.LibpodContainersPruneReport + for ctrID, size := range prunedContainers { + response = append(response, handlers.LibpodContainersPruneReport{ID: ctrID, SpaceReclaimed: size}) + } + for ctrID, err := range pruneErrors { + response = append(response, handlers.LibpodContainersPruneReport{ID: ctrID, PruneError: err.Error()}) + } + utils.WriteResponse(w, http.StatusOK, response) + return + } + for ctrID, size := range prunedContainers { + if pruneErrors[ctrID] == nil { + space += size + delContainers = append(delContainers, ctrID) + } + } + report := types.ContainersPruneReport{ + ContainersDeleted: delContainers, + SpaceReclaimed: uint64(space), + } + utils.WriteResponse(w, http.StatusOK, report) +} diff --git a/pkg/api/handlers/compat/containers_restart.go b/pkg/api/handlers/compat/containers_restart.go new file mode 100644 index 000000000..5b8fafaa4 --- /dev/null +++ b/pkg/api/handlers/compat/containers_restart.go @@ -0,0 +1,61 @@ +package compat + +import ( + "fmt" + "net/http" + + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/gorilla/schema" + "github.com/pkg/errors" +) + +func RestartContainer(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + // /{version}/containers/(name)/restart + query := struct { + Timeout int `schema:"t"` + }{ + // Override golang default values for types + } + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.BadRequest(w, "url", r.URL.String(), errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) + return + } + + name := utils.GetName(r) + con, err := runtime.LookupContainer(name) + if err != nil { + utils.ContainerNotFound(w, name, err) + return + } + + state, err := con.State() + if err != nil { + utils.InternalServerError(w, err) + return + } + + // FIXME: This is not in the swagger.yml... + // If the Container is stopped already, send a 409 + if state == define.ContainerStateStopped || state == define.ContainerStateExited { + msg := fmt.Sprintf("Container %s is not running", name) + utils.Error(w, msg, http.StatusConflict, errors.New(msg)) + return + } + + timeout := con.StopTimeout() + if _, found := r.URL.Query()["t"]; found { + timeout = uint(query.Timeout) + } + + if err := con.RestartWithTimeout(r.Context(), timeout); err != nil { + utils.InternalServerError(w, err) + return + } + + // Success + utils.WriteResponse(w, http.StatusNoContent, "") +} diff --git a/pkg/api/handlers/compat/containers_start.go b/pkg/api/handlers/compat/containers_start.go new file mode 100644 index 000000000..67bd287ab --- /dev/null +++ b/pkg/api/handlers/compat/containers_start.go @@ -0,0 +1,51 @@ +package compat + +import ( + "net/http" + + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/gorilla/schema" + "github.com/pkg/errors" +) + +func StartContainer(w http.ResponseWriter, r *http.Request) { + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + DetachKeys string `schema:"detachKeys"` + }{ + // Override golang default values for types + } + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.BadRequest(w, "url", r.URL.String(), err) + return + } + if len(query.DetachKeys) > 0 { + // TODO - start does not support adding detach keys + utils.BadRequest(w, "detachKeys", query.DetachKeys, errors.New("the detachKeys parameter is not supported yet")) + return + } + runtime := r.Context().Value("runtime").(*libpod.Runtime) + name := utils.GetName(r) + con, err := runtime.LookupContainer(name) + if err != nil { + utils.ContainerNotFound(w, name, err) + return + } + + state, err := con.State() + if err != nil { + utils.InternalServerError(w, err) + return + } + if state == define.ContainerStateRunning { + utils.WriteResponse(w, http.StatusNotModified, "") + return + } + if err := con.Start(r.Context(), false); err != nil { + utils.InternalServerError(w, err) + return + } + utils.WriteResponse(w, http.StatusNoContent, "") +} diff --git a/pkg/api/handlers/generic/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go index 977979741..53ad0a632 100644 --- a/pkg/api/handlers/generic/containers_stats.go +++ b/pkg/api/handlers/compat/containers_stats.go @@ -1,4 +1,4 @@ -package generic +package compat import ( "encoding/json" diff --git a/pkg/api/handlers/containers_top.go b/pkg/api/handlers/compat/containers_top.go index 06d5dd653..202be55d1 100644 --- a/pkg/api/handlers/containers_top.go +++ b/pkg/api/handlers/compat/containers_top.go @@ -1,10 +1,11 @@ -package handlers +package compat import ( "net/http" "strings" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/gorilla/schema" "github.com/pkg/errors" @@ -42,7 +43,7 @@ func TopContainer(w http.ResponseWriter, r *http.Request) { return } - var body = ContainerTopOKBody{} + var body = handlers.ContainerTopOKBody{} if len(output) > 0 { body.Titles = strings.Split(output[0], "\t") for _, line := range output[1:] { diff --git a/pkg/api/handlers/compat/containers_unpause.go b/pkg/api/handlers/compat/containers_unpause.go new file mode 100644 index 000000000..adabdeaea --- /dev/null +++ b/pkg/api/handlers/compat/containers_unpause.go @@ -0,0 +1,28 @@ +package compat + +import ( + "net/http" + + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers/utils" +) + +func UnpauseContainer(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + + // /{version}/containers/(name)/unpause + name := utils.GetName(r) + con, err := runtime.LookupContainer(name) + if err != nil { + utils.ContainerNotFound(w, name, err) + return + } + + if err := con.Unpause(); err != nil { + utils.InternalServerError(w, err) + return + } + + // Success + utils.WriteResponse(w, http.StatusNoContent, "") +} diff --git a/pkg/api/handlers/events.go b/pkg/api/handlers/compat/events.go index 22dad9923..0f72ef328 100644 --- a/pkg/api/handlers/events.go +++ b/pkg/api/handlers/compat/events.go @@ -1,12 +1,15 @@ -package handlers +package compat import ( "encoding/json" "fmt" "net/http" + "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/events" + "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/gorilla/schema" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -15,13 +18,16 @@ func GetEvents(w http.ResponseWriter, r *http.Request) { var ( fromStart bool eventsError error + decoder = r.Context().Value("decoder").(*schema.Decoder) + runtime = r.Context().Value("runtime").(*libpod.Runtime) ) + query := struct { Since string `schema:"since"` Until string `schema:"until"` Filters map[string][]string `schema:"filters"` }{} - if err := decodeQuery(r, &query); err != nil { + if err := decoder.Decode(&query, r.URL.Query()); err != nil { utils.Error(w, "Failed to parse parameters", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) } @@ -38,19 +44,20 @@ func GetEvents(w http.ResponseWriter, r *http.Request) { eventChannel := make(chan *events.Event) go func() { readOpts := events.ReadOptions{FromStart: fromStart, Stream: true, Filters: libpodFilters, EventChannel: eventChannel, Since: query.Since, Until: query.Until} - eventsError = getRuntime(r).Events(readOpts) + eventsError = runtime.Events(readOpts) }() if eventsError != nil { utils.InternalServerError(w, eventsError) return } + + coder := json.NewEncoder(w) + coder.SetEscapeHTML(true) + w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) for event := range eventChannel { - e := EventToApiEvent(event) - //utils.WriteJSON(w, http.StatusOK, e) - coder := json.NewEncoder(w) - coder.SetEscapeHTML(true) + e := handlers.EventToApiEvent(event) if err := coder.Encode(e); err != nil { logrus.Errorf("unable to write json: %q", err) } diff --git a/pkg/api/handlers/generic/images.go b/pkg/api/handlers/compat/images.go index 1ced499d9..b18687bf9 100644 --- a/pkg/api/handlers/generic/images.go +++ b/pkg/api/handlers/compat/images.go @@ -1,4 +1,4 @@ -package generic +package compat import ( "encoding/json" @@ -90,7 +90,7 @@ func PruneImages(w http.ResponseWriter, r *http.Request) { }) } - //FIXME/TODO to do this exacty correct, pruneimages needs to return idrs and space-reclaimed, then we are golden + //FIXME/TODO to do this exactly correct, pruneimages needs to return idrs and space-reclaimed, then we are golden ipr := types.ImagesPruneReport{ ImagesDeleted: idr, SpaceReclaimed: 1, // TODO we cannot supply this right now @@ -198,7 +198,7 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) { return } source = f.Name() - if err := handlers.SaveFromBody(f, r); err != nil { + if err := SaveFromBody(f, r); err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file")) } } @@ -286,7 +286,7 @@ func GetImage(w http.ResponseWriter, r *http.Request) { // 404 no such // 500 internal name := utils.GetName(r) - newImage, err := handlers.GetImage(r, name) + newImage, err := utils.GetImage(r, name) if err != nil { utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "Failed to find image %s", name)) return @@ -305,7 +305,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed get images")) return } - var summaries = make([]*handlers.ImageSummary, len(images)+1) + var summaries = make([]*handlers.ImageSummary, len(images)) for j, img := range images { is, err := handlers.ImageToImageSummary(img) if err != nil { @@ -344,7 +344,7 @@ func LoadImages(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to create tempfile")) return } - if err := handlers.SaveFromBody(f, r); err != nil { + if err := SaveFromBody(f, r); err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file")) return } diff --git a/pkg/api/handlers/images_build.go b/pkg/api/handlers/compat/images_build.go index d969e3a47..e208e6ddc 100644 --- a/pkg/api/handlers/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -1,4 +1,4 @@ -package handlers +package compat import ( "bytes" @@ -15,12 +15,15 @@ import ( "github.com/containers/buildah" "github.com/containers/buildah/imagebuildah" + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/containers/storage/pkg/archive" + "github.com/gorilla/schema" ) func BuildImage(w http.ResponseWriter, r *http.Request) { - authConfigs := map[string]AuthConfig{} + authConfigs := map[string]handlers.AuthConfig{} if hdr, found := r.Header["X-Registry-Config"]; found && len(hdr) > 0 { authConfigsJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(hdr[0])) if json.NewDecoder(authConfigsJSON).Decode(&authConfigs) != nil { @@ -96,8 +99,8 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { Outputs: "", Registry: "docker.io", } - - if err := decodeQuery(r, &query); err != nil { + decoder := r.Context().Value("decoder").(*schema.Decoder) + if err := decoder.Decode(&query, r.URL.Query()); err != nil { utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err) return } @@ -219,7 +222,8 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { Devices: nil, } - id, _, err := getRuntime(r).Build(r.Context(), buildOptions, query.Dockerfile) + runtime := r.Context().Value("runtime").(*libpod.Runtime) + id, _, err := runtime.Build(r.Context(), buildOptions, query.Dockerfile) if err != nil { utils.InternalServerError(w, err) } diff --git a/pkg/api/handlers/compat/images_history.go b/pkg/api/handlers/compat/images_history.go new file mode 100644 index 000000000..04304caa4 --- /dev/null +++ b/pkg/api/handlers/compat/images_history.go @@ -0,0 +1,40 @@ +package compat + +import ( + "net/http" + + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/pkg/errors" +) + +func HistoryImage(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + name := utils.GetName(r) + var allHistory []handlers.HistoryResponse + + newImage, err := runtime.ImageRuntime().NewFromLocal(name) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "Failed to find image %s", name)) + return + + } + history, err := newImage.History(r.Context()) + if err != nil { + utils.InternalServerError(w, err) + return + } + for _, h := range history { + l := handlers.HistoryResponse{ + ID: h.ID, + Created: h.Created.UnixNano(), + CreatedBy: h.CreatedBy, + Tags: h.Tags, + Size: h.Size, + Comment: h.Comment, + } + allHistory = append(allHistory, l) + } + utils.WriteResponse(w, http.StatusOK, allHistory) +} diff --git a/pkg/api/handlers/compat/images_remove.go b/pkg/api/handlers/compat/images_remove.go new file mode 100644 index 000000000..3d346543e --- /dev/null +++ b/pkg/api/handlers/compat/images_remove.go @@ -0,0 +1,52 @@ +package compat + +import ( + "net/http" + + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/gorilla/schema" + "github.com/pkg/errors" +) + +func RemoveImage(w http.ResponseWriter, r *http.Request) { + decoder := r.Context().Value("decoder").(*schema.Decoder) + runtime := r.Context().Value("runtime").(*libpod.Runtime) + + query := struct { + Force bool `schema:"force"` + NoPrune bool `schema:"noprune"` + }{ + // This is where you can override the golang default value for one of fields + } + + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) + return + } + if _, found := r.URL.Query()["noprune"]; found { + if query.NoPrune { + utils.UnSupportedParameter("noprune") + } + } + name := utils.GetName(r) + newImage, err := runtime.ImageRuntime().NewFromLocal(name) + if err != nil { + utils.ImageNotFound(w, name, errors.Wrapf(err, "Failed to find image %s", name)) + return + } + + _, err = runtime.RemoveImage(r.Context(), newImage, query.Force) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) + return + } + // TODO + // This will need to be fixed for proper response, like Deleted: and Untagged: + m := make(map[string]string) + m["Deleted"] = newImage.ID() + foo := []map[string]string{} + foo = append(foo, m) + utils.WriteResponse(w, http.StatusOK, foo) + +} diff --git a/pkg/api/handlers/compat/images_save.go b/pkg/api/handlers/compat/images_save.go new file mode 100644 index 000000000..b39c719a0 --- /dev/null +++ b/pkg/api/handlers/compat/images_save.go @@ -0,0 +1,14 @@ +package compat + +import ( + "io" + "net/http" + "os" +) + +func SaveFromBody(f *os.File, r *http.Request) error { // nolint + if _, err := io.Copy(f, r.Body); err != nil { + return err + } + return f.Close() +} diff --git a/pkg/api/handlers/compat/images_search.go b/pkg/api/handlers/compat/images_search.go new file mode 100644 index 000000000..7283b22c4 --- /dev/null +++ b/pkg/api/handlers/compat/images_search.go @@ -0,0 +1,66 @@ +package compat + +import ( + "net/http" + "strconv" + + "github.com/containers/image/v5/types" + "github.com/containers/libpod/libpod/image" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/gorilla/schema" + "github.com/pkg/errors" +) + +func SearchImages(w http.ResponseWriter, r *http.Request) { + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + Term string `json:"term"` + Limit int `json:"limit"` + Filters map[string][]string `json:"filters"` + }{ + // This is where you can override the golang default value for one of fields + } + + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) + return + } + + filter := image.SearchFilter{} + if len(query.Filters) > 0 { + if len(query.Filters["stars"]) > 0 { + stars, err := strconv.Atoi(query.Filters["stars"][0]) + if err != nil { + utils.InternalServerError(w, err) + return + } + filter.Stars = stars + } + if len(query.Filters["is-official"]) > 0 { + isOfficial, err := strconv.ParseBool(query.Filters["is-official"][0]) + if err != nil { + utils.InternalServerError(w, err) + return + } + filter.IsOfficial = types.NewOptionalBool(isOfficial) + } + if len(query.Filters["is-automated"]) > 0 { + isAutomated, err := strconv.ParseBool(query.Filters["is-automated"][0]) + if err != nil { + utils.InternalServerError(w, err) + return + } + filter.IsAutomated = types.NewOptionalBool(isAutomated) + } + } + options := image.SearchOptions{ + Filter: filter, + Limit: query.Limit, + } + results, err := image.SearchImages(query.Term, options) + if err != nil { + utils.BadRequest(w, "term", query.Term, err) + return + } + utils.WriteResponse(w, http.StatusOK, results) +} diff --git a/pkg/api/handlers/compat/images_tag.go b/pkg/api/handlers/compat/images_tag.go new file mode 100644 index 000000000..722be5653 --- /dev/null +++ b/pkg/api/handlers/compat/images_tag.go @@ -0,0 +1,37 @@ +package compat + +import ( + "fmt" + "net/http" + + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/pkg/errors" +) + +func TagImage(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + + // /v1.xx/images/(name)/tag + name := utils.GetName(r) + newImage, err := runtime.ImageRuntime().NewFromLocal(name) + if err != nil { + utils.ImageNotFound(w, name, errors.Wrapf(err, "Failed to find image %s", name)) + return + } + tag := "latest" + if len(r.Form.Get("tag")) > 0 { + tag = r.Form.Get("tag") + } + if len(r.Form.Get("repo")) < 1 { + utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.New("repo parameter is required to tag an image")) + return + } + repo := r.Form.Get("repo") + tagName := fmt.Sprintf("%s:%s", repo, tag) + if err := newImage.TagImage(tagName); err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) + return + } + utils.WriteResponse(w, http.StatusCreated, "") +} diff --git a/pkg/api/handlers/generic/info.go b/pkg/api/handlers/compat/info.go index c9e79233d..30b49948d 100644 --- a/pkg/api/handlers/generic/info.go +++ b/pkg/api/handlers/compat/info.go @@ -1,4 +1,4 @@ -package generic +package compat import ( "fmt" diff --git a/pkg/api/handlers/ping.go b/pkg/api/handlers/compat/ping.go index d41da60f3..6e77e270f 100644 --- a/pkg/api/handlers/ping.go +++ b/pkg/api/handlers/compat/ping.go @@ -1,10 +1,11 @@ -package handlers +package compat import ( "fmt" "net/http" "github.com/containers/buildah" + "github.com/containers/libpod/pkg/api/handlers" ) // Ping returns headers to client about the service @@ -12,14 +13,14 @@ import ( // This handler must always be the same for the compatibility and libpod URL trees! // Clients will use the Header availability to test which backend engine is in use. func Ping(w http.ResponseWriter, r *http.Request) { - w.Header().Set("API-Version", DefaultApiVersion) + w.Header().Set("API-Version", handlers.DefaultApiVersion) w.Header().Set("BuildKit-Version", "") w.Header().Set("Docker-Experimental", "true") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Pragma", "no-cache") // API-Version and Libpod-API-Version may not always be equal - w.Header().Set("Libpod-API-Version", DefaultApiVersion) + w.Header().Set("Libpod-API-Version", handlers.DefaultApiVersion) w.Header().Set("Libpod-Buildha-Version", buildah.Version) w.WriteHeader(http.StatusOK) diff --git a/pkg/api/handlers/generic/swagger.go b/pkg/api/handlers/compat/swagger.go index c9c9610bb..cbd8e61fb 100644 --- a/pkg/api/handlers/generic/swagger.go +++ b/pkg/api/handlers/compat/swagger.go @@ -1,4 +1,4 @@ -package generic +package compat import ( "github.com/containers/libpod/pkg/api/handlers/utils" diff --git a/pkg/api/handlers/generic/system.go b/pkg/api/handlers/compat/system.go index edf1f8522..47e187ba1 100644 --- a/pkg/api/handlers/generic/system.go +++ b/pkg/api/handlers/compat/system.go @@ -1,4 +1,4 @@ -package generic +package compat import ( "net/http" diff --git a/pkg/api/handlers/generic/types.go b/pkg/api/handlers/compat/types.go index f068ac011..b8d06760f 100644 --- a/pkg/api/handlers/generic/types.go +++ b/pkg/api/handlers/compat/types.go @@ -1,4 +1,4 @@ -package generic +package compat import ( "time" diff --git a/pkg/api/handlers/unsupported.go b/pkg/api/handlers/compat/unsupported.go index 956d31f8b..d9c3c3f49 100644 --- a/pkg/api/handlers/unsupported.go +++ b/pkg/api/handlers/compat/unsupported.go @@ -1,4 +1,4 @@ -package handlers +package compat import ( "fmt" diff --git a/pkg/api/handlers/version.go b/pkg/api/handlers/compat/version.go index 94166952c..c7f7917ac 100644 --- a/pkg/api/handlers/version.go +++ b/pkg/api/handlers/compat/version.go @@ -1,4 +1,4 @@ -package handlers +package compat import ( "fmt" @@ -8,16 +8,12 @@ import ( "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" docker "github.com/docker/docker/api/types" "github.com/pkg/errors" ) -const ( - DefaultApiVersion = "1.40" // See https://docs.docker.com/engine/api/v1.40/ - MinimalApiVersion = "1.24" -) - func VersionHandler(w http.ResponseWriter, r *http.Request) { // 200 ok // 500 internal @@ -40,19 +36,19 @@ func VersionHandler(w http.ResponseWriter, r *http.Request) { Name: "Podman Engine", Version: versionInfo.Version, Details: map[string]string{ - "APIVersion": DefaultApiVersion, + "APIVersion": handlers.DefaultApiVersion, "Arch": goRuntime.GOARCH, "BuildTime": time.Unix(versionInfo.Built, 0).Format(time.RFC3339), "Experimental": "true", "GitCommit": versionInfo.GitCommit, "GoVersion": versionInfo.GoVersion, "KernelVersion": hostInfo["kernel"].(string), - "MinAPIVersion": MinimalApiVersion, + "MinAPIVersion": handlers.MinimalApiVersion, "Os": goRuntime.GOOS, }, }} - utils.WriteResponse(w, http.StatusOK, Version{Version: docker.Version{ + utils.WriteResponse(w, http.StatusOK, handlers.Version{Version: docker.Version{ Platform: struct { Name string }{ diff --git a/pkg/api/handlers/containers.go b/pkg/api/handlers/containers.go deleted file mode 100644 index ee080e794..000000000 --- a/pkg/api/handlers/containers.go +++ /dev/null @@ -1,244 +0,0 @@ -package handlers - -import ( - "fmt" - "github.com/docker/docker/api/types" - "net/http" - - "github.com/containers/libpod/libpod" - "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/pkg/api/handlers/utils" - "github.com/gorilla/schema" - "github.com/pkg/errors" -) - -func StopContainer(w http.ResponseWriter, r *http.Request) { - runtime := r.Context().Value("runtime").(*libpod.Runtime) - decoder := r.Context().Value("decoder").(*schema.Decoder) - - // /{version}/containers/(name)/stop - query := struct { - Timeout int `schema:"t"` - }{ - // override any golang type defaults - } - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, - errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) - return - } - - name := utils.GetName(r) - con, err := runtime.LookupContainer(name) - if err != nil { - utils.ContainerNotFound(w, name, err) - return - } - - state, err := con.State() - if err != nil { - utils.InternalServerError(w, errors.Wrapf(err, "unable to get state for Container %s", name)) - return - } - // If the Container is stopped already, send a 304 - if state == define.ContainerStateStopped || state == define.ContainerStateExited { - utils.WriteResponse(w, http.StatusNotModified, "") - return - } - - var stopError error - if query.Timeout > 0 { - stopError = con.StopWithTimeout(uint(query.Timeout)) - } else { - stopError = con.Stop() - } - if stopError != nil { - utils.InternalServerError(w, errors.Wrapf(stopError, "failed to stop %s", name)) - return - } - - // Success - utils.WriteResponse(w, http.StatusNoContent, "") -} - -func UnpauseContainer(w http.ResponseWriter, r *http.Request) { - runtime := r.Context().Value("runtime").(*libpod.Runtime) - - // /{version}/containers/(name)/unpause - name := utils.GetName(r) - con, err := runtime.LookupContainer(name) - if err != nil { - utils.ContainerNotFound(w, name, err) - return - } - - // the api does not error if the Container is already paused, so just into it - if err := con.Unpause(); err != nil { - utils.InternalServerError(w, err) - return - } - - // Success - utils.WriteResponse(w, http.StatusNoContent, "") -} - -func PauseContainer(w http.ResponseWriter, r *http.Request) { - runtime := r.Context().Value("runtime").(*libpod.Runtime) - - // /{version}/containers/(name)/pause - name := utils.GetName(r) - con, err := runtime.LookupContainer(name) - if err != nil { - utils.ContainerNotFound(w, name, err) - return - } - - // the api does not error if the Container is already paused, so just into it - if err := con.Pause(); err != nil { - utils.InternalServerError(w, err) - return - } - // Success - utils.WriteResponse(w, http.StatusNoContent, "") -} - -func StartContainer(w http.ResponseWriter, r *http.Request) { - decoder := r.Context().Value("decoder").(*schema.Decoder) - query := struct { - DetachKeys string `schema:"detachKeys"` - }{ - // Override golang default values for types - } - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) - return - } - if len(query.DetachKeys) > 0 { - // TODO - start does not support adding detach keys - utils.Error(w, "Something went wrong", http.StatusBadRequest, errors.New("the detachKeys parameter is not supported yet")) - return - } - runtime := r.Context().Value("runtime").(*libpod.Runtime) - name := utils.GetName(r) - con, err := runtime.LookupContainer(name) - if err != nil { - utils.ContainerNotFound(w, name, err) - return - } - - state, err := con.State() - if err != nil { - utils.InternalServerError(w, err) - return - } - if state == define.ContainerStateRunning { - utils.WriteResponse(w, http.StatusNotModified, "") - return - } - if err := con.Start(r.Context(), false); err != nil { - utils.InternalServerError(w, err) - return - } - utils.WriteResponse(w, http.StatusNoContent, "") -} - -func RestartContainer(w http.ResponseWriter, r *http.Request) { - runtime := r.Context().Value("runtime").(*libpod.Runtime) - decoder := r.Context().Value("decoder").(*schema.Decoder) - // /{version}/containers/(name)/restart - query := struct { - Timeout int `schema:"t"` - }{ - // Override golang default values for types - } - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) - return - } - - name := utils.GetName(r) - con, err := runtime.LookupContainer(name) - if err != nil { - utils.ContainerNotFound(w, name, err) - return - } - - state, err := con.State() - if err != nil { - utils.InternalServerError(w, err) - return - } - - // FIXME: This is not in the swagger.yml... - // If the Container is stopped already, send a 409 - if state == define.ContainerStateStopped || state == define.ContainerStateExited { - msg := fmt.Sprintf("Container %s is not running", name) - utils.Error(w, msg, http.StatusConflict, errors.New(msg)) - return - } - - timeout := con.StopTimeout() - if _, found := r.URL.Query()["t"]; found { - timeout = uint(query.Timeout) - } - - if err := con.RestartWithTimeout(r.Context(), timeout); err != nil { - utils.InternalServerError(w, err) - return - } - - // Success - utils.WriteResponse(w, http.StatusNoContent, "") -} - -func PruneContainers(w http.ResponseWriter, r *http.Request) { - var ( - delContainers []string - space int64 - ) - runtime := r.Context().Value("runtime").(*libpod.Runtime) - decoder := r.Context().Value("decoder").(*schema.Decoder) - - query := struct { - Filters map[string][]string `schema:"filter"` - }{} - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) - return - } - - filterFuncs, err := utils.GenerateFilterFuncsFromMap(runtime, query.Filters) - if err != nil { - utils.InternalServerError(w, err) - return - } - prunedContainers, pruneErrors, err := runtime.PruneContainers(filterFuncs) - if err != nil { - utils.InternalServerError(w, err) - return - } - - // Libpod response differs - if utils.IsLibpodRequest(r) { - var response []LibpodContainersPruneReport - for ctrID, size := range prunedContainers { - response = append(response, LibpodContainersPruneReport{ID: ctrID, SpaceReclaimed: size}) - } - for ctrID, err := range pruneErrors { - response = append(response, LibpodContainersPruneReport{ID: ctrID, PruneError: err.Error()}) - } - utils.WriteResponse(w, http.StatusOK, response) - return - } - for ctrID, size := range prunedContainers { - if pruneErrors[ctrID] == nil { - space += size - delContainers = append(delContainers, ctrID) - } - } - report := types.ContainersPruneReport{ - ContainersDeleted: delContainers, - SpaceReclaimed: uint64(space), - } - utils.WriteResponse(w, http.StatusOK, report) -} diff --git a/pkg/api/handlers/exec.go b/pkg/api/handlers/exec.go deleted file mode 100644 index 8a7b2ae26..000000000 --- a/pkg/api/handlers/exec.go +++ /dev/null @@ -1,25 +0,0 @@ -package handlers - -import ( - "net/http" - - "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/pkg/api/handlers/utils" -) - -func CreateExec(w http.ResponseWriter, r *http.Request) { - utils.Error(w, "function not implemented", http.StatusInternalServerError, define.ErrNotImplemented) -} - -func StartExec(w http.ResponseWriter, r *http.Request) { - utils.Error(w, "function not implemented", http.StatusInternalServerError, define.ErrNotImplemented) -} - -func ResizeExec(w http.ResponseWriter, r *http.Request) { - utils.Error(w, "function not implemented", http.StatusInternalServerError, define.ErrNotImplemented) - -} - -func InspectExec(w http.ResponseWriter, r *http.Request) { - utils.Error(w, "function not implemented", http.StatusInternalServerError, define.ErrNotImplemented) -} diff --git a/pkg/api/handlers/handler.go b/pkg/api/handlers/handler.go index 231c11f23..2dd2c886b 100644 --- a/pkg/api/handlers/handler.go +++ b/pkg/api/handlers/handler.go @@ -1,38 +1,6 @@ package handlers -import ( - "net/http" - - "github.com/containers/libpod/libpod" - "github.com/gorilla/schema" - "github.com/pkg/errors" +const ( + DefaultApiVersion = "1.40" // See https://docs.docker.com/engine/api/v1.40/ + MinimalApiVersion = "1.24" ) - -// Convenience routines to reduce boiler plate in handlers - -// func hasVar(r *http.Request, k string) bool { -// _, found := mux.Vars(r)[k] -// return found -// } - -func decodeQuery(r *http.Request, i interface{}) error { - decoder := r.Context().Value("decoder").(*schema.Decoder) - - if err := decoder.Decode(i, r.URL.Query()); err != nil { - return errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()) - } - return nil -} - -func getRuntime(r *http.Request) *libpod.Runtime { - return r.Context().Value("runtime").(*libpod.Runtime) -} - -// func getHeader(r *http.Request, k string) string { -// return r.Header.Get(k) -// } -// -// func hasHeader(r *http.Request, k string) bool { -// _, found := r.Header[k] -// return found -// } diff --git a/pkg/api/handlers/images.go b/pkg/api/handlers/images.go deleted file mode 100644 index d4549e5b4..000000000 --- a/pkg/api/handlers/images.go +++ /dev/null @@ -1,187 +0,0 @@ -package handlers - -import ( - "fmt" - "io" - "net/http" - "os" - "strconv" - - "github.com/containers/image/v5/types" - "github.com/containers/libpod/libpod" - "github.com/containers/libpod/libpod/image" - "github.com/containers/libpod/pkg/api/handlers/utils" - "github.com/gorilla/schema" - "github.com/pkg/errors" -) - -func HistoryImage(w http.ResponseWriter, r *http.Request) { - runtime := r.Context().Value("runtime").(*libpod.Runtime) - name := utils.GetName(r) - var allHistory []HistoryResponse - - newImage, err := runtime.ImageRuntime().NewFromLocal(name) - if err != nil { - utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "Failed to find image %s", name)) - return - - } - history, err := newImage.History(r.Context()) - if err != nil { - utils.InternalServerError(w, err) - return - } - for _, h := range history { - l := HistoryResponse{ - ID: h.ID, - Created: h.Created.UnixNano(), - CreatedBy: h.CreatedBy, - Tags: h.Tags, - Size: h.Size, - Comment: h.Comment, - } - allHistory = append(allHistory, l) - } - utils.WriteResponse(w, http.StatusOK, allHistory) -} - -func TagImage(w http.ResponseWriter, r *http.Request) { - runtime := r.Context().Value("runtime").(*libpod.Runtime) - - // /v1.xx/images/(name)/tag - name := utils.GetName(r) - newImage, err := runtime.ImageRuntime().NewFromLocal(name) - if err != nil { - utils.ImageNotFound(w, name, errors.Wrapf(err, "Failed to find image %s", name)) - return - } - tag := "latest" - if len(r.Form.Get("tag")) > 0 { - tag = r.Form.Get("tag") - } - if len(r.Form.Get("repo")) < 1 { - utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.New("repo parameter is required to tag an image")) - return - } - repo := r.Form.Get("repo") - tagName := fmt.Sprintf("%s:%s", repo, tag) - if err := newImage.TagImage(tagName); err != nil { - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) - return - } - utils.WriteResponse(w, http.StatusCreated, "") -} - -func RemoveImage(w http.ResponseWriter, r *http.Request) { - decoder := r.Context().Value("decoder").(*schema.Decoder) - runtime := r.Context().Value("runtime").(*libpod.Runtime) - - query := struct { - noPrune bool - }{ - // This is where you can override the golang default value for one of fields - } - - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) - return - } - if _, found := r.URL.Query()["noprune"]; found { - if query.noPrune { - utils.UnSupportedParameter("noprune") - } - } - name := utils.GetName(r) - newImage, err := runtime.ImageRuntime().NewFromLocal(name) - if err != nil { - utils.ImageNotFound(w, name, errors.Wrapf(err, "Failed to find image %s", name)) - return - } - - force := false - if len(r.Form.Get("force")) > 0 { - force, err = strconv.ParseBool(r.Form.Get("force")) - if err != nil { - utils.Error(w, "Something went wrong.", http.StatusBadRequest, err) - return - } - } - _, err = runtime.RemoveImage(r.Context(), newImage, force) - if err != nil { - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) - return - } - // TODO - // This will need to be fixed for proper response, like Deleted: and Untagged: - m := make(map[string]string) - m["Deleted"] = newImage.ID() - foo := []map[string]string{} - foo = append(foo, m) - utils.WriteResponse(w, http.StatusOK, foo) - -} -func GetImage(r *http.Request, name string) (*image.Image, error) { - runtime := r.Context().Value("runtime").(*libpod.Runtime) - return runtime.ImageRuntime().NewFromLocal(name) -} - -func SaveFromBody(f *os.File, r *http.Request) error { // nolint - if _, err := io.Copy(f, r.Body); err != nil { - return err - } - return f.Close() -} - -func SearchImages(w http.ResponseWriter, r *http.Request) { - decoder := r.Context().Value("decoder").(*schema.Decoder) - query := struct { - Term string `json:"term"` - Limit int `json:"limit"` - Filters map[string][]string `json:"filters"` - }{ - // This is where you can override the golang default value for one of fields - } - - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) - return - } - - filter := image.SearchFilter{} - if len(query.Filters) > 0 { - if len(query.Filters["stars"]) > 0 { - stars, err := strconv.Atoi(query.Filters["stars"][0]) - if err != nil { - utils.InternalServerError(w, err) - return - } - filter.Stars = stars - } - if len(query.Filters["is-official"]) > 0 { - isOfficial, err := strconv.ParseBool(query.Filters["is-official"][0]) - if err != nil { - utils.InternalServerError(w, err) - return - } - filter.IsOfficial = types.NewOptionalBool(isOfficial) - } - if len(query.Filters["is-automated"]) > 0 { - isAutomated, err := strconv.ParseBool(query.Filters["is-automated"][0]) - if err != nil { - utils.InternalServerError(w, err) - return - } - filter.IsAutomated = types.NewOptionalBool(isAutomated) - } - } - options := image.SearchOptions{ - Filter: filter, - Limit: query.Limit, - } - results, err := image.SearchImages(query.Term, options) - if err != nil { - utils.BadRequest(w, "term", query.Term, err) - return - } - utils.WriteResponse(w, http.StatusOK, results) -} diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go index d8dd0d69b..8020c391d 100644 --- a/pkg/api/handlers/libpod/containers.go +++ b/pkg/api/handlers/libpod/containers.go @@ -10,17 +10,12 @@ import ( "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/gorilla/schema" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) -func StopContainer(w http.ResponseWriter, r *http.Request) { - handlers.StopContainer(w, r) -} - func ContainerExists(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) name := utils.GetName(r) @@ -32,22 +27,6 @@ func ContainerExists(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusNoContent, "") } -func RemoveContainer(w http.ResponseWriter, r *http.Request) { - decoder := r.Context().Value("decoder").(*schema.Decoder) - query := struct { - Force bool `schema:"force"` - Vols bool `schema:"v"` - }{ - // override any golang type defaults - } - - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, - errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) - return - } - utils.RemoveContainer(w, r, query.Force, query.Vols) -} func ListContainers(w http.ResponseWriter, r *http.Request) { var ( filterFuncs []libpod.ContainerFilter @@ -165,16 +144,6 @@ func GetContainer(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusOK, data) } -func KillContainer(w http.ResponseWriter, r *http.Request) { - // /{version}/containers/(name)/kill - _, err := utils.KillContainer(w, r) - if err != nil { - return - } - // Success - utils.WriteResponse(w, http.StatusNoContent, "") -} - func WaitContainer(w http.ResponseWriter, r *http.Request) { exitCode, err := utils.WaitContainer(w, r) if err != nil { diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index 71603e6cc..cfd3b993e 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -79,7 +79,7 @@ func ImageTree(w http.ResponseWriter, r *http.Request) { func GetImage(w http.ResponseWriter, r *http.Request) { name := utils.GetName(r) - newImage, err := handlers.GetImage(r, name) + newImage, err := utils.GetImage(r, name) if err != nil { utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "Failed to find image %s", name)) return diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go index e8dc5bde2..f93c8f8d5 100644 --- a/pkg/api/handlers/libpod/pods.go +++ b/pkg/api/handlers/libpod/pods.go @@ -172,7 +172,6 @@ func PodStop(w http.ResponseWriter, r *http.Request) { errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) return } - allContainersStopped := true name := utils.GetName(r) pod, err := runtime.LookupPod(name) if err != nil { @@ -180,26 +179,12 @@ func PodStop(w http.ResponseWriter, r *http.Request) { return } - // TODO we need to implement a pod.State/Status in libpod internal so libpod api - // users dont have to run through all containers. - podContainers, err := pod.AllContainers() + status, err := pod.GetPodStatus() if err != nil { utils.Error(w, "Something went wrong", http.StatusInternalServerError, err) return } - - for _, con := range podContainers { - containerState, err := con.State() - if err != nil { - utils.Error(w, "Something went wrong", http.StatusInternalServerError, err) - return - } - if containerState == define.ContainerStateRunning { - allContainersStopped = false - break - } - } - if allContainersStopped { + if status != define.PodStateRunning { utils.WriteResponse(w, http.StatusNotModified, "") return } @@ -218,34 +203,18 @@ func PodStop(w http.ResponseWriter, r *http.Request) { func PodStart(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) - allContainersRunning := true name := utils.GetName(r) pod, err := runtime.LookupPod(name) if err != nil { utils.PodNotFound(w, name, err) return } - - // TODO we need to implement a pod.State/Status in libpod internal so libpod api - // users dont have to run through all containers. - podContainers, err := pod.AllContainers() + status, err := pod.GetPodStatus() if err != nil { utils.Error(w, "Something went wrong", http.StatusInternalServerError, err) return } - - for _, con := range podContainers { - containerState, err := con.State() - if err != nil { - utils.Error(w, "Something went wrong", http.StatusInternalServerError, err) - return - } - if containerState != define.ContainerStateRunning { - allContainersRunning = false - break - } - } - if allContainersRunning { + if status == define.PodStateRunning { utils.WriteResponse(w, http.StatusNotModified, "") return } diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go index 2930a9567..2e429dc58 100644 --- a/pkg/api/handlers/types.go +++ b/pkg/api/handlers/types.go @@ -347,7 +347,7 @@ func ImageDataToImageInspect(ctx context.Context, l *libpodImage.Image) (*ImageI } -func LibpodToContainer(l *libpod.Container, infoData []define.InfoData) (*Container, error) { +func LibpodToContainer(l *libpod.Container, infoData []define.InfoData, sz bool) (*Container, error) { imageId, imageName := l.Image() var ( @@ -360,11 +360,18 @@ func LibpodToContainer(l *libpod.Container, infoData []define.InfoData) (*Contai if state, err = l.State(); err != nil { return nil, err } - if sizeRW, err = l.RWSize(); err != nil { - return nil, err + stateStr := state.String() + if stateStr == "configured" { + stateStr = "created" } - if sizeRootFs, err = l.RootFsSize(); err != nil { - return nil, err + + if sz { + if sizeRW, err = l.RWSize(); err != nil { + return nil, err + } + if sizeRootFs, err = l.RootFsSize(); err != nil { + return nil, err + } } return &Container{docker.Container{ @@ -378,7 +385,7 @@ func LibpodToContainer(l *libpod.Container, infoData []define.InfoData) (*Contai SizeRw: sizeRW, SizeRootFs: sizeRootFs, Labels: l.Labels(), - State: string(state), + State: stateStr, Status: "", HostConfig: struct { NetworkMode string `json:",omitempty"` @@ -391,9 +398,9 @@ func LibpodToContainer(l *libpod.Container, infoData []define.InfoData) (*Contai }, nil } -func LibpodToContainerJSON(l *libpod.Container) (*docker.ContainerJSON, error) { +func LibpodToContainerJSON(l *libpod.Container, sz bool) (*docker.ContainerJSON, error) { _, imageName := l.Image() - inspect, err := l.Inspect(true) + inspect, err := l.Inspect(sz) if err != nil { return nil, err } diff --git a/pkg/api/handlers/utils/containers.go b/pkg/api/handlers/utils/containers.go index 07efef0f5..d5a79bdc8 100644 --- a/pkg/api/handlers/utils/containers.go +++ b/pkg/api/handlers/utils/containers.go @@ -2,9 +2,7 @@ package utils import ( "context" - "fmt" "net/http" - "syscall" "time" "github.com/containers/libpod/cmd/podman/shared" @@ -23,60 +21,6 @@ type ContainerCreateResponse struct { Warnings []string `json:"Warnings"` } -func KillContainer(w http.ResponseWriter, r *http.Request) (*libpod.Container, error) { - runtime := r.Context().Value("runtime").(*libpod.Runtime) - decoder := r.Context().Value("decoder").(*schema.Decoder) - query := struct { - Signal syscall.Signal `schema:"signal"` - }{ - Signal: syscall.SIGKILL, - } - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) - return nil, err - } - name := GetName(r) - con, err := runtime.LookupContainer(name) - if err != nil { - ContainerNotFound(w, name, err) - return nil, err - } - - state, err := con.State() - if err != nil { - InternalServerError(w, err) - return con, err - } - - // If the Container is stopped already, send a 409 - if state == define.ContainerStateStopped || state == define.ContainerStateExited { - Error(w, fmt.Sprintf("Container %s is not running", name), http.StatusConflict, errors.New(fmt.Sprintf("Cannot kill Container %s, it is not running", name))) - return con, err - } - - err = con.Kill(uint(query.Signal)) - if err != nil { - Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "unable to kill Container %s", name)) - } - return con, err -} - -func RemoveContainer(w http.ResponseWriter, r *http.Request, force, vols bool) { - runtime := r.Context().Value("runtime").(*libpod.Runtime) - name := GetName(r) - con, err := runtime.LookupContainer(name) - if err != nil { - ContainerNotFound(w, name, err) - return - } - - if err := runtime.RemoveContainer(r.Context(), con, force, vols); err != nil { - InternalServerError(w, err) - return - } - WriteResponse(w, http.StatusNoContent, "") -} - func WaitContainer(w http.ResponseWriter, r *http.Request) (int32, error) { var ( err error diff --git a/pkg/api/handlers/utils/handler.go b/pkg/api/handlers/utils/handler.go index 44bcc794c..32b8c5b0a 100644 --- a/pkg/api/handlers/utils/handler.go +++ b/pkg/api/handlers/utils/handler.go @@ -3,7 +3,6 @@ package utils import ( "encoding/json" "fmt" - "github.com/pkg/errors" "io" "net/http" "net/url" @@ -11,6 +10,7 @@ import ( "strings" "github.com/gorilla/mux" + "github.com/pkg/errors" "github.com/sirupsen/logrus" ) diff --git a/pkg/api/handlers/utils/images.go b/pkg/api/handlers/utils/images.go index a97fd5c07..696d5f745 100644 --- a/pkg/api/handlers/utils/images.go +++ b/pkg/api/handlers/utils/images.go @@ -43,3 +43,8 @@ func GetImages(w http.ResponseWriter, r *http.Request) ([]*image.Image, error) { } } + +func GetImage(r *http.Request, name string) (*image.Image, error) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + return runtime.ImageRuntime().NewFromLocal(name) +} diff --git a/pkg/api/server/register_auth.go b/pkg/api/server/register_auth.go index 8db131153..33b707fa4 100644 --- a/pkg/api/server/register_auth.go +++ b/pkg/api/server/register_auth.go @@ -1,11 +1,13 @@ package server import ( - "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/gorilla/mux" ) func (s *APIServer) registerAuthHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/auth"), s.APIHandler(handlers.UnsupportedHandler)) + r.Handle(VersionedPath("/auth"), s.APIHandler(compat.UnsupportedHandler)) + // Added non version path to URI to support docker non versioned paths + r.Handle("/auth", s.APIHandler(compat.UnsupportedHandler)) return nil } diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go index 6aad7ff88..2656d1d89 100644 --- a/pkg/api/server/register_containers.go +++ b/pkg/api/server/register_containers.go @@ -3,8 +3,7 @@ package server import ( "net/http" - "github.com/containers/libpod/pkg/api/handlers" - "github.com/containers/libpod/pkg/api/handlers/generic" + "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/containers/libpod/pkg/api/handlers/libpod" "github.com/gorilla/mux" ) @@ -33,7 +32,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/ConflictError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/create"), s.APIHandler(generic.CreateContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/create"), s.APIHandler(compat.CreateContainer)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/create", s.APIHandler(compat.CreateContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/json compat listContainers // --- // tags: @@ -83,7 +84,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/BadParamError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/json"), s.APIHandler(generic.ListContainers)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/containers/json"), s.APIHandler(compat.ListContainers)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/json", s.APIHandler(compat.ListContainers)).Methods(http.MethodGet) // swagger:operation POST /containers/prune compat pruneContainers // --- // tags: @@ -105,7 +108,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/DocsContainerPruneReport" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/prune"), s.APIHandler(handlers.PruneContainers)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/prune"), s.APIHandler(compat.PruneContainers)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/prune", s.APIHandler(compat.PruneContainers)).Methods(http.MethodPost) // swagger:operation DELETE /containers/{name} compat removeContainer // --- // tags: @@ -144,7 +149,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/ConflictError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}"), s.APIHandler(generic.RemoveContainer)).Methods(http.MethodDelete) + r.HandleFunc(VersionedPath("/containers/{name}"), s.APIHandler(compat.RemoveContainer)).Methods(http.MethodDelete) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}", s.APIHandler(compat.RemoveContainer)).Methods(http.MethodDelete) // swagger:operation GET /containers/{name}/json compat getContainer // --- // tags: @@ -171,7 +178,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/json"), s.APIHandler(generic.GetContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/containers/{name}/json"), s.APIHandler(compat.GetContainer)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/json", s.APIHandler(compat.GetContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{name}/kill compat killContainer // --- // tags: @@ -201,7 +210,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/ConflictError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/kill"), s.APIHandler(generic.KillContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/kill"), s.APIHandler(compat.KillContainer)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/kill", s.APIHandler(compat.KillContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/{name}/logs compat logsFromContainer // --- // tags: @@ -253,7 +264,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/logs"), s.APIHandler(generic.LogsFromContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/containers/{name}/logs"), s.APIHandler(compat.LogsFromContainer)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/logs", s.APIHandler(compat.LogsFromContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{name}/pause compat pauseContainer // --- // tags: @@ -275,8 +288,12 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/pause"), s.APIHandler(handlers.PauseContainer)).Methods(http.MethodPost) - r.HandleFunc(VersionedPath("/containers/{name}/rename"), s.APIHandler(handlers.UnsupportedHandler)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/pause"), s.APIHandler(compat.PauseContainer)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/pause", s.APIHandler(compat.PauseContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/rename"), s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/rename", s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/restart compat restartContainer // --- // tags: @@ -301,7 +318,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/restart"), s.APIHandler(handlers.RestartContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/restart"), s.APIHandler(compat.RestartContainer)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/restart", s.APIHandler(compat.RestartContainer)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/start compat startContainer // --- // tags: @@ -329,7 +348,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/start"), s.APIHandler(handlers.StartContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/start"), s.APIHandler(compat.StartContainer)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/start", s.APIHandler(compat.StartContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/{name}/stats compat statsContainer // --- // tags: @@ -356,7 +377,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/stats"), s.APIHandler(generic.StatsContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/containers/{name}/stats"), s.APIHandler(compat.StatsContainer)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/stats", s.APIHandler(compat.StatsContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{name}/stop compat stopContainer // --- // tags: @@ -384,7 +407,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/stop"), s.APIHandler(handlers.StopContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/stop"), s.APIHandler(compat.StopContainer)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/stop", s.APIHandler(compat.StopContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/{name}/top compat topContainer // --- // tags: @@ -409,7 +434,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/top"), s.APIHandler(handlers.TopContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/containers/{name}/top"), s.APIHandler(compat.TopContainer)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/top", s.APIHandler(compat.TopContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{name}/unpause compat unpauseContainer // --- // tags: @@ -431,7 +458,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/unpause"), s.APIHandler(handlers.UnpauseContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/unpause"), s.APIHandler(compat.UnpauseContainer)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/unpause", s.APIHandler(compat.UnpauseContainer)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/wait compat waitContainer // --- // tags: @@ -464,7 +493,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/wait"), s.APIHandler(generic.WaitContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/wait"), s.APIHandler(compat.WaitContainer)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/wait", s.APIHandler(compat.WaitContainer)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/attach compat attachContainer // --- // tags: @@ -519,7 +550,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/attach"), s.APIHandler(handlers.AttachContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/attach"), s.APIHandler(compat.AttachContainer)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/attach", s.APIHandler(compat.AttachContainer)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/resize compat resizeContainer // --- // tags: @@ -551,7 +584,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/resize"), s.APIHandler(handlers.ResizeContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/resize"), s.APIHandler(compat.ResizeContainer)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/containers/{name}/resize", s.APIHandler(compat.ResizeContainer)).Methods(http.MethodPost) /* libpod endpoints @@ -668,7 +703,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/DocsLibpodPruneResponse" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/prune"), s.APIHandler(handlers.PruneContainers)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/prune"), s.APIHandler(compat.PruneContainers)).Methods(http.MethodPost) // swagger:operation GET /libpod/containers/showmounted libpod libpodShowMountedContainers // --- // tags: @@ -720,7 +755,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/ConflictError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}"), s.APIHandler(libpod.RemoveContainer)).Methods(http.MethodDelete) + r.HandleFunc(VersionedPath("/libpod/containers/{name}"), s.APIHandler(compat.RemoveContainer)).Methods(http.MethodDelete) // swagger:operation GET /libpod/containers/{name}/json libpod libpodGetContainer // --- // tags: @@ -775,7 +810,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/ConflictError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/kill"), s.APIHandler(libpod.KillContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/kill"), s.APIHandler(compat.KillContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{name}/mount libpod libpodMountContainer // --- // tags: @@ -875,7 +910,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/logs"), s.APIHandler(generic.LogsFromContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/logs"), s.APIHandler(compat.LogsFromContainer)).Methods(http.MethodGet) // swagger:operation POST /libpod/containers/{name}/pause libpod libpodPauseContainer // --- // tags: @@ -897,7 +932,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // "$ref": "#/responses/NoSuchContainer" // 500: // "$ref": "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/pause"), s.APIHandler(handlers.PauseContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/pause"), s.APIHandler(compat.PauseContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{name}/restart libpod libpodRestartContainer // --- // tags: @@ -922,7 +957,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/restart"), s.APIHandler(handlers.RestartContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/restart"), s.APIHandler(compat.RestartContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{name}/start libpod libpodStartContainer // --- // tags: @@ -950,7 +985,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/start"), s.APIHandler(handlers.StartContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/start"), s.APIHandler(compat.StartContainer)).Methods(http.MethodPost) // swagger:operation GET /libpod/containers/{name}/stats libpod libpodStatsContainer // --- // tags: @@ -977,7 +1012,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/stats"), s.APIHandler(generic.StatsContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/stats"), s.APIHandler(compat.StatsContainer)).Methods(http.MethodGet) // swagger:operation GET /libpod/containers/{name}/top libpod libpodTopContainer // --- // tags: @@ -1011,7 +1046,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/top"), s.APIHandler(handlers.TopContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/top"), s.APIHandler(compat.TopContainer)).Methods(http.MethodGet) // swagger:operation POST /libpod/containers/{name}/unpause libpod libpodUnpauseContainer // --- // tags: @@ -1032,7 +1067,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/unpause"), s.APIHandler(handlers.UnpauseContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/unpause"), s.APIHandler(compat.UnpauseContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{name}/wait libpod libpodWaitContainer // --- // tags: @@ -1114,7 +1149,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/stop"), s.APIHandler(handlers.StopContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/stop"), s.APIHandler(compat.StopContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{name}/attach libpod libpodAttachContainer // --- // tags: @@ -1169,7 +1204,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/attach"), s.APIHandler(handlers.AttachContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/attach"), s.APIHandler(compat.AttachContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{name}/resize libpod libpodResizeContainer // --- // tags: @@ -1201,6 +1236,6 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/resize"), s.APIHandler(handlers.ResizeContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/resize"), s.APIHandler(compat.ResizeContainer)).Methods(http.MethodPost) return nil } diff --git a/pkg/api/server/register_distribution.go b/pkg/api/server/register_distribution.go index f03662224..89f69ea67 100644 --- a/pkg/api/server/register_distribution.go +++ b/pkg/api/server/register_distribution.go @@ -1,11 +1,13 @@ package server import ( - "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/gorilla/mux" ) func (s *APIServer) registerDistributionHandlers(r *mux.Router) error { - r.HandleFunc(VersionedPath("/distribution/{name}/json"), handlers.UnsupportedHandler) + r.HandleFunc(VersionedPath("/distribution/{name}/json"), compat.UnsupportedHandler) + // Added non version path to URI to support docker non versioned paths + r.HandleFunc("/distribution/{name}/json", compat.UnsupportedHandler) return nil } diff --git a/pkg/api/server/register_events.go b/pkg/api/server/register_events.go index bc3b62662..b0f403709 100644 --- a/pkg/api/server/register_events.go +++ b/pkg/api/server/register_events.go @@ -3,7 +3,7 @@ package server import ( "net/http" - "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/gorilla/mux" ) @@ -11,8 +11,37 @@ func (s *APIServer) registerEventsHandlers(r *mux.Router) error { // swagger:operation GET /events system getEvents // --- // tags: + // - system (compat) + // summary: Get events + // description: Returns events filtered on query parameters + // produces: + // - application/json + // parameters: + // - name: since + // type: string + // in: query + // description: start streaming events from this time + // - name: until + // type: string + // in: query + // description: stop streaming events later than this + // - name: filters + // type: string + // in: query + // description: JSON encoded map[string][]string of constraints + // responses: + // 200: + // description: returns a string of json data describing an event + // 500: + // "$ref": "#/responses/InternalError" + r.Handle(VersionedPath("/events"), s.APIHandler(compat.GetEvents)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.Handle("/events", s.APIHandler(compat.GetEvents)).Methods(http.MethodGet) + // swagger:operation GET /libpod/events system libpodGetEvents + // --- + // tags: // - system - // summary: Returns events filtered on query parameters + // summary: Get events // description: Returns events filtered on query parameters // produces: // - application/json @@ -34,6 +63,6 @@ func (s *APIServer) registerEventsHandlers(r *mux.Router) error { // description: returns a string of json data describing an event // 500: // "$ref": "#/responses/InternalError" - r.Handle(VersionedPath("/events"), s.APIHandler(handlers.GetEvents)).Methods(http.MethodGet) + r.Handle(VersionedPath("/events"), s.APIHandler(compat.GetEvents)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_exec.go b/pkg/api/server/register_exec.go index ad62de3f5..d27d21a04 100644 --- a/pkg/api/server/register_exec.go +++ b/pkg/api/server/register_exec.go @@ -3,7 +3,7 @@ package server import ( "net/http" - "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/gorilla/mux" ) @@ -74,7 +74,9 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // description: container is paused // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/containers/{name}/create"), s.APIHandler(handlers.CreateExec)).Methods(http.MethodPost) + r.Handle(VersionedPath("/containers/{name}/create"), s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.Handle("/containers/{name}/create", s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation POST /exec/{id}/start compat startExec // --- // tags: @@ -110,7 +112,9 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // description: container is stopped or paused // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/exec/{id}/start"), s.APIHandler(handlers.StartExec)).Methods(http.MethodPost) + r.Handle(VersionedPath("/exec/{id}/start"), s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.Handle("/exec/{id}/start", s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation POST /exec/{id}/resize compat resizeExec // --- // tags: @@ -141,7 +145,9 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchExecInstance" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/exec/{id}/resize"), s.APIHandler(handlers.ResizeExec)).Methods(http.MethodPost) + r.Handle(VersionedPath("/exec/{id}/resize"), s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.Handle("/exec/{id}/resize", s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation GET /exec/{id}/json compat inspectExec // --- // tags: @@ -163,7 +169,9 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchExecInstance" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/exec/{id}/json"), s.APIHandler(handlers.InspectExec)).Methods(http.MethodGet) + r.Handle(VersionedPath("/exec/{id}/json"), s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.Handle("/exec/{id}/json", s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodGet) /* libpod api follows @@ -235,7 +243,7 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // description: container is paused // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/containers/{name}/create"), s.APIHandler(handlers.CreateExec)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/containers/{name}/create"), s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation POST /libpod/exec/{id}/start libpod libpodStartExec // --- // tags: @@ -271,7 +279,7 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // description: container is stopped or paused // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/exec/{id}/start"), s.APIHandler(handlers.StartExec)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/exec/{id}/start"), s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation POST /libpod/exec/{id}/resize libpod libpodResizeExec // --- // tags: @@ -302,7 +310,7 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchExecInstance" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/exec/{id}/resize"), s.APIHandler(handlers.ResizeExec)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/exec/{id}/resize"), s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation GET /libpod/exec/{id}/json libpod libpodInspectExec // --- // tags: @@ -324,6 +332,6 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchExecInstance" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/exec/{id}/json"), s.APIHandler(handlers.InspectExec)).Methods(http.MethodGet) + r.Handle(VersionedPath("/libpod/exec/{id}/json"), s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index db04ecdc9..e6ad045a2 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -3,8 +3,7 @@ package server import ( "net/http" - "github.com/containers/libpod/pkg/api/handlers" - "github.com/containers/libpod/pkg/api/handlers/generic" + "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/containers/libpod/pkg/api/handlers/libpod" "github.com/gorilla/mux" ) @@ -47,8 +46,12 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchImage" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/images/create"), s.APIHandler(generic.CreateImageFromImage)).Methods(http.MethodPost).Queries("fromImage", "{fromImage}") - r.Handle(VersionedPath("/images/create"), s.APIHandler(generic.CreateImageFromSrc)).Methods(http.MethodPost).Queries("fromSrc", "{fromSrc}") + r.Handle(VersionedPath("/images/create"), s.APIHandler(compat.CreateImageFromImage)).Methods(http.MethodPost).Queries("fromImage", "{fromImage}") + // Added non version path to URI to support docker non versioned paths + r.Handle("/images/create", s.APIHandler(compat.CreateImageFromImage)).Methods(http.MethodPost).Queries("fromImage", "{fromImage}") + r.Handle(VersionedPath("/images/create"), s.APIHandler(compat.CreateImageFromSrc)).Methods(http.MethodPost).Queries("fromSrc", "{fromSrc}") + // Added non version path to URI to support docker non versioned paths + r.Handle("/images/create", s.APIHandler(compat.CreateImageFromSrc)).Methods(http.MethodPost).Queries("fromSrc", "{fromSrc}") // swagger:operation GET /images/json compat listImages // --- // tags: @@ -83,7 +86,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/DockerImageSummary" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/json"), s.APIHandler(generic.GetImages)).Methods(http.MethodGet) + r.Handle(VersionedPath("/images/json"), s.APIHandler(compat.GetImages)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.Handle("/images/json", s.APIHandler(compat.GetImages)).Methods(http.MethodGet) // swagger:operation POST /images/load compat importImage // --- // tags: @@ -107,7 +112,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: no error // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/load"), s.APIHandler(generic.LoadImages)).Methods(http.MethodPost) + r.Handle(VersionedPath("/images/load"), s.APIHandler(compat.LoadImages)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.Handle("/images/load", s.APIHandler(compat.LoadImages)).Methods(http.MethodPost) // swagger:operation POST /images/prune compat pruneImages // --- // tags: @@ -132,7 +139,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/DocsImageDeleteResponse" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/prune"), s.APIHandler(generic.PruneImages)).Methods(http.MethodPost) + r.Handle(VersionedPath("/images/prune"), s.APIHandler(compat.PruneImages)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.Handle("/images/prune", s.APIHandler(compat.PruneImages)).Methods(http.MethodPost) // swagger:operation GET /images/search compat searchImages // --- // tags: @@ -165,7 +174,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/BadParamError" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/search"), s.APIHandler(handlers.SearchImages)).Methods(http.MethodGet) + r.Handle(VersionedPath("/images/search"), s.APIHandler(compat.SearchImages)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.Handle("/images/search", s.APIHandler(compat.SearchImages)).Methods(http.MethodGet) // swagger:operation DELETE /images/{name:.*} compat removeImage // --- // tags: @@ -197,7 +208,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/ConflictError' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/{name:.*}"), s.APIHandler(handlers.RemoveImage)).Methods(http.MethodDelete) + r.Handle(VersionedPath("/images/{name:.*}"), s.APIHandler(compat.RemoveImage)).Methods(http.MethodDelete) + // Added non version path to URI to support docker non versioned paths + r.Handle("/images/{name:.*}", s.APIHandler(compat.RemoveImage)).Methods(http.MethodDelete) // swagger:operation GET /images/{name:.*}/get compat exportImage // --- // tags: @@ -220,7 +233,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // format: binary // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/{name:.*}/get"), s.APIHandler(generic.ExportImage)).Methods(http.MethodGet) + r.Handle(VersionedPath("/images/{name:.*}/get"), s.APIHandler(compat.ExportImage)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.Handle("/images/{name:.*}/get", s.APIHandler(compat.ExportImage)).Methods(http.MethodGet) // swagger:operation GET /images/{name:.*}/history compat imageHistory // --- // tags: @@ -242,7 +257,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchImage" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/images/{name:.*}/history"), s.APIHandler(handlers.HistoryImage)).Methods(http.MethodGet) + r.Handle(VersionedPath("/images/{name:.*}/history"), s.APIHandler(compat.HistoryImage)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.Handle("/images/{name:.*}/history", s.APIHandler(compat.HistoryImage)).Methods(http.MethodGet) // swagger:operation GET /images/{name:.*}/json compat inspectImage // --- // tags: @@ -264,7 +281,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchImage" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/images/{name:.*}/json"), s.APIHandler(generic.GetImage)).Methods(http.MethodGet) + r.Handle(VersionedPath("/images/{name:.*}/json"), s.APIHandler(compat.GetImage)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.Handle("/images/{name:.*}/json", s.APIHandler(compat.GetImage)).Methods(http.MethodGet) // swagger:operation POST /images/{name:.*}/tag compat tagImage // --- // tags: @@ -298,7 +317,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/ConflictError' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/{name:.*}/tag"), s.APIHandler(handlers.TagImage)).Methods(http.MethodPost) + r.Handle(VersionedPath("/images/{name:.*}/tag"), s.APIHandler(compat.TagImage)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.Handle("/images/{name:.*}/tag", s.APIHandler(compat.TagImage)).Methods(http.MethodPost) // swagger:operation POST /commit compat commitContainer // --- // tags: @@ -343,7 +364,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/NoSuchImage' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/commit"), s.APIHandler(generic.CommitContainer)).Methods(http.MethodPost) + r.Handle(VersionedPath("/commit"), s.APIHandler(compat.CommitContainer)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.Handle("/commit", s.APIHandler(compat.CommitContainer)).Methods(http.MethodPost) // swagger:operation POST /build compat buildImage // --- @@ -553,7 +576,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/BadParamError" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/build"), s.APIHandler(handlers.BuildImage)).Methods(http.MethodPost) + r.Handle(VersionedPath("/build"), s.APIHandler(compat.BuildImage)).Methods(http.MethodPost) + // Added non version path to URI to support docker non versioned paths + r.Handle("/build", s.APIHandler(compat.BuildImage)).Methods(http.MethodPost) /* libpod endpoints */ @@ -627,7 +652,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/NoSuchImage' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/{name:.*}/history"), s.APIHandler(handlers.HistoryImage)).Methods(http.MethodGet) + r.Handle(VersionedPath("/libpod/images/{name:.*}/history"), s.APIHandler(compat.HistoryImage)).Methods(http.MethodGet) // swagger:operation GET /libpod/images/json libpod libpodListImages // --- // tags: @@ -822,7 +847,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/DocsSearchResponse" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/search"), s.APIHandler(handlers.SearchImages)).Methods(http.MethodGet) + r.Handle(VersionedPath("/libpod/images/search"), s.APIHandler(compat.SearchImages)).Methods(http.MethodGet) // swagger:operation DELETE /libpod/images/{name:.*} libpod libpodRemoveImage // --- // tags: @@ -852,7 +877,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/ConflictError' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/{name:.*}"), s.APIHandler(handlers.RemoveImage)).Methods(http.MethodDelete) + r.Handle(VersionedPath("/libpod/images/{name:.*}"), s.APIHandler(compat.RemoveImage)).Methods(http.MethodDelete) // swagger:operation GET /libpod/images/{name:.*}/get libpod libpodExportImage // --- // tags: @@ -941,7 +966,51 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/ConflictError' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/{name:.*}/tag"), s.APIHandler(handlers.TagImage)).Methods(http.MethodPost) - + r.Handle(VersionedPath("/libpod/images/{name:.*}/tag"), s.APIHandler(compat.TagImage)).Methods(http.MethodPost) + // swagger:operation POST /commit libpod libpodCommitContainer + // --- + // tags: + // - containers + // summary: Commit + // description: Create a new image from a container + // parameters: + // - in: query + // name: container + // type: string + // description: the name or ID of a container + // - in: query + // name: repo + // type: string + // description: the repository name for the created image + // - in: query + // name: tag + // type: string + // description: tag name for the created image + // - in: query + // name: comment + // type: string + // description: commit message + // - in: query + // name: author + // type: string + // description: author of the image + // - in: query + // name: pause + // type: boolean + // description: pause the container before committing it + // - in: query + // name: changes + // type: string + // description: instructions to apply while committing in Dockerfile format + // produces: + // - application/json + // responses: + // 201: + // description: no error + // 404: + // $ref: '#/responses/NoSuchImage' + // 500: + // $ref: '#/responses/InternalError' + r.Handle(VersionedPath("/commit"), s.APIHandler(compat.CommitContainer)).Methods(http.MethodPost) return nil } diff --git a/pkg/api/server/register_info.go b/pkg/api/server/register_info.go index 36c467cc3..b4ab8871c 100644 --- a/pkg/api/server/register_info.go +++ b/pkg/api/server/register_info.go @@ -3,7 +3,7 @@ package server import ( "net/http" - "github.com/containers/libpod/pkg/api/handlers/generic" + "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/gorilla/mux" ) @@ -21,6 +21,8 @@ func (s *APIServer) registerInfoHandlers(r *mux.Router) error { // description: to be determined // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/info"), s.APIHandler(generic.GetInfo)).Methods(http.MethodGet) + r.Handle(VersionedPath("/info"), s.APIHandler(compat.GetInfo)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.Handle("/info", s.APIHandler(compat.GetInfo)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_monitor.go b/pkg/api/server/register_monitor.go index dbe0d27ce..b7a7c3792 100644 --- a/pkg/api/server/register_monitor.go +++ b/pkg/api/server/register_monitor.go @@ -1,11 +1,13 @@ package server import ( - "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/gorilla/mux" ) func (s *APIServer) registerMonitorHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/monitor"), s.APIHandler(handlers.UnsupportedHandler)) + r.Handle(VersionedPath("/monitor"), s.APIHandler(compat.UnsupportedHandler)) + // Added non version path to URI to support docker non versioned paths + r.Handle("/monitor", s.APIHandler(compat.UnsupportedHandler)) return nil } diff --git a/pkg/api/server/register_ping.go b/pkg/api/server/register_ping.go index 349a8a71a..8a1cda3d4 100644 --- a/pkg/api/server/register_ping.go +++ b/pkg/api/server/register_ping.go @@ -3,14 +3,14 @@ package server import ( "net/http" - "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/gorilla/mux" ) func (s *APIServer) registerPingHandlers(r *mux.Router) error { - r.Handle("/_ping", s.APIHandler(handlers.Ping)).Methods(http.MethodGet) - r.Handle("/_ping", s.APIHandler(handlers.Ping)).Methods(http.MethodHead) + r.Handle("/_ping", s.APIHandler(compat.Ping)).Methods(http.MethodGet) + r.Handle("/_ping", s.APIHandler(compat.Ping)).Methods(http.MethodHead) // swagger:operation GET /libpod/_ping libpod libpodPingGet // --- @@ -61,7 +61,7 @@ func (s *APIServer) registerPingHandlers(r *mux.Router) error { // determine if talking to Podman engine or another engine // 500: // $ref: "#/responses/InternalError" - r.Handle("/libpod/_ping", s.APIHandler(handlers.Ping)).Methods(http.MethodGet) - r.Handle("/libpod/_ping", s.APIHandler(handlers.Ping)).Methods(http.MethodHead) + r.Handle("/libpod/_ping", s.APIHandler(compat.Ping)).Methods(http.MethodGet) + r.Handle("/libpod/_ping", s.APIHandler(compat.Ping)).Methods(http.MethodHead) return nil } diff --git a/pkg/api/server/register_plugins.go b/pkg/api/server/register_plugins.go index 479a79d1f..5f6473fe8 100644 --- a/pkg/api/server/register_plugins.go +++ b/pkg/api/server/register_plugins.go @@ -1,11 +1,13 @@ package server import ( - "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/gorilla/mux" ) func (s *APIServer) registerPluginsHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/plugins"), s.APIHandler(handlers.UnsupportedHandler)) + r.Handle(VersionedPath("/plugins"), s.APIHandler(compat.UnsupportedHandler)) + // Added non version path to URI to support docker non versioned paths + r.Handle("/plugins", s.APIHandler(compat.UnsupportedHandler)) return nil } diff --git a/pkg/api/server/register_swarm.go b/pkg/api/server/register_swarm.go index e37ac4e41..8a5588268 100644 --- a/pkg/api/server/register_swarm.go +++ b/pkg/api/server/register_swarm.go @@ -16,6 +16,14 @@ func (s *APIServer) registerSwarmHandlers(r *mux.Router) error { r.PathPrefix("/v{version:[0-9.]+}/services/").HandlerFunc(noSwarm) r.PathPrefix("/v{version:[0-9.]+}/swarm/").HandlerFunc(noSwarm) r.PathPrefix("/v{version:[0-9.]+}/tasks/").HandlerFunc(noSwarm) + + // Added non version path to URI to support docker non versioned paths + r.PathPrefix("/configs/").HandlerFunc(noSwarm) + r.PathPrefix("/nodes/").HandlerFunc(noSwarm) + r.PathPrefix("/secrets/").HandlerFunc(noSwarm) + r.PathPrefix("/services/").HandlerFunc(noSwarm) + r.PathPrefix("/swarm/").HandlerFunc(noSwarm) + r.PathPrefix("/tasks/").HandlerFunc(noSwarm) return nil } diff --git a/pkg/api/server/register_system.go b/pkg/api/server/register_system.go index 188c1cdac..708ccd39b 100644 --- a/pkg/api/server/register_system.go +++ b/pkg/api/server/register_system.go @@ -3,11 +3,13 @@ package server import ( "net/http" - "github.com/containers/libpod/pkg/api/handlers/generic" + "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/gorilla/mux" ) func (s *APIServer) registerSystemHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/system/df"), s.APIHandler(generic.GetDiskUsage)).Methods(http.MethodGet) + r.Handle(VersionedPath("/system/df"), s.APIHandler(compat.GetDiskUsage)).Methods(http.MethodGet) + // Added non version path to URI to support docker non versioned paths + r.Handle("/system/df", s.APIHandler(compat.GetDiskUsage)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_version.go b/pkg/api/server/register_version.go index ee01ad4b3..25cacbc61 100644 --- a/pkg/api/server/register_version.go +++ b/pkg/api/server/register_version.go @@ -3,12 +3,12 @@ package server import ( "net/http" - "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/gorilla/mux" ) func (s *APIServer) registerVersionHandlers(r *mux.Router) error { - r.Handle("/version", s.APIHandler(handlers.VersionHandler)).Methods(http.MethodGet) - r.Handle(VersionedPath("/version"), s.APIHandler(handlers.VersionHandler)).Methods(http.MethodGet) + r.Handle("/version", s.APIHandler(compat.VersionHandler)).Methods(http.MethodGet) + r.Handle(VersionedPath("/version"), s.APIHandler(compat.VersionHandler)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go index a5922e5d7..a0addb303 100644 --- a/pkg/api/server/server.go +++ b/pkg/api/server/server.go @@ -12,7 +12,7 @@ import ( "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/api/handlers" - "github.com/coreos/go-systemd/activation" + "github.com/coreos/go-systemd/v22/activation" "github.com/gorilla/mux" "github.com/gorilla/schema" "github.com/pkg/errors" diff --git a/pkg/api/tags.yaml b/pkg/api/tags.yaml index 3bf2bb64f..571f49e44 100644 --- a/pkg/api/tags.yaml +++ b/pkg/api/tags.yaml @@ -18,4 +18,4 @@ tags: - name: images (compat) description: Actions related to images for the compatibility endpoints - name: system (compat) - description: Actions related to Podman and compatiblity engines + description: Actions related to Podman and compatibility engines diff --git a/pkg/apparmor/apparmor.go b/pkg/apparmor/apparmor.go index 45c029c07..1e824550d 100644 --- a/pkg/apparmor/apparmor.go +++ b/pkg/apparmor/apparmor.go @@ -2,6 +2,7 @@ package apparmor import ( "errors" + libpodVersion "github.com/containers/libpod/version" ) diff --git a/pkg/bindings/containers/create.go b/pkg/bindings/containers/create.go index 43a3ef02d..495f9db49 100644 --- a/pkg/bindings/containers/create.go +++ b/pkg/bindings/containers/create.go @@ -11,7 +11,7 @@ import ( jsoniter "github.com/json-iterator/go" ) -func CreateWithSpec(ctx context.Context, s specgen.SpecGenerator) (utils.ContainerCreateResponse, error) { +func CreateWithSpec(ctx context.Context, s *specgen.SpecGenerator) (utils.ContainerCreateResponse, error) { var ccr utils.ContainerCreateResponse conn, err := bindings.GetClient(ctx) if err != nil { diff --git a/pkg/bindings/containers/healthcheck.go b/pkg/bindings/containers/healthcheck.go index dc607c1b3..3f94fad01 100644 --- a/pkg/bindings/containers/healthcheck.go +++ b/pkg/bindings/containers/healthcheck.go @@ -2,10 +2,10 @@ package containers import ( "context" - "github.com/containers/libpod/pkg/bindings" "net/http" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/bindings" ) // RunHealthCheck executes the container's healthcheck and returns the health status of the diff --git a/pkg/bindings/test/common_test.go b/pkg/bindings/test/common_test.go index 1fc774074..a4d065a14 100644 --- a/pkg/bindings/test/common_test.go +++ b/pkg/bindings/test/common_test.go @@ -1,6 +1,7 @@ package test_bindings import ( + "context" "fmt" "io/ioutil" "os" @@ -8,6 +9,9 @@ import ( "path/filepath" "strings" + . "github.com/containers/libpod/pkg/bindings" + "github.com/containers/libpod/pkg/bindings/containers" + "github.com/containers/libpod/pkg/specgen" "github.com/onsi/ginkgo" "github.com/onsi/gomega/gexec" "github.com/pkg/errors" @@ -55,6 +59,16 @@ type bindingTest struct { tempDirPath string runRoot string crioRoot string + conn context.Context +} + +func (b *bindingTest) NewConnection() error { + connText, err := NewConnection(context.Background(), b.sock) + if err != nil { + return err + } + b.conn = connText + return nil } func (b *bindingTest) runPodman(command []string) *gexec.Session { @@ -173,17 +187,27 @@ func (b *bindingTest) restoreImageFromCache(i testImage) { // Run a container within or without a pod // and add or append the alpine image to it -func (b *bindingTest) RunTopContainer(containerName *string, insidePod *bool, podName *string) { - cmd := []string{"run", "-dt"} +func (b *bindingTest) RunTopContainer(containerName *string, insidePod *bool, podName *string) (string, error) { + s := specgen.NewSpecGenerator(alpine.name) + s.Terminal = false + s.Command = []string{"top"} + if containerName != nil { + s.Name = *containerName + } if insidePod != nil && podName != nil { - pName := *podName - cmd = append(cmd, "--pod", pName) - } else if containerName != nil { - cName := *containerName - cmd = append(cmd, "--name", cName) - } - cmd = append(cmd, alpine.name, "top") - b.runPodman(cmd).Wait(45) + s.Pod = *podName + } + ctr, err := containers.CreateWithSpec(b.conn, s) + if err != nil { + return "", nil + } + err = containers.Start(b.conn, ctr.ID, nil) + if err != nil { + return "", err + } + waiting := "running" + _, err = containers.Wait(b.conn, ctr.ID, &waiting) + return ctr.ID, err } // This method creates a pod with the given pod name. diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go index 299a78ac2..e7ef620d4 100644 --- a/pkg/bindings/test/containers_test.go +++ b/pkg/bindings/test/containers_test.go @@ -1,7 +1,6 @@ package test_bindings import ( - "context" "net/http" "strconv" "time" @@ -18,7 +17,6 @@ var _ = Describe("Podman containers ", func() { var ( bt *bindingTest s *gexec.Session - connText context.Context err error falseFlag bool = false trueFlag bool = true @@ -29,18 +27,18 @@ var _ = Describe("Podman containers ", func() { bt.RestoreImagesFromCache() s = bt.startAPIService() time.Sleep(1 * time.Second) - connText, err = bindings.NewConnection(context.Background(), bt.sock) + err := bt.NewConnection() Expect(err).To(BeNil()) }) AfterEach(func() { s.Kill() - bt.cleanup() + //bt.cleanup() }) It("podman pause a bogus container", func() { // Pausing bogus container should return 404 - err = containers.Pause(connText, "foobar") + err = containers.Pause(bt.conn, "foobar") Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) @@ -48,7 +46,7 @@ var _ = Describe("Podman containers ", func() { It("podman unpause a bogus container", func() { // Unpausing bogus container should return 404 - err = containers.Unpause(connText, "foobar") + err = containers.Unpause(bt.conn, "foobar") Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) @@ -57,12 +55,13 @@ var _ = Describe("Podman containers ", func() { It("podman pause a running container by name", func() { // Pausing by name should work var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - err := containers.Pause(connText, name) + _, err := bt.RunTopContainer(&name, &falseFlag, nil) + Expect(err).To(BeNil()) + err = containers.Pause(bt.conn, name) Expect(err).To(BeNil()) // Ensure container is paused - data, err := containers.Inspect(connText, name, nil) + data, err := containers.Inspect(bt.conn, name, nil) Expect(err).To(BeNil()) Expect(data.State.Status).To(Equal("paused")) }) @@ -70,54 +69,60 @@ var _ = Describe("Podman containers ", func() { It("podman pause a running container by id", func() { // Pausing by id should work var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - data, err := containers.Inspect(connText, name, nil) + cid, err := bt.RunTopContainer(&name, &falseFlag, nil) Expect(err).To(BeNil()) - err = containers.Pause(connText, data.ID) + err = containers.Pause(bt.conn, cid) Expect(err).To(BeNil()) // Ensure container is paused - data, err = containers.Inspect(connText, data.ID, nil) + data, err := containers.Inspect(bt.conn, cid, nil) + Expect(err).To(BeNil()) Expect(data.State.Status).To(Equal("paused")) }) It("podman unpause a running container by name", func() { // Unpausing by name should work var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - err := containers.Pause(connText, name) + _, err := bt.RunTopContainer(&name, &falseFlag, nil) Expect(err).To(BeNil()) - err = containers.Unpause(connText, name) + err = containers.Pause(bt.conn, name) + Expect(err).To(BeNil()) + err = containers.Unpause(bt.conn, name) Expect(err).To(BeNil()) // Ensure container is unpaused - data, err := containers.Inspect(connText, name, nil) + data, err := containers.Inspect(bt.conn, name, nil) + Expect(err).To(BeNil()) Expect(data.State.Status).To(Equal("running")) }) It("podman unpause a running container by ID", func() { // Unpausing by ID should work var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - // Pause by name - err := containers.Pause(connText, name) - data, err := containers.Inspect(connText, name, nil) + _, err := bt.RunTopContainer(&name, &falseFlag, nil) Expect(err).To(BeNil()) - err = containers.Unpause(connText, data.ID) + // Pause by name + err = containers.Pause(bt.conn, name) + //paused := "paused" + //_, err = containers.Wait(bt.conn, cid, &paused) + //Expect(err).To(BeNil()) + err = containers.Unpause(bt.conn, name) Expect(err).To(BeNil()) // Ensure container is unpaused - data, err = containers.Inspect(connText, name, nil) + data, err := containers.Inspect(bt.conn, name, nil) + Expect(err).To(BeNil()) Expect(data.State.Status).To(Equal("running")) }) It("podman pause a paused container by name", func() { // Pausing a paused container by name should fail var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - err := containers.Pause(connText, name) + _, err := bt.RunTopContainer(&name, &falseFlag, nil) Expect(err).To(BeNil()) - err = containers.Pause(connText, name) + err = containers.Pause(bt.conn, name) + Expect(err).To(BeNil()) + err = containers.Pause(bt.conn, name) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) @@ -126,12 +131,11 @@ var _ = Describe("Podman containers ", func() { It("podman pause a paused container by id", func() { // Pausing a paused container by id should fail var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - data, err := containers.Inspect(connText, name, nil) + cid, err := bt.RunTopContainer(&name, &falseFlag, nil) Expect(err).To(BeNil()) - err = containers.Pause(connText, data.ID) + err = containers.Pause(bt.conn, cid) Expect(err).To(BeNil()) - err = containers.Pause(connText, data.ID) + err = containers.Pause(bt.conn, cid) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) @@ -140,10 +144,11 @@ var _ = Describe("Podman containers ", func() { It("podman pause a stopped container by name", func() { // Pausing a stopped container by name should fail var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - err := containers.Stop(connText, name, nil) + _, err := bt.RunTopContainer(&name, &falseFlag, nil) + Expect(err).To(BeNil()) + err = containers.Stop(bt.conn, name, nil) Expect(err).To(BeNil()) - err = containers.Pause(connText, name) + err = containers.Pause(bt.conn, name) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) @@ -152,11 +157,11 @@ var _ = Describe("Podman containers ", func() { It("podman pause a stopped container by id", func() { // Pausing a stopped container by id should fail var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - data, err := containers.Inspect(connText, name, nil) - err = containers.Stop(connText, data.ID, nil) + cid, err := bt.RunTopContainer(&name, &falseFlag, nil) Expect(err).To(BeNil()) - err = containers.Pause(connText, data.ID) + err = containers.Stop(bt.conn, cid, nil) + Expect(err).To(BeNil()) + err = containers.Pause(bt.conn, cid) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) @@ -165,12 +170,11 @@ var _ = Describe("Podman containers ", func() { It("podman remove a paused container by id without force", func() { // Removing a paused container without force should fail var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - data, err := containers.Inspect(connText, name, nil) + cid, err := bt.RunTopContainer(&name, &falseFlag, nil) Expect(err).To(BeNil()) - err = containers.Pause(connText, data.ID) + err = containers.Pause(bt.conn, cid) Expect(err).To(BeNil()) - err = containers.Remove(connText, data.ID, &falseFlag, &falseFlag) + err = containers.Remove(bt.conn, cid, &falseFlag, &falseFlag) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) @@ -187,22 +191,22 @@ var _ = Describe("Podman containers ", func() { // Removing a paused container with force should work var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - data, err := containers.Inspect(connText, name, nil) + cid, err := bt.RunTopContainer(&name, &falseFlag, nil) Expect(err).To(BeNil()) - err = containers.Pause(connText, data.ID) + err = containers.Pause(bt.conn, cid) Expect(err).To(BeNil()) - err = containers.Remove(connText, data.ID, &trueFlag, &falseFlag) + err = containers.Remove(bt.conn, cid, &trueFlag, &falseFlag) Expect(err).To(BeNil()) }) It("podman stop a paused container by name", func() { // Stopping a paused container by name should fail var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - err := containers.Pause(connText, name) + _, err := bt.RunTopContainer(&name, &falseFlag, nil) + Expect(err).To(BeNil()) + err = containers.Pause(bt.conn, name) Expect(err).To(BeNil()) - err = containers.Stop(connText, name, nil) + err = containers.Stop(bt.conn, name, nil) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) @@ -211,12 +215,11 @@ var _ = Describe("Podman containers ", func() { It("podman stop a paused container by id", func() { // Stopping a paused container by id should fail var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - data, err := containers.Inspect(connText, name, nil) + cid, err := bt.RunTopContainer(&name, &falseFlag, nil) Expect(err).To(BeNil()) - err = containers.Pause(connText, data.ID) + err = containers.Pause(bt.conn, cid) Expect(err).To(BeNil()) - err = containers.Stop(connText, data.ID, nil) + err = containers.Stop(bt.conn, cid, nil) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) @@ -225,12 +228,13 @@ var _ = Describe("Podman containers ", func() { It("podman stop a running container by name", func() { // Stopping a running container by name should work var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - err := containers.Stop(connText, name, nil) + _, err := bt.RunTopContainer(&name, &falseFlag, nil) + Expect(err).To(BeNil()) + err = containers.Stop(bt.conn, name, nil) Expect(err).To(BeNil()) // Ensure container is stopped - data, err := containers.Inspect(connText, name, nil) + data, err := containers.Inspect(bt.conn, name, nil) Expect(err).To(BeNil()) Expect(isStopped(data.State.Status)).To(BeTrue()) }) @@ -238,14 +242,13 @@ var _ = Describe("Podman containers ", func() { It("podman stop a running container by ID", func() { // Stopping a running container by ID should work var name = "top" - bt.RunTopContainer(&name, &falseFlag, nil) - data, err := containers.Inspect(connText, name, nil) + cid, err := bt.RunTopContainer(&name, &falseFlag, nil) Expect(err).To(BeNil()) - err = containers.Stop(connText, data.ID, nil) + err = containers.Stop(bt.conn, cid, nil) Expect(err).To(BeNil()) // Ensure container is stopped - data, err = containers.Inspect(connText, name, nil) + data, err := containers.Inspect(bt.conn, name, nil) Expect(err).To(BeNil()) Expect(isStopped(data.State.Status)).To(BeTrue()) }) @@ -255,19 +258,20 @@ var _ = Describe("Podman containers ", func() { name = "top" exitCode int32 = -1 ) - _, err := containers.Wait(connText, "foobar", nil) + _, err := containers.Wait(bt.conn, "foobar", nil) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) errChan := make(chan error) - bt.RunTopContainer(&name, nil, nil) + _, err = bt.RunTopContainer(&name, nil, nil) + Expect(err).To(BeNil()) go func() { - exitCode, err = containers.Wait(connText, name, nil) + exitCode, err = containers.Wait(bt.conn, name, nil) errChan <- err close(errChan) }() - err = containers.Stop(connText, name, nil) + err = containers.Stop(bt.conn, name, nil) Expect(err).To(BeNil()) wait := <-errChan Expect(wait).To(BeNil()) @@ -282,13 +286,14 @@ var _ = Describe("Podman containers ", func() { unpause = "running" ) errChan := make(chan error) - bt.RunTopContainer(&name, nil, nil) + _, err := bt.RunTopContainer(&name, nil, nil) + Expect(err).To(BeNil()) go func() { - exitCode, err = containers.Wait(connText, name, &pause) + exitCode, err = containers.Wait(bt.conn, name, &pause) errChan <- err close(errChan) }() - err := containers.Pause(connText, name) + err = containers.Pause(bt.conn, name) Expect(err).To(BeNil()) wait := <-errChan Expect(wait).To(BeNil()) @@ -296,11 +301,11 @@ var _ = Describe("Podman containers ", func() { errChan = make(chan error) go func() { - exitCode, err = containers.Wait(connText, name, &unpause) + exitCode, err = containers.Wait(bt.conn, name, &unpause) errChan <- err close(errChan) }() - err = containers.Unpause(connText, name) + err = containers.Unpause(bt.conn, name) Expect(err).To(BeNil()) unPausewait := <-errChan Expect(unPausewait).To(BeNil()) diff --git a/pkg/bindings/test/create_test.go b/pkg/bindings/test/create_test.go new file mode 100644 index 000000000..f83a9b14d --- /dev/null +++ b/pkg/bindings/test/create_test.go @@ -0,0 +1,50 @@ +package test_bindings + +import ( + "time" + + "github.com/containers/libpod/pkg/bindings/containers" + "github.com/containers/libpod/pkg/specgen" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/gexec" +) + +var _ = Describe("Create containers ", func() { + var ( + bt *bindingTest + s *gexec.Session + ) + + BeforeEach(func() { + bt = newBindingTest() + bt.RestoreImagesFromCache() + s = bt.startAPIService() + time.Sleep(1 * time.Second) + err := bt.NewConnection() + Expect(err).To(BeNil()) + }) + + AfterEach(func() { + s.Kill() + bt.cleanup() + }) + + It("create a container running top", func() { + s := specgen.NewSpecGenerator(alpine.name) + s.Command = []string{"top"} + s.Terminal = true + s.Name = "top" + ctr, err := containers.CreateWithSpec(bt.conn, s) + Expect(err).To(BeNil()) + data, err := containers.Inspect(bt.conn, ctr.ID, nil) + Expect(err).To(BeNil()) + Expect(data.Name).To(Equal("top")) + err = containers.Start(bt.conn, ctr.ID, nil) + Expect(err).To(BeNil()) + data, err = containers.Inspect(bt.conn, ctr.ID, nil) + Expect(err).To(BeNil()) + Expect(data.State.Status).To(Equal("running")) + }) + +}) diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go index 8eef28502..17b3b254a 100644 --- a/pkg/bindings/test/images_test.go +++ b/pkg/bindings/test/images_test.go @@ -1,7 +1,6 @@ package test_bindings import ( - "context" "net/http" "os" "path/filepath" @@ -22,7 +21,6 @@ var _ = Describe("Podman images", func() { //podmanTest *PodmanTestIntegration bt *bindingTest s *gexec.Session - connText context.Context err error falseFlag bool = false trueFlag bool = true @@ -40,7 +38,7 @@ var _ = Describe("Podman images", func() { bt.RestoreImagesFromCache() s = bt.startAPIService() time.Sleep(1 * time.Second) - connText, err = bindings.NewConnection(context.Background(), bt.sock) + err := bt.NewConnection() Expect(err).To(BeNil()) }) @@ -53,32 +51,32 @@ var _ = Describe("Podman images", func() { }) It("inspect image", func() { // Inspect invalid image be 404 - _, err = images.GetImage(connText, "foobar5000", nil) + _, err = images.GetImage(bt.conn, "foobar5000", nil) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) // Inspect by short name - data, err := images.GetImage(connText, alpine.shortName, nil) + data, err := images.GetImage(bt.conn, alpine.shortName, nil) Expect(err).To(BeNil()) // Inspect with full ID - _, err = images.GetImage(connText, data.ID, nil) + _, err = images.GetImage(bt.conn, data.ID, nil) Expect(err).To(BeNil()) // Inspect with partial ID - _, err = images.GetImage(connText, data.ID[0:12], nil) + _, err = images.GetImage(bt.conn, data.ID[0:12], nil) Expect(err).To(BeNil()) // Inspect by long name - _, err = images.GetImage(connText, alpine.name, nil) + _, err = images.GetImage(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) // TODO it looks like the images API alwaays returns size regardless // of bool or not. What should we do ? //Expect(data.Size).To(BeZero()) // Enabling the size parameter should result in size being populated - data, err = images.GetImage(connText, alpine.name, &trueFlag) + data, err = images.GetImage(bt.conn, alpine.name, &trueFlag) Expect(err).To(BeNil()) Expect(data.Size).To(BeNumerically(">", 0)) }) @@ -86,49 +84,50 @@ var _ = Describe("Podman images", func() { // Test to validate the remove image api It("remove image", func() { // Remove invalid image should be a 404 - _, err = images.Remove(connText, "foobar5000", &falseFlag) + _, err = images.Remove(bt.conn, "foobar5000", &falseFlag) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) // Remove an image by name, validate image is removed and error is nil - inspectData, err := images.GetImage(connText, busybox.shortName, nil) + inspectData, err := images.GetImage(bt.conn, busybox.shortName, nil) Expect(err).To(BeNil()) - response, err := images.Remove(connText, busybox.shortName, nil) + response, err := images.Remove(bt.conn, busybox.shortName, nil) Expect(err).To(BeNil()) Expect(inspectData.ID).To(Equal(response[0]["Deleted"])) - inspectData, err = images.GetImage(connText, busybox.shortName, nil) + inspectData, err = images.GetImage(bt.conn, busybox.shortName, nil) code, _ = bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) // Start a container with alpine image var top string = "top" - bt.RunTopContainer(&top, &falseFlag, nil) + _, err = bt.RunTopContainer(&top, &falseFlag, nil) + Expect(err).To(BeNil()) // we should now have a container called "top" running - containerResponse, err := containers.Inspect(connText, "top", &falseFlag) + containerResponse, err := containers.Inspect(bt.conn, "top", &falseFlag) Expect(err).To(BeNil()) Expect(containerResponse.Name).To(Equal("top")) // try to remove the image "alpine". This should fail since we are not force // deleting hence image cannot be deleted until the container is deleted. - response, err = images.Remove(connText, alpine.shortName, &falseFlag) + response, err = images.Remove(bt.conn, alpine.shortName, &falseFlag) code, _ = bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) // Removing the image "alpine" where force = true - response, err = images.Remove(connText, alpine.shortName, &trueFlag) + response, err = images.Remove(bt.conn, alpine.shortName, &trueFlag) Expect(err).To(BeNil()) // Checking if both the images are gone as well as the container is deleted - inspectData, err = images.GetImage(connText, busybox.shortName, nil) + inspectData, err = images.GetImage(bt.conn, busybox.shortName, nil) code, _ = bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) - inspectData, err = images.GetImage(connText, alpine.shortName, nil) + inspectData, err = images.GetImage(bt.conn, alpine.shortName, nil) code, _ = bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) - _, err = containers.Inspect(connText, "top", &falseFlag) + _, err = containers.Inspect(bt.conn, "top", &falseFlag) code, _ = bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) }) @@ -136,17 +135,17 @@ var _ = Describe("Podman images", func() { // Tests to validate the image tag command. It("tag image", func() { // Validates if invalid image name is given a bad response is encountered. - err = images.Tag(connText, "dummy", "demo", alpine.shortName) + err = images.Tag(bt.conn, "dummy", "demo", alpine.shortName) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) - // Validates if the image is tagged sucessfully. - err = images.Tag(connText, alpine.shortName, "demo", alpine.shortName) + // Validates if the image is tagged successfully. + err = images.Tag(bt.conn, alpine.shortName, "demo", alpine.shortName) Expect(err).To(BeNil()) //Validates if name updates when the image is retagged. - _, err := images.GetImage(connText, "alpine:demo", nil) + _, err := images.GetImage(bt.conn, "alpine:demo", nil) Expect(err).To(BeNil()) }) @@ -154,7 +153,7 @@ var _ = Describe("Podman images", func() { // Test to validate the List images command. It("List image", func() { // Array to hold the list of images returned - imageSummary, err := images.List(connText, nil, nil) + imageSummary, err := images.List(bt.conn, nil, nil) // There Should be no errors in the response. Expect(err).To(BeNil()) // Since in the begin context two images are created the @@ -164,7 +163,7 @@ var _ = Describe("Podman images", func() { // Adding one more image. There Should be no errors in the response. // And the count should be three now. bt.Pull("busybox:glibc") - imageSummary, err = images.List(connText, nil, nil) + imageSummary, err = images.List(bt.conn, nil, nil) Expect(err).To(BeNil()) Expect(len(imageSummary)).To(Equal(3)) @@ -179,13 +178,13 @@ var _ = Describe("Podman images", func() { // List images with a filter filters := make(map[string][]string) filters["reference"] = []string{alpine.name} - filteredImages, err := images.List(connText, &falseFlag, filters) + filteredImages, err := images.List(bt.conn, &falseFlag, filters) Expect(err).To(BeNil()) Expect(len(filteredImages)).To(BeNumerically("==", 1)) // List images with a bad filter filters["name"] = []string{alpine.name} - _, err = images.List(connText, &falseFlag, filters) + _, err = images.List(bt.conn, &falseFlag, filters) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) @@ -193,64 +192,64 @@ var _ = Describe("Podman images", func() { It("Image Exists", func() { // exists on bogus image should be false, with no error - exists, err := images.Exists(connText, "foobar") + exists, err := images.Exists(bt.conn, "foobar") Expect(err).To(BeNil()) Expect(exists).To(BeFalse()) // exists with shortname should be true - exists, err = images.Exists(connText, alpine.shortName) + exists, err = images.Exists(bt.conn, alpine.shortName) Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) // exists with fqname should be true - exists, err = images.Exists(connText, alpine.name) + exists, err = images.Exists(bt.conn, alpine.name) Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) }) It("Load|Import Image", func() { // load an image - _, err := images.Remove(connText, alpine.name, nil) + _, err := images.Remove(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) - exists, err := images.Exists(connText, alpine.name) + exists, err := images.Exists(bt.conn, alpine.name) Expect(err).To(BeNil()) Expect(exists).To(BeFalse()) f, err := os.Open(filepath.Join(ImageCacheDir, alpine.tarballName)) defer f.Close() Expect(err).To(BeNil()) - names, err := images.Load(connText, f, nil) + names, err := images.Load(bt.conn, f, nil) Expect(err).To(BeNil()) Expect(names).To(Equal(alpine.name)) - exists, err = images.Exists(connText, alpine.name) + exists, err = images.Exists(bt.conn, alpine.name) Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) // load with a repo name f, err = os.Open(filepath.Join(ImageCacheDir, alpine.tarballName)) Expect(err).To(BeNil()) - _, err = images.Remove(connText, alpine.name, nil) + _, err = images.Remove(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) - exists, err = images.Exists(connText, alpine.name) + exists, err = images.Exists(bt.conn, alpine.name) Expect(err).To(BeNil()) Expect(exists).To(BeFalse()) newName := "quay.io/newname:fizzle" - names, err = images.Load(connText, f, &newName) + names, err = images.Load(bt.conn, f, &newName) Expect(err).To(BeNil()) Expect(names).To(Equal(alpine.name)) - exists, err = images.Exists(connText, newName) + exists, err = images.Exists(bt.conn, newName) Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) // load with a bad repo name should trigger a 500 f, err = os.Open(filepath.Join(ImageCacheDir, alpine.tarballName)) Expect(err).To(BeNil()) - _, err = images.Remove(connText, alpine.name, nil) + _, err = images.Remove(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) - exists, err = images.Exists(connText, alpine.name) + exists, err = images.Exists(bt.conn, alpine.name) Expect(err).To(BeNil()) Expect(exists).To(BeFalse()) badName := "quay.io/newName:fizzle" - _, err = images.Load(connText, f, &badName) + _, err = images.Load(bt.conn, f, &badName) Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) @@ -262,7 +261,7 @@ var _ = Describe("Podman images", func() { w, err := os.Create(filepath.Join(bt.tempDirPath, alpine.tarballName)) defer w.Close() Expect(err).To(BeNil()) - err = images.Export(connText, alpine.name, w, nil, nil) + err = images.Export(bt.conn, alpine.name, w, nil, nil) Expect(err).To(BeNil()) _, err = os.Stat(exportPath) Expect(err).To(BeNil()) @@ -272,9 +271,9 @@ var _ = Describe("Podman images", func() { It("Import Image", func() { // load an image - _, err = images.Remove(connText, alpine.name, nil) + _, err = images.Remove(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) - exists, err := images.Exists(connText, alpine.name) + exists, err := images.Exists(bt.conn, alpine.name) Expect(err).To(BeNil()) Expect(exists).To(BeFalse()) f, err := os.Open(filepath.Join(ImageCacheDir, alpine.tarballName)) @@ -282,27 +281,27 @@ var _ = Describe("Podman images", func() { Expect(err).To(BeNil()) changes := []string{"CMD /bin/foobar"} testMessage := "test_import" - _, err = images.Import(connText, changes, &testMessage, &alpine.name, nil, f) + _, err = images.Import(bt.conn, changes, &testMessage, &alpine.name, nil, f) Expect(err).To(BeNil()) - exists, err = images.Exists(connText, alpine.name) + exists, err = images.Exists(bt.conn, alpine.name) Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) - data, err := images.GetImage(connText, alpine.name, nil) + data, err := images.GetImage(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) Expect(data.Comment).To(Equal(testMessage)) }) It("History Image", func() { // a bogus name should return a 404 - _, err := images.History(connText, "foobar") + _, err := images.History(bt.conn, "foobar") Expect(err).To(Not(BeNil())) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) var foundID bool - data, err := images.GetImage(connText, alpine.name, nil) + data, err := images.GetImage(bt.conn, alpine.name, nil) Expect(err).To(BeNil()) - history, err := images.History(connText, alpine.name) + history, err := images.History(bt.conn, alpine.name) Expect(err).To(BeNil()) for _, i := range history { if i.ID == data.ID { @@ -314,7 +313,7 @@ var _ = Describe("Podman images", func() { }) It("Search for an image", func() { - imgs, err := images.Search(connText, "alpine", nil, nil) + imgs, err := images.Search(bt.conn, "alpine", nil, nil) Expect(err).To(BeNil()) Expect(len(imgs)).To(BeNumerically(">", 1)) var foundAlpine bool @@ -328,21 +327,21 @@ var _ = Describe("Podman images", func() { // Search for alpine with a limit of 10 ten := 10 - imgs, err = images.Search(connText, "docker.io/alpine", &ten, nil) + imgs, err = images.Search(bt.conn, "docker.io/alpine", &ten, nil) Expect(err).To(BeNil()) Expect(len(imgs)).To(BeNumerically("<=", 10)) // Search for alpine with stars greater than 100 filters := make(map[string][]string) filters["stars"] = []string{"100"} - imgs, err = images.Search(connText, "docker.io/alpine", nil, filters) + imgs, err = images.Search(bt.conn, "docker.io/alpine", nil, filters) Expect(err).To(BeNil()) for _, i := range imgs { Expect(i.Stars).To(BeNumerically(">=", 100)) } // Search with a fqdn - imgs, err = images.Search(connText, "quay.io/libpod/alpine_nginx", nil, nil) + imgs, err = images.Search(bt.conn, "quay.io/libpod/alpine_nginx", nil, nil) Expect(len(imgs)).To(BeNumerically(">=", 1)) }) diff --git a/pkg/bindings/test/pods_test.go b/pkg/bindings/test/pods_test.go index afffee4e6..7e29265b7 100644 --- a/pkg/bindings/test/pods_test.go +++ b/pkg/bindings/test/pods_test.go @@ -1,7 +1,6 @@ package test_bindings import ( - "context" "net/http" "time" @@ -17,7 +16,6 @@ var _ = Describe("Podman pods", func() { var ( bt *bindingTest s *gexec.Session - connText context.Context newpod string err error trueFlag bool = true @@ -30,7 +28,7 @@ var _ = Describe("Podman pods", func() { bt.Podcreate(&newpod) s = bt.startAPIService() time.Sleep(1 * time.Second) - connText, err = bindings.NewConnection(context.Background(), bt.sock) + err := bt.NewConnection() Expect(err).To(BeNil()) }) @@ -41,13 +39,13 @@ var _ = Describe("Podman pods", func() { It("inspect pod", func() { //Inspect an invalid pod name - _, err := pods.Inspect(connText, "dummyname") + _, err := pods.Inspect(bt.conn, "dummyname") Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) //Inspect an valid pod name - response, err := pods.Inspect(connText, newpod) + response, err := pods.Inspect(bt.conn, newpod) Expect(err).To(BeNil()) Expect(response.Config.Name).To(Equal(newpod)) }) @@ -55,12 +53,13 @@ var _ = Describe("Podman pods", func() { // Test validates the list all api returns It("list pod", func() { //List all the pods in the current instance - podSummary, err := pods.List(connText, nil) + podSummary, err := pods.List(bt.conn, nil) Expect(err).To(BeNil()) Expect(len(podSummary)).To(Equal(1)) // Adding an alpine container to the existing pod - bt.RunTopContainer(nil, &trueFlag, &newpod) - podSummary, err = pods.List(connText, nil) + _, err = bt.RunTopContainer(nil, &trueFlag, &newpod) + Expect(err).To(BeNil()) + podSummary, err = pods.List(bt.conn, nil) // Verify no errors. Expect(err).To(BeNil()) // Verify number of containers in the pod. @@ -69,7 +68,7 @@ var _ = Describe("Podman pods", func() { // Add multiple pods and verify them by name and size. var newpod2 string = "newpod2" bt.Podcreate(&newpod2) - podSummary, err = pods.List(connText, nil) + podSummary, err = pods.List(bt.conn, nil) Expect(len(podSummary)).To(Equal(2)) var names []string for _, i := range podSummary { @@ -83,19 +82,19 @@ var _ = Describe("Podman pods", func() { // Validate list pod with filters //filters := make(map[string][]string) //filters["name"] = []string{newpod} - //filteredPods, err := pods.List(connText, filters) + //filteredPods, err := pods.List(bt.conn, filters) //Expect(err).To(BeNil()) //Expect(len(filteredPods)).To(BeNumerically("==", 1)) }) // The test validates if the exists responds It("exists pod", func() { - response, err := pods.Exists(connText, "dummyName") + response, err := pods.Exists(bt.conn, "dummyName") Expect(err).To(BeNil()) Expect(response).To(BeFalse()) // Should exit with no error and response should be true - response, err = pods.Exists(connText, "newpod") + response, err = pods.Exists(bt.conn, "newpod") Expect(err).To(BeNil()) Expect(response).To(BeTrue()) }) @@ -103,23 +102,24 @@ var _ = Describe("Podman pods", func() { // This test validates if All running containers within // each specified pod are paused and unpaused It("pause upause pod", func() { + // TODO fix this + Skip("Pod behavior is jacked right now.") // Pause invalid container - err := pods.Pause(connText, "dummyName") + err := pods.Pause(bt.conn, "dummyName") Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) // Adding an alpine container to the existing pod - bt.RunTopContainer(nil, &trueFlag, &newpod) - response, err := pods.Inspect(connText, newpod) + _, err = bt.RunTopContainer(nil, &trueFlag, &newpod) Expect(err).To(BeNil()) // Binding needs to be modified to inspect the pod state. - // Since we dont have a pod state we inspect the states of the containers within the pod. + // Since we don't have a pod state we inspect the states of the containers within the pod. // Pause a valid container - err = pods.Pause(connText, newpod) + err = pods.Pause(bt.conn, newpod) Expect(err).To(BeNil()) - response, err = pods.Inspect(connText, newpod) + response, err := pods.Inspect(bt.conn, newpod) Expect(response.State.Status).To(Equal(define.PodStatePaused)) for _, i := range response.Containers { Expect(define.StringToContainerStatus(i.State)). @@ -127,9 +127,9 @@ var _ = Describe("Podman pods", func() { } // Unpause a valid container - err = pods.Unpause(connText, newpod) + err = pods.Unpause(bt.conn, newpod) Expect(err).To(BeNil()) - response, err = pods.Inspect(connText, newpod) + response, err = pods.Inspect(bt.conn, newpod) Expect(response.State.Status).To(Equal(define.PodStateRunning)) for _, i := range response.Containers { Expect(define.StringToContainerStatus(i.State)). @@ -139,28 +139,28 @@ var _ = Describe("Podman pods", func() { It("start stop restart pod", func() { // Start an invalid pod - err = pods.Start(connText, "dummyName") + err = pods.Start(bt.conn, "dummyName") Expect(err).ToNot(BeNil()) code, _ := bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) // Stop an invalid pod - err = pods.Stop(connText, "dummyName", nil) + err = pods.Stop(bt.conn, "dummyName", nil) Expect(err).ToNot(BeNil()) code, _ = bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) // Restart an invalid pod - err = pods.Restart(connText, "dummyName") + err = pods.Restart(bt.conn, "dummyName") Expect(err).ToNot(BeNil()) code, _ = bindings.CheckResponseCode(err) Expect(code).To(BeNumerically("==", http.StatusNotFound)) // Start a valid pod and inspect status of each container - err = pods.Start(connText, newpod) + err = pods.Start(bt.conn, newpod) Expect(err).To(BeNil()) - response, err := pods.Inspect(connText, newpod) + response, err := pods.Inspect(bt.conn, newpod) Expect(response.State.Status).To(Equal(define.PodStateRunning)) for _, i := range response.Containers { Expect(define.StringToContainerStatus(i.State)). @@ -168,13 +168,13 @@ var _ = Describe("Podman pods", func() { } // Start an already running pod - err = pods.Start(connText, newpod) + err = pods.Start(bt.conn, newpod) Expect(err).To(BeNil()) // Stop the running pods - err = pods.Stop(connText, newpod, nil) + err = pods.Stop(bt.conn, newpod, nil) Expect(err).To(BeNil()) - response, _ = pods.Inspect(connText, newpod) + response, _ = pods.Inspect(bt.conn, newpod) Expect(response.State.Status).To(Equal(define.PodStateExited)) for _, i := range response.Containers { Expect(define.StringToContainerStatus(i.State)). @@ -182,12 +182,12 @@ var _ = Describe("Podman pods", func() { } // Stop an already stopped pod - err = pods.Stop(connText, newpod, nil) + err = pods.Stop(bt.conn, newpod, nil) Expect(err).To(BeNil()) - err = pods.Restart(connText, newpod) + err = pods.Restart(bt.conn, newpod) Expect(err).To(BeNil()) - response, _ = pods.Inspect(connText, newpod) + response, _ = pods.Inspect(bt.conn, newpod) Expect(response.State.Status).To(Equal(define.PodStateRunning)) for _, i := range response.Containers { Expect(define.StringToContainerStatus(i.State)). @@ -195,58 +195,58 @@ var _ = Describe("Podman pods", func() { } }) - // Test to validate all the pods in the stopped/exited state are pruned sucessfully. + // Test to validate all the pods in the stopped/exited state are pruned successfully. It("prune pod", func() { // Add a new pod var newpod2 string = "newpod2" bt.Podcreate(&newpod2) // No pods pruned since no pod in exited state - err = pods.Prune(connText) + err = pods.Prune(bt.conn) Expect(err).To(BeNil()) - podSummary, err := pods.List(connText, nil) + podSummary, err := pods.List(bt.conn, nil) Expect(err).To(BeNil()) Expect(len(podSummary)).To(Equal(2)) // Prune only one pod which is in exited state. // Start then stop a pod. // pod moves to exited state one pod should be pruned now. - err = pods.Start(connText, newpod) + err = pods.Start(bt.conn, newpod) Expect(err).To(BeNil()) - err = pods.Stop(connText, newpod, nil) + err = pods.Stop(bt.conn, newpod, nil) Expect(err).To(BeNil()) - response, err := pods.Inspect(connText, newpod) + response, err := pods.Inspect(bt.conn, newpod) Expect(response.State.Status).To(Equal(define.PodStateExited)) - err = pods.Prune(connText) + err = pods.Prune(bt.conn) Expect(err).To(BeNil()) - podSummary, err = pods.List(connText, nil) + podSummary, err = pods.List(bt.conn, nil) Expect(err).To(BeNil()) Expect(len(podSummary)).To(Equal(1)) // Test prune all pods in exited state. bt.Podcreate(&newpod) - err = pods.Start(connText, newpod) + err = pods.Start(bt.conn, newpod) Expect(err).To(BeNil()) - err = pods.Start(connText, newpod2) + err = pods.Start(bt.conn, newpod2) Expect(err).To(BeNil()) - err = pods.Stop(connText, newpod, nil) + err = pods.Stop(bt.conn, newpod, nil) Expect(err).To(BeNil()) - response, err = pods.Inspect(connText, newpod) + response, err = pods.Inspect(bt.conn, newpod) Expect(response.State.Status).To(Equal(define.PodStateExited)) for _, i := range response.Containers { Expect(define.StringToContainerStatus(i.State)). To(Equal(define.ContainerStateStopped)) } - err = pods.Stop(connText, newpod2, nil) + err = pods.Stop(bt.conn, newpod2, nil) Expect(err).To(BeNil()) - response, err = pods.Inspect(connText, newpod2) + response, err = pods.Inspect(bt.conn, newpod2) Expect(response.State.Status).To(Equal(define.PodStateExited)) for _, i := range response.Containers { Expect(define.StringToContainerStatus(i.State)). To(Equal(define.ContainerStateStopped)) } - err = pods.Prune(connText) + err = pods.Prune(bt.conn) Expect(err).To(BeNil()) - podSummary, err = pods.List(connText, nil) + podSummary, err = pods.List(bt.conn, nil) Expect(err).To(BeNil()) Expect(len(podSummary)).To(Equal(0)) }) diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go index 6c5b7978c..d51905f4b 100644 --- a/pkg/cgroups/cgroups.go +++ b/pkg/cgroups/cgroups.go @@ -11,8 +11,8 @@ import ( "strings" "github.com/containers/libpod/pkg/rootless" - systemdDbus "github.com/coreos/go-systemd/dbus" - "github.com/godbus/dbus" + systemdDbus "github.com/coreos/go-systemd/v22/dbus" + "github.com/godbus/dbus/v5" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" diff --git a/pkg/cgroups/systemd.go b/pkg/cgroups/systemd.go index b8e6db156..9bbdca415 100644 --- a/pkg/cgroups/systemd.go +++ b/pkg/cgroups/systemd.go @@ -5,8 +5,8 @@ import ( "path/filepath" "strings" - systemdDbus "github.com/coreos/go-systemd/dbus" - "github.com/godbus/dbus" + systemdDbus "github.com/coreos/go-systemd/v22/dbus" + "github.com/godbus/dbus/v5" ) func systemdCreate(path string, c *systemdDbus.Conn) error { diff --git a/pkg/hooks/exec/exec.go b/pkg/hooks/exec/exec.go index 4038e3d94..77b350573 100644 --- a/pkg/hooks/exec/exec.go +++ b/pkg/hooks/exec/exec.go @@ -5,13 +5,13 @@ import ( "bytes" "context" "fmt" - "github.com/sirupsen/logrus" "io" osexec "os/exec" "time" rspec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) // DefaultPostKillTimeout is the recommended default post-kill timeout. diff --git a/pkg/lookup/lookup.go b/pkg/lookup/lookup.go index a249dd753..dff25f74f 100644 --- a/pkg/lookup/lookup.go +++ b/pkg/lookup/lookup.go @@ -4,7 +4,7 @@ import ( "os" "strconv" - "github.com/cyphar/filepath-securejoin" + securejoin "github.com/cyphar/filepath-securejoin" "github.com/opencontainers/runc/libcontainer/user" "github.com/sirupsen/logrus" ) diff --git a/pkg/resolvconf/resolvconf.go b/pkg/resolvconf/resolvconf.go index e85bcb377..20618e2dc 100644 --- a/pkg/resolvconf/resolvconf.go +++ b/pkg/resolvconf/resolvconf.go @@ -10,7 +10,7 @@ import ( "sync" "github.com/containers/libpod/pkg/resolvconf/dns" - "github.com/docker/docker/pkg/ioutils" + "github.com/containers/storage/pkg/ioutils" "github.com/sirupsen/logrus" ) diff --git a/pkg/spec/security.go b/pkg/spec/security.go index ca025eb3e..0f8d36f00 100644 --- a/pkg/spec/security.go +++ b/pkg/spec/security.go @@ -128,10 +128,10 @@ func (c *SecurityConfig) ConfigureGenerator(g *generate.Generator, user *UserCon privCapRequired := []string{} if !c.Privileged && len(c.CapRequired) > 0 { - // Pass CapRequired in CapAdd field to normalize capabilties names + // Pass CapRequired in CapAdd field to normalize capabilities names capRequired, err := capabilities.MergeCapabilities(nil, c.CapRequired, nil) if err != nil { - logrus.Errorf("capabilties requested by user or image are not valid: %q", strings.Join(c.CapRequired, ",")) + logrus.Errorf("capabilities requested by user or image are not valid: %q", strings.Join(c.CapRequired, ",")) } else { // Verify all capRequiered are in the defaultCapList for _, cap := range capRequired { @@ -143,7 +143,7 @@ func (c *SecurityConfig) ConfigureGenerator(g *generate.Generator, user *UserCon if len(privCapRequired) == 0 { defaultCaplist = capRequired } else { - logrus.Errorf("capabilties requested by user or image are not allowed by default: %q", strings.Join(privCapRequired, ",")) + logrus.Errorf("capabilities requested by user or image are not allowed by default: %q", strings.Join(privCapRequired, ",")) } } configSpec.Process.Capabilities.Bounding = defaultCaplist diff --git a/pkg/specgen/create.go b/pkg/specgen/create.go index 34f9ffac2..99a99083b 100644 --- a/pkg/specgen/create.go +++ b/pkg/specgen/create.go @@ -2,17 +2,17 @@ package specgen import ( "context" + "os" + "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/config" "github.com/containers/libpod/libpod/define" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "os" ) // MakeContainer creates a container based on the SpecGenerator func (s *SpecGenerator) MakeContainer(rt *libpod.Runtime) (*libpod.Container, error) { - var pod *libpod.Pod if err := s.validate(rt); err != nil { return nil, errors.Wrap(err, "invalid config provided") } @@ -21,7 +21,7 @@ func (s *SpecGenerator) MakeContainer(rt *libpod.Runtime) (*libpod.Container, er return nil, err } - options, err := s.createContainerOptions(rt, pod) + options, err := s.createContainerOptions(rt) if err != nil { return nil, err } @@ -45,7 +45,7 @@ func (s *SpecGenerator) MakeContainer(rt *libpod.Runtime) (*libpod.Container, er return rt.NewContainer(context.Background(), runtimeSpec, options...) } -func (s *SpecGenerator) createContainerOptions(rt *libpod.Runtime, pod *libpod.Pod) ([]libpod.CtrCreateOption, error) { +func (s *SpecGenerator) createContainerOptions(rt *libpod.Runtime) ([]libpod.CtrCreateOption, error) { var options []libpod.CtrCreateOption var err error @@ -60,6 +60,10 @@ func (s *SpecGenerator) createContainerOptions(rt *libpod.Runtime, pod *libpod.P options = append(options, libpod.WithName(s.Name)) } if s.Pod != "" { + pod, err := rt.LookupPod(s.Pod) + if err != nil { + return nil, err + } logrus.Debugf("adding container to pod %s", s.Pod) options = append(options, rt.WithPod(pod)) } @@ -115,7 +119,6 @@ func (s *SpecGenerator) createContainerOptions(rt *libpod.Runtime, pod *libpod.P } options = append(options, namespaceOptions...) - // TODO NetworkNS still needs to be done! if len(s.ConmonPidFile) > 0 { options = append(options, libpod.WithConmonPidFile(s.ConmonPidFile)) } diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go index 79a83819a..fa2dee77d 100644 --- a/pkg/specgen/namespaces.go +++ b/pkg/specgen/namespaces.go @@ -70,9 +70,7 @@ func (n *Namespace) IsPrivate() bool { return n.NSMode == Private } -// validate perform simple validation on the namespace to make sure it is not -// invalid from the get-go -func (n *Namespace) validate() error { +func validateNetNS(n *Namespace) error { if n == nil { return nil } @@ -82,6 +80,15 @@ func (n *Namespace) validate() error { default: return errors.Errorf("invalid network %q", n.NSMode) } + return nil +} + +// validate perform simple validation on the namespace to make sure it is not +// invalid from the get-go +func (n *Namespace) validate() error { + if n == nil { + return nil + } // Path and From Container MUST have a string value set if n.NSMode == Path || n.NSMode == FromContainer { if len(n.Value) < 1 { diff --git a/pkg/specgen/validate.go b/pkg/specgen/validate.go index 78e4d8ad5..dd5ca3a55 100644 --- a/pkg/specgen/validate.go +++ b/pkg/specgen/validate.go @@ -138,7 +138,7 @@ func (s *SpecGenerator) validate(rt *libpod.Runtime) error { if err := s.IpcNS.validate(); err != nil { return err } - if err := s.NetNS.validate(); err != nil { + if err := validateNetNS(&s.NetNS); err != nil { return err } if err := s.PidNS.validate(); err != nil { diff --git a/pkg/systemd/generate/systemdgen.go b/pkg/systemd/generate/systemdgen.go index 00ddc63f3..4410e1395 100644 --- a/pkg/systemd/generate/systemdgen.go +++ b/pkg/systemd/generate/systemdgen.go @@ -110,7 +110,7 @@ KillMode=none Type=forking [Install] -WantedBy=multi-user.target` +WantedBy=multi-user.target default.target` // Options include different options to control the unit file generation. type Options struct { diff --git a/pkg/systemd/generate/systemdgen_test.go b/pkg/systemd/generate/systemdgen_test.go index 145296ea9..3749d89ce 100644 --- a/pkg/systemd/generate/systemdgen_test.go +++ b/pkg/systemd/generate/systemdgen_test.go @@ -52,7 +52,7 @@ KillMode=none Type=forking [Install] -WantedBy=multi-user.target` +WantedBy=multi-user.target default.target` goodName := `# container-foobar.service # autogenerated by Podman CI @@ -72,7 +72,7 @@ KillMode=none Type=forking [Install] -WantedBy=multi-user.target` +WantedBy=multi-user.target default.target` goodNameBoundTo := `# container-foobar.service # autogenerated by Podman CI @@ -96,7 +96,7 @@ KillMode=none Type=forking [Install] -WantedBy=multi-user.target` +WantedBy=multi-user.target default.target` podGoodName := `# pod-123abc.service # autogenerated by Podman CI @@ -118,7 +118,7 @@ KillMode=none Type=forking [Install] -WantedBy=multi-user.target` +WantedBy=multi-user.target default.target` goodNameNew := `# jadda-jadda.service # autogenerated by Podman CI @@ -140,7 +140,7 @@ KillMode=none Type=forking [Install] -WantedBy=multi-user.target` +WantedBy=multi-user.target default.target` tests := []struct { name string diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 4a52ea68d..a4df48c88 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -600,3 +600,12 @@ func HomeDir() (string, error) { } return home, nil } + +func Tmpdir() string { + tmpdir := os.Getenv("TMPDIR") + if tmpdir == "" { + tmpdir = "/var/tmp" + } + + return tmpdir +} diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go index 603edbe6b..389f2c822 100644 --- a/test/e2e/generate_kube_test.go +++ b/test/e2e/generate_kube_test.go @@ -10,7 +10,7 @@ import ( "github.com/ghodss/yaml" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" ) var _ = Describe("Podman generate kube", func() { @@ -69,6 +69,51 @@ var _ = Describe("Podman generate kube", func() { Expect(numContainers).To(Equal(1)) }) + It("podman generate service kube on container with --security-opt level", func() { + session := podmanTest.Podman([]string{"create", "--name", "test", "--security-opt", "label=level:s0:c100,c200", "alpine"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + kube := podmanTest.Podman([]string{"generate", "kube", "test"}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Equal(0)) + + pod := new(v1.Pod) + err := yaml.Unmarshal(kube.Out.Contents(), pod) + Expect(err).To(BeNil()) + Expect(kube.OutputToString()).To(ContainSubstring("level: s0:c100,c200")) + }) + + It("podman generate service kube on container with --security-opt disable", func() { + session := podmanTest.Podman([]string{"create", "--name", "test-disable", "--security-opt", "label=disable", "alpine"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + kube := podmanTest.Podman([]string{"generate", "kube", "test-disable"}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Equal(0)) + + pod := new(v1.Pod) + err = yaml.Unmarshal(kube.Out.Contents(), pod) + Expect(err).To(BeNil()) + Expect(kube.OutputToString()).To(ContainSubstring("type: spc_t")) + }) + + It("podman generate service kube on container with --security-opt type", func() { + session := podmanTest.Podman([]string{"create", "--name", "test", "--security-opt", "label=type:foo_bar_t", "alpine"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + kube := podmanTest.Podman([]string{"generate", "kube", "test"}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Equal(0)) + + pod := new(v1.Pod) + err = yaml.Unmarshal(kube.Out.Contents(), pod) + Expect(err).To(BeNil()) + Expect(kube.OutputToString()).To(ContainSubstring("type: foo_bar_t")) + }) + It("podman generate service kube on container", func() { session := podmanTest.RunTopContainer("top") session.WaitWithDefaultTimeout() diff --git a/utils/utils_supported.go b/utils/utils_supported.go index 8bc232179..ce9fd5604 100644 --- a/utils/utils_supported.go +++ b/utils/utils_supported.go @@ -5,8 +5,8 @@ package utils import ( "github.com/containers/libpod/pkg/cgroups" "github.com/containers/libpod/pkg/rootless" - systemdDbus "github.com/coreos/go-systemd/dbus" - "github.com/godbus/dbus" + systemdDbus "github.com/coreos/go-systemd/v22/dbus" + "github.com/godbus/dbus/v5" ) // RunUnderSystemdScope adds the specified pid to a systemd scope diff --git a/vendor/github.com/containernetworking/cni/libcni/api.go b/vendor/github.com/containernetworking/cni/libcni/api.go index 22b111742..7e52bd838 100644 --- a/vendor/github.com/containernetworking/cni/libcni/api.go +++ b/vendor/github.com/containernetworking/cni/libcni/api.go @@ -409,6 +409,9 @@ func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net if err := utils.ValidateNetworkName(name); err != nil { return nil, err } + if err := utils.ValidateInterfaceName(rt.IfName); err != nil { + return nil, err + } newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt) if err != nil { @@ -629,6 +632,9 @@ func (c *CNIConfig) validatePlugin(ctx context.Context, pluginName, expectedVers if err != nil { return err } + if expectedVersion == "" { + expectedVersion = "0.1.0" + } vi, err := invoke.GetVersionInfo(ctx, pluginPath, c.exec) if err != nil { diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/args.go b/vendor/github.com/containernetworking/cni/pkg/invoke/args.go index d31a44e87..3cdb4bc8d 100644 --- a/vendor/github.com/containernetworking/cni/pkg/invoke/args.go +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/args.go @@ -60,8 +60,8 @@ func (args *Args) AsEnv() []string { pluginArgsStr = stringify(args.PluginArgs) } - // Duplicated values which come first will be overrided, so we must put the - // custom values in the end to avoid being overrided by the process environments. + // Duplicated values which come first will be overridden, so we must put the + // custom values in the end to avoid being overridden by the process environments. env = append(env, "CNI_COMMAND="+args.Command, "CNI_CONTAINERID="+args.ContainerID, diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go b/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go index ad8498ba2..4f89a5dda 100644 --- a/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go @@ -44,10 +44,14 @@ func (e *RawExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData [ } func pluginErr(err error, output []byte) error { - if _, ok := err.(*exec.ExitError); ok { + if exitError, ok := err.(*exec.ExitError); ok { emsg := types.Error{} if len(output) == 0 { - emsg.Msg = "netplugin failed with no error message" + if len(exitError.Stderr) == 0 { + emsg.Msg = "netplugin failed with no error message" + } else { + emsg.Msg = fmt.Sprintf("netplugin failed: %q", string(exitError.Stderr)) + } } else if perr := json.Unmarshal(output, &emsg); perr != nil { emsg.Msg = fmt.Sprintf("netplugin failed but error parsing its diagnostic message %q: %v", string(output), perr) } diff --git a/vendor/github.com/containernetworking/cni/pkg/types/020/types.go b/vendor/github.com/containernetworking/cni/pkg/types/020/types.go index 53256167f..36f31678a 100644 --- a/vendor/github.com/containernetworking/cni/pkg/types/020/types.go +++ b/vendor/github.com/containernetworking/cni/pkg/types/020/types.go @@ -86,20 +86,6 @@ func (r *Result) PrintTo(writer io.Writer) error { return err } -// String returns a formatted string in the form of "[IP4: $1,][ IP6: $2,] DNS: $3" where -// $1 represents the receiver's IPv4, $2 represents the receiver's IPv6 and $3 the -// receiver's DNS. If $1 or $2 are nil, they won't be present in the returned string. -func (r *Result) String() string { - var str string - if r.IP4 != nil { - str = fmt.Sprintf("IP4:%+v, ", *r.IP4) - } - if r.IP6 != nil { - str += fmt.Sprintf("IP6:%+v, ", *r.IP6) - } - return fmt.Sprintf("%sDNS:%+v", str, r.DNS) -} - // IPConfig contains values necessary to configure an interface type IPConfig struct { IP net.IPNet diff --git a/vendor/github.com/containernetworking/cni/pkg/types/current/types.go b/vendor/github.com/containernetworking/cni/pkg/types/current/types.go index 7267a2e6d..754cc6e72 100644 --- a/vendor/github.com/containernetworking/cni/pkg/types/current/types.go +++ b/vendor/github.com/containernetworking/cni/pkg/types/current/types.go @@ -207,23 +207,6 @@ func (r *Result) PrintTo(writer io.Writer) error { return err } -// String returns a formatted string in the form of "[Interfaces: $1,][ IP: $2,] DNS: $3" where -// $1 represents the receiver's Interfaces, $2 represents the receiver's IP addresses and $3 the -// receiver's DNS. If $1 or $2 are nil, they won't be present in the returned string. -func (r *Result) String() string { - var str string - if len(r.Interfaces) > 0 { - str += fmt.Sprintf("Interfaces:%+v, ", r.Interfaces) - } - if len(r.IPs) > 0 { - str += fmt.Sprintf("IP:%+v, ", r.IPs) - } - if len(r.Routes) > 0 { - str += fmt.Sprintf("Routes:%+v, ", r.Routes) - } - return fmt.Sprintf("%sDNS:%+v", str, r.DNS) -} - // Convert this old version result to the current CNI version result func (r *Result) Convert() (*Result, error) { return r, nil diff --git a/vendor/github.com/containernetworking/cni/pkg/types/types.go b/vendor/github.com/containernetworking/cni/pkg/types/types.go index 3e185c1ce..3fa757a5d 100644 --- a/vendor/github.com/containernetworking/cni/pkg/types/types.go +++ b/vendor/github.com/containernetworking/cni/pkg/types/types.go @@ -100,9 +100,6 @@ type Result interface { // Prints the result in JSON format to provided writer PrintTo(writer io.Writer) error - - // Returns a JSON string representation of the result - String() string } func PrintResult(result Result, version string) error { diff --git a/vendor/github.com/containernetworking/cni/pkg/utils/utils.go b/vendor/github.com/containernetworking/cni/pkg/utils/utils.go index 324c40dea..b8ec38874 100644 --- a/vendor/github.com/containernetworking/cni/pkg/utils/utils.go +++ b/vendor/github.com/containernetworking/cni/pkg/utils/utils.go @@ -15,14 +15,22 @@ package utils import ( + "bytes" + "fmt" "regexp" + "unicode" "github.com/containernetworking/cni/pkg/types" ) -// cniValidNameChars is the regexp used to validate valid characters in -// containerID and networkName -const cniValidNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.\-]` +const ( + // cniValidNameChars is the regexp used to validate valid characters in + // containerID and networkName + cniValidNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.\-]` + + // maxInterfaceNameLength is the length max of a valid interface name + maxInterfaceNameLength = 15 +) var cniReg = regexp.MustCompile(`^` + cniValidNameChars + `*$`) @@ -49,3 +57,28 @@ func ValidateNetworkName(networkName string) *types.Error { } return nil } + +// ValidateInterfaceName will validate the interface name based on the three rules below +// 1. The name must not be empty +// 2. The name must be less than 16 characters +// 3. The name must not be "." or ".." +// 3. The name must not contain / or : or any whitespace characters +// ref to https://github.com/torvalds/linux/blob/master/net/core/dev.c#L1024 +func ValidateInterfaceName(ifName string) *types.Error { + if len(ifName) == 0 { + return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is empty", "") + } + if len(ifName) > maxInterfaceNameLength { + return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is too long", fmt.Sprintf("interface name should be less than %d characters", maxInterfaceNameLength+1)) + } + if ifName == "." || ifName == ".." { + return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is . or ..", "") + } + for _, r := range bytes.Runes([]byte(ifName)) { + if r == '/' || r == ':' || unicode.IsSpace(r) { + return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name contains / or : or whitespace characters", "") + } + } + + return nil +} diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION index 41c11ffb7..4a02d2c31 100644 --- a/vendor/github.com/containers/storage/VERSION +++ b/vendor/github.com/containers/storage/VERSION @@ -1 +1 @@ -1.16.1 +1.16.2 diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod index 073bb7d2b..8a3b7bb60 100644 --- a/vendor/github.com/containers/storage/go.mod +++ b/vendor/github.com/containers/storage/go.mod @@ -2,13 +2,10 @@ module github.com/containers/storage require ( github.com/BurntSushi/toml v0.3.1 - github.com/DataDog/zstd v1.4.0 // indirect github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 github.com/Microsoft/hcsshim v0.8.7 - github.com/docker/docker v0.0.0-20171019062838-86f080cff091 // indirect github.com/docker/go-units v0.4.0 github.com/klauspost/compress v1.10.2 - github.com/klauspost/cpuid v1.2.1 // indirect github.com/klauspost/pgzip v1.2.1 github.com/mattn/go-shellwords v1.0.10 github.com/mistifyio/go-zfs v2.1.1+incompatible @@ -18,7 +15,6 @@ require ( github.com/pkg/errors v0.9.1 github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7 github.com/sirupsen/logrus v1.4.2 - github.com/spf13/pflag v1.0.3 // indirect github.com/stretchr/testify v1.5.1 github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 github.com/tchap/go-patricia v2.3.0+incompatible diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum index 7fd19b00b..6674a08f5 100644 --- a/vendor/github.com/containers/storage/go.sum +++ b/vendor/github.com/containers/storage/go.sum @@ -1,27 +1,15 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/DataDog/zstd v1.4.0 h1:vhoV+DUHnRZdKW1i5UMjAk2G4JY8wN4ayRfYDNdEhwo= -github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc= -github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA= -github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg= github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b h1:T4nWG1TXIxeor8mAu5bFguPJgSIGhZqv/f0z55KCrJM= -github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b/go.mod h1:TrMrLQfeENAPYPRsJuq3jsqdlRh3lvi6trTZJG8+tho= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50 h1:WMpHmC6AxwWb9hMqhudkqG7A/p14KiMnl6d3r1iUMjU= -github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= @@ -29,32 +17,18 @@ github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/docker v0.0.0-20171019062838-86f080cff091 h1:QpxpTw4MJeOzbC7X00IFxnZhZx8oDOqXMrMAHiwNn54= -github.com/docker/docker v0.0.0-20171019062838-86f080cff091/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= -github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4= -github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -63,77 +37,28 @@ 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.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.7.2 h1:liMOoeIvFpr9kEvalrZ7VVBA4wGf7zfOgwBjzz/5g2Y= -github.com/klauspost/compress v1.7.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.1 h1:TWy0o9J9c6LK9C8t7Msh6IAJNXbsU/nvKLTQUU5HdaY= -github.com/klauspost/compress v1.9.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.2 h1:LfVyl+ZlLlLDeQ/d2AqfGIIH4qEDu0Ed2S5GyhCWIWY= -github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.3 h1:hkFELABwacUEgBfiguNeQydKv3M9pawBq8o24Ypw9+M= -github.com/klauspost/compress v1.9.3/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.4 h1:xhvAeUPQ2drNUhKtrGdTGNvV9nNafHMUkRyLkzxJoB4= -github.com/klauspost/compress v1.9.4/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M= -github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7 h1:hYW1gP94JUmAhBtJ+LNz5My+gBobDxPR1iVuKug26aA= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.8 h1:VMAMUUOh+gaxKTMk+zqbjsSjsIcUcL/LF4o63i82QyA= -github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.10.0 h1:92XGj1AcYzA6UrVdd4qIIBrT8OroryvRvdmg/IfmC7Y= -github.com/klauspost/compress v1.10.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.10.1 h1:a/QY0o9S6wCi0XhxaMX/QmusicNUqCqFugR6WKPOSoQ= -github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.2 h1:Znfn6hXZAHaLPNnlqUYRrBSReFHYybslgv4PTiyz6P0= github.com/klauspost/compress v1.10.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM= github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/mattn/go-shellwords v1.0.5 h1:JhhFTIOslh5ZsPrpa3Wdg8bF0WI3b44EMblmU9wIsXc= -github.com/mattn/go-shellwords v1.0.5/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.6 h1:9Jok5pILi5S1MnDirGVTufYGtksUs/V2BWUP3ZkeUUI= -github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.7 h1:KqhVjVZomx2puPACkj9vrGFqnp42Htvo9SEAWePHKOs= -github.com/mattn/go-shellwords v1.0.7/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.9 h1:eaB5JspOwiKKcHdqcjbfe5lA9cNn/4NRRtddXJCimqk= -github.com/mattn/go-shellwords v1.0.9/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= 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/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/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 h1:7InQ7/zrOh6SlFjaXFubv0xX0HsuC9qJsdqm7bNQpYM= -github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc8 h1:dDCFes8Hj1r/i5qnypONo5jdOme/8HWZC/aNDyhECt0= -github.com/opencontainers/runc v1.0.0-rc8/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc9 h1:/k06BMULKF5hidyoZymkoDCzdJzltZpz/UU4LguQVtc= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.1 h1:wY4pOY8fBdSIvs9+IDHC55thBuEulhzfSgKeC1yFvzQ= -github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= -github.com/opencontainers/selinux v1.2.2 h1:Kx9J6eDG5/24A6DtUquGSpJQ+m2MUTahn4FtGEe8bFg= -github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= -github.com/opencontainers/selinux v1.3.0 h1:xsI95WzPZu5exzA6JzkLSfdr/DilzOhCJOqGe5TgR0g= -github.com/opencontainers/selinux v1.3.0/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= -github.com/opencontainers/selinux v1.3.1 h1:dn2Rc3wTEvTB6iVqoFrKKeMb0uZ38ZheeyMu2h5C1TI= -github.com/opencontainers/selinux v1.3.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= -github.com/opencontainers/selinux v1.3.2 h1:DR4lL9SYVjgcTZKEZIncvDU06fKSc/eygjmNGOA3E1s= -github.com/opencontainers/selinux v1.3.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/opencontainers/selinux v1.3.3 h1:RX0wAeqtvVSYQcr017X3pFXPkLEtB6V4NjRD7gVQgg4= github.com/opencontainers/selinux v1.3.3/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.0 h1:J8lpUdobwIeCI7OiSxHqEwJUKvJwicL5+3v1oe2Yb4k= -github.com/pkg/errors v0.9.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -141,26 +66,13 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7 h1:gGBSHPOU7g8YjTbhwn+lvFm2VDEhhA+PwDIlstkgSxE= github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M= github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo= -github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.0 h1:DMOzIV76tmoDNE9pX6RSN0aDtCYeCg5VueieJaAo1uw= -github.com/stretchr/testify v1.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -169,22 +81,14 @@ github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs= github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE= github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g= -github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM= -github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= -github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f h1:nBX3nTcmxEtHSERBJaIo1Qa26VwRaopnZmfDQUXsF4I= -github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -193,7 +97,6 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -205,25 +108,16 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339 h1:zSqWKgm/o7HAnlAzBQ+aetp9fpuyytsXnKA8eiLHYQM= -golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777 h1:wejkGHRTr38uaKRqECZlsCsJ1/TGxIyFbH32x5zUdu4= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2 h1:/J2nHFg1MTqaRLFO7M+J78ASNsJoz3r0cvHBPQ77fsE= -golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180810170437-e96c4e24768d/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -234,11 +128,10 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +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/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gotest.tools v0.0.0-20190624233834-05ebafbffc79 h1:C+K4iPg1rIvmCf4JjelkbWv2jeWevEwp05Lz8XfTYgE= -gotest.tools v0.0.0-20190624233834-05ebafbffc79/go.mod h1:R//lfYlUuTOTfblYI3lGoAAAebUdzjvbmQsuB7Ykd90= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/containers/storage/pkg/ioutils/fswriters.go b/vendor/github.com/containers/storage/pkg/ioutils/fswriters.go index a56c46265..0df326b03 100644 --- a/vendor/github.com/containers/storage/pkg/ioutils/fswriters.go +++ b/vendor/github.com/containers/storage/pkg/ioutils/fswriters.go @@ -65,7 +65,7 @@ func (w *atomicFileWriter) Close() (retErr error) { os.Remove(w.f.Name()) } }() - if err := w.f.Sync(); err != nil { + if err := fdatasync(w.f); err != nil { w.f.Close() return err } @@ -126,7 +126,7 @@ type syncFileCloser struct { } func (w syncFileCloser) Close() error { - err := w.File.Sync() + err := fdatasync(w.File) if err1 := w.File.Close(); err == nil { err = err1 } diff --git a/vendor/github.com/containers/storage/pkg/ioutils/fswriters_linux.go b/vendor/github.com/containers/storage/pkg/ioutils/fswriters_linux.go new file mode 100644 index 000000000..0da78a063 --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/ioutils/fswriters_linux.go @@ -0,0 +1,11 @@ +package ioutils + +import ( + "os" + + "golang.org/x/sys/unix" +) + +func fdatasync(f *os.File) error { + return unix.Fdatasync(int(f.Fd())) +} diff --git a/vendor/github.com/containers/storage/pkg/ioutils/fswriters_unsupported.go b/vendor/github.com/containers/storage/pkg/ioutils/fswriters_unsupported.go new file mode 100644 index 000000000..79a094035 --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/ioutils/fswriters_unsupported.go @@ -0,0 +1,11 @@ +// +build !linux + +package ioutils + +import ( + "os" +) + +func fdatasync(f *os.File) error { + return f.Sync() +} diff --git a/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go b/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go index 302a523f5..6429d6254 100644 --- a/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go +++ b/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go @@ -206,10 +206,6 @@ func (l *lockfile) Touch() error { if n != len(id) { return unix.ENOSPC } - err = unix.Fsync(int(l.fd)) - if err != nil { - return err - } return nil } diff --git a/vendor/github.com/containers/storage/pkg/system/xattrs_linux.go b/vendor/github.com/containers/storage/pkg/system/xattrs_linux.go index 24c3f37ef..e94bb5d5c 100644 --- a/vendor/github.com/containers/storage/pkg/system/xattrs_linux.go +++ b/vendor/github.com/containers/storage/pkg/system/xattrs_linux.go @@ -2,45 +2,43 @@ package system import ( "bytes" - "syscall" "golang.org/x/sys/unix" ) const ( // Value is larger than the maximum size allowed - E2BIG syscall.Errno = unix.E2BIG + E2BIG unix.Errno = unix.E2BIG // Operation not supported - EOPNOTSUPP syscall.Errno = unix.EOPNOTSUPP + EOPNOTSUPP unix.Errno = unix.EOPNOTSUPP ) // Lgetxattr retrieves the value of the extended attribute identified by attr // and associated with the given path in the file system. -// It will returns a nil slice and nil error if the xattr is not set. +// Returns a []byte slice if the xattr is set and nil otherwise. func Lgetxattr(path string, attr string) ([]byte, error) { // Start with a 128 length byte array dest := make([]byte, 128) sz, errno := unix.Lgetxattr(path, attr, dest) - switch { - case errno == unix.ENODATA: - return nil, nil - case errno == unix.ERANGE: - // 128 byte array might just not be good enough. A dummy buffer is used - // to get the real size of the xattrs on disk + for errno == unix.ERANGE { + // Buffer too small, use zero-sized buffer to get the actual size sz, errno = unix.Lgetxattr(path, attr, []byte{}) if errno != nil { return nil, errno } dest = make([]byte, sz) sz, errno = unix.Lgetxattr(path, attr, dest) - if errno != nil { - return nil, errno - } + } + + switch { + case errno == unix.ENODATA: + return nil, nil case errno != nil: return nil, errno } + return dest[:sz], nil } @@ -53,24 +51,25 @@ func Lsetxattr(path string, attr string, data []byte, flags int) error { // Llistxattr lists extended attributes associated with the given path // in the file system. func Llistxattr(path string) ([]string, error) { - var dest []byte + dest := make([]byte, 128) + sz, errno := unix.Llistxattr(path, dest) - for { - sz, err := unix.Llistxattr(path, dest) - if err != nil { - return nil, err + for errno == unix.ERANGE { + // Buffer too small, use zero-sized buffer to get the actual size + sz, errno = unix.Llistxattr(path, []byte{}) + if errno != nil { + return nil, errno } - if sz > len(dest) { - dest = make([]byte, sz) - } else { - dest = dest[:sz] - break - } + dest = make([]byte, sz) + sz, errno = unix.Llistxattr(path, dest) + } + if errno != nil { + return nil, errno } var attrs []string - for _, token := range bytes.Split(dest, []byte{0}) { + for _, token := range bytes.Split(dest[:sz], []byte{0}) { if len(token) > 0 { attrs = append(attrs, string(token)) } diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go index 2c32e1504..49699b263 100644 --- a/vendor/github.com/containers/storage/store.go +++ b/vendor/github.com/containers/storage/store.go @@ -2320,24 +2320,53 @@ func (s *store) DeleteContainer(id string) error { if rcstore.Exists(id) { if container, err := rcstore.Get(id); err == nil { + errChan := make(chan error) + var wg sync.WaitGroup + if rlstore.Exists(container.LayerID) { - if err = rlstore.Delete(container.LayerID); err != nil { - return err - } - } - if err = rcstore.Delete(id); err != nil { - return err - } + wg.Add(1) + go func() { + errChan <- rlstore.Delete(container.LayerID) + wg.Done() + }() + } + wg.Add(1) + go func() { + errChan <- rcstore.Delete(id) + wg.Done() + }() + middleDir := s.graphDriverName + "-containers" gcpath := filepath.Join(s.GraphRoot(), middleDir, container.ID) - if err = os.RemoveAll(gcpath); err != nil { - return err - } + wg.Add(1) + go func() { + errChan <- os.RemoveAll(gcpath) + wg.Done() + }() + rcpath := filepath.Join(s.RunRoot(), middleDir, container.ID) - if err = os.RemoveAll(rcpath); err != nil { - return err + wg.Add(1) + go func() { + errChan <- os.RemoveAll(rcpath) + wg.Done() + }() + + go func() { + wg.Wait() + close(errChan) + }() + + for { + select { + case err, ok := <-errChan: + if !ok { + return nil + } + if err != nil { + return err + } + } } - return nil } } return ErrNotAContainer diff --git a/vendor/github.com/coreos/go-systemd/LICENSE b/vendor/github.com/coreos/go-systemd/v22/LICENSE index 37ec93a14..37ec93a14 100644 --- a/vendor/github.com/coreos/go-systemd/LICENSE +++ b/vendor/github.com/coreos/go-systemd/v22/LICENSE diff --git a/vendor/github.com/coreos/go-systemd/NOTICE b/vendor/github.com/coreos/go-systemd/v22/NOTICE index 23a0ada2f..23a0ada2f 100644 --- a/vendor/github.com/coreos/go-systemd/NOTICE +++ b/vendor/github.com/coreos/go-systemd/v22/NOTICE diff --git a/vendor/github.com/coreos/go-systemd/activation/files.go b/vendor/github.com/coreos/go-systemd/v22/activation/files.go index 29dd18def..29dd18def 100644 --- a/vendor/github.com/coreos/go-systemd/activation/files.go +++ b/vendor/github.com/coreos/go-systemd/v22/activation/files.go diff --git a/vendor/github.com/coreos/go-systemd/activation/listeners.go b/vendor/github.com/coreos/go-systemd/v22/activation/listeners.go index 3dbe2b087..3dbe2b087 100644 --- a/vendor/github.com/coreos/go-systemd/activation/listeners.go +++ b/vendor/github.com/coreos/go-systemd/v22/activation/listeners.go diff --git a/vendor/github.com/coreos/go-systemd/activation/packetconns.go b/vendor/github.com/coreos/go-systemd/v22/activation/packetconns.go index a97206785..a97206785 100644 --- a/vendor/github.com/coreos/go-systemd/activation/packetconns.go +++ b/vendor/github.com/coreos/go-systemd/v22/activation/packetconns.go diff --git a/vendor/github.com/coreos/go-systemd/dbus/dbus.go b/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go index f652582e6..91584a166 100644 --- a/vendor/github.com/coreos/go-systemd/dbus/dbus.go +++ b/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go @@ -23,7 +23,7 @@ import ( "strings" "sync" - "github.com/godbus/dbus" + "github.com/godbus/dbus/v5" ) const ( diff --git a/vendor/github.com/coreos/go-systemd/dbus/methods.go b/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go index 5859583eb..e38659d7b 100644 --- a/vendor/github.com/coreos/go-systemd/dbus/methods.go +++ b/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go @@ -20,7 +20,7 @@ import ( "path" "strconv" - "github.com/godbus/dbus" + "github.com/godbus/dbus/v5" ) func (c *Conn) jobComplete(signal *dbus.Signal) { diff --git a/vendor/github.com/coreos/go-systemd/dbus/properties.go b/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go index 6c8189587..fb42b6273 100644 --- a/vendor/github.com/coreos/go-systemd/dbus/properties.go +++ b/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go @@ -15,7 +15,7 @@ package dbus import ( - "github.com/godbus/dbus" + "github.com/godbus/dbus/v5" ) // From the systemd docs: @@ -56,7 +56,7 @@ type execStart struct { // http://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart= func PropExecStart(command []string, uncleanIsFailure bool) Property { execStarts := []execStart{ - execStart{ + { Path: command[0], Args: command, UncleanIsFailure: uncleanIsFailure, diff --git a/vendor/github.com/coreos/go-systemd/dbus/set.go b/vendor/github.com/coreos/go-systemd/v22/dbus/set.go index 17c5d4856..17c5d4856 100644 --- a/vendor/github.com/coreos/go-systemd/dbus/set.go +++ b/vendor/github.com/coreos/go-systemd/v22/dbus/set.go diff --git a/vendor/github.com/coreos/go-systemd/dbus/subscription.go b/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go index f6d7a08a1..7e370fea2 100644 --- a/vendor/github.com/coreos/go-systemd/dbus/subscription.go +++ b/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go @@ -19,7 +19,7 @@ import ( "log" "time" - "github.com/godbus/dbus" + "github.com/godbus/dbus/v5" ) const ( diff --git a/vendor/github.com/coreos/go-systemd/dbus/subscription_set.go b/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go index 5b408d584..5b408d584 100644 --- a/vendor/github.com/coreos/go-systemd/dbus/subscription_set.go +++ b/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go diff --git a/vendor/github.com/coreos/pkg/dlopen/dlopen.go b/vendor/github.com/coreos/go-systemd/v22/internal/dlopen/dlopen.go index 23774f612..23774f612 100644 --- a/vendor/github.com/coreos/pkg/dlopen/dlopen.go +++ b/vendor/github.com/coreos/go-systemd/v22/internal/dlopen/dlopen.go diff --git a/vendor/github.com/coreos/go-systemd/journal/journal.go b/vendor/github.com/coreos/go-systemd/v22/journal/journal.go index a0f4837a0..a0f4837a0 100644 --- a/vendor/github.com/coreos/go-systemd/journal/journal.go +++ b/vendor/github.com/coreos/go-systemd/v22/journal/journal.go diff --git a/vendor/github.com/coreos/go-systemd/sdjournal/functions.go b/vendor/github.com/coreos/go-systemd/v22/sdjournal/functions.go index e132369c1..3cbd05658 100644 --- a/vendor/github.com/coreos/go-systemd/sdjournal/functions.go +++ b/vendor/github.com/coreos/go-systemd/v22/sdjournal/functions.go @@ -16,7 +16,7 @@ package sdjournal import ( - "github.com/coreos/pkg/dlopen" + "github.com/coreos/go-systemd/v22/internal/dlopen" "sync" "unsafe" ) diff --git a/vendor/github.com/coreos/go-systemd/sdjournal/journal.go b/vendor/github.com/coreos/go-systemd/v22/sdjournal/journal.go index 7f840def8..7f840def8 100644 --- a/vendor/github.com/coreos/go-systemd/sdjournal/journal.go +++ b/vendor/github.com/coreos/go-systemd/v22/sdjournal/journal.go diff --git a/vendor/github.com/coreos/go-systemd/sdjournal/read.go b/vendor/github.com/coreos/go-systemd/v22/sdjournal/read.go index 51a060fb5..51a060fb5 100644 --- a/vendor/github.com/coreos/go-systemd/sdjournal/read.go +++ b/vendor/github.com/coreos/go-systemd/v22/sdjournal/read.go diff --git a/vendor/github.com/coreos/pkg/LICENSE b/vendor/github.com/coreos/pkg/LICENSE deleted file mode 100644 index e06d20818..000000000 --- a/vendor/github.com/coreos/pkg/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/vendor/github.com/coreos/pkg/NOTICE b/vendor/github.com/coreos/pkg/NOTICE deleted file mode 100644 index b39ddfa5c..000000000 --- a/vendor/github.com/coreos/pkg/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -CoreOS Project -Copyright 2014 CoreOS, Inc - -This product includes software developed at CoreOS, Inc. -(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/pkg/dlopen/dlopen_example.go b/vendor/github.com/coreos/pkg/dlopen/dlopen_example.go deleted file mode 100644 index 48a660104..000000000 --- a/vendor/github.com/coreos/pkg/dlopen/dlopen_example.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// +build linux - -package dlopen - -// #include <string.h> -// #include <stdlib.h> -// -// int -// my_strlen(void *f, const char *s) -// { -// size_t (*strlen)(const char *); -// -// strlen = (size_t (*)(const char *))f; -// return strlen(s); -// } -import "C" - -import ( - "fmt" - "unsafe" -) - -func strlen(libs []string, s string) (int, error) { - h, err := GetHandle(libs) - if err != nil { - return -1, fmt.Errorf(`couldn't get a handle to the library: %v`, err) - } - defer h.Close() - - f := "strlen" - cs := C.CString(s) - defer C.free(unsafe.Pointer(cs)) - - strlen, err := h.GetSymbolPointer(f) - if err != nil { - return -1, fmt.Errorf(`couldn't get symbol %q: %v`, f, err) - } - - len := C.my_strlen(strlen, cs) - - return int(len), nil -} diff --git a/vendor/github.com/godbus/dbus/.travis.yml b/vendor/github.com/godbus/dbus/.travis.yml deleted file mode 100644 index 9cd57f432..000000000 --- a/vendor/github.com/godbus/dbus/.travis.yml +++ /dev/null @@ -1,46 +0,0 @@ -dist: precise -language: go -go_import_path: github.com/godbus/dbus -sudo: true - -go: - - 1.7.3 - - 1.8.7 - - 1.9.5 - - 1.10.1 - - tip - -env: - global: - matrix: - - TARGET=amd64 - - TARGET=arm64 - - TARGET=arm - - TARGET=386 - - TARGET=ppc64le - -matrix: - fast_finish: true - allow_failures: - - go: tip - exclude: - - go: tip - env: TARGET=arm - - go: tip - env: TARGET=arm64 - - go: tip - env: TARGET=386 - - go: tip - env: TARGET=ppc64le - -addons: - apt: - packages: - - dbus - - dbus-x11 - -before_install: - -script: - - go test -v -race ./... # Run all the tests with the race detector enabled - - go vet ./... # go vet is the official Go static analyzer diff --git a/vendor/github.com/godbus/dbus/go.mod b/vendor/github.com/godbus/dbus/go.mod deleted file mode 100644 index 57014e4ac..000000000 --- a/vendor/github.com/godbus/dbus/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/godbus/dbus - -go 1.12 diff --git a/vendor/github.com/godbus/dbus/v5/.travis.yml b/vendor/github.com/godbus/dbus/v5/.travis.yml new file mode 100644 index 000000000..dd6767204 --- /dev/null +++ b/vendor/github.com/godbus/dbus/v5/.travis.yml @@ -0,0 +1,50 @@ +dist: bionic +language: go +go_import_path: github.com/godbus/dbus + +go: + - 1.11.x + - 1.12.x + - 1.13.x + - tip + +matrix: + fast_finish: true + allow_failures: + - go: tip + +addons: + apt: + packages: + - dbus + - dbus-x11 + +before_install: + - export GO111MODULE=on + +script: + - go test -v -race -mod=readonly ./... # Run all the tests with the race detector enabled + - go vet ./... # go vet is the official Go static analyzer + +jobs: + include: + # The build matrix doesn't cover build stages, so manually expand + # the jobs with anchors + - &multiarch + stage: "Multiarch Test" + go: 1.11.x + env: TARGETS="386 arm arm64 ppc64le" + before_install: + - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + script: + - | + set -e + for target in $TARGETS; do + printf "\e[1mRunning test suite under ${target}.\e[0m\n" + GOARCH="$target" go test -v ./... + printf "\n\n" + done + - <<: *multiarch + go: 1.12.x + - <<: *multiarch + go: 1.13.x diff --git a/vendor/github.com/godbus/dbus/CONTRIBUTING.md b/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md index c88f9b2bd..c88f9b2bd 100644 --- a/vendor/github.com/godbus/dbus/CONTRIBUTING.md +++ b/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md diff --git a/vendor/github.com/godbus/dbus/LICENSE b/vendor/github.com/godbus/dbus/v5/LICENSE index 670d88fca..670d88fca 100644 --- a/vendor/github.com/godbus/dbus/LICENSE +++ b/vendor/github.com/godbus/dbus/v5/LICENSE diff --git a/vendor/github.com/godbus/dbus/MAINTAINERS b/vendor/github.com/godbus/dbus/v5/MAINTAINERS index 27618c9cd..27618c9cd 100644 --- a/vendor/github.com/godbus/dbus/MAINTAINERS +++ b/vendor/github.com/godbus/dbus/v5/MAINTAINERS diff --git a/vendor/github.com/godbus/dbus/README.markdown b/vendor/github.com/godbus/dbus/v5/README.markdown index fd2964875..fd2964875 100644 --- a/vendor/github.com/godbus/dbus/README.markdown +++ b/vendor/github.com/godbus/dbus/v5/README.markdown diff --git a/vendor/github.com/godbus/dbus/auth.go b/vendor/github.com/godbus/dbus/v5/auth.go index b0dcb54e6..31abac629 100644 --- a/vendor/github.com/godbus/dbus/auth.go +++ b/vendor/github.com/godbus/dbus/v5/auth.go @@ -77,7 +77,7 @@ func (conn *Conn) Auth(methods []Auth) error { for _, m := range methods { if name, data, status := m.FirstData(); bytes.Equal(v, name) { var ok bool - err = authWriteLine(conn.transport, []byte("AUTH"), []byte(v), data) + err = authWriteLine(conn.transport, []byte("AUTH"), v, data) if err != nil { return err } @@ -127,7 +127,7 @@ func (conn *Conn) Auth(methods []Auth) error { // tryAuth tries to authenticate with m as the mechanism, using state as the // initial authState and in for reading input. It returns (nil, true) on // success, (nil, false) on a REJECTED and (someErr, false) if some other -// error occured. +// error occurred. func (conn *Conn) tryAuth(m Auth, state authState, in *bufio.Reader) (error, bool) { for { s, err := authReadLine(in) diff --git a/vendor/github.com/godbus/dbus/auth_anonymous.go b/vendor/github.com/godbus/dbus/v5/auth_anonymous.go index 75f3ad34d..75f3ad34d 100644 --- a/vendor/github.com/godbus/dbus/auth_anonymous.go +++ b/vendor/github.com/godbus/dbus/v5/auth_anonymous.go diff --git a/vendor/github.com/godbus/dbus/auth_external.go b/vendor/github.com/godbus/dbus/v5/auth_external.go index 7e376d3ef..7e376d3ef 100644 --- a/vendor/github.com/godbus/dbus/auth_external.go +++ b/vendor/github.com/godbus/dbus/v5/auth_external.go diff --git a/vendor/github.com/godbus/dbus/auth_sha1.go b/vendor/github.com/godbus/dbus/v5/auth_sha1.go index df15b4611..80286700b 100644 --- a/vendor/github.com/godbus/dbus/auth_sha1.go +++ b/vendor/github.com/godbus/dbus/v5/auth_sha1.go @@ -60,7 +60,7 @@ func (a authCookieSha1) HandleData(data []byte) ([]byte, AuthStatus) { // getCookie searches for the cookie identified by id in context and returns // the cookie content or nil. (Since HandleData can't return a specific error, -// but only whether an error occured, this function also doesn't bother to +// but only whether an error occurred, this function also doesn't bother to // return an error.) func (a authCookieSha1) getCookie(context, id []byte) []byte { file, err := os.Open(a.home + "/.dbus-keyrings/" + string(context)) diff --git a/vendor/github.com/godbus/dbus/call.go b/vendor/github.com/godbus/dbus/v5/call.go index 2cb189012..2cb189012 100644 --- a/vendor/github.com/godbus/dbus/call.go +++ b/vendor/github.com/godbus/dbus/v5/call.go diff --git a/vendor/github.com/godbus/dbus/conn.go b/vendor/github.com/godbus/dbus/v5/conn.go index 9dced0cc4..b55bc99c8 100644 --- a/vendor/github.com/godbus/dbus/conn.go +++ b/vendor/github.com/godbus/dbus/v5/conn.go @@ -5,7 +5,6 @@ import ( "errors" "io" "os" - "reflect" "strings" "sync" ) @@ -31,6 +30,12 @@ var ErrClosed = errors.New("dbus: connection closed by user") type Conn struct { transport + ctx context.Context + cancelCtx context.CancelFunc + + closeOnce sync.Once + closeErr error + busObj BusObject unixFD bool uuid string @@ -38,6 +43,8 @@ type Conn struct { handler Handler signalHandler SignalHandler serialGen SerialGenerator + inInt Interceptor + outInt Interceptor names *nameTracker calls *callTracker @@ -190,6 +197,33 @@ func WithSerialGenerator(gen SerialGenerator) ConnOption { } } +// Interceptor intercepts incoming and outgoing messages. +type Interceptor func(msg *Message) + +// WithIncomingInterceptor sets the given interceptor for incoming messages. +func WithIncomingInterceptor(interceptor Interceptor) ConnOption { + return func(conn *Conn) error { + conn.inInt = interceptor + return nil + } +} + +// WithOutgoingInterceptor sets the given interceptor for outgoing messages. +func WithOutgoingInterceptor(interceptor Interceptor) ConnOption { + return func(conn *Conn) error { + conn.outInt = interceptor + return nil + } +} + +// WithContext overrides the default context for the connection. +func WithContext(ctx context.Context) ConnOption { + return func(conn *Conn) error { + conn.ctx = ctx + return nil + } +} + // NewConn creates a new private *Conn from an already established connection. func NewConn(conn io.ReadWriteCloser, opts ...ConnOption) (*Conn, error) { return newConn(genericTransport{conn}, opts...) @@ -211,6 +245,15 @@ func newConn(tr transport, opts ...ConnOption) (*Conn, error) { return nil, err } } + if conn.ctx == nil { + conn.ctx = context.Background() + } + conn.ctx, conn.cancelCtx = context.WithCancel(conn.ctx) + go func() { + <-conn.ctx.Done() + conn.Close() + }() + conn.calls = newCallTracker() if conn.handler == nil { conn.handler = NewDefaultHandler() @@ -237,27 +280,38 @@ func (conn *Conn) BusObject() BusObject { // and the channels passed to Eavesdrop and Signal are closed. This method must // not be called on shared connections. func (conn *Conn) Close() error { - conn.outHandler.close() - if term, ok := conn.signalHandler.(Terminator); ok { - term.Terminate() - } + conn.closeOnce.Do(func() { + conn.outHandler.close() + if term, ok := conn.signalHandler.(Terminator); ok { + term.Terminate() + } - if term, ok := conn.handler.(Terminator); ok { - term.Terminate() - } + if term, ok := conn.handler.(Terminator); ok { + term.Terminate() + } - conn.eavesdroppedLck.Lock() - if conn.eavesdropped != nil { - close(conn.eavesdropped) - } - conn.eavesdroppedLck.Unlock() + conn.eavesdroppedLck.Lock() + if conn.eavesdropped != nil { + close(conn.eavesdropped) + } + conn.eavesdroppedLck.Unlock() + + conn.cancelCtx() + + conn.closeErr = conn.transport.Close() + }) + return conn.closeErr +} - return conn.transport.Close() +// Context returns the context associated with the connection. The +// context will be cancelled when the connection is closed. +func (conn *Conn) Context() context.Context { + return conn.ctx } // Eavesdrop causes conn to send all incoming messages to the given channel // without further processing. Method replies, errors and signals will not be -// sent to the appropiate channels and method calls will not be handled. If nil +// sent to the appropriate channels and method calls will not be handled. If nil // is passed, the normal behaviour is restored. // // The caller has to make sure that ch is sufficiently buffered; @@ -294,7 +348,7 @@ func (conn *Conn) inWorker() { msg, err := conn.ReadMessage() if err != nil { if _, ok := err.(InvalidMessageError); !ok { - // Some read error occured (usually EOF); we can't really do + // Some read error occurred (usually EOF); we can't really do // anything but to shut down all stuff and returns errors to all // pending replies. conn.Close() @@ -323,6 +377,10 @@ func (conn *Conn) inWorker() { // Ignore it. continue } + + if conn.inInt != nil { + conn.inInt(msg) + } switch msg.Type { case TypeError: conn.serialGen.RetireSerial(conn.calls.handleDBusError(msg)) @@ -383,11 +441,10 @@ func (conn *Conn) Object(dest string, path ObjectPath) BusObject { return &Object{conn, dest, path} } -func (conn *Conn) sendMessage(msg *Message) { - conn.sendMessageAndIfClosed(msg, func() {}) -} - func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) { + if conn.outInt != nil { + conn.outInt(msg) + } err := conn.outHandler.sendAndIfClosed(msg, ifClosed) conn.calls.handleSendError(msg, err) if err != nil { @@ -483,7 +540,7 @@ func (conn *Conn) sendError(err error, dest string, serial uint32) { if len(e.Body) > 0 { msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...)) } - conn.sendMessage(msg) + conn.sendMessageAndIfClosed(msg, nil) } // sendReply creates a method reply message corresponding to the parameters and @@ -501,33 +558,54 @@ func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) { if len(values) > 0 { msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...)) } - conn.sendMessage(msg) + conn.sendMessageAndIfClosed(msg, nil) } -func (conn *Conn) defaultSignalAction(fn func(h *defaultSignalHandler, ch chan<- *Signal), ch chan<- *Signal) { - if !isDefaultSignalHandler(conn.signalHandler) { - return - } - handler := conn.signalHandler.(*defaultSignalHandler) - fn(handler, ch) +// AddMatchSignal registers the given match rule to receive broadcast +// signals based on their contents. +func (conn *Conn) AddMatchSignal(options ...MatchOption) error { + options = append([]MatchOption{withMatchType("signal")}, options...) + return conn.busObj.Call( + "org.freedesktop.DBus.AddMatch", 0, + formatMatchOptions(options), + ).Store() +} + +// RemoveMatchSignal removes the first rule that matches previously registered with AddMatchSignal. +func (conn *Conn) RemoveMatchSignal(options ...MatchOption) error { + options = append([]MatchOption{withMatchType("signal")}, options...) + return conn.busObj.Call( + "org.freedesktop.DBus.RemoveMatch", 0, + formatMatchOptions(options), + ).Store() } // Signal registers the given channel to be passed all received signal messages. -// The caller has to make sure that ch is sufficiently buffered; if a message -// arrives when a write to c is not possible, it is discarded. // // Multiple of these channels can be registered at the same time. // // These channels are "overwritten" by Eavesdrop; i.e., if there currently is a // channel for eavesdropped messages, this channel receives all signals, and // none of the channels passed to Signal will receive any signals. +// +// Panics if the signal handler is not a `SignalRegistrar`. func (conn *Conn) Signal(ch chan<- *Signal) { - conn.defaultSignalAction((*defaultSignalHandler).addSignal, ch) + handler, ok := conn.signalHandler.(SignalRegistrar) + if !ok { + panic("cannot use this method with a non SignalRegistrar handler") + } + handler.AddSignal(ch) } // RemoveSignal removes the given channel from the list of the registered channels. +// +// Panics if the signal handler is not a `SignalRegistrar`. func (conn *Conn) RemoveSignal(ch chan<- *Signal) { - conn.defaultSignalAction((*defaultSignalHandler).removeSignal, ch) + handler, ok := conn.signalHandler.(SignalRegistrar) + if !ok { + panic("cannot use this method with a non SignalRegistrar handler") + } + handler.RemoveSignal(ch) } // SupportsUnixFDs returns whether the underlying transport supports passing of @@ -614,18 +692,6 @@ func getTransport(address string) (transport, error) { return nil, err } -// dereferenceAll returns a slice that, assuming that vs is a slice of pointers -// of arbitrary types, containes the values that are obtained from dereferencing -// all elements in vs. -func dereferenceAll(vs []interface{}) []interface{} { - for i := range vs { - v := reflect.ValueOf(vs[i]) - v = v.Elem() - vs[i] = v.Interface() - } - return vs -} - // getKey gets a key from a the list of keys. Returns "" on error / not found... func getKey(s, key string) string { for _, keyEqualsValue := range strings.Split(s, ",") { @@ -650,7 +716,9 @@ func (h *outputHandler) sendAndIfClosed(msg *Message, ifClosed func()) error { h.closed.lck.RLock() defer h.closed.lck.RUnlock() if h.closed.isClosed { - ifClosed() + if ifClosed != nil { + ifClosed() + } return nil } h.sendLck.Lock() @@ -801,7 +869,6 @@ func (tracker *callTracker) finalize(sn uint32) { delete(tracker.calls, sn) c.ContextCancel() } - return } func (tracker *callTracker) finalizeWithBody(sn uint32, body []interface{}) { @@ -815,7 +882,6 @@ func (tracker *callTracker) finalizeWithBody(sn uint32, body []interface{}) { c.Body = body c.done() } - return } func (tracker *callTracker) finalizeWithError(sn uint32, err error) { @@ -829,7 +895,6 @@ func (tracker *callTracker) finalizeWithError(sn uint32, err error) { c.Err = err c.done() } - return } func (tracker *callTracker) finalizeAllWithError(err error) { diff --git a/vendor/github.com/godbus/dbus/conn_darwin.go b/vendor/github.com/godbus/dbus/v5/conn_darwin.go index 6e2e40202..6e2e40202 100644 --- a/vendor/github.com/godbus/dbus/conn_darwin.go +++ b/vendor/github.com/godbus/dbus/v5/conn_darwin.go diff --git a/vendor/github.com/godbus/dbus/conn_other.go b/vendor/github.com/godbus/dbus/v5/conn_other.go index 616dcf664..616dcf664 100644 --- a/vendor/github.com/godbus/dbus/conn_other.go +++ b/vendor/github.com/godbus/dbus/v5/conn_other.go diff --git a/vendor/github.com/godbus/dbus/conn_unix.go b/vendor/github.com/godbus/dbus/v5/conn_unix.go index 4cba8ae8e..58aee7d2a 100644 --- a/vendor/github.com/godbus/dbus/conn_unix.go +++ b/vendor/github.com/godbus/dbus/v5/conn_unix.go @@ -4,7 +4,6 @@ package dbus import ( "os" - "fmt" ) const defaultSystemBusAddress = "unix:path=/var/run/dbus/system_bus_socket" @@ -12,7 +11,7 @@ const defaultSystemBusAddress = "unix:path=/var/run/dbus/system_bus_socket" func getSystemBusPlatformAddress() string { address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS") if address != "" { - return fmt.Sprintf("unix:path=%s", address) + return address } return defaultSystemBusAddress -}
\ No newline at end of file +} diff --git a/vendor/github.com/godbus/dbus/conn_windows.go b/vendor/github.com/godbus/dbus/v5/conn_windows.go index 4291e4519..4291e4519 100644 --- a/vendor/github.com/godbus/dbus/conn_windows.go +++ b/vendor/github.com/godbus/dbus/v5/conn_windows.go diff --git a/vendor/github.com/godbus/dbus/dbus.go b/vendor/github.com/godbus/dbus/v5/dbus.go index c6d0d3ce0..428923d26 100644 --- a/vendor/github.com/godbus/dbus/dbus.go +++ b/vendor/github.com/godbus/dbus/v5/dbus.go @@ -87,6 +87,7 @@ func setDest(dest, src reflect.Value) error { } if isVariant(src.Type()) && !isVariant(dest.Type()) { src = getVariantValue(src) + return store(dest, src) } if !src.Type().ConvertibleTo(dest.Type()) { return fmt.Errorf( diff --git a/vendor/github.com/godbus/dbus/decoder.go b/vendor/github.com/godbus/dbus/v5/decoder.go index ede91575b..ede91575b 100644 --- a/vendor/github.com/godbus/dbus/decoder.go +++ b/vendor/github.com/godbus/dbus/v5/decoder.go diff --git a/vendor/github.com/godbus/dbus/default_handler.go b/vendor/github.com/godbus/dbus/v5/default_handler.go index 890b6f4e0..6d8bf32f9 100644 --- a/vendor/github.com/godbus/dbus/default_handler.go +++ b/vendor/github.com/godbus/dbus/v5/default_handler.go @@ -47,7 +47,7 @@ func (h *defaultHandler) introspectPath(path ObjectPath) string { subpath := make(map[string]struct{}) var xml bytes.Buffer xml.WriteString("<node>") - for obj, _ := range h.objects { + for obj := range h.objects { p := string(path) if p != "/" { p += "/" @@ -57,7 +57,7 @@ func (h *defaultHandler) introspectPath(path ObjectPath) string { subpath[node_name] = struct{}{} } } - for s, _ := range subpath { + for s := range subpath { xml.WriteString("\n\t<node name=\"" + s + "\"/>") } xml.WriteString("\n</node>") @@ -234,88 +234,95 @@ func (obj *exportedIntf) isFallbackInterface() bool { // // Deprecated: this is the default value, don't use it, it will be unexported. func NewDefaultSignalHandler() *defaultSignalHandler { - return &defaultSignalHandler{ - closeChan: make(chan struct{}), - } -} - -func isDefaultSignalHandler(handler SignalHandler) bool { - _, ok := handler.(*defaultSignalHandler) - return ok + return &defaultSignalHandler{} } type defaultSignalHandler struct { - sync.RWMutex - closed bool - signals []chan<- *Signal - closeChan chan struct{} + mu sync.RWMutex + closed bool + signals []*signalChannelData } func (sh *defaultSignalHandler) DeliverSignal(intf, name string, signal *Signal) { - sh.RLock() - defer sh.RUnlock() + sh.mu.RLock() + defer sh.mu.RUnlock() if sh.closed { return } - for _, ch := range sh.signals { - select { - case ch <- signal: - case <-sh.closeChan: - return - default: - go func(ch chan<- *Signal) { - select { - case ch <- signal: - case <-sh.closeChan: - return - } - }(ch) - } + for _, scd := range sh.signals { + scd.deliver(signal) } } -func (sh *defaultSignalHandler) Init() error { - sh.Lock() - sh.signals = make([]chan<- *Signal, 0) - sh.closeChan = make(chan struct{}) - sh.Unlock() - return nil -} - func (sh *defaultSignalHandler) Terminate() { - sh.Lock() - if !sh.closed { - close(sh.closeChan) + sh.mu.Lock() + defer sh.mu.Unlock() + if sh.closed { + return } - sh.closed = true - for _, ch := range sh.signals { - close(ch) + + for _, scd := range sh.signals { + scd.close() + close(scd.ch) } + sh.closed = true sh.signals = nil - sh.Unlock() } -func (sh *defaultSignalHandler) addSignal(ch chan<- *Signal) { - sh.Lock() - defer sh.Unlock() +func (sh *defaultSignalHandler) AddSignal(ch chan<- *Signal) { + sh.mu.Lock() + defer sh.mu.Unlock() if sh.closed { return } - sh.signals = append(sh.signals, ch) - + sh.signals = append(sh.signals, &signalChannelData{ + ch: ch, + done: make(chan struct{}), + }) } -func (sh *defaultSignalHandler) removeSignal(ch chan<- *Signal) { - sh.Lock() - defer sh.Unlock() +func (sh *defaultSignalHandler) RemoveSignal(ch chan<- *Signal) { + sh.mu.Lock() + defer sh.mu.Unlock() if sh.closed { return } for i := len(sh.signals) - 1; i >= 0; i-- { - if ch == sh.signals[i] { + if ch == sh.signals[i].ch { + sh.signals[i].close() copy(sh.signals[i:], sh.signals[i+1:]) sh.signals[len(sh.signals)-1] = nil sh.signals = sh.signals[:len(sh.signals)-1] } } } + +type signalChannelData struct { + wg sync.WaitGroup + ch chan<- *Signal + done chan struct{} +} + +func (scd *signalChannelData) deliver(signal *Signal) { + select { + case scd.ch <- signal: + case <-scd.done: + return + default: + scd.wg.Add(1) + go scd.deferredDeliver(signal) + } +} + +func (scd *signalChannelData) deferredDeliver(signal *Signal) { + select { + case scd.ch <- signal: + case <-scd.done: + } + scd.wg.Done() +} + +func (scd *signalChannelData) close() { + close(scd.done) + scd.wg.Wait() // wait until all spawned goroutines return +} diff --git a/vendor/github.com/godbus/dbus/doc.go b/vendor/github.com/godbus/dbus/v5/doc.go index 895036a8c..ade1df951 100644 --- a/vendor/github.com/godbus/dbus/doc.go +++ b/vendor/github.com/godbus/dbus/v5/doc.go @@ -61,7 +61,7 @@ Handling Unix file descriptors deserves special mention. To use them, you should first check that they are supported on a connection by calling SupportsUnixFDs. If it returns true, all method of Connection will translate messages containing UnixFD's to messages that are accompanied by the given file descriptors with the -UnixFD values being substituted by the correct indices. Similarily, the indices +UnixFD values being substituted by the correct indices. Similarly, the indices of incoming messages are automatically resolved. It shouldn't be necessary to use UnixFDIndex. diff --git a/vendor/github.com/godbus/dbus/encoder.go b/vendor/github.com/godbus/dbus/v5/encoder.go index 8bb717761..adfbb75c5 100644 --- a/vendor/github.com/godbus/dbus/encoder.go +++ b/vendor/github.com/godbus/dbus/v5/encoder.go @@ -60,7 +60,7 @@ func (enc *encoder) binwrite(v interface{}) { } } -// Encode encodes the given values to the underyling reader. All written values +// Encode encodes the given values to the underlying reader. All written values // are aligned properly as required by the D-Bus spec. func (enc *encoder) Encode(vs ...interface{}) (err error) { defer func() { diff --git a/vendor/github.com/godbus/dbus/export.go b/vendor/github.com/godbus/dbus/v5/export.go index 95d0e2958..c277ab142 100644 --- a/vendor/github.com/godbus/dbus/export.go +++ b/vendor/github.com/godbus/dbus/v5/export.go @@ -171,7 +171,7 @@ func (conn *Conn) handleCall(msg *Message) { } reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...)) - conn.sendMessage(reply) + conn.sendMessageAndIfClosed(reply, nil) } } diff --git a/vendor/github.com/godbus/dbus/v5/go.mod b/vendor/github.com/godbus/dbus/v5/go.mod new file mode 100644 index 000000000..15b920203 --- /dev/null +++ b/vendor/github.com/godbus/dbus/v5/go.mod @@ -0,0 +1,3 @@ +module github.com/godbus/dbus/v5 + +go 1.12 diff --git a/vendor/github.com/godbus/dbus/v5/go.sum b/vendor/github.com/godbus/dbus/v5/go.sum new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/vendor/github.com/godbus/dbus/v5/go.sum diff --git a/vendor/github.com/godbus/dbus/homedir.go b/vendor/github.com/godbus/dbus/v5/homedir.go index 0b745f931..0b745f931 100644 --- a/vendor/github.com/godbus/dbus/homedir.go +++ b/vendor/github.com/godbus/dbus/v5/homedir.go diff --git a/vendor/github.com/godbus/dbus/homedir_dynamic.go b/vendor/github.com/godbus/dbus/v5/homedir_dynamic.go index 2732081e7..2732081e7 100644 --- a/vendor/github.com/godbus/dbus/homedir_dynamic.go +++ b/vendor/github.com/godbus/dbus/v5/homedir_dynamic.go diff --git a/vendor/github.com/godbus/dbus/homedir_static.go b/vendor/github.com/godbus/dbus/v5/homedir_static.go index b9d9cb552..b9d9cb552 100644 --- a/vendor/github.com/godbus/dbus/homedir_static.go +++ b/vendor/github.com/godbus/dbus/v5/homedir_static.go diff --git a/vendor/github.com/godbus/dbus/v5/match.go b/vendor/github.com/godbus/dbus/v5/match.go new file mode 100644 index 000000000..086ee336a --- /dev/null +++ b/vendor/github.com/godbus/dbus/v5/match.go @@ -0,0 +1,62 @@ +package dbus + +import ( + "strings" +) + +// MatchOption specifies option for dbus routing match rule. Options can be constructed with WithMatch* helpers. +// For full list of available options consult +// https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules +type MatchOption struct { + key string + value string +} + +func formatMatchOptions(options []MatchOption) string { + items := make([]string, 0, len(options)) + for _, option := range options { + items = append(items, option.key+"='"+option.value+"'") + } + return strings.Join(items, ",") +} + +// WithMatchOption creates match option with given key and value +func WithMatchOption(key, value string) MatchOption { + return MatchOption{key, value} +} + +// doesn't make sense to export this option because clients can only +// subscribe to messages with signal type. +func withMatchType(typ string) MatchOption { + return WithMatchOption("type", typ) +} + +// WithMatchSender sets sender match option. +func WithMatchSender(sender string) MatchOption { + return WithMatchOption("sender", sender) +} + +// WithMatchSender sets interface match option. +func WithMatchInterface(iface string) MatchOption { + return WithMatchOption("interface", iface) +} + +// WithMatchMember sets member match option. +func WithMatchMember(member string) MatchOption { + return WithMatchOption("member", member) +} + +// WithMatchObjectPath creates match option that filters events based on given path +func WithMatchObjectPath(path ObjectPath) MatchOption { + return WithMatchOption("path", string(path)) +} + +// WithMatchPathNamespace sets path_namespace match option. +func WithMatchPathNamespace(namespace ObjectPath) MatchOption { + return WithMatchOption("path_namespace", string(namespace)) +} + +// WithMatchDestination sets destination match option. +func WithMatchDestination(destination string) MatchOption { + return WithMatchOption("destination", destination) +} diff --git a/vendor/github.com/godbus/dbus/message.go b/vendor/github.com/godbus/dbus/v5/message.go index 6a925367e..6a925367e 100644 --- a/vendor/github.com/godbus/dbus/message.go +++ b/vendor/github.com/godbus/dbus/v5/message.go diff --git a/vendor/github.com/godbus/dbus/object.go b/vendor/github.com/godbus/dbus/v5/object.go index 9309b9b40..8acd7fc8b 100644 --- a/vendor/github.com/godbus/dbus/object.go +++ b/vendor/github.com/godbus/dbus/v5/object.go @@ -38,41 +38,16 @@ func (o *Object) CallWithContext(ctx context.Context, method string, flags Flags return <-o.createCall(ctx, method, flags, make(chan *Call, 1), args...).Done } -// MatchOption specifies option for dbus routing match rule. Options can be constructed with WithMatch* helpers. -// For full list of available options consult -// https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules -type MatchOption struct { - key string - value string -} - -// WithMatchOption creates match option with given key and value -func WithMatchOption(key, value string) MatchOption { - return MatchOption{key, value} -} - -// WithMatchObjectPath creates match option that filters events based on given path -func WithMatchObjectPath(path ObjectPath) MatchOption { - return MatchOption{"path", string(path)} -} - -func formatMatchOptions(options []MatchOption) string { - items := make([]string, 0, len(options)) - for _, option := range options { - items = append(items, option.key+"='"+option.value+"'") - } - - return strings.Join(items, ",") -} - // AddMatchSignal subscribes BusObject to signals from specified interface, // method (member). Additional filter rules can be added via WithMatch* option constructors. // Note: To filter events by object path you have to specify this path via an option. +// +// Deprecated: use (*Conn) AddMatchSignal instead. func (o *Object) AddMatchSignal(iface, member string, options ...MatchOption) *Call { base := []MatchOption{ - {"type", "signal"}, - {"interface", iface}, - {"member", member}, + withMatchType("signal"), + WithMatchInterface(iface), + WithMatchMember(member), } options = append(base, options...) @@ -85,11 +60,13 @@ func (o *Object) AddMatchSignal(iface, member string, options ...MatchOption) *C // RemoveMatchSignal unsubscribes BusObject from signals from specified interface, // method (member). Additional filter rules can be added via WithMatch* option constructors +// +// Deprecated: use (*Conn) RemoveMatchSignal instead. func (o *Object) RemoveMatchSignal(iface, member string, options ...MatchOption) *Call { base := []MatchOption{ - {"type", "signal"}, - {"interface", iface}, - {"member", member}, + withMatchType("signal"), + WithMatchInterface(iface), + WithMatchMember(member), } options = append(base, options...) diff --git a/vendor/github.com/godbus/dbus/server_interfaces.go b/vendor/github.com/godbus/dbus/v5/server_interfaces.go index 01166f0bd..79d97edf3 100644 --- a/vendor/github.com/godbus/dbus/server_interfaces.go +++ b/vendor/github.com/godbus/dbus/v5/server_interfaces.go @@ -77,6 +77,14 @@ type SignalHandler interface { DeliverSignal(iface, name string, signal *Signal) } +// SignalRegistrar manages signal delivery channels. +// +// This is an optional set of methods for `SignalHandler`. +type SignalRegistrar interface { + AddSignal(ch chan<- *Signal) + RemoveSignal(ch chan<- *Signal) +} + // A DBusError is used to convert a generic object to a D-Bus error. // // Any custom error mechanism may implement this interface to provide diff --git a/vendor/github.com/godbus/dbus/sig.go b/vendor/github.com/godbus/dbus/v5/sig.go index c1b809202..c1b809202 100644 --- a/vendor/github.com/godbus/dbus/sig.go +++ b/vendor/github.com/godbus/dbus/v5/sig.go diff --git a/vendor/github.com/godbus/dbus/transport_darwin.go b/vendor/github.com/godbus/dbus/v5/transport_darwin.go index 1bba0d6bf..1bba0d6bf 100644 --- a/vendor/github.com/godbus/dbus/transport_darwin.go +++ b/vendor/github.com/godbus/dbus/v5/transport_darwin.go diff --git a/vendor/github.com/godbus/dbus/transport_generic.go b/vendor/github.com/godbus/dbus/v5/transport_generic.go index 718a1ff02..718a1ff02 100644 --- a/vendor/github.com/godbus/dbus/transport_generic.go +++ b/vendor/github.com/godbus/dbus/v5/transport_generic.go diff --git a/vendor/github.com/godbus/dbus/transport_nonce_tcp.go b/vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go index 697739efa..697739efa 100644 --- a/vendor/github.com/godbus/dbus/transport_nonce_tcp.go +++ b/vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go diff --git a/vendor/github.com/godbus/dbus/transport_tcp.go b/vendor/github.com/godbus/dbus/v5/transport_tcp.go index f91c9b7d7..f91c9b7d7 100644 --- a/vendor/github.com/godbus/dbus/transport_tcp.go +++ b/vendor/github.com/godbus/dbus/v5/transport_tcp.go diff --git a/vendor/github.com/godbus/dbus/transport_unix.go b/vendor/github.com/godbus/dbus/v5/transport_unix.go index c7cd02f97..c7cd02f97 100644 --- a/vendor/github.com/godbus/dbus/transport_unix.go +++ b/vendor/github.com/godbus/dbus/v5/transport_unix.go diff --git a/vendor/github.com/godbus/dbus/transport_unixcred_dragonfly.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_dragonfly.go index a8cd39395..a8cd39395 100644 --- a/vendor/github.com/godbus/dbus/transport_unixcred_dragonfly.go +++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_dragonfly.go diff --git a/vendor/github.com/godbus/dbus/transport_unixcred_freebsd.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_freebsd.go index 0fc5b9273..0fc5b9273 100644 --- a/vendor/github.com/godbus/dbus/transport_unixcred_freebsd.go +++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_freebsd.go diff --git a/vendor/github.com/godbus/dbus/transport_unixcred_linux.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go index d9dfdf698..d9dfdf698 100644 --- a/vendor/github.com/godbus/dbus/transport_unixcred_linux.go +++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go diff --git a/vendor/github.com/godbus/dbus/transport_unixcred_openbsd.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_openbsd.go index af7bafdf9..af7bafdf9 100644 --- a/vendor/github.com/godbus/dbus/transport_unixcred_openbsd.go +++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_openbsd.go diff --git a/vendor/github.com/godbus/dbus/variant.go b/vendor/github.com/godbus/dbus/v5/variant.go index 0ca123b01..5b51828c8 100644 --- a/vendor/github.com/godbus/dbus/variant.go +++ b/vendor/github.com/godbus/dbus/v5/variant.go @@ -26,7 +26,7 @@ func MakeVariantWithSignature(v interface{}, s Signature) Variant { } // ParseVariant parses the given string as a variant as described at -// https://developer.gnome.org/glib/unstable/gvariant-text.html. If sig is not +// https://developer.gnome.org/glib/stable/gvariant-text.html. If sig is not // empty, it is taken to be the expected signature for the variant. func ParseVariant(s string, sig Signature) (Variant, error) { tokens := varLex(s) @@ -129,7 +129,7 @@ func (v Variant) Signature() Signature { } // String returns the string representation of the underlying value of v as -// described at https://developer.gnome.org/glib/unstable/gvariant-text.html. +// described at https://developer.gnome.org/glib/stable/gvariant-text.html. func (v Variant) String() string { s, unamb := v.format() if !unamb { diff --git a/vendor/github.com/godbus/dbus/variant_lexer.go b/vendor/github.com/godbus/dbus/v5/variant_lexer.go index 332007d6f..bf1398c8f 100644 --- a/vendor/github.com/godbus/dbus/variant_lexer.go +++ b/vendor/github.com/godbus/dbus/v5/variant_lexer.go @@ -51,7 +51,7 @@ func varLex(s string) []varToken { } func (l *varLexer) accept(valid string) bool { - if strings.IndexRune(valid, l.next()) >= 0 { + if strings.ContainsRune(valid, l.next()) { return true } l.backup() @@ -214,17 +214,17 @@ func varLexNumber(l *varLexer) lexState { digits = "01234567" } } - for strings.IndexRune(digits, l.next()) >= 0 { + for strings.ContainsRune(digits, l.next()) { } l.backup() if l.accept(".") { - for strings.IndexRune(digits, l.next()) >= 0 { + for strings.ContainsRune(digits, l.next()) { } l.backup() } if l.accept("eE") { l.accept("+-") - for strings.IndexRune("0123456789", l.next()) >= 0 { + for strings.ContainsRune("0123456789", l.next()) { } l.backup() } diff --git a/vendor/github.com/godbus/dbus/variant_parser.go b/vendor/github.com/godbus/dbus/v5/variant_parser.go index d20f5da6d..d20f5da6d 100644 --- a/vendor/github.com/godbus/dbus/variant_parser.go +++ b/vendor/github.com/godbus/dbus/v5/variant_parser.go diff --git a/vendor/modules.txt b/vendor/modules.txt index 96b4edd6f..f6b0e9b40 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -48,7 +48,7 @@ github.com/containerd/containerd/errdefs github.com/containerd/continuity/fs github.com/containerd/continuity/syscallx github.com/containerd/continuity/sysx -# github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 +# github.com/containernetworking/cni v0.7.2-0.20200304161608-4fae32b84921 github.com/containernetworking/cni/libcni github.com/containernetworking/cni/pkg/invoke github.com/containernetworking/cni/pkg/types @@ -142,7 +142,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.16.1 +# github.com/containers/storage v1.16.2 github.com/containers/storage github.com/containers/storage/drivers github.com/containers/storage/drivers/aufs @@ -184,13 +184,12 @@ github.com/containers/storage/pkg/tarlog github.com/containers/storage/pkg/truncindex # github.com/coreos/go-iptables v0.4.5 github.com/coreos/go-iptables/iptables -# github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f -github.com/coreos/go-systemd/activation -github.com/coreos/go-systemd/dbus -github.com/coreos/go-systemd/journal -github.com/coreos/go-systemd/sdjournal -# github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f -github.com/coreos/pkg/dlopen +# github.com/coreos/go-systemd/v22 v22.0.0 +github.com/coreos/go-systemd/v22/activation +github.com/coreos/go-systemd/v22/dbus +github.com/coreos/go-systemd/v22/internal/dlopen +github.com/coreos/go-systemd/v22/journal +github.com/coreos/go-systemd/v22/sdjournal # github.com/cri-o/ocicni v0.1.1-0.20190920040751-deac903fd99b github.com/cri-o/ocicni/pkg/ocicni # github.com/cyphar/filepath-securejoin v0.2.2 @@ -271,8 +270,8 @@ github.com/fsouza/go-dockerclient github.com/fullsailor/pkcs7 # github.com/ghodss/yaml v1.0.0 github.com/ghodss/yaml -# github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e -github.com/godbus/dbus +# github.com/godbus/dbus/v5 v5.0.3 +github.com/godbus/dbus/v5 # github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d github.com/gogo/protobuf/gogoproto github.com/gogo/protobuf/proto diff --git a/version/version.go b/version/version.go index d5926d744..5a7b4a36e 100644 --- a/version/version.go +++ b/version/version.go @@ -4,7 +4,7 @@ package version // NOTE: remember to bump the version at the top // of the top-level README.md file when this is // bumped. -const Version = "1.8.1-dev" +const Version = "1.8.2-dev" // RemoteAPIVersion is the version for the remote // client API. It is used to determine compatibility |