diff options
245 files changed, 2501 insertions, 2437 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 84a31e3ac..5ec35cccb 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -107,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 @@ -138,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}' @@ -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 @@ -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 513a3eeca..78e13c227 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -9,6 +9,7 @@ - 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 @@ -37,6 +38,7 @@ - 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 @@ -52,7 +54,7 @@ ### Misc - Updated vendored Buildah to v1.14.2 -- Updated vendored containers/storage to v1.16.0 +- 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 9b0968265..651ef89b8 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,33 @@ +- 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 diff --git a/cmd/podman/build.go b/cmd/podman/build.go index b8b315c68..acd402fdd 100644 --- a/cmd/podman/build.go +++ b/cmd/podman/build.go @@ -342,6 +342,7 @@ func buildCmd(c *cliconfig.BuildValues) error { } options := imagebuildah.BuildOptions{ + Architecture: c.Arch, CommonBuildOpts: &buildOpts, AdditionalTags: tags, Annotations: c.Annotation, @@ -359,6 +360,7 @@ func buildCmd(c *cliconfig.BuildValues) error { Layers: layers, NamespaceOptions: nsValues, NoCache: c.NoCache, + OS: c.OS, Out: stdout, Output: output, OutputFormat: format, diff --git a/cmd/podman/images.go b/cmd/podman/images.go index de61690ae..41790a5aa 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -155,7 +155,7 @@ func imagesCmd(c *cliconfig.ImagesValues) error { return errors.New("can not specify an image and a filter") } filters := c.Filter - if len(filters) < 1 { + if len(filters) < 1 && len(image) > 0 { filters = append(filters, fmt.Sprintf("reference=%s", image)) } 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/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 11b2bd027..8968f10e8 100644 --- a/cmd/podman/shared/create.go +++ b/cmd/podman/shared/create.go @@ -101,7 +101,7 @@ func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod. if err != nil { return nil, nil, err } - imageData, err = newImage.Inspect(ctx) + imageData, err = newImage.InspectNoSize(ctx) if err != nil { return nil, nil, err } 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/integration_test.sh b/contrib/cirrus/integration_test.sh index 20e067c93..6341bcb4a 100755 --- a/contrib/cirrus/integration_test.sh +++ b/contrib/cirrus/integration_test.sh @@ -45,7 +45,7 @@ case "$SPECIALMODE" in bindings) make make install PREFIX=/usr ETCDIR=/etc - cd pkg/bindings/test && ginkgo -r + cd pkg/bindings/test && ginkgo -trace -noColor -debug -r ;; none) make 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 e08eebc24..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. @@ -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 23106fe76..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: diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md index 3199232fa..27b40bbb6 100644 --- a/docs/source/markdown/podman-generate-systemd.1.md +++ b/docs/source/markdown/podman-generate-systemd.1.md @@ -43,8 +43,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 @@ -59,7 +59,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. @@ -73,8 +73,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 @@ -91,7 +91,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-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-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 f595e77e4..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: 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,6 +6,7 @@ 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/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 @@ -13,8 +14,8 @@ require ( 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.3 + 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 @@ -24,9 +25,9 @@ require ( github.com/docker/go-connections v0.4.0 github.com/docker/go-units v0.4.0 github.com/etcd-io/bbolt v1.3.3 - github.com/fsnotify/fsnotify v1.4.7 + github.com/fsnotify/fsnotify v1.4.9 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 @@ -42,7 +43,7 @@ require ( github.com/opencontainers/runc v1.0.0-rc9 github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7 github.com/opencontainers/runtime-tools v0.9.0 - github.com/opencontainers/selinux v1.3.3 + github.com/opencontainers/selinux v1.4.0 github.com/opentracing/opentracing-go v1.1.0 github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.0 @@ -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= @@ -70,25 +65,8 @@ github.com/containernetworking/cni v0.7.2-0.20200304161608-4fae32b84921 h1:eUMd8 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= @@ -106,15 +84,20 @@ 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/containers/storage v1.16.3 h1:bctiz1I+0TIivtXbrVmy02ZYlOA+IjKIJMzAMTBifj8= +github.com/containers/storage v1.16.3/go.mod h1:dNTv0+BaebIAOGgH34dPtwGPR+Km2fObcfOlFxYFwA0= 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= @@ -153,9 +136,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= @@ -165,6 +150,8 @@ github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6 github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsouza/go-dockerclient v1.6.3 h1:VS/I3mxieZVIeaWXd57JKvSjheELafUJYtblGg75RIQ= github.com/fsouza/go-dockerclient v1.6.3/go.mod h1:OiSy/IhZIF+zheikZkXK7LVpGzxWchJPJKGWhBqOK4M= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU= @@ -192,12 +179,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= @@ -211,6 +201,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= @@ -285,9 +276,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= @@ -360,6 +353,8 @@ github.com/opencontainers/selinux v1.3.2 h1:DR4lL9SYVjgcTZKEZIncvDU06fKSc/eygjmN 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/opencontainers/selinux v1.4.0 h1:cpiX/2wWIju/6My60T6/z9CxNG7c8xTQyEmA9fChpUo= +github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316 h1:enQG2QUGwug4fR1yM6hL0Fjzx6Km/exZY6RbSPwMu3o= github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316/go.mod h1:dv+J0b/HWai0QnMVb37/H0v36klkLBi2TNpPeWDxX10= github.com/openshift/imagebuilder v1.1.1 h1:KAUR31p8UBJdfVO42azWgb+LeMAed2zaKQ19e0C0X2I= @@ -434,6 +429,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= @@ -482,6 +478,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= @@ -554,6 +551,7 @@ golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -578,7 +576,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= @@ -603,6 +600,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= @@ -622,8 +620,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/container_api.go b/libpod/container_api.go index 5e8fcea47..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 diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 60b13f125..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 { 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/image.go b/libpod/image/image.go index 43fd52a1a..5f914ed79 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -916,12 +916,7 @@ func (i *Image) imageInspectInfo(ctx context.Context) (*types.ImageInspectInfo, return i.inspectInfo, nil } -// Inspect returns an image's inspect data -func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) { - span, _ := opentracing.StartSpanFromContext(ctx, "imageInspect") - span.SetTag("type", "image") - defer span.Finish() - +func (i *Image) inspect(ctx context.Context, calculateSize bool) (*inspect.ImageData, error) { ociv1Img, err := i.ociv1Image(ctx) if err != nil { ociv1Img = &ociv1.Image{} @@ -936,8 +931,10 @@ func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) { } size := int64(-1) - if usize, err := i.Size(ctx); err == nil { - size = int64(*usize) + if calculateSize { + if usize, err := i.Size(ctx); err == nil { + size = int64(*usize) + } } repoTags, err := i.RepoTags() @@ -1002,6 +999,26 @@ func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) { return data, nil } +// Inspect returns an image's inspect data +func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) { + span, _ := opentracing.StartSpanFromContext(ctx, "imageInspect") + + span.SetTag("type", "image") + defer span.Finish() + + return i.inspect(ctx, true) +} + +// InspectNoSize returns an image's inspect data without calculating the size for the image +func (i *Image) InspectNoSize(ctx context.Context) (*inspect.ImageData, error) { + span, _ := opentracing.StartSpanFromContext(ctx, "imageInspectNoSize") + + span.SetTag("type", "image") + defer span.Finish() + + return i.inspect(ctx, false) +} + // Import imports and image into the store and returns an image func (ir *Runtime) Import(ctx context.Context, path, reference string, writer io.Writer, signingOptions SigningOptions, imageConfig ociv1.Image) (*Image, error) { src, err := tarball.Transport.ParseReference(path) 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/oci.go b/libpod/oci.go index 41d420664..27edebefc 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -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/reset.go b/libpod/reset.go index a35b476a4..ae0a0cde9 100644 --- a/libpod/reset.go +++ b/libpod/reset.go @@ -7,6 +7,7 @@ import ( "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/rootless" + "github.com/containers/libpod/pkg/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -87,12 +88,22 @@ func (r *Runtime) Reset(ctx context.Context) error { } prevError = err } - if err := os.RemoveAll(r.config.TmpDir); err != nil { + + runtimeDir, err := util.GetRuntimeDir() + if err != nil { + return err + } + tempDir := r.config.TmpDir + if r.config.TmpDir == runtimeDir { + tempDir = filepath.Join(r.config.TmpDir, "containers") + } + if err := os.RemoveAll(tempDir); err != nil { if prevError != nil { logrus.Error(prevError) } prevError = err } + if rootless.IsRootless() { configPath := filepath.Join(os.Getenv("HOME"), ".config/containers") if err := os.RemoveAll(configPath); err != nil { diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go index 27735a9b2..279cafa39 100644 --- a/libpod/runtime_pod_infra_linux.go +++ b/libpod/runtime_pod_infra_linux.go @@ -147,7 +147,7 @@ func (r *Runtime) createInfraContainer(ctx context.Context, p *Pod) (*Container, return nil, err } - data, err := newImage.Inspect(ctx) + data, err := newImage.InspectNoSize(ctx) if err != nil { return nil, err } diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go index 220d4cf75..d87de481c 100644 --- a/pkg/adapter/runtime_remote.go +++ b/pkg/adapter/runtime_remote.go @@ -201,8 +201,11 @@ func (r *LocalRuntime) GetRWImages() ([]*ContainerImage, error) { } func (r *LocalRuntime) GetFilteredImages(filters []string, rwOnly bool) ([]*ContainerImage, error) { + if len(filters) > 0 { + return nil, errors.Wrap(define.ErrNotImplemented, "filtering images is not supported on the remote client") + } var newImages []*ContainerImage - images, err := iopodman.ListImagesWithFilters().Call(r.Conn, filters) + images, err := iopodman.ListImages().Call(r.Conn) if err != nil { return nil, err } diff --git a/pkg/adapter/sigproxy_linux.go b/pkg/adapter/sigproxy_linux.go index 8295e4250..5695d0e42 100644 --- a/pkg/adapter/sigproxy_linux.go +++ b/pkg/adapter/sigproxy_linux.go @@ -20,7 +20,10 @@ func ProxySignals(ctr *libpod.Container) { for s := range sigBuffer { // Ignore SIGCHLD and SIGPIPE - these are mostly likely // intended for the podman command itself. - if s == syscall.SIGCHLD || s == syscall.SIGPIPE { + // SIGURG was added because of golang 1.14 and its preemptive changes + // causing more signals to "show up". + // https://github.com/containers/libpod/issues/5483 + if s == syscall.SIGCHLD || s == syscall.SIGPIPE || s == syscall.SIGURG { continue } 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 b8460702c..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) { @@ -126,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 078896834..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" @@ -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 @@ -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 1256256fd..000000000 --- a/pkg/api/handlers/containers.go +++ /dev/null @@ -1,243 +0,0 @@ -package handlers - -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/docker/docker/api/types" - "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 - } - - 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/healthcheck.go b/pkg/api/handlers/libpod/healthcheck.go index 6c74500b9..6eb2ab0e3 100644 --- a/pkg/api/handlers/libpod/healthcheck.go +++ b/pkg/api/handlers/libpod/healthcheck.go @@ -14,8 +14,30 @@ func RunHealthCheck(w http.ResponseWriter, r *http.Request) { if err != nil { if status == libpod.HealthCheckContainerNotFound { utils.ContainerNotFound(w, name, err) + return } + if status == libpod.HealthCheckNotDefined { + utils.Error(w, "no healthcheck defined", http.StatusConflict, err) + return + } + if status == libpod.HealthCheckContainerStopped { + utils.Error(w, "container not running", http.StatusConflict, err) + return + } + utils.InternalServerError(w, err) + return + } + ctr, err := runtime.LookupContainer(name) + if err != nil { utils.InternalServerError(w, err) + return } - utils.WriteResponse(w, http.StatusOK, status) + + hcLog, err := ctr.GetHealthCheckLog() + if err != nil { + utils.InternalServerError(w, err) + return + } + + utils.WriteResponse(w, http.StatusOK, hcLog) } 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 ee697b6b7..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 don't 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 don't 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/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/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 7e51c2b63..33b707fa4 100644 --- a/pkg/api/server/register_auth.go +++ b/pkg/api/server/register_auth.go @@ -1,13 +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(handlers.UnsupportedHandler)) + 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 a87e8eaee..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,9 +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(generic.CreateContainer)).Methods(http.MethodPost) + r.HandleFunc("/containers/create", s.APIHandler(compat.CreateContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/json compat listContainers // --- // tags: @@ -85,9 +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(generic.ListContainers)).Methods(http.MethodGet) + r.HandleFunc("/containers/json", s.APIHandler(compat.ListContainers)).Methods(http.MethodGet) // swagger:operation POST /containers/prune compat pruneContainers // --- // tags: @@ -109,9 +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(handlers.PruneContainers)).Methods(http.MethodPost) + r.HandleFunc("/containers/prune", s.APIHandler(compat.PruneContainers)).Methods(http.MethodPost) // swagger:operation DELETE /containers/{name} compat removeContainer // --- // tags: @@ -150,9 +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(generic.RemoveContainer)).Methods(http.MethodDelete) + r.HandleFunc("/containers/{name}", s.APIHandler(compat.RemoveContainer)).Methods(http.MethodDelete) // swagger:operation GET /containers/{name}/json compat getContainer // --- // tags: @@ -179,9 +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(generic.GetContainer)).Methods(http.MethodGet) + r.HandleFunc("/containers/{name}/json", s.APIHandler(compat.GetContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{name}/kill compat killContainer // --- // tags: @@ -211,9 +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(generic.KillContainer)).Methods(http.MethodPost) + r.HandleFunc("/containers/{name}/kill", s.APIHandler(compat.KillContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/{name}/logs compat logsFromContainer // --- // tags: @@ -265,9 +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(generic.LogsFromContainer)).Methods(http.MethodGet) + r.HandleFunc("/containers/{name}/logs", s.APIHandler(compat.LogsFromContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{name}/pause compat pauseContainer // --- // tags: @@ -289,12 +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}/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(handlers.PauseContainer)).Methods(http.MethodPost) - r.HandleFunc(VersionedPath("/containers/{name}/rename"), s.APIHandler(handlers.UnsupportedHandler)).Methods(http.MethodPost) + 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(handlers.UnsupportedHandler)).Methods(http.MethodPost) + r.HandleFunc("/containers/{name}/rename", s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/restart compat restartContainer // --- // tags: @@ -319,9 +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(handlers.RestartContainer)).Methods(http.MethodPost) + r.HandleFunc("/containers/{name}/restart", s.APIHandler(compat.RestartContainer)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/start compat startContainer // --- // tags: @@ -349,9 +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(handlers.StartContainer)).Methods(http.MethodPost) + r.HandleFunc("/containers/{name}/start", s.APIHandler(compat.StartContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/{name}/stats compat statsContainer // --- // tags: @@ -378,9 +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(generic.StatsContainer)).Methods(http.MethodGet) + r.HandleFunc("/containers/{name}/stats", s.APIHandler(compat.StatsContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{name}/stop compat stopContainer // --- // tags: @@ -408,9 +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(handlers.StopContainer)).Methods(http.MethodPost) + r.HandleFunc("/containers/{name}/stop", s.APIHandler(compat.StopContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/{name}/top compat topContainer // --- // tags: @@ -435,9 +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(handlers.TopContainer)).Methods(http.MethodGet) + r.HandleFunc("/containers/{name}/top", s.APIHandler(compat.TopContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{name}/unpause compat unpauseContainer // --- // tags: @@ -459,9 +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(handlers.UnpauseContainer)).Methods(http.MethodPost) + r.HandleFunc("/containers/{name}/unpause", s.APIHandler(compat.UnpauseContainer)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/wait compat waitContainer // --- // tags: @@ -494,9 +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(generic.WaitContainer)).Methods(http.MethodPost) + r.HandleFunc("/containers/{name}/wait", s.APIHandler(compat.WaitContainer)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/attach compat attachContainer // --- // tags: @@ -551,9 +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(handlers.AttachContainer)).Methods(http.MethodPost) + r.HandleFunc("/containers/{name}/attach", s.APIHandler(compat.AttachContainer)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/resize compat resizeContainer // --- // tags: @@ -585,9 +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(handlers.ResizeContainer)).Methods(http.MethodPost) + r.HandleFunc("/containers/{name}/resize", s.APIHandler(compat.ResizeContainer)).Methods(http.MethodPost) /* libpod endpoints @@ -704,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: @@ -756,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: @@ -811,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: @@ -911,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: @@ -933,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: @@ -958,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: @@ -986,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: @@ -1013,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: @@ -1047,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: @@ -1068,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: @@ -1150,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: @@ -1205,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: @@ -1237,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 730129d5d..89f69ea67 100644 --- a/pkg/api/server/register_distribution.go +++ b/pkg/api/server/register_distribution.go @@ -1,13 +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", handlers.UnsupportedHandler) + 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 ea5d21882..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,8 @@ func (s *APIServer) registerEventsHandlers(r *mux.Router) error { // swagger:operation GET /events system getEvents // --- // tags: - // - system - // summary: Returns events filtered on query parameters + // - system (compat) + // summary: Get events // description: Returns events filtered on query parameters // produces: // - application/json @@ -34,8 +34,35 @@ 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) // Added non version path to URI to support docker non versioned paths - r.Handle("/events", s.APIHandler(handlers.GetEvents)).Methods(http.MethodGet) + r.Handle("/events", s.APIHandler(compat.GetEvents)).Methods(http.MethodGet) + // swagger:operation GET /libpod/events system libpodGetEvents + // --- + // tags: + // - system + // 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) return nil } diff --git a/pkg/api/server/register_exec.go b/pkg/api/server/register_exec.go index 76033a9ca..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,9 +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(handlers.CreateExec)).Methods(http.MethodPost) + r.Handle("/containers/{name}/create", s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation POST /exec/{id}/start compat startExec // --- // tags: @@ -112,9 +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(handlers.StartExec)).Methods(http.MethodPost) + r.Handle("/exec/{id}/start", s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation POST /exec/{id}/resize compat resizeExec // --- // tags: @@ -145,9 +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(handlers.ResizeExec)).Methods(http.MethodPost) + r.Handle("/exec/{id}/resize", s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation GET /exec/{id}/json compat inspectExec // --- // tags: @@ -169,9 +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(handlers.InspectExec)).Methods(http.MethodGet) + r.Handle("/exec/{id}/json", s.APIHandler(compat.UnsupportedHandler)).Methods(http.MethodGet) /* libpod api follows @@ -243,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: @@ -279,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: @@ -310,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: @@ -332,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_healthcheck.go b/pkg/api/server/register_healthcheck.go index 5466e2905..69aa5bbfb 100644 --- a/pkg/api/server/register_healthcheck.go +++ b/pkg/api/server/register_healthcheck.go @@ -8,6 +8,29 @@ import ( ) func (s *APIServer) registerHealthCheckHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/libpod/containers/{name}/runhealthcheck"), s.APIHandler(libpod.RunHealthCheck)).Methods(http.MethodGet) + // swagger:operation GET /libpod/containers/{name:.*}/healthcheck libpod libpodRunHealthCheck + // --- + // tags: + // - containers + // summary: Run a container's healthcheck + // description: Execute the defined healthcheck and return information about the results + // parameters: + // - in: path + // name: name:.* + // type: string + // required: true + // description: the name or ID of the container + // produces: + // - application/json + // responses: + // 200: + // $ref: "#/responses/HealthcheckRun" + // 404: + // $ref: "#/responses/NoSuchContainer" + // 409: + // description: container has no healthcheck or is not running + // 500: + // $ref: '#/responses/InternalError' + r.Handle(VersionedPath("/libpod/containers/{name:.*}/healthcheck"), s.APIHandler(libpod.RunHealthCheck)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 8c75c4d04..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,12 +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(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(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("/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(generic.CreateImageFromSrc)).Methods(http.MethodPost).Queries("fromSrc", "{fromSrc}") + r.Handle("/images/create", s.APIHandler(compat.CreateImageFromSrc)).Methods(http.MethodPost).Queries("fromSrc", "{fromSrc}") // swagger:operation GET /images/json compat listImages // --- // tags: @@ -87,9 +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(generic.GetImages)).Methods(http.MethodGet) + r.Handle("/images/json", s.APIHandler(compat.GetImages)).Methods(http.MethodGet) // swagger:operation POST /images/load compat importImage // --- // tags: @@ -113,9 +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(generic.LoadImages)).Methods(http.MethodPost) + r.Handle("/images/load", s.APIHandler(compat.LoadImages)).Methods(http.MethodPost) // swagger:operation POST /images/prune compat pruneImages // --- // tags: @@ -140,9 +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(generic.PruneImages)).Methods(http.MethodPost) + r.Handle("/images/prune", s.APIHandler(compat.PruneImages)).Methods(http.MethodPost) // swagger:operation GET /images/search compat searchImages // --- // tags: @@ -175,9 +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(handlers.SearchImages)).Methods(http.MethodGet) + r.Handle("/images/search", s.APIHandler(compat.SearchImages)).Methods(http.MethodGet) // swagger:operation DELETE /images/{name:.*} compat removeImage // --- // tags: @@ -209,9 +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(handlers.RemoveImage)).Methods(http.MethodDelete) + r.Handle("/images/{name:.*}", s.APIHandler(compat.RemoveImage)).Methods(http.MethodDelete) // swagger:operation GET /images/{name:.*}/get compat exportImage // --- // tags: @@ -234,9 +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(generic.ExportImage)).Methods(http.MethodGet) + r.Handle("/images/{name:.*}/get", s.APIHandler(compat.ExportImage)).Methods(http.MethodGet) // swagger:operation GET /images/{name:.*}/history compat imageHistory // --- // tags: @@ -258,9 +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(handlers.HistoryImage)).Methods(http.MethodGet) + r.Handle("/images/{name:.*}/history", s.APIHandler(compat.HistoryImage)).Methods(http.MethodGet) // swagger:operation GET /images/{name:.*}/json compat inspectImage // --- // tags: @@ -282,9 +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(generic.GetImage)).Methods(http.MethodGet) + r.Handle("/images/{name:.*}/json", s.APIHandler(compat.GetImage)).Methods(http.MethodGet) // swagger:operation POST /images/{name:.*}/tag compat tagImage // --- // tags: @@ -318,9 +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(handlers.TagImage)).Methods(http.MethodPost) + r.Handle("/images/{name:.*}/tag", s.APIHandler(compat.TagImage)).Methods(http.MethodPost) // swagger:operation POST /commit compat commitContainer // --- // tags: @@ -365,9 +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(generic.CommitContainer)).Methods(http.MethodPost) + r.Handle("/commit", s.APIHandler(compat.CommitContainer)).Methods(http.MethodPost) // swagger:operation POST /build compat buildImage // --- @@ -577,9 +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(handlers.BuildImage)).Methods(http.MethodPost) + r.Handle("/build", s.APIHandler(compat.BuildImage)).Methods(http.MethodPost) /* libpod endpoints */ @@ -653,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: @@ -848,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: @@ -878,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: @@ -967,7 +966,7 @@ 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: @@ -1012,6 +1011,6 @@ 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) return nil } diff --git a/pkg/api/server/register_info.go b/pkg/api/server/register_info.go index 975a19fef..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,8 +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(generic.GetInfo)).Methods(http.MethodGet) + 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 b821efbaa..b7a7c3792 100644 --- a/pkg/api/server/register_monitor.go +++ b/pkg/api/server/register_monitor.go @@ -1,13 +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(handlers.UnsupportedHandler)) + 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 50026f6ad..5f6473fe8 100644 --- a/pkg/api/server/register_plugins.go +++ b/pkg/api/server/register_plugins.go @@ -1,13 +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(handlers.UnsupportedHandler)) + r.Handle("/plugins", s.APIHandler(compat.UnsupportedHandler)) return nil } diff --git a/pkg/api/server/register_system.go b/pkg/api/server/register_system.go index 4776692f5..708ccd39b 100644 --- a/pkg/api/server/register_system.go +++ b/pkg/api/server/register_system.go @@ -3,13 +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(generic.GetDiskUsage)).Methods(http.MethodGet) + 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/server/swagger.go b/pkg/api/server/swagger.go index 011196e5a..e3c991d6d 100644 --- a/pkg/api/server/swagger.go +++ b/pkg/api/server/swagger.go @@ -156,3 +156,12 @@ type swagVolumeListResponse struct { // in:body Body []libpod.Volume } + +// Healthcheck +// swagger:response HealthcheckRun +type swagHealthCheckRunResponse struct { + // in:body + Body struct { + libpod.HealthCheckResults + } +} diff --git a/pkg/bindings/containers/healthcheck.go b/pkg/bindings/containers/healthcheck.go index 3f94fad01..85cc2814c 100644 --- a/pkg/bindings/containers/healthcheck.go +++ b/pkg/bindings/containers/healthcheck.go @@ -10,15 +10,15 @@ import ( // RunHealthCheck executes the container's healthcheck and returns the health status of the // container. -func RunHealthCheck(ctx context.Context, nameOrID string) (*libpod.HealthCheckStatus, error) { +func RunHealthCheck(ctx context.Context, nameOrID string) (*libpod.HealthCheckResults, error) { conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } var ( - status libpod.HealthCheckStatus + status libpod.HealthCheckResults ) - response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/runhealthcheck", nil, nameOrID) + response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/healthcheck", nil, nameOrID) if err != nil { return nil, err } diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go index e7ef620d4..34a9c3136 100644 --- a/pkg/bindings/test/containers_test.go +++ b/pkg/bindings/test/containers_test.go @@ -312,4 +312,49 @@ var _ = Describe("Podman containers ", func() { Expect(exitCode).To(BeNumerically("==", -1)) }) + It("run healthcheck", func() { + bt.runPodman([]string{"run", "-d", "--name", "hc", "--health-interval", "disable", "--health-retries", "2", "--health-cmd", "ls / || exit 1", alpine.name, "top"}) + + // bogus name should result in 404 + _, err := containers.RunHealthCheck(bt.conn, "foobar") + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusNotFound)) + + // a container that has no healthcheck should be a 409 + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + _, err = containers.RunHealthCheck(bt.conn, name) + Expect(err).ToNot(BeNil()) + code, _ = bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusConflict)) + + // TODO for the life of me, i cannot get this to work. maybe another set + // of eyes will + // successful healthcheck + //status := "healthy" + //for i:=0; i < 10; i++ { + // result, err := containers.RunHealthCheck(connText, "hc") + // Expect(err).To(BeNil()) + // if result.Status != "healthy" { + // fmt.Println("Healthcheck container still starting, retrying in 1 second") + // time.Sleep(1 * time.Second) + // continue + // } + // status = result.Status + // break + //} + //Expect(status).To(Equal("healthy")) + + // TODO enable this when wait is working + // healthcheck on a stopped container should be a 409 + //err = containers.Stop(connText, "hc", nil) + //Expect(err).To(BeNil()) + //_, err = containers.Wait(connText, "hc") + //Expect(err).To(BeNil()) + //_, err = containers.RunHealthCheck(connText, "hc") + //code, _ = bindings.CheckResponseCode(err) + //Expect(code).To(BeNumerically("==", http.StatusConflict)) + }) + }) 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/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/rootlessport/rootlessport_linux.go b/pkg/rootlessport/rootlessport_linux.go index 2b51f4e09..febfc2268 100644 --- a/pkg/rootlessport/rootlessport_linux.go +++ b/pkg/rootlessport/rootlessport_linux.go @@ -160,6 +160,13 @@ func parent() error { return err } + childErrCh := make(chan error) + go func() { + err := cmd.Wait() + childErrCh <- err + close(childErrCh) + }() + defer func() { if err := syscall.Kill(cmd.Process.Pid, syscall.SIGTERM); err != nil { logrus.WithError(err).Warn("kill child process") @@ -174,6 +181,10 @@ outer: case <-initComplete: logrus.Infof("initComplete is closed; parent and child established the communication channel") break outer + case err := <-childErrCh: + if err != nil { + return err + } case err := <-errCh: if err != nil { return err diff --git a/pkg/systemd/generate/systemdgen.go b/pkg/systemd/generate/systemdgen.go index f2798819f..4cd7745c0 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 3c20dd8b9..9eb21e9ed 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` goodNameNewDetach := `# jadda-jadda.service # autogenerated by Podman CI diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go index b4e400549..240ef1627 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "strings" . "github.com/containers/libpod/test/utils" @@ -43,6 +44,15 @@ var _ = Describe("Podman build", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + iid := session.OutputToStringArray()[len(session.OutputToStringArray())-1] + + // Verify that OS and Arch are being set + inspect := podmanTest.PodmanNoCache([]string{"inspect", iid}) + inspect.WaitWithDefaultTimeout() + data := inspect.InspectImageJSON() + Expect(data[0].Os).To(Equal(runtime.GOOS)) + Expect(data[0].Architecture).To(Equal(runtime.GOARCH)) + session = podmanTest.PodmanNoCache([]string{"rmi", "alpine"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) 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/test/system/030-run.bats b/test/system/030-run.bats index b89c76981..98c65f788 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -136,21 +136,26 @@ echo $rand | 0 | $rand run_podman rmi busybox } -# 'run --rmi' deletes the image in the end unless it's used by another container. -@test "podman run --rmi - remove image" { - skip_if_remote "podman-remote does not emit 'Trying to pull' msgs" - run_podman 0 run --rmi --rm redis /bin/true - run_podman 1 image exists redis -} - - -@test "podman run --rmi - not remove image" { - skip_if_remote "podman-remote does not emit 'Trying to pull' msgs" - run_podman run redis /bin/true - run_podman images | grep redis - run_podman run --rmi --rm redis /bin/true - run_podman images | grep redis - run_podman 0 rm -a +# 'run --rmi' deletes the image in the end unless it's used by another container +@test "podman run --rmi" { + skip_if_remote + + # Name of a nonlocal image. It should be pulled in by the first 'run' + NONLOCAL_IMAGE=busybox + run_podman 1 image exists $NONLOCAL_IMAGE + + # Run a container, without --rm; this should block subsequent --rmi + run_podman run --name keepme $NONLOCAL_IMAGE /bin/true + run_podman image exists $NONLOCAL_IMAGE + + # Now try running with --rmi : it should succeed, but not remove the image + run_podman run --rmi --rm $NONLOCAL_IMAGE /bin/true + run_podman image exists $NONLOCAL_IMAGE + + # Remove the stray container, and run one more time with --rmi. + run_podman rm keepme + run_podman run --rmi --rm $NONLOCAL_IMAGE /bin/true + run_podman 1 image exists $NONLOCAL_IMAGE } # vim: filetype=sh diff --git a/troubleshooting.md b/troubleshooting.md index 0f9440799..010d33f81 100644 --- a/troubleshooting.md +++ b/troubleshooting.md @@ -390,7 +390,7 @@ Choose one of the following: * Complete the build operation as a privileged user. * Install and configure fuse-overlayfs. * Install the fuse-overlayfs package for your Linux Distribution. - * Add `mount_program = "/usr/bin/fuse-overlayfs` under `[storage.options]` in your `~/.config/containers/storage.conf` file. + * Add `mount_program = "/usr/bin/fuse-overlayfs"` under `[storage.options]` in your `~/.config/containers/storage.conf` file. ### 16) rhel7-init based images don't work with cgroups v2 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/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION index 41c11ffb7..c807441cf 100644 --- a/vendor/github.com/containers/storage/VERSION +++ b/vendor/github.com/containers/storage/VERSION @@ -1 +1 @@ -1.16.1 +1.16.3 diff --git a/vendor/github.com/containers/storage/drivers/chown.go b/vendor/github.com/containers/storage/drivers/chown.go index f2f1ec386..7604a86db 100644 --- a/vendor/github.com/containers/storage/drivers/chown.go +++ b/vendor/github.com/containers/storage/drivers/chown.go @@ -5,10 +5,10 @@ import ( "encoding/json" "fmt" "os" - "path/filepath" "github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/reexec" + "github.com/opencontainers/selinux/pkg/pwalk" ) const ( @@ -51,16 +51,13 @@ func chownByMapsMain() { if len(toHost.UIDs()) == 0 && len(toHost.GIDs()) == 0 { toHost = nil } - chown := func(path string, info os.FileInfo, err error) error { - if err != nil { - return fmt.Errorf("error walking to %q: %v", path, err) - } + chown := func(path string, info os.FileInfo, _ error) error { if path == "." { return nil } return platformLChown(path, info, toHost, toContainer) } - if err := filepath.Walk(".", chown); err != nil { + if err := pwalk.Walk(".", chown); err != nil { fmt.Fprintf(os.Stderr, "error during chown: %v", err) os.Exit(1) } diff --git a/vendor/github.com/containers/storage/drivers/chown_unix.go b/vendor/github.com/containers/storage/drivers/chown_unix.go index 94c641536..3a3978b71 100644 --- a/vendor/github.com/containers/storage/drivers/chown_unix.go +++ b/vendor/github.com/containers/storage/drivers/chown_unix.go @@ -12,66 +12,63 @@ import ( ) func platformLChown(path string, info os.FileInfo, toHost, toContainer *idtools.IDMappings) error { - sysinfo := info.Sys() - if st, ok := sysinfo.(*syscall.Stat_t); ok { - // Map an on-disk UID/GID pair from host to container - // using the first map, then back to the host using the - // second map. Skip that first step if they're 0, to - // compensate for cases where a parent layer should - // have had a mapped value, but didn't. - uid, gid := int(st.Uid), int(st.Gid) - if toContainer != nil { - pair := idtools.IDPair{ - UID: uid, - GID: gid, - } - mappedUID, mappedGID, err := toContainer.ToContainer(pair) - if err != nil { - if (uid != 0) || (gid != 0) { - return fmt.Errorf("error mapping host ID pair %#v for %q to container: %v", pair, path, err) - } - mappedUID, mappedGID = uid, gid - } - uid, gid = mappedUID, mappedGID + st, ok := info.Sys().(*syscall.Stat_t) + if !ok { + return nil + } + // Map an on-disk UID/GID pair from host to container + // using the first map, then back to the host using the + // second map. Skip that first step if they're 0, to + // compensate for cases where a parent layer should + // have had a mapped value, but didn't. + uid, gid := int(st.Uid), int(st.Gid) + if toContainer != nil { + pair := idtools.IDPair{ + UID: uid, + GID: gid, } - if toHost != nil { - pair := idtools.IDPair{ - UID: uid, - GID: gid, - } - mappedPair, err := toHost.ToHost(pair) - if err != nil { - return fmt.Errorf("error mapping container ID pair %#v for %q to host: %v", pair, path, err) + mappedUID, mappedGID, err := toContainer.ToContainer(pair) + if err != nil { + if (uid != 0) || (gid != 0) { + return fmt.Errorf("error mapping host ID pair %#v for %q to container: %v", pair, path, err) } - uid, gid = mappedPair.UID, mappedPair.GID + mappedUID, mappedGID = uid, gid + } + uid, gid = mappedUID, mappedGID + } + if toHost != nil { + pair := idtools.IDPair{ + UID: uid, + GID: gid, + } + mappedPair, err := toHost.ToHost(pair) + if err != nil { + return fmt.Errorf("error mapping container ID pair %#v for %q to host: %v", pair, path, err) + } + uid, gid = mappedPair.UID, mappedPair.GID + } + if uid != int(st.Uid) || gid != int(st.Gid) { + cap, err := system.Lgetxattr(path, "security.capability") + if err != nil && err != system.ErrNotSupportedPlatform { + return fmt.Errorf("%s: Lgetxattr(%q): %v", os.Args[0], path, err) } - if uid != int(st.Uid) || gid != int(st.Gid) { - stat, err := os.Lstat(path) - if err != nil { - return fmt.Errorf("%s: lstat(%q): %v", os.Args[0], path, err) - } - cap, err := system.Lgetxattr(path, "security.capability") - if err != nil && err != system.ErrNotSupportedPlatform { - return fmt.Errorf("%s: Lgetxattr(%q): %v", os.Args[0], path, err) - } - // Make the change. - if err := syscall.Lchown(path, uid, gid); err != nil { - return fmt.Errorf("%s: chown(%q): %v", os.Args[0], path, err) - } - // Restore the SUID and SGID bits if they were originally set. - if (stat.Mode()&os.ModeSymlink == 0) && stat.Mode()&(os.ModeSetuid|os.ModeSetgid) != 0 { - if err := os.Chmod(path, stat.Mode()); err != nil { - return fmt.Errorf("%s: chmod(%q): %v", os.Args[0], path, err) - } + // Make the change. + if err := syscall.Lchown(path, uid, gid); err != nil { + return fmt.Errorf("%s: chown(%q): %v", os.Args[0], path, err) + } + // Restore the SUID and SGID bits if they were originally set. + if (info.Mode()&os.ModeSymlink == 0) && info.Mode()&(os.ModeSetuid|os.ModeSetgid) != 0 { + if err := os.Chmod(path, info.Mode()); err != nil { + return fmt.Errorf("%s: chmod(%q): %v", os.Args[0], path, err) } - if cap != nil { - if err := system.Lsetxattr(path, "security.capability", cap, 0); err != nil { - return fmt.Errorf("%s: Lsetxattr(%q): %v", os.Args[0], path, err) - } + } + if cap != nil { + if err := system.Lsetxattr(path, "security.capability", cap, 0); err != nil { + return fmt.Errorf("%s: Lsetxattr(%q): %v", os.Args[0], path, err) } - } + } return nil } diff --git a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go index 867ad1196..d0c7fab0a 100644 --- a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go +++ b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go @@ -1209,7 +1209,7 @@ func (devices *DeviceSet) growFS(info *devInfo) error { options = joinMountOptions(options, devices.mountOptions) if err := mount.Mount(info.DevName(), fsMountPoint, devices.BaseDeviceFilesystem, options); err != nil { - return fmt.Errorf("Error mounting '%s' on '%s': %s\n%v", info.DevName(), fsMountPoint, err, string(dmesg.Dmesg(256))) + return errors.Wrapf(err, "Failed to mount; dmesg: %s", string(dmesg.Dmesg(256))) } defer unix.Unmount(fsMountPoint, unix.MNT_DETACH) @@ -2414,7 +2414,7 @@ func (devices *DeviceSet) MountDevice(hash, path string, moptions graphdriver.Mo options = joinMountOptions(options, label.FormatMountLabel("", moptions.MountLabel)) if err := mount.Mount(info.DevName(), path, fstype, options); err != nil { - return fmt.Errorf("devmapper: Error mounting '%s' on '%s': %s\n%v", info.DevName(), path, err, string(dmesg.Dmesg(256))) + return errors.Wrapf(err, "Failed to mount; dmesg: %s", string(dmesg.Dmesg(256))) } if fstype == xfs && devices.xfsNospaceRetries != "" { diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod index 073bb7d2b..84bfc9616 100644 --- a/vendor/github.com/containers/storage/go.mod +++ b/vendor/github.com/containers/storage/go.mod @@ -2,23 +2,19 @@ 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 github.com/opencontainers/go-digest v1.0.0-rc1 github.com/opencontainers/runc v1.0.0-rc9 - github.com/opencontainers/selinux v1.3.3 + github.com/opencontainers/selinux v1.4.0 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..5d86e062f 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/opencontainers/selinux v1.4.0 h1:cpiX/2wWIju/6My60T6/z9CxNG7c8xTQyEmA9fChpUo= +github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= 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/mount/flags_freebsd.go b/vendor/github.com/containers/storage/pkg/mount/flags_freebsd.go deleted file mode 100644 index 5f76f331b..000000000 --- a/vendor/github.com/containers/storage/pkg/mount/flags_freebsd.go +++ /dev/null @@ -1,49 +0,0 @@ -// +build freebsd,cgo - -package mount - -/* -#include <sys/mount.h> -*/ -import "C" - -const ( - // RDONLY will mount the filesystem as read-only. - RDONLY = C.MNT_RDONLY - - // NOSUID will not allow set-user-identifier or set-group-identifier bits to - // take effect. - NOSUID = C.MNT_NOSUID - - // NOEXEC will not allow execution of any binaries on the mounted file system. - NOEXEC = C.MNT_NOEXEC - - // SYNCHRONOUS will allow any I/O to the file system to be done synchronously. - SYNCHRONOUS = C.MNT_SYNCHRONOUS - - // NOATIME will not update the file access time when reading from a file. - NOATIME = C.MNT_NOATIME -) - -// These flags are unsupported. -const ( - BIND = 0 - DIRSYNC = 0 - MANDLOCK = 0 - NODEV = 0 - NODIRATIME = 0 - UNBINDABLE = 0 - RUNBINDABLE = 0 - PRIVATE = 0 - RPRIVATE = 0 - SHARED = 0 - RSHARED = 0 - SLAVE = 0 - RSLAVE = 0 - RBIND = 0 - RELATIVE = 0 - RELATIME = 0 - REMOUNT = 0 - STRICTATIME = 0 - mntDetach = 0 -) diff --git a/vendor/github.com/containers/storage/pkg/mount/flags_linux.go b/vendor/github.com/containers/storage/pkg/mount/flags_linux.go index a5dc5e287..0425d0dd6 100644 --- a/vendor/github.com/containers/storage/pkg/mount/flags_linux.go +++ b/vendor/github.com/containers/storage/pkg/mount/flags_linux.go @@ -82,4 +82,6 @@ const ( // it possible for the kernel to default to relatime or noatime but still // allow userspace to override it. STRICTATIME = unix.MS_STRICTATIME + + mntDetach = unix.MNT_DETACH ) diff --git a/vendor/github.com/containers/storage/pkg/mount/flags_unsupported.go b/vendor/github.com/containers/storage/pkg/mount/flags_unsupported.go index 9ed741e3f..9afd26d4c 100644 --- a/vendor/github.com/containers/storage/pkg/mount/flags_unsupported.go +++ b/vendor/github.com/containers/storage/pkg/mount/flags_unsupported.go @@ -1,4 +1,4 @@ -// +build !linux,!freebsd freebsd,!cgo solaris,!cgo +// +build !linux package mount diff --git a/vendor/github.com/containers/storage/pkg/mount/mount.go b/vendor/github.com/containers/storage/pkg/mount/mount.go index 7197448da..4276d63af 100644 --- a/vendor/github.com/containers/storage/pkg/mount/mount.go +++ b/vendor/github.com/containers/storage/pkg/mount/mount.go @@ -2,12 +2,47 @@ package mount import ( "sort" + "strconv" "strings" - "time" "github.com/containers/storage/pkg/fileutils" ) +// mountError holds an error from a mount or unmount operation +type mountError struct { + op string + source, target string + flags uintptr + data string + err error +} + +// Error returns a string representation of mountError +func (e *mountError) Error() string { + out := e.op + " " + + if e.source != "" { + out += e.source + ":" + e.target + } else { + out += e.target + } + + if e.flags != uintptr(0) { + out += ", flags: 0x" + strconv.FormatUint(uint64(e.flags), 16) + } + if e.data != "" { + out += ", data: " + e.data + } + + out += ": " + e.err.Error() + return out +} + +// Cause returns the underlying cause of the error +func (e *mountError) Cause() error { + return e.err +} + // GetMounts retrieves a list of mounts for the current running process. func GetMounts() ([]*Info, error) { return parseMountTable() @@ -39,13 +74,13 @@ func Mounted(mountpoint string) (bool, error) { // specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See // flags.go for supported option flags. func Mount(device, target, mType, options string) error { - flag, _ := ParseOptions(options) + flag, data := ParseOptions(options) if flag&REMOUNT != REMOUNT { if mounted, err := Mounted(target); err != nil || mounted { return err } } - return ForceMount(device, target, mType, options) + return mount(device, target, mType, uintptr(flag), data) } // ForceMount will mount a filesystem according to the specified configuration, @@ -60,14 +95,11 @@ func ForceMount(device, target, mType, options string) error { // Unmount lazily unmounts a filesystem on supported platforms, otherwise // does a normal unmount. func Unmount(target string) error { - if mounted, err := Mounted(target); err != nil || !mounted { - return err - } - return ForceUnmount(target) + return unmount(target, mntDetach) } // RecursiveUnmount unmounts the target and all mounts underneath, starting with -// the deepsest mount first. +// the deepest mount first. func RecursiveUnmount(target string) error { mounts, err := GetMounts() if err != nil { @@ -75,16 +107,16 @@ func RecursiveUnmount(target string) error { } // Make the deepest mount be first - sort.Sort(sort.Reverse(byMountpoint(mounts))) + sort.Slice(mounts, func(i, j int) bool { + return len(mounts[i].Mountpoint) > len(mounts[j].Mountpoint) + }) for i, m := range mounts { if !strings.HasPrefix(m.Mountpoint, target) { continue } if err := Unmount(m.Mountpoint); err != nil && i == len(mounts)-1 { - if mounted, err := Mounted(m.Mountpoint); err != nil || mounted { - return err - } + return err // Ignore errors for submounts and continue trying to unmount others // The final unmount should fail if there ane any submounts remaining } @@ -92,15 +124,10 @@ func RecursiveUnmount(target string) error { return nil } -// ForceUnmount will force an unmount of the target filesystem, regardless if -// it is mounted or not. -func ForceUnmount(target string) (err error) { - // Simple retry logic for unmount - for i := 0; i < 10; i++ { - if err = unmount(target, 0); err == nil { - return nil - } - time.Sleep(100 * time.Millisecond) - } - return nil +// ForceUnmount lazily unmounts a filesystem on supported platforms, +// otherwise does a normal unmount. +// +// Deprecated: please use Unmount instead, it is identical. +func ForceUnmount(target string) error { + return unmount(target, mntDetach) } diff --git a/vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go b/vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go index 814896cc9..b31cf99d0 100644 --- a/vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go +++ b/vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go @@ -14,8 +14,6 @@ import ( "fmt" "strings" "unsafe" - - "golang.org/x/sys/unix" ) func allocateIOVecs(options []string) []C.struct_iovec { @@ -54,7 +52,3 @@ func mount(device, target, mType string, flag uintptr, data string) error { } return nil } - -func unmount(target string, flag int) error { - return unix.Unmount(target, flag) -} diff --git a/vendor/github.com/containers/storage/pkg/mount/mounter_linux.go b/vendor/github.com/containers/storage/pkg/mount/mounter_linux.go index de47c7af8..594cd0881 100644 --- a/vendor/github.com/containers/storage/pkg/mount/mounter_linux.go +++ b/vendor/github.com/containers/storage/pkg/mount/mounter_linux.go @@ -35,25 +35,40 @@ func mount(device, target, mType string, flags uintptr, data string) error { // Initial call applying all non-propagation flags for mount // or remount with changed data if err := unix.Mount(device, target, mType, oflags, data); err != nil { - return err + return &mountError{ + op: "mount", + source: device, + target: target, + flags: oflags, + data: data, + err: err, + } } } if flags&ptypes != 0 { // Change the propagation type. if err := unix.Mount("", target, "", flags&pflags, ""); err != nil { - return err + return &mountError{ + op: "remount", + target: target, + flags: flags & pflags, + err: err, + } } } if oflags&broflags == broflags { // Remount the bind to apply read only. - return unix.Mount("", target, "", oflags|unix.MS_REMOUNT, "") + if err := unix.Mount("", target, "", oflags|unix.MS_REMOUNT, ""); err != nil { + return &mountError{ + op: "remount-ro", + target: target, + flags: oflags | unix.MS_REMOUNT, + err: err, + } + } } return nil } - -func unmount(target string, flag int) error { - return unix.Unmount(target, flag) -} diff --git a/vendor/github.com/containers/storage/pkg/mount/mounter_solaris.go b/vendor/github.com/containers/storage/pkg/mount/mounter_solaris.go deleted file mode 100644 index 48b86771e..000000000 --- a/vendor/github.com/containers/storage/pkg/mount/mounter_solaris.go +++ /dev/null @@ -1,34 +0,0 @@ -// +build solaris,cgo - -package mount - -import ( - "unsafe" - - "golang.org/x/sys/unix" -) - -// #include <stdlib.h> -// #include <stdio.h> -// #include <sys/mount.h> -// int Mount(const char *spec, const char *dir, int mflag, -// char *fstype, char *dataptr, int datalen, char *optptr, int optlen) { -// return mount(spec, dir, mflag, fstype, dataptr, datalen, optptr, optlen); -// } -import "C" - -func mount(device, target, mType string, flag uintptr, data string) error { - spec := C.CString(device) - dir := C.CString(target) - fstype := C.CString(mType) - _, err := C.Mount(spec, dir, C.int(flag), fstype, nil, 0, nil, 0) - C.free(unsafe.Pointer(spec)) - C.free(unsafe.Pointer(dir)) - C.free(unsafe.Pointer(fstype)) - return err -} - -func unmount(target string, flag int) error { - err := unix.Unmount(target, flag) - return err -} diff --git a/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go b/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go index a2a3bb457..42d1d422c 100644 --- a/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go +++ b/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go @@ -1,11 +1,7 @@ -// +build !linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo +// +build !linux package mount func mount(device, target, mType string, flag uintptr, data string) error { panic("Not implemented") } - -func unmount(target string, flag int) error { - panic("Not implemented") -} diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo.go index ff4cc1d86..e3fc3535e 100644 --- a/vendor/github.com/containers/storage/pkg/mount/mountinfo.go +++ b/vendor/github.com/containers/storage/pkg/mount/mountinfo.go @@ -38,17 +38,3 @@ type Info struct { // VfsOpts represents per super block options. VfsOpts string } - -type byMountpoint []*Info - -func (by byMountpoint) Len() int { - return len(by) -} - -func (by byMountpoint) Less(i, j int) bool { - return by[i].Mountpoint < by[j].Mountpoint -} - -func (by byMountpoint) Swap(i, j int) { - by[i], by[j] = by[j], by[i] -} diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go index be69fee1d..19556d06b 100644 --- a/vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go +++ b/vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go @@ -1,5 +1,3 @@ -// +build linux - package mount import ( @@ -7,25 +5,10 @@ import ( "fmt" "io" "os" + "strconv" "strings" -) -const ( - /* 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue - (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11) - - (1) mount ID: unique identifier of the mount (may be reused after umount) - (2) parent ID: ID of parent (or of self for the top of the mount tree) - (3) major:minor: value of st_dev for files on filesystem - (4) root: root of the mount within the filesystem - (5) mount point: mount point relative to the process's root - (6) mount options: per mount options - (7) optional fields: zero or more fields of the form "tag[:value]" - (8) separator: marks the end of the optional fields - (9) filesystem type: name of filesystem of the form "type[.subtype]" - (10) mount source: filesystem specific information or "none" - (11) super options: per super block options*/ - mountinfoFormat = "%d %d %d:%d %s %s %s %s" + "github.com/pkg/errors" ) // Parse /proc/self/mountinfo because comparing Dev and ino does not work from @@ -41,43 +24,85 @@ func parseMountTable() ([]*Info, error) { } func parseInfoFile(r io.Reader) ([]*Info, error) { - var ( - s = bufio.NewScanner(r) - out = []*Info{} - ) + s := bufio.NewScanner(r) + out := []*Info{} for s.Scan() { - if err := s.Err(); err != nil { - return nil, err + /* + 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue + (0)(1)(2) (3) (4) (5) (6) (7) (8) (9) (10) + + (0) mount ID: unique identifier of the mount (may be reused after umount) + (1) parent ID: ID of parent (or of self for the top of the mount tree) + (2) major:minor: value of st_dev for files on filesystem + (3) root: root of the mount within the filesystem + (4) mount point: mount point relative to the process's root + (5) mount options: per mount options + (6) optional fields: zero or more fields of the form "tag[:value]" + (7) separator: marks the end of the optional fields + (8) filesystem type: name of filesystem of the form "type[.subtype]" + (9) mount source: filesystem specific information or "none" + (10) super options: per super block options + */ + text := s.Text() + fields := strings.Split(text, " ") + numFields := len(fields) + if numFields < 10 { + // should be at least 10 fields + return nil, errors.Errorf("Parsing %q failed: not enough fields (%d)", text, numFields) } - var ( - p = &Info{} - text = s.Text() - optionalFields string - ) + p := &Info{} + // ignore any number parsing errors, there should not be any + p.ID, _ = strconv.Atoi(fields[0]) + p.Parent, _ = strconv.Atoi(fields[1]) + mm := strings.Split(fields[2], ":") + if len(mm) != 2 { + return nil, fmt.Errorf("Parsing %q failed: unexpected minor:major pair %s", text, mm) + } + p.Major, _ = strconv.Atoi(mm[0]) + p.Minor, _ = strconv.Atoi(mm[1]) + p.Root = fields[3] + p.Mountpoint = fields[4] + p.Opts = fields[5] - if _, err := fmt.Sscanf(text, mountinfoFormat, - &p.ID, &p.Parent, &p.Major, &p.Minor, - &p.Root, &p.Mountpoint, &p.Opts, &optionalFields); err != nil { - return nil, fmt.Errorf("Scanning '%s' failed: %s", text, err) + // one or more optional fields, when a separator (-) + i := 6 + for ; i < numFields && fields[i] != "-"; i++ { + switch i { + case 6: + p.Optional = string(fields[6]) + default: + /* NOTE there might be more optional fields before the separator, + such as fields[7] or fields[8], although as of Linux kernel 5.5 + the only known ones are mount propagation flags in fields[6]. + The correct behavior is to ignore any unknown optional fields. + */ + } } - // Safe as mountinfo encodes mountpoints with spaces as \040. - index := strings.Index(text, " - ") - postSeparatorFields := strings.Fields(text[index+3:]) - if len(postSeparatorFields) < 3 { - return nil, fmt.Errorf("Error found less than 3 fields post '-' in %q", text) + if i == numFields { + return nil, fmt.Errorf("Parsing %q failed: missing - separator", text) } - if optionalFields != "-" { - p.Optional = optionalFields + // There should be 3 fields after the separator... + if i+4 > numFields { + return nil, fmt.Errorf("Parsing %q failed: not enough fields after a - separator", text) } + // ... but in Linux <= 3.9 mounting a cifs with spaces in a share name + // (like "//serv/My Documents") _may_ end up having a space in the last field + // of mountinfo (like "unc=//serv/My Documents"). Since kernel 3.10-rc1, cifs + // option unc= is ignored, so a space should not appear. In here we ignore + // those "extra" fields caused by extra spaces. + p.Fstype = fields[i+1] + p.Source = fields[i+2] + p.VfsOpts = fields[i+3] - p.Fstype = postSeparatorFields[0] - p.Source = postSeparatorFields[1] - p.VfsOpts = strings.Join(postSeparatorFields[2:], " ") out = append(out, p) } + if err := s.Err(); err != nil { + return nil, err + } + return out, nil } diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo_solaris.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo_solaris.go deleted file mode 100644 index ad9ab57f8..000000000 --- a/vendor/github.com/containers/storage/pkg/mount/mountinfo_solaris.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build solaris,cgo - -package mount - -/* -#include <stdio.h> -#include <sys/mnttab.h> -*/ -import "C" - -import ( - "fmt" -) - -func parseMountTable() ([]*Info, error) { - mnttab := C.fopen(C.CString(C.MNTTAB), C.CString("r")) - if mnttab == nil { - return nil, fmt.Errorf("Failed to open %s", C.MNTTAB) - } - - var out []*Info - var mp C.struct_mnttab - - ret := C.getmntent(mnttab, &mp) - for ret == 0 { - var mountinfo Info - mountinfo.Mountpoint = C.GoString(mp.mnt_mountp) - mountinfo.Source = C.GoString(mp.mnt_special) - mountinfo.Fstype = C.GoString(mp.mnt_fstype) - mountinfo.Opts = C.GoString(mp.mnt_mntopts) - out = append(out, &mountinfo) - ret = C.getmntent(mnttab, &mp) - } - - C.fclose(mnttab) - return out, nil -} diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go index 7fbcf1921..6cde1ed77 100644 --- a/vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go +++ b/vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go @@ -1,4 +1,4 @@ -// +build !windows,!linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo +// +build !linux package mount diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo_windows.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo_windows.go deleted file mode 100644 index dab8a37ed..000000000 --- a/vendor/github.com/containers/storage/pkg/mount/mountinfo_windows.go +++ /dev/null @@ -1,6 +0,0 @@ -package mount - -func parseMountTable() ([]*Info, error) { - // Do NOT return an error! - return nil, nil -} diff --git a/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_linux.go b/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_linux.go index 8ceec84bc..80922ad5c 100644 --- a/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_linux.go +++ b/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_linux.go @@ -1,69 +1,64 @@ -// +build linux - package mount // MakeShared ensures a mounted filesystem has the SHARED mount option enabled. // See the supported options in flags.go for further reference. func MakeShared(mountPoint string) error { - return ensureMountedAs(mountPoint, "shared") + return ensureMountedAs(mountPoint, SHARED) } // MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled. // See the supported options in flags.go for further reference. func MakeRShared(mountPoint string) error { - return ensureMountedAs(mountPoint, "rshared") + return ensureMountedAs(mountPoint, RSHARED) } // MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled. // See the supported options in flags.go for further reference. func MakePrivate(mountPoint string) error { - return ensureMountedAs(mountPoint, "private") + return ensureMountedAs(mountPoint, PRIVATE) } // MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option // enabled. See the supported options in flags.go for further reference. func MakeRPrivate(mountPoint string) error { - return ensureMountedAs(mountPoint, "rprivate") + return ensureMountedAs(mountPoint, RPRIVATE) } // MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled. // See the supported options in flags.go for further reference. func MakeSlave(mountPoint string) error { - return ensureMountedAs(mountPoint, "slave") + return ensureMountedAs(mountPoint, SLAVE) } // MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled. // See the supported options in flags.go for further reference. func MakeRSlave(mountPoint string) error { - return ensureMountedAs(mountPoint, "rslave") + return ensureMountedAs(mountPoint, RSLAVE) } // MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option // enabled. See the supported options in flags.go for further reference. func MakeUnbindable(mountPoint string) error { - return ensureMountedAs(mountPoint, "unbindable") + return ensureMountedAs(mountPoint, UNBINDABLE) } // MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount // option enabled. See the supported options in flags.go for further reference. func MakeRUnbindable(mountPoint string) error { - return ensureMountedAs(mountPoint, "runbindable") + return ensureMountedAs(mountPoint, RUNBINDABLE) } -func ensureMountedAs(mountPoint, options string) error { - mounted, err := Mounted(mountPoint) +func ensureMountedAs(mnt string, flags int) error { + mounted, err := Mounted(mnt) if err != nil { return err } if !mounted { - if err := Mount(mountPoint, mountPoint, "none", "bind,rw"); err != nil { + if err := mount(mnt, mnt, "none", uintptr(BIND), ""); err != nil { return err } } - if _, err = Mounted(mountPoint); err != nil { - return err - } - return ForceMount("", mountPoint, "none", options) + return mount("", mnt, "none", uintptr(flags), "") } diff --git a/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_solaris.go b/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_solaris.go deleted file mode 100644 index 09f6b03cb..000000000 --- a/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_solaris.go +++ /dev/null @@ -1,58 +0,0 @@ -// +build solaris - -package mount - -// MakeShared ensures a mounted filesystem has the SHARED mount option enabled. -// See the supported options in flags.go for further reference. -func MakeShared(mountPoint string) error { - return ensureMountedAs(mountPoint, "shared") -} - -// MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled. -// See the supported options in flags.go for further reference. -func MakeRShared(mountPoint string) error { - return ensureMountedAs(mountPoint, "rshared") -} - -// MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled. -// See the supported options in flags.go for further reference. -func MakePrivate(mountPoint string) error { - return ensureMountedAs(mountPoint, "private") -} - -// MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option -// enabled. See the supported options in flags.go for further reference. -func MakeRPrivate(mountPoint string) error { - return ensureMountedAs(mountPoint, "rprivate") -} - -// MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled. -// See the supported options in flags.go for further reference. -func MakeSlave(mountPoint string) error { - return ensureMountedAs(mountPoint, "slave") -} - -// MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled. -// See the supported options in flags.go for further reference. -func MakeRSlave(mountPoint string) error { - return ensureMountedAs(mountPoint, "rslave") -} - -// MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option -// enabled. See the supported options in flags.go for further reference. -func MakeUnbindable(mountPoint string) error { - return ensureMountedAs(mountPoint, "unbindable") -} - -// MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount -// option enabled. See the supported options in flags.go for further reference. -func MakeRUnbindable(mountPoint string) error { - return ensureMountedAs(mountPoint, "runbindable") -} - -func ensureMountedAs(mountPoint, options string) error { - // TODO: Solaris does not support bind mounts. - // Evaluate lofs and also look at the relevant - // mount flags to be supported. - return nil -} diff --git a/vendor/github.com/containers/storage/pkg/mount/unmount_unix.go b/vendor/github.com/containers/storage/pkg/mount/unmount_unix.go new file mode 100644 index 000000000..1d1afeee2 --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/mount/unmount_unix.go @@ -0,0 +1,22 @@ +// +build !windows + +package mount + +import "golang.org/x/sys/unix" + +func unmount(target string, flags int) error { + err := unix.Unmount(target, flags) + if err == nil || err == unix.EINVAL { + // Ignore "not mounted" error here. Note the same error + // can be returned if flags are invalid, so this code + // assumes that the flags value is always correct. + return nil + } + + return &mountError{ + op: "umount", + target: target, + flags: uintptr(flags), + err: err, + } +} diff --git a/vendor/github.com/containers/storage/pkg/mount/unmount_unsupported.go b/vendor/github.com/containers/storage/pkg/mount/unmount_unsupported.go new file mode 100644 index 000000000..eebc4ab84 --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/mount/unmount_unsupported.go @@ -0,0 +1,7 @@ +// +build windows + +package mount + +func unmount(target string, flag int) error { + panic("Not implemented") +} diff --git a/vendor/github.com/containers/storage/pkg/system/lstat_unix.go b/vendor/github.com/containers/storage/pkg/system/lstat_unix.go index bd23c4d50..e9d301f09 100644 --- a/vendor/github.com/containers/storage/pkg/system/lstat_unix.go +++ b/vendor/github.com/containers/storage/pkg/system/lstat_unix.go @@ -3,6 +3,7 @@ package system import ( + "os" "syscall" ) @@ -13,7 +14,7 @@ import ( func Lstat(path string) (*StatT, error) { s := &syscall.Stat_t{} if err := syscall.Lstat(path, s); err != nil { - return nil, err + return nil, &os.PathError{"Lstat", path, err} } return fromStatT(s) } diff --git a/vendor/github.com/containers/storage/pkg/system/rm.go b/vendor/github.com/containers/storage/pkg/system/rm.go index b1599d23f..618c1dc75 100644 --- a/vendor/github.com/containers/storage/pkg/system/rm.go +++ b/vendor/github.com/containers/storage/pkg/system/rm.go @@ -34,7 +34,7 @@ func EnsureRemoveAll(dir string) error { for { err := os.RemoveAll(dir) if err == nil { - return err + return nil } pe, ok := err.(*os.PathError) @@ -63,12 +63,8 @@ func EnsureRemoveAll(dir string) error { return err } - if mounted, _ := mount.Mounted(pe.Path); mounted { - if e := mount.Unmount(pe.Path); e != nil { - if mounted, _ := mount.Mounted(pe.Path); mounted { - return errors.Wrapf(e, "error while removing %s", dir) - } - } + if e := mount.Unmount(pe.Path); e != nil { + return errors.Wrapf(e, "error while removing %s", dir) } if exitOnErr[pe.Path] == maxRetry { diff --git a/vendor/github.com/containers/storage/pkg/system/stat_unix.go b/vendor/github.com/containers/storage/pkg/system/stat_unix.go index f9a1b4877..2fac918bf 100644 --- a/vendor/github.com/containers/storage/pkg/system/stat_unix.go +++ b/vendor/github.com/containers/storage/pkg/system/stat_unix.go @@ -3,6 +3,8 @@ package system import ( + "os" + "strconv" "syscall" ) @@ -54,7 +56,7 @@ func (s StatT) Mtim() syscall.Timespec { func Stat(path string) (*StatT, error) { s := &syscall.Stat_t{} if err := syscall.Stat(path, s); err != nil { - return nil, err + return nil, &os.PathError{Op: "Stat", Path: path, Err: err} } return fromStatT(s) } @@ -66,7 +68,7 @@ func Stat(path string) (*StatT, error) { func Fstat(fd int) (*StatT, error) { s := &syscall.Stat_t{} if err := syscall.Fstat(fd, s); err != nil { - return nil, err + return nil, &os.PathError{Op: "Fstat", Path: strconv.Itoa(fd), Err: err} } return fromStatT(s) } 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/fsnotify/fsnotify/.editorconfig b/vendor/github.com/fsnotify/fsnotify/.editorconfig index ba49e3c23..fad895851 100644 --- a/vendor/github.com/fsnotify/fsnotify/.editorconfig +++ b/vendor/github.com/fsnotify/fsnotify/.editorconfig @@ -1,5 +1,12 @@ root = true -[*] +[*.go] indent_style = tab indent_size = 4 +insert_final_newline = true + +[*.{yml,yaml}] +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/vendor/github.com/fsnotify/fsnotify/.gitattributes b/vendor/github.com/fsnotify/fsnotify/.gitattributes new file mode 100644 index 000000000..32f1001be --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/.gitattributes @@ -0,0 +1 @@ +go.sum linguist-generated diff --git a/vendor/github.com/fsnotify/fsnotify/.travis.yml b/vendor/github.com/fsnotify/fsnotify/.travis.yml index 981d1bb81..a9c30165c 100644 --- a/vendor/github.com/fsnotify/fsnotify/.travis.yml +++ b/vendor/github.com/fsnotify/fsnotify/.travis.yml @@ -2,29 +2,35 @@ sudo: false language: go go: - - 1.8.x - - 1.9.x - - tip + - "stable" + - "1.11.x" + - "1.10.x" + - "1.9.x" matrix: + include: + - go: "stable" + env: GOLINT=true allow_failures: - go: tip fast_finish: true -before_script: - - go get -u github.com/golang/lint/golint + +before_install: + - if [ ! -z "${GOLINT}" ]; then go get -u golang.org/x/lint/golint; fi script: - - go test -v --race ./... + - go test --race ./... after_script: - test -z "$(gofmt -s -l -w . | tee /dev/stderr)" - - test -z "$(golint ./... | tee /dev/stderr)" + - if [ ! -z "${GOLINT}" ]; then echo running golint; golint --set_exit_status ./...; else echo skipping golint; fi - go vet ./... os: - linux - osx + - windows notifications: email: false diff --git a/vendor/github.com/fsnotify/fsnotify/LICENSE b/vendor/github.com/fsnotify/fsnotify/LICENSE index f21e54080..e180c8fb0 100644 --- a/vendor/github.com/fsnotify/fsnotify/LICENSE +++ b/vendor/github.com/fsnotify/fsnotify/LICENSE @@ -1,5 +1,5 @@ Copyright (c) 2012 The Go Authors. All rights reserved. -Copyright (c) 2012 fsnotify Authors. All rights reserved. +Copyright (c) 2012-2019 fsnotify Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/vendor/github.com/fsnotify/fsnotify/README.md b/vendor/github.com/fsnotify/fsnotify/README.md index 399320741..b2629e522 100644 --- a/vendor/github.com/fsnotify/fsnotify/README.md +++ b/vendor/github.com/fsnotify/fsnotify/README.md @@ -10,16 +10,16 @@ go get -u golang.org/x/sys/... Cross platform: Windows, Linux, BSD and macOS. -|Adapter |OS |Status | -|----------|----------|----------| -|inotify |Linux 2.6.27 or later, Android\*|Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify)| -|kqueue |BSD, macOS, iOS\*|Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify)| -|ReadDirectoryChangesW|Windows|Supported [![Build status](https://ci.appveyor.com/api/projects/status/ivwjubaih4r0udeh/branch/master?svg=true)](https://ci.appveyor.com/project/NathanYoungman/fsnotify/branch/master)| -|FSEvents |macOS |[Planned](https://github.com/fsnotify/fsnotify/issues/11)| -|FEN |Solaris 11 |[In Progress](https://github.com/fsnotify/fsnotify/issues/12)| -|fanotify |Linux 2.6.37+ | | -|USN Journals |Windows |[Maybe](https://github.com/fsnotify/fsnotify/issues/53)| -|Polling |*All* |[Maybe](https://github.com/fsnotify/fsnotify/issues/9)| +| Adapter | OS | Status | +| --------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| inotify | Linux 2.6.27 or later, Android\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) | +| kqueue | BSD, macOS, iOS\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) | +| ReadDirectoryChangesW | Windows | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) | +| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) | +| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/issues/12) | +| fanotify | Linux 2.6.37+ | [Planned](https://github.com/fsnotify/fsnotify/issues/114) | +| USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) | +| Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) | \* Android and iOS are untested. @@ -33,6 +33,53 @@ All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based o Go 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project, and likewise for `golang.org/x/sys`. +## Usage + +```go +package main + +import ( + "log" + + "github.com/fsnotify/fsnotify" +) + +func main() { + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Fatal(err) + } + defer watcher.Close() + + done := make(chan bool) + go func() { + for { + select { + case event, ok := <-watcher.Events: + if !ok { + return + } + log.Println("event:", event) + if event.Op&fsnotify.Write == fsnotify.Write { + log.Println("modified file:", event.Name) + } + case err, ok := <-watcher.Errors: + if !ok { + return + } + log.Println("error:", err) + } + } + }() + + err = watcher.Add("/tmp/foo") + if err != nil { + log.Fatal(err) + } + <-done +} +``` + ## Contributing Please refer to [CONTRIBUTING][] before opening an issue or pull request. @@ -65,6 +112,10 @@ There are OS-specific limits as to how many watches can be created: * Linux: /proc/sys/fs/inotify/max_user_watches contains the limit, reaching this limit results in a "no space left on device" error. * BSD / OSX: sysctl variables "kern.maxfiles" and "kern.maxfilesperproc", reaching these limits results in a "too many open files" error. +**Why don't notifications work with NFS filesystems or filesystem in userspace (FUSE)?** + +fsnotify requires support from underlying OS to work. The current NFS protocol does not provide network level support for file notifications. + [#62]: https://github.com/howeyc/fsnotify/issues/62 [#18]: https://github.com/fsnotify/fsnotify/issues/18 [#11]: https://github.com/fsnotify/fsnotify/issues/11 diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/vendor/github.com/fsnotify/fsnotify/fsnotify.go index 190bf0de5..89cab046d 100644 --- a/vendor/github.com/fsnotify/fsnotify/fsnotify.go +++ b/vendor/github.com/fsnotify/fsnotify/fsnotify.go @@ -63,4 +63,6 @@ func (e Event) String() string { } // Common errors that can be reported by a watcher -var ErrEventOverflow = errors.New("fsnotify queue overflow") +var ( + ErrEventOverflow = errors.New("fsnotify queue overflow") +) diff --git a/vendor/github.com/fsnotify/fsnotify/go.mod b/vendor/github.com/fsnotify/fsnotify/go.mod new file mode 100644 index 000000000..ff11e13f2 --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/go.mod @@ -0,0 +1,5 @@ +module github.com/fsnotify/fsnotify + +go 1.13 + +require golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 diff --git a/vendor/github.com/fsnotify/fsnotify/go.sum b/vendor/github.com/fsnotify/fsnotify/go.sum new file mode 100644 index 000000000..f60af9855 --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go index cc7db4b22..b33f2b4d4 100644 --- a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go +++ b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go @@ -40,12 +40,12 @@ func newFdPoller(fd int) (*fdPoller, error) { poller.fd = fd // Create epoll fd - poller.epfd, errno = unix.EpollCreate1(0) + poller.epfd, errno = unix.EpollCreate1(unix.EPOLL_CLOEXEC) if poller.epfd == -1 { return nil, errno } // Create pipe; pipe[0] is the read end, pipe[1] the write end. - errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK) + errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK|unix.O_CLOEXEC) if errno != nil { return nil, errno } diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go index 7d8de1451..2306c4620 100644 --- a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go +++ b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go @@ -8,4 +8,4 @@ package fsnotify import "golang.org/x/sys/unix" -const openMode = unix.O_NONBLOCK | unix.O_RDONLY +const openMode = unix.O_NONBLOCK | unix.O_RDONLY | unix.O_CLOEXEC diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go index 9139e1716..870c4d6d1 100644 --- a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go +++ b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go @@ -9,4 +9,4 @@ package fsnotify import "golang.org/x/sys/unix" // note: this constant is not defined on BSD -const openMode = unix.O_EVTONLY +const openMode = unix.O_EVTONLY | unix.O_CLOEXEC 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/github.com/opencontainers/selinux/go-selinux/label/label.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go index e178568fd..6e38d3d32 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go @@ -1,109 +1,77 @@ -// +build !selinux !linux - package label -// InitLabels returns the process label and file labels to be used within -// the container. A list of options can be passed into this function to alter -// the labels. -func InitLabels(options []string) (string, string, error) { - return "", "", nil -} - -func ROMountLabel() string { - return "" -} - -func GenLabels(options string) (string, string, error) { - return "", "", nil -} +import ( + "github.com/opencontainers/selinux/go-selinux" +) -func FormatMountLabel(src string, mountLabel string) string { - return src -} +// Deprecated: use selinux.ROFileLabel +var ROMountLabel = selinux.ROFileLabel -func SetProcessLabel(processLabel string) error { - return nil -} +// SetProcessLabel takes a process label and tells the kernel to assign the +// label to the next program executed by the current process. +// Deprecated: use selinux.SetExecLabel +var SetProcessLabel = selinux.SetExecLabel -func ProcessLabel() (string, error) { - return "", nil -} +// ProcessLabel returns the process label that the kernel will assign +// to the next program executed by the current process. If "" is returned +// this indicates that the default labeling will happen for the process. +// Deprecated: use selinux.ExecLabel +var ProcessLabel = selinux.ExecLabel -func SetSocketLabel(processLabel string) error { - return nil -} +// SetSocketLabel takes a process label and tells the kernel to assign the +// label to the next socket that gets created +// Deprecated: use selinux.SetSocketLabel +var SetSocketLabel = selinux.SetSocketLabel -func SocketLabel() (string, error) { - return "", nil -} +// SocketLabel retrieves the current default socket label setting +// Deprecated: use selinux.SocketLabel +var SocketLabel = selinux.SocketLabel -func SetKeyLabel(processLabel string) error { - return nil -} +// SetKeyLabel takes a process label and tells the kernel to assign the +// label to the next kernel keyring that gets created +// Deprecated: use selinux.SetKeyLabel +var SetKeyLabel = selinux.SetKeyLabel -func KeyLabel() (string, error) { - return "", nil -} +// KeyLabel retrieves the current default kernel keyring label setting +// Deprecated: use selinux.KeyLabel +var KeyLabel = selinux.KeyLabel -func FileLabel(path string) (string, error) { - return "", nil -} +// FileLabel returns the label for specified path +// Deprecated: use selinux.FileLabel +var FileLabel = selinux.FileLabel -func SetFileLabel(path string, fileLabel string) error { - return nil -} - -func SetFileCreateLabel(fileLabel string) error { - return nil -} - -func Relabel(path string, fileLabel string, shared bool) error { - return nil -} - -func PidLabel(pid int) (string, error) { - return "", nil -} +// PidLabel will return the label of the process running with the specified pid +// Deprecated: use selinux.PidLabel +var PidLabel = selinux.PidLabel +// Init initialises the labeling system func Init() { + selinux.GetEnabled() } -// ClearLabels clears all reserved labels -func ClearLabels() { - return -} +// ClearLabels will clear all reserved labels +// Deprecated: use selinux.ClearLabels +var ClearLabels = selinux.ClearLabels +// ReserveLabel will record the fact that the MCS label has already been used. +// This will prevent InitLabels from using the MCS label in a newly created +// container +// Deprecated: use selinux.ReserveLabel func ReserveLabel(label string) error { + selinux.ReserveLabel(label) return nil } +// ReleaseLabel will remove the reservation of the MCS label. +// This will allow InitLabels to use the MCS label in a newly created +// containers +// Deprecated: use selinux.ReleaseLabel func ReleaseLabel(label string) error { + selinux.ReleaseLabel(label) return nil } // DupSecOpt takes a process label and returns security options that // can be used to set duplicate labels on future container processes -func DupSecOpt(src string) ([]string, error) { - return nil, nil -} - -// DisableSecOpt returns a security opt that can disable labeling -// support for future container processes -func DisableSecOpt() []string { - return nil -} - -// Validate checks that the label does not include unexpected options -func Validate(label string) error { - return nil -} - -// RelabelNeeded checks whether the user requested a relabel -func RelabelNeeded(label string) bool { - return false -} - -// IsShared checks that the label includes a "shared" mark -func IsShared(label string) bool { - return false -} +// Deprecated: use selinux.DupSecOpt +var DupSecOpt = selinux.DupSecOpt diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go index 2730fcf4a..903829958 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/opencontainers/selinux/go-selinux" + "github.com/pkg/errors" ) // Valid Label Options @@ -21,7 +22,7 @@ var validOptions = map[string]bool{ "level": true, } -var ErrIncompatibleLabel = fmt.Errorf("Bad SELinux option z and Z can not be used together") +var ErrIncompatibleLabel = errors.New("Bad SELinux option z and Z can not be used together") // InitLabels returns the process label and file labels to be used within // the container. A list of options can be passed into this function to alter @@ -35,7 +36,7 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) { if processLabel != "" { defer func() { if Err != nil { - ReleaseLabel(mountLabel) + selinux.ReleaseLabel(mountLabel) } }() pcon, err := selinux.NewContext(processLabel) @@ -52,11 +53,11 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) { return "", mountLabel, nil } if i := strings.Index(opt, ":"); i == -1 { - return "", "", fmt.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt) + return "", "", errors.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt) } con := strings.SplitN(opt, ":", 2) if !validOptions[con[0]] { - return "", "", fmt.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0]) + return "", "", errors.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0]) } if con[0] == "filetype" { @@ -67,19 +68,16 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) { mcon[con[0]] = con[1] } } - _ = ReleaseLabel(processLabel) + selinux.ReleaseLabel(processLabel) processLabel = pcon.Get() mountLabel = mcon.Get() - _ = ReserveLabel(processLabel) + selinux.ReserveLabel(processLabel) } return processLabel, mountLabel, nil } -func ROMountLabel() string { - return selinux.ROFileLabel() -} - -// DEPRECATED: The GenLabels function is only to be used during the transition to the official API. +// Deprecated: The GenLabels function is only to be used during the transition +// to the official API. Use InitLabels(strings.Fields(options)) instead. func GenLabels(options string) (string, string, error) { return InitLabels(strings.Fields(options)) } @@ -102,71 +100,27 @@ func FormatMountLabel(src, mountLabel string) string { return src } -// SetProcessLabel takes a process label and tells the kernel to assign the -// label to the next program executed by the current process. -func SetProcessLabel(processLabel string) error { - return selinux.SetExecLabel(processLabel) -} - -// SetSocketLabel takes a process label and tells the kernel to assign the -// label to the next socket that gets created -func SetSocketLabel(processLabel string) error { - return selinux.SetSocketLabel(processLabel) -} - -// SocketLabel retrieves the current default socket label setting -func SocketLabel() (string, error) { - return selinux.SocketLabel() -} - -// SetKeyLabel takes a process label and tells the kernel to assign the -// label to the next kernel keyring that gets created -func SetKeyLabel(processLabel string) error { - return selinux.SetKeyLabel(processLabel) -} - -// KeyLabel retrieves the current default kernel keyring label setting -func KeyLabel() (string, error) { - return selinux.KeyLabel() -} - -// ProcessLabel returns the process label that the kernel will assign -// to the next program executed by the current process. If "" is returned -// this indicates that the default labeling will happen for the process. -func ProcessLabel() (string, error) { - return selinux.ExecLabel() -} - -// FileLabel returns the label for specified path -func FileLabel(path string) (string, error) { - return selinux.FileLabel(path) -} - // SetFileLabel modifies the "path" label to the specified file label func SetFileLabel(path string, fileLabel string) error { - if selinux.GetEnabled() && fileLabel != "" { - return selinux.SetFileLabel(path, fileLabel) + if !selinux.GetEnabled() || fileLabel == "" { + return nil } - return nil + return selinux.SetFileLabel(path, fileLabel) } // SetFileCreateLabel tells the kernel the label for all files to be created func SetFileCreateLabel(fileLabel string) error { - if selinux.GetEnabled() { - return selinux.SetFSCreateLabel(fileLabel) + if !selinux.GetEnabled() { + return nil } - return nil + return selinux.SetFSCreateLabel(fileLabel) } // Relabel changes the label of path to the filelabel string. // It changes the MCS label to s0 if shared is true. // This will allow all containers to share the content. func Relabel(path string, fileLabel string, shared bool) error { - if !selinux.GetEnabled() { - return nil - } - - if fileLabel == "" { + if !selinux.GetEnabled() || fileLabel == "" { return nil } @@ -211,7 +165,7 @@ func Relabel(path string, fileLabel string, shared bool) error { path = strings.TrimSuffix(path, "/") } if exclude_paths[path] { - return fmt.Errorf("SELinux relabeling of %s is not allowed", path) + return errors.Errorf("SELinux relabeling of %s is not allowed", path) } if shared { @@ -229,48 +183,10 @@ func Relabel(path string, fileLabel string, shared bool) error { return nil } -// PidLabel will return the label of the process running with the specified pid -func PidLabel(pid int) (string, error) { - return selinux.PidLabel(pid) -} - -// Init initialises the labeling system -func Init() { - selinux.GetEnabled() -} - -// ClearLabels will clear all reserved labels -func ClearLabels() { - selinux.ClearLabels() -} - -// ReserveLabel will record the fact that the MCS label has already been used. -// This will prevent InitLabels from using the MCS label in a newly created -// container -func ReserveLabel(label string) error { - selinux.ReserveLabel(label) - return nil -} - -// ReleaseLabel will remove the reservation of the MCS label. -// This will allow InitLabels to use the MCS label in a newly created -// containers -func ReleaseLabel(label string) error { - selinux.ReleaseLabel(label) - return nil -} - -// DupSecOpt takes a process label and returns security options that -// can be used to set duplicate labels on future container processes -func DupSecOpt(src string) ([]string, error) { - return selinux.DupSecOpt(src) -} - // DisableSecOpt returns a security opt that can disable labeling // support for future container processes -func DisableSecOpt() []string { - return selinux.DisableSecOpt() -} +// Deprecated: use selinux.DisableSecOpt +var DisableSecOpt = selinux.DisableSecOpt // Validate checks that the label does not include unexpected options func Validate(label string) error { diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go new file mode 100644 index 000000000..cda59d671 --- /dev/null +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go @@ -0,0 +1,54 @@ +// +build !selinux !linux + +package label + +// InitLabels returns the process label and file labels to be used within +// the container. A list of options can be passed into this function to alter +// the labels. +func InitLabels(options []string) (string, string, error) { + return "", "", nil +} + +// Deprecated: The GenLabels function is only to be used during the transition +// to the official API. Use InitLabels(strings.Fields(options)) instead. +func GenLabels(options string) (string, string, error) { + return "", "", nil +} + +func FormatMountLabel(src string, mountLabel string) string { + return src +} + +func SetFileLabel(path string, fileLabel string) error { + return nil +} + +func SetFileCreateLabel(fileLabel string) error { + return nil +} + +func Relabel(path string, fileLabel string, shared bool) error { + return nil +} + +// DisableSecOpt returns a security opt that can disable labeling +// support for future container processes +func DisableSecOpt() []string { + // TODO the selinux.DisableSecOpt stub returns []string{"disable"} instead of "nil" + return nil +} + +// Validate checks that the label does not include unexpected options +func Validate(label string) error { + return nil +} + +// RelabelNeeded checks whether the user requested a relabel +func RelabelNeeded(label string) bool { + return false +} + +// IsShared checks that the label includes a "shared" mark +func IsShared(label string) bool { + return false +} diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go index c51ddfda2..599bdb6e2 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go @@ -17,8 +17,8 @@ import ( "strconv" "strings" "sync" - "syscall" + "github.com/opencontainers/selinux/pkg/pwalk" "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -37,7 +37,6 @@ const ( selinuxTypeTag = "SELINUXTYPE" selinuxTag = "SELINUX" xattrNameSelinux = "security.selinux" - stRdOnly = 0x01 ) type selinuxState struct { @@ -103,13 +102,13 @@ func SetDisabled() { } func verifySELinuxfsMount(mnt string) bool { - var buf syscall.Statfs_t + var buf unix.Statfs_t for { - err := syscall.Statfs(mnt, &buf) + err := unix.Statfs(mnt, &buf) if err == nil { break } - if err == syscall.EAGAIN { + if err == unix.EAGAIN { continue } return false @@ -118,7 +117,7 @@ func verifySELinuxfsMount(mnt string) bool { if uint32(buf.Type) != uint32(unix.SELINUX_MAGIC) { return false } - if (buf.Flags & stRdOnly) != 0 { + if (buf.Flags & unix.ST_RDONLY) != 0 { return false } @@ -251,10 +250,10 @@ func isProcHandle(fh *os.File) error { var buf unix.Statfs_t err := unix.Fstatfs(int(fh.Fd()), &buf) if err != nil { - return fmt.Errorf("statfs(%q) failed: %v", fh.Name(), err) + return errors.Wrapf(err, "statfs(%q) failed", fh.Name()) } if buf.Type != unix.PROC_SUPER_MAGIC { - return fmt.Errorf("file %q is not on procfs", fh.Name()) + return errors.Errorf("file %q is not on procfs", fh.Name()) } return nil @@ -282,12 +281,29 @@ func readCon(fpath string) (string, error) { return strings.Trim(retval, "\x00"), nil } +// ClassIndex returns the int index for an object class in the loaded policy, or -1 and an error +func ClassIndex(class string) (int, error) { + permpath := fmt.Sprintf("class/%s/index", class) + indexpath := filepath.Join(getSelinuxMountPoint(), permpath) + + indexB, err := ioutil.ReadFile(indexpath) + if err != nil { + return -1, err + } + index, err := strconv.Atoi(string(indexB)) + if err != nil { + return -1, err + } + + return index, nil +} + // SetFileLabel sets the SELinux label for this path or returns an error. func SetFileLabel(fpath string, label string) error { if fpath == "" { return ErrEmptyPath } - if err := lsetxattr(fpath, xattrNameSelinux, []byte(label), 0); err != nil { + if err := unix.Lsetxattr(fpath, xattrNameSelinux, []byte(label), 0); err != nil { return errors.Wrapf(err, "failed to set file label on %s", fpath) } return nil @@ -390,7 +406,7 @@ func attrPath(attr string) string { return path.Join(threadSelfPrefix, attr) } - return path.Join("/proc/self/task/", strconv.Itoa(syscall.Gettid()), "/attr/", attr) + return path.Join("/proc/self/task/", strconv.Itoa(unix.Gettid()), "/attr/", attr) } func readAttr(attr string) (string, error) { @@ -410,6 +426,18 @@ func CanonicalizeContext(val string) (string, error) { return readWriteCon(filepath.Join(getSelinuxMountPoint(), "context"), val) } +/* +ComputeCreateContext requests the type transition from source to target for class from the kernel. +*/ +func ComputeCreateContext(source string, target string, class string) (string, error) { + classidx, err := ClassIndex(class) + if err != nil { + return "", err + } + + return readWriteCon(filepath.Join(getSelinuxMountPoint(), "create"), fmt.Sprintf("%s %s %d", source, target, classidx)) +} + func readWriteCon(fpath string, val string) (string, error) { if fpath == "" { return "", ErrEmptyPath @@ -461,17 +489,17 @@ func SocketLabel() (string, error) { // PeerLabel retrieves the label of the client on the other side of a socket func PeerLabel(fd uintptr) (string, error) { - return unix.GetsockoptString(int(fd), syscall.SOL_SOCKET, syscall.SO_PEERSEC) + return unix.GetsockoptString(int(fd), unix.SOL_SOCKET, unix.SO_PEERSEC) } // SetKeyLabel takes a process label and tells the kernel to assign the // label to the next kernel keyring that gets created func SetKeyLabel(label string) error { err := writeCon("/proc/self/attr/keycreate", label) - if os.IsNotExist(err) { + if os.IsNotExist(errors.Cause(err)) { return nil } - if label == "" && os.IsPermission(err) { + if label == "" && os.IsPermission(errors.Cause(err)) { return nil } return err @@ -772,14 +800,14 @@ func badPrefix(fpath string) error { badPrefixes := []string{"/usr"} for _, prefix := range badPrefixes { if strings.HasPrefix(fpath, prefix) { - return fmt.Errorf("relabeling content in %s is not allowed", prefix) + return errors.Errorf("relabeling content in %s is not allowed", prefix) } } return nil } -// Chcon changes the `fpath` file object to the SELinux label `label`. -// If `fpath` is a directory and `recurse`` is true, Chcon will walk the +// Chcon changes the fpath file object to the SELinux label label. +// If fpath is a directory and recurse is true, Chcon will walk the // directory tree setting the label. func Chcon(fpath string, label string, recurse bool) error { if fpath == "" { @@ -791,19 +819,19 @@ func Chcon(fpath string, label string, recurse bool) error { if err := badPrefix(fpath); err != nil { return err } - callback := func(p string, info os.FileInfo, err error) error { + + if !recurse { + return SetFileLabel(fpath, label) + } + + return pwalk.Walk(fpath, func(p string, info os.FileInfo, err error) error { e := SetFileLabel(p, label) - if os.IsNotExist(e) { + // Walk a file tree can race with removal, so ignore ENOENT + if os.IsNotExist(errors.Cause(e)) { return nil } return e - } - - if recurse { - return filepath.Walk(fpath, callback) - } - - return SetFileLabel(fpath, label) + }) } // DupSecOpt takes an SELinux process label and returns security options that diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go index 0c2e1cd38..f349513d9 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go @@ -1,4 +1,4 @@ -// +build !selinux +// +build !selinux !linux package selinux @@ -35,6 +35,11 @@ func GetEnabled() bool { return false } +// ClassIndex returns the int index for an object class in the loaded policy, or -1 and an error +func ClassIndex(class string) (int, error) { + return -1, nil +} + // SetFileLabel sets the SELinux label for this path or returns an error. func SetFileLabel(fpath string, label string) error { return nil @@ -89,6 +94,13 @@ func CanonicalizeContext(val string) (string, error) { } /* +ComputeCreateContext requests the type transition from source to target for class from the kernel. +*/ +func ComputeCreateContext(source string, target string, class string) (string, error) { + return "", nil +} + +/* SetExecLabel sets the SELinux label that the kernel will use for any programs that are executed by the current process thread, or an error. */ diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go index 4e711a9f8..de5c80ef3 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go @@ -12,8 +12,8 @@ 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) - if errno == unix.ERANGE { - // Buffer too small, get the real size first + 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 @@ -28,7 +28,3 @@ func lgetxattr(path string, attr string) ([]byte, error) { return dest[:sz], nil } - -func lsetxattr(path string, attr string, data []byte, flags int) error { - return unix.Lsetxattr(path, attr, data, flags) -} diff --git a/vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md b/vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md new file mode 100644 index 000000000..16c4dfd3e --- /dev/null +++ b/vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md @@ -0,0 +1,42 @@ +## pwalk: parallel implementation of filepath.Walk + +This is a wrapper for [filepath.Walk](https://pkg.go.dev/path/filepath?tab=doc#Walk) +which may speed it up by calling multiple callback functions (WalkFunc) in parallel, +utilizing goroutines. + +By default, it utilizes 2\*runtime.NumCPU() goroutines for callbacks. +This can be changed by using WalkN function which has the additional +parameter, specifying the number of goroutines (concurrency). + +### Caveats + +Please note the following limitations of this code: + +* Unlike filepath.Walk, the order of calls is non-deterministic; + +* Only primitive error handling is supported: + + * filepath.SkipDir is not supported; + + * no errors are ever passed to WalkFunc; + + * once any error is returned from any WalkFunc instance, no more new calls + to WalkFunc are made, and the error is returned to the caller of Walk; + + * if more than one walkFunc instance will return an error, only one + of such errors will be propagated and returned by Walk, others + will be silently discarded. + +### Documentation + +For the official documentation, see +https://pkg.go.dev/github.com/opencontainers/selinux/pkg/pwalk?tab=doc + +### Benchmarks + +For a WalkFunc that consists solely of the return statement, this +implementation is about 10% slower than the standard library's +filepath.Walk. + +Otherwise (if a WalkFunc is doing something) this is usually faster, +except when the WalkN(..., 1) is used. diff --git a/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go b/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go new file mode 100644 index 000000000..2ee0d0150 --- /dev/null +++ b/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go @@ -0,0 +1,99 @@ +package pwalk + +import ( + "os" + "path/filepath" + "runtime" + "sync" + + "github.com/pkg/errors" +) + +type WalkFunc = filepath.WalkFunc + +// Walk is a wrapper for filepath.Walk which can call multiple walkFn +// in parallel, allowing to handle each item concurrently. A maximum of +// twice the runtime.NumCPU() walkFn will be called at any one time. +// If you want to change the maximum, use WalkN instead. +// +// The order of calls is non-deterministic. +// +// Note that this implementation only supports primitive error handling: +// +// * no errors are ever passed to WalkFn +// +// * once a walkFn returns any error, all further processing stops +// and the error is returned to the caller of Walk; +// +// * filepath.SkipDir is not supported; +// +// * if more than one walkFn instance will return an error, only one +// of such errors will be propagated and returned by Walk, others +// will be silently discarded. +// +func Walk(root string, walkFn WalkFunc) error { + return WalkN(root, walkFn, runtime.NumCPU()*2) +} + +// WalkN is a wrapper for filepath.Walk which can call multiple walkFn +// in parallel, allowing to handle each item concurrently. A maximum of +// num walkFn will be called at any one time. +func WalkN(root string, walkFn WalkFunc, num int) error { + // make sure limit is sensible + if num < 1 { + return errors.Errorf("walk(%q): num must be > 0", root) + } + + files := make(chan *walkArgs, 2*num) + errCh := make(chan error, 1) // get the first error, ignore others + + // Start walking a tree asap + var err error + go func() { + err = filepath.Walk(root, func(p string, info os.FileInfo, err error) error { + if err != nil { + close(files) + return err + } + // add a file to the queue unless a callback sent an error + select { + case e := <-errCh: + close(files) + return e + default: + files <- &walkArgs{path: p, info: &info} + return nil + } + }) + if err == nil { + close(files) + } + }() + + var wg sync.WaitGroup + wg.Add(num) + for i := 0; i < num; i++ { + go func() { + for file := range files { + if e := walkFn(file.path, *file.info, nil); e != nil { + select { + case errCh <- e: // sent ok + default: // buffer full + } + } + } + wg.Done() + }() + } + + wg.Wait() + + return err +} + +// walkArgs holds the arguments that were passed to the Walk or WalkLimit +// functions. +type walkArgs struct { + path string + info *os.FileInfo +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 53745057c..e5ee01a4e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -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.3 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 @@ -263,7 +262,7 @@ github.com/docker/spdystream github.com/docker/spdystream/spdy # github.com/etcd-io/bbolt v1.3.3 github.com/etcd-io/bbolt -# github.com/fsnotify/fsnotify v1.4.7 +# github.com/fsnotify/fsnotify v1.4.9 github.com/fsnotify/fsnotify # github.com/fsouza/go-dockerclient v1.6.3 github.com/fsouza/go-dockerclient @@ -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 @@ -405,9 +404,10 @@ github.com/opencontainers/runtime-tools/generate github.com/opencontainers/runtime-tools/generate/seccomp github.com/opencontainers/runtime-tools/specerror github.com/opencontainers/runtime-tools/validate -# github.com/opencontainers/selinux v1.3.3 +# github.com/opencontainers/selinux v1.4.0 github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label +github.com/opencontainers/selinux/pkg/pwalk # github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316 github.com/openshift/api/config/v1 # github.com/openshift/imagebuilder v1.1.1 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 |