summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELEASE_NOTES.md31
-rw-r--r--changelog.txt30
-rw-r--r--cmd/podman/common/completion.go251
-rw-r--r--cmd/podman/common/create_opts.go89
-rw-r--r--cmd/podman/common/createparse.go2
-rw-r--r--cmd/podman/common/volumes.go4
-rw-r--r--cmd/podman/containers/ps.go20
-rw-r--r--cmd/podman/containers/top.go10
-rw-r--r--cmd/podman/images/list.go3
-rw-r--r--cmd/podman/images/load.go2
-rw-r--r--cmd/podman/networks/connect.go2
-rw-r--r--cmd/podman/networks/disconnect.go2
-rw-r--r--cmd/podman/networks/list.go2
-rw-r--r--cmd/podman/pods/create.go2
-rw-r--r--cmd/podman/pods/top.go2
-rw-r--r--cmd/podman/root.go52
-rw-r--r--cmd/podman/volumes/list.go2
-rw-r--r--contrib/spec/podman.spec.in2
-rw-r--r--contrib/systemd/system/podman.service3
-rw-r--r--docs/source/Tutorials.rst2
-rw-r--r--docs/source/conf.py4
-rw-r--r--docs/source/managecontainers.rst2
-rw-r--r--docs/source/markdown/links/podman-list.11
-rw-r--r--docs/source/markdown/links/podman-ls.11
-rw-r--r--docs/source/markdown/podman-build.1.md11
-rw-r--r--docs/source/markdown/podman-container.1.md1
-rw-r--r--docs/source/markdown/podman-create.1.md153
-rw-r--r--docs/source/markdown/podman-export.1.md2
-rw-r--r--docs/source/markdown/podman-import.1.md1
-rw-r--r--docs/source/markdown/podman-load.1.md3
-rw-r--r--docs/source/markdown/podman-ps.1.md8
-rw-r--r--docs/source/markdown/podman-pull.1.md29
-rw-r--r--docs/source/markdown/podman-push.1.md12
-rw-r--r--docs/source/markdown/podman-run.1.md157
-rw-r--r--docs/source/markdown/podman-save.1.md4
-rw-r--r--docs/source/markdown/podman-system-service.1.md5
-rw-r--r--docs/source/markdown/podman-top.1.md2
-rw-r--r--docs/source/markdown/podman.1.md4
-rw-r--r--docs/tutorials/mac_win_client.md2
-rw-r--r--go.mod4
-rw-r--r--go.sum20
-rw-r--r--libpod/container.go20
-rw-r--r--libpod/container_api.go14
-rw-r--r--libpod/container_internal.go37
-rw-r--r--libpod/container_internal_linux.go4
-rw-r--r--libpod/healthcheck_linux.go4
-rw-r--r--libpod/image/manifests.go36
-rw-r--r--libpod/network/config.go10
-rw-r--r--libpod/network/create.go1
-rw-r--r--libpod/network/files.go5
-rw-r--r--libpod/network/netconflist.go7
-rw-r--r--libpod/network/network.go28
-rw-r--r--libpod/network/subnet.go14
-rw-r--r--libpod/network/subnet_test.go62
-rw-r--r--libpod/networking_linux.go28
-rw-r--r--libpod/rootless_cni_linux.go4
-rw-r--r--libpod/runtime.go4
-rw-r--r--pkg/api/handlers/compat/containers.go15
-rw-r--r--pkg/api/handlers/compat/containers_create.go21
-rw-r--r--pkg/api/handlers/compat/info.go3
-rw-r--r--pkg/api/handlers/compat/ping.go3
-rw-r--r--pkg/api/handlers/libpod/containers.go24
-rw-r--r--pkg/api/handlers/libpod/images.go6
-rw-r--r--pkg/api/handlers/libpod/images_pull.go3
-rw-r--r--pkg/api/handlers/types.go13
-rw-r--r--pkg/api/server/handler_api.go7
-rw-r--r--pkg/api/server/listener_api.go1
-rw-r--r--pkg/api/server/register_ping.go2
-rw-r--r--pkg/api/server/server.go6
-rw-r--r--pkg/bindings/containers/containers.go12
-rw-r--r--pkg/domain/entities/images.go8
-rw-r--r--pkg/domain/infra/abi/containers.go15
-rw-r--r--pkg/domain/infra/abi/play.go67
-rw-r--r--pkg/domain/infra/tunnel/containers.go27
-rw-r--r--pkg/domain/infra/tunnel/images.go4
-rw-r--r--pkg/specgen/generate/container.go14
-rw-r--r--pkg/specgen/generate/kube/kube.go40
-rw-r--r--pkg/specgen/generate/kube/volume.go124
-rw-r--r--pkg/specgen/namespaces.go16
-rw-r--r--pkg/specgen/volumes.go4
-rw-r--r--test/apiv2/25-containersMore.at27
-rw-r--r--test/apiv2/rest_api/__init__.py15
-rw-r--r--test/apiv2/rest_api/test_rest_v2_0_0.py90
-rw-r--r--test/apiv2/rest_api/v1_test_rest_v1_0_0.py4
-rw-r--r--test/e2e/create_staticmac_test.go18
-rw-r--r--test/e2e/network_test.go11
-rw-r--r--test/e2e/play_kube_test.go89
-rw-r--r--test/e2e/ps_test.go6
-rw-r--r--test/e2e/run_test.go4
-rw-r--r--test/python/docker/__init__.py14
-rw-r--r--test/python/docker/common.py4
-rw-r--r--test/python/docker/test_containers.py2
-rw-r--r--test/python/docker/test_images.py4
-rw-r--r--test/system/030-run.bats5
-rw-r--r--vendor/github.com/containers/buildah/buildah.go2
-rw-r--r--vendor/github.com/containers/buildah/go.mod7
-rw-r--r--vendor/github.com/containers/buildah/go.sum20
-rw-r--r--vendor/github.com/containers/buildah/image.go5
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/build.go2
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/executor.go9
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/stage_executor.go7
-rw-r--r--vendor/github.com/containers/buildah/install.md63
-rw-r--r--vendor/github.com/containers/buildah/pkg/cli/common.go3
-rw-r--r--vendor/github.com/containers/buildah/pkg/umask/umask_unsupported.go7
-rw-r--r--vendor/github.com/containers/buildah/run_linux.go28
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go4
-rw-r--r--vendor/github.com/containers/common/pkg/config/containers.conf10
-rw-r--r--vendor/github.com/containers/common/pkg/config/default.go4
-rw-r--r--vendor/github.com/containers/common/pkg/retry/retry.go2
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/default_linux.go2
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/supported.go2
-rw-r--r--vendor/github.com/containers/common/pkg/subscriptions/mounts.conf1
-rw-r--r--vendor/github.com/containers/common/pkg/subscriptions/subscriptions.go (renamed from vendor/github.com/containers/buildah/pkg/secrets/secrets.go)111
-rw-r--r--vendor/github.com/containers/common/pkg/umask/umask_unix.go (renamed from vendor/github.com/containers/buildah/pkg/umask/umask_unix.go)6
-rw-r--r--vendor/github.com/containers/common/pkg/umask/umask_unsupported.go7
-rw-r--r--vendor/github.com/containers/common/version/version.go2
-rw-r--r--vendor/modules.txt8
-rw-r--r--version/version.go4
118 files changed, 1529 insertions, 732 deletions
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index f4df37a0e..a1027b465 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -3,12 +3,14 @@
## 2.2.0
### Features
- Experimental support for shortname aliasing has been added. This is not enabled by default, but can be turned on by setting the environment variable `CONTAINERS_SHORT_NAME_ALIASING` to `on`. Documentation is [available here](https://github.com/containers/image/blob/master/docs/containers-registries.conf.5.md#short-name-aliasing).
+- Initial support has been added for the `podman network connect` and `podman network disconnect` commands, which allow existing containers to modify what networks they are connected to. At present, these commands can only be used on running containers that did not specify `--network=none` when they were created.
+- The `podman run` command now supports the `--network-alias` option to set network aliases (additional names the container can be accessed at from other containers via DNS if the `dnsname` CNI plugin is in use). Aliases can also be added and removed using the new `podman network connect` and `podman network disconnect` commands. Please note that this requires a new release (v1.1.0) of the `dnsname` plugin, and will only work on newly-created CNI networks.
- The `podman generate kube` command now features support for exporting container's memory and CPU limits ([#7855](https://github.com/containers/podman/issues/7855)).
- The `podman play kube` command now features support for setting CPU and Memory limits for containers ([#7742](https://github.com/containers/podman/issues/7742)).
+- The `podman play kube` command now supports persistent volumes claims using Podman named volumes.
- The `podman play kube` command now supports Kubernetes configmaps via the `--configmap` option ([#7567](https://github.com/containers/podman/issues/7567)).
- The `podman play kube` command now supports a `--log-driver` option to set the log driver for created containers.
- The `podman play kube` command now supports a `--start` option, enabled by default, to start the pod after creating it. This allows for `podman play kube` to be more easily used in systemd unitfiles.
-- The `podman run` command now supports the `--network-alias` option to set network aliases (additional names the container can be accessed at from other containers via DNS if the `dnsname` CNI plugin is in use). Please note that this requires a new release (v1.1.0) of the `dnsname` plugin, and will only work on newly-created CNI networks.
- The `podman network create` command now supports the `--ipv6` option to enable dual-stack IPv6 networking for created networks ([#7302](https://github.com/containers/podman/issues/7302)).
- The `podman inspect` command can now inspect pods, networks, and volumes, in addition to containers and images ([#6757](https://github.com/containers/podman/issues/6757)).
- The `--mount` option for `podman run` and `podman create` now supports a new type, `image`, to mount the contents of an image into the container at a given location.
@@ -25,7 +27,8 @@
- The `podman events` command now supports filtering events based on the labels of the container they occurred on using the `--filter label=key=value` option.
- The `podman volume ls` command now supports filtering volumes based on their labels using the `--filter label=key=value` option.
- The `--volume` and `--mount` options to `podman run` and `podman create` now support two new mount propagation options, `unbindable` and `runbindable`.
-- The `name` filter for `podman pod ps` now matches based on a regular expression, instead of requiring an exact match.
+- The `name` and `id` filters for `podman pod ps` now match based on a regular expression, instead of requiring an exact match.
+- The `podman pod ps` command now supports a new filter `status`, that matches pods in a certain state.
### Changes
- The `podman network rm --force` command will now also remove pods that are using the network ([#7791](https://github.com/containers/podman/issues/7791)).
@@ -38,6 +41,10 @@
- Podman now delays the SIGTERM and SIGINT signals during container creation to ensure that Podman is not stopped midway through creating a container resulting in potential resource leakage ([#7941](https://github.com/containers/podman/issues/7941)).
- The `podman save` command now strips signatures from images it is exporting, as the formats we export to do not support signatures ([#7659](https://github.com/containers/podman/issues/7659)).
- A new `Degraded` state has been added to pods. Pods that have some, but not all, of their containers running are now considered to be `Degraded` instead of `Running`.
+- Podman will now print a warning when conflicting network options related to port forwarding (e.g. `--publish` and `--net=host`) are specified when creating a container.
+- The `--restart on-failure` and `--rm` options for containers no longer conflict. When both are specified, the container will be restarted if it exits with a non-zero error code, and removed if it exits cleanly ([#7906](https://github.com/containers/podman/issues/7906)).
+- Remote Podman will no longer use settings from the client's `containers.conf`; defaults will instead be provided by the server's `containers.conf` ([#7657](https://github.com/containers/podman/issues/7657)).
+- The `podman network rm` command now has a new alias, `podman network remove` ([#8402](https://github.com/containers/podman/issues/8402)).
### Bugfixes
- Fixed a bug where `podman load` on the remote client did not error when attempting to load a directory, which is not yet supported for remote use.
@@ -103,6 +110,14 @@
- Fixed a bug where the `podman stats` command did not show memory limits for containers ([#8265](https://github.com/containers/podman/issues/8265)).
- Fixed a bug where the `podman pod inspect` command printed the static MAC address of the pod in a non-human-readable format ([#8386](https://github.com/containers/podman/pull/8386)).
- Fixed a bug where the `--tls-verify` option of the `podman play kube` command had its logic inverted (`false` would enforce the use of TLS, `true` would disable it).
+- Fixed a bug where the `podman network rm` command would error when trying to remove `macvlan` networks and rootless CNI networks ([#8491](https://github.com/containers/podman/issues/8491)).
+- Fixed a bug where Podman was not setting sane defaults for missing `XDG_` environment variables.
+- Fixed a bug where remote Podman would check if volume paths to be mounted in the container existed on the host, not the server ([#8473](https://github.com/containers/podman/issues/8473)).
+- Fixed a bug where the `podman manifest create` and `podman manifest add` commands on local images would drop any images in the manifest not pulled by the host.
+- Fixed a bug where networks made by `podman network create` did not include the `tuning` plugin, and as such did not support setting custom MAC addresses ([#8385](https://github.com/containers/podman/issues/8385)).
+- Fixed a bug where container healthchecks did not use `$PATH` when searching for the Podman executable to run the healthcheck.
+- Fixed a bug where the `--ip-range` option to `podman network create` did not properly handle non-classful subnets when calculating the last usable IP for DHCP assignment ([#8448](https://github.com/containers/podman/issues/8448)).
+- Fixed a bug where the `podman container ps` alias for `podman ps` was missing ([#8445](https://github.com/containers/podman/issues/8445)).
### API
- The Compat Create endpoint for Container has received a major refactor to share more code with the Libpod Create endpoint, and should be significantly more stable.
@@ -112,22 +127,28 @@
- The Compat Create endpoint for images now properly supports specifying images by digest.
- The Libpod Build endpoint for images now supports an `httpproxy` query parameter which, if set to true, will forward the server's HTTP proxy settings into the build container for `RUN` instructions.
- The Libpod Untag endpoint for images will now remove all tags for the given image if no repository and tag are specified for removal.
+- Fixed a bug where the Ping endpoint misspelled a header name (`Libpod-Buildha-Version` instead of `Libpod-Buildah-Version`).
+- Fixed a bug where the Ping endpoint sent an extra newline at the end of its response where Docker did not.
- Fixed a bug where the Compat Logs endpoint for containers did not send a newline character after each log line.
- Fixed a bug where the Compat Logs endpoint for containers would mangle line endings to change newline characters to add a preceding carriage return ([#7942](https://github.com/containers/podman/issues/7942)).
- Fixed a bug where the Compat Inspect endpoint for Containers did not properly list the container's stop signal ([#7917](https://github.com/containers/podman/issues/7917)).
- Fixed a bug where the Compat Inspect endpoint for Containers formatted the container's create time incorrectly ([#7860](https://github.com/containers/podman/issues/7860)).
-- Fixed a bug where the Compat Inspect endpoint for Containers did not include complete network information on the container.
+- Fixed a bug where the Compat Inspect endpoint for Containers did not include the container's Path, Args, and Restart Count.
+- Fixed a bug where the Compat Inspect endpoint for Containers prefixed added and dropped capabilities with `CAP_` (Docker does not do so).
+- Fixed a bug where the Compat Info endpoint for the Engine did not include configured registries.
- Fixed a bug where the server could panic if a client closed a connection midway through an image pull ([#7896](https://github.com/containers/podman/issues/7896)).
- Fixed a bug where the Compat Create endpoint for volumes returned an error when a volume with the same name already existed, instead of succeeding with a 201 code ([#7740](https://github.com/containers/podman/issues/7740)).
- Fixed a bug where a client disconnecting from the Libpod or Compat events endpoints could result in the server using 100% CPU ([#7946](https://github.com/containers/podman/issues/7946)).
- Fixed a bug where the "no such image" error message sent by the Compat Inspect endpoint for Images returned a 404 status code with an error that was improperly formatted for Docker compatibility.
- Fixed a bug where the Compat Create endpoint for networks did not properly set a default for the `driver` parameter if it was not provided by the client.
- Fixed a bug where the Compat Inspect endpoint for images did not populate the `RootFS` field of the response.
+- Fixed a bug where the Compat Inspect endpoint for images would omit the `ParentId` field if the image had no parent, and the `Created` field if the image did not have a creation time.
+- Fixed a bug where the Compat Remove endpoint for Networks did not support the `Force` query parameter.
### Misc
- Updated Buildah to v1.18.0
-- Updated the containers/storage library to v1.24.0
-- Updated the containers/image library to v5.8.0
+- Updated the containers/storage library to v1.24.1
+- Updated the containers/image library to v5.8.1
- Updated the containers/common library to v0.27.0
## 2.1.1
diff --git a/changelog.txt b/changelog.txt
index 4d423ca44..326f52718 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,33 @@
+- Changelog for HEAD (2020-11-24):
+ * Set PATH env in systemd timer.
+ * Docker compat API fixes
+ * shell completions: remove usage of ShellCompDirectiveError
+ * more shell completion improvements
+ * Fix ip-range for classless subnet masks
+ * Bump github.com/containers/common from 0.27.0 to 0.29.0
+ * Add podman container ps command
+ * clarify ps(1) fallback of `podman top`
+ * APIv2 - create container sets wrong entrypoint
+ * Enable remote shell completion without a running endpoint
+ * Specify what the replace flag replaces in help text
+ * APIv2 - strip CAP_ prefix from capabilities in json
+ * Make c.networks() list include the default network
+ * Allow containers to --restart on-failure with --rm
+ * REST API v2 - list of images - mandatory Created attribute
+ * Allow multiple --network flags for podman run/create
+ * fix container cgroup lookup
+ * Make podman service log events
+ * vendor in containers/storage v1.24.1 containers/image v5.8.1
+ * Document containers.conf settings for remote connections
+ * Shell completion for podman ps and podman pod ps --filter
+ * Add alias for podman network rm -> remove
+ * add network connect|disconnect compat endpoints
+ * Fix sed regex to update version in version/version.go
+ * Github-Actions: Send e-mail on Cirrus cron failure
+ * Align the podman pod ps --filter behavior with podman ps
+ * podman-remote network rm --force is broken
+ * Remove build \!remote flags from test
+
- Changelog for v2.2.0-rc1 (2020-11-18):
* Add release notes for v2.2.0-RC1
* correct numbering typo
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go
index db4d3d0d3..9856e46ef 100644
--- a/cmd/podman/common/completion.go
+++ b/cmd/podman/common/completion.go
@@ -12,7 +12,9 @@ import (
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/registries"
+ "github.com/containers/podman/v2/pkg/rootless"
systemdGen "github.com/containers/podman/v2/pkg/systemd/generate"
+ "github.com/containers/podman/v2/pkg/util"
"github.com/spf13/cobra"
)
@@ -36,7 +38,35 @@ const (
type keyValueCompletion map[string]func(s string) ([]string, cobra.ShellCompDirective)
-func getContainers(toComplete string, cType completeType, statuses ...string) ([]string, cobra.ShellCompDirective) {
+func setupContainerEngine(cmd *cobra.Command) (entities.ContainerEngine, error) {
+ containerEngine, err := registry.NewContainerEngine(cmd, []string{})
+ if err != nil {
+ cobra.CompErrorln(err.Error())
+ return nil, err
+ }
+ if !registry.IsRemote() && rootless.IsRootless() {
+ err := containerEngine.SetupRootless(registry.Context(), cmd)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return containerEngine, nil
+}
+
+func setupImageEngine(cmd *cobra.Command) (entities.ImageEngine, error) {
+ imageEngine, err := registry.NewImageEngine(cmd, []string{})
+ if err != nil {
+ return nil, err
+ }
+ // we also need to set up the container engine since this
+ // is required to setup the rootless namespace
+ if _, err = setupContainerEngine(cmd); err != nil {
+ return nil, err
+ }
+ return imageEngine, nil
+}
+
+func getContainers(cmd *cobra.Command, toComplete string, cType completeType, statuses ...string) ([]string, cobra.ShellCompDirective) {
suggestions := []string{}
listOpts := entities.ContainerListOptions{
Filters: make(map[string][]string),
@@ -47,10 +77,15 @@ func getContainers(toComplete string, cType completeType, statuses ...string) ([
listOpts.Filters["status"] = statuses
}
- containers, err := registry.ContainerEngine().ContainerList(registry.GetContext(), listOpts)
+ engine, err := setupContainerEngine(cmd)
+ if err != nil {
+ cobra.CompErrorln(err.Error())
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ containers, err := engine.ContainerList(registry.GetContext(), listOpts)
if err != nil {
cobra.CompErrorln(err.Error())
- return nil, cobra.ShellCompDirectiveError
+ return nil, cobra.ShellCompDirectiveNoFileComp
}
for _, c := range containers {
@@ -68,7 +103,7 @@ func getContainers(toComplete string, cType completeType, statuses ...string) ([
return suggestions, cobra.ShellCompDirectiveNoFileComp
}
-func getPods(toComplete string, cType completeType, statuses ...string) ([]string, cobra.ShellCompDirective) {
+func getPods(cmd *cobra.Command, toComplete string, cType completeType, statuses ...string) ([]string, cobra.ShellCompDirective) {
suggestions := []string{}
listOpts := entities.PodPSOptions{
Filters: make(map[string][]string),
@@ -77,10 +112,15 @@ func getPods(toComplete string, cType completeType, statuses ...string) ([]strin
listOpts.Filters["status"] = statuses
}
- pods, err := registry.ContainerEngine().PodPs(registry.GetContext(), listOpts)
+ engine, err := setupContainerEngine(cmd)
if err != nil {
cobra.CompErrorln(err.Error())
- return nil, cobra.ShellCompDirectiveError
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ pods, err := engine.PodPs(registry.GetContext(), listOpts)
+ if err != nil {
+ cobra.CompErrorln(err.Error())
+ return nil, cobra.ShellCompDirectiveNoFileComp
}
for _, pod := range pods {
@@ -98,14 +138,19 @@ func getPods(toComplete string, cType completeType, statuses ...string) ([]strin
return suggestions, cobra.ShellCompDirectiveNoFileComp
}
-func getVolumes(toComplete string) ([]string, cobra.ShellCompDirective) {
+func getVolumes(cmd *cobra.Command, toComplete string) ([]string, cobra.ShellCompDirective) {
suggestions := []string{}
lsOpts := entities.VolumeListOptions{}
- volumes, err := registry.ContainerEngine().VolumeList(registry.GetContext(), lsOpts)
+ engine, err := setupContainerEngine(cmd)
+ if err != nil {
+ cobra.CompErrorln(err.Error())
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ volumes, err := engine.VolumeList(registry.GetContext(), lsOpts)
if err != nil {
cobra.CompErrorln(err.Error())
- return nil, cobra.ShellCompDirectiveError
+ return nil, cobra.ShellCompDirectiveNoFileComp
}
for _, v := range volumes {
@@ -116,14 +161,19 @@ func getVolumes(toComplete string) ([]string, cobra.ShellCompDirective) {
return suggestions, cobra.ShellCompDirectiveNoFileComp
}
-func getImages(toComplete string) ([]string, cobra.ShellCompDirective) {
+func getImages(cmd *cobra.Command, toComplete string) ([]string, cobra.ShellCompDirective) {
suggestions := []string{}
listOptions := entities.ImageListOptions{}
- images, err := registry.ImageEngine().List(registry.GetContext(), listOptions)
+ engine, err := setupImageEngine(cmd)
+ if err != nil {
+ cobra.CompErrorln(err.Error())
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ images, err := engine.List(registry.GetContext(), listOptions)
if err != nil {
cobra.CompErrorln(err.Error())
- return nil, cobra.ShellCompDirectiveError
+ return nil, cobra.ShellCompDirectiveNoFileComp
}
for _, image := range images {
@@ -166,19 +216,24 @@ func getRegistries() ([]string, cobra.ShellCompDirective) {
regs, err := registries.GetRegistries()
if err != nil {
cobra.CompErrorln(err.Error())
- return nil, cobra.ShellCompDirectiveError
+ return nil, cobra.ShellCompDirectiveNoFileComp
}
return regs, cobra.ShellCompDirectiveNoFileComp
}
-func getNetworks(toComplete string) ([]string, cobra.ShellCompDirective) {
+func getNetworks(cmd *cobra.Command, toComplete string) ([]string, cobra.ShellCompDirective) {
suggestions := []string{}
networkListOptions := entities.NetworkListOptions{}
- networks, err := registry.ContainerEngine().NetworkList(registry.Context(), networkListOptions)
+ engine, err := setupContainerEngine(cmd)
+ if err != nil {
+ cobra.CompErrorln(err.Error())
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ networks, err := engine.NetworkList(registry.Context(), networkListOptions)
if err != nil {
cobra.CompErrorln(err.Error())
- return nil, cobra.ShellCompDirectiveError
+ return nil, cobra.ShellCompDirectiveNoFileComp
}
for _, n := range networks {
@@ -266,7 +321,7 @@ func AutocompleteContainers(cmd *cobra.Command, args []string, toComplete string
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- return getContainers(toComplete, completeDefault)
+ return getContainers(cmd, toComplete, completeDefault)
}
// AutocompleteContainersCreated - Autocomplete only created container names.
@@ -274,7 +329,7 @@ func AutocompleteContainersCreated(cmd *cobra.Command, args []string, toComplete
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- return getContainers(toComplete, completeDefault, "created")
+ return getContainers(cmd, toComplete, completeDefault, "created")
}
// AutocompleteContainersExited - Autocomplete only exited container names.
@@ -282,7 +337,7 @@ func AutocompleteContainersExited(cmd *cobra.Command, args []string, toComplete
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- return getContainers(toComplete, completeDefault, "exited")
+ return getContainers(cmd, toComplete, completeDefault, "exited")
}
// AutocompleteContainersPaused - Autocomplete only paused container names.
@@ -290,7 +345,7 @@ func AutocompleteContainersPaused(cmd *cobra.Command, args []string, toComplete
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- return getContainers(toComplete, completeDefault, "paused")
+ return getContainers(cmd, toComplete, completeDefault, "paused")
}
// AutocompleteContainersRunning - Autocomplete only running container names.
@@ -298,7 +353,7 @@ func AutocompleteContainersRunning(cmd *cobra.Command, args []string, toComplete
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- return getContainers(toComplete, completeDefault, "running")
+ return getContainers(cmd, toComplete, completeDefault, "running")
}
// AutocompleteContainersStartable - Autocomplete only created and exited container names.
@@ -306,7 +361,7 @@ func AutocompleteContainersStartable(cmd *cobra.Command, args []string, toComple
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- return getContainers(toComplete, completeDefault, "created", "exited")
+ return getContainers(cmd, toComplete, completeDefault, "created", "exited")
}
// AutocompletePods - Autocomplete all pod names.
@@ -314,7 +369,7 @@ func AutocompletePods(cmd *cobra.Command, args []string, toComplete string) ([]s
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- return getPods(toComplete, completeDefault)
+ return getPods(cmd, toComplete, completeDefault)
}
// AutocompletePodsRunning - Autocomplete only running pod names.
@@ -323,7 +378,7 @@ func AutocompletePodsRunning(cmd *cobra.Command, args []string, toComplete strin
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- return getPods(toComplete, completeDefault, "running", "degraded")
+ return getPods(cmd, toComplete, completeDefault, "running", "degraded")
}
// AutocompleteContainersAndPods - Autocomplete container names and pod names.
@@ -331,8 +386,8 @@ func AutocompleteContainersAndPods(cmd *cobra.Command, args []string, toComplete
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- containers, _ := getContainers(toComplete, completeDefault)
- pods, _ := getPods(toComplete, completeDefault)
+ containers, _ := getContainers(cmd, toComplete, completeDefault)
+ pods, _ := getPods(cmd, toComplete, completeDefault)
return append(containers, pods...), cobra.ShellCompDirectiveNoFileComp
}
@@ -341,8 +396,8 @@ func AutocompleteContainersAndImages(cmd *cobra.Command, args []string, toComple
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- containers, _ := getContainers(toComplete, completeDefault)
- images, _ := getImages(toComplete)
+ containers, _ := getContainers(cmd, toComplete, completeDefault)
+ images, _ := getImages(cmd, toComplete)
return append(containers, images...), cobra.ShellCompDirectiveNoFileComp
}
@@ -351,7 +406,7 @@ func AutocompleteVolumes(cmd *cobra.Command, args []string, toComplete string) (
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- return getVolumes(toComplete)
+ return getVolumes(cmd, toComplete)
}
// AutocompleteImages - Autocomplete images.
@@ -359,7 +414,7 @@ func AutocompleteImages(cmd *cobra.Command, args []string, toComplete string) ([
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- return getImages(toComplete)
+ return getImages(cmd, toComplete)
}
// AutocompleteCreateRun - Autocomplete only the fist argument as image and then do file completion.
@@ -368,7 +423,7 @@ func AutocompleteCreateRun(cmd *cobra.Command, args []string, toComplete string)
return nil, cobra.ShellCompDirectiveNoFileComp
}
if len(args) < 1 {
- return getImages(toComplete)
+ return getImages(cmd, toComplete)
}
// TODO: add path completion for files in the image
return nil, cobra.ShellCompDirectiveDefault
@@ -387,7 +442,7 @@ func AutocompleteNetworks(cmd *cobra.Command, args []string, toComplete string)
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
- return getNetworks(toComplete)
+ return getNetworks(cmd, toComplete)
}
// AutocompleteCpCommand - Autocomplete podman cp command args.
@@ -396,7 +451,7 @@ func AutocompleteCpCommand(cmd *cobra.Command, args []string, toComplete string)
return nil, cobra.ShellCompDirectiveNoFileComp
}
if len(args) < 2 {
- containers, _ := getContainers(toComplete, completeDefault)
+ containers, _ := getContainers(cmd, toComplete, completeDefault)
for _, container := range containers {
// TODO: Add path completion for inside the container if possible
if strings.HasPrefix(container, toComplete) {
@@ -410,6 +465,37 @@ func AutocompleteCpCommand(cmd *cobra.Command, args []string, toComplete string)
return nil, cobra.ShellCompDirectiveNoFileComp
}
+// AutocompleteNetworkConnectCmd - Autocomplete podman network connect/disconnect command args.
+func AutocompleteNetworkConnectCmd(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ if len(args) == 0 {
+ return getNetworks(cmd, toComplete)
+ }
+ if len(args) == 1 {
+ return getContainers(cmd, toComplete, completeDefault)
+ }
+ // don't complete more than 2 args
+ return nil, cobra.ShellCompDirectiveNoFileComp
+}
+
+// AutocompleteTopCmd - Autocomplete podman top/pod top command args.
+func AutocompleteTopCmd(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ latest := cmd.Flags().Lookup("latest")
+ // only complete containers/pods as first arg if latest is not set
+ if len(args) == 0 && (latest == nil || !latest.Changed) {
+ if cmd.Parent().Name() == "pod" {
+ // need to complete pods since we are using pod top
+ return getPods(cmd, toComplete, completeDefault)
+ }
+ return getContainers(cmd, toComplete, completeDefault)
+ }
+ descriptors, err := util.GetContainerPidInformationDescriptors()
+ if err != nil {
+ cobra.CompErrorln(err.Error())
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ return descriptors, cobra.ShellCompDirectiveNoFileComp
+}
+
// AutocompleteSystemConnections - Autocomplete system connections.
func AutocompleteSystemConnections(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) {
@@ -419,7 +505,7 @@ func AutocompleteSystemConnections(cmd *cobra.Command, args []string, toComplete
cfg, err := config.ReadCustomConfig()
if err != nil {
cobra.CompErrorln(err.Error())
- return nil, cobra.ShellCompDirectiveError
+ return nil, cobra.ShellCompDirectiveNoFileComp
}
for k, v := range cfg.Engine.ServiceDestinations {
@@ -464,7 +550,7 @@ func AutocompleteCreateAttach(cmd *cobra.Command, args []string, toComplete stri
// -> host,container:[name],ns:[path],private
func AutocompleteNamespace(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
kv := keyValueCompletion{
- "container:": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(s, completeDefault) },
+ "container:": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(cmd, s, completeDefault) },
"ns:": func(s string) ([]string, cobra.ShellCompDirective) { return nil, cobra.ShellCompDirectiveDefault },
"host": nil,
"private": nil,
@@ -567,7 +653,8 @@ func AutocompleteUserFlag(cmd *cobra.Command, args []string, toComplete string)
// but at this point we don't know the image.
file, err := os.Open("/etc/group")
if err != nil {
- return nil, cobra.ShellCompDirectiveError
+ cobra.CompErrorln(err.Error())
+ return nil, cobra.ShellCompDirectiveNoFileComp
}
defer file.Close()
@@ -583,7 +670,8 @@ func AutocompleteUserFlag(cmd *cobra.Command, args []string, toComplete string)
}
}
if err = scanner.Err(); err != nil {
- return nil, cobra.ShellCompDirectiveError
+ cobra.CompErrorln(err.Error())
+ return nil, cobra.ShellCompDirectiveNoFileComp
}
return groups, cobra.ShellCompDirectiveNoFileComp
}
@@ -592,7 +680,8 @@ func AutocompleteUserFlag(cmd *cobra.Command, args []string, toComplete string)
// but at this point we don't know the image.
file, err := os.Open("/etc/passwd")
if err != nil {
- return nil, cobra.ShellCompDirectiveError
+ cobra.CompErrorln(err.Error())
+ return nil, cobra.ShellCompDirectiveNoFileComp
}
defer file.Close()
@@ -607,7 +696,7 @@ func AutocompleteUserFlag(cmd *cobra.Command, args []string, toComplete string)
}
}
if err = scanner.Err(); err != nil {
- return nil, cobra.ShellCompDirectiveError
+ return nil, cobra.ShellCompDirectiveNoFileComp
}
return users, cobra.ShellCompDirectiveNoSpace
}
@@ -623,7 +712,7 @@ func AutocompleteMountFlag(cmd *cobra.Command, args []string, toComplete string)
// AutocompleteVolumeFlag - Autocomplete volume flag options.
// -> volumes and paths
func AutocompleteVolumeFlag(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
- volumes, _ := getVolumes(toComplete)
+ volumes, _ := getVolumes(cmd, toComplete)
directive := cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveDefault
if strings.Contains(toComplete, ":") {
// add space after second path
@@ -641,8 +730,22 @@ func AutocompleteJSONFormat(cmd *cobra.Command, args []string, toComplete string
// AutocompleteEventFilter - Autocomplete event filter flag options.
// -> "container=", "event=", "image=", "pod=", "volume=", "type="
func AutocompleteEventFilter(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
- filters := []string{"container=", "event=", "image=", "pod=", "volume=", "type="}
- return filters, cobra.ShellCompDirectiveNoSpace
+ eventTypes := func(_ string) ([]string, cobra.ShellCompDirective) {
+ return []string{"attach", "checkpoint", "cleanup", "commit", "create", "exec",
+ "export", "import", "init", "kill", "mount", "pause", "prune", "remove",
+ "restart", "restore", "start", "stop", "sync", "unmount", "unpause",
+ "pull", "push", "save", "tag", "untag", "refresh", "renumber",
+ }, cobra.ShellCompDirectiveNoFileComp
+ }
+ kv := keyValueCompletion{
+ "container=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(cmd, s, completeDefault) },
+ "image=": func(s string) ([]string, cobra.ShellCompDirective) { return getImages(cmd, s) },
+ "pod=": func(s string) ([]string, cobra.ShellCompDirective) { return getPods(cmd, s, completeDefault) },
+ "volume=": func(s string) ([]string, cobra.ShellCompDirective) { return getVolumes(cmd, s) },
+ "event=": eventTypes,
+ "type=": eventTypes,
+ }
+ return completeKeyValues(toComplete, kv)
}
// AutocompleteSystemdRestartOptions - Autocomplete systemd restart options.
@@ -753,15 +856,15 @@ var containerStatuses = []string{"created", "running", "paused", "stopped", "exi
// AutocompletePsFilters - Autocomplete ps filter options.
func AutocompletePsFilters(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
kv := keyValueCompletion{
- "id=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(s, completeIDs) },
- "name=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(s, completeNames) },
+ "id=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(cmd, s, completeIDs) },
+ "name=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(cmd, s, completeNames) },
"status=": func(_ string) ([]string, cobra.ShellCompDirective) {
return containerStatuses, cobra.ShellCompDirectiveNoFileComp
},
- "ancestor": func(s string) ([]string, cobra.ShellCompDirective) { return getImages(s) },
- "before=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(s, completeDefault) },
- "since=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(s, completeDefault) },
- "volume=": func(s string) ([]string, cobra.ShellCompDirective) { return getVolumes(s) },
+ "ancestor": func(s string) ([]string, cobra.ShellCompDirective) { return getImages(cmd, s) },
+ "before=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(cmd, s, completeDefault) },
+ "since=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(cmd, s, completeDefault) },
+ "volume=": func(s string) ([]string, cobra.ShellCompDirective) { return getVolumes(cmd, s) },
"health=": func(_ string) ([]string, cobra.ShellCompDirective) {
return []string{define.HealthCheckHealthy,
define.HealthCheckUnhealthy}, cobra.ShellCompDirectiveNoFileComp
@@ -776,14 +879,14 @@ func AutocompletePsFilters(cmd *cobra.Command, args []string, toComplete string)
// AutocompletePodPsFilters - Autocomplete pod ps filter options.
func AutocompletePodPsFilters(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
kv := keyValueCompletion{
- "id=": func(s string) ([]string, cobra.ShellCompDirective) { return getPods(s, completeIDs) },
- "name=": func(s string) ([]string, cobra.ShellCompDirective) { return getPods(s, completeNames) },
+ "id=": func(s string) ([]string, cobra.ShellCompDirective) { return getPods(cmd, s, completeIDs) },
+ "name=": func(s string) ([]string, cobra.ShellCompDirective) { return getPods(cmd, s, completeNames) },
"status=": func(_ string) ([]string, cobra.ShellCompDirective) {
return []string{"stopped", "running",
"paused", "exited", "dead", "created", "degraded"}, cobra.ShellCompDirectiveNoFileComp
},
- "ctr-ids=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(s, completeIDs) },
- "ctr-names=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(s, completeNames) },
+ "ctr-ids=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(cmd, s, completeIDs) },
+ "ctr-names=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(cmd, s, completeNames) },
"ctr-number=": nil,
"ctr-status=": func(_ string) ([]string, cobra.ShellCompDirective) {
return containerStatuses, cobra.ShellCompDirectiveNoFileComp
@@ -792,3 +895,47 @@ func AutocompletePodPsFilters(cmd *cobra.Command, args []string, toComplete stri
}
return completeKeyValues(toComplete, kv)
}
+
+// AutocompleteImageFilters - Autocomplete image ls --filter options.
+func AutocompleteImageFilters(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ getBool := func(_ string) ([]string, cobra.ShellCompDirective) {
+ return []string{"true", "false"}, cobra.ShellCompDirectiveNoFileComp
+ }
+ getImg := func(s string) ([]string, cobra.ShellCompDirective) { return getImages(cmd, s) }
+ kv := keyValueCompletion{
+ "before=": getImg,
+ "since=": getImg,
+ "label=": nil,
+ "reference=": nil,
+ "dangling=": getBool,
+ "readonly=": getBool,
+ }
+ return completeKeyValues(toComplete, kv)
+}
+
+// AutocompleteNetworkFilters - Autocomplete network ls --filter options.
+func AutocompleteNetworkFilters(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ kv := keyValueCompletion{
+ "name=": func(s string) ([]string, cobra.ShellCompDirective) { return getNetworks(cmd, s) },
+ "plugin=": nil,
+ }
+ return completeKeyValues(toComplete, kv)
+}
+
+// AutocompleteVolumeFilters - Autocomplete volume ls --filter options.
+func AutocompleteVolumeFilters(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ local := func(_ string) ([]string, cobra.ShellCompDirective) {
+ return []string{"local"}, cobra.ShellCompDirectiveNoFileComp
+ }
+ kv := keyValueCompletion{
+ "name=": func(s string) ([]string, cobra.ShellCompDirective) { return getVolumes(cmd, s) },
+ "driver=": local,
+ "scope=": local,
+ "label=": nil,
+ "opt=": nil,
+ "dangling=": func(_ string) ([]string, cobra.ShellCompDirective) {
+ return []string{"true", "false"}, cobra.ShellCompDirectiveNoFileComp
+ },
+ }
+ return completeKeyValues(toComplete, kv)
+}
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index f34666fff..6dc43dbc6 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -134,10 +134,9 @@ func stringMaptoArray(m map[string]string) []string {
// a specgen spec.
func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroupsManager string) (*ContainerCLIOpts, []string, error) {
var (
- aliases []string
capAdd []string
cappDrop []string
- entrypoint string
+ entrypoint *string
init bool
specPorts []specgen.PortMapping
)
@@ -181,13 +180,14 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup
// marshall it to json; otherwise it should just be the string
// value
if len(cc.Config.Entrypoint) > 0 {
- entrypoint = cc.Config.Entrypoint[0]
+ entrypoint = &cc.Config.Entrypoint[0]
if len(cc.Config.Entrypoint) > 1 {
b, err := json.Marshal(cc.Config.Entrypoint)
if err != nil {
return nil, nil, err
}
- entrypoint = string(b)
+ var jsonString = string(b)
+ entrypoint = &jsonString
}
}
@@ -211,7 +211,7 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup
mounts = append(mounts, mount)
}
- //volumes
+ // volumes
volumes := make([]string, 0, len(cc.Config.Volumes))
for v := range cc.Config.Volumes {
volumes = append(volumes, v)
@@ -241,16 +241,6 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup
}
}
- // network names
- endpointsConfig := cc.NetworkingConfig.EndpointsConfig
- cniNetworks := make([]string, 0, len(endpointsConfig))
- for netName, endpoint := range endpointsConfig {
- cniNetworks = append(cniNetworks, netName)
- if len(endpoint.Aliases) > 0 {
- aliases = append(aliases, endpoint.Aliases...)
- }
- }
-
// netMode
nsmode, _, err := specgen.ParseNetworkNamespace(cc.HostConfig.NetworkMode.NetworkName())
if err != nil {
@@ -267,8 +257,6 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup
// defined when there is only one network.
netInfo := entities.NetOptions{
AddHosts: cc.HostConfig.ExtraHosts,
- Aliases: aliases,
- CNINetworks: cniNetworks,
DNSOptions: cc.HostConfig.DNSOptions,
DNSSearch: cc.HostConfig.DNSSearch,
DNSServers: dns,
@@ -276,31 +264,58 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup
PublishPorts: specPorts,
}
- // static IP and MAC
- if len(endpointsConfig) == 1 {
- for _, ep := range endpointsConfig {
- // if IP address is provided
- if len(ep.IPAddress) > 0 {
- staticIP := net.ParseIP(ep.IPAddress)
- netInfo.StaticIP = &staticIP
+ // network names
+ switch {
+ case len(cc.NetworkingConfig.EndpointsConfig) > 0:
+ var aliases []string
+
+ endpointsConfig := cc.NetworkingConfig.EndpointsConfig
+ cniNetworks := make([]string, 0, len(endpointsConfig))
+ for netName, endpoint := range endpointsConfig {
+
+ cniNetworks = append(cniNetworks, netName)
+
+ if endpoint == nil {
+ continue
+ }
+ if len(endpoint.Aliases) > 0 {
+ aliases = append(aliases, endpoint.Aliases...)
}
- // If MAC address is provided
- if len(ep.MacAddress) > 0 {
- staticMac, err := net.ParseMAC(ep.MacAddress)
- if err != nil {
- return nil, nil, err
+ }
+
+ // static IP and MAC
+ if len(endpointsConfig) == 1 {
+ for _, ep := range endpointsConfig {
+ if ep == nil {
+ continue
+ }
+ // if IP address is provided
+ if len(ep.IPAddress) > 0 {
+ staticIP := net.ParseIP(ep.IPAddress)
+ netInfo.StaticIP = &staticIP
+ }
+ // If MAC address is provided
+ if len(ep.MacAddress) > 0 {
+ staticMac, err := net.ParseMAC(ep.MacAddress)
+ if err != nil {
+ return nil, nil, err
+ }
+ netInfo.StaticMAC = &staticMac
}
- netInfo.StaticMAC = &staticMac
+ break
}
- break
}
+ netInfo.Aliases = aliases
+ netInfo.CNINetworks = cniNetworks
+ case len(cc.HostConfig.NetworkMode) > 0:
+ netInfo.CNINetworks = []string{string(cc.HostConfig.NetworkMode)}
}
// Note: several options here are marked as "don't need". this is based
// on speculation by Matt and I. We think that these come into play later
// like with start. We believe this is just a difference in podman/compat
cliOpts := ContainerCLIOpts{
- //Attach: nil, // dont need?
+ // Attach: nil, // dont need?
Authfile: "",
CapAdd: append(capAdd, cc.HostConfig.CapAdd...),
CapDrop: append(cappDrop, cc.HostConfig.CapDrop...),
@@ -311,18 +326,18 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup
CPURTPeriod: uint64(cc.HostConfig.CPURealtimePeriod),
CPURTRuntime: cc.HostConfig.CPURealtimeRuntime,
CPUShares: uint64(cc.HostConfig.CPUShares),
- //CPUS: 0, // dont need?
+ // CPUS: 0, // dont need?
CPUSetCPUs: cc.HostConfig.CpusetCpus,
CPUSetMems: cc.HostConfig.CpusetMems,
- //Detach: false, // dont need
- //DetachKeys: "", // dont need
+ // Detach: false, // dont need
+ // DetachKeys: "", // dont need
Devices: devices,
DeviceCGroupRule: nil,
DeviceReadBPs: readBps,
DeviceReadIOPs: readIops,
DeviceWriteBPs: writeBps,
DeviceWriteIOPs: writeIops,
- Entrypoint: &entrypoint,
+ Entrypoint: entrypoint,
Env: cc.Config.Env,
Expose: expose,
GroupAdd: cc.HostConfig.GroupAdd,
@@ -437,7 +452,7 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup
}
// specgen assumes the image name is arg[0]
- cmd := []string{cc.Image}
+ cmd := []string{cc.Config.Image}
cmd = append(cmd, cc.Config.Cmd...)
return &cliOpts, cmd, nil
}
diff --git a/cmd/podman/common/createparse.go b/cmd/podman/common/createparse.go
index 09ee5aa0c..3a69f11b6 100644
--- a/cmd/podman/common/createparse.go
+++ b/cmd/podman/common/createparse.go
@@ -9,7 +9,7 @@ import (
// by validate must not need any state information on the flag (i.e. changed)
func (c *ContainerCLIOpts) validate() error {
var ()
- if c.Rm && c.Restart != "" && c.Restart != "no" {
+ if c.Rm && (c.Restart != "" && c.Restart != "no" && c.Restart != "on-failure") {
return errors.Errorf(`the --rm option conflicts with --restart, when the restartPolicy is not "" and "no"`)
}
diff --git a/cmd/podman/common/volumes.go b/cmd/podman/common/volumes.go
index 0468f15e0..dfbb7b1b2 100644
--- a/cmd/podman/common/volumes.go
+++ b/cmd/podman/common/volumes.go
@@ -323,8 +323,8 @@ func getBindMount(args []string) (spec.Mount, error) {
if len(kv) == 1 {
return newMount, errors.Wrapf(optionArgError, kv[0])
}
- if err := parse.ValidateVolumeHostDir(kv[1]); err != nil {
- return newMount, err
+ if len(kv[1]) == 0 {
+ return newMount, errors.Wrapf(optionArgError, "host directory cannot be empty")
}
newMount.Source = kv[1]
setSource = true
diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go
index dcbd5657a..5d08e6163 100644
--- a/cmd/podman/containers/ps.go
+++ b/cmd/podman/containers/ps.go
@@ -29,15 +29,25 @@ var (
psDescription = "Prints out information about the containers"
psCommand = &cobra.Command{
Use: "ps [options]",
- Args: validate.NoArgs,
Short: "List containers",
Long: psDescription,
RunE: ps,
+ Args: validate.NoArgs,
ValidArgsFunction: completion.AutocompleteNone,
Example: `podman ps -a
podman ps -a --format "{{.ID}} {{.Image}} {{.Labels}} {{.Mounts}}"
podman ps --size --sort names`,
}
+
+ psContainerCommand = &cobra.Command{
+ Use: psCommand.Use,
+ Short: psCommand.Short,
+ Long: psCommand.Long,
+ RunE: psCommand.RunE,
+ Args: psCommand.Args,
+ ValidArgsFunction: psCommand.ValidArgsFunction,
+ Example: strings.ReplaceAll(psCommand.Example, "podman ps", "podman container ps"),
+ }
)
var (
listOpts = entities.ContainerListOptions{
@@ -54,6 +64,14 @@ func init() {
})
listFlagSet(psCommand)
validate.AddLatestFlag(psCommand, &listOpts.Latest)
+
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: psContainerCommand,
+ Parent: containerCmd,
+ })
+ listFlagSet(psContainerCommand)
+ validate.AddLatestFlag(psContainerCommand, &listOpts.Latest)
}
func listFlagSet(cmd *cobra.Command) {
diff --git a/cmd/podman/containers/top.go b/cmd/podman/containers/top.go
index 3eb6d2af2..e691f527a 100644
--- a/cmd/podman/containers/top.go
+++ b/cmd/podman/containers/top.go
@@ -18,12 +18,10 @@ import (
)
var (
- topDescription = `Similar to system "top" command.
-
- Specify format descriptors to alter the output.
-
- Running "podman top -l pid pcpu seccomp" will print the process ID, the CPU percentage and the seccomp mode of each process of the latest container.`
+ topDescription = `Display the running processes of a container.
+ The top command extends the ps(1) compatible AIX descriptors with container-specific ones as shown below. In the presence of ps(1) specific flags (e.g, -eo), Podman will execute ps(1) inside the container.
+`
topOptions = entities.TopOptions{}
topCommand = &cobra.Command{
@@ -32,7 +30,7 @@ var (
Long: topDescription,
RunE: top,
Args: cobra.ArbitraryArgs,
- ValidArgsFunction: common.AutocompleteContainersRunning,
+ ValidArgsFunction: common.AutocompleteTopCmd,
Example: `podman top ctrID
podman top --latest
podman top ctrID pid seccomp args %C
diff --git a/cmd/podman/images/list.go b/cmd/podman/images/list.go
index 4692699f2..bcb31e6ee 100644
--- a/cmd/podman/images/list.go
+++ b/cmd/podman/images/list.go
@@ -79,8 +79,7 @@ func imageListFlagSet(cmd *cobra.Command) {
filterFlagName := "filter"
flags.StringSliceVarP(&listOptions.Filter, filterFlagName, "f", []string{}, "Filter output based on conditions provided (default [])")
- // TODO: add completion function for filters
- _ = cmd.RegisterFlagCompletionFunc(filterFlagName, completion.AutocompleteNone)
+ _ = cmd.RegisterFlagCompletionFunc(filterFlagName, common.AutocompleteImageFilters)
formatFlagName := "format"
flags.StringVar(&listFlag.format, formatFlagName, "", "Change the output format to JSON or a Go template")
diff --git a/cmd/podman/images/load.go b/cmd/podman/images/load.go
index a7884f4c5..a24f46781 100644
--- a/cmd/podman/images/load.go
+++ b/cmd/podman/images/load.go
@@ -23,7 +23,7 @@ var (
loadDescription = "Loads an image from a locally stored archive (tar file) into container storage."
loadCommand = &cobra.Command{
Use: "load [options] [NAME[:TAG]]",
- Short: "Load an image from container archive",
+ Short: "Load image(s) from a tar archive",
Long: loadDescription,
RunE: load,
Args: cobra.MaximumNArgs(1),
diff --git a/cmd/podman/networks/connect.go b/cmd/podman/networks/connect.go
index a7636688c..8afc0c7c0 100644
--- a/cmd/podman/networks/connect.go
+++ b/cmd/podman/networks/connect.go
@@ -17,7 +17,7 @@ var (
RunE: networkConnect,
Example: `podman network connect web secondary`,
Args: cobra.ExactArgs(2),
- ValidArgsFunction: common.AutocompleteNetworks,
+ ValidArgsFunction: common.AutocompleteNetworkConnectCmd,
}
)
diff --git a/cmd/podman/networks/disconnect.go b/cmd/podman/networks/disconnect.go
index 598c23a1c..a30315774 100644
--- a/cmd/podman/networks/disconnect.go
+++ b/cmd/podman/networks/disconnect.go
@@ -17,7 +17,7 @@ var (
RunE: networkDisconnect,
Example: `podman network disconnect web secondary`,
Args: cobra.ExactArgs(2),
- ValidArgsFunction: common.AutocompleteNetworks,
+ ValidArgsFunction: common.AutocompleteNetworkConnectCmd,
}
)
diff --git a/cmd/podman/networks/list.go b/cmd/podman/networks/list.go
index f2a5a431a..dcba3f186 100644
--- a/cmd/podman/networks/list.go
+++ b/cmd/podman/networks/list.go
@@ -46,7 +46,7 @@ func networkListFlags(flags *pflag.FlagSet) {
filterFlagName := "filter"
flags.StringVarP(&networkListOptions.Filter, filterFlagName, "", "", "Provide filter values (e.g. 'name=podman')")
- _ = networklistCommand.RegisterFlagCompletionFunc(filterFlagName, completion.AutocompleteNone)
+ _ = networklistCommand.RegisterFlagCompletionFunc(filterFlagName, common.AutocompleteNetworkFilters)
}
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index 449d60bb9..d997ea344 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -94,7 +94,7 @@ func init() {
flags.StringVar(&podIDFile, podIDFileFlagName, "", "Write the pod ID to the file")
_ = createCommand.RegisterFlagCompletionFunc(podIDFileFlagName, completion.AutocompleteDefault)
- flags.BoolVar(&replace, "replace", false, "If a pod with the same exists, replace it")
+ flags.BoolVar(&replace, "replace", false, "If a pod with the same name exists, replace it")
shareFlagName := "share"
flags.StringVar(&share, shareFlagName, specgen.DefaultKernelNamespaces, "A comma delimited list of kernel namespaces the pod will share")
diff --git a/cmd/podman/pods/top.go b/cmd/podman/pods/top.go
index 45ef1e7c2..829882080 100644
--- a/cmd/podman/pods/top.go
+++ b/cmd/podman/pods/top.go
@@ -29,7 +29,7 @@ var (
Long: topDescription,
RunE: top,
Args: cobra.ArbitraryArgs,
- ValidArgsFunction: common.AutocompletePodsRunning,
+ ValidArgsFunction: common.AutocompleteTopCmd,
Example: `podman pod top podID
podman pod top --latest
podman pod top podID pid seccomp args %C
diff --git a/cmd/podman/root.go b/cmd/podman/root.go
index 34d92cd0f..7840e6100 100644
--- a/cmd/podman/root.go
+++ b/cmd/podman/root.go
@@ -113,33 +113,9 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error {
return nil
}
- // Special case if command is hidden completion command ("__complete","__completeNoDesc")
- // Since __completeNoDesc is an alias the cm.Name is always __complete
- if cmd.Name() == cobra.ShellCompRequestCmd {
- // Parse the cli arguments after the the completion cmd (always called as second argument)
- // This ensures that the --url, --identity and --connection flags are properly set
- compCmd, _, err := cmd.Root().Traverse(os.Args[2:])
- if err != nil {
- return err
- }
- // If we don't complete the root cmd hide all root flags
- // so they won't show up in the completions on subcommands.
- if compCmd != compCmd.Root() {
- compCmd.Root().Flags().VisitAll(func(flag *pflag.Flag) {
- flag.Hidden = true
- })
- }
- // No need for further setup when completing commands with subcommands.
- if compCmd.HasSubCommands() {
- requireCleanup = false
- return nil
- }
- }
-
cfg := registry.PodmanConfig()
// --connection is not as "special" as --remote so we can wait and process it here
- var connErr error
conn := cmd.Root().LocalFlags().Lookup("connection")
if conn != nil && conn.Changed {
cfg.Engine.ActiveService = conn.Value.String()
@@ -147,19 +123,37 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error {
var err error
cfg.URI, cfg.Identity, err = cfg.ActiveDestination()
if err != nil {
- connErr = errors.Wrap(err, "failed to resolve active destination")
+ return errors.Wrap(err, "failed to resolve active destination")
}
if err := cmd.Root().LocalFlags().Set("url", cfg.URI); err != nil {
- connErr = errors.Wrap(err, "failed to override --url flag")
+ return errors.Wrap(err, "failed to override --url flag")
}
if err := cmd.Root().LocalFlags().Set("identity", cfg.Identity); err != nil {
- connErr = errors.Wrap(err, "failed to override --identity flag")
+ return errors.Wrap(err, "failed to override --identity flag")
}
}
- if connErr != nil {
- return connErr
+
+ // Special case if command is hidden completion command ("__complete","__completeNoDesc")
+ // Since __completeNoDesc is an alias the cm.Name is always __complete
+ if cmd.Name() == cobra.ShellCompRequestCmd {
+ // Parse the cli arguments after the the completion cmd (always called as second argument)
+ // This ensures that the --url, --identity and --connection flags are properly set
+ compCmd, _, err := cmd.Root().Traverse(os.Args[2:])
+ if err != nil {
+ return err
+ }
+ // If we don't complete the root cmd hide all root flags
+ // so they won't show up in the completions on subcommands.
+ if compCmd != compCmd.Root() {
+ compCmd.Root().Flags().VisitAll(func(flag *pflag.Flag) {
+ flag.Hidden = true
+ })
+ }
+ // No need for further setup the completion logic setups the engines as needed.
+ requireCleanup = false
+ return nil
}
// Prep the engines
diff --git a/cmd/podman/volumes/list.go b/cmd/podman/volumes/list.go
index b0d999765..7e54de38a 100644
--- a/cmd/podman/volumes/list.go
+++ b/cmd/podman/volumes/list.go
@@ -56,7 +56,7 @@ func init() {
filterFlagName := "filter"
flags.StringSliceVarP(&cliOpts.Filter, filterFlagName, "f", []string{}, "Filter volume output")
- _ = lsCommand.RegisterFlagCompletionFunc(filterFlagName, completion.AutocompleteNone)
+ _ = lsCommand.RegisterFlagCompletionFunc(filterFlagName, common.AutocompleteVolumeFilters)
formatFlagName := "format"
flags.StringVar(&cliOpts.Format, formatFlagName, "{{.Driver}}\t{{.Name}}\n", "Format volume output using Go template")
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index ee8ce4d45..7886a483b 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -42,7 +42,7 @@ Epoch: 99
%else
Epoch: 0
%endif
-Version: 2.2.0
+Version: 3.0.0
Release: #COMMITDATE#.git%{shortcommit0}%{?dist}
Summary: Manage Pods, Containers and Container Images
License: ASL 2.0
diff --git a/contrib/systemd/system/podman.service b/contrib/systemd/system/podman.service
index e14bbe078..9b5a1a87f 100644
--- a/contrib/systemd/system/podman.service
+++ b/contrib/systemd/system/podman.service
@@ -8,4 +8,5 @@ StartLimitIntervalSec=0
[Service]
Type=notify
KillMode=process
-ExecStart=/usr/bin/podman system service
+Environment=LOGGING="--log-level=info"
+ExecStart=/usr/bin/podman $LOGGING system service
diff --git a/docs/source/Tutorials.rst b/docs/source/Tutorials.rst
index 83818e3ae..e3e869d5b 100644
--- a/docs/source/Tutorials.rst
+++ b/docs/source/Tutorials.rst
@@ -2,7 +2,7 @@
Tutorials
=========
-Here are a number of useful tutorials to get you up and running with Podman. If you are familiar with the Docker `Container Engine`_ the command in Podman_ should be quite familiar. If are brand new to containers, take a look at our `Introduction`.
+Here are a number of useful tutorials to get you up and running with Podman. If you are familiar with the Docker `Container Engine`_ the command in Podman_ should be quite familiar. If you are brand new to containers, take a look at our `Introduction`.
* `Basic Setup and Use of Podman <https://github.com/containers/podman/blob/master/docs/tutorials/podman_tutorial.md>`_: Learn how to setup Podman and perform some basic commands with the utility.
* `Basic Setup and Use of Podman in a Rootless environment <https://github.com/containers/podman/blob/master/docs/tutorials/rootless_tutorial.md>`_: The steps required to setup rootless Podman are enumerated.
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 368d7cc29..e3715937d 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -28,11 +28,11 @@ author = "team"
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
- 'sphinx_markdown_tables',
+ "sphinx_markdown_tables",
]
source_parsers = {
- '.md': 'recommonmark.parser.CommonMarkParser',
+ ".md": "recommonmark.parser.CommonMarkParser",
}
diff --git a/docs/source/managecontainers.rst b/docs/source/managecontainers.rst
index 849fd1d25..9926f9996 100644
--- a/docs/source/managecontainers.rst
+++ b/docs/source/managecontainers.rst
@@ -39,6 +39,8 @@ Manage Containers
:doc:`prune <markdown/podman-container-prune.1>` Remove all stopped containers
+:doc:`ps <markdown/podman-ps.1>` List containers
+
:doc:`restart <markdown/podman-restart.1>` Restart one or more containers
:doc:`restore <markdown/podman-container-restore.1>` Restores one or more containers from a checkpoint
diff --git a/docs/source/markdown/links/podman-list.1 b/docs/source/markdown/links/podman-list.1
deleted file mode 100644
index f7f44c704..000000000
--- a/docs/source/markdown/links/podman-list.1
+++ /dev/null
@@ -1 +0,0 @@
-.so man1/podman-ps.1
diff --git a/docs/source/markdown/links/podman-ls.1 b/docs/source/markdown/links/podman-ls.1
deleted file mode 100644
index f7f44c704..000000000
--- a/docs/source/markdown/links/podman-ls.1
+++ /dev/null
@@ -1 +0,0 @@
-.so man1/podman-ps.1
diff --git a/docs/source/markdown/podman-build.1.md b/docs/source/markdown/podman-build.1.md
index 4570bf3ff..c71f4fae9 100644
--- a/docs/source/markdown/podman-build.1.md
+++ b/docs/source/markdown/podman-build.1.md
@@ -317,6 +317,10 @@ Pass through HTTP Proxy environment variables.
Write the image ID to the file.
+#### **--ignorefile**
+
+Path to an alternative .dockerignore file.
+
#### **--ipc**=*how*
Sets the configuration for IPC namespaces when handling `RUN` instructions.
@@ -844,9 +848,10 @@ $ podman build -f dev/Containerfile https://10.10.10.1/podman/context.tar.gz
### `.dockerignore`
-If the file .dockerignore exists in the context directory, `podman build` reads
-its contents. Podman uses the content to exclude files and directories from
-the context directory, when executing COPY and ADD directives in the
+If the file .dockerignore exists in the context directory, `buildah copy` reads
+its contents. Use the `--ignorefile` flag to override .dockerignore path location.
+Podman uses the content to exclude files and directories from the context
+directory, when executing COPY and ADD directives in the
Containerfile/Dockerfile
Users can specify a series of Unix shell globals in a .dockerignore file to
diff --git a/docs/source/markdown/podman-container.1.md b/docs/source/markdown/podman-container.1.md
index 0a6ceea33..9da5db601 100644
--- a/docs/source/markdown/podman-container.1.md
+++ b/docs/source/markdown/podman-container.1.md
@@ -32,6 +32,7 @@ The container command allows you to manage containers
| pause | [podman-pause(1)](podman-pause.1.md) | Pause one or more containers. |
| port | [podman-port(1)](podman-port.1.md) | List port mappings for the container. |
| prune | [podman-container-prune(1)](podman-container-prune.1.md)| Remove all stopped containers from local storage. |
+| ps | [podman-ps(1)](podman-ps.1.md) | Prints out information about containers. |
| restart | [podman-restart(1)](podman-restart.1.md) | Restart one or more containers. |
| restore | [podman-container-restore(1)](podman-container-restore.1.md) | Restores one or more containers from a checkpoint. |
| rm | [podman-rm(1)](podman-rm.1.md) | Remove one or more containers. |
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index 8251ba3b6..f280087c2 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -22,12 +22,54 @@ Default settings for flags are defined in `containers.conf`. Most settings for
remote connections use the server's containers.conf, except when documented in
man pages.
+## IMAGE
+
+ The image is specified using transport:path format. If no transport is specified, the `docker` (container registry)
+transport will be used by default. For remote Podman, `docker` is the only allowed transport.
+
+ **dir:**_path_
+ An existing local directory _path_ storing the manifest, layer tarballs and signatures as individual files. This
+is a non-standardized format, primarily useful for debugging or noninvasive container inspection.
+
+ $ podman save --format docker-dir fedora -o /tmp/fedora
+ $ podman create dir:/tmp/fedora echo hello
+
+ **docker://**_docker-reference_ (Default)
+ An image reference stored in a remote container image registry. Example: "quay.io/podman/stable:latest".
+The reference can include a path to a specific registry; if it does not, the
+registries listed in registries.conf will be queried to find a matching image.
+By default, credentials from `podman login` (stored at
+$XDG_RUNTIME_DIR/containers/auth.json by default) will be used to authenticate;
+otherwise it falls back to using credentials in $HOME/.docker/config.json.
+
+ $ podman create registry.fedoraproject.org/fedora:latest echo hello
+
+ **docker-archive:**_path_[**:**_docker-reference_]
+An image stored in the `docker save` formatted file. _docker-reference_ is only used when creating such a
+file, and it must not contain a digest.
+
+ $ podman save --format docker-archive fedora -o /tmp/fedora
+ $ podman create docker-archive:/tmp/fedora echo hello
+
+ **docker-daemon:**_docker-reference_
+ An image in _docker-reference_ format stored in the docker daemon internal storage. The _docker-reference_ can also be an image ID (docker-daemon:algo:digest).
+
+ $ sudo docker pull fedora
+ $ sudo podman create docker-daemon:docker.io/library/fedora echo hello
+
+ **oci-archive:**_path_**:**_tag_
+ An image in a directory compliant with the "Open Container Image Layout Specification" at the specified _path_
+and specified with a _tag_.
+
+ $ podman save --format oci-archive fedora -o /tmp/fedora
+ $ podman create oci-archive:/tmp/fedora echo hello
+
## OPTIONS
#### **--add-host**=*host*
Add a custom host-to-IP mapping (host:ip)
-Add a line to /etc/hosts. The format is hostname:ip. The **--add-host**
+Add a line to /etc/hosts. The format is hostname:ip. The **--add-host**
option can be set multiple times.
#### **--annotation**=*key=value*
@@ -77,7 +119,7 @@ Set the cgroup namespace mode for the container.
**ns:<PATH>**: join the namespace at the specified path.
**private**: create a new cgroup namespace.
-If the host uses cgroups v1, the default is set to **host**. On cgroups v2 the default is **private**.
+If the host uses cgroups v1, the default is set to **host**. On cgroups v2 the default is **private**.
#### **--cgroups**=*mode*
@@ -87,7 +129,7 @@ Valid values are *enabled*, *disabled*, *no-conmon*, *split*, which the default
The *enabled* option will create a new cgroup under the cgroup-parent.
The *disabled* option will force the container to not create CGroups, and thus conflicts with CGroup options (**--cgroupns** and **--cgroup-parent**).
The *no-conmon* option disables a new CGroup only for the conmon process.
-The *split* option splits the current cgroup in two sub-cgroups: one for conmon and one for the container payload. It is not possible to set *--cgroup-parent* with *split*.
+The *split* option splits the current cgroup in two sub-cgroups: one for conmon and one for the container payload. It is not possible to set *--cgroup-parent* with *split*.
#### **--cgroup-parent**=*path*
@@ -95,7 +137,7 @@ Path to cgroups under which the cgroup for the container will be created. If the
#### **--cgroup-conf**=*KEY=VALUE*
-When running on cgroup v2, specify the cgroup file to write to and its value. For example **--cgroup-conf=memory.high=1073741824** sets the memory.high limit to 1GB.
+When running on cgroup v2, specify the cgroup file to write to and its value. For example **--cgroup-conf=memory.high=1073741824** sets the memory.high limit to 1GB.
#### **--cidfile**=*id*
@@ -248,7 +290,7 @@ Limit write rate (IO per second) to a device (e.g. --device-write-iops=/dev/sda:
#### **--disable-content-trust**
This is a Docker specific option to disable image verification to a Docker
-registry and is not supported by Podman. This flag is a NOOP and provided
+registry and is not supported by Podman. This flag is a NOOP and provided
solely for scripting compatibility.
#### **--dns**=*dns*
@@ -292,7 +334,7 @@ You need to specify multi option commands in the form of a json string.
Set environment variables
-This option allows arbitrary environment variables that are available for the process to be launched inside of the container. If an environment variable is specified without a value, Podman will check the host environment for a value and set the variable only if it is set on the host. If an environment variable ending in __*__ is specified, Podman will search the host environment for variables starting with the prefix and will add those variables to the container. If an environment variable with a trailing ***** is specified, then a value must be supplied.
+This option allows arbitrary environment variables that are available for the process to be launched inside of the container. If an environment variable is specified without a value, Podman will check the host environment for a value and set the variable only if it is set on the host. If an environment variable ending in __*__ is specified, Podman will search the host environment for variables starting with the prefix and will add those variables to the container. If an environment variable with a trailing ***** is specified, then a value must be supplied.
See [**Environment**](#environment) note below for precedence and examples.
@@ -311,7 +353,7 @@ on the host system.
#### **--gidmap**=*container_gid:host_gid:amount*
-GID map for the user namespace. Using this flag will run the container with user namespace enabled. It conflicts with the `--userns` and `--subgidname` flags.
+GID map for the user namespace. Using this flag will run the container with user namespace enabled. It conflicts with the `--userns` and `--subgidname` flags.
The following example maps uids 0-2000 in the container to the uids 30000-31999 on the host and gids 0-2000 in the container to the gids 30000-31999 on the host. `--gidmap=0:30000:2000`
@@ -322,8 +364,8 @@ Add additional groups to run as
#### **--health-cmd**=*"command"* | *'["command", "arg1", ...]'*
Set or alter a healthcheck command for a container. The command is a command to be executed inside your
-container that determines your container health. The command is required for other healthcheck options
-to be applied. A value of `none` disables existing healthchecks.
+container that determines your container health. The command is required for other healthcheck options
+to be applied. A value of `none` disables existing healthchecks.
Multiple options can be passed in the form of a JSON array; otherwise, the command will be interpreted
as an argument to `/bin/sh -c`.
@@ -334,17 +376,17 @@ Set an interval for the healthchecks (a value of `disable` results in no automat
#### **--health-retries**=*retries*
-The number of retries allowed before a healthcheck is considered to be unhealthy. The default value is `3`.
+The number of retries allowed before a healthcheck is considered to be unhealthy. The default value is `3`.
#### **--health-start-period**=*period*
The initialization time needed for a container to bootstrap. The value can be expressed in time format like
-`2m3s`. The default value is `0s`
+`2m3s`. The default value is `0s`
#### **--health-timeout**=*timeout*
-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`.
+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**
@@ -359,13 +401,13 @@ Print usage statement
#### **--http-proxy**=*true|false*
By default proxy environment variables are passed into the container if set
-for the Podman process. This can be disabled by setting the `--http-proxy`
-option to `false`. The environment variables passed in include `http_proxy`,
+for the Podman process. This can be disabled by setting the `--http-proxy`
+option to `false`. The environment variables passed in include `http_proxy`,
`https_proxy`, `ftp_proxy`, `no_proxy`, and also the upper case versions of
-those. This option is only needed when the host system must use a proxy but
-the container should not use any proxy. Proxy environment variables specified
+those. This option is only needed when the host system must use a proxy but
+the container should not use any proxy. Proxy environment variables specified
for the container in any other way will override the values that would have
-been passed through from the host. (Other ways to specify the proxy for the
+been passed through from the host. (Other ways to specify the proxy for the
container include passing the values with the `--env` flag, or hard coding the
proxy environment at container build time.) (Not available for remote commands)
@@ -411,9 +453,9 @@ The address must be within the CNI network's IP address pool (default **10.88.0.
#### **--ipc**=*ipc*
Default is to create a private IPC namespace (POSIX SysV IPC) for the container
- 'container:<name|id>': reuses another container shared memory, semaphores and message queues
- 'host': use the host shared memory,semaphores and message queues inside the container. Note: the host mode gives the container full access to local shared memory and is therefore considered insecure.
- 'ns:<path>' path to an IPC namespace to join.
+ 'container:<name|id>': reuses another container shared memory, semaphores and message queues
+ 'host': use the host shared memory,semaphores and message queues inside the container. Note: the host mode gives the container full access to local shared memory and is therefore considered insecure.
+ 'ns:<path>' path to an IPC namespace to join.
#### **--kernel-memory**=*number[unit]*
@@ -439,7 +481,7 @@ Not implemented
#### **--log-driver**="*k8s-file*"
-Logging driver for the container. Currently available options are *k8s-file*, *journald*, and *none*, with *json-file* aliased to *k8s-file* for scripting compatibility.
+Logging driver for the container. Currently available options are *k8s-file*, *journald*, and *none*, with *json-file* aliased to *k8s-file* for scripting compatibility.
#### **--log-opt**=*name*=*value*
@@ -496,7 +538,7 @@ as memory limit.
A limit value equal to memory plus swap. Must be used with the **-m**
(**--memory**) flag. The swap `LIMIT` should always be larger than **-m**
-(**--memory**) value. By default, the swap `LIMIT` will be set to double
+(**--memory**) value. By default, the swap `LIMIT` will be set to double
the value of --memory.
The format of `LIMIT` is `<number>[<unit>]`. Unit can be `b` (bytes),
@@ -547,7 +589,7 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
· bind-propagation: shared, slave, private, unbindable, rshared, rslave, runbindable, or rprivate(default). See also mount(2).
- . bind-nonrecursive: do not setup a recursive bind mount. By default it is recursive.
+ . bind-nonrecursive: do not setup a recursive bind mount. By default it is recursive.
. relabel: shared, private.
@@ -559,7 +601,7 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
· tmpfs-mode: File mode of the tmpfs in octal. (e.g. 700 or 0700.) Defaults to 1777 in Linux.
- · tmpcopyup: Enable copyup from the image directory at the same location to the tmpfs. Used by default.
+ · tmpcopyup: Enable copyup from the image directory at the same location to the tmpfs. Used by default.
· notmpcopyup: Disable copying files from the image to the tmpfs.
@@ -591,7 +633,7 @@ Valid _mode_ values are:
- _network-id_: connect to a user-defined network, multiple networks should be comma separated;
- **ns:**_path_: path to a network namespace to join;
- **private**: create a new namespace for the container (default)
-- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options:
+- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options:
- **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
- **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`).
- **enable_ipv6=true|false**: Enable IPv6. Default is false. (Required for `outbound_addr6`).
@@ -632,7 +674,7 @@ Override the architecture, defaults to hosts, of the image to be pulled. For exa
Override the OS, defaults to hosts, of the image to be pulled. For example, `windows`.
#### **--override-variant**=*VARIANT*
-Use _VARIANT_ instead of the default architecture variant of the container image. Some images can use multiple variants of the arm architectures, such as arm/v5 and arm/v7.
+Use _VARIANT_ instead of the default architecture variant of the container image. Some images can use multiple variants of the arm architectures, such as arm/v5 and arm/v7.
#### **--pid**=*pid*
@@ -654,7 +696,7 @@ To make a pod with more granular options, use the `podman pod create` command be
#### **--pod-id-file**=*path*
-Run container in an existing pod and read the pod's ID from the specified file. If a container is run within a pod, and the pod has an infra-container, the infra-container will be started before the container is.
+Run container in an existing pod and read the pod's ID from the specified file. If a container is run within a pod, and the pod has an infra-container, the infra-container will be started before the container is.
#### **--privileged**=*true|false*
@@ -688,7 +730,7 @@ If it is not, the container port will be randomly assigned a port on the host.
Use `podman port` to see the actual mapping: `podman port CONTAINER $CONTAINERPORT`
**Note:** if a container will be run within a pod, it is not necessary to publish the port for
-the containers in the pod. The port must only be published by the pod itself. Pod network
+the containers in the pod. The port must only be published by the pod itself. Pod network
stacks act like the network stack on the host - you have a variety of containers in the pod,
and programs in the container, all sharing a single interface and IP address, and
associated ports. If one container binds to a port, no other container can use that port
@@ -725,16 +767,16 @@ Suppress output information when pulling images
Mount the container's root filesystem as read only.
By default a container will have its root filesystem writable allowing processes
-to write files anywhere. By specifying the `--read-only` flag the container will have
+to write files anywhere. By specifying the `--read-only` flag the container will have
its root filesystem mounted as read only prohibiting any writes.
#### **--read-only-tmpfs**=*true|false*
-If container is running in --read-only mode, then mount a read-write tmpfs on /run, /tmp, and /var/tmp. The default is *true*
+If container is running in --read-only mode, then mount a read-write tmpfs on /run, /tmp, and /var/tmp. The default is *true*
#### **--replace**=**true**|**false**
-If another container with the same name already exists, replace and remove it. The default is **false**.
+If another container with the same name already exists, replace and remove it. The default is **false**.
#### **--restart**=*policy*
@@ -772,9 +814,9 @@ of the container is assumed to be managed externally.
Determines how to use the NOTIFY_SOCKET, as passed with systemd and Type=notify.
Default is **container**, which means allow the OCI runtime to proxy the socket into the
-container to receive ready notification. Podman will set the MAINPID to conmon's pid.
+container to receive ready notification. Podman will set the MAINPID to conmon's pid.
The **conmon** option sets MAINPID to conmon's pid, and sends READY when the container
-has started. The socket is never passed to the runtime or the container.
+has started. The socket is never passed to the runtime or the container.
The **ignore** option removes NOTIFY_SOCKET from the environment for itself and child processes,
for the case where some other process above Podman uses NOTIFY_SOCKET and Podman should not use it.
@@ -803,7 +845,7 @@ Security Options
- `seccomp=unconfined` : Turn off seccomp confinement for the container
- `seccomp=profile.json` : White listed syscalls seccomp Json file to be used as a seccomp filter
-- `proc-opts=OPTIONS` : Comma separated list of options to use for the /proc mount. More details for the
+- `proc-opts=OPTIONS` : Comma separated list of options to use for the /proc mount. More details for the
possible mount options are specified at **proc(5)** man page.
Note: Labeling can be disabled for all containers by setting label=false in the **containers.conf** (`/etc/containers/containers.conf` or `$HOME/.config/containers/containers.conf`) file.
@@ -825,11 +867,11 @@ Remote connections use local containers.conf for defaults
#### **--subgidname**=*name*
-Name for GID map from the `/etc/subgid` file. Using this flag will run the container with user namespace enabled. This flag conflicts with `--userns` and `--gidmap`.
+Name for GID map from the `/etc/subgid` file. Using this flag will run the container with user namespace enabled. This flag conflicts with `--userns` and `--gidmap`.
#### **--subuidname**=*name*
-Name for UID map from the `/etc/subuid` file. Using this flag will run the container with user namespace enabled. This flag conflicts with `--userns` and `--uidmap`.
+Name for UID map from the `/etc/subuid` file. Using this flag will run the container with user namespace enabled. This flag conflicts with `--userns` and `--uidmap`.
#### **--sysctl**=*SYSCTL*
@@ -852,7 +894,7 @@ Note: if you use the --network=host option these sysctls will not be allowed.
Run container in systemd mode. The default is *true*.
The value *always* enforces the systemd mode is enforced without
-looking at the executable name. Otherwise, if set to true and the
+looking at the executable name. Otherwise, if set to true and the
command you are running inside the container is systemd, /usr/sbin/init,
/sbin/init or /usr/local/sbin/init.
@@ -866,7 +908,7 @@ It will also set the default stop signal to SIGRTMIN+3.
This allow systemd to run in a confined container without any modifications.
Note: On `SELinux` systems, systemd attempts to write to the cgroup
-file system. Containers writing to the cgroup file system are denied by default.
+file system. Containers writing to the cgroup file system are denied by default.
The `container_manage_cgroup` boolean must be enabled for this to be allowed on an SELinux separated system.
`setsebool -P container_manage_cgroup true`
@@ -879,7 +921,7 @@ Mount a temporary filesystem (`tmpfs`) mount into a container, for example:
$ podman create -d --tmpfs /tmp:rw,size=787448k,mode=1777 my_image
-This command mounts a `tmpfs` at `/tmp` within the container. The supported mount
+This command mounts a `tmpfs` at `/tmp` within the container. The supported mount
options are the same as the Linux default `mount` flags. If you do not specify
any options, the systems uses the following options:
`rw,noexec,nosuid,nodev`.
@@ -907,7 +949,7 @@ Remote connections use local containers.conf for defaults
#### **--uidmap**=*container_uid:host_uid:amount*
-UID map for the user namespace. Using this flag will run the container with user namespace enabled. It conflicts with the `--userns` and `--subuidname` flags.
+UID map for the user namespace. Using this flag will run the container with user namespace enabled. It conflicts with the `--userns` and `--subuidname` flags.
The following example maps uids 0-2000 in the container to the uids 30000-31999 on the host and gids 0-2000 in the container to the gids 30000-31999 on the host. `--uidmap=0:30000:2000`
@@ -933,11 +975,11 @@ Without this argument the command will be run as root in the container.
#### **--userns**=private
#### **--userns**=*ns:my_namespace*
-Set the user namespace mode for the container. It defaults to the **PODMAN_USERNS** environment variable. An empty value means user namespaces are disabled.
+Set the user namespace mode for the container. It defaults to the **PODMAN_USERNS** environment variable. An empty value means user namespaces are disabled.
-- `auto`: automatically create a namespace. It is possible to specify other options to `auto`. The supported options are
- **size=SIZE** to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will guess a size for the user namespace.
+- `auto`: automatically create a namespace. It is possible to specify other options to `auto`. The supported options are
+ **size=SIZE** to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will guess a size for the user namespace.
**uidmapping=HOST_UID:CONTAINER_UID:SIZE** to force a UID mapping to be present in the user namespace.
**gidmapping=HOST_UID:CONTAINER_UID:SIZE** to force a GID mapping to be present in the user namespace.
- `container`: join the user namespace of the specified container.
@@ -946,7 +988,7 @@ Set the user namespace mode for the container. It defaults to the **PODMAN_USER
- `ns`: run the container in the given existing user namespace.
- `private`: create a new namespace for the container (default)
-This option is incompatible with --gidmap, --uidmap, --subuid and --subgid
+This option is incompatible with **--gidmap**, **--uidmap**, **--subuidname** and **--subgidname**.
#### **--uts**=*mode*
@@ -959,9 +1001,9 @@ Set the UTS namespace mode for the container. The following values are supported
#### **--volume**, **-v**[=*[[SOURCE-VOLUME|HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*]
-Create a bind mount. If you specify, ` -v /HOST-DIR:/CONTAINER-DIR`, podman
-bind mounts `/HOST-DIR` in the host to `/CONTAINER-DIR` in the podman
-container. Similarly, `-v SOURCE-VOLUME:/CONTAINER-DIR` will mount the volume
+Create a bind mount. If you specify, ` -v /HOST-DIR:/CONTAINER-DIR`, Podman
+bind mounts `/HOST-DIR` in the host to `/CONTAINER-DIR` in the Podman
+container. Similarly, `-v SOURCE-VOLUME:/CONTAINER-DIR` will mount the volume
in the host to the container. If no such named volume exists, Podman will
create one. The `OPTIONS` are a comma delimited list and can be: <sup>[[1]](#Footnote1)</sup>
@@ -1021,7 +1063,7 @@ Only the current container can use a private volume.
The `:O` flag tells Podman to mount the directory from the host as a
temporary storage using the `overlay file system`. The container processes
can modify content within the mountpoint which is stored in the
-container storage in a separate directory. In overlay terms, the source
+container storage in a separate directory. In overlay terms, the source
directory will be the lower, and the container storage directory will be the
upper. Modifications to the mount point are destroyed when the container
finishes executing, similar to a tmpfs mount point being unmounted.
@@ -1042,7 +1084,7 @@ and can read/write `container_file_t`. If you can not change the labels on a
source volume, SELinux container separation must be disabled for the container
to work.
- The source directory mounted into the container with an overlay mount
-should not be modified, it can cause unexpected failures. It is recommended
+should not be modified, it can cause unexpected failures. It is recommended
that you do not modify the directory until the container finishes running.
`Mounts propagation`
@@ -1065,7 +1107,7 @@ slave volumes, the source mount point has to be either shared or slave.
<sup>[[1]](#Footnote1)</sup>
If you want to recursively mount a volume and all of its submounts into a
-container, then you can use the `rbind` option. By default the bind option is
+container, then you can use the `rbind` option. By default the bind option is
used, and submounts of the source directory will not be mounted into the
container.
@@ -1124,7 +1166,7 @@ default, Podman does not change the labels set by the OS.
To change a label in the container context, you can add `z` to the volume mount.
This suffix tells Podman to relabel file objects on the shared volumes. The `z`
option tells Podman that two containers share the volume content. As a result,
-podman labels the content with a shared content label. Shared volume labels allow
+Podman labels the content with a shared content label. Shared volume labels allow
all containers to read/write content.
If the location of the volume from the source container overlaps with
@@ -1179,7 +1221,7 @@ $ podman create --tz=US/Eastern alpine date
### Rootless Containers
Podman runs as a non root user on most systems. This feature requires that a new enough version of shadow-utils
-be installed. The shadow-utils package must include the newuidmap and newgidmap executables.
+be installed. The shadow-utils package must include the newuidmap and newgidmap executables.
Note: RHEL7 and Centos 7 will not have this feature until RHEL7.7 is released.
@@ -1199,7 +1241,7 @@ Precedence order (later entries override earlier entries):
- **--env-host** : Host environment of the process executing Podman is added.
- **--http-proxy**: By default, several environment variables will be passed in from the host, such as **http_proxy** and **no_proxy**. See **--http-proxy** for details.
- Container image : Any environment variables specified in the container image.
-- **--env-file** : Any environment variables specified via env-files. If multiple files specified, then they override each other in order of entry.
+- **--env-file** : Any environment variables specified via env-files. If multiple files specified, then they override each other in order of entry.
- **--env** : Any environment variables specified will override previous settings.
Create containers and set the environment ending with a __*__ and a *****
@@ -1223,7 +1265,8 @@ b
NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`.
## SEE ALSO
-**subgid**(5), **subuid**(5), **containers.conf**(5), **systemd.unit**(5), **setsebool**(8), **slirp4netns**(1), **fuse-overlayfs**(1), **proc**(5)**.
+**podman**(1), **podman-save**(1), **podman-ps**(1), **podman-attach**(1), **podman-pod-create**(1), **podman-port**(1), **podman-kill**(1), **podman-stop**(1),
+**podman-generate-systemd**(1) **podman-rm**(1), **subgid**(5), **subuid**(5), **containers.conf**(5), **systemd.unit**(5), **setsebool**(8), **slirp4netns**(1), **fuse-overlayfs**(1), **proc**(5)**.
## HISTORY
October 2017, converted from Docker documentation to Podman by Dan Walsh for Podman <dwalsh@redhat.com>
diff --git a/docs/source/markdown/podman-export.1.md b/docs/source/markdown/podman-export.1.md
index 647c25770..63989a4db 100644
--- a/docs/source/markdown/podman-export.1.md
+++ b/docs/source/markdown/podman-export.1.md
@@ -12,6 +12,8 @@ podman\-export - Export a container's filesystem contents as a tar archive
**podman export** exports the filesystem of a container and saves it as a tarball
on the local machine. **podman export** writes to STDOUT by default and can be
redirected to a file using the `--output` flag.
+The image of the container exported by **podman export** can be imported by **podman import**.
+To export image(s) with parent layers, use **podman save**.
Note: `:` is a restricted character and cannot be part of the file name.
**podman [GLOBAL OPTIONS]**
diff --git a/docs/source/markdown/podman-import.1.md b/docs/source/markdown/podman-import.1.md
index ebedf90b4..427c67da4 100644
--- a/docs/source/markdown/podman-import.1.md
+++ b/docs/source/markdown/podman-import.1.md
@@ -14,6 +14,7 @@ and saves it as a filesystem image. Remote tarballs can be specified using a URL
Various image instructions can be configured with the **--change** flag and
a commit message can be set using the **--message** flag.
**reference**, if present, is a tag to assign to the image.
+**podman import** is used for importing from the archive generated by **podman export**, that includes the container's filesystem. To import the archive of image layers created by **podman save**, use **podman load**.
Note: `:` is a restricted character and cannot be part of the file name.
## OPTIONS
diff --git a/docs/source/markdown/podman-load.1.md b/docs/source/markdown/podman-load.1.md
index cdc99fbf2..177709a43 100644
--- a/docs/source/markdown/podman-load.1.md
+++ b/docs/source/markdown/podman-load.1.md
@@ -1,7 +1,7 @@
% podman-load(1)
## NAME
-podman\-load - Load an image from a container image archive into container storage
+podman\-load - Load image(s) from a tar archive into container storage
## SYNOPSIS
**podman load** [*options*] [*name*[:*tag*]]
@@ -11,6 +11,7 @@ podman\-load - Load an image from a container image archive into container stora
## DESCRIPTION
**podman load** loads an image from either an **oci-archive** or a **docker-archive** stored on the local machine into container storage. **podman load** reads from stdin by default or a file if the **input** option is set.
You can also specify a name for the image if the archive does not contain a named reference, of if you want an additional name for the local image.
+**podman load** is used for loading from the archive generated by **podman save**, that includes the image parent layers. To load the archive of container's filesystem created by **podman export**, use **podman import**.
The local client further supports loading an **oci-dir** or a **docker-dir** as created with **podman save** (1).
diff --git a/docs/source/markdown/podman-ps.1.md b/docs/source/markdown/podman-ps.1.md
index f542daf4c..b94964f6c 100644
--- a/docs/source/markdown/podman-ps.1.md
+++ b/docs/source/markdown/podman-ps.1.md
@@ -6,15 +6,11 @@ podman\-ps - Prints out information about containers
## SYNOPSIS
**podman ps** [*options*]
-**podman container list** [*options*]
-
-**podman container ls** [*options*]
-
**podman container ps** [*options*]
-**podman list** [*options*]
+**podman container list** [*options*]
-**podman ls** [*options*]
+**podman container ls** [*options*]
## DESCRIPTION
**podman ps** lists the running containers on the system. Use the **--all** flag to view
diff --git a/docs/source/markdown/podman-pull.1.md b/docs/source/markdown/podman-pull.1.md
index 130c54ba9..4495cec3a 100644
--- a/docs/source/markdown/podman-pull.1.md
+++ b/docs/source/markdown/podman-pull.1.md
@@ -27,25 +27,42 @@ Images are stored in local image storage.
## SOURCE
The SOURCE is the location from which the container images are pulled.
- The Image "SOURCE" uses a "transport":"details" format.
+ The Image "SOURCE" uses a "transport":"details" format. Only the `docker` (container registry)
+ transport is allowed for remote access.
Multiple transports are supported:
**dir:**_path_
- An existing local directory _path_ storing the manifest, layer tarballs and signatures as individual files. This is a non-standardized format, primarily useful for debugging or noninvasive container inspection.
+ An existing local directory _path_ storing the manifest, layer tarballs and signatures as individual files. This
+ is a non-standardized format, primarily useful for debugging or noninvasive container inspection.
- **docker://**_docker-reference_
- An image in a registry implementing the "Docker Registry HTTP API V2". By default, uses the authorization state in `$XDG_RUNTIME_DIR/containers/auth.json`, which is set using `(podman login)`. If the authorization state is not found there, `$HOME/.docker/config.json` is checked, which is set using `(docker login)`.
+ $ podman pull dir:/tmp/myimage
+
+ **docker://**_docker-reference_ (Default)
+ An image reference stored in a remote container image registry. The reference can include a path to a
+ specific registry; if it does not, the registries listed in registries.conf will be queried to find a matching
+ image. By default, credentials from podman login (stored at $XDG_RUNTIME_DIR/containers/auth.json by default)
+ will be used to authenticate; if these cannot be found, we will fall back to using credentials in
+ $HOME/.docker/config.json.
+
+ $ podman pull quay.io/username/myimage
**docker-archive:**_path_[**:**_docker-reference_]
- An image is stored in the `docker save` formatted file. _docker-reference_ is only used when creating such a file, and it must not contain a digest.
+ An image is stored in the `docker save` formatted file. _docker-reference_ is only used when creating such a
+ file, and it must not contain a digest.
+
+ $ podman pull docker-archive:/tmp/myimage
**docker-daemon:**_docker-reference_
- An image _docker-reference_ stored in the docker daemon internal storage. _docker-reference_ must contain either a tag or a digest. Alternatively, when reading images, the format can also be docker-daemon:algo:digest (an image ID).
+ An image in _docker-reference_ format stored in the docker daemon internal storage. The _docker-reference_ can also be an image ID (docker-daemon:algo:digest).
+
+ $ sudo podman pull docker-daemon:docker.io/library/myimage:33
**oci-archive:**_path_**:**_tag_
An image _tag_ in a directory compliant with "Open Container Image Layout Specification" at _path_.
+ $ podman pull oci-archive:/tmp/myimage
+
## OPTIONS
#### **--all-tags**, **a**
diff --git a/docs/source/markdown/podman-push.1.md b/docs/source/markdown/podman-push.1.md
index 87e64858c..68ea528cb 100644
--- a/docs/source/markdown/podman-push.1.md
+++ b/docs/source/markdown/podman-push.1.md
@@ -29,18 +29,28 @@ Images are pushed from those stored in local image storage.
**dir:**_path_
An existing local directory _path_ storing the manifest, layer tarballs and signatures as individual files. This is a non-standardized format, primarily useful for debugging or noninvasive container inspection.
+ $ podman push myimage dir:/tmp/myimage
+
**docker://**_docker-reference_
An image in a registry implementing the "Docker Registry HTTP API V2". By default, uses the authorization state in `$XDG_RUNTIME_DIR/containers/auth.json`, which is set using `(podman login)`. If the authorization state is not found there, `$HOME/.docker/config.json` is checked, which is set using `(docker login)`.
+ $ podman push myimage quay.io/username/myimage
+
**docker-archive:**_path_[**:**_docker-reference_]
An image is stored in the `docker save` formatted file. _docker-reference_ is only used when creating such a file, and it must not contain a digest.
+ $ podman push myimage docker-archive:/tmp/myimage
+
**docker-daemon:**_docker-reference_
- An image _docker-reference_ stored in the docker daemon internal storage. _docker-reference_ must contain either a tag or a digest. Alternatively, when reading images, the format can also be docker-daemon:algo:digest (an image ID).
+ An image in _docker-reference_ format stored in the docker daemon internal storage. _docker-reference_ must contain a tag.
+
+ $ sudo podman push myimage docker-daemon:docker.io/library/myimage:33
**oci-archive:**_path_**:**_tag_
An image _tag_ in a directory compliant with "Open Container Image Layout Specification" at _path_.
+ $ podman push myimage oci-archive:/tmp/myimage
+
## OPTIONS
#### **--authfile**=*path*
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index bc3d5a8bb..d65d5d26f 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -16,7 +16,7 @@ which starts the process may define defaults related to the process that will be
run in the container, the networking to expose, and more, but **podman run**
gives final control to the operator or administrator who starts the container
from the image. For that reason **podman run** has more options than any other
-podman command.
+Podman command.
If the _image_ is not already loaded then **podman run** will pull the _image_, and
all image dependencies, from the repository in the same way running **podman
@@ -37,6 +37,48 @@ Default settings are defined in `containers.conf`. Most settings for remote
connections use the servers containers.conf, except when documented in man
pages.
+## IMAGE
+
+ The image is specified using transport:path format. If no transport is specified, the `docker` (container registry)
+transport will be used by default. For remote Podman, `docker` is the only allowed transport.
+
+ **dir:**_path_
+ An existing local directory _path_ storing the manifest, layer tarballs and signatures as individual files. This
+is a non-standardized format, primarily useful for debugging or noninvasive container inspection.
+
+ $ podman save --format docker-dir fedora -o /tmp/fedora
+ $ podman run dir:/tmp/fedora echo hello
+
+ **docker://**_docker-reference_ (Default)
+ An image reference stored in a remote container image registry. Example: "quay.io/podman/stable:latest".
+The reference can include a path to a specific registry; if it does not, the
+registries listed in registries.conf will be queried to find a matching image.
+By default, credentials from `podman login` (stored at
+$XDG_RUNTIME_DIR/containers/auth.json by default) will be used to authenticate;
+otherwise it falls back to using credentials in $HOME/.docker/config.json.
+
+ $ podman run registry.fedoraproject.org/fedora:latest echo hello
+
+ **docker-archive:**_path_[**:**_docker-reference_]
+An image stored in the `docker save` formatted file. _docker-reference_ is only used when creating such a
+file, and it must not contain a digest.
+
+ $ podman save --format docker-archive fedora -o /tmp/fedora
+ $ podman run docker-archive:/tmp/fedora echo hello
+
+ **docker-daemon:**_docker-reference_
+ An image in _docker-reference_ format stored in the docker daemon internal storage. The _docker-reference_ can also be an image ID (docker-daemon:algo:digest).
+
+ $ sudo docker pull fedora
+ $ sudo podman run docker-daemon:docker.io/library/fedora echo hello
+
+ **oci-archive:**_path_**:**_tag_
+ An image in a directory compliant with the "Open Container Image Layout Specification" at the specified _path_
+and specified with a _tag_.
+
+ $ podman save --format oci-archive fedora -o /tmp/fedora
+ $ podman run oci-archive:/tmp/fedora echo hello
+
## OPTIONS
#### **--add-host**=_host_:_ip_
@@ -91,7 +133,7 @@ Set the cgroup namespace mode for the container.
- **private**: create a new cgroup namespace.
- **ns:**_path_: join the namespace at the specified path.
-If the host uses cgroups v1, the default is set to **host**. On cgroups v2, the default is **private**.
+If the host uses cgroups v1, the default is set to **host**. On cgroups v2, the default is **private**.
#### **--cgroups**=**enabled**|**disabled**|**no-conmon**|**split**
@@ -102,7 +144,7 @@ Default is **enabled**.
The **enabled** option will create a new cgroup under the cgroup-parent.
The **disabled** option will force the container to not create CGroups, and thus conflicts with CGroup options (**--cgroupns** and **--cgroup-parent**).
The **no-conmon** option disables a new CGroup only for the **conmon** process.
-The **split** option splits the current cgroup in two sub-cgroups: one for conmon and one for the container payload. It is not possible to set **--cgroup-parent** with **split**.
+The **split** option splits the current cgroup in two sub-cgroups: one for conmon and one for the container payload. It is not possible to set **--cgroup-parent** with **split**.
#### **--cgroup-parent**=*path*
@@ -110,7 +152,7 @@ Path to cgroups under which the cgroup for the container will be created. If the
#### **--cgroup-conf**=*KEY=VALUE*
-When running on cgroup v2, specify the cgroup file to write to and its value. For example **--cgroup-conf=memory.high=1073741824** sets the memory.high limit to 1GB.
+When running on cgroup v2, specify the cgroup file to write to and its value. For example **--cgroup-conf=memory.high=1073741824** sets the memory.high limit to 1GB.
#### **--cidfile**=*file*
@@ -254,7 +296,7 @@ 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**.
Podman may load kernel modules required for using the specified
-device. The devices that podman will load modules when necessary are:
+device. The devices that Podman will load modules when necessary are:
/dev/fuse.
#### **--device-cgroup-rule**=rule
@@ -280,7 +322,7 @@ Limit write rate (in IO operations per second) to a device (e.g. **--device-writ
#### **--disable-content-trust**
This is a Docker specific option to disable image verification to a Docker
-registry and is not supported by Podman. This flag is a NOOP and provided
+registry and is not supported by Podman. This flag is a NOOP and provided
solely for scripting compatibility.
#### **--dns**=*ipaddr*
@@ -326,7 +368,7 @@ You need to specify multi option commands in the form of a json string.
Set environment variables.
-This option allows arbitrary environment variables that are available for the process to be launched inside of the container. If an environment variable is specified without a value, Podman will check the host environment for a value and set the variable only if it is set on the host. If an environment variable ending in __*__ is specified, Podman will search the host environment for variables starting with the prefix and will add those variables to the container. If an environment variable with a trailing ***** is specified, then a value must be supplied.
+This option allows arbitrary environment variables that are available for the process to be launched inside of the container. If an environment variable is specified without a value, Podman will check the host environment for a value and set the variable only if it is set on the host. If an environment variable ending in __*__ is specified, Podman will search the host environment for variables starting with the prefix and will add those variables to the container. If an environment variable with a trailing ***** is specified, then a value must be supplied.
See [**Environment**](#environment) note below for precedence and examples.
@@ -356,8 +398,8 @@ Add additional groups to run as
#### **--health-cmd**=*"command"* | *'["command", "arg1", ...]'*
Set or alter a healthcheck command for a container. The command is a command to be executed inside your
-container that determines your container health. The command is required for other healthcheck options
-to be applied. A value of **none** disables existing healthchecks.
+container that determines your container health. The command is required for other healthcheck options
+to be applied. A value of **none** disables existing healthchecks.
Multiple options can be passed in the form of a JSON array; otherwise, the command will be interpreted
as an argument to **/bin/sh -c**.
@@ -373,12 +415,12 @@ The number of retries allowed before a healthcheck is considered to be unhealthy
#### **--health-start-period**=*period*
The initialization time needed for a container to bootstrap. The value can be expressed in time format like
-**2m3s**. The default value is **0s**.
+**2m3s**. The default value is **0s**.
#### **--health-timeout**=*timeout*
-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**.
+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**.
#### **--help**
@@ -393,13 +435,13 @@ Sets the container host name that is available inside the container. Can only be
#### **--http-proxy**=**true**|**false**
By default proxy environment variables are passed into the container if set
-for the Podman process. This can be disabled by setting the value to **false**.
+for the Podman process. This can be disabled by setting the value to **false**.
The environment variables passed in include **http_proxy**,
**https_proxy**, **ftp_proxy**, **no_proxy**, and also the upper case versions of
-those. This option is only needed when the host system must use a proxy but
-the container should not use any proxy. Proxy environment variables specified
+those. This option is only needed when the host system must use a proxy but
+the container should not use any proxy. Proxy environment variables specified
for the container in any other way will override the values that would have
-been passed through from the host. (Other ways to specify the proxy for the
+been passed through from the host. (Other ways to specify the proxy for the
container include passing the values with the **--env** flag, or hard coding the
proxy environment at container build time.) (Not available for remote commands)
@@ -443,7 +485,7 @@ Set the IPC namespace mode for a container. The default is to create
a private IPC namespace.
- **container:**_id_: reuses another container shared memory, semaphores and message queues
-- **host**: use the host shared memory,semaphores and message queues inside the container. Note: the host mode gives the container full access to local shared memory and is therefore considered insecure.
+- **host**: use the host shared memory,semaphores and message queues inside the container. Note: the host mode gives the container full access to local shared memory and is therefore considered insecure.
- **ns:**_path_: path to an IPC namespace to join.
#### **--kernel-memory**=_number_[_unit_]
@@ -522,9 +564,9 @@ as memory limit.
A limit value equal to memory plus swap.
A _unit_ can be **b** (bytes), **k** (kilobytes), **m** (megabytes), or **g** (gigabytes).
-Must be used with the **-m** (**--memory**) flag.
+Must be used with the **-m** (**--memory**) flag.
The argument value should always be larger than that of
- **-m** (**--memory**). By default, it is set to double
+ **-m** (**--memory**) By default, it is set to double
the value of **--memory**.
Set _number_ to **-1** to enable unlimited swap.
@@ -573,7 +615,7 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
· bind-propagation: shared, slave, private, unbindable, rshared, rslave, runbindable, or rprivate(default). See also mount(2).
- . bind-nonrecursive: do not setup a recursive bind mount. By default it is recursive.
+ . bind-nonrecursive: do not setup a recursive bind mount. By default it is recursive.
. relabel: shared, private.
@@ -585,7 +627,7 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
· tmpfs-mode: File mode of the tmpfs in octal. (e.g. 700 or 0700.) Defaults to 1777 in Linux.
- · tmpcopyup: Enable copyup from the image directory at the same location to the tmpfs. Used by default.
+ · tmpcopyup: Enable copyup from the image directory at the same location to the tmpfs. Used by default.
· notmpcopyup: Disable copying files from the image to the tmpfs.
@@ -617,7 +659,7 @@ Valid _mode_ values are:
- _network-id_: connect to a user-defined network, multiple networks should be comma separated;
- **ns:**_path_: path to a network namespace to join;
- **private**: create a new namespace for the container (default)
-- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options:
+- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options:
- **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
- **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`).
- **enable_ipv6=true|false**: Enable IPv6. Default is false. (Required for `outbound_addr6`).
@@ -659,7 +701,7 @@ Override the architecture, defaults to hosts, of the image to be pulled. For exa
Override the OS, defaults to hosts, of the image to be pulled. For example, `windows`.
#### **--override-variant**=*VARIANT*
-Use _VARIANT_ instead of the default architecture variant of the container image. Some images can use multiple variants of the arm architectures, such as arm/v5 and arm/v7.
+Use _VARIANT_ instead of the default architecture variant of the container image. Some images can use multiple variants of the arm architectures, such as arm/v5 and arm/v7.
#### **--pid**=*mode*
@@ -683,19 +725,21 @@ If a container is run with a pod, and the pod has an infra-container, the infra-
#### **--pod-id-file**=*path*
-Run container in an existing pod and read the pod's ID from the specified file. If a container is run within a pod, and the pod has an infra-container, the infra-container will be started before the container is.
+Run container in an existing pod and read the pod's ID from the specified file.
+If a container is run within a pod, and the pod has an infra-container, the infra-container will be started before the container is.
#### **--preserve-fds**=*N*
-Pass down to the process N additional file descriptors (in addition to 0, 1, 2). The total FDs will be 3+N.
+Pass down to the process N additional file descriptors (in addition to 0, 1, 2).
+The total FDs will be 3+N.
#### **--privileged**=**true**|**false**
Give extended privileges to this container. The default is **false**.
By default, Podman containers are unprivileged (**=false**) and cannot, for
-example, modify parts of the operating system. This is because by default a
-container is only allowed limited access to devices. A "privileged" container
+example, modify parts of the operating system. This is because by default a
+container is only allowed limited access to devices. A "privileged" container
is given the same access to devices as the user launching the container.
A privileged container turns off the security features that isolate the
@@ -720,7 +764,7 @@ If it is not, the container port will be randomly assigned a port on the host.
Use **podman port** to see the actual mapping: **podman port $CONTAINER $CONTAINERPORT**.
**Note:** if a container will be run within a pod, it is not necessary to publish the port for
-the containers in the pod. The port must only be published by the pod itself. Pod network
+the containers in the pod. The port must only be published by the pod itself. Pod network
stacks act like the network stack on the host - you have a variety of containers in the pod,
and programs in the container, all sharing a single interface and IP address, and
associated ports. If one container binds to a port, no other container can use that port
@@ -745,7 +789,7 @@ To find the mapping between the host ports and the exposed ports, use **podman p
Pull image before running. The default is **missing**.
- **missing**: attempt to pull the latest image from the registries listed in registries.conf if a local image does not exist.Raise an error if the image is not in any listed registry and is not present locally.
-- **always**: Pull the image from the first registry it is found in as listed in registries.conf. Raise an error if not found in the registries, even if the image is present locally.
+- **always**: Pull the image from the first registry it is found in as listed in registries.conf. Raise an error if not found in the registries, even if the image is present locally.
- **never**: do not pull the image from the registry, use only the local version. Raise an error if the image is not present locally.
#### **--quiet**, **-q**
@@ -757,7 +801,7 @@ Suppress output information when pulling images
Mount the container's root filesystem as read only.
By default a container will have its root filesystem writable allowing processes
-to write files anywhere. By specifying the **--read-only** flag, the container will have
+to write files anywhere. By specifying the **--read-only** flag, the container will have
its root filesystem mounted as read only prohibiting any writes.
#### **--read-only-tmpfs**=**true**|**false**
@@ -766,7 +810,7 @@ If container is running in **--read-only** mode, then mount a read-write tmpfs o
#### **--replace**=**true**|**false**
-If another container with the same name already exists, replace and remove it. The default is **false**.
+If another container with the same name already exists, replace and remove it. The default is **false**.
#### **--restart**=*policy*
@@ -812,9 +856,9 @@ Note: On **SELinux** systems, the rootfs needs the correct label, which is by de
Determines how to use the NOTIFY_SOCKET, as passed with systemd and Type=notify.
Default is **container**, which means allow the OCI runtime to proxy the socket into the
-container to receive ready notification. Podman will set the MAINPID to conmon's pid.
+container to receive ready notification. Podman will set the MAINPID to conmon's pid.
The **conmon** option sets MAINPID to conmon's pid, and sends READY when the container
-has started. The socket is never passed to the runtime or the container.
+has started. The socket is never passed to the runtime or the container.
The **ignore** option removes NOTIFY_SOCKET from the environment for itself and child processes,
for the case where some other process above Podman uses NOTIFY_SOCKET and Podman should not use it.
@@ -838,15 +882,15 @@ Security Options
- **label=disable**: Turn off label separation for the container
- **no-new-privileges**: Disable container processes from gaining additional privileges
- **seccomp=unconfined**: Turn off seccomp confinement for the container
-- **seccomp**=_profile.json_: Allowed syscall list seccomp JSON file to be used as a seccomp filter
-- **proc-opts**=_OPTIONS_ : Comma separated list of options to use for the /proc mount. More details
+- **seccomp**=_profile.json_: Allowed syscall list seccomp JSON file to be used as a seccomp filter
+- **proc-opts**=_OPTIONS_ : Comma separated list of options to use for the /proc mount. More details
for the possible mount options are specified at **proc(5)** man page.
Note: Labeling can be disabled for all containers by setting **label=false** in the **containers.conf**(5) file.
#### **--shm-size**=_number_[_unit_]
-Size of _/dev/shm_. A _unit_ can be **b** (bytes), **k** (kilobytes), **m** (megabytes), or **g** (gigabytes).
+Size of _/dev/shm_. A _unit_ 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 default is **64m**.
When _size_ is **0**, there is no limit on the amount of memory used for IPC by the container.
@@ -904,7 +948,7 @@ Note: if you use the **--network=host** option, these sysctls will not be allowe
Run container in systemd mode. The default is **true**.
The value *always* enforces the systemd mode is enforced without
-looking at the executable name. Otherwise, if set to **true** and the
+looking at the executable name. Otherwise, if set to **true** and the
command you are running inside the container is systemd, _/usr/sbin/init_,
_/sbin/init_ or _/usr/local/sbin/init_.
@@ -922,7 +966,7 @@ It will also set the default stop signal to **SIGRTMIN+3**.
This allows systemd to run in a confined container without any modifications.
Note that on **SELinux** systems, systemd attempts to write to the cgroup
-file system. Containers writing to the cgroup file system are denied by default.
+file system. Containers writing to the cgroup file system are denied by default.
The **container_manage_cgroup** boolean must be enabled for this to be allowed on an SELinux separated system.
```
setsebool -P container_manage_cgroup true
@@ -938,7 +982,7 @@ Mount a temporary filesystem (**tmpfs**) mount into a container, for example:
$ podman run -d --tmpfs /tmp:rw,size=787448k,mode=1777 my_image
```
-This command mounts a **tmpfs** at _/tmp_ within the container. The supported mount
+This command mounts a **tmpfs** at _/tmp_ within the container. The supported mount
options are the same as the Linux default mount flags. If you do not specify
any options, the systems uses the following options:
**rw,noexec,nosuid,nodev**.
@@ -987,10 +1031,10 @@ When a user namespace is not in use, the UID and GID used within the container a
#### **--userns**=**auto**|**host**|**keep-id**|**container:**_id_|**ns:**_namespace_
-Set the user namespace mode for the container. It defaults to the **PODMAN_USERNS** environment variable. An empty value ("") means user namespaces are disabled unless an explicit mapping is set with they `--uidmapping` and `--gidmapping` options.
+Set the user namespace mode for the container. It defaults to the **PODMAN_USERNS** environment variable. An empty value ("") means user namespaces are disabled unless an explicit mapping is set with they `--uidmapping` and `--gidmapping` options.
-- **auto**: automatically create a namespace. It is possible to specify other options to `auto`. The supported options are
- **size=SIZE** to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will guess a size for the user namespace.
+- **auto**: automatically create a namespace. It is possible to specify other options to `auto`. The supported options are
+ **size=SIZE** to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will guess a size for the user namespace.
**uidmapping=HOST_UID:CONTAINER_UID:SIZE** to force a UID mapping to be present in the user namespace.
**gidmapping=HOST_UID:CONTAINER_UID:SIZE** to force a GID mapping to be present in the user namespace.
- **host**: run in the user namespace of the caller. The processes running in the container will have the same privileges on the host as any other process launched by the calling user (default).
@@ -999,7 +1043,7 @@ Set the user namespace mode for the container. It defaults to the **PODMAN_USER
- **private**: create a new namespace for the container.
- **container**: join the user namespace of the specified container.
-This option is incompatible with **--gidmap**, **--uidmap**, **--subuid** and **--subgid**.
+This option is incompatible with **--gidmap**, **--uidmap**, **--subuidname** and **--subgidname**.
#### **--uts**=*mode*
@@ -1044,7 +1088,7 @@ If a volume with that name does not exist, it will be created. Volumes created
with names are not anonymous and are not removed by **--rm** and
**podman rm --volumes**.
-You can specify multiple **-v** options to mount one or more volumes into a
+You can specify multiple **-v** options to mount one or more volumes into a
container.
You can add **:ro** or **:rw** option to mount a volume in read-only or
@@ -1069,7 +1113,7 @@ The **Z** option tells Podman to label the content with a private unshared label
The `:O` flag tells Podman to mount the directory from the host as a
temporary storage using the `overlay file system`. The container processes
can modify content within the mountpoint which is stored in the
-container storage in a separate directory. In overlay terms, the source
+container storage in a separate directory. In overlay terms, the source
directory will be the lower, and the container storage directory will be the
upper. Modifications to the mount point are destroyed when the container
finishes executing, similar to a tmpfs mount point being unmounted.
@@ -1090,7 +1134,7 @@ and can read/write `container_file_t`. If you can not change the labels on a
source volume, SELinux container separation must be disabled for the container
to work.
- The source directory mounted into the container with an overlay mount
-should not be modified, it can cause unexpected failures. It is recommended
+should not be modified, it can cause unexpected failures. It is recommended
that you do not modify the directory until the container finishes running.
Only the current container can use a private volume.
@@ -1115,7 +1159,7 @@ slave volumes, source mount has to be either shared or slave.
<sup>[[1]](#Footnote1)</sup>
If you want to recursively mount a volume and all of its submounts into a
-container, then you can use the **rbind** option. By default the bind option is
+container, then you can use the **rbind** option. By default the bind option is
used, and submounts of the source directory will not be mounted into the
container.
@@ -1174,7 +1218,7 @@ default, Podman does not change the labels set by the OS.
To change a label in the container context, you can add `z` to the volume mount.
This suffix tells Podman to relabel file objects on the shared volumes. The `z`
option tells Podman that two containers share the volume content. As a result,
-podman labels the content with a shared content label. Shared volume labels allow
+Podman labels the content with a shared content label. Shared volume labels allow
all containers to read/write content.
If the location of the volume from the source container overlaps with
@@ -1192,7 +1236,7 @@ can override the working directory by using the **-w** option.
## Exit Status
The exit code from **podman run** gives information about why the container
-failed to run or why it exited. When **podman run** exits with a non-zero code,
+failed to run or why it exited. When **podman run** exits with a non-zero code,
the exit codes follow the **chroot**(1) standard, see below:
**125** The error is with Podman itself
@@ -1223,12 +1267,12 @@ the exit codes follow the **chroot**(1) standard, see below:
### Running container in read-only mode
During container image development, containers often need to write to the image
-content. Installing packages into _/usr_, for example. In production,
+content. Installing packages into _/usr_, for example. In production,
applications seldom need to write to the image. Container applications write
-to volumes if they need to write to file systems at all. Applications can be
+to volumes if they need to write to file systems at all. Applications can be
made more secure by running them in read-only mode using the **--read-only** switch.
This protects the containers image from modification. Read only containers may
-still need to write temporary data. The best way to handle this is to mount
+still need to write temporary data. The best way to handle this is to mount
tmpfs directories on _/run_ and _/tmp_.
```
@@ -1462,7 +1506,7 @@ $ podman run --uidmap 0:30000:7000 --gidmap 0:30000:7000 fedora echo hello
### Configuring Storage Options from the command line
Podman allows for the configuration of storage by changing the values
-in the _/etc/container/storage.conf_ or by using global options. This
+in the _/etc/container/storage.conf_ or by using global options. This
shows how to setup and use fuse-overlayfs for a one time run of busybox
using global options.
@@ -1481,7 +1525,7 @@ $ podman run --tz=US/Eastern alpine date
### Rootless Containers
Podman runs as a non root user on most systems. This feature requires that a new enough version of **shadow-utils**
-be installed. The **shadow-utils** package must include the **newuidmap**(1) and **newgidmap**(1) executables.
+be installed. The **shadow-utils** package must include the **newuidmap**(1) and **newgidmap**(1) executables.
Note: RHEL7 and Centos 7 will not have this feature until RHEL7.7 is released.
@@ -1500,7 +1544,7 @@ in the following order of precedence (later entries override earlier entries):
- Container image: Any environment variables specified in the container image.
- **--http-proxy**: By default, several environment variables will be passed in from the host, such as **http_proxy** and **no_proxy**. See **--http-proxy** for details.
- **--env-host**: Host environment of the process executing Podman is added.
-- **--env-file**: Any environment variables specified via env-files. If multiple files specified, then they override each other in order of entry.
+- **--env-file**: Any environment variables specified via env-files. If multiple files specified, then they override each other in order of entry.
- **--env**: Any environment variables specified will override previous settings.
Run containers and set the environment ending with a __*__ and a __*****__:
@@ -1523,7 +1567,8 @@ b
NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`.
## SEE ALSO
-**subgid**(5), **subuid**(5), **containers.conf**(5), **systemd.unit**(5), **setsebool**(8), **slirp4netns**(1), **fuse-overlayfs**(1), **proc**(5)**.
+**podman**(1), **podman-save**(1), **podman-ps**(1), **podman-attach**(1), **podman-pod-create**(1), **podman-port**(1), **podman-kill**(1), **podman-stop**(1),
+**podman-generate-systemd**(1) **podman-rm**(1), **subgid**(5), **subuid**(5), **containers.conf**(5), **systemd.unit**(5), **setsebool**(8), **slirp4netns**(1), **fuse-overlayfs**(1), **proc**(5)**.
## HISTORY
September 2018, updated by Kunal Kushwaha <kushwaha_kunal_v7@lab.ntt.co.jp>
diff --git a/docs/source/markdown/podman-save.1.md b/docs/source/markdown/podman-save.1.md
index bfb52e7f8..fb79cfd2a 100644
--- a/docs/source/markdown/podman-save.1.md
+++ b/docs/source/markdown/podman-save.1.md
@@ -1,7 +1,7 @@
% podman-save(1)
## NAME
-podman\-save - Save an image to a container archive
+podman\-save - Save image(s) to an archive
## SYNOPSIS
**podman save** [*options*] *name*[:*tag*]
@@ -12,6 +12,8 @@ podman\-save - Save an image to a container archive
**podman save** saves an image to either **docker-archive**, **oci-archive**, **oci-dir** (directory with oci manifest type), or **docker-dir** (directory with v2s2 manifest type) on the local machine,
default is **docker-archive**. **podman save** writes to STDOUT by default and can be redirected to a
file using the **output** flag. The **quiet** flag suppresses the output when set.
+**podman save** will save parent layers of the image(s) and the image(s) can be loaded using **podman load**.
+To export the containers, use the **podman export**.
Note: `:` is a restricted character and cannot be part of the file name.
**podman [GLOBAL OPTIONS]**
diff --git a/docs/source/markdown/podman-system-service.1.md b/docs/source/markdown/podman-system-service.1.md
index 39e30ec02..1fdecfa5c 100644
--- a/docs/source/markdown/podman-system-service.1.md
+++ b/docs/source/markdown/podman-system-service.1.md
@@ -17,12 +17,14 @@ The REST API provided by **podman system service** is split into two parts: a co
Documentation for the latter is available at *https://docs.podman.io/en/latest/_static/api.html*.
Both APIs are versioned, but the server will not reject requests with an unsupported version set.
+Note: The default systemd unit files (system and user) change the log-level option to *info* from *error*. This change provides additional information on each API call.
+
## OPTIONS
#### **--time**, **-t**
The time until the session expires in _seconds_. The default is 5
-seconds. A value of `0` means no timeout and the session will not expire.
+seconds. A value of `0` means no timeout, therefore the session will not expire.
#### **--help**, **-h**
@@ -40,3 +42,4 @@ podman(1), podman-system-service(1), podman-system-connection(1)
## HISTORY
January 2020, Originally compiled by Brent Baude<bbaude@redhat.com>
+November 2020, Updated by Jhon Honce <jhonce at redhat.com>
diff --git a/docs/source/markdown/podman-top.1.md b/docs/source/markdown/podman-top.1.md
index f307f96da..cfb89567c 100644
--- a/docs/source/markdown/podman-top.1.md
+++ b/docs/source/markdown/podman-top.1.md
@@ -9,7 +9,7 @@ podman\-top - Display the running processes of a container
**podman container top** [*options*] *container* [*format-descriptors*]
## DESCRIPTION
-Display the running processes of the container. The *format-descriptors* are ps (1) compatible AIX format descriptors but extended to print additional information, such as the seccomp mode or the effective capabilities of a given process. The descriptors can either be passed as separated arguments or as a single comma-separated argument. Note that you can also specify options and or flags of ps(1); in this case, Podman will fallback to executing ps with the specified arguments and flags in the container.
+Display the running processes of the container. The *format-descriptors* are ps (1) compatible AIX format descriptors but extended to print additional information, such as the seccomp mode or the effective capabilities of a given process. The descriptors can either be passed as separated arguments or as a single comma-separated argument. Note that you can also specify options and or flags of ps(1); in this case, Podman will fallback to executing ps with the specified arguments and flags in the container. Please use the "h*" descriptors if you want to extract host-related information. For instance, `podman top $name hpid huser` to display the PID and user of the processes in the host context.
## OPTIONS
diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/podman.1.md
index 68a17d26b..7da01d389 100644
--- a/docs/source/markdown/podman.1.md
+++ b/docs/source/markdown/podman.1.md
@@ -231,7 +231,7 @@ the exit codes follow the `chroot` standard, see below:
| [podman-init(1)](podman-init.1.md) | Initialize one or more containers |
| [podman-inspect(1)](podman-inspect.1.md) | Display a container, image, volume, network, or pod's configuration. |
| [podman-kill(1)](podman-kill.1.md) | Kill the main process in one or more containers. |
-| [podman-load(1)](podman-load.1.md) | Load an image from a container image archive into container storage. |
+| [podman-load(1)](podman-load.1.md) | Load image(s) from a tar archive into container storage. |
| [podman-login(1)](podman-login.1.md) | Login to a container registry. |
| [podman-logout(1)](podman-logout.1.md) | Logout of a container registry. |
| [podman-logs(1)](podman-logs.1.md) | Display the logs of one or more containers. |
@@ -249,7 +249,7 @@ the exit codes follow the `chroot` standard, see below:
| [podman-rm(1)](podman-rm.1.md) | Remove one or more containers. |
| [podman-rmi(1)](podman-rmi.1.md) | Removes one or more locally stored images. |
| [podman-run(1)](podman-run.1.md) | Run a command in a new container. |
-| [podman-save(1)](podman-save.1.md) | Save an image to a container archive. |
+| [podman-save(1)](podman-save.1.md) | Save image(s) to an archive. |
| [podman-search(1)](podman-search.1.md) | Search a registry for an image. |
| [podman-start(1)](podman-start.1.md) | Start one or more containers. |
| [podman-stats(1)](podman-stats.1.md) | Display a live stream of one or more container's resource usage statistics. |
diff --git a/docs/tutorials/mac_win_client.md b/docs/tutorials/mac_win_client.md
index af2668e10..375f73102 100644
--- a/docs/tutorials/mac_win_client.md
+++ b/docs/tutorials/mac_win_client.md
@@ -55,7 +55,7 @@ host:
In order for the client to communicate with the server you need to enable and start the SSH daemon on your Linux machine, if it is not currently enabled.
```
-sudo systemctl enable --now -s sshd
+sudo systemctl enable --now sshd
```
#### Setting up SSH
diff --git a/go.mod b/go.mod
index 0a556c328..bf8519678 100644
--- a/go.mod
+++ b/go.mod
@@ -10,8 +10,8 @@ require (
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect
github.com/containernetworking/cni v0.8.0
github.com/containernetworking/plugins v0.8.7
- github.com/containers/buildah v1.18.0
- github.com/containers/common v0.27.0
+ github.com/containers/buildah v1.18.1-0.20201125084616-dd26b137459c
+ github.com/containers/common v0.29.0
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.8.1
github.com/containers/psgo v1.5.1
diff --git a/go.sum b/go.sum
index 4a7047084..af24b4b46 100644
--- a/go.sum
+++ b/go.sum
@@ -93,16 +93,12 @@ github.com/containernetworking/cni v0.8.0 h1:BT9lpgGoH4jw3lFC7Odz2prU5ruiYKcgAjM
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
github.com/containernetworking/plugins v0.8.7 h1:bU7QieuAp+sACI2vCzESJ3FoT860urYP+lThyZkb/2M=
github.com/containernetworking/plugins v0.8.7/go.mod h1:R7lXeZaBzpfqapcAbHRW8/CYwm0dHzbz0XEjofx0uB0=
-github.com/containers/buildah v1.18.0 h1:mWEm013LVNGecF++sYo0T7fe/4pqMas/PQxQ/qviC68=
-github.com/containers/buildah v1.18.0/go.mod h1:qHLk7RUL7cHfA7ve1MKkZ6cyKUxHD0YxiLJcKY+mJe8=
-github.com/containers/common v0.26.3/go.mod h1:hJWZIlrl5MsE2ELNRa+MPp6I1kPbXHauuj0Ym4BsLG4=
-github.com/containers/common v0.27.0 h1:+QlYEOitVYtU9/x8xebRgxdGqt4sLaIqV6MBOns+zLk=
-github.com/containers/common v0.27.0/go.mod h1:ZTswJJfu4aGF6Anyi2yON8Getda9NDYcdIzurOEHHXI=
+github.com/containers/buildah v1.18.1-0.20201125084616-dd26b137459c h1:vyc2iYz9b2vfDiigpLyhiXNqXITt/dmDk74HpHzlQow=
+github.com/containers/buildah v1.18.1-0.20201125084616-dd26b137459c/go.mod h1:B+0OkXUogxdwsEy4ax3a5/vDtJjL6vCisiV6frQZJ4A=
+github.com/containers/common v0.29.0 h1:hTMC+urdkk5bKfhL/OgCixIX5xjJgQ2l2jPG745ECFQ=
+github.com/containers/common v0.29.0/go.mod h1:yT4GTUHsKRmpaDb+mecXRnIMre7W3ZgwXqaYMywXlaA=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
-github.com/containers/image/v5 v5.7.0/go.mod h1:8aOy+YaItukxghRORkvhq5ibWttHErzDLy6egrKfKos=
-github.com/containers/image/v5 v5.8.0 h1:B3FGHi0bdGXgg698kBIGOlHCXN5n+scJr6/5354GOPU=
-github.com/containers/image/v5 v5.8.0/go.mod h1:jKxdRtyIDumVa56hdsZvV+gwx4zB50hRou6pIuCWLkg=
github.com/containers/image/v5 v5.8.1 h1:aHW8a/Kd0dTJ7PTL/fc6y12sJqHxWgqilu+XyHfjD8Q=
github.com/containers/image/v5 v5.8.1/go.mod h1:blOEFd/iFdeyh891ByhCVUc+xAcaI3gBegXECwz9UbQ=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
@@ -111,12 +107,7 @@ github.com/containers/ocicrypt v1.0.3 h1:vYgl+RZ9Q3DPMuTfxmN+qp0X2Bj52uuY2vnt6Gz
github.com/containers/ocicrypt v1.0.3/go.mod h1:CUBa+8MRNL/VkpxYIpaMtgn1WgXGyvPQj8jcy0EVG6g=
github.com/containers/psgo v1.5.1 h1:MQNb7FLbXqBdqz6u4lI2QWizVz4RSTzs1+Nk9XT1iVA=
github.com/containers/psgo v1.5.1/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzPUWfawVU=
-github.com/containers/storage v1.23.6/go.mod h1:haFs0HRowKwyzvWEx9EgI3WsL8XCSnBDb5f8P5CAxJY=
github.com/containers/storage v1.23.7/go.mod h1:cUT2zHjtx+WlVri30obWmM2gpqpi8jfPsmIzP1TVpEI=
-github.com/containers/storage v1.23.9 h1:qbgnTp76pLSyW3vYwY5GH4vk5cHYVXFJ+CsUEBp9TMw=
-github.com/containers/storage v1.23.9/go.mod h1:3b2ktpB6pw53SEeIoFfO0sQfP9+IoJJKPq5iJk74gxE=
-github.com/containers/storage v1.24.0 h1:Fo2LkF7tkMLmo38sTZ/G8wHjcn8JfUFPfyTxM4WwMfk=
-github.com/containers/storage v1.24.0/go.mod h1:A4d3BzuZK9b3oLVEsiSRhZLPIx3z7utgiPyXLK/YMhY=
github.com/containers/storage v1.24.1 h1:1+f8fy6ly35c8SLet5jzZ8t0WJJs5+xSpfMAYw0R3kc=
github.com/containers/storage v1.24.1/go.mod h1:0xJL06Dmd+ZYXIUdnBUPN0JnhHGgwMkLvnnAonJfWJU=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
@@ -324,8 +315,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.11.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ=
-github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.3 h1:dB4Bn0tN3wdCzQxnS8r06kV74qN/TAfaIS0bVE8h3jc=
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
@@ -374,7 +363,6 @@ github.com/moby/sys/mount v0.1.1 h1:mdhBytJ1SMmMat0gtzWWjFX/87K5j6E/7Q5z7rR0cZY=
github.com/moby/sys/mount v0.1.1/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74=
github.com/moby/sys/mountinfo v0.1.0/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o=
github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o=
-github.com/moby/sys/mountinfo v0.3.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/mountinfo v0.4.0 h1:1KInV3Huv18akCu58V7lzNlt+jFmqlu1EaErnEHE/VM=
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/term v0.0.0-20200429084858-129dac9f73f6/go.mod h1:or9wGItza1sRcM4Wd3dIv8DsFHYQuFsMHEdxUIlUxms=
diff --git a/libpod/container.go b/libpod/container.go
index 31c958959..e954d84eb 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -13,6 +13,7 @@ import (
"github.com/containers/image/v5/manifest"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/lock"
+ "github.com/containers/podman/v2/pkg/rootless"
"github.com/containers/storage"
"github.com/cri-o/ocicni/pkg/ocicni"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -1095,13 +1096,17 @@ func (c *Container) Umask() string {
// values at runtime via network connect and disconnect.
// If the container is configured to use CNI and this function returns an empty
// array, the container will still be connected to the default network.
-func (c *Container) Networks() ([]string, error) {
+// The second return parameter, a bool, indicates that the container container
+// is joining the default CNI network - the network name will be included in the
+// returned array of network names, but the container did not explicitly join
+// this network.
+func (c *Container) Networks() ([]string, bool, error) {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
if err := c.syncContainer(); err != nil {
- return nil, err
+ return nil, false, err
}
}
@@ -1109,19 +1114,22 @@ func (c *Container) Networks() ([]string, error) {
}
// Unlocked accessor for networks
-func (c *Container) networks() ([]string, error) {
+func (c *Container) networks() ([]string, bool, error) {
networks, err := c.runtime.state.GetNetworks(c)
if err != nil && errors.Cause(err) == define.ErrNoSuchNetwork {
- return c.config.Networks, nil
+ if len(c.config.Networks) == 0 && !rootless.IsRootless() {
+ return []string{c.runtime.netPlugin.GetDefaultNetworkName()}, true, nil
+ }
+ return c.config.Networks, false, nil
}
- return networks, err
+ return networks, false, err
}
// networksByNameIndex provides us with a map of container networks where key
// is network name and value is the index position
func (c *Container) networksByNameIndex() (map[string]int, error) {
- networks, err := c.networks()
+ networks, _, err := c.networks()
if err != nil {
return nil, err
}
diff --git a/libpod/container_api.go b/libpod/container_api.go
index a9808a30e..6a7ddc421 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -714,3 +714,17 @@ func (c *Container) Restore(ctx context.Context, options ContainerCheckpointOpti
defer c.newContainerEvent(events.Restore)
return c.restore(ctx, options)
}
+
+// Indicate whether or not the container should restart
+func (c *Container) ShouldRestart(ctx context.Context) bool {
+ logrus.Debugf("Checking if container %s should restart", c.ID())
+ if !c.batched {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ if err := c.syncContainer(); err != nil {
+ return false
+ }
+ }
+ return c.shouldRestart()
+}
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 108954bad..b6a3244ea 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -206,37 +206,39 @@ func (c *Container) handleExitFile(exitFile string, fi os.FileInfo) error {
return nil
}
-// Handle container restart policy.
-// This is called when a container has exited, and was not explicitly stopped by
-// an API call to stop the container or pod it is in.
-func (c *Container) handleRestartPolicy(ctx context.Context) (_ bool, retErr error) {
- // If we did not get a restart policy match, exit immediately.
+func (c *Container) shouldRestart() bool {
+ // If we did not get a restart policy match, return false
// Do the same if we're not a policy that restarts.
if !c.state.RestartPolicyMatch ||
c.config.RestartPolicy == RestartPolicyNo ||
c.config.RestartPolicy == RestartPolicyNone {
- return false, nil
+ return false
}
// If we're RestartPolicyOnFailure, we need to check retries and exit
// code.
if c.config.RestartPolicy == RestartPolicyOnFailure {
if c.state.ExitCode == 0 {
- return false, nil
+ return false
}
// If we don't have a max retries set, continue
if c.config.RestartRetries > 0 {
- if c.state.RestartCount < c.config.RestartRetries {
- logrus.Debugf("Container %s restart policy trigger: on retry %d (of %d)",
- c.ID(), c.state.RestartCount, c.config.RestartRetries)
- } else {
- logrus.Debugf("Container %s restart policy trigger: retries exhausted", c.ID())
- return false, nil
+ if c.state.RestartCount >= c.config.RestartRetries {
+ return false
}
}
}
+ return true
+}
+// Handle container restart policy.
+// This is called when a container has exited, and was not explicitly stopped by
+// an API call to stop the container or pod it is in.
+func (c *Container) handleRestartPolicy(ctx context.Context) (_ bool, retErr error) {
+ if !c.shouldRestart() {
+ return false, nil
+ }
logrus.Debugf("Restarting container %s due to restart policy %s", c.ID(), c.config.RestartPolicy)
// Need to check if dependencies are alive.
@@ -641,18 +643,13 @@ func (c *Container) removeIPv4Allocations() error {
cniDefaultNetwork = c.runtime.netPlugin.GetDefaultNetworkName()
}
- networks, err := c.networks()
+ networks, _, err := c.networks()
if err != nil {
return err
}
- switch {
- case len(networks) > 0 && len(networks) != len(c.state.NetworkStatus):
+ if len(networks) != len(c.state.NetworkStatus) {
return errors.Wrapf(define.ErrInternal, "network mismatch: asked to join %d CNI networks but got %d CNI results", len(networks), len(c.state.NetworkStatus))
- case len(networks) == 0 && len(c.state.NetworkStatus) != 1:
- return errors.Wrapf(define.ErrInternal, "network mismatch: did not specify CNI networks but joined more than one (%d)", len(c.state.NetworkStatus))
- case len(networks) == 0 && cniDefaultNetwork == "":
- return errors.Wrapf(define.ErrInternal, "could not retrieve name of CNI default network")
}
for index, result := range c.state.NetworkStatus {
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index b81f3f716..56575c195 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -22,9 +22,9 @@ import (
cnitypes "github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containers/buildah/pkg/overlay"
- "github.com/containers/buildah/pkg/secrets"
"github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/subscriptions"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/events"
"github.com/containers/podman/v2/pkg/annotations"
@@ -1435,7 +1435,7 @@ func (c *Container) makeBindMounts() error {
}
// Add Secret Mounts
- secretMounts := secrets.SecretMountsWithUIDGID(c.config.MountLabel, c.state.RunDir, c.runtime.config.Containers.DefaultMountsFile, c.state.Mountpoint, c.RootUID(), c.RootGID(), rootless.IsRootless(), false)
+ secretMounts := subscriptions.MountsWithUIDGID(c.config.MountLabel, c.state.RunDir, c.runtime.config.Containers.DefaultMountsFile, c.state.Mountpoint, c.RootUID(), c.RootGID(), rootless.IsRootless(), false)
for _, mount := range secretMounts {
if _, ok := c.state.BindMounts[mount.Destination]; !ok {
c.state.BindMounts[mount.Destination] = mount.Source
diff --git a/libpod/healthcheck_linux.go b/libpod/healthcheck_linux.go
index b0f1ff35d..0ad15da09 100644
--- a/libpod/healthcheck_linux.go
+++ b/libpod/healthcheck_linux.go
@@ -26,6 +26,10 @@ func (c *Container) createTimer() error {
if rootless.IsRootless() {
cmd = append(cmd, "--user")
}
+ path := os.Getenv("PATH")
+ if path != "" {
+ cmd = append(cmd, "--setenv=PATH="+path)
+ }
cmd = append(cmd, "--unit", c.ID(), fmt.Sprintf("--on-unit-inactive=%s", c.HealthCheckConfig().Interval.String()), "--timer-property=AccuracySec=1s", podman, "healthcheck", "run", c.ID())
conn, err := systemd.ConnectToDBUS()
diff --git a/libpod/image/manifests.go b/libpod/image/manifests.go
index 59678fdb2..14f7c2f83 100644
--- a/libpod/image/manifests.go
+++ b/libpod/image/manifests.go
@@ -2,13 +2,14 @@ package image
import (
"context"
+ "fmt"
"github.com/containers/buildah/manifests"
+ "github.com/containers/image/v5/docker"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/transports/alltransports"
"github.com/containers/image/v5/types"
"github.com/opencontainers/go-digest"
- "github.com/pkg/errors"
)
// Options for adding a manifest
@@ -69,19 +70,10 @@ func CreateManifestList(rt *Runtime, systemContext types.SystemContext, names []
list := manifests.Create()
opts := ManifestAddOpts{Images: names, All: all}
for _, img := range imgs {
- var ref types.ImageReference
- newImage, err := rt.NewFromLocal(img)
- if err == nil {
- ir, err := newImage.toImageRef(context.Background())
- if err != nil {
- return "", err
- }
- if ir == nil {
- return "", errors.New("unable to convert image to ImageReference")
- }
- ref = ir.Reference()
- } else {
- ref, err = alltransports.ParseImageName(img)
+ ref, err := alltransports.ParseImageName(img)
+ if err != nil {
+ dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name())
+ ref, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, img))
if err != nil {
return "", err
}
@@ -134,18 +126,10 @@ func addManifestToList(ref types.ImageReference, list manifests.List, systemCont
// AddManifest adds a manifest to a given manifest list.
func (i *Image) AddManifest(systemContext types.SystemContext, opts ManifestAddOpts) (string, error) {
- var (
- ref types.ImageReference
- )
- newImage, err := i.imageruntime.NewFromLocal(opts.Images[0])
- if err == nil {
- ir, err := newImage.toImageRef(context.Background())
- if err != nil {
- return "", err
- }
- ref = ir.Reference()
- } else {
- ref, err = alltransports.ParseImageName(opts.Images[0])
+ ref, err := alltransports.ParseImageName(opts.Images[0])
+ if err != nil {
+ dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name())
+ ref, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, opts.Images[0]))
if err != nil {
return "", err
}
diff --git a/libpod/network/config.go b/libpod/network/config.go
index ce8a4446c..ce351129e 100644
--- a/libpod/network/config.go
+++ b/libpod/network/config.go
@@ -129,6 +129,16 @@ func (f FirewallConfig) Bytes() ([]byte, error) {
return json.MarshalIndent(f, "", "\t")
}
+// TuningConfig describes the tuning plugin
+type TuningConfig struct {
+ PluginType string `json:"type"`
+}
+
+// Bytes outputs the configuration as []byte
+func (f TuningConfig) Bytes() ([]byte, error) {
+ return json.MarshalIndent(f, "", "\t")
+}
+
// DNSNameConfig describes the dns container name resolution plugin config
type DNSNameConfig struct {
PluginType string `json:"type"`
diff --git a/libpod/network/create.go b/libpod/network/create.go
index 387f4fcd3..7e4fc574a 100644
--- a/libpod/network/create.go
+++ b/libpod/network/create.go
@@ -176,6 +176,7 @@ func createBridge(name string, options entities.NetworkCreateOptions, runtimeCon
plugins = append(plugins, bridge)
plugins = append(plugins, NewPortMapPlugin())
plugins = append(plugins, NewFirewallPlugin())
+ plugins = append(plugins, NewTuningPlugin())
// if we find the dnsname plugin or are rootless, we add configuration for it
// the rootless-cni-infra container has the dnsname plugin always installed
if (HasDNSNamePlugin(runtimeConfig.Network.CNIPluginDirs) || rootless.IsRootless()) && !options.DisableDNS {
diff --git a/libpod/network/files.go b/libpod/network/files.go
index 846e5c62d..7f1e3ee18 100644
--- a/libpod/network/files.go
+++ b/libpod/network/files.go
@@ -14,6 +14,9 @@ import (
"github.com/pkg/errors"
)
+// ErrNoSuchNetworkInterface indicates that no network interface exists
+var ErrNoSuchNetworkInterface = errors.New("unable to find interface name for network")
+
// GetCNIConfDir get CNI configuration directory
func GetCNIConfDir(configArg *config.Config) string {
if len(configArg.Network.NetworkConfigDir) < 1 {
@@ -142,7 +145,7 @@ func GetInterfaceNameFromConfig(path string) (string, error) {
}
}
if len(name) == 0 {
- return "", errors.New("unable to find interface name for network")
+ return "", ErrNoSuchNetworkInterface
}
return name, nil
}
diff --git a/libpod/network/netconflist.go b/libpod/network/netconflist.go
index 111f1715c..ee9adce14 100644
--- a/libpod/network/netconflist.go
+++ b/libpod/network/netconflist.go
@@ -119,6 +119,13 @@ func NewFirewallPlugin() FirewallConfig {
}
}
+// NewTuningPlugin creates a generic tuning section
+func NewTuningPlugin() TuningConfig {
+ return TuningConfig{
+ PluginType: "tuning",
+ }
+}
+
// NewDNSNamePlugin creates the dnsname config with a given
// domainname
func NewDNSNamePlugin(domainName string) DNSNameConfig {
diff --git a/libpod/network/network.go b/libpod/network/network.go
index 7327a1a7d..0febb52f6 100644
--- a/libpod/network/network.go
+++ b/libpod/network/network.go
@@ -10,6 +10,7 @@ import (
"github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator"
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v2/libpod/define"
+ "github.com/containers/podman/v2/pkg/rootless"
"github.com/containers/podman/v2/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -181,21 +182,26 @@ func RemoveNetwork(config *config.Config, name string) error {
// Before we delete the configuration file, we need to make sure we can read and parse
// it to get the network interface name so we can remove that too
interfaceName, err := GetInterfaceNameFromConfig(cniPath)
- if err != nil {
- return errors.Wrapf(err, "failed to find network interface name in %q", cniPath)
- }
- liveNetworkNames, err := GetLiveNetworkNames()
- if err != nil {
- return errors.Wrapf(err, "failed to get live network names")
- }
- if util.StringInSlice(interfaceName, liveNetworkNames) {
- if err := RemoveInterface(interfaceName); err != nil {
- return errors.Wrapf(err, "failed to delete the network interface %q", interfaceName)
+ if err == nil {
+ // Don't try to remove the network interface if we are not root
+ if !rootless.IsRootless() {
+ liveNetworkNames, err := GetLiveNetworkNames()
+ if err != nil {
+ return errors.Wrapf(err, "failed to get live network names")
+ }
+ if util.StringInSlice(interfaceName, liveNetworkNames) {
+ if err := RemoveInterface(interfaceName); err != nil {
+ return errors.Wrapf(err, "failed to delete the network interface %q", interfaceName)
+ }
+ }
}
+ } else if err != ErrNoSuchNetworkInterface {
+ // Don't error if we couldn't find the network interface name
+ return err
}
// Remove the configuration file
if err := os.Remove(cniPath); err != nil {
- return errors.Wrapf(err, "failed to remove network configuration file %q", cniPath)
+ return errors.Wrap(err, "failed to remove network configuration")
}
return nil
}
diff --git a/libpod/network/subnet.go b/libpod/network/subnet.go
index 90f0cdfce..120038e57 100644
--- a/libpod/network/subnet.go
+++ b/libpod/network/subnet.go
@@ -54,14 +54,10 @@ func LastIPInSubnet(addr *net.IPNet) (net.IP, error) { //nolint:interfacer
ones, bits := cidr.Mask.Size()
if ones == bits {
- return FirstIPInSubnet(cidr)
+ return cidr.IP, nil
}
- hostStart := ones / 8
- // Handle the first host byte
- cidr.IP[hostStart] |= 0xff & cidr.Mask[hostStart]
- // Fill the rest with ones
- for i := hostStart; i < len(cidr.IP); i++ {
- cidr.IP[i] = 0xff
+ for i := range cidr.IP {
+ cidr.IP[i] = cidr.IP[i] | ^cidr.Mask[i]
}
return cidr.IP, nil
}
@@ -73,6 +69,10 @@ func FirstIPInSubnet(addr *net.IPNet) (net.IP, error) { //nolint:interfacer
if err != nil {
return nil, err
}
+ ones, bits := cidr.Mask.Size()
+ if ones == bits {
+ return cidr.IP, nil
+ }
cidr.IP[len(cidr.IP)-1]++
return cidr.IP, nil
}
diff --git a/libpod/network/subnet_test.go b/libpod/network/subnet_test.go
index 917c3be88..55b2443bd 100644
--- a/libpod/network/subnet_test.go
+++ b/libpod/network/subnet_test.go
@@ -33,3 +33,65 @@ func TestNextSubnet(t *testing.T) {
})
}
}
+
+func TestFirstIPInSubnet(t *testing.T) {
+ tests := []struct {
+ name string
+ args *net.IPNet
+ want net.IP
+ wantErr bool
+ }{
+ {"class b", parseCIDR("192.168.0.0/16"), net.ParseIP("192.168.0.1"), false},
+ {"class c", parseCIDR("192.168.1.0/24"), net.ParseIP("192.168.1.1"), false},
+ {"cidr /23", parseCIDR("192.168.0.0/23"), net.ParseIP("192.168.0.1"), false},
+ {"cidr /25", parseCIDR("192.168.1.0/25"), net.ParseIP("192.168.1.1"), false},
+ {"cidr /26", parseCIDR("172.16.1.128/26"), net.ParseIP("172.16.1.129"), false},
+ {"class a", parseCIDR("10.0.0.0/8"), net.ParseIP("10.0.0.1"), false},
+ {"cidr /32", parseCIDR("192.168.255.4/32"), net.ParseIP("192.168.255.4"), false},
+ {"cidr /31", parseCIDR("192.168.255.4/31"), net.ParseIP("192.168.255.5"), false},
+ }
+ for _, tt := range tests {
+ test := tt
+ t.Run(test.name, func(t *testing.T) {
+ got, err := FirstIPInSubnet(test.args)
+ if (err != nil) != test.wantErr {
+ t.Errorf("FirstIPInSubnet() error = %v, wantErr %v", err, test.wantErr)
+ return
+ }
+ if !got.Equal(test.want) {
+ t.Errorf("FirstIPInSubnet() got = %v, want %v", got, test.want)
+ }
+ })
+ }
+}
+
+func TestLastIPInSubnet(t *testing.T) {
+ tests := []struct {
+ name string
+ args *net.IPNet
+ want net.IP
+ wantErr bool
+ }{
+ {"class b", parseCIDR("192.168.0.0/16"), net.ParseIP("192.168.255.255"), false},
+ {"class c", parseCIDR("192.168.1.0/24"), net.ParseIP("192.168.1.255"), false},
+ {"cidr /23", parseCIDR("192.168.0.0/23"), net.ParseIP("192.168.1.255"), false},
+ {"cidr /25", parseCIDR("192.168.1.0/25"), net.ParseIP("192.168.1.127"), false},
+ {"cidr /26", parseCIDR("172.16.1.128/26"), net.ParseIP("172.16.1.191"), false},
+ {"class a", parseCIDR("10.0.0.0/8"), net.ParseIP("10.255.255.255"), false},
+ {"cidr /32", parseCIDR("192.168.255.4/32"), net.ParseIP("192.168.255.4"), false},
+ {"cidr /31", parseCIDR("192.168.255.4/31"), net.ParseIP("192.168.255.5"), false},
+ }
+ for _, tt := range tests {
+ test := tt
+ t.Run(test.name, func(t *testing.T) {
+ got, err := LastIPInSubnet(test.args)
+ if (err != nil) != test.wantErr {
+ t.Errorf("LastIPInSubnet() error = %v, wantErr %v", err, test.wantErr)
+ return
+ }
+ if !got.Equal(test.want) {
+ t.Errorf("LastIPInSubnet() got = %v, want %v", got, test.want)
+ }
+ })
+ }
+}
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 8dce7c9fe..4e7ffaf81 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -110,10 +110,15 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re
podName := getCNIPodName(ctr)
- networks, err := ctr.networks()
+ networks, _, err := ctr.networks()
if err != nil {
return nil, err
}
+ // All networks have been removed from the container.
+ // This is effectively forcing net=none.
+ if len(networks) == 0 {
+ return nil, nil
+ }
// Update container map of interface descriptions
if err := ctr.setupNetworkDescriptions(networks); err != nil {
@@ -224,7 +229,7 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
if ctr.config.NetMode.IsSlirp4netns() {
return r.setupSlirp4netns(ctr)
}
- networks, err := ctr.networks()
+ networks, _, err := ctr.networks()
if err != nil {
return err
}
@@ -744,13 +749,13 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {
logrus.Debugf("Tearing down network namespace at %s for container %s", ctr.state.NetNS.Path(), ctr.ID())
- networks, err := ctr.networks()
+ networks, _, err := ctr.networks()
if err != nil {
return err
}
// rootless containers do not use the CNI plugin directly
- if !rootless.IsRootless() && !ctr.config.NetMode.IsSlirp4netns() {
+ if !rootless.IsRootless() && !ctr.config.NetMode.IsSlirp4netns() && len(networks) > 0 {
var requestedIP net.IP
if ctr.requestedIP != nil {
requestedIP = ctr.requestedIP
@@ -863,7 +868,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
settings := new(define.InspectNetworkSettings)
settings.Ports = makeInspectPortBindings(c.config.PortMappings)
- networks, err := c.networks()
+ networks, isDefault, err := c.networks()
if err != nil {
return nil, err
}
@@ -872,7 +877,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
if c.state.NetNS == nil {
// We still want to make dummy configurations for each CNI net
// the container joined.
- if len(networks) > 0 {
+ if len(networks) > 0 && !isDefault {
settings.Networks = make(map[string]*define.InspectAdditionalNetwork, len(networks))
for _, net := range networks {
cniNet := new(define.InspectAdditionalNetwork)
@@ -893,9 +898,9 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
}
// If we have CNI networks - handle that here
- if len(networks) > 0 {
+ if len(networks) > 0 && !isDefault {
if len(networks) != len(c.state.NetworkStatus) {
- return nil, errors.Wrapf(define.ErrInternal, "network inspection mismatch: asked to join %d CNI networks but have information on %d networks", len(networks), len(c.state.NetworkStatus))
+ return nil, errors.Wrapf(define.ErrInternal, "network inspection mismatch: asked to join %d CNI network(s) %v, but have information on %d network(s)", len(networks), networks, len(c.state.NetworkStatus))
}
settings.Networks = make(map[string]*define.InspectAdditionalNetwork)
@@ -1101,7 +1106,7 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e
return err
}
- ctrNetworks, err := c.networks()
+ ctrNetworks, _, err := c.networks()
if err != nil {
return err
}
@@ -1139,8 +1144,8 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e
// build a list of network names so we can sort and
// get the new name's index
var networkNames []string
- for netName := range networks {
- networkNames = append(networkNames, netName)
+ for name := range networks {
+ networkNames = append(networkNames, name)
}
networkNames = append(networkNames, netName)
// sort
@@ -1152,6 +1157,7 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e
// populate network status
copy(networkStatus[index+1:], networkStatus[index:])
networkStatus[index] = networkResults[0]
+ c.state.NetworkStatus = networkStatus
}
c.newNetworkEvent(events.NetworkConnect, netName)
return c.save()
diff --git a/libpod/rootless_cni_linux.go b/libpod/rootless_cni_linux.go
index 1d6158cc2..2c2977f9f 100644
--- a/libpod/rootless_cni_linux.go
+++ b/libpod/rootless_cni_linux.go
@@ -40,7 +40,7 @@ const (
//
// AllocRootlessCNI does not lock c. c should be already locked.
func AllocRootlessCNI(ctx context.Context, c *Container) (ns.NetNS, []*cnitypes.Result, error) {
- networks, err := c.networks()
+ networks, _, err := c.networks()
if err != nil {
return nil, nil, err
}
@@ -81,7 +81,7 @@ func AllocRootlessCNI(ctx context.Context, c *Container) (ns.NetNS, []*cnitypes.
//
// DeallocRootlessCNI does not lock c. c should be already locked.
func DeallocRootlessCNI(ctx context.Context, c *Container) error {
- networks, err := c.networks()
+ networks, _, err := c.networks()
if err != nil {
return err
}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 792492db6..df3dfae2b 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -162,6 +162,10 @@ func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...R
runtime.config = conf
+ if err := SetXdgDirs(); err != nil {
+ return nil, err
+ }
+
storeOpts, err := storage.DefaultStoreOptions(rootless.IsRootless(), rootless.GetRootlessUID())
if err != nil {
return nil, err
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index 00be8e845..5886455e7 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -298,6 +298,9 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
state.Running = true
}
+ formatCapabilities(inspect.HostConfig.CapDrop)
+ formatCapabilities(inspect.HostConfig.CapAdd)
+
h, err := json.Marshal(inspect.HostConfig)
if err != nil {
return nil, err
@@ -318,8 +321,8 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
cb := types.ContainerJSONBase{
ID: l.ID(),
Created: l.CreatedTime().Format(time.RFC3339Nano),
- Path: "",
- Args: nil,
+ Path: inspect.Path,
+ Args: inspect.Args,
State: &state,
Image: imageName,
ResolvConfPath: inspect.ResolvConfPath,
@@ -328,7 +331,7 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
LogPath: l.LogPath(),
Node: nil,
Name: fmt.Sprintf("/%s", l.Name()),
- RestartCount: 0,
+ RestartCount: int(inspect.RestartCount),
Driver: inspect.Driver,
Platform: "linux",
MountLabel: inspect.MountLabel,
@@ -428,3 +431,9 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
}
return &c, nil
}
+
+func formatCapabilities(slice []string) {
+ for i := range slice {
+ slice[i] = strings.TrimPrefix(slice[i], "CAP_")
+ }
+}
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go
index 4efe770b3..729639928 100644
--- a/pkg/api/handlers/compat/containers_create.go
+++ b/pkg/api/handlers/compat/containers_create.go
@@ -19,7 +19,6 @@ import (
func CreateContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
- input := handlers.CreateContainerConfig{}
query := struct {
Name string `schema:"name"`
}{
@@ -30,11 +29,15 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
- if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
+
+ // compatible configuration
+ body := handlers.CreateContainerConfig{}
+ if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
return
}
- if len(input.HostConfig.Links) > 0 {
+
+ if len(body.HostConfig.Links) > 0 {
utils.Error(w, utils.ErrLinkNotSupport.Error(), http.StatusBadRequest, errors.Wrapf(utils.ErrLinkNotSupport, "bad parameter"))
return
}
@@ -43,7 +46,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "unable to obtain runtime config", http.StatusInternalServerError, errors.Wrap(err, "unable to get runtime config"))
}
- newImage, err := runtime.ImageRuntime().NewFromLocal(input.Image)
+ newImage, err := runtime.ImageRuntime().NewFromLocal(body.Config.Image)
if err != nil {
if errors.Cause(err) == define.ErrNoSuchImage {
utils.Error(w, "No such image", http.StatusNotFound, err)
@@ -54,11 +57,8 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
return
}
- // Add the container name to the input struct
- input.Name = query.Name
-
- // Take input structure and convert to cliopts
- cliOpts, args, err := common.ContainerCreateToContainerCLIOpts(input, rtc.Engine.CgroupManager)
+ // Take body structure and convert to cliopts
+ cliOpts, args, err := common.ContainerCreateToContainerCLIOpts(body, rtc.Engine.CgroupManager)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "make cli opts()"))
return
@@ -69,6 +69,9 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
return
}
+ // Override the container name in the body struct
+ body.Name = query.Name
+
ic := abi.ContainerEngine{Libpod: runtime}
report, err := ic.ContainerCreate(r.Context(), sg)
if err != nil {
diff --git a/pkg/api/handlers/compat/info.go b/pkg/api/handlers/compat/info.go
index 2bb165522..4b3a390f1 100644
--- a/pkg/api/handlers/compat/info.go
+++ b/pkg/api/handlers/compat/info.go
@@ -17,6 +17,7 @@ import (
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/rootless"
docker "github.com/docker/docker/api/types"
+ "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
"github.com/google/uuid"
"github.com/pkg/errors"
@@ -103,7 +104,7 @@ func GetInfo(w http.ResponseWriter, r *http.Request) {
PidsLimit: sysInfo.PidsLimit,
Plugins: docker.PluginsInfo{},
ProductLicense: "Apache-2.0",
- RegistryConfig: nil,
+ RegistryConfig: new(registry.ServiceConfig),
RuncCommit: docker.Commit{},
Runtimes: getRuntimes(configInfo),
SecurityOptions: getSecOpts(sysInfo),
diff --git a/pkg/api/handlers/compat/ping.go b/pkg/api/handlers/compat/ping.go
index 06150bb63..9f6611b30 100644
--- a/pkg/api/handlers/compat/ping.go
+++ b/pkg/api/handlers/compat/ping.go
@@ -19,11 +19,10 @@ func Ping(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Pragma", "no-cache")
- w.Header().Set("Libpod-Buildha-Version", buildah.Version)
+ w.Header().Set("Libpod-Buildah-Version", buildah.Version)
w.WriteHeader(http.StatusOK)
if r.Method == http.MethodGet {
fmt.Fprint(w, "OK")
}
- fmt.Fprint(w, "\n")
}
diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go
index 7e6481321..14eb44831 100644
--- a/pkg/api/handlers/libpod/containers.go
+++ b/pkg/api/handlers/libpod/containers.go
@@ -344,3 +344,27 @@ func InitContainer(w http.ResponseWriter, r *http.Request) {
}
utils.WriteResponse(w, http.StatusNoContent, "")
}
+
+func ShouldRestart(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ // Now use the ABI implementation to prevent us from having duplicate
+ // code.
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
+
+ name := utils.GetName(r)
+ report, err := containerEngine.ShouldRestart(r.Context(), name)
+ if err != nil {
+ if errors.Cause(err) == define.ErrNoSuchCtr {
+ utils.ContainerNotFound(w, name, err)
+ return
+ }
+ utils.InternalServerError(w, err)
+ return
+
+ }
+ if report.Value {
+ utils.WriteResponse(w, http.StatusNoContent, "")
+ } else {
+ utils.ContainerNotFound(w, name, define.ErrNoSuchCtr)
+ }
+}
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 55264b3b6..be5a394de 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -422,8 +422,7 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
source := strings.TrimSuffix(utils.GetName(r), "/push") // GetName returns the entire path
if _, err := utils.ParseStorageReference(source); err != nil {
- utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Wrapf(err, "image source %q is not a containers-storage-transport reference", source))
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
@@ -433,8 +432,7 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
}
if _, err := utils.ParseDockerReference(destination); err != nil {
- utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Wrapf(err, "image destination %q is not a docker-transport reference", destination))
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go
index 05e4b8258..5e2727e95 100644
--- a/pkg/api/handlers/libpod/images_pull.go
+++ b/pkg/api/handlers/libpod/images_pull.go
@@ -53,8 +53,7 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
imageRef, err := utils.ParseDockerReference(query.Reference)
if err != nil {
- utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Wrapf(err, "image destination %q is not a docker-transport reference", query.Reference))
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go
index 6bb5f5101..40cf16807 100644
--- a/pkg/api/handlers/types.go
+++ b/pkg/api/handlers/types.go
@@ -110,11 +110,12 @@ type ContainerWaitOKBody struct {
}
}
+// CreateContainerConfig used when compatible endpoint creates a container
type CreateContainerConfig struct {
- Name string
- dockerContainer.Config
- HostConfig dockerContainer.HostConfig
- NetworkingConfig dockerNetwork.NetworkingConfig
+ Name string // container name
+ dockerContainer.Config // desired container configuration
+ HostConfig dockerContainer.HostConfig // host dependent configuration for container
+ NetworkingConfig dockerNetwork.NetworkingConfig // network configuration for container
}
// swagger:model IDResponse
@@ -253,7 +254,7 @@ func ImageDataToImageInspect(ctx context.Context, l *libpodImage.Image) (*ImageI
// StdinOnce: false,
Env: info.Config.Env,
Cmd: info.Config.Cmd,
- //Healthcheck: l.ImageData.HealthCheck,
+ // Healthcheck: l.ImageData.HealthCheck,
// ArgsEscaped: false,
// Image: "",
Volumes: info.Config.Volumes,
@@ -261,7 +262,7 @@ func ImageDataToImageInspect(ctx context.Context, l *libpodImage.Image) (*ImageI
Entrypoint: info.Config.Entrypoint,
// NetworkDisabled: false,
// MacAddress: "",
- //OnBuild: info.Config.OnBuild,
+ // OnBuild: info.Config.OnBuild,
Labels: info.Labels,
StopSignal: info.Config.StopSignal,
// StopTimeout: nil,
diff --git a/pkg/api/server/handler_api.go b/pkg/api/server/handler_api.go
index 28f5a0b42..1d0ddb457 100644
--- a/pkg/api/server/handler_api.go
+++ b/pkg/api/server/handler_api.go
@@ -30,14 +30,14 @@ func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc {
// Wrapper to hide some boiler plate
fn := func(w http.ResponseWriter, r *http.Request) {
rid := uuid.New().String()
+ logrus.Infof("APIHandler(%s) -- %s %s BEGIN", rid, r.Method, r.URL.String())
if logrus.IsLevelEnabled(logrus.DebugLevel) {
- logrus.Debugf("APIHandler(%s) -- Method: %s URL: %s", rid, r.Method, r.URL.String())
for k, v := range r.Header {
switch auth.HeaderAuthName(k) {
case auth.XRegistryConfigHeader, auth.XRegistryAuthHeader:
- logrus.Debugf("APIHandler(%s) -- Header: %s: <hidden>", rid, k)
+ logrus.Debugf("APIHandler(%s) -- Header: %s=<hidden>", rid, k)
default:
- logrus.Debugf("APIHandler(%s) -- Header: %s: %v", rid, k, v)
+ logrus.Debugf("APIHandler(%s) -- Header: %s=%v", rid, k, v)
}
}
}
@@ -63,6 +63,7 @@ func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc {
w.Header().Set("Server", "Libpod/"+lv+" ("+runtime.GOOS+")")
h(w, r)
+ logrus.Debugf("APIHandler(%s) -- %s %s END", rid, r.Method, r.URL.String())
}
fn(w, r)
}
diff --git a/pkg/api/server/listener_api.go b/pkg/api/server/listener_api.go
index 4984216b8..2d02df7dc 100644
--- a/pkg/api/server/listener_api.go
+++ b/pkg/api/server/listener_api.go
@@ -27,5 +27,6 @@ func ListenUnix(network string, path string) (net.Listener, error) {
if err != nil {
return nil, errors.Wrapf(err, "net.Listen(%s, %s) failed to report the failure to create socket", network, path)
}
+
return listener, nil
}
diff --git a/pkg/api/server/register_ping.go b/pkg/api/server/register_ping.go
index 4e299008c..446a12a68 100644
--- a/pkg/api/server/register_ping.go
+++ b/pkg/api/server/register_ping.go
@@ -53,7 +53,7 @@ func (s *APIServer) registerPingHandlers(r *mux.Router) error {
// Max Podman API Version the server supports.
// Available if service is backed by Podman, therefore may be used to
// determine if talking to Podman engine or another engine
- // Libpod-Buildha-Version:
+ // Libpod-Buildah-Version:
// type: string
// description: |
// Default version of libpod image builder.
diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go
index 64008767b..09b6079e4 100644
--- a/pkg/api/server/server.go
+++ b/pkg/api/server/server.go
@@ -51,10 +51,7 @@ func NewServer(runtime *libpod.Runtime) (*APIServer, error) {
}
// NewServerWithSettings will create and configure a new API server using provided settings
-func NewServerWithSettings(runtime *libpod.Runtime, duration time.Duration, listener *net.Listener) (
- *APIServer,
- error,
-) {
+func NewServerWithSettings(runtime *libpod.Runtime, duration time.Duration, listener *net.Listener) (*APIServer, error) {
return newServer(runtime, duration, listener)
}
@@ -75,6 +72,7 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
listener = &listeners[0]
}
+ logrus.Infof("API server listening on %q", (*listener).Addr())
router := mux.NewRouter().UseEncodedPath()
idle := idle.NewTracker(duration)
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index b5cd2128b..4331ae6c2 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -390,3 +390,15 @@ func ContainerInit(ctx context.Context, nameOrID string) error {
}
return response.Process(nil)
}
+
+func ShouldRestart(ctx context.Context, nameOrID string) (bool, error) {
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return false, err
+ }
+ response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/shouldrestart", nil, nil, nameOrID)
+ if err != nil {
+ return false, err
+ }
+ return response.IsSuccess(), nil
+}
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index 101542a98..ab545d882 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -51,10 +51,10 @@ func (i *Image) Id() string { // nolint
}
type ImageSummary struct {
- ID string `json:"Id"`
- ParentId string `json:",omitempty"` // nolint
- RepoTags []string `json:",omitempty"`
- Created int64 `json:",omitempty"`
+ ID string `json:"Id"`
+ ParentId string // nolint
+ RepoTags []string `json:",omitempty"`
+ Created int64
Size int64 `json:",omitempty"`
SharedSize int `json:",omitempty"`
VirtualSize int64 `json:",omitempty"`
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 4b69ac74e..ff4277a2e 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -911,7 +911,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
} else {
report.ExitCode = int(ecode)
}
- if opts.Rm {
+ if opts.Rm && !ctr.ShouldRestart(ctx) {
if err := ic.Libpod.RemoveContainer(ctx, ctr, false, true); err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr ||
errors.Cause(err) == define.ErrCtrRemoved {
@@ -992,7 +992,7 @@ func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []st
return []*entities.ContainerCleanupReport{}, nil
}
- if options.Remove {
+ if options.Remove && !ctr.ShouldRestart(ctx) {
err = ic.Libpod.RemoveContainer(ctx, ctr, false, true)
if err != nil {
report.RmErr = errors.Wrapf(err, "failed to cleanup and remove container %v", ctr.ID())
@@ -1015,6 +1015,7 @@ func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []st
_, err = ic.Libpod.RemoveImage(ctx, ctrImage, false)
report.RmiErr = err
}
+
reports = append(reports, &report)
}
return reports, nil
@@ -1314,3 +1315,13 @@ func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []stri
return statsChan, nil
}
+
+// ShouldRestart returns whether the container should be restarted
+func (ic *ContainerEngine) ShouldRestart(ctx context.Context, nameOrID string) (*entities.BoolReport, error) {
+ ctr, err := ic.Libpod.LookupContainer(nameOrID)
+ if err != nil {
+ return nil, err
+ }
+
+ return &entities.BoolReport{Value: ctr.ShouldRestart(ctx)}, nil
+}
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 4bcc6469c..3aeb6a2ee 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -8,7 +8,6 @@ import (
"os"
"strings"
- "github.com/containers/buildah/pkg/parse"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/image"
@@ -24,13 +23,6 @@ import (
v1 "k8s.io/api/core/v1"
)
-const (
- // https://kubernetes.io/docs/concepts/storage/volumes/#hostpath
- kubeDirectoryPermission = 0755
- // https://kubernetes.io/docs/concepts/storage/volumes/#hostpath
- kubeFilePermission = 0644
-)
-
func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options entities.PlayKubeOptions) (*entities.PlayKubeReport, error) {
var (
kubeObject v1.ObjectReference
@@ -168,62 +160,9 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
DockerInsecureSkipTLSVerify: options.SkipTLSVerify,
}
- // map from name to mount point
- volumes := make(map[string]string)
- for _, volume := range podYAML.Spec.Volumes {
- hostPath := volume.VolumeSource.HostPath
- if hostPath == nil {
- return nil, errors.Errorf("HostPath is currently the only supported VolumeSource")
- }
- if hostPath.Type != nil {
- switch *hostPath.Type {
- case v1.HostPathDirectoryOrCreate:
- if _, err := os.Stat(hostPath.Path); os.IsNotExist(err) {
- if err := os.Mkdir(hostPath.Path, kubeDirectoryPermission); err != nil {
- return nil, err
- }
- }
- // Label a newly created volume
- if err := libpod.LabelVolumePath(hostPath.Path); err != nil {
- return nil, errors.Wrapf(err, "error giving %s a label", hostPath.Path)
- }
- case v1.HostPathFileOrCreate:
- if _, err := os.Stat(hostPath.Path); os.IsNotExist(err) {
- f, err := os.OpenFile(hostPath.Path, os.O_RDONLY|os.O_CREATE, kubeFilePermission)
- if err != nil {
- return nil, errors.Wrap(err, "error creating HostPath")
- }
- if err := f.Close(); err != nil {
- logrus.Warnf("Error in closing newly created HostPath file: %v", err)
- }
- }
- // unconditionally label a newly created volume
- if err := libpod.LabelVolumePath(hostPath.Path); err != nil {
- return nil, errors.Wrapf(err, "error giving %s a label", hostPath.Path)
- }
- case v1.HostPathSocket:
- st, err := os.Stat(hostPath.Path)
- if err != nil {
- return nil, errors.Wrap(err, "error checking HostPathSocket")
- }
- if st.Mode()&os.ModeSocket != os.ModeSocket {
- return nil, errors.Errorf("error checking HostPathSocket: path %s is not a socket", hostPath.Path)
- }
-
- case v1.HostPathDirectory:
- case v1.HostPathFile:
- case v1.HostPathUnset:
- // do nothing here because we will verify the path exists in validateVolumeHostDir
- break
- default:
- return nil, errors.Errorf("Invalid HostPath type %v", hostPath.Type)
- }
- }
-
- if err := parse.ValidateVolumeHostDir(hostPath.Path); err != nil {
- return nil, errors.Wrapf(err, "error in parsing HostPath in YAML")
- }
- volumes[volume.Name] = hostPath.Path
+ volumes, err := kube.InitializeVolumes(podYAML.Spec.Volumes)
+ if err != nil {
+ return nil, err
}
seccompPaths, err := kube.InitializeSeccompPaths(podYAML.ObjectMeta.Annotations, options.SeccompProfileRoot)
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 8066e1c00..63677719b 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -235,7 +235,7 @@ func (ic *ContainerEngine) ContainerCommit(ctx context.Context, nameOrID string,
if len(options.ImageName) > 0 {
ref, err := reference.Parse(options.ImageName)
if err != nil {
- return nil, err
+ return nil, errors.Wrapf(err, "error parsing reference %q", options.ImageName)
}
if t, ok := ref.(reference.Tagged); ok {
tag = t.Tag()
@@ -595,12 +595,20 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
// Defer the removal, so we can return early if needed and
// de-spaghetti the code.
defer func() {
- if err := containers.Remove(ic.ClientCxt, con.ID, bindings.PFalse, bindings.PTrue); err != nil {
- if errorhandling.Contains(err, define.ErrNoSuchCtr) ||
- errorhandling.Contains(err, define.ErrCtrRemoved) {
- logrus.Warnf("Container %s does not exist: %v", con.ID, err)
- } else {
- logrus.Errorf("Error removing container %s: %v", con.ID, err)
+ shouldRestart, err := containers.ShouldRestart(ic.ClientCxt, con.ID)
+ if err != nil {
+ logrus.Errorf("Failed to check if %s should restart: %v", con.ID, err)
+ return
+ }
+
+ if !shouldRestart {
+ if err := containers.Remove(ic.ClientCxt, con.ID, bindings.PFalse, bindings.PTrue); err != nil {
+ if errorhandling.Contains(err, define.ErrNoSuchCtr) ||
+ errorhandling.Contains(err, define.ErrCtrRemoved) {
+ logrus.Warnf("Container %s does not exist: %v", con.ID, err)
+ } else {
+ logrus.Errorf("Error removing container %s: %v", con.ID, err)
+ }
}
}
}()
@@ -737,3 +745,8 @@ func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []stri
}
return containers.Stats(ic.ClientCxt, namesOrIds, &options.Stream)
}
+
+// ShouldRestart reports back whether the containre will restart
+func (ic *ContainerEngine) ShouldRestart(_ context.Context, id string) (bool, error) {
+ return containers.ShouldRestart(ic.ClientCxt, id)
+}
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 61ac2141c..09931de12 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -119,7 +119,7 @@ func (ir *ImageEngine) Tag(ctx context.Context, nameOrID string, tags []string,
)
ref, err := reference.Parse(newTag)
if err != nil {
- return err
+ return errors.Wrapf(err, "error parsing reference %q", newTag)
}
if t, ok := ref.(reference.Tagged); ok {
tag = t.Tag()
@@ -148,7 +148,7 @@ func (ir *ImageEngine) Untag(ctx context.Context, nameOrID string, tags []string
)
ref, err := reference.Parse(newTag)
if err != nil {
- return err
+ return errors.Wrapf(err, "error parsing reference %q", newTag)
}
if t, ok := ref.(reference.Tagged); ok {
tag = t.Tag()
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 2ee8f2441..c7e62d185 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -257,7 +257,19 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
}
}
- return verifyContainerResources(s)
+ warnings, err := verifyContainerResources(s)
+ if err != nil {
+ return warnings, err
+ }
+
+ // Warn on net=host/container/pod/none and port mappings.
+ if (s.NetNS.NSMode == specgen.Host || s.NetNS.NSMode == specgen.FromContainer ||
+ s.NetNS.NSMode == specgen.FromPod || s.NetNS.NSMode == specgen.NoNetwork) &&
+ len(s.PortMappings) > 0 {
+ warnings = append(warnings, "Port mappings have been discarded as one of the Host, Container, Pod, and None network modes are in use")
+ }
+
+ return warnings, nil
}
// finishThrottleDevices takes the temporary representation of the throttle
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index e1202956c..5f72d28bb 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -47,7 +47,7 @@ func ToPodGen(ctx context.Context, podName string, podYAML *v1.PodTemplateSpec)
return p, nil
}
-func ToSpecGen(ctx context.Context, containerYAML v1.Container, iid string, newImage *image.Image, volumes map[string]string, podID, podName, infraID string, configMaps []v1.ConfigMap, seccompPaths *KubeSeccompPaths, restartPolicy string) (*specgen.SpecGenerator, error) {
+func ToSpecGen(ctx context.Context, containerYAML v1.Container, iid string, newImage *image.Image, volumes map[string]*KubeVolume, podID, podName, infraID string, configMaps []v1.ConfigMap, seccompPaths *KubeSeccompPaths, restartPolicy string) (*specgen.SpecGenerator, error) {
s := specgen.NewSpecGenerator(iid, false)
// podName should be non-empty for Deployment objects to be able to create
@@ -163,22 +163,36 @@ func ToSpecGen(ctx context.Context, containerYAML v1.Container, iid string, newI
s.Env = envs
for _, volume := range containerYAML.VolumeMounts {
- hostPath, exists := volumes[volume.Name]
+ volumeSource, exists := volumes[volume.Name]
if !exists {
return nil, errors.Errorf("Volume mount %s specified for container but not configured in volumes", volume.Name)
}
- if err := parse.ValidateVolumeCtrDir(volume.MountPath); err != nil {
- return nil, errors.Wrapf(err, "error in parsing MountPath")
- }
- mount := spec.Mount{
- Destination: volume.MountPath,
- Source: hostPath,
- Type: "bind",
- }
- if volume.ReadOnly {
- mount.Options = []string{"ro"}
+ switch volumeSource.Type {
+ case KubeVolumeTypeBindMount:
+ if err := parse.ValidateVolumeCtrDir(volume.MountPath); err != nil {
+ return nil, errors.Wrapf(err, "error in parsing MountPath")
+ }
+ mount := spec.Mount{
+ Destination: volume.MountPath,
+ Source: volumeSource.Source,
+ Type: "bind",
+ }
+ if volume.ReadOnly {
+ mount.Options = []string{"ro"}
+ }
+ s.Mounts = append(s.Mounts, mount)
+ case KubeVolumeTypeNamed:
+ namedVolume := specgen.NamedVolume{
+ Dest: volume.MountPath,
+ Name: volumeSource.Source,
+ }
+ if volume.ReadOnly {
+ namedVolume.Options = []string{"ro"}
+ }
+ s.Volumes = append(s.Volumes, &namedVolume)
+ default:
+ return nil, errors.Errorf("Unsupported volume source type")
}
- s.Mounts = append(s.Mounts, mount)
}
s.RestartPolicy = restartPolicy
diff --git a/pkg/specgen/generate/kube/volume.go b/pkg/specgen/generate/kube/volume.go
new file mode 100644
index 000000000..2ef0f4c23
--- /dev/null
+++ b/pkg/specgen/generate/kube/volume.go
@@ -0,0 +1,124 @@
+package kube
+
+import (
+ "os"
+
+ "github.com/containers/buildah/pkg/parse"
+ "github.com/containers/podman/v2/libpod"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+ v1 "k8s.io/api/core/v1"
+)
+
+const (
+ // https://kubernetes.io/docs/concepts/storage/volumes/#hostpath
+ kubeDirectoryPermission = 0755
+ // https://kubernetes.io/docs/concepts/storage/volumes/#hostpath
+ kubeFilePermission = 0644
+)
+
+type KubeVolumeType int
+
+const (
+ KubeVolumeTypeBindMount KubeVolumeType = iota
+ KubeVolumeTypeNamed KubeVolumeType = iota
+)
+
+type KubeVolume struct {
+ // Type of volume to create
+ Type KubeVolumeType
+ // Path for bind mount or volume name for named volume
+ Source string
+}
+
+// Create a KubeVolume from an HostPathVolumeSource
+func VolumeFromHostPath(hostPath *v1.HostPathVolumeSource) (*KubeVolume, error) {
+ if hostPath.Type != nil {
+ switch *hostPath.Type {
+ case v1.HostPathDirectoryOrCreate:
+ if _, err := os.Stat(hostPath.Path); os.IsNotExist(err) {
+ if err := os.Mkdir(hostPath.Path, kubeDirectoryPermission); err != nil {
+ return nil, err
+ }
+ }
+ // Label a newly created volume
+ if err := libpod.LabelVolumePath(hostPath.Path); err != nil {
+ return nil, errors.Wrapf(err, "error giving %s a label", hostPath.Path)
+ }
+ case v1.HostPathFileOrCreate:
+ if _, err := os.Stat(hostPath.Path); os.IsNotExist(err) {
+ f, err := os.OpenFile(hostPath.Path, os.O_RDONLY|os.O_CREATE, kubeFilePermission)
+ if err != nil {
+ return nil, errors.Wrap(err, "error creating HostPath")
+ }
+ if err := f.Close(); err != nil {
+ logrus.Warnf("Error in closing newly created HostPath file: %v", err)
+ }
+ }
+ // unconditionally label a newly created volume
+ if err := libpod.LabelVolumePath(hostPath.Path); err != nil {
+ return nil, errors.Wrapf(err, "error giving %s a label", hostPath.Path)
+ }
+ case v1.HostPathSocket:
+ st, err := os.Stat(hostPath.Path)
+ if err != nil {
+ return nil, errors.Wrap(err, "error checking HostPathSocket")
+ }
+ if st.Mode()&os.ModeSocket != os.ModeSocket {
+ return nil, errors.Errorf("error checking HostPathSocket: path %s is not a socket", hostPath.Path)
+ }
+
+ case v1.HostPathDirectory:
+ case v1.HostPathFile:
+ case v1.HostPathUnset:
+ // do nothing here because we will verify the path exists in validateVolumeHostDir
+ break
+ default:
+ return nil, errors.Errorf("Invalid HostPath type %v", hostPath.Type)
+ }
+ }
+
+ if err := parse.ValidateVolumeHostDir(hostPath.Path); err != nil {
+ return nil, errors.Wrapf(err, "error in parsing HostPath in YAML")
+ }
+
+ return &KubeVolume{
+ Type: KubeVolumeTypeBindMount,
+ Source: hostPath.Path,
+ }, nil
+}
+
+// Create a KubeVolume from a PersistentVolumeClaimVolumeSource
+func VolumeFromPersistentVolumeClaim(claim *v1.PersistentVolumeClaimVolumeSource) (*KubeVolume, error) {
+ return &KubeVolume{
+ Type: KubeVolumeTypeNamed,
+ Source: claim.ClaimName,
+ }, nil
+}
+
+// Create a KubeVolume from one of the supported VolumeSource
+func VolumeFromSource(volumeSource v1.VolumeSource) (*KubeVolume, error) {
+ if volumeSource.HostPath != nil {
+ return VolumeFromHostPath(volumeSource.HostPath)
+ } else if volumeSource.PersistentVolumeClaim != nil {
+ return VolumeFromPersistentVolumeClaim(volumeSource.PersistentVolumeClaim)
+ } else {
+ return nil, errors.Errorf("HostPath and PersistentVolumeClaim are currently the conly supported VolumeSource")
+ }
+}
+
+// Create a map of volume name to KubeVolume
+func InitializeVolumes(specVolumes []v1.Volume) (map[string]*KubeVolume, error) {
+ volumes := make(map[string]*KubeVolume)
+
+ for _, specVolume := range specVolumes {
+ volume, err := VolumeFromSource(specVolume.VolumeSource)
+ if err != nil {
+ return nil, err
+ }
+
+ volumes[specVolume.Name] = volume
+ }
+
+ return volumes, nil
+}
diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go
index 90c56d366..d15745fa0 100644
--- a/pkg/specgen/namespaces.go
+++ b/pkg/specgen/namespaces.go
@@ -27,19 +27,25 @@ const (
// Private indicates the namespace is private
Private NamespaceMode = "private"
// NoNetwork indicates no network namespace should
- // be joined. loopback should still exists
+ // be joined. loopback should still exists.
+ // Only used with the network namespace, invalid otherwise.
NoNetwork NamespaceMode = "none"
// Bridge indicates that a CNI network stack
- // should be used
+ // should be used.
+ // Only used with the network namespace, invalid otherwise.
Bridge NamespaceMode = "bridge"
// Slirp indicates that a slirp4netns network stack should
- // be used
+ // be used.
+ // Only used with the network namespace, invalid otherwise.
Slirp NamespaceMode = "slirp4netns"
// KeepId indicates a user namespace to keep the owner uid inside
- // of the namespace itself
+ // of the namespace itself.
+ // Only used with the user namespace, invalid otherwise.
KeepID NamespaceMode = "keep-id"
- // KeepId indicates to automatically create a user namespace
+ // Auto indicates to automatically create a user namespace.
+ // Only used with the user namespace, invalid otherwise.
Auto NamespaceMode = "auto"
+
// DefaultKernelNamespaces is a comma-separated list of default kernel
// namespaces.
DefaultKernelNamespaces = "cgroup,ipc,net,uts"
diff --git a/pkg/specgen/volumes.go b/pkg/specgen/volumes.go
index 1178f9960..a4f42d715 100644
--- a/pkg/specgen/volumes.go
+++ b/pkg/specgen/volumes.go
@@ -87,8 +87,8 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
// Do not check source dir for anonymous volumes
if len(splitVol) > 1 {
- if err := parse.ValidateVolumeHostDir(src); err != nil {
- return nil, nil, nil, err
+ if len(src) == 0 {
+ return nil, nil, nil, errors.New("host directory cannot be empty")
}
}
if err := parse.ValidateVolumeCtrDir(dest); err != nil {
diff --git a/test/apiv2/25-containersMore.at b/test/apiv2/25-containersMore.at
index e0e6f7222..4f6b80a5f 100644
--- a/test/apiv2/25-containersMore.at
+++ b/test/apiv2/25-containersMore.at
@@ -52,4 +52,31 @@ t POST libpod/containers/foo/unmount '' 204
t DELETE libpod/containers/foo?force=true 204
+podman run $IMAGE true
+
+t GET libpod/containers/json?last=1 200 \
+ length=1 \
+ .[0].Id~[0-9a-f]\\{64\\} \
+ .[0].Image=$IMAGE \
+ .[0].Command[0]="true" \
+ .[0].State~\\\(exited\\\|stopped\\\) \
+ .[0].ExitCode=0 \
+ .[0].IsInfra=false
+
+cid=$(jq -r '.[0].Id' <<<"$output")
+
+t GET libpod/generate/$cid/kube 200
+like "$output" ".*apiVersion:.*" "Check generated kube yaml - apiVersion"
+like "$output" ".*kind:\\sPod.*" "Check generated kube yaml - kind: Pod"
+like "$output" ".*metadata:.*" "Check generated kube yaml - metadata"
+like "$output" ".*spec:.*" "Check generated kube yaml - spec"
+
+t GET libpod/generate/$cid/kube?service=true 200
+like "$output" ".*apiVersion:.*" "Check generated kube yaml(service=true) - apiVersion"
+like "$output" ".*kind:\\sPod.*" "Check generated kube yaml(service=true) - kind: Pod"
+like "$output" ".*metadata:.*" "Check generated kube yaml(service=true) - metadata"
+like "$output" ".*spec:.*" "Check generated kube yaml(service=true) - spec"
+like "$output" ".*kind:\\sService.*" "Check generated kube yaml(service=true) - kind: Service"
+
+t DELETE libpod/containers/$cid 204
# vim: filetype=sh
diff --git a/test/apiv2/rest_api/__init__.py b/test/apiv2/rest_api/__init__.py
index 8100a4df5..db0257f03 100644
--- a/test/apiv2/rest_api/__init__.py
+++ b/test/apiv2/rest_api/__init__.py
@@ -16,19 +16,18 @@ class Podman(object):
binary = os.getenv("PODMAN", "bin/podman")
self.cmd = [binary, "--storage-driver=vfs"]
- cgroupfs = os.getenv("CGROUP_MANAGER", "cgroupfs")
+ cgroupfs = os.getenv("CGROUP_MANAGER", "systemd")
self.cmd.append(f"--cgroup-manager={cgroupfs}")
if os.getenv("DEBUG"):
self.cmd.append("--log-level=debug")
+ self.cmd.append("--syslog=true")
self.anchor_directory = tempfile.mkdtemp(prefix="podman_restapi_")
self.cmd.append("--root=" + os.path.join(self.anchor_directory, "crio"))
self.cmd.append("--runroot=" + os.path.join(self.anchor_directory, "crio-run"))
- os.environ["REGISTRIES_CONFIG_PATH"] = os.path.join(
- self.anchor_directory, "registry.conf"
- )
+ os.environ["REGISTRIES_CONFIG_PATH"] = os.path.join(self.anchor_directory, "registry.conf")
p = configparser.ConfigParser()
p.read_dict(
{
@@ -40,14 +39,10 @@ class Podman(object):
with open(os.environ["REGISTRIES_CONFIG_PATH"], "w") as w:
p.write(w)
- os.environ["CNI_CONFIG_PATH"] = os.path.join(
- self.anchor_directory, "cni", "net.d"
- )
+ os.environ["CNI_CONFIG_PATH"] = os.path.join(self.anchor_directory, "cni", "net.d")
os.makedirs(os.environ["CNI_CONFIG_PATH"], exist_ok=True)
self.cmd.append("--cni-config-dir=" + os.environ["CNI_CONFIG_PATH"])
- cni_cfg = os.path.join(
- os.environ["CNI_CONFIG_PATH"], "87-podman-bridge.conflist"
- )
+ cni_cfg = os.path.join(os.environ["CNI_CONFIG_PATH"], "87-podman-bridge.conflist")
# json decoded and encoded to ensure legal json
buf = json.loads(
"""
diff --git a/test/apiv2/rest_api/test_rest_v2_0_0.py b/test/apiv2/rest_api/test_rest_v2_0_0.py
index 49e18f063..52348d4f4 100644
--- a/test/apiv2/rest_api/test_rest_v2_0_0.py
+++ b/test/apiv2/rest_api/test_rest_v2_0_0.py
@@ -61,9 +61,7 @@ class TestApi(unittest.TestCase):
super().setUpClass()
TestApi.podman = Podman()
- TestApi.service = TestApi.podman.open(
- "system", "service", "tcp:localhost:8080", "--time=0"
- )
+ TestApi.service = TestApi.podman.open("system", "service", "tcp:localhost:8080", "--time=0")
# give the service some time to be ready...
time.sleep(2)
@@ -165,11 +163,71 @@ class TestApi(unittest.TestCase):
r = requests.get(_url(ctnr("/containers/{}/logs?stdout=true")))
self.assertEqual(r.status_code, 200, r.text)
- def test_post_create_compat(self):
+ # TODO Need to support Docker-py order of network/container creates
+ def test_post_create_compat_connect(self):
"""Create network and container then connect to network"""
- net = requests.post(
- PODMAN_URL + "/v1.40/networks/create", json={"Name": "TestNetwork"}
+ net_default = requests.post(
+ PODMAN_URL + "/v1.40/networks/create", json={"Name": "TestDefaultNetwork"}
+ )
+ self.assertEqual(net_default.status_code, 201, net_default.text)
+
+ create = requests.post(
+ PODMAN_URL + "/v1.40/containers/create?name=postCreate",
+ json={
+ "Cmd": ["top"],
+ "Image": "alpine:latest",
+ "NetworkDisabled": False,
+ # FIXME adding these 2 lines cause: (This is sampled from docker-py)
+ # "network already exists","message":"container
+ # 01306e499df5441560d70071a54342611e422a94de20865add50a9565fd79fb9 is already connected to CNI network \"TestDefaultNetwork\": network already exists"
+ # "HostConfig": {"NetworkMode": "TestDefaultNetwork"},
+ # "NetworkingConfig": {"EndpointsConfig": {"TestDefaultNetwork": None}},
+ # FIXME These two lines cause:
+ # CNI network \"TestNetwork\" not found","message":"error configuring network namespace for container 369ddfa7d3211ebf1fbd5ddbff91bd33fa948858cea2985c133d6b6507546dff: CNI network \"TestNetwork\" not found"
+ # "HostConfig": {"NetworkMode": "TestNetwork"},
+ # "NetworkingConfig": {"EndpointsConfig": {"TestNetwork": None}},
+ # FIXME no networking defined cause: (note this error is from the container inspect below)
+ # "internal libpod error","message":"network inspection mismatch: asked to join 2 CNI network(s) [TestDefaultNetwork podman], but have information on 1 network(s): internal libpod error"
+ },
+ )
+ self.assertEqual(create.status_code, 201, create.text)
+ payload = json.loads(create.text)
+ self.assertIsNotNone(payload["Id"])
+
+ start = requests.post(PODMAN_URL + f"/v1.40/containers/{payload['Id']}/start")
+ self.assertEqual(start.status_code, 204, start.text)
+
+ connect = requests.post(
+ PODMAN_URL + "/v1.40/networks/TestDefaultNetwork/connect",
+ json={"Container": payload["Id"]},
+ )
+ self.assertEqual(connect.status_code, 200, connect.text)
+ self.assertEqual(connect.text, "OK\n")
+
+ inspect = requests.get(f"{PODMAN_URL}/v1.40/containers/{payload['Id']}/json")
+ self.assertEqual(inspect.status_code, 200, inspect.text)
+
+ payload = json.loads(inspect.text)
+ self.assertFalse(payload["Config"].get("NetworkDisabled", False))
+
+ self.assertEqual(
+ "TestDefaultNetwork",
+ payload["NetworkSettings"]["Networks"]["TestDefaultNetwork"]["NetworkID"],
)
+ # TODO restore this to test, when joining multiple networks possible
+ # self.assertEqual(
+ # "TestNetwork",
+ # payload["NetworkSettings"]["Networks"]["TestNetwork"]["NetworkID"],
+ # )
+ # TODO Need to support network aliases
+ # self.assertIn(
+ # "test_post_create",
+ # payload["NetworkSettings"]["Networks"]["TestNetwork"]["Aliases"],
+ # )
+
+ def test_post_create_compat(self):
+ """Create network and connect container during create"""
+ net = requests.post(PODMAN_URL + "/v1.40/networks/create", json={"Name": "TestNetwork"})
self.assertEqual(net.status_code, 201, net.text)
create = requests.post(
@@ -178,23 +236,21 @@ class TestApi(unittest.TestCase):
"Cmd": ["date"],
"Image": "alpine:latest",
"NetworkDisabled": False,
- "NetworkConfig": {
- "EndpointConfig": {"TestNetwork": {"Aliases": ["test_post_create"]}}
- },
+ "HostConfig": {"NetworkMode": "TestNetwork"},
},
)
self.assertEqual(create.status_code, 201, create.text)
payload = json.loads(create.text)
self.assertIsNotNone(payload["Id"])
- # This cannot be done until full completion of the network connect
- # stack and network disconnect stack are complete
- # connect = requests.post(
- # PODMAN_URL + "/v1.40/networks/TestNetwork/connect",
- # json={"Container": payload["Id"]},
- # )
- # self.assertEqual(connect.status_code, 200, connect.text)
- # self.assertEqual(connect.text, "OK\n")
+ inspect = requests.get(f"{PODMAN_URL}/v1.40/containers/{payload['Id']}/json")
+ self.assertEqual(inspect.status_code, 200, inspect.text)
+ payload = json.loads(inspect.text)
+ self.assertFalse(payload["Config"].get("NetworkDisabled", False))
+ self.assertEqual(
+ "TestNetwork",
+ payload["NetworkSettings"]["Networks"]["TestNetwork"]["NetworkID"],
+ )
def test_commit(self):
r = requests.post(_url(ctnr("/commit?container={}")))
diff --git a/test/apiv2/rest_api/v1_test_rest_v1_0_0.py b/test/apiv2/rest_api/v1_test_rest_v1_0_0.py
index acd6273ef..23528a246 100644
--- a/test/apiv2/rest_api/v1_test_rest_v1_0_0.py
+++ b/test/apiv2/rest_api/v1_test_rest_v1_0_0.py
@@ -84,9 +84,7 @@ class TestApi(unittest.TestCase):
print("\nService Stderr:\n" + stderr.decode("utf-8"))
if TestApi.podman.returncode > 0:
- sys.stderr.write(
- "podman exited with error code {}\n".format(TestApi.podman.returncode)
- )
+ sys.stderr.write("podman exited with error code {}\n".format(TestApi.podman.returncode))
sys.exit(2)
return super().tearDownClass()
diff --git a/test/e2e/create_staticmac_test.go b/test/e2e/create_staticmac_test.go
index adffdc1ca..1ac431da2 100644
--- a/test/e2e/create_staticmac_test.go
+++ b/test/e2e/create_staticmac_test.go
@@ -5,6 +5,7 @@ import (
"github.com/containers/podman/v2/pkg/rootless"
. "github.com/containers/podman/v2/test/utils"
+ "github.com/containers/storage/pkg/stringid"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
@@ -45,4 +46,21 @@ var _ = Describe("Podman run with --mac-address flag", func() {
Expect(result.OutputToString()).To(ContainSubstring("92:d0:c6:0a:29:34"))
}
})
+
+ It("Podman run --mac-address with custom network", func() {
+ net := "n1" + stringid.GenerateNonCryptoID()
+ session := podmanTest.Podman([]string{"network", "create", net})
+ session.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(net)
+ Expect(session.ExitCode()).To(BeZero())
+
+ result := podmanTest.Podman([]string{"run", "--network", net, "--mac-address", "92:d0:c6:00:29:34", ALPINE, "ip", "addr"})
+ result.WaitWithDefaultTimeout()
+ if rootless.IsRootless() {
+ Expect(result.ExitCode()).To(Equal(125))
+ } else {
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(result.OutputToString()).To(ContainSubstring("92:d0:c6:00:29:34"))
+ }
+ })
})
diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go
index 139a90ac7..adcf74f7e 100644
--- a/test/e2e/network_test.go
+++ b/test/e2e/network_test.go
@@ -499,4 +499,15 @@ var _ = Describe("Podman network", func() {
exec.WaitWithDefaultTimeout()
Expect(exec.ExitCode()).To(BeZero())
})
+
+ It("podman network create/remove macvlan", func() {
+ net := "macvlan" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", "--macvlan", "lo", net})
+ nc.WaitWithDefaultTimeout()
+ Expect(nc.ExitCode()).To(Equal(0))
+
+ nc = podmanTest.Podman([]string{"network", "rm", net})
+ nc.WaitWithDefaultTimeout()
+ Expect(nc.ExitCode()).To(Equal(0))
+ })
})
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index 92e4544f9..5ecfdd6b5 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -164,9 +164,15 @@ spec:
volumes:
{{ range . }}
- name: {{ .Name }}
+ {{- if (eq .VolumeType "HostPath") }}
hostPath:
- path: {{ .Path }}
- type: {{ .Type }}
+ path: {{ .HostPath.Path }}
+ type: {{ .HostPath.Type }}
+ {{- end }}
+ {{- if (eq .VolumeType "PersistentVolumeClaim") }}
+ persistentVolumeClaim:
+ claimName: {{ .PersistentVolumeClaim.ClaimName }}
+ {{- end }}
{{ end }}
{{ end }}
status: {}
@@ -692,19 +698,44 @@ func getCtrNameInPod(pod *Pod) string {
return fmt.Sprintf("%s-%s", pod.Name, defaultCtrName)
}
-type Volume struct {
- Name string
+type HostPath struct {
Path string
Type string
}
-// getVolume takes a type and a location for a volume
-// giving it a default name of volName
-func getVolume(vType, vPath string) *Volume {
+type PersistentVolumeClaim struct {
+ ClaimName string
+}
+
+type Volume struct {
+ VolumeType string
+ Name string
+ HostPath
+ PersistentVolumeClaim
+}
+
+// getHostPathVolume takes a type and a location for a HostPath
+// volume giving it a default name of volName
+func getHostPathVolume(vType, vPath string) *Volume {
+ return &Volume{
+ VolumeType: "HostPath",
+ Name: defaultVolName,
+ HostPath: HostPath{
+ Path: vPath,
+ Type: vType,
+ },
+ }
+}
+
+// getHostPathVolume takes a name for a Persistentvolumeclaim
+// volume giving it a default name of volName
+func getPersistentVolumeClaimVolume(vName string) *Volume {
return &Volume{
- Name: defaultVolName,
- Path: vPath,
- Type: vType,
+ VolumeType: "PersistentVolumeClaim",
+ Name: defaultVolName,
+ PersistentVolumeClaim: PersistentVolumeClaim{
+ ClaimName: vName,
+ },
}
}
@@ -1257,7 +1288,7 @@ spec:
It("podman play kube test with non-existent empty HostPath type volume", func() {
hostPathLocation := filepath.Join(tempdir, "file")
- pod := getPod(withVolume(getVolume(`""`, hostPathLocation)))
+ pod := getPod(withVolume(getHostPathVolume(`""`, hostPathLocation)))
err := generateKubeYaml("pod", pod, kubeYaml)
Expect(err).To(BeNil())
@@ -1272,7 +1303,7 @@ spec:
Expect(err).To(BeNil())
f.Close()
- pod := getPod(withVolume(getVolume(`""`, hostPathLocation)))
+ pod := getPod(withVolume(getHostPathVolume(`""`, hostPathLocation)))
err = generateKubeYaml("pod", pod, kubeYaml)
Expect(err).To(BeNil())
@@ -1284,7 +1315,7 @@ spec:
It("podman play kube test with non-existent File HostPath type volume", func() {
hostPathLocation := filepath.Join(tempdir, "file")
- pod := getPod(withVolume(getVolume("File", hostPathLocation)))
+ pod := getPod(withVolume(getHostPathVolume("File", hostPathLocation)))
err := generateKubeYaml("pod", pod, kubeYaml)
Expect(err).To(BeNil())
@@ -1299,7 +1330,7 @@ spec:
Expect(err).To(BeNil())
f.Close()
- pod := getPod(withVolume(getVolume("File", hostPathLocation)))
+ pod := getPod(withVolume(getHostPathVolume("File", hostPathLocation)))
err = generateKubeYaml("pod", pod, kubeYaml)
Expect(err).To(BeNil())
@@ -1311,7 +1342,7 @@ spec:
It("podman play kube test with FileOrCreate HostPath type volume", func() {
hostPathLocation := filepath.Join(tempdir, "file")
- pod := getPod(withVolume(getVolume("FileOrCreate", hostPathLocation)))
+ pod := getPod(withVolume(getHostPathVolume("FileOrCreate", hostPathLocation)))
err := generateKubeYaml("pod", pod, kubeYaml)
Expect(err).To(BeNil())
@@ -1327,7 +1358,7 @@ spec:
It("podman play kube test with DirectoryOrCreate HostPath type volume", func() {
hostPathLocation := filepath.Join(tempdir, "file")
- pod := getPod(withVolume(getVolume("DirectoryOrCreate", hostPathLocation)))
+ pod := getPod(withVolume(getHostPathVolume("DirectoryOrCreate", hostPathLocation)))
err := generateKubeYaml("pod", pod, kubeYaml)
Expect(err).To(BeNil())
@@ -1347,7 +1378,7 @@ spec:
Expect(err).To(BeNil())
f.Close()
- pod := getPod(withVolume(getVolume("Socket", hostPathLocation)))
+ pod := getPod(withVolume(getHostPathVolume("Socket", hostPathLocation)))
err = generateKubeYaml("pod", pod, kubeYaml)
Expect(err).To(BeNil())
@@ -1356,14 +1387,14 @@ spec:
Expect(kube.ExitCode()).NotTo(Equal(0))
})
- It("podman play kube test with read only volume", func() {
+ It("podman play kube test with read only HostPath volume", func() {
hostPathLocation := filepath.Join(tempdir, "file")
f, err := os.Create(hostPathLocation)
Expect(err).To(BeNil())
f.Close()
ctr := getCtr(withVolumeMount(hostPathLocation, true), withImage(BB))
- pod := getPod(withVolume(getVolume("File", hostPathLocation)), withCtr(ctr))
+ pod := getPod(withVolume(getHostPathVolume("File", hostPathLocation)), withCtr(ctr))
err = generateKubeYaml("pod", pod, kubeYaml)
Expect(err).To(BeNil())
@@ -1379,6 +1410,26 @@ spec:
Expect(inspect.OutputToString()).To(ContainSubstring(correct))
})
+ It("podman play kube test with PersistentVolumeClaim volume", func() {
+ volumeName := "namedVolume"
+
+ ctr := getCtr(withVolumeMount("/test", false), withImage(BB))
+ pod := getPod(withVolume(getPersistentVolumeClaimVolume(volumeName)), withCtr(ctr))
+ err = generateKubeYaml("pod", pod, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube.ExitCode()).To(Equal(0))
+
+ inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "{{ (index .Mounts 0).Type }}:{{ (index .Mounts 0).Name }}"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(Equal(0))
+
+ correct := fmt.Sprintf("volume:%s", volumeName)
+ Expect(inspect.OutputToString()).To(Equal(correct))
+ })
+
It("podman play kube applies labels to pods", func() {
var numReplicas int32 = 5
expectedLabelKey := "key1"
diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go
index fd08d4308..05571157c 100644
--- a/test/e2e/ps_test.go
+++ b/test/e2e/ps_test.go
@@ -44,6 +44,12 @@ var _ = Describe("Podman ps", func() {
Expect(session.ExitCode()).To(Equal(0))
})
+ It("podman container ps no containers", func() {
+ session := podmanTest.Podman([]string{"container", "ps"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ })
+
It("podman ps default", func() {
session := podmanTest.RunTopContainer("")
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 5ee85efb9..0d65a3e59 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -75,11 +75,9 @@ var _ = Describe("Podman run", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- // the --rm option conflicts with --restart, when the restartPolicy is not "" and "no"
- // so the exitCode should not equal 0
session = podmanTest.Podman([]string{"run", "--rm", "--restart", "on-failure", ALPINE})
session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(Not(Equal(0)))
+ Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"run", "--rm", "--restart", "always", ALPINE})
session.WaitWithDefaultTimeout()
diff --git a/test/python/docker/__init__.py b/test/python/docker/__init__.py
index 316b102f4..351834316 100644
--- a/test/python/docker/__init__.py
+++ b/test/python/docker/__init__.py
@@ -39,9 +39,7 @@ class Podman(object):
self.cmd.append("--root=" + os.path.join(self.anchor_directory, "crio"))
self.cmd.append("--runroot=" + os.path.join(self.anchor_directory, "crio-run"))
- os.environ["REGISTRIES_CONFIG_PATH"] = os.path.join(
- self.anchor_directory, "registry.conf"
- )
+ os.environ["REGISTRIES_CONFIG_PATH"] = os.path.join(self.anchor_directory, "registry.conf")
p = configparser.ConfigParser()
p.read_dict(
{
@@ -53,20 +51,16 @@ class Podman(object):
with open(os.environ["REGISTRIES_CONFIG_PATH"], "w") as w:
p.write(w)
- os.environ["CNI_CONFIG_PATH"] = os.path.join(
- self.anchor_directory, "cni", "net.d"
- )
+ os.environ["CNI_CONFIG_PATH"] = os.path.join(self.anchor_directory, "cni", "net.d")
os.makedirs(os.environ["CNI_CONFIG_PATH"], exist_ok=True)
self.cmd.append("--cni-config-dir=" + os.environ["CNI_CONFIG_PATH"])
- cni_cfg = os.path.join(
- os.environ["CNI_CONFIG_PATH"], "87-podman-bridge.conflist"
- )
+ cni_cfg = os.path.join(os.environ["CNI_CONFIG_PATH"], "87-podman-bridge.conflist")
# json decoded and encoded to ensure legal json
buf = json.loads(
"""
{
"cniVersion": "0.3.0",
- "name": "podman",
+ "name": "default",
"plugins": [{
"type": "bridge",
"bridge": "cni0",
diff --git a/test/python/docker/common.py b/test/python/docker/common.py
index e79d64a9b..11f512495 100644
--- a/test/python/docker/common.py
+++ b/test/python/docker/common.py
@@ -4,9 +4,7 @@ from test.python.docker import constant
def run_top_container(client: DockerClient):
- c = client.containers.create(
- constant.ALPINE, command="top", detach=True, tty=True, name="top"
- )
+ c = client.containers.create(constant.ALPINE, command="top", detach=True, tty=True, name="top")
c.start()
return c.id
diff --git a/test/python/docker/test_containers.py b/test/python/docker/test_containers.py
index 0fd419d9d..20d8417c3 100644
--- a/test/python/docker/test_containers.py
+++ b/test/python/docker/test_containers.py
@@ -87,7 +87,7 @@ class TestContainers(unittest.TestCase):
self.assertEqual(len(containers), 2)
def test_stop_container(self):
- top = self.client.containers.get("top")
+ top = self.client.containers.get(TestContainers.topContainerId)
self.assertEqual(top.status, "running")
# Stop a running container and validate the state
diff --git a/test/python/docker/test_images.py b/test/python/docker/test_images.py
index 7ef3d708b..1fa4aade9 100644
--- a/test/python/docker/test_images.py
+++ b/test/python/docker/test_images.py
@@ -78,9 +78,7 @@ class TestImages(unittest.TestCase):
self.assertEqual(len(self.client.images.list()), 2)
# List images with filter
- self.assertEqual(
- len(self.client.images.list(filters={"reference": "alpine"})), 1
- )
+ self.assertEqual(len(self.client.images.list(filters={"reference": "alpine"})), 1)
def test_search_image(self):
"""Search for image"""
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index 12df966e2..71831da10 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -532,4 +532,9 @@ json-file | f
run_podman untag $IMAGE $newtag $newtag2
}
+@test "podman run with --net=host and --port prints warning" {
+ run_podman run -d --rm -p 8080 --net=host $IMAGE ls > /dev/null
+ is "$output" ".*Port mappings have been discarded as one of the Host, Container, Pod, and None network modes are in use"
+}
+
# vim: filetype=sh
diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go
index 9ab47e60c..10e3f17ed 100644
--- a/vendor/github.com/containers/buildah/buildah.go
+++ b/vendor/github.com/containers/buildah/buildah.go
@@ -28,7 +28,7 @@ const (
Package = "buildah"
// Version for the Package. Bump version in contrib/rpm/buildah.spec
// too.
- Version = "1.18.0"
+ Version = "1.19.0-dev"
// The value we use to identify what type of information, currently a
// serialized Builder structure, we are using as per-container state.
// This should only be changed when we make incompatible changes to
diff --git a/vendor/github.com/containers/buildah/go.mod b/vendor/github.com/containers/buildah/go.mod
index b1f3ad67a..0d795f6b6 100644
--- a/vendor/github.com/containers/buildah/go.mod
+++ b/vendor/github.com/containers/buildah/go.mod
@@ -5,12 +5,11 @@ go 1.12
require (
github.com/containerd/containerd v1.4.1 // indirect
github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784
- github.com/containers/common v0.26.3
- github.com/containers/image/v5 v5.8.0
+ github.com/containers/common v0.29.0
+ github.com/containers/image/v5 v5.8.1
github.com/containers/ocicrypt v1.0.3
- github.com/containers/storage v1.24.0
+ github.com/containers/storage v1.24.1
github.com/docker/distribution v2.7.1+incompatible
- github.com/docker/docker v17.12.0-ce-rc1.0.20201020191947-73dc6a680cdd+incompatible // indirect
github.com/docker/go-units v0.4.0
github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316
github.com/fsouza/go-dockerclient v1.6.6
diff --git a/vendor/github.com/containers/buildah/go.sum b/vendor/github.com/containers/buildah/go.sum
index 069328c38..e3413bc68 100644
--- a/vendor/github.com/containers/buildah/go.sum
+++ b/vendor/github.com/containers/buildah/go.sum
@@ -73,20 +73,17 @@ github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDG
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 h1:rqUVLD8I859xRgUx/WMC3v7QAFqbLKZbs+0kqYboRJc=
github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
-github.com/containers/common v0.26.3 h1:5Kb5fMmJ7/xMiJ+iEbPA+5pQpl/FGxCgJex4nml4Slo=
-github.com/containers/common v0.26.3/go.mod h1:hJWZIlrl5MsE2ELNRa+MPp6I1kPbXHauuj0Ym4BsLG4=
-github.com/containers/image/v5 v5.7.0 h1:fiTC8/Xbr+zEP6njGTZtPW/3UD7MC93nC9DbUoWdxkA=
-github.com/containers/image/v5 v5.7.0/go.mod h1:8aOy+YaItukxghRORkvhq5ibWttHErzDLy6egrKfKos=
-github.com/containers/image/v5 v5.8.0 h1:B3FGHi0bdGXgg698kBIGOlHCXN5n+scJr6/5354GOPU=
-github.com/containers/image/v5 v5.8.0/go.mod h1:jKxdRtyIDumVa56hdsZvV+gwx4zB50hRou6pIuCWLkg=
+github.com/containers/common v0.29.0 h1:hTMC+urdkk5bKfhL/OgCixIX5xjJgQ2l2jPG745ECFQ=
+github.com/containers/common v0.29.0/go.mod h1:yT4GTUHsKRmpaDb+mecXRnIMre7W3ZgwXqaYMywXlaA=
+github.com/containers/image/v5 v5.8.1 h1:aHW8a/Kd0dTJ7PTL/fc6y12sJqHxWgqilu+XyHfjD8Q=
+github.com/containers/image/v5 v5.8.1/go.mod h1:blOEFd/iFdeyh891ByhCVUc+xAcaI3gBegXECwz9UbQ=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.0.3 h1:vYgl+RZ9Q3DPMuTfxmN+qp0X2Bj52uuY2vnt6GzVe1c=
github.com/containers/ocicrypt v1.0.3/go.mod h1:CUBa+8MRNL/VkpxYIpaMtgn1WgXGyvPQj8jcy0EVG6g=
-github.com/containers/storage v1.23.6/go.mod h1:haFs0HRowKwyzvWEx9EgI3WsL8XCSnBDb5f8P5CAxJY=
github.com/containers/storage v1.23.7/go.mod h1:cUT2zHjtx+WlVri30obWmM2gpqpi8jfPsmIzP1TVpEI=
-github.com/containers/storage v1.24.0 h1:Fo2LkF7tkMLmo38sTZ/G8wHjcn8JfUFPfyTxM4WwMfk=
-github.com/containers/storage v1.24.0/go.mod h1:A4d3BzuZK9b3oLVEsiSRhZLPIx3z7utgiPyXLK/YMhY=
+github.com/containers/storage v1.24.1 h1:1+f8fy6ly35c8SLet5jzZ8t0WJJs5+xSpfMAYw0R3kc=
+github.com/containers/storage v1.24.1/go.mod h1:0xJL06Dmd+ZYXIUdnBUPN0JnhHGgwMkLvnnAonJfWJU=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@@ -232,8 +229,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.11.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ=
-github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.3 h1:dB4Bn0tN3wdCzQxnS8r06kV74qN/TAfaIS0bVE8h3jc=
+github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
@@ -278,7 +275,6 @@ github.com/moby/sys/mount v0.1.1 h1:mdhBytJ1SMmMat0gtzWWjFX/87K5j6E/7Q5z7rR0cZY=
github.com/moby/sys/mount v0.1.1/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74=
github.com/moby/sys/mountinfo v0.1.0/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o=
github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o=
-github.com/moby/sys/mountinfo v0.3.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/mountinfo v0.4.0 h1:1KInV3Huv18akCu58V7lzNlt+jFmqlu1EaErnEHE/VM=
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/term v0.0.0-20200429084858-129dac9f73f6/go.mod h1:or9wGItza1sRcM4Wd3dIv8DsFHYQuFsMHEdxUIlUxms=
diff --git a/vendor/github.com/containers/buildah/image.go b/vendor/github.com/containers/buildah/image.go
index 154bc503f..7c55020ab 100644
--- a/vendor/github.com/containers/buildah/image.go
+++ b/vendor/github.com/containers/buildah/image.go
@@ -321,10 +321,7 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System
}
// If we're not re-exporting the data, and we're reusing layers individually, reuse
// the blobsum and diff IDs.
- if !i.exporting && !i.squash && layerID != i.layerID {
- if layer.UncompressedDigest == "" {
- return nil, errors.Errorf("unable to look up size of layer %q", layerID)
- }
+ if !i.exporting && !i.squash && layerID != i.layerID && layer.UncompressedDigest != "" {
layerBlobSum := layer.UncompressedDigest
layerBlobSize := layer.UncompressedSize
diffID := layer.UncompressedDigest
diff --git a/vendor/github.com/containers/buildah/imagebuildah/build.go b/vendor/github.com/containers/buildah/imagebuildah/build.go
index a97a403b3..1ec21e786 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/build.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/build.go
@@ -185,6 +185,8 @@ type BuildOptions struct {
Jobs *int
// LogRusage logs resource usage for each step.
LogRusage bool
+ // Excludes is a list of excludes to be used instead of the .dockerignore file.
+ Excludes []string
}
// BuildDockerfiles parses a set of one or more Dockerfiles (which may be
diff --git a/vendor/github.com/containers/buildah/imagebuildah/executor.go b/vendor/github.com/containers/buildah/imagebuildah/executor.go
index 8c96b4e67..3c41ec1d2 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/executor.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/executor.go
@@ -130,9 +130,12 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod
return nil, errors.Wrapf(err, "failed to get container config")
}
- excludes, err := imagebuilder.ParseDockerignore(options.ContextDirectory)
- if err != nil {
- return nil, err
+ excludes := options.Excludes
+ if len(excludes) == 0 {
+ excludes, err = imagebuilder.ParseDockerignore(options.ContextDirectory)
+ if err != nil {
+ return nil, err
+ }
}
capabilities, err := defaultContainerConfig.Capabilities("", options.AddCapabilities, options.DropCapabilities)
if err != nil {
diff --git a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
index 6c058e226..191645b89 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
@@ -368,6 +368,7 @@ func (s *StageExecutor) Run(run imagebuilder.Run, config docker.Config) error {
Stderr: s.executor.err,
Quiet: s.executor.quiet,
NamespaceOptions: s.executor.namespaceOptions,
+ Terminal: buildah.WithoutTerminal,
}
if config.NetworkDisabled {
options.ConfigureNetwork = buildah.NetworkDisabled
@@ -1144,7 +1145,11 @@ func (s *StageExecutor) intermediateImageExists(ctx context.Context, currNode *p
// lines in the Dockerfile up till the point we are at in the build.
manifestType, history, diffIDs, err := s.executor.getImageTypeAndHistoryAndDiffIDs(ctx, image.ID)
if err != nil {
- return "", errors.Wrapf(err, "error getting history of %q", image.ID)
+ // It's possible that this image is for another architecture, which results
+ // in a custom-crafted error message that we'd have to use substring matching
+ // to recognize. Instead, ignore the image.
+ logrus.Debugf("error getting history of %q (%v), ignoring it", image.ID, err)
+ continue
}
// If this candidate isn't of the type that we're building, then it may have lost
// some format-specific information that a building-without-cache run wouldn't lose.
diff --git a/vendor/github.com/containers/buildah/install.md b/vendor/github.com/containers/buildah/install.md
index 00381e16a..119315d1f 100644
--- a/vendor/github.com/containers/buildah/install.md
+++ b/vendor/github.com/containers/buildah/install.md
@@ -59,35 +59,31 @@ sudo dnf -y install buildah
#### [Debian](https://debian.org)
-The buildah package is [being worked on](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=928083)
-for inclusion in the default Debian repos.
-
-Alternatively, the [Kubic project](https://build.opensuse.org/project/show/devel:kubic:libcontainers:stable)
-provides packages for Debian 10, testing and unstable.
+The buildah package is available in
+the [Bullseye (testing) branch](https://packages.debian.org/bullseye/buildah), which
+will be the next stable release (Debian 11) as well as Debian Unstable/Sid.
```bash
-# Debian Unstable/Sid
-echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Unstable/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
-wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_Unstable/Release.key -O Release.key
+# Debian Testing/Bullseye or Unstable/Sid
+sudo apt-get update
+sudo apt-get -y install buildah
+```
-# Debian Testing
-echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Testing/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
-wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_Testing/Release.key -O Release.key
+The [Kubic project](https://build.opensuse.org/project/show/devel:kubic:libcontainers:stable)
+provides packages for Debian 10. The Kubic packages for Debian Testing/Bullseye and Debian Unstable/Sid
+have been discontinued to avoid
+[conflicts](https://github.com/containers/buildah/issues/2797) with the official packages.
-# Debian 10
-echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
-wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_10/Release.key -O Release.key
+Caution: If you upgrade from Debian 10 to Testing/Bullseye or
+Unstable/Sid you would likely end up downgrading Buildah because the version in
+OBS is more frequently updated than the one in Debian's official repositories,
+due to how Debian works.
-sudo apt-key add - < Release.key
-sudo apt-get update -qq
-sudo apt-get -qq -y install buildah
-```
-
-### [Fedora](https://www.fedoraproject.org), [CentOS](https://www.centos.org)
+### [Fedora](https://www.fedoraproject.org)
```bash
-sudo yum -y install buildah
+sudo dnf -y install buildah
```
### [Fedora SilverBlue](https://silverblue.fedoraproject.org)
@@ -127,19 +123,25 @@ sudo subscription-manager repos --enable=rhel-7-server-extras-rpms
sudo yum -y install buildah
```
-#### [Raspbian](https://raspbian.org)
+#### [Raspberry Pi OS armhf (ex Raspbian)](https://www.raspberrypi.org/downloads/raspberry-pi-os/)
The Kubic project provides packages for Raspbian 10.
```bash
# Raspbian 10
-echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Raspbian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
-wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Raspbian_10/Release.key -O Release.key
-sudo apt-key add - < Release.key
+echo 'deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Raspbian_10/ /' | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
+curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Raspbian_10/Release.key | sudo apt-key add -
sudo apt-get update -qq
sudo apt-get -qq -y install buildah
```
+#### [Raspberry Pi OS arm64 (beta)](https://downloads.raspberrypi.org/raspios_arm64/images/)
+
+Raspberry Pi OS use the standard Debian's repositories,
+so it is fully compatible with Debian's arm64 repository.
+You can simply follow the [steps for Debian](#debian) to install podman.
+
+
### [RHEL8 Beta](https://www.redhat.com/en/blog/powering-its-future-while-preserving-present-introducing-red-hat-enterprise-linux-8-beta?intcmp=701f2000001Cz6OAAS)
```bash
@@ -149,7 +151,16 @@ sudo yum module install -y buildah
### [Ubuntu](https://www.ubuntu.com)
-The Kubic project provides packages for Ubuntu 18.04, 19.04 and 19.10 (it should also work with direct derivatives like Pop!\_OS).
+The buildah package is available in the official repositories for Ubuntu 20.10
+and newer.
+
+```bash
+# Ubuntu 20.10 and newer
+sudo apt-get -y update
+sudo apt-get -y install buildah
+```
+
+The [Kubic project](https://build.opensuse.org/package/show/devel:kubic:libcontainers:stable/buildah) provides packages for some older but supported Ubuntu versions (it should also work with direct derivatives like Pop!\_OS).
```bash
. /etc/os-release
diff --git a/vendor/github.com/containers/buildah/pkg/cli/common.go b/vendor/github.com/containers/buildah/pkg/cli/common.go
index 62a328de0..123548d97 100644
--- a/vendor/github.com/containers/buildah/pkg/cli/common.go
+++ b/vendor/github.com/containers/buildah/pkg/cli/common.go
@@ -59,6 +59,7 @@ type BudResults struct {
Creds string
DisableCompression bool
DisableContentTrust bool
+ IgnoreFile string
File []string
Format string
Iidfile string
@@ -185,6 +186,7 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
fs.StringVar(&flags.Creds, "creds", "", "use `[username[:password]]` for accessing the registry")
fs.BoolVarP(&flags.DisableCompression, "disable-compression", "D", true, "don't compress layers by default")
fs.BoolVar(&flags.DisableContentTrust, "disable-content-trust", false, "This is a Docker specific option and is a NOOP")
+ fs.StringVar(&flags.IgnoreFile, "ignorefile", "", "path to an alternate .dockerignore file")
fs.StringSliceVarP(&flags.File, "file", "f", []string{}, "`pathname or URL` of a Dockerfile")
fs.StringVar(&flags.Format, "format", DefaultFormat(), "`format` of the built image's manifest and metadata. Use BUILDAH_FORMAT environment variable to override.")
fs.StringVar(&flags.Iidfile, "iidfile", "", "`file` to write the image ID to")
@@ -231,6 +233,7 @@ func GetBudFlagsCompletions() commonComp.FlagCompletions {
flagCompletion["creds"] = commonComp.AutocompleteNone
flagCompletion["file"] = commonComp.AutocompleteDefault
flagCompletion["format"] = commonComp.AutocompleteNone
+ flagCompletion["ignorefile"] = commonComp.AutocompleteDefault
flagCompletion["iidfile"] = commonComp.AutocompleteDefault
flagCompletion["jobs"] = commonComp.AutocompleteNone
flagCompletion["label"] = commonComp.AutocompleteNone
diff --git a/vendor/github.com/containers/buildah/pkg/umask/umask_unsupported.go b/vendor/github.com/containers/buildah/pkg/umask/umask_unsupported.go
deleted file mode 100644
index 20913a718..000000000
--- a/vendor/github.com/containers/buildah/pkg/umask/umask_unsupported.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// +build !linux,!darwin
-
-package umask
-
-func CheckUmask() {}
-
-func SetUmask(int) int { return 0 }
diff --git a/vendor/github.com/containers/buildah/run_linux.go b/vendor/github.com/containers/buildah/run_linux.go
index d907941ed..d20d39423 100644
--- a/vendor/github.com/containers/buildah/run_linux.go
+++ b/vendor/github.com/containers/buildah/run_linux.go
@@ -25,10 +25,10 @@ import (
"github.com/containers/buildah/chroot"
"github.com/containers/buildah/copier"
"github.com/containers/buildah/pkg/overlay"
- "github.com/containers/buildah/pkg/secrets"
"github.com/containers/buildah/util"
"github.com/containers/common/pkg/capabilities"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/subscriptions"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/ioutils"
"github.com/containers/storage/pkg/reexec"
@@ -216,16 +216,28 @@ func (b *Builder) Run(command []string, options RunOptions) error {
}
// Empty file, so no need to recreate if it exists
if _, ok := bindFiles["/run/.containerenv"]; !ok {
- // Empty string for now, but we may consider populating this later
containerenvPath := filepath.Join(path, "/run/.containerenv")
if err = os.MkdirAll(filepath.Dir(containerenvPath), 0755); err != nil {
return err
}
- emptyFile, err := os.Create(containerenvPath)
- if err != nil {
+
+ rootless := 0
+ if unshare.IsRootless() {
+ rootless = 1
+ }
+ // Populate the .containerenv with container information
+ containerenv := fmt.Sprintf(`\
+engine="buildah-%s"
+name=%q
+id=%q
+image=%q
+imageid=%q
+rootless=%d
+`, Version, b.Container, b.ContainerID, b.FromImage, b.FromImageID, rootless)
+
+ if err = ioutils.AtomicWriteFile(containerenvPath, []byte(containerenv), 0755); err != nil {
return err
}
- emptyFile.Close()
if err := label.Relabel(containerenvPath, b.MountLabel, false); err != nil {
return err
}
@@ -477,15 +489,15 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st
return errors.Wrapf(err, "error determining work directory for container %q", b.ContainerID)
}
- // Figure out which UID and GID to tell the secrets package to use
+ // Figure out which UID and GID to tell the subscritions package to use
// for files that it creates.
rootUID, rootGID, err := util.GetHostRootIDs(spec)
if err != nil {
return err
}
- // Get the list of secrets mounts.
- secretMounts := secrets.SecretMountsWithUIDGID(b.MountLabel, cdir, b.DefaultMountsFilePath, mountPoint, int(rootUID), int(rootGID), unshare.IsRootless(), false)
+ // Get the list of subscriptionss mounts.
+ secretMounts := subscriptions.MountsWithUIDGID(b.MountLabel, cdir, b.DefaultMountsFilePath, mountPoint, int(rootUID), int(rootGID), unshare.IsRootless(), false)
// Add temporary copies of the contents of volume locations at the
// volume locations, unless we already have something there.
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index c6a9a660e..2769781f2 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -113,6 +113,10 @@ type ContainersConfig struct {
// DNSSearches set default DNS search domains.
DNSSearches []string `toml:"dns_searches,omitempty"`
+ // EnableKeyring tells the container engines whether to create
+ // a kernel keyring for use within the container
+ EnableKeyring bool `toml:"keyring,omitempty"`
+
// EnableLabeling tells the container engines whether to use MAC
// Labeling to separate containers (SELinux)
EnableLabeling bool `toml:"label,omitempty"`
diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf
index e8519b251..ed7c91931 100644
--- a/vendor/github.com/containers/common/pkg/config/containers.conf
+++ b/vendor/github.com/containers/common/pkg/config/containers.conf
@@ -146,9 +146,13 @@ default_sysctls = [
#
# ipcns = "private"
-# Flag tells container engine to whether to use container separation using
-# MAC(SELinux)labeling or not.
-# Flag is ignored on label disabled systems.
+# keyring tells the container engine whether to create
+# a kernel keyring for use within the container.
+# keyring = true
+
+# label tells the container engine whether to use container separation using
+# MAC(SELinux) labeling or not.
+# The label flag is ignored on label disabled systems.
#
# label = true
diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go
index 5f8f4999f..4f1460e3b 100644
--- a/vendor/github.com/containers/common/pkg/config/default.go
+++ b/vendor/github.com/containers/common/pkg/config/default.go
@@ -46,8 +46,6 @@ var (
DefaultInitPath = "/usr/libexec/podman/catatonit"
// DefaultInfraImage to use for infra container
DefaultInfraImage = "k8s.gcr.io/pause:3.2"
- // DefaultInfraCommand to be run in an infra container
- DefaultInfraCommand = "/pause"
// DefaultRootlessSHMLockPath is the default path for rootless SHM locks
DefaultRootlessSHMLockPath = "/libpod_rootless_lock"
// DefaultDetachKeys is the default keys sequence for detaching a
@@ -179,6 +177,7 @@ func DefaultConfig() (*Config, error) {
DNSServers: []string{},
DNSOptions: []string{},
DNSSearches: []string{},
+ EnableKeyring: true,
EnableLabeling: selinuxEnabled(),
Env: []string{
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
@@ -308,7 +307,6 @@ func defaultConfigFromMemory() (*EngineConfig, error) {
c.InitPath = DefaultInitPath
c.NoPivotRoot = false
- c.InfraCommand = DefaultInfraCommand
c.InfraImage = DefaultInfraImage
c.EnablePortReservation = true
c.NumLocks = 2048
diff --git a/vendor/github.com/containers/common/pkg/retry/retry.go b/vendor/github.com/containers/common/pkg/retry/retry.go
index d0ac19fb6..f6ecab0c0 100644
--- a/vendor/github.com/containers/common/pkg/retry/retry.go
+++ b/vendor/github.com/containers/common/pkg/retry/retry.go
@@ -30,7 +30,7 @@ func RetryIfNecessary(ctx context.Context, operation func() error, retryOptions
if retryOptions.Delay != 0 {
delay = retryOptions.Delay
}
- logrus.Infof("Warning: failed, retrying in %s ... (%d/%d)", delay, attempt+1, retryOptions.MaxRetry)
+ logrus.Infof("Warning: failed, retrying in %s ... (%d/%d). Error: %v", delay, attempt+1, retryOptions.MaxRetry, err)
select {
case <-time.After(delay):
break
diff --git a/vendor/github.com/containers/common/pkg/seccomp/default_linux.go b/vendor/github.com/containers/common/pkg/seccomp/default_linux.go
index ddc25ac67..09629724d 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/default_linux.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/default_linux.go
@@ -174,6 +174,7 @@ func DefaultProfile() *Seccomp {
"ioprio_get",
"ioprio_set",
"ipc",
+ "keyctl",
"kill",
"lchown",
"lchown32",
@@ -327,6 +328,7 @@ func DefaultProfile() *Seccomp {
"signalfd",
"signalfd4",
"sigreturn",
+ "socket",
"socketcall",
"socketpair",
"splice",
diff --git a/vendor/github.com/containers/common/pkg/seccomp/supported.go b/vendor/github.com/containers/common/pkg/seccomp/supported.go
index ab2a94a73..1177ef630 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/supported.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/supported.go
@@ -1,3 +1,5 @@
+// +build !windows
+
package seccomp
import (
diff --git a/vendor/github.com/containers/common/pkg/subscriptions/mounts.conf b/vendor/github.com/containers/common/pkg/subscriptions/mounts.conf
new file mode 100644
index 000000000..b7cde9d8a
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/subscriptions/mounts.conf
@@ -0,0 +1 @@
+/usr/share/rhel/secrets:/run/secrets
diff --git a/vendor/github.com/containers/buildah/pkg/secrets/secrets.go b/vendor/github.com/containers/common/pkg/subscriptions/subscriptions.go
index 32f888fa8..6aa66b0c8 100644
--- a/vendor/github.com/containers/buildah/pkg/secrets/secrets.go
+++ b/vendor/github.com/containers/common/pkg/subscriptions/subscriptions.go
@@ -1,4 +1,4 @@
-package secrets
+package subscriptions
import (
"bufio"
@@ -7,7 +7,7 @@ import (
"path/filepath"
"strings"
- "github.com/containers/buildah/pkg/umask"
+ "github.com/containers/common/pkg/umask"
"github.com/containers/storage/pkg/idtools"
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label"
@@ -27,16 +27,16 @@ var (
UserOverrideMountsFile = filepath.Join(os.Getenv("HOME"), ".config/containers/mounts.conf")
)
-// secretData stores the name of the file and the content read from it
-type secretData struct {
+// subscriptionData stores the name of the file and the content read from it
+type subscriptionData struct {
name string
data []byte
mode os.FileMode
dirMode os.FileMode
}
-// saveTo saves secret data to given directory
-func (s secretData) saveTo(dir string) error {
+// saveTo saves subscription data to given directory
+func (s subscriptionData) saveTo(dir string) error {
path := filepath.Join(dir, s.name)
if err := os.MkdirAll(filepath.Dir(path), s.dirMode); err != nil {
return err
@@ -44,10 +44,10 @@ func (s secretData) saveTo(dir string) error {
return ioutil.WriteFile(path, s.data, s.mode)
}
-func readAll(root, prefix string, parentMode os.FileMode) ([]secretData, error) {
+func readAll(root, prefix string, parentMode os.FileMode) ([]subscriptionData, error) {
path := filepath.Join(root, prefix)
- data := []secretData{}
+ data := []subscriptionData{}
files, err := ioutil.ReadDir(path)
if err != nil {
@@ -74,7 +74,7 @@ func readAll(root, prefix string, parentMode os.FileMode) ([]secretData, error)
return data, nil
}
-func readFileOrDir(root, name string, parentMode os.FileMode) ([]secretData, error) {
+func readFileOrDir(root, name string, parentMode os.FileMode) ([]subscriptionData, error) {
path := filepath.Join(root, name)
s, err := os.Stat(path)
@@ -93,7 +93,7 @@ func readFileOrDir(root, name string, parentMode os.FileMode) ([]secretData, err
if err != nil {
return nil, err
}
- return []secretData{{
+ return []subscriptionData{{
name: name,
data: bytes,
mode: s.Mode(),
@@ -101,13 +101,13 @@ func readFileOrDir(root, name string, parentMode os.FileMode) ([]secretData, err
}}, nil
}
-func getHostSecretData(hostDir string, mode os.FileMode) ([]secretData, error) {
- var allSecrets []secretData
- hostSecrets, err := readAll(hostDir, "", mode)
+func getHostSubscriptionData(hostDir string, mode os.FileMode) ([]subscriptionData, error) {
+ var allSubscriptions []subscriptionData
+ hostSubscriptions, err := readAll(hostDir, "", mode)
if err != nil {
- return nil, errors.Wrapf(err, "failed to read secrets from %q", hostDir)
+ return nil, errors.Wrapf(err, "failed to read subscriptions from %q", hostDir)
}
- return append(allSecrets, hostSecrets...), nil
+ return append(allSubscriptions, hostSubscriptions...), nil
}
func getMounts(filePath string) []string {
@@ -136,7 +136,7 @@ func getMounts(filePath string) []string {
}
// getHostAndCtrDir separates the host:container paths
-func getMountsMap(path string) (string, string, error) {
+func getMountsMap(path string) (string, string, error) { //nolint
arr := strings.SplitN(path, ":", 2)
switch len(arr) {
case 1:
@@ -147,27 +147,21 @@ func getMountsMap(path string) (string, string, error) {
return "", "", errors.Errorf("unable to get host and container dir from path: %s", path)
}
-// SecretMounts copies, adds, and mounts the secrets to the container root filesystem
-// Deprecated, Please use SecretMountWithUIDGID
-func SecretMounts(mountLabel, containerWorkingDir, mountFile string, rootless, disableFips bool) []rspec.Mount {
- return SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, containerWorkingDir, 0, 0, rootless, disableFips)
-}
-
-// SecretMountsWithUIDGID copies, adds, and mounts the secrets to the container root filesystem
+// MountsWithUIDGID copies, adds, and mounts the subscriptions to the container root filesystem
// mountLabel: MAC/SELinux label for container content
-// containerWorkingDir: Private data for storing secrets on the host mounted in container.
+// containerWorkingDir: Private data for storing subscriptions on the host mounted in container.
// mountFile: Additional mount points required for the container.
// mountPoint: Container image mountpoint
-// uid: to assign to content created for secrets
-// gid: to assign to content created for secrets
+// uid: to assign to content created for subscriptions
+// gid: to assign to content created for subscriptions
// rootless: indicates whether container is running in rootless mode
// disableFips: indicates whether system should ignore fips mode
-func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPoint string, uid, gid int, rootless, disableFips bool) []rspec.Mount {
+func MountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPoint string, uid, gid int, rootless, disableFips bool) []rspec.Mount {
var (
- secretMounts []rspec.Mount
- mountFiles []string
+ subscriptionMounts []rspec.Mount
+ mountFiles []string
)
- // Add secrets from paths given in the mounts.conf files
+ // Add subscriptions from paths given in the mounts.conf files
// mountFile will have a value if the hidden --default-mounts-file flag is set
// Note for testing purposes only
if mountFile == "" {
@@ -180,31 +174,32 @@ func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPoi
}
for _, file := range mountFiles {
if _, err := os.Stat(file); err == nil {
- mounts, err := addSecretsFromMountsFile(file, mountLabel, containerWorkingDir, uid, gid)
+ mounts, err := addSubscriptionsFromMountsFile(file, mountLabel, containerWorkingDir, uid, gid)
if err != nil {
- logrus.Warnf("error mounting secrets, skipping entry in %s: %v", file, err)
+ logrus.Warnf("error mounting subscriptions, skipping entry in %s: %v", file, err)
}
- secretMounts = mounts
+ subscriptionMounts = mounts
break
}
}
- // Only add FIPS secret mount if disableFips=false
+ // Only add FIPS subscription mount if disableFips=false
if disableFips {
- return secretMounts
+ return subscriptionMounts
}
- // Add FIPS mode secret if /etc/system-fips exists on the host
+ // Add FIPS mode subscription if /etc/system-fips exists on the host
_, err := os.Stat("/etc/system-fips")
- if err == nil {
- if err := addFIPSModeSecret(&secretMounts, containerWorkingDir, mountPoint, mountLabel, uid, gid); err != nil {
- logrus.Errorf("error adding FIPS mode secret to container: %v", err)
+ switch {
+ case err == nil:
+ if err := addFIPSModeSubscription(&subscriptionMounts, containerWorkingDir, mountPoint, mountLabel, uid, gid); err != nil {
+ logrus.Errorf("error adding FIPS mode subscription to container: %v", err)
}
- } else if os.IsNotExist(err) {
- logrus.Debug("/etc/system-fips does not exist on host, not mounting FIPS mode secret")
- } else {
- logrus.Errorf("stat /etc/system-fips failed for FIPS mode secret: %v", err)
+ case os.IsNotExist(err):
+ logrus.Debug("/etc/system-fips does not exist on host, not mounting FIPS mode subscription")
+ default:
+ logrus.Errorf("stat /etc/system-fips failed for FIPS mode subscription: %v", err)
}
- return secretMounts
+ return subscriptionMounts
}
func rchown(chowndir string, uid, gid int) error {
@@ -213,9 +208,9 @@ func rchown(chowndir string, uid, gid int) error {
})
}
-// addSecretsFromMountsFile copies the contents of host directory to container directory
+// addSubscriptionsFromMountsFile copies the contents of host directory to container directory
// and returns a list of mounts
-func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir string, uid, gid int) ([]rspec.Mount, error) {
+func addSubscriptionsFromMountsFile(filePath, mountLabel, containerWorkingDir string, uid, gid int) ([]rspec.Mount, error) {
var mounts []rspec.Mount
defaultMountsPaths := getMounts(filePath)
for _, path := range defaultMountsPaths {
@@ -235,7 +230,7 @@ func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir string,
ctrDirOrFileOnHost := filepath.Join(containerWorkingDir, ctrDirOrFile)
- // In the event of a restart, don't want to copy secrets over again as they already would exist in ctrDirOrFileOnHost
+ // In the event of a restart, don't want to copy subscriptions over again as they already would exist in ctrDirOrFileOnHost
_, err = os.Stat(ctrDirOrFileOnHost)
if os.IsNotExist(err) {
@@ -245,17 +240,17 @@ func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir string,
}
// Don't let the umask have any influence on the file and directory creation
- oldUmask := umask.SetUmask(0)
- defer umask.SetUmask(oldUmask)
+ oldUmask := umask.Set(0)
+ defer umask.Set(oldUmask)
switch mode := fileInfo.Mode(); {
case mode.IsDir():
if err = os.MkdirAll(ctrDirOrFileOnHost, mode.Perm()); err != nil {
return nil, errors.Wrapf(err, "making container directory %q failed", ctrDirOrFileOnHost)
}
- data, err := getHostSecretData(hostDirOrFile, mode.Perm())
+ data, err := getHostSubscriptionData(hostDirOrFile, mode.Perm())
if err != nil {
- return nil, errors.Wrapf(err, "getting host secret data failed")
+ return nil, errors.Wrapf(err, "getting host subscription data failed")
}
for _, s := range data {
if err := s.saveTo(ctrDirOrFileOnHost); err != nil {
@@ -305,15 +300,15 @@ func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir string,
return mounts, nil
}
-// addFIPSModeSecret creates /run/secrets/system-fips in the container
+// addFIPSModeSubscription creates /run/secrets/system-fips in the container
// root filesystem if /etc/system-fips exists on hosts.
// This enables the container to be FIPS compliant and run openssl in
// FIPS mode as the host is also in FIPS mode.
-func addFIPSModeSecret(mounts *[]rspec.Mount, containerWorkingDir, mountPoint, mountLabel string, uid, gid int) error {
- secretsDir := "/run/secrets"
- ctrDirOnHost := filepath.Join(containerWorkingDir, secretsDir)
+func addFIPSModeSubscription(mounts *[]rspec.Mount, containerWorkingDir, mountPoint, mountLabel string, uid, gid int) error {
+ subscriptionsDir := "/run/secrets"
+ ctrDirOnHost := filepath.Join(containerWorkingDir, subscriptionsDir)
if _, err := os.Stat(ctrDirOnHost); os.IsNotExist(err) {
- if err = idtools.MkdirAllAs(ctrDirOnHost, 0755, uid, gid); err != nil {
+ if err = idtools.MkdirAllAs(ctrDirOnHost, 0755, uid, gid); err != nil { //nolint
return errors.Wrapf(err, "making container directory %q on host failed", ctrDirOnHost)
}
if err = label.Relabel(ctrDirOnHost, mountLabel, false); err != nil {
@@ -330,10 +325,10 @@ func addFIPSModeSecret(mounts *[]rspec.Mount, containerWorkingDir, mountPoint, m
defer file.Close()
}
- if !mountExists(*mounts, secretsDir) {
+ if !mountExists(*mounts, subscriptionsDir) {
m := rspec.Mount{
Source: ctrDirOnHost,
- Destination: secretsDir,
+ Destination: subscriptionsDir,
Type: "bind",
Options: []string{"bind", "rprivate"},
}
diff --git a/vendor/github.com/containers/buildah/pkg/umask/umask_unix.go b/vendor/github.com/containers/common/pkg/umask/umask_unix.go
index 02e10945b..bb589f7ac 100644
--- a/vendor/github.com/containers/buildah/pkg/umask/umask_unix.go
+++ b/vendor/github.com/containers/common/pkg/umask/umask_unix.go
@@ -8,13 +8,13 @@ import (
"github.com/sirupsen/logrus"
)
-func CheckUmask() {
- oldUmask := syscall.Umask(0022)
+func Check() {
+ oldUmask := syscall.Umask(0022) //nolint
if (oldUmask & ^0022) != 0 {
logrus.Debugf("umask value too restrictive. Forcing it to 022")
}
}
-func SetUmask(value int) int {
+func Set(value int) int {
return syscall.Umask(value)
}
diff --git a/vendor/github.com/containers/common/pkg/umask/umask_unsupported.go b/vendor/github.com/containers/common/pkg/umask/umask_unsupported.go
new file mode 100644
index 000000000..9041d5f20
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/umask/umask_unsupported.go
@@ -0,0 +1,7 @@
+// +build !linux,!darwin
+
+package umask
+
+func Check() {}
+
+func Set(int) int { return 0 }
diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go
index ef7c612e2..72f4e00f7 100644
--- a/vendor/github.com/containers/common/version/version.go
+++ b/vendor/github.com/containers/common/version/version.go
@@ -1,4 +1,4 @@
package version
// Version is the version of the build.
-const Version = "0.27.0"
+const Version = "0.29.0"
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 965713ed1..a60ea9db3 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -67,7 +67,7 @@ github.com/containernetworking/plugins/pkg/utils/hwaddr
github.com/containernetworking/plugins/pkg/utils/sysctl
github.com/containernetworking/plugins/plugins/ipam/host-local/backend
github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator
-# github.com/containers/buildah v1.18.0
+# github.com/containers/buildah v1.18.1-0.20201125084616-dd26b137459c
github.com/containers/buildah
github.com/containers/buildah/bind
github.com/containers/buildah/chroot
@@ -84,11 +84,9 @@ github.com/containers/buildah/pkg/manifests
github.com/containers/buildah/pkg/overlay
github.com/containers/buildah/pkg/parse
github.com/containers/buildah/pkg/rusage
-github.com/containers/buildah/pkg/secrets
github.com/containers/buildah/pkg/supplemented
-github.com/containers/buildah/pkg/umask
github.com/containers/buildah/util
-# github.com/containers/common v0.27.0
+# github.com/containers/common v0.29.0
github.com/containers/common/pkg/apparmor
github.com/containers/common/pkg/apparmor/internal/supported
github.com/containers/common/pkg/auth
@@ -100,7 +98,9 @@ github.com/containers/common/pkg/report
github.com/containers/common/pkg/report/camelcase
github.com/containers/common/pkg/retry
github.com/containers/common/pkg/seccomp
+github.com/containers/common/pkg/subscriptions
github.com/containers/common/pkg/sysinfo
+github.com/containers/common/pkg/umask
github.com/containers/common/version
# github.com/containers/conmon v2.0.20+incompatible
github.com/containers/conmon/runner/config
diff --git a/version/version.go b/version/version.go
index a62648eea..0bba0147b 100644
--- a/version/version.go
+++ b/version/version.go
@@ -8,9 +8,9 @@ import (
// NOTE: remember to bump the version at the top
// of the top-level README.md file when this is
// bumped.
-var Version = semver.MustParse("2.2.0-dev")
+var Version = semver.MustParse("3.0.0-dev")
// APIVersion is the version for the remote
// client API. It is used to determine compatibility
// between a remote podman client and its backend
-var APIVersion = semver.MustParse("2.1.0")
+var APIVersion = semver.MustParse("3.0.0")