diff options
32 files changed, 641 insertions, 328 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/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go index 898d65bd0..cae52ccaa 100644 --- a/cmd/podman/common/netflags.go +++ b/cmd/podman/common/netflags.go @@ -59,8 +59,8 @@ func DefineNetFlags(cmd *cobra.Command) { _ = cmd.RegisterFlagCompletionFunc(macAddressFlagName, completion.AutocompleteNone) networkFlagName := "network" - netFlags.StringArray( - networkFlagName, []string{containerConfig.NetNS()}, + netFlags.String( + networkFlagName, containerConfig.NetNS(), "Connect a container to a network", ) _ = cmd.RegisterFlagCompletionFunc(networkFlagName, AutocompleteNetworks) @@ -194,29 +194,25 @@ func NetFlagsToNetOptions(cmd *cobra.Command) (*entities.NetOptions, error) { } if cmd.Flags().Changed("network") { - networks, err := cmd.Flags().GetStringArray("network") + network, err := cmd.Flags().GetString("network") if err != nil { return nil, err } - for i, network := range networks { - parts := strings.SplitN(network, ":", 2) - ns, cniNets, err := specgen.ParseNetworkNamespace(network) - if err != nil { - return nil, err - } - if i > 0 && (len(cniNets) == 0 || len(opts.CNINetworks) == 0) { - return nil, errors.Errorf("network conflict between type %s and %s", opts.Network.NSMode, ns.NSMode) - } + parts := strings.SplitN(network, ":", 2) - if len(parts) > 1 { - opts.NetworkOptions = make(map[string][]string) - opts.NetworkOptions[parts[0]] = strings.Split(parts[1], ",") - cniNets = nil - } - opts.Network = ns - opts.CNINetworks = append(opts.CNINetworks, cniNets...) + ns, cniNets, err := specgen.ParseNetworkNamespace(network) + if err != nil { + return nil, err + } + + if len(parts) > 1 { + opts.NetworkOptions = make(map[string][]string) + opts.NetworkOptions[parts[0]] = strings.Split(parts[1], ",") + cniNets = nil } + opts.Network = ns + opts.CNINetworks = cniNets } aliases, err := cmd.Flags().GetStringSlice("network-alias") 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/pods/create.go b/cmd/podman/pods/create.go index 5b0aa2fe4..d997ea344 100644 --- a/cmd/podman/pods/create.go +++ b/cmd/podman/pods/create.go @@ -171,7 +171,33 @@ func create(cmd *cobra.Command, args []string) error { if err != nil { return err } - + createOptions.Net.Network = specgen.Namespace{} + if cmd.Flag("network").Changed { + netInput, err := cmd.Flags().GetString("network") + if err != nil { + return err + } + parts := strings.SplitN(netInput, ":", 2) + + n := specgen.Namespace{} + switch { + case netInput == "bridge": + n.NSMode = specgen.Bridge + case netInput == "host": + n.NSMode = specgen.Host + case netInput == "slirp4netns", strings.HasPrefix(netInput, "slirp4netns:"): + n.NSMode = specgen.Slirp + if len(parts) > 1 { + createOptions.Net.NetworkOptions = make(map[string][]string) + createOptions.Net.NetworkOptions[parts[0]] = strings.Split(parts[1], ",") + } + default: + // Container and NS mode are presently unsupported + n.NSMode = specgen.Bridge + createOptions.Net.CNINetworks = strings.Split(netInput, ",") + } + createOptions.Net.Network = n + } if len(createOptions.Net.PublishPorts) > 0 { if !createOptions.Infra { return errors.Errorf("you must have an infra container to publish port bindings to the host") 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/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/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md index eb73609d4..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. @@ -588,10 +630,10 @@ Valid _mode_ values are: - **none**: no networking; - **container:**_id_: reuse another container's network stack; - **host**: use the Podman host network stack. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure; -- **cni-network**: connect to a user-defined network, multiple networks should be comma-separated or they can be specified with multiple uses of the **--network** option; +- _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-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 184c12acd..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. @@ -614,10 +656,10 @@ Valid _mode_ values are: - **none**: no networking; - **container:**_id_: reuse another container's network stack; - **host**: use the Podman host network stack. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure; -- **cni-network**: connect to a user-defined network, multiple networks should be comma-separated or they can be specified with multiple uses of the **--network** option; +- _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/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/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/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/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/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/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/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 1aa5afbe7..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() 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 11108a5c1..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" @@ -272,10 +278,16 @@ func ParseNetworkNamespace(ns string) (Namespace, []string, error) { toReturn.NSMode = Private case strings.HasPrefix(ns, "ns:"): split := strings.SplitN(ns, ":", 2) + if len(split) != 2 { + return toReturn, nil, errors.Errorf("must provide a path to a namespace when specifying ns:") + } toReturn.NSMode = Path toReturn.Value = split[1] case strings.HasPrefix(ns, "container:"): split := strings.SplitN(ns, ":", 2) + if len(split) != 2 { + return toReturn, nil, errors.Errorf("must provide name or ID or a container when specifying container:") + } toReturn.NSMode = FromContainer toReturn.Value = split[1] default: 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/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/pod_create_test.go b/test/e2e/pod_create_test.go index ccfbcefae..be0a2f6f0 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -9,7 +9,6 @@ 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" ) @@ -477,23 +476,4 @@ entrypoint ["/fromimage"] Expect(status3.ExitCode()).To(Equal(0)) Expect(strings.Contains(status3.OutputToString(), "Degraded")).To(BeTrue()) }) - - It("podman create pod invalid network config", func() { - net1 := "n1" + stringid.GenerateNonCryptoID() - session := podmanTest.Podman([]string{"network", "create", net1}) - session.WaitWithDefaultTimeout() - defer podmanTest.removeCNINetwork(net1) - Expect(session.ExitCode()).To(BeZero()) - - session = podmanTest.Podman([]string{"pod", "create", "--network", "host", "--network", net1}) - session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) - Expect(session.ErrorToString()).To(ContainSubstring("host")) - Expect(session.ErrorToString()).To(ContainSubstring("bridge")) - - session = podmanTest.Podman([]string{"pod", "create", "--network", "container:abc"}) - session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) - Expect(session.ErrorToString()).To(ContainSubstring("pods presently do not support network mode container")) - }) }) diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index 1d416498c..3e80e953e 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -665,33 +665,4 @@ var _ = Describe("Podman run networking", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) }) - - It("podman run with multiple networks", func() { - net1 := "n1" + stringid.GenerateNonCryptoID() - session := podmanTest.Podman([]string{"network", "create", net1}) - session.WaitWithDefaultTimeout() - defer podmanTest.removeCNINetwork(net1) - Expect(session.ExitCode()).To(BeZero()) - - net2 := "n2" + stringid.GenerateNonCryptoID() - session = podmanTest.Podman([]string{"network", "create", net2}) - session.WaitWithDefaultTimeout() - defer podmanTest.removeCNINetwork(net2) - Expect(session.ExitCode()).To(BeZero()) - - run := podmanTest.Podman([]string{"run", "--network", net1, "--network", net2, ALPINE, "ip", "-o", "-4", "addr"}) - run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(BeZero()) - Expect(len(run.OutputToStringArray())).To(Equal(3)) - Expect(run.OutputToString()).To(ContainSubstring("lo")) - Expect(run.OutputToString()).To(ContainSubstring("eth0")) - Expect(run.OutputToString()).To(ContainSubstring("eth1")) - - //invalid config network host and cni should fail - run = podmanTest.Podman([]string{"run", "--network", "host", "--network", net2, ALPINE, "ip", "-o", "-4", "addr"}) - run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(125)) - Expect(run.ErrorToString()).To(ContainSubstring("host")) - Expect(run.ErrorToString()).To(ContainSubstring("bridge")) - }) }) 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/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") |