diff options
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)) + }) }) |