summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/main_local.go9
-rw-r--r--cmd/podman/shared/volumes_shared.go62
-rw-r--r--cmd/podman/volume_create.go2
-rw-r--r--docs/podman-create.1.md18
-rw-r--r--docs/podman-run.1.md6
-rw-r--r--docs/podman-volume-create.1.md13
-rw-r--r--docs/rtd/Makefile105
-rw-r--r--docs/rtd/source/Commands.rst107
-rw-r--r--docs/rtd/source/Introduction.rst2
-rw-r--r--docs/rtd/source/Reference.rst2
-rw-r--r--docs/rtd/source/Tutorials.rst2
-rw-r--r--docs/rtd/source/conf.py1
-rw-r--r--docs/rtd/source/index.rst6
-rw-r--r--docs/rtd/source/man/generate.rst6
-rw-r--r--docs/rtd/source/man/healthcheck.rst4
-rw-r--r--docs/rtd/source/man/image.rst35
-rw-r--r--docs/rtd/source/man/managecontainers.rst64
-rw-r--r--docs/rtd/source/man/network.rst10
-rw-r--r--docs/rtd/source/man/play.rst4
-rw-r--r--docs/rtd/source/man/pod.rst30
-rw-r--r--docs/rtd/source/man/system.rst12
-rw-r--r--docs/rtd/source/man/volume.rst11
-rw-r--r--libpod/container_internal_linux.go1
-rw-r--r--libpod/options.go16
-rw-r--r--libpod/runtime.go21
-rw-r--r--pkg/adapter/containers.go6
-rw-r--r--pkg/adapter/runtime.go7
-rw-r--r--pkg/network/devices.go17
-rw-r--r--pkg/network/files.go26
-rw-r--r--pkg/spec/spec.go24
-rw-r--r--pkg/spec/storage.go4
-rw-r--r--pkg/varlinkapi/volumes.go6
-rw-r--r--test/e2e/run_volume_test.go7
-rw-r--r--test/e2e/volume_create_test.go20
34 files changed, 630 insertions, 36 deletions
diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go
index bdffb6b1e..202d93b35 100644
--- a/cmd/podman/main_local.go
+++ b/cmd/podman/main_local.go
@@ -174,14 +174,13 @@ func setupRootless(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
-
+ conf, err := runtime.GetConfig()
+ if err != nil {
+ return err
+ }
if !ownsCgroup {
unitName := fmt.Sprintf("podman-%d.scope", os.Getpid())
if err := utils.RunUnderSystemdScope(os.Getpid(), "user.slice", unitName); err != nil {
- conf, err2 := runtime.GetConfig()
- if err2 != nil {
- return err2
- }
if conf.CgroupManager == libpod.SystemdCgroupsManager {
logrus.Warnf("Failed to add podman to systemd sandbox cgroup: %v", err)
} else {
diff --git a/cmd/podman/shared/volumes_shared.go b/cmd/podman/shared/volumes_shared.go
index 912615cad..74c0ce011 100644
--- a/cmd/podman/shared/volumes_shared.go
+++ b/cmd/podman/shared/volumes_shared.go
@@ -2,8 +2,13 @@ package shared
import (
"context"
+ "strconv"
+ "strings"
"github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/define"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// Remove given set of volumes
@@ -45,3 +50,60 @@ func SharedRemoveVolumes(ctx context.Context, runtime *libpod.Runtime, vols []st
return success, failed, nil
}
+
+// Handle volume options from CLI.
+// Parse "o" option to find UID, GID.
+func ParseVolumeOptions(opts map[string]string) ([]libpod.VolumeCreateOption, error) {
+ libpodOptions := []libpod.VolumeCreateOption{}
+ volumeOptions := make(map[string]string)
+
+ for key, value := range opts {
+ switch key {
+ case "o":
+ // o has special handling to parse out UID, GID.
+ // These are separate Libpod options.
+ splitVal := strings.Split(value, ",")
+ finalVal := []string{}
+ for _, o := range splitVal {
+ // Options will be formatted as either "opt" or
+ // "opt=value"
+ splitO := strings.SplitN(o, "=", 2)
+ switch strings.ToLower(splitO[0]) {
+ case "uid":
+ if len(splitO) != 2 {
+ return nil, errors.Wrapf(define.ErrInvalidArg, "uid option must provide a UID")
+ }
+ intUID, err := strconv.Atoi(splitO[1])
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot convert UID %s to integer", splitO[1])
+ }
+ logrus.Debugf("Removing uid= from options and adding WithVolumeUID for UID %d", intUID)
+ libpodOptions = append(libpodOptions, libpod.WithVolumeUID(intUID))
+ case "gid":
+ if len(splitO) != 2 {
+ return nil, errors.Wrapf(define.ErrInvalidArg, "gid option must provide a GID")
+ }
+ intGID, err := strconv.Atoi(splitO[1])
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot convert GID %s to integer", splitO[1])
+ }
+ logrus.Debugf("Removing gid= from options and adding WithVolumeGID for GID %d", intGID)
+ libpodOptions = append(libpodOptions, libpod.WithVolumeGID(intGID))
+ default:
+ finalVal = append(finalVal, o)
+ }
+ }
+ if len(finalVal) > 0 {
+ volumeOptions[key] = strings.Join(finalVal, ",")
+ }
+ default:
+ volumeOptions[key] = value
+ }
+ }
+
+ if len(volumeOptions) > 0 {
+ libpodOptions = append(libpodOptions, libpod.WithVolumeOptions(volumeOptions))
+ }
+
+ return libpodOptions, nil
+}
diff --git a/cmd/podman/volume_create.go b/cmd/podman/volume_create.go
index 617f701a4..e5a576749 100644
--- a/cmd/podman/volume_create.go
+++ b/cmd/podman/volume_create.go
@@ -37,7 +37,7 @@ func init() {
flags := volumeCreateCommand.Flags()
flags.StringVar(&volumeCreateCommand.Driver, "driver", "", "Specify volume driver name (default local)")
flags.StringSliceVarP(&volumeCreateCommand.Label, "label", "l", []string{}, "Set metadata for a volume (default [])")
- flags.StringSliceVarP(&volumeCreateCommand.Opt, "opt", "o", []string{}, "Set driver specific options (default [])")
+ flags.StringArrayVarP(&volumeCreateCommand.Opt, "opt", "o", []string{}, "Set driver specific options (default [])")
}
func volumeCreateCmd(c *cliconfig.VolumeCreateValues) error {
diff --git a/docs/podman-create.1.md b/docs/podman-create.1.md
index 626ed9f64..6617850fd 100644
--- a/docs/podman-create.1.md
+++ b/docs/podman-create.1.md
@@ -515,13 +515,16 @@ This works for both background and foreground containers.
**--network**, **--net**="*bridge*"
Set the Network mode for the container. Invalid if using **--dns**, **--dns-option**, or **--dns-search** with **--network** that is set to 'none' or 'container:<name|id>'.
- 'bridge': create a network stack on the default bridge
- 'none': no networking
- 'container:<name|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.
- '<network-name>|<network-id>': connect to a user-defined network
- 'ns:<path>': path to a network namespace to join
- 'slirp4netns': use slirp4netns to create a user network stack. This is the default for rootless containers
+
+Valid values are:
+
+- `bridge`: create a network stack on the default bridge
+- `none`: no networking
+- `container:<name|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.
+- `<network-name>|<network-id>`: connect to a user-defined network, multiple networks should be comma separated
+- `ns:<path>`: path to a network namespace to join
+- `slirp4netns`: use slirp4netns to create a user network stack. This is the default for rootless containers
**--network-alias**=*alias*
@@ -626,6 +629,7 @@ If container is running in --read-only mode, then mount a read-write tmpfs on /r
Restart policy to follow when containers exit.
Restart policy will not take effect if a container is stopped via the `podman kill` or `podman stop` commands.
+
Valid values are:
- `no` : Do not restart containers on exit
diff --git a/docs/podman-run.1.md b/docs/podman-run.1.md
index 9a92aba82..d6d8f4c1e 100644
--- a/docs/podman-run.1.md
+++ b/docs/podman-run.1.md
@@ -526,11 +526,14 @@ This works for both background and foreground containers.
**--network**, **--net**=*node*
Set the Network mode for the container. Invalid if using **--dns**, **--dns-option**, or **--dns-search** with **--network** that is set to 'none' or 'container:<name|id>'.
+
+Valid values are:
+
- `bridge`: create a network stack on the default bridge
- `none`: no networking
- `container:<name|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.
-- `<network-name>|<network-id>`: connect to a user-defined network
+- `<network-name>|<network-id>`: connect to a user-defined network, multiple networks should be comma separated
- `ns:<path>`: path to a network namespace to join
- `slirp4netns`: use slirp4netns to create a user network stack. This is the default for rootless containers
@@ -645,6 +648,7 @@ If container is running in --read-only mode, then mount a read-write tmpfs on /r
Restart policy to follow when containers exit.
Restart policy will not take effect if a container is stopped via the `podman kill` or `podman stop` commands.
+
Valid values are:
- `no` : Do not restart containers on exit
diff --git a/docs/podman-volume-create.1.md b/docs/podman-volume-create.1.md
index 6612b0ad2..b354f396f 100644
--- a/docs/podman-volume-create.1.md
+++ b/docs/podman-volume-create.1.md
@@ -30,6 +30,13 @@ Set metadata for a volume (e.g., --label mykey=value).
**-o**, **--opt**=*option*
Set driver specific options.
+For the default driver, `local`, this allows a volume to be configured to mount a filesystem on the host.
+For the `local` driver the following options are supported: `type`, `device`, and `o`.
+The `type` option sets the type of the filesystem to be mounted, and is equivalent to the `-t` flag to **mount(8)**.
+The `device` option sets the device to be mounted, and is equivalent to the `device` argument to **mount(8)**.
+The `o` option sets options for the mount, and is equivalent to the `-o` flag to **mount(8)** with two exceptions.
+The `o` option supports `uid` and `gid` options to set the UID and GID of the created volume that are not normally supported by **mount(8)**.
+Using volume options with the `local` driver requires root privileges.
## EXAMPLES
@@ -40,11 +47,13 @@ $ podman volume create
$ podman volume create --label foo=bar myvol
-$ podman volume create --opt device=tmpfs --opt type=tmpfs --opt o=nodev,noexec myvol
+# podman volume create --opt device=tmpfs --opt type=tmpfs --opt o=nodev,noexec myvol
+
+# podman volume create --opt device=tmpfs --opt type=tmpfs --opt o=uid=1000,gid=1000 testvol
```
## SEE ALSO
-podman-volume(1)
+podman-volume(1), mount(8)
## HISTORY
November 2018, Originally compiled by Urvashi Mohnani <umohnani@redhat.com>
diff --git a/docs/rtd/Makefile b/docs/rtd/Makefile
index d0c3cbf10..50af6490a 100644
--- a/docs/rtd/Makefile
+++ b/docs/rtd/Makefile
@@ -12,7 +12,110 @@ BUILDDIR = build
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-.PHONY: help Makefile
+clean:
+ rm -fr build/
+ rm -f source/man/podman-*.1.md
+
+copy:
+ cp -v ../podman-attach.1.md source/man/
+ cp -v ../podman-build.1.md source/man/
+ cp -v ../podman-commit.1.md source/man/
+ # container
+ cp -v ../podman-container-checkpoint.1.md source/man/
+ cp -v ../podman-container-exists.1.md source/man/
+ cp -v ../podman-container-restore.1.md source/man/
+ cp -v ../podman-container-cleanup.1.md source/man/
+ cp -v ../podman-container-prune.1.md source/man/
+ cp -v ../podman-container-runlabel.1.md source/man/
+ cp -v ../podman-cp.1.md source/man/
+ cp -v ../podman-create.1.md source/man/
+ cp -v ../podman-diff.1.md source/man/
+ cp -v ../podman-events.1.md source/man/
+ cp -v ../podman-exec.1.md source/man/
+ cp -v ../podman-export.1.md source/man/
+ # generate
+ cp -v ../podman-generate-systemd.1.md source/man/
+ cp -v ../podman-generate-kube.1.md source/man/
+ # healthcheck
+ cp -v ../podman-healthcheck-run.1.md source/man/
+ #cp -v ../podman-help.1.md source/
+ cp -v ../podman-history.1.md source/man/
+ # image
+ cp -v ../podman-image-prune.1.md source/man/
+ cp -v ../podman-image-tree.1.md source/man/
+ cp -v ../podman-image-trust.1.md source/man/
+ cp -v ../podman-image-exists.1.md source/man/
+ cp -v ../podman-image-sign.1.md source/man/
+ cp -v ../podman-images.1.md source/man/
+ cp -v ../podman-import.1.md source/man/
+ cp -v ../podman-info.1.md source/man/
+ cp -v ../podman-init.1.md source/man/
+ cp -v ../podman-inspect.1.md source/man/
+ cp -v ../podman-kill.1.md source/man/
+ cp -v ../podman-load.1.md source/man/
+ cp -v ../podman-login.1.md source/man/
+ cp -v ../podman-logout.1.md source/man/
+ cp -v ../podman-logs.1.md source/man/
+ cp -v ../podman-mount.1.md source/man/
+ # network
+ cp -v ../podman-network-create.1.md source/man/
+ cp -v ../podman-network-ls.1.md source/man/
+ cp -v ../podman-network-inspect.1.md source/man/
+ cp -v ../podman-network-rm.1.md source/man/
+ cp -v ../podman-pause.1.md source/man/
+ # play
+ cp -v ../podman-play-kube.1.md source/man/
+ # pod
+ cp -v ../podman-pod-create.1.md source/man/
+ cp -v ../podman-pod-pause.1.md source/man/
+ cp -v ../podman-pod-rm.1.md source/man/
+ cp -v ../podman-pod-top.1.md source/man/
+ cp -v ../podman-pod-exists.1.md source/man/
+ cp -v ../podman-pod-prune.1.md source/man/
+ cp -v ../podman-pod-start.1.md source/man/
+ cp -v ../podman-pod-unpause.1.md source/man/
+ cp -v ../podman-pod-inspect.1.md source/man/
+ cp -v ../podman-pod-ps.1.md source/man/
+ cp -v ../podman-pod-stats.1.md source/man/
+ cp -v ../podman-pod-kill.1.md source/man/
+ cp -v ../podman-pod-restart.1.md source/man/
+ cp -v ../podman-pod-stop.1.md source/man/
+ cp -v ../podman-port.1.md source/man/
+ cp -v ../podman-ps.1.md source/man/
+ cp -v ../podman-pull.1.md source/man/
+ cp -v ../podman-push.1.md source/man/
+ cp -v ../podman-restart.1.md source/man/
+ cp -v ../podman-rm.1.md source/man/
+ cp -v ../podman-rmi.1.md source/man/
+ cp -v ../podman-run.1.md source/man/
+ cp -v ../podman-save.1.md source/man/
+ cp -v ../podman-search.1.md source/man/
+ cp -v ../podman-start.1.md source/man/
+ cp -v ../podman-stats.1.md source/man/
+ cp -v ../podman-stop.1.md source/man/
+ # system
+ cp -v ../podman-system-migrate.1.md source/man/
+ cp -v ../podman-system-renumber.1.md source/man/
+ cp -v ../podman-system-df.1.md source/man/
+ cp -v ../podman-system-prune.1.md source/man/
+ cp -v ../podman-top.1.md source/man/
+ cp -v ../podman-umount.1.md source/man/
+ cp -v ../podman-unpause.1.md source/man/
+ cp -v ../podman-unshare.1.md source/man/
+ cp -v ../podman-varlink.1.md source/man/
+ cp -v ../podman-version.1.md source/man/
+ # volume
+ cp -v ../podman-volume-inspect.1.md source/man/
+ cp -v ../podman-volume-prune.1.md source/man/
+ cp -v ../podman-volume-create.1.md source/man/
+ cp -v ../podman-volume-ls.1.md source/man/
+ cp -v ../podman-volume-rm.1.md source/man/
+ cp -v ../podman-wait.1.md source/man/
+
+.PHONY: help Makefile copy
+
+html: copy
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
diff --git a/docs/rtd/source/Commands.rst b/docs/rtd/source/Commands.rst
new file mode 100644
index 000000000..f6ba5b20d
--- /dev/null
+++ b/docs/rtd/source/Commands.rst
@@ -0,0 +1,107 @@
+Commands
+========
+
+
+:doc:`attach <man/podman-attach.1>` Attach to a running container
+
+:doc:`build <man/podman-build.1>` Build an image using instructions from Containerfiles
+
+:doc:`commit <man/podman-commit.1>` Create new image based on the changed container
+
+:doc:`containers <man/managecontainers>` Manage Containers
+
+:doc:`cp <man/podman-cp.1>` Copy files/folders between a container and the local filesystem
+
+:doc:`create <man/podman-create.1>` Create but do not start a container
+
+:doc:`diff <man/podman-diff.1>` Inspect changes on container's file systems
+
+:doc:`events <man/podman-events.1>` Show podman events
+
+:doc:`exec <man/podman-exec.1>` Run a process in a running container
+
+:doc:`export <man/podman-export.1>` Export container's filesystem contents as a tar archive
+
+:doc:`generate <man/generate>` Generated structured data
+
+:doc:`healthcheck <man/healthcheck>` Manage Healthcheck
+
+:doc:`history <man/podman-history.1>` Show history of a specified image
+
+:doc:`image <man/image>` Manage images
+
+:doc:`images <man/podman-images.1>` List images in local storage
+
+:doc:`import <man/podman-import.1>` Import a tarball to create a filesystem image
+
+:doc:`info <man/podman-info.1>` Display podman system information
+
+:doc:`init <man/podman-init.1>` Initialize one or more containers
+
+:doc:`inspect <man/podman-inspect.1>` Display the configuration of a container or image
+
+:doc:`kill <man/podman-kill.1>` Kill one or more running containers with a specific signal
+
+:doc:`load <man/podman-load.1>` Load an image from container archive
+
+:doc:`login <man/podman-login.1>` Login to a container registry
+
+:doc:`logout <man/podman-logout.1>` Logout of a container registry
+
+:doc:`logs <man/podman-logs.1>` Fetch the logs of a container
+
+:doc:`mount <man/podman-mount.1>` Mount a working container's root filesystem
+
+:doc:`network <man/network>` Manage Networks
+
+:doc:`pause <man/podman-pause.1>` Pause all the processes in one or more containers
+
+:doc:`play <man/play>` Play a pod
+
+:doc:`pod <man/pod>` Manage pods
+
+:doc:`port <man/podman-port.1>` List port mappings or a specific mapping for the container
+
+:doc:`ps <man/podman-ps.1>` List containers
+
+:doc:`pull <man/podman-pull.1>` Pull an image from a registry
+
+:doc:`push <man/podman-push.1>` Push an image to a specified destination
+
+:doc:`restart <man/podman-restart.1>` Restart one or more containers
+
+:doc:`rm <man/podman-rm.1>` Remove one or more containers
+
+:doc:`rmi <man/podman-rmi.1>` Removes one or more images from local storage
+
+:doc:`run <man/podman-run.1>` Run a command in a new container
+
+:doc:`save <man/podman-save.1>` Save image to an archive
+
+:doc:`search <man/podman-search.1>` Search registry for image
+
+:doc:`start <man/podman-start.1>` Start one or more containers
+
+:doc:`stats <man/podman-stats.1>` Display a live stream of container resource usage statistics
+
+:doc:`stop <man/podman-stop.1>` Stop one or more containers
+
+:doc:`system <man/system>` Manage podman
+
+:doc:`tag <man/podman-tag.1>` Add an additional name to a local image
+
+:doc:`top <man/podman-top.1>` Display the running processes of a container
+
+:doc:`umount <man/podman-umount.1>` Unmounts working container's root filesystem
+
+:doc:`unpause <man/podman-unpause.1>` Unpause the processes in one or more containers
+
+:doc:`unshare <man/podman-unshare.1>` Run a command in a modified user namespace
+
+:doc:`varlink <man/podman-varlink.1>` Run varlink interface
+
+:doc:`version <man/podman-version.1>` Display the Podman Version Information
+
+:doc:`volume <man/volume>` Manage volumes
+
+:doc:`wait <man/podman-wait.1>` Block on one or more containers \ No newline at end of file
diff --git a/docs/rtd/source/Introduction.rst b/docs/rtd/source/Introduction.rst
new file mode 100644
index 000000000..c516b3317
--- /dev/null
+++ b/docs/rtd/source/Introduction.rst
@@ -0,0 +1,2 @@
+Introduction
+============
diff --git a/docs/rtd/source/Reference.rst b/docs/rtd/source/Reference.rst
new file mode 100644
index 000000000..9a771c87f
--- /dev/null
+++ b/docs/rtd/source/Reference.rst
@@ -0,0 +1,2 @@
+Reference
+=========
diff --git a/docs/rtd/source/Tutorials.rst b/docs/rtd/source/Tutorials.rst
new file mode 100644
index 000000000..0c7e28c3b
--- /dev/null
+++ b/docs/rtd/source/Tutorials.rst
@@ -0,0 +1,2 @@
+Tutorials
+=========
diff --git a/docs/rtd/source/conf.py b/docs/rtd/source/conf.py
index 9290c343a..d95290f72 100644
--- a/docs/rtd/source/conf.py
+++ b/docs/rtd/source/conf.py
@@ -39,6 +39,7 @@ templates_path = ['_templates']
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
+master_doc = 'index'
# -- Options for HTML output -------------------------------------------------
diff --git a/docs/rtd/source/index.rst b/docs/rtd/source/index.rst
index 90033056c..9dd61a6a6 100644
--- a/docs/rtd/source/index.rst
+++ b/docs/rtd/source/index.rst
@@ -10,6 +10,12 @@ Welcome to Podman's documentation!
:maxdepth: 2
:caption: Contents:
+ Introduction
+ Commands
+ Reference
+ Tutorials
+
+
Indices and tables
diff --git a/docs/rtd/source/man/generate.rst b/docs/rtd/source/man/generate.rst
new file mode 100644
index 000000000..e82a15735
--- /dev/null
+++ b/docs/rtd/source/man/generate.rst
@@ -0,0 +1,6 @@
+Generate
+========
+
+:doc:`kube <podman-generate-kube.1>` Generate Kubernetes pod YAML from a container or pod
+
+:doc:`systemd <podman-generate-systemd.1>` Generate a systemd unit file for a Podman container
diff --git a/docs/rtd/source/man/healthcheck.rst b/docs/rtd/source/man/healthcheck.rst
new file mode 100644
index 000000000..697c1358b
--- /dev/null
+++ b/docs/rtd/source/man/healthcheck.rst
@@ -0,0 +1,4 @@
+HealthCheck
+===========
+
+:doc:`run <podman-healthcheck-run.1>` run the health check of a container
diff --git a/docs/rtd/source/man/image.rst b/docs/rtd/source/man/image.rst
new file mode 100644
index 000000000..ad963cd41
--- /dev/null
+++ b/docs/rtd/source/man/image.rst
@@ -0,0 +1,35 @@
+Image
+=====
+
+
+:doc:`build <podman-build.1>` Build an image using instructions from Containerfiles
+
+:doc:`exists <podman-image-exists.1>` Check if an image exists in local storage
+
+:doc:`history <podman-history.1>` Show history of a specified image
+
+:doc:`import <podman-import.1>` Import a tarball to create a filesystem image
+
+:doc:`inspect <podman-inspect.1>` Display the configuration of an image
+
+:doc:`list <podman-images.1>` List images in local storage
+
+:doc:`load <podman-load.1>` Load an image from container archive
+
+:doc:`prune <podman-image-prune.1>` Remove unused images
+
+:doc:`pull <podman-pull.1>` Pull an image from a registry
+
+:doc:`push <podman-push.1>` Push an image to a specified destination
+
+:doc:`rm <podman-rmi.1>` Removes one or more images from local storage
+
+:doc:`save <podman-save.1>` Save image to an archive
+
+:doc:`sign <podman-image-sign.1>` Sign an image
+
+:doc:`tag <podman-tag.1>` Add an additional name to a local image
+
+:doc:`tree <podman-image-tree.1>` Prints layer hierarchy of an image in a tree format
+
+:doc:`trust <podman-image-trust.1>` Manage container image trust policy
diff --git a/docs/rtd/source/man/managecontainers.rst b/docs/rtd/source/man/managecontainers.rst
new file mode 100644
index 000000000..20e8c0679
--- /dev/null
+++ b/docs/rtd/source/man/managecontainers.rst
@@ -0,0 +1,64 @@
+Manage Containers
+=================
+
+:doc:`attach <podman-attach.1>` Attach to a running container
+
+:doc:`checkpoint <podman-container-checkpoint.1>` Checkpoints one or more containers
+
+:doc:`cleanup <podman-container-cleanup.1>` Cleanup network and mountpoints of one or more containers
+
+:doc:`commit <podman-commit.1>` Create new image based on the changed container
+
+:doc:`cp <podman-cp.1>` Copy files/folders between a container and the local filesystem
+
+:doc:`create <podman-create.1>` Create but do not start a container
+
+:doc:`diff <podman-diff.1>` Inspect changes on container's file systems
+
+:doc:`exec <podman-exec.1>` Run a process in a running container
+
+:doc:`exists <podman-exists.1>` Check if a container exists in local storage
+
+:doc:`export <podman-export.1>` Export container's filesystem contents as a tar archive
+
+:doc:`init <podman-init.1>` Initialize one or more containers
+
+:doc:`inspect <podman-inspect.1>` Display the configuration of a container or image
+
+:doc:`kill <podman-kill.1>` Kill one or more running containers with a specific signal
+
+:doc:`list <podman-ps.1>` List containers
+
+:doc:`logs <podman-logs.1>` Fetch the logs of a container
+
+:doc:`mount <podman-mount.1>` Mount a working container's root filesystem
+
+:doc:`pause <podman-pause.1>` Pause all the processes in one or more containers
+
+:doc:`port <podman-port.1>` List port mappings or a specific mapping for the container
+
+:doc:`restart <podman-restart.1>` Restart one or more containers
+
+:doc:`prune <podman-container-prune.1>` Remove all stopped containers
+
+:doc:`restore <podman-container-restore.1>` Restores one or more containers from a checkpoint
+
+:doc:`rm <podman-rm.1>` Remove one or more containers
+
+:doc:`run <podman-run.1>` Run a command in a new container
+
+:doc:`runlabel <podman-container-runlabel.1>` Execute the command described by an image label
+
+:doc:`start <podman-start.1>` Start one or more containers
+
+:doc:`stats <podman-stats.1>` Display a live stream of container resource usage statistics
+
+:doc:`stop <podman-stop.1>` Stop one or more containers
+
+:doc:`top <podman-top.1>` Display the running processes of a container
+
+:doc:`umount <podman-umount.1>` Unmounts working container's root filesystem
+
+:doc:`unpause <podman-unpause.1>` Unpause the processes in one or more containers
+
+:doc:`wait <podman-wait.1>` Block on one or more containers
diff --git a/docs/rtd/source/man/network.rst b/docs/rtd/source/man/network.rst
new file mode 100644
index 000000000..6d6a4c022
--- /dev/null
+++ b/docs/rtd/source/man/network.rst
@@ -0,0 +1,10 @@
+Network
+=====
+
+:doc:`create <podman-network-create.1>` network create
+
+:doc:`inspect <podman-network-inspect.1>` network inspect
+
+:doc:`ls <podman-network-ls.1>` network list
+
+:doc:`rm <podman-network-rm.1>` network rm \ No newline at end of file
diff --git a/docs/rtd/source/man/play.rst b/docs/rtd/source/man/play.rst
new file mode 100644
index 000000000..93e1a9a1e
--- /dev/null
+++ b/docs/rtd/source/man/play.rst
@@ -0,0 +1,4 @@
+Play
+====
+
+:doc:`kube <podman-play-kube.1>` Play a pod based on Kubernetes YAML
diff --git a/docs/rtd/source/man/pod.rst b/docs/rtd/source/man/pod.rst
new file mode 100644
index 000000000..13c1740f8
--- /dev/null
+++ b/docs/rtd/source/man/pod.rst
@@ -0,0 +1,30 @@
+Pod
+===
+
+:doc:`create <podman-pod-create.1>` Create a new empty pod
+
+:doc:`exists <podman-pod-exists.1>` Check if a pod exists in local storage
+
+:doc:`inspect <podman-pod-inspect.1>` Displays a pod configuration
+
+:doc:`kill <podman-pod-kill.1>` Send the specified signal or SIGKILL to containers in pod
+
+:doc:`pause <podman-pause.1>` Pause one or more pods
+
+:doc:`prune <podman-pod-prune.1>` Remove all stopped pods
+
+:doc:`ps <podman-pod-ps.1>` List pods
+
+:doc:`restart <podman-pod-restart.1>` Restart one or more pods
+
+:doc:`rm <podman-pod-rm.1>` Remove one or more pods
+
+:doc:`start <podman-pod-start.1>` Start one or more pods
+
+:doc:`stats <podman-pod-stats.1>` Display a live stream of resource usage statistics for the containers in one or more pods
+
+:doc:`stop <podman-pod-stop.1>` Stop one or more pods
+
+:doc:`top <podman-pod-top.1>` Display the running processes of containers in a pod
+
+:doc:`unpause <podman-pod-unpause.1>` Unpause one or more pods
diff --git a/docs/rtd/source/man/system.rst b/docs/rtd/source/man/system.rst
new file mode 100644
index 000000000..764ec01c1
--- /dev/null
+++ b/docs/rtd/source/man/system.rst
@@ -0,0 +1,12 @@
+System
+======
+
+:doc:`df <podman-system-df.1>` Show podman disk usage
+
+:doc:`info <podman-info.1>` Display podman system information
+
+:doc:`migrate <podman-system-migrate.1>` Migrate containers
+
+:doc:`prune <podman-system-prune.1>` Remove unused data
+
+:doc:`renumber <podman-system-renumber.1>` Migrate lock numbers
diff --git a/docs/rtd/source/man/volume.rst b/docs/rtd/source/man/volume.rst
new file mode 100644
index 000000000..ee18e4b2e
--- /dev/null
+++ b/docs/rtd/source/man/volume.rst
@@ -0,0 +1,11 @@
+Volume
+======
+:doc:`create <podman-volume-create.1>` Create a new volume
+
+:doc:`inspect <podman-volume-inspect.1>` Display detailed information on one or more volumes
+
+:doc:`ls <podman-volume-ls.1>` List volumes
+
+:doc:`prune <podman-volume-prune.1>` Remove all unused volumes
+
+:doc:`rm <podman-volume-rm.1>` Remove one or more volumes \ No newline at end of file
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index b7d353327..283d38a0f 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -550,6 +550,7 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
Options: []string{"bind", "nodev", "noexec", "nosuid"},
}
g.AddMount(systemdMnt)
+ g.AddLinuxMaskedPaths("/sys/fs/cgroup/systemd/release_agent")
}
return nil
diff --git a/libpod/options.go b/libpod/options.go
index ddc5993af..f779b0413 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1014,6 +1014,13 @@ func WithNetNS(portMappings []ocicni.PortMapping, postConfigureNetNS bool, netmo
ctr.config.NetMode = namespaces.NetworkMode(netmode)
ctr.config.CreateNetNS = true
ctr.config.PortMappings = portMappings
+
+ if rootless.IsRootless() {
+ if len(networks) > 0 {
+ return errors.New("cannot use CNI networks with rootless containers")
+ }
+ }
+
ctr.config.Networks = networks
return nil
@@ -1487,6 +1494,8 @@ func WithVolumeLabels(labels map[string]string) VolumeCreateOption {
}
// WithVolumeOptions sets the options of the volume.
+// If the "local" driver has been selected, options will be validated. There are
+// currently 3 valid options for the "local" driver - o, type, and device.
func WithVolumeOptions(options map[string]string) VolumeCreateOption {
return func(volume *Volume) error {
if volume.valid {
@@ -1495,6 +1504,13 @@ func WithVolumeOptions(options map[string]string) VolumeCreateOption {
volume.config.Options = make(map[string]string)
for key, value := range options {
+ switch key {
+ case "type", "device", "o":
+ volume.config.Options[key] = value
+ default:
+ return errors.Wrapf(define.ErrInvalidArg, "unrecognized volume option %q is not supported with local driver", key)
+ }
+
volume.config.Options[key] = value
}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 8f145a809..a06b2bb51 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -1474,6 +1474,25 @@ func (r *Runtime) GetOCIRuntimePath() string {
// TODO Once runc has support for cgroups, this function should be removed.
func cgroupV2Check(configPath string, tmpConfig *RuntimeConfig) error {
if !tmpConfig.CgroupCheck && rootless.IsRootless() {
+ if tmpConfig.CgroupManager == SystemdCgroupsManager {
+ // If we are running rootless and the systemd manager is requested, be sure that dbus is accessible
+ session := os.Getenv("DBUS_SESSION_BUS_ADDRESS")
+ hasSession := session != ""
+ if hasSession && strings.HasPrefix(session, "unix:path=") {
+ _, err := os.Stat(strings.TrimPrefix(session, "unix:path="))
+ hasSession = err == nil
+ }
+
+ if !hasSession {
+ logrus.Warningf("The cgroups manager is set to systemd but there is no systemd user session available")
+ logrus.Warningf("For using systemd, you may need to login using an user session")
+ logrus.Warningf("Alternatively, you can enable lingering with: `loginctl enable-linger %d` (possibily as root)", rootless.GetRootlessUID())
+ logrus.Warningf("Falling back to --cgroup-manager=cgroupfs")
+
+ tmpConfig.CgroupManager = CgroupfsCgroupsManager
+ }
+
+ }
cgroupsV2, err := cgroups.IsCgroup2UnifiedMode()
if err != nil {
return err
@@ -1487,7 +1506,7 @@ func cgroupV2Check(configPath string, tmpConfig *RuntimeConfig) error {
}
tmpConfig.CgroupCheck = true
tmpConfig.OCIRuntime = path
- file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE, 0666)
+ file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
return errors.Wrapf(err, "cannot open file %s", configPath)
}
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index bff93cc9e..73e6dba3a 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -438,7 +438,11 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode
if c.IsSet("rm") {
if err := r.Runtime.RemoveContainer(ctx, ctr, false, true); err != nil {
- logrus.Errorf("Error removing container %s: %v", ctr.ID(), err)
+ if errors.Cause(err) == define.ErrNoSuchCtr {
+ logrus.Warnf("Container %s does not exist: %v", ctr.ID(), err)
+ } else {
+ logrus.Errorf("Error removing container %s: %v", ctr.ID(), err)
+ }
}
}
diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go
index 0706d4b6a..84d43c337 100644
--- a/pkg/adapter/runtime.go
+++ b/pkg/adapter/runtime.go
@@ -186,7 +186,12 @@ func (r *LocalRuntime) CreateVolume(ctx context.Context, c *cliconfig.VolumeCrea
}
if len(opts) != 0 {
- options = append(options, libpod.WithVolumeOptions(opts))
+ // We need to process -o for uid, gid
+ parsedOptions, err := shared.ParseVolumeOptions(opts)
+ if err != nil {
+ return "", err
+ }
+ options = append(options, parsedOptions...)
}
newVolume, err := r.NewVolume(ctx, options...)
if err != nil {
diff --git a/pkg/network/devices.go b/pkg/network/devices.go
index 85068a7d1..78e1a5aa5 100644
--- a/pkg/network/devices.go
+++ b/pkg/network/devices.go
@@ -24,19 +24,26 @@ func GetFreeDeviceName() (string, error) {
if err != nil {
return "", err
}
+ bridgeNames, err := GetBridgeNamesFromFileSystem()
+ if err != nil {
+ return "", err
+ }
for {
deviceName = fmt.Sprintf("%s%d", CNIDeviceName, deviceNum)
- logrus.Debugf("checking if device name %s exists in other cni networks", deviceName)
+ logrus.Debugf("checking if device name %q exists in other cni networks", deviceName)
if util.StringInSlice(deviceName, networkNames) {
deviceNum++
continue
}
- logrus.Debugf("checking if device name %s exists in live networks", deviceName)
- if !util.StringInSlice(deviceName, liveNetworksNames) {
+ logrus.Debugf("checking if device name %q exists in live networks", deviceName)
+ if util.StringInSlice(deviceName, liveNetworksNames) {
+ deviceNum++
+ continue
+ }
+ logrus.Debugf("checking if device name %q already exists as a bridge name ", deviceName)
+ if !util.StringInSlice(deviceName, bridgeNames) {
break
}
- // TODO Still need to check the bridge names for a conflict but I dont know
- // how to get them yet!
deviceNum++
}
return deviceName, nil
diff --git a/pkg/network/files.go b/pkg/network/files.go
index d55ec2dfd..2f3932974 100644
--- a/pkg/network/files.go
+++ b/pkg/network/files.go
@@ -129,3 +129,29 @@ func GetInterfaceNameFromConfig(path string) (string, error) {
}
return name, nil
}
+
+// GetBridgeNamesFromFileSystem is a convenience function to get all the bridge
+// names from the configured networks
+func GetBridgeNamesFromFileSystem() ([]string, error) {
+ var bridgeNames []string
+ networks, err := LoadCNIConfsFromDir(CNIConfigDir)
+ if err != nil {
+ return nil, err
+ }
+ for _, n := range networks {
+ var name string
+ // iterate network conflists
+ for _, cniplugin := range n.Plugins {
+ // iterate plugins
+ if cniplugin.Network.Type == "bridge" {
+ plugin := make(map[string]interface{})
+ if err := json.Unmarshal(cniplugin.Bytes, &plugin); err != nil {
+ continue
+ }
+ name = plugin["bridge"].(string)
+ }
+ }
+ bridgeNames = append(bridgeNames, name)
+ }
+ return bridgeNames, nil
+}
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 8f00d3270..da5c14948 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -300,6 +300,15 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
blockAccessToKernelFilesystems(config, &g)
+ var runtimeConfig *libpod.RuntimeConfig
+
+ if runtime != nil {
+ runtimeConfig, err = runtime.GetConfig()
+ if err != nil {
+ return nil, err
+ }
+ }
+
// RESOURCES - PIDS
if config.Resources.PidsLimit > 0 {
// if running on rootless on a cgroupv1 machine or using the cgroupfs manager, pids
@@ -312,11 +321,7 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
if err != nil {
return nil, err
}
- runtimeConfig, err := runtime.GetConfig()
- if err != nil {
- return nil, err
- }
- if (!cgroup2 || runtimeConfig.CgroupManager != libpod.SystemdCgroupsManager) && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() {
+ if (!cgroup2 || (runtimeConfig != nil && runtimeConfig.CgroupManager != libpod.SystemdCgroupsManager)) && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() {
setPidLimit = false
}
}
@@ -411,10 +416,13 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
if !addedResources {
configSpec.Linux.Resources = &spec.LinuxResources{}
}
- if addedResources && !cgroup2 {
- return nil, errors.New("invalid configuration, cannot set resources with rootless containers not using cgroups v2 unified mode")
+
+ canUseResources := cgroup2 && runtimeConfig != nil && (runtimeConfig.CgroupManager == libpod.SystemdCgroupsManager)
+
+ if addedResources && !canUseResources {
+ return nil, errors.New("invalid configuration, cannot specify resource limits without cgroups v2 and --cgroup-manager=systemd")
}
- if !cgroup2 {
+ if !canUseResources {
// Force the resources block to be empty instead of having default values.
configSpec.Linux.Resources = &spec.LinuxResources{}
}
diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go
index a394a19ae..095534589 100644
--- a/pkg/spec/storage.go
+++ b/pkg/spec/storage.go
@@ -738,13 +738,13 @@ func (config *CreateConfig) getImageVolumes() (map[string]spec.Mount, map[string
Destination: cleanDest,
Source: TypeTmpfs,
Type: TypeTmpfs,
- Options: []string{"rprivate", "rw", "nodev"},
+ Options: []string{"rprivate", "rw", "nodev", "exec"},
}
mounts[vol] = mount
} else {
// Anonymous volumes have no name.
namedVolume := new(libpod.ContainerNamedVolume)
- namedVolume.Options = []string{"rprivate", "rw", "nodev"}
+ namedVolume.Options = []string{"rprivate", "rw", "nodev", "exec"}
namedVolume.Dest = cleanDest
volumes[vol] = namedVolume
}
diff --git a/pkg/varlinkapi/volumes.go b/pkg/varlinkapi/volumes.go
index 0ba76902e..2dddd3008 100644
--- a/pkg/varlinkapi/volumes.go
+++ b/pkg/varlinkapi/volumes.go
@@ -24,7 +24,11 @@ func (i *LibpodAPI) VolumeCreate(call iopodman.VarlinkCall, options iopodman.Vol
volumeOptions = append(volumeOptions, libpod.WithVolumeLabels(options.Labels))
}
if len(options.Options) > 0 {
- volumeOptions = append(volumeOptions, libpod.WithVolumeOptions(options.Options))
+ parsedOptions, err := shared.ParseVolumeOptions(options.Options)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ volumeOptions = append(volumeOptions, parsedOptions...)
}
newVolume, err := i.Runtime.NewVolume(getContext(), volumeOptions...)
if err != nil {
diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go
index d04eb07b3..c96059787 100644
--- a/test/e2e/run_volume_test.go
+++ b/test/e2e/run_volume_test.go
@@ -357,4 +357,11 @@ var _ = Describe("Podman run with volumes", func() {
Expect(len(arr2)).To(Equal(1))
Expect(arr2[0]).To(Equal(volName))
})
+
+ It("podman run image volume is not noexec", func() {
+ session := podmanTest.Podman([]string{"run", "--rm", redis, "grep", "/data", "/proc/self/mountinfo"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Not(ContainSubstring("noexec")))
+ })
})
diff --git a/test/e2e/volume_create_test.go b/test/e2e/volume_create_test.go
index 41107b5ba..71023f9e2 100644
--- a/test/e2e/volume_create_test.go
+++ b/test/e2e/volume_create_test.go
@@ -1,6 +1,7 @@
package integration
import (
+ "fmt"
"os"
. "github.com/containers/libpod/test/utils"
@@ -63,4 +64,23 @@ var _ = Describe("Podman volume create", func() {
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
})
+
+ It("podman create volume with o=uid,gid", func() {
+ volName := "testVol"
+ uid := "3000"
+ gid := "4000"
+ session := podmanTest.Podman([]string{"volume", "create", "--opt", fmt.Sprintf("o=uid=%s,gid=%s", uid, gid), volName})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ inspectUID := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .UID }}", volName})
+ inspectUID.WaitWithDefaultTimeout()
+ Expect(inspectUID.ExitCode()).To(Equal(0))
+ Expect(inspectUID.OutputToString()).To(Equal(uid))
+
+ inspectGID := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .GID }}", volName})
+ inspectGID.WaitWithDefaultTimeout()
+ Expect(inspectGID.ExitCode()).To(Equal(0))
+ Expect(inspectGID.OutputToString()).To(Equal(gid))
+ })
})