diff options
-rw-r--r-- | .cirrus.yml | 79 | ||||
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 69 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | RELEASE_NOTES.md | 29 | ||||
-rw-r--r-- | cmd/podman/build.go | 7 | ||||
-rw-r--r-- | cmd/podman/cliconfig/config.go | 2 | ||||
-rw-r--r-- | cmd/podman/common.go | 2 | ||||
-rw-r--r-- | cmd/podman/cp.go | 11 | ||||
-rw-r--r-- | cmd/podman/logs.go | 2 | ||||
-rw-r--r-- | cmd/podman/main_local.go | 11 | ||||
-rw-r--r-- | cmd/podman/utils.go | 13 | ||||
-rw-r--r-- | contrib/spec/podman.spec.in | 2 | ||||
-rw-r--r-- | docs/Makefile | 23 | ||||
-rw-r--r-- | docs/Readme.md | 21 | ||||
-rw-r--r-- | docs/make.bat (renamed from docs/rtd/make.bat) | 0 | ||||
-rwxr-xr-x | docs/remote-docs.sh (renamed from docs/podman-remote.sh) | 55 | ||||
-rw-r--r-- | docs/requirements.txt (renamed from docs/rtd/requirements.txt) | 0 | ||||
-rw-r--r-- | docs/rtd/Makefile | 123 | ||||
-rw-r--r-- | docs/rtd/source/Commands.rst | 107 | ||||
-rw-r--r-- | docs/rtd/source/man/generate.rst | 6 | ||||
-rw-r--r-- | docs/rtd/source/man/healthcheck.rst | 4 | ||||
-rw-r--r-- | docs/rtd/source/man/image.rst | 35 | ||||
-rw-r--r-- | docs/rtd/source/man/managecontainers.rst | 64 | ||||
-rw-r--r-- | docs/rtd/source/man/network.rst | 10 | ||||
-rw-r--r-- | docs/rtd/source/man/play.rst | 4 | ||||
-rw-r--r-- | docs/rtd/source/man/pod.rst | 30 | ||||
-rw-r--r-- | docs/rtd/source/man/system.rst | 12 | ||||
-rw-r--r-- | docs/rtd/source/man/volume.rst | 11 | ||||
-rw-r--r-- | docs/source/Commands.rst | 107 | ||||
-rw-r--r-- | docs/source/Introduction.rst (renamed from docs/rtd/source/Introduction.rst) | 0 | ||||
-rw-r--r-- | docs/source/Reference.rst (renamed from docs/rtd/source/Reference.rst) | 0 | ||||
-rw-r--r-- | docs/source/Tutorials.rst (renamed from docs/rtd/source/Tutorials.rst) | 0 | ||||
-rw-r--r-- | docs/source/conf.py (renamed from docs/rtd/source/conf.py) | 0 | ||||
-rw-r--r-- | docs/source/generate.rst | 6 | ||||
-rw-r--r-- | docs/source/healthcheck.rst | 4 | ||||
-rw-r--r-- | docs/source/image.rst | 35 | ||||
-rw-r--r-- | docs/source/index.rst (renamed from docs/rtd/source/index.rst) | 0 | ||||
-rw-r--r-- | docs/source/managecontainers.rst | 64 | ||||
-rw-r--r-- | docs/source/markdown/containers-mounts.conf.5.md (renamed from docs/containers-mounts.conf.5.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/libpod.conf.5.md (renamed from docs/libpod.conf.5.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-attach.1 (renamed from docs/links/podman-container-attach.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-commit.1 (renamed from docs/links/podman-container-commit.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-cp.1 (renamed from docs/links/podman-container-cp.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-create.1 (renamed from docs/links/podman-container-create.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-diff.1 (renamed from docs/links/podman-container-diff.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-exec.1 (renamed from docs/links/podman-container-exec.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-export.1 (renamed from docs/links/podman-container-export.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-init.1 (renamed from docs/links/podman-container-init.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-inspect.1 (renamed from docs/links/podman-container-inspect.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-kill.1 (renamed from docs/links/podman-container-kill.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-list.1 (renamed from docs/links/podman-container-list.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-logs.1 (renamed from docs/links/podman-container-logs.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-ls.1 (renamed from docs/links/podman-container-ls.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-mount.1 (renamed from docs/links/podman-container-mount.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-pause.1 (renamed from docs/links/podman-container-pause.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-port.1 (renamed from docs/links/podman-container-port.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-ps.1 (renamed from docs/links/podman-container-ps.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-restart.1 (renamed from docs/links/podman-container-restart.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-rm.1 (renamed from docs/links/podman-container-rm.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-run.1 (renamed from docs/links/podman-container-run.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-start.1 (renamed from docs/links/podman-container-start.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-stats.1 (renamed from docs/links/podman-container-stats.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-stop.1 (renamed from docs/links/podman-container-stop.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-top.1 (renamed from docs/links/podman-container-top.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-umount.1 (renamed from docs/links/podman-container-umount.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-unmount.1 (renamed from docs/links/podman-container-unmount.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-unpause.1 (renamed from docs/links/podman-container-unpause.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-container-wait.1 (renamed from docs/links/podman-container-wait.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-help.1 (renamed from docs/links/podman-help.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-image-build.1 (renamed from docs/links/podman-image-build.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-image-history.1 (renamed from docs/links/podman-image-history.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-image-import.1 (renamed from docs/links/podman-image-import.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-image-inspect.1 (renamed from docs/links/podman-image-inspect.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-image-list.1 (renamed from docs/links/podman-image-list.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-image-load.1 (renamed from docs/links/podman-image-load.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-image-ls.1 (renamed from docs/links/podman-image-ls.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-image-pull.1 (renamed from docs/links/podman-image-pull.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-image-push.1 (renamed from docs/links/podman-image-push.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-image-rm.1 (renamed from docs/links/podman-image-rm.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-image-save.1 (renamed from docs/links/podman-image-save.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-image-tag.1 (renamed from docs/links/podman-image-tag.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-list.1 (renamed from docs/links/podman-list.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-ls.1 (renamed from docs/links/podman-ls.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-system-info.1 (renamed from docs/links/podman-system-info.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/links/podman-unmount.1 (renamed from docs/links/podman-unmount.1) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-attach.1.md (renamed from docs/podman-attach.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-build.1.md (renamed from docs/podman-build.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-commit.1.md (renamed from docs/podman-commit.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-container-checkpoint.1.md (renamed from docs/podman-container-checkpoint.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-container-cleanup.1.md (renamed from docs/podman-container-cleanup.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-container-exists.1.md (renamed from docs/podman-container-exists.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-container-prune.1.md (renamed from docs/podman-container-prune.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-container-restore.1.md (renamed from docs/podman-container-restore.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-container-runlabel.1.md (renamed from docs/podman-container-runlabel.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-container.1.md (renamed from docs/podman-container.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-cp.1.md (renamed from docs/podman-cp.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-create.1.md (renamed from docs/podman-create.1.md) | 4 | ||||
-rw-r--r-- | docs/source/markdown/podman-diff.1.md (renamed from docs/podman-diff.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-events.1.md (renamed from docs/podman-events.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-exec.1.md (renamed from docs/podman-exec.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-export.1.md (renamed from docs/podman-export.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-generate-kube.1.md (renamed from docs/podman-generate-kube.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-generate-systemd.1.md (renamed from docs/podman-generate-systemd.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-generate.1.md (renamed from docs/podman-generate.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-healthcheck-run.1.md (renamed from docs/podman-healthcheck-run.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-healthcheck.1.md (renamed from docs/podman-healthcheck.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-history.1.md (renamed from docs/podman-history.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-image-exists.1.md (renamed from docs/podman-image-exists.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-image-prune.1.md (renamed from docs/podman-image-prune.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-image-sign.1.md (renamed from docs/podman-image-sign.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-image-tree.1.md (renamed from docs/podman-image-tree.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-image-trust.1.md (renamed from docs/podman-image-trust.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-image.1.md (renamed from docs/podman-image.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-images.1.md (renamed from docs/podman-images.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-import.1.md (renamed from docs/podman-import.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-info.1.md (renamed from docs/podman-info.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-init.1.md (renamed from docs/podman-init.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-inspect.1.md (renamed from docs/podman-inspect.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-kill.1.md (renamed from docs/podman-kill.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-load.1.md (renamed from docs/podman-load.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-login.1.md (renamed from docs/podman-login.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-logout.1.md (renamed from docs/podman-logout.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-logs.1.md (renamed from docs/podman-logs.1.md) | 2 | ||||
-rw-r--r-- | docs/source/markdown/podman-mount.1.md (renamed from docs/podman-mount.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-network-create.1.md (renamed from docs/podman-network-create.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-network-inspect.1.md (renamed from docs/podman-network-inspect.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-network-ls.1.md (renamed from docs/podman-network-ls.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-network-rm.1.md (renamed from docs/podman-network-rm.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-network.1.md (renamed from docs/podman-network.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pause.1.md (renamed from docs/podman-pause.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-play-kube.1.md (renamed from docs/podman-play-kube.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-play.1.md (renamed from docs/podman-play.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-create.1.md (renamed from docs/podman-pod-create.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-exists.1.md (renamed from docs/podman-pod-exists.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-inspect.1.md (renamed from docs/podman-pod-inspect.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-kill.1.md (renamed from docs/podman-pod-kill.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-pause.1.md (renamed from docs/podman-pod-pause.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-prune.1.md (renamed from docs/podman-pod-prune.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-ps.1.md (renamed from docs/podman-pod-ps.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-restart.1.md (renamed from docs/podman-pod-restart.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-rm.1.md (renamed from docs/podman-pod-rm.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-start.1.md (renamed from docs/podman-pod-start.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-stats.1.md (renamed from docs/podman-pod-stats.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-stop.1.md (renamed from docs/podman-pod-stop.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-top.1.md (renamed from docs/podman-pod-top.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-unpause.1.md (renamed from docs/podman-pod-unpause.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod.1.md (renamed from docs/podman-pod.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-port.1.md (renamed from docs/podman-port.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-ps.1.md (renamed from docs/podman-ps.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-pull.1.md (renamed from docs/podman-pull.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-push.1.md (renamed from docs/podman-push.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-remote.1.md (renamed from docs/podman-remote.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-remote.conf.5.md (renamed from docs/podman-remote.conf.5.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-restart.1.md (renamed from docs/podman-restart.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-rm.1.md (renamed from docs/podman-rm.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-rmi.1.md (renamed from docs/podman-rmi.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-run.1.md (renamed from docs/podman-run.1.md) | 4 | ||||
-rw-r--r-- | docs/source/markdown/podman-save.1.md (renamed from docs/podman-save.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-search.1.md (renamed from docs/podman-search.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-start.1.md (renamed from docs/podman-start.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-stats.1.md (renamed from docs/podman-stats.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-stop.1.md (renamed from docs/podman-stop.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-system-df.1.md (renamed from docs/podman-system-df.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-system-migrate.1.md (renamed from docs/podman-system-migrate.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-system-prune.1.md (renamed from docs/podman-system-prune.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-system-renumber.1.md (renamed from docs/podman-system-renumber.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-system.1.md (renamed from docs/podman-system.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-tag.1.md (renamed from docs/podman-tag.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-top.1.md (renamed from docs/podman-top.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-umount.1.md (renamed from docs/podman-umount.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-unpause.1.md (renamed from docs/podman-unpause.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-unshare.1.md (renamed from docs/podman-unshare.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-varlink.1.md (renamed from docs/podman-varlink.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-version.1.md (renamed from docs/podman-version.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-volume-create.1.md (renamed from docs/podman-volume-create.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-volume-inspect.1.md (renamed from docs/podman-volume-inspect.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-volume-ls.1.md (renamed from docs/podman-volume-ls.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-volume-prune.1.md (renamed from docs/podman-volume-prune.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-volume-rm.1.md (renamed from docs/podman-volume-rm.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-volume.1.md (renamed from docs/podman-volume.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman-wait.1.md (renamed from docs/podman-wait.1.md) | 0 | ||||
-rw-r--r-- | docs/source/markdown/podman.1.md (renamed from docs/podman.1.md) | 0 | ||||
-rw-r--r-- | docs/source/network.rst | 10 | ||||
-rw-r--r-- | docs/source/play.rst | 4 | ||||
-rw-r--r-- | docs/source/pod.rst | 30 | ||||
-rw-r--r-- | docs/source/system.rst | 12 | ||||
-rw-r--r-- | docs/source/volume.rst | 11 | ||||
-rw-r--r-- | go.mod | 6 | ||||
-rw-r--r-- | go.sum | 22 | ||||
-rwxr-xr-x | hack/man-page-checker | 2 | ||||
-rwxr-xr-x | hack/podman-commands.sh | 6 | ||||
-rw-r--r-- | install.md | 2 | ||||
-rw-r--r-- | libpod/boltdb_state.go | 5 | ||||
-rw-r--r-- | libpod/common_test.go | 3 | ||||
-rw-r--r-- | libpod/config/config.go | 549 | ||||
-rw-r--r-- | libpod/config/config_test.go | 64 | ||||
-rw-r--r-- | libpod/config/default.go | 137 | ||||
-rw-r--r-- | libpod/config/merge.go | 183 | ||||
-rw-r--r-- | libpod/config/merge_test.go | 157 | ||||
-rw-r--r-- | libpod/config/testdata/empty.conf | 0 | ||||
l--------- | libpod/config/testdata/libpod.conf | 1 | ||||
-rw-r--r-- | libpod/container.go | 4 | ||||
-rw-r--r-- | libpod/container_api.go | 3 | ||||
-rw-r--r-- | libpod/container_inspect.go | 4 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 6 | ||||
-rw-r--r-- | libpod/container_log_linux.go | 9 | ||||
-rw-r--r-- | libpod/define/config.go | 18 | ||||
-rw-r--r-- | libpod/define/runtime.go | 37 | ||||
-rw-r--r-- | libpod/healthcheck.go | 4 | ||||
-rw-r--r-- | libpod/image/pull.go | 8 | ||||
-rw-r--r-- | libpod/in_memory_state.go | 5 | ||||
-rw-r--r-- | libpod/logs/log.go | 6 | ||||
-rw-r--r-- | libpod/networking_linux.go | 2 | ||||
-rw-r--r-- | libpod/oci_attach_linux.go | 2 | ||||
-rw-r--r-- | libpod/oci_conmon_linux.go | 13 | ||||
-rw-r--r-- | libpod/oci_conmon_unsupported.go | 3 | ||||
-rw-r--r-- | libpod/oci_util.go | 26 | ||||
-rw-r--r-- | libpod/options.go | 24 | ||||
-rw-r--r-- | libpod/pod_internal.go | 4 | ||||
-rw-r--r-- | libpod/runtime.go | 828 | ||||
-rw-r--r-- | libpod/runtime_ctr.go | 6 | ||||
-rw-r--r-- | libpod/runtime_pod_linux.go | 10 | ||||
-rw-r--r-- | libpod/state.go | 13 | ||||
-rw-r--r-- | libpod/state_test.go | 3 | ||||
-rw-r--r-- | libpod/stats.go | 24 | ||||
-rw-r--r-- | libpod/util.go | 20 | ||||
-rw-r--r-- | logo/podman-logo-source.svg | 10 | ||||
-rw-r--r-- | logo/podman-logo.png | bin | 37056 -> 37991 bytes | |||
-rw-r--r-- | pkg/adapter/containers.go | 39 | ||||
-rw-r--r-- | pkg/adapter/pods.go | 18 | ||||
-rw-r--r-- | pkg/adapter/runtime.go | 2 | ||||
-rw-r--r-- | pkg/adapter/terminal_linux.go | 3 | ||||
-rw-r--r-- | pkg/cgroups/cpu.go | 4 | ||||
-rw-r--r-- | pkg/namespaces/namespaces.go | 5 | ||||
-rw-r--r-- | pkg/rootless/rootless_linux.c | 14 | ||||
-rw-r--r-- | pkg/spec/spec.go | 21 | ||||
-rw-r--r-- | pkg/util/utils.go | 14 | ||||
-rw-r--r-- | pkg/varlinkapi/attach.go | 2 | ||||
-rw-r--r-- | pkg/varlinkapi/containers.go | 8 | ||||
-rw-r--r-- | rootless.md | 15 | ||||
-rw-r--r-- | test/e2e/logs_test.go | 12 | ||||
-rw-r--r-- | test/e2e/run_cgroup_parent_test.go | 6 | ||||
-rw-r--r-- | test/e2e/run_selinux_test.go | 2 | ||||
-rw-r--r-- | test/e2e/start_test.go | 21 | ||||
-rw-r--r-- | test/e2e/test.yaml | 34 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/.cirrus.yml | 30 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/.golangci.yml | 1 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/.papr.sh | 1 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/.papr.yml | 1 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/.travis.yml | 16 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/CHANGELOG.md | 22 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/Makefile | 7 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/buildah.go | 2 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/go.mod | 2 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/go.sum | 2 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/install.md | 15 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/ostree_tag.sh | 6 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/pkg/cli/common.go | 5 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/pkg/secrets/secrets.go | 10 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/run_linux.go | 2 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/troubleshooting.md | 6 | ||||
-rw-r--r-- | vendor/github.com/containers/buildah/util.go | 28 | ||||
-rw-r--r-- | vendor/github.com/onsi/ginkgo/.travis.yml | 3 | ||||
-rw-r--r-- | vendor/github.com/onsi/ginkgo/CHANGELOG.md | 22 | ||||
-rw-r--r-- | vendor/github.com/onsi/ginkgo/config/config.go | 9 | ||||
-rw-r--r-- | vendor/github.com/onsi/ginkgo/extensions/table/table_entry.go | 13 | ||||
-rw-r--r-- | vendor/github.com/onsi/ginkgo/ginkgo/run_command.go | 17 | ||||
-rw-r--r-- | vendor/github.com/onsi/ginkgo/ginkgo_dsl.go | 5 | ||||
-rw-r--r-- | vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go | 21 | ||||
-rw-r--r-- | vendor/gopkg.in/yaml.v2/decode.go | 14 | ||||
-rw-r--r-- | vendor/modules.txt | 6 | ||||
-rw-r--r-- | version/version.go | 2 |
273 files changed, 2166 insertions, 1582 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 0713f6dda..145e49457 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -32,7 +32,7 @@ env: ### _BUILT_IMAGE_SUFFIX: "libpod-5642998972416000" FEDORA_CACHE_IMAGE_NAME: "fedora-30-${_BUILT_IMAGE_SUFFIX}" - PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-29-${_BUILT_IMAGE_SUFFIX}" + PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-30-${_BUILT_IMAGE_SUFFIX}" SPECIAL_FEDORA_CACHE_IMAGE_NAME: "xfedora-30-${_BUILT_IMAGE_SUFFIX}" UBUNTU_CACHE_IMAGE_NAME: "ubuntu-19-${_BUILT_IMAGE_SUFFIX}" PRIOR_UBUNTU_CACHE_IMAGE_NAME: "ubuntu-18-${_BUILT_IMAGE_SUFFIX}" @@ -136,7 +136,9 @@ gating_task: # in sync at all times. vendor_task: - only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + only_if: >- + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' depends_on: - "gating" @@ -166,7 +168,9 @@ vendor_task: # whether the git tree is clean. varlink_api_task: - only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + only_if: >- + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' depends_on: - "gating" @@ -201,8 +205,10 @@ build_each_commit_task: - "vendor" - "varlink_api" - only_if: $CIRRUS_BRANCH != $DEST_BRANCH && - $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + only_if: >- + $CIRRUS_BRANCH != $DEST_BRANCH && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' gce_instance: image_project: "libpod-218412" @@ -232,8 +238,10 @@ build_without_cgo_task: - "vendor" - "varlink_api" - only_if: $CIRRUS_BRANCH != $DEST_BRANCH && - $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + only_if: >- + $CIRRUS_BRANCH != $DEST_BRANCH && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' gce_instance: image_project: "libpod-218412" @@ -326,12 +334,14 @@ testing_task: - "build_without_cgo" # Only test build cache-images, if that's what's requested - only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + only_if: >- + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' gce_instance: matrix: # Images are generated separately, from build_images_task (below) - image_name: "${FEDORA_CACHE_IMAGE_NAME}" + #image_name: "${FEDORA_CACHE_IMAGE_NAME}" image_name: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" # Multiple test failures on Ubuntu 19 - Fixes TBD in future PR # TODO: image_name: "${UBUNTU_CACHE_IMAGE_NAME}" @@ -381,7 +391,9 @@ special_testing_rootless_task: - "build_each_commit" - "build_without_cgo" - only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + only_if: >- + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' env: ADD_SECOND_PARTITION: true @@ -413,7 +425,9 @@ special_testing_in_podman_task: - "build_each_commit" - "build_without_cgo" - only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + only_if: >- + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' env: ADD_SECOND_PARTITION: true @@ -439,7 +453,9 @@ special_testing_cross_task: - "varlink_api" - "vendor" - only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + only_if: >- + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' env: matrix: @@ -473,7 +489,9 @@ special_testing_cgroupv2_task: - "varlink_api" - "vendor" - only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + only_if: >- + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' gce_instance: image_name: "${SPECIAL_FEDORA_CACHE_IMAGE_NAME}" @@ -503,7 +521,9 @@ special_testing_endpoint_task: - "varlink_api" - "vendor" - only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + only_if: >- + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' env: SPECIALMODE: 'endpoint' # See docs @@ -525,7 +545,9 @@ test_building_snap_task: depends_on: - "gating" - only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + only_if: >- + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:IMG.*' && + $CIRRUS_CHANGE_MESSAGE !=~ '.*CI:DOCS.*' container: image: yakshaveinc/snapcraft:core18 @@ -539,7 +561,7 @@ test_build_cache_images_task: only_if: >- $CIRRUS_BRANCH != $DEST_BRANCH && - $CIRRUS_CHANGE_MESSAGE =~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + $CIRRUS_CHANGE_MESSAGE =~ '.*CI:IMG.*' depends_on: - "gating" @@ -571,7 +593,7 @@ verify_test_built_images_task: only_if: >- $CIRRUS_BRANCH != $DEST_BRANCH && - $CIRRUS_CHANGE_MESSAGE =~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + $CIRRUS_CHANGE_MESSAGE =~ '.*CI:IMG.*' depends_on: @@ -589,8 +611,8 @@ verify_test_built_images_task: TEST_REMOTE_CLIENT: false matrix: # Required env. var. by check_image_script - PACKER_BUILDER_NAME: "fedora-29" PACKER_BUILDER_NAME: "fedora-30" + #PACKER_BUILDER_NAME: "fedora-31" PACKER_BUILDER_NAME: "xfedora-30" PACKER_BUILDER_NAME: "ubuntu-18" # TODO support $UBUNTU_CACHE_IMAGE_NAME: PACKER_BUILDER_NAME: "ubuntu-19" @@ -638,6 +660,26 @@ upload_snap_task: - 'cd contrib/snapcraft && snapcraft && snapcraft push *.snap --release edge' +test_docs_task: + + only_if: >- + $CIRRUS_BRANCH != $DEST_BRANCH && + $CIRRUS_CHANGE_MESSAGE =~ '.*CI:DOCS.*' + depends_on: + - "gating" + - "vendor" + #- "test_docs" + #- "varlink_api" + #- "build_each_commit" + stub_script: '/bin/true' + + +#publish_docs_task: +# +# only_if: $CIRRUS_BRANCH == $DEST_BRANCH && +# $CIRRUS_TAG =~ '^v[0-9]\.[0-9]\.[0-9]$' + + # Post message to IRC if everything passed PR testing success_task: @@ -664,6 +706,7 @@ success_task: - "test_building_snap" - "upload_snap" - "verify_test_built_images" + - "test_docs" env: CIRRUS_WORKING_DIR: "/usr/src/libpod" diff --git a/.gitignore b/.gitignore index 598384582..54b63518f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /docs/*.[158] /docs/*.[158].gz /docs/remote +/docs/build/ *.o *.orig /pause/pause.o @@ -25,3 +26,4 @@ release.txt podman-remote*.zip podman*.tar.gz .idea* +.vscode* @@ -3,7 +3,7 @@ export GOPROXY=https://proxy.golang.org GO ?= go DESTDIR ?= -EPOCH_TEST_COMMIT ?= 2b0892e757c878cdb087dd22b8986bccef0276ed +EPOCH_TEST_COMMIT ?= ac73fd3fe5dcbf2647d589f9c9f37fe9531ed663 HEAD ?= HEAD CHANGELOG_BASE ?= HEAD~ CHANGELOG_TARGET ?= HEAD @@ -73,8 +73,8 @@ ASMFLAGS ?= all=-trimpath=${PWD} LDFLAGS_PODMAN ?= $(LDFLAGS) \ -X $(LIBPOD)/define.gitCommit=$(GIT_COMMIT) \ -X $(LIBPOD)/define.buildInfo=$(BUILD_INFO) \ - -X $(LIBPOD).installPrefix=$(PREFIX) \ - -X $(LIBPOD).etcDir=$(ETCDIR) + -X $(LIBPOD)/config._installPrefix=$(PREFIX) \ + -X $(LIBPOD)/config._etcDir=$(ETCDIR) #Update to LIBSECCOMP_COMMIT should reflect in Dockerfile too. LIBSECCOMP_COMMIT := release-2.3 # Rarely if ever should integration tests take more than 50min, @@ -167,13 +167,11 @@ podman-remote: .gopathok $(PODMAN_VARLINK_DEPENDENCIES) ## Build with podman on $(GO_BUILD) $(BUILDFLAGS) -gcflags '$(GCFLAGS)' -asmflags '$(ASMFLAGS)' -ldflags '$(LDFLAGS_PODMAN)' -tags "$(BUILDTAGS) remoteclient" -o bin/$@ $(PROJECT)/cmd/podman .PHONY: podman.msi -podman.msi: podman-remote podman-remote-windows docs ## Will always rebuild exe as there is no podman-remote-windows.exe target to verify timestamp - rm -rf bin/windows - mkdir -p bin/windows - docs/podman-remote.sh windows bin/windows docs - find bin/windows -print \ - |wixl-heat --var var.ManSourceDir --component-group ManFiles --directory-ref INSTALLDIR --prefix bin/windows/ >bin/windows/pages.wsx - wixl -D VERSION=$(RELEASE_NUMBER) -D ManSourceDir=bin/windows -o podman-v$(RELEASE_NUMBER).msi contrib/msi/podman.wxs bin/windows/pages.wsx +podman.msi: podman-remote podman-remote-windows install-podman-remote-windows-docs ## Will always rebuild exe as there is no podman-remote-windows.exe target to verify timestamp + $(eval DOCFILE := docs/build/remote/windows) + find $(DOCFILE) -print \ + |wixl-heat --var var.ManSourceDir --component-group ManFiles --directory-ref INSTALLDIR --prefix $(DOCFILE)/ >$(DOCFILE)/pages.wsx + wixl -D VERSION=$(RELEASE_NUMBER) -D ManSourceDir=$(DOCFILE) -o podman-v$(RELEASE_NUMBER).msi contrib/msi/podman.wxs $(DOCFILE)/pages.wsx podman-remote-%: .gopathok $(PODMAN_VARLINK_DEPENDENCIES) ## Build podman for a specific GOOS $(eval BINSFX := $(shell test "$*" != "windows" || echo ".exe")) @@ -196,7 +194,6 @@ clean: ## Clean artifacts $(wildcard podman*.tar.gz) \ bin \ build \ - docs/remote \ test/checkseccomp/checkseccomp \ test/goecho/goecho \ test/testdata/redis-image \ @@ -205,9 +202,7 @@ clean: ## Clean artifacts libpod/pod_ffjson.go \ libpod/container_easyjson.go \ libpod/pod_easyjson.go \ - $(MANPAGES) ||: - find . -name \*~ -delete - find . -name \#\* -delete + docs/build libpodimage: ## Build the libpod image ${CONTAINER_RUNTIME} build -t ${LIBPOD_IMAGE} . @@ -312,20 +307,26 @@ install.catatonit: test-binaries: test/checkseccomp/checkseccomp test/goecho/goecho install.catatonit -MANPAGES_MD ?= $(wildcard docs/*.md pkg/*/docs/*.md) +MANPAGES_MD ?= $(wildcard docs/source/markdown/*.md pkg/*/docs/*.md) MANPAGES ?= $(MANPAGES_MD:%.md=%) +MANPAGES_DEST ?= $(subst markdown,man, $(subst source,build,$(MANPAGES))) $(MANPAGES): %: %.md .gopathok - @sed -e 's/\((podman.*\.md)\)//' -e 's/\[\(podman.*\)\]/\1/' $< | $(GOMD2MAN) -in /dev/stdin -out $@ + @sed -e 's/\((podman.*\.md)\)//' -e 's/\[\(podman.*\)\]/\1/' $< | $(GOMD2MAN) -in /dev/stdin -out $(subst source/markdown,build/man,$@) -docs: $(MANPAGES) ## Generate documentation +docdir: + mkdir -p docs/build/man -install-podman-remote-docs: podman-remote docs - rm -rf docs/remote - docs/podman-remote.sh darwin docs/remote docs +docs: docdir $(MANPAGES) ## Generate documentation + +install-podman-remote-%-docs: podman-remote docs $(MANPAGES) + rm -rf docs/build/remote + mkdir -p docs/build/remote + ln -sf $(shell pwd)/docs/source/markdown/links docs/build/man/ + docs/remote-docs.sh $* docs/build/remote/$* $(if $(findstring windows,$*),docs/source/markdown,docs/build/man) man-page-check: - ./hack/man-page-checker + hack/man-page-checker # When publishing releases include critical build-time details .PHONY: release.txt @@ -349,7 +350,7 @@ podman-v$(RELEASE_NUMBER).tar.gz: binaries docs release.txt # Must call make in-line: Dependency-spec. w/ wild-card also consumes variable value. podman-remote-v$(RELEASE_NUMBER)-%.zip: - $(MAKE) podman-remote-$* install-podman-remote-docs release.txt \ + $(MAKE) podman-remote-$* install-podman-remote-$*-docs release.txt \ RELEASE_BASENAME=$(shell hack/get_release_info.sh REMOTENAME) \ RELEASE_DIST=$* RELEASE_DIST_VER="-" $(eval TMPDIR := $(shell mktemp -d -p '' $podman_remote_XXXX)) @@ -359,13 +360,7 @@ podman-remote-v$(RELEASE_NUMBER)-%.zip: # release.txt location and content depended upon by automated tooling cp release.txt "$(TMPDIR)/" cp ./bin/podman-remote-$*$(BINSFX) "$(TMPDIR)/$(SUBDIR)/podman$(BINSFX)" - cp -r ./docs/remote "$(TMPDIR)/$(SUBDIR)/docs/" - $(eval DOCFILE := $(TMPDIR)/$(SUBDIR)/docs/podman.1) - cp docs/podman-remote.1 "$(DOCFILE)" - sed -i 's/podman\\*-remote/podman/g' "$(DOCFILE)" - sed -i 's/Podman\\*-remote/Podman\ for\ $*/g' "$(DOCFILE)" - sed -i 's/podman\.conf/podman\-remote\.conf/g' "$(DOCFILE)" - sed -i 's/A\ remote\ CLI\ for\ Podman\:\ //g' "$(DOCFILE)" + cp -r ./docs/build/remote/$* "$(TMPDIR)/$(SUBDIR)/docs/" cd "$(TMPDIR)" && \ zip --recurse-paths "$(CURDIR)/$@" "./release.txt" "./" -rm -rf "$(TMPDIR)" @@ -381,7 +376,7 @@ podman-remote-%-release: $(MAKE) podman-remote-v$(RELEASE_NUMBER)-$*.zip docker-docs: docs - (cd docs; ./dckrman.sh *.1) + (cd docs; ./dckrman.sh ./build/man/*.1) changelog: ## Generate changelog @echo "Creating changelog from $(CHANGELOG_BASE) to $(CHANGELOG_TARGET)" @@ -408,9 +403,9 @@ install.bin: podman install.man: docs install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(MANDIR)/man1 install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(MANDIR)/man5 - install ${SELINUXOPT} -m 644 $(filter %.1,$(MANPAGES)) -t $(DESTDIR)$(MANDIR)/man1 - install ${SELINUXOPT} -m 644 $(filter %.5,$(MANPAGES)) -t $(DESTDIR)$(MANDIR)/man5 - install ${SELINUXOPT} -m 644 docs/links/*1 -t $(DESTDIR)$(MANDIR)/man1 + install ${SELINUXOPT} -m 644 $(filter %.1,$(MANPAGES_DEST)) -t $(DESTDIR)$(MANDIR)/man1 + install ${SELINUXOPT} -m 644 $(filter %.5,$(MANPAGES_DEST)) -t $(DESTDIR)$(MANDIR)/man5 + install ${SELINUXOPT} -m 644 docs/source/markdown/links/*1 -t $(DESTDIR)$(MANDIR)/man1 install.config: install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(SHAREDIR_CONTAINERS) @@ -430,7 +425,7 @@ install.cni: install.docker: docker-docs install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man1 install ${SELINUXOPT} -m 755 docker $(DESTDIR)$(BINDIR)/docker - install ${SELINUXOPT} -m 644 docs/docker*.1 -t $(DESTDIR)$(MANDIR)/man1 + install ${SELINUXOPT} -m 644 docs/build/man/docker*.1 -t $(DESTDIR)$(MANDIR)/man1 install.systemd: install ${SELINUXOPT} -m 755 -d ${DESTDIR}${SYSTEMDDIR} ${DESTDIR}${USERSYSTEMDDIR} ${DESTDIR}${TMPFILESDIR} @@ -444,16 +439,16 @@ install.systemd: install ${SELINUXOPT} -m 644 contrib/varlink/podman.conf ${DESTDIR}${TMPFILESDIR}/podman.conf uninstall: - for i in $(filter %.1,$(MANPAGES)); do \ + for i in $(filter %.1,$(MANPAGES_DEST)); do \ rm -f $(DESTDIR)$(MANDIR)/man1/$$(basename $${i}); \ done; \ - for i in $(filter %.5,$(MANPAGES)); do \ + for i in $(filter %.5,$(MANPAGES_DEST)); do \ rm -f $(DESTDIR)$(MANDIR)/man5/$$(basename $${i}); \ done .PHONY: .gitvalidation .gitvalidation: .gopathok - GIT_CHECK_EXCLUDE="./vendor:docs/rtd/make.bat" $(GOBIN)/git-validation -v -run DCO,short-subject,dangling-whitespace -range $(EPOCH_TEST_COMMIT)..$(HEAD) + GIT_CHECK_EXCLUDE="./vendor:docs/make.bat" $(GOBIN)/git-validation -v -run DCO,short-subject,dangling-whitespace -range $(EPOCH_TEST_COMMIT)..$(HEAD) .PHONY: install.tools install.tools: .install.gitvalidation .install.gometalinter .install.md2man .install.ginkgo .install.golangci-lint ## Install needed tools @@ -5,7 +5,7 @@ Libpod provides a library for applications looking to use the Container Pod concept, popularized by Kubernetes. Libpod also contains the Pod Manager tool `(Podman)`. Podman manages pods, containers, container images, and container volumes. -* [Latest Version: 1.6.2](https://github.com/containers/libpod/releases/latest) +* [Latest Version: 1.6.3](https://github.com/containers/libpod/releases/latest) * [Continuous Integration:](contrib/cirrus/README.md) [![Build Status](https://api.cirrus-ci.com/github/containers/libpod.svg)](https://cirrus-ci.com/github/containers/libpod/master) * [GoDoc: ![GoDoc](https://godoc.org/github.com/containers/libpod/libpod?status.svg)](https://godoc.org/github.com/containers/libpod/libpod) * Automated continuous release downloads (including remote-client): @@ -106,7 +106,7 @@ Information on how Podman configures [OCI Hooks][spec-hooks] to run when launchi **[Podman API](API.md)** Documentation on the Podman API using [Varlink](https://www.varlink.org/). -**[Podman Commands](commands.md)** +**[Podman Commands](https://podman.readthedocs.io/en/latest/Commands.html)** A list of the Podman commands with links to their man pages and in many cases videos showing the commands in use. diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 235871273..cefad25f4 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,34 @@ # Release Notes +## 1.6.3 +### Features +- Handling of the `libpod.conf` configuration file has seen major changes. Most significantly, rootless users will no longer automatically receive a complete configuration file when they first use Podman, and will instead only receive differences from the global configuration. +- Initial support for the CNI DNS plugin, which allows containers to resolve the IPs of other containers via DNS name, has been added +- Podman now supports anonymous named volumes, created by specifying only a destination to the `-v` flag to the `podman create` and `podman run` commands +- Named volumes now support `uid` and `gid` options in `--opt o=...` to set UID and GID of the created volume + +### Bugfixes +- Fixed a bug where the `podman start` command would print container ID, instead of name, when starting containers given their name +- Fixed a bug where named volumes with options did not properly detect issues with mounting the volume, leading to an inconsistent state ([#4303](https://github.com/containers/libpod/issues/4303)) +- Fixed a bug where incorrect Seccomp profiles were used in containers generated by `podman play kube` +- Fixed a bug where processes started by `podman exec` would have the wrong SELinux label in some circumstances ([#4361](https://github.com/containers/libpod/issues/4361)) +- Fixed a bug where error messages from `slirp4netns` would be lost +- Fixed a bug where `podman run --network=$NAME` would not throw an error in rootless Podman, where CNI networks are not supported +- Fixed a bug where `podman network create` would throw confusing errors when trying to create a volume with a name that already exists +- Fixed a bug where Podman would not error if the `systemd` CGroup manager was specified, but systemd could not be contacted over DBus +- Fixed a bug where image volumes were mounted `noexec` ([#4318](https://github.com/containers/libpod/issues/4318)) +- Fixed a bug where the `podman stats` command required the name of a container to be given, instead of showing all containers when no container was specified ([#4274](https://github.com/containers/libpod/issues/4274)) +- Fixed a bug where the `podman volume inspect` command would not show the options that named volumes were created with +- Fixed a bug where custom storage configuration was not written to `storage.conf` at time of first creation for rootless Podman ([#2659](https://github.com/containers/libpod/issues/2659)) +- Fixed a bug where remote Podman did not support shell redirection of container output + +### Misc +- Updated vendored containers/image library to v5.0 +- Initial support for images using manifest lists has been added, though commands for directly interacting with manifests are still missing +- Support for pushing to and pulling from OSTree has been removed due to deprecation in the containers/image library +- Rootless Podman no longer enables linger on systems with systemd as init by default. As such, containers will now be killed when the user who ran them logs out, unless linger is explicitly enabled using [loginctl](https://www.freedesktop.org/software/systemd/man/loginctl.html) +- Podman will now check the version of `conmon` that is in use to ensure it is sufficient + ## 1.6.2 ### Features - Added a `--runtime` flag to `podman system migrate` to allow the OCI runtime for all containers to be reset, to ease transition to the `crun` runtime on CGroups V2 systems until `runc` gains full support diff --git a/cmd/podman/build.go b/cmd/podman/build.go index e9ebc50aa..bbc1d5b5f 100644 --- a/cmd/podman/build.go +++ b/cmd/podman/build.go @@ -11,7 +11,7 @@ import ( buildahcli "github.com/containers/buildah/pkg/cli" "github.com/containers/image/v5/types" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/adapter" "github.com/docker/go-units" "github.com/opencontainers/runtime-spec/specs-go" @@ -238,6 +238,9 @@ func buildCmd(c *cliconfig.BuildValues) error { if contextDir == "" { return errors.Errorf("no context directory specified, and no containerfile specified") } + if !fileIsDir(contextDir) { + return errors.Errorf("context must be a directory: %v", contextDir) + } if len(containerfiles) == 0 { if checkIfFileExists(filepath.Join(contextDir, "Containerfile")) { containerfiles = append(containerfiles, filepath.Join(contextDir, "Containerfile")) @@ -260,7 +263,7 @@ func buildCmd(c *cliconfig.BuildValues) error { if err != nil { return err } - if conf != nil && conf.CgroupManager == libpod.SystemdCgroupsManager { + if conf != nil && conf.CgroupManager == define.SystemdCgroupsManager { runtimeFlags = append(runtimeFlags, "--systemd-cgroup") } // end from buildah diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go index 1bb5fa30c..58d67ddc1 100644 --- a/cmd/podman/cliconfig/config.go +++ b/cmd/podman/cliconfig/config.go @@ -251,7 +251,7 @@ type LogsValues struct { Details bool Follow bool Since string - Tail uint64 + Tail int64 Timestamps bool Latest bool } diff --git a/cmd/podman/common.go b/cmd/podman/common.go index 33a848553..37511641b 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -132,7 +132,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "Drop capabilities from the container", ) createFlags.String( - "cgroupns", "host", + "cgroupns", "", "cgroup namespace to use", ) createFlags.String( diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go index 75a23afd6..c53a97df3 100644 --- a/cmd/podman/cp.go +++ b/cmd/podman/cp.go @@ -257,8 +257,15 @@ func parsePath(runtime *libpod.Runtime, path string) (*libpod.Container, string) return nil, path } +func evalSymlinks(path string) (string, error) { + if path == os.Stdin.Name() { + return path, nil + } + return filepath.EvalSymlinks(path) +} + func getPathInfo(path string) (string, os.FileInfo, error) { - path, err := filepath.EvalSymlinks(path) + path, err := evalSymlinks(path) if err != nil { return "", nil, errors.Wrapf(err, "error evaluating symlinks %q", path) } @@ -270,7 +277,7 @@ func getPathInfo(path string) (string, os.FileInfo, error) { } func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, chownOpts *idtools.IDPair, extract, isFromHostToCtr bool) error { - srcPath, err := filepath.EvalSymlinks(src) + srcPath, err := evalSymlinks(src) if err != nil { return errors.Wrapf(err, "error evaluating symlinks %q", srcPath) } diff --git a/cmd/podman/logs.go b/cmd/podman/logs.go index 32605389e..a2594b5bf 100644 --- a/cmd/podman/logs.go +++ b/cmd/podman/logs.go @@ -52,7 +52,7 @@ func init() { flags.BoolVarP(&logsCommand.Follow, "follow", "f", false, "Follow log output. The default is false") flags.BoolVarP(&logsCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.StringVar(&logsCommand.Since, "since", "", "Show logs since TIMESTAMP") - flags.Uint64Var(&logsCommand.Tail, "tail", 0, "Output the specified number of LINES at the end of the logs. Defaults to 0, which prints all lines") + flags.Int64Var(&logsCommand.Tail, "tail", -1, "Output the specified number of LINES at the end of the logs. Defaults to -1, which prints all lines") flags.BoolVarP(&logsCommand.Timestamps, "timestamps", "t", false, "Output the timestamps in the log") markFlagHidden(flags, "details") flags.SetInterspersed(false) diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go index 202d93b35..f630f1210 100644 --- a/cmd/podman/main_local.go +++ b/cmd/podman/main_local.go @@ -16,7 +16,7 @@ import ( "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/libpodruntime" - "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/cgroups" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/tracing" @@ -32,10 +32,7 @@ import ( const remote = false func init() { - cgroupManager := libpod.SystemdCgroupsManager - if runtimeConfig, err := libpod.DefaultRuntimeConfig(); err == nil { - cgroupManager = runtimeConfig.CgroupManager - } + cgroupManager := define.SystemdCgroupsManager cgroupHelp := "Cgroup manager to use (cgroupfs or systemd)" cgroupv2, _ := cgroups.IsCgroup2UnifiedMode() if rootless.IsRootless() && !cgroupv2 { @@ -181,7 +178,7 @@ func setupRootless(cmd *cobra.Command, args []string) error { if !ownsCgroup { unitName := fmt.Sprintf("podman-%d.scope", os.Getpid()) if err := utils.RunUnderSystemdScope(os.Getpid(), "user.slice", unitName); err != nil { - if conf.CgroupManager == libpod.SystemdCgroupsManager { + if conf.CgroupManager == define.SystemdCgroupsManager { logrus.Warnf("Failed to add podman to systemd sandbox cgroup: %v", err) } else { logrus.Debugf("Failed to add podman to systemd sandbox cgroup: %v", err) @@ -225,7 +222,7 @@ func setupRootless(cmd *cobra.Command, args []string) error { if err != nil { return err } - if conf.CgroupManager == libpod.SystemdCgroupsManager { + if conf.CgroupManager == define.SystemdCgroupsManager { logrus.Warnf("Failed to add pause process to systemd sandbox cgroup: %v", err) } else { logrus.Debugf("Failed to add pause process to systemd sandbox cgroup: %v", err) diff --git a/cmd/podman/utils.go b/cmd/podman/utils.go index 592d7a1d1..21389b43a 100644 --- a/cmd/podman/utils.go +++ b/cmd/podman/utils.go @@ -68,8 +68,19 @@ func aliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName { // Check if a file exists and is not a directory func checkIfFileExists(name string) bool { file, err := os.Stat(name) - if os.IsNotExist(err) { + // All errors return file == nil + if err != nil { return false } return !file.IsDir() } + +// Check if a file is or is not a directory +func fileIsDir(name string) bool { + file, err := os.Stat(name) + // All errors return file == nil + if err != nil { + return false + } + return file.IsDir() +} diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in index 8e0cb9950..33ecc8eba 100644 --- a/contrib/spec/podman.spec.in +++ b/contrib/spec/podman.spec.in @@ -39,7 +39,7 @@ %global shortcommit_conmon %(c=%{commit_conmon}; echo ${c:0:7}) Name: podman -Version: 1.6.3 +Version: 1.6.4 Release: #COMMITDATE#.git%{shortcommit0}%{?dist} Summary: Manage Pods, Containers and Container Images License: ASL 2.0 diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 000000000..fb67e266c --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,23 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +clean: + rm -fr build/ + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/Readme.md b/docs/Readme.md new file mode 100644 index 000000000..4514afa77 --- /dev/null +++ b/docs/Readme.md @@ -0,0 +1,21 @@ +# Build the Docs + +## Directory Structure + +| | Directory | +| ------------------------------------ | --------------------------- | +| Markdown source for man pages | docs/source/markdown/ | +| man pages aliases as .so files | docs/source/markdown/links/ | +| restructured text for readthedocs.io | docs/rst/ | +| target for output | docs/build | +| man pages | docs/build/man | +| remote linux man pages | docs/build/remote/linux | +| remote darwin man pages | docs/build/remote/darwin | +| remote windows html pages | docs/build/remote/windows | + +## Support files + +| | | +| ------------------------------------ | --------------------------- | +| docs/remote-docs.sh | Read the docs/source/markdown files and format for each platform | +| docs/links-to-html.lua | pandoc filter to do aliases for html files |
\ No newline at end of file diff --git a/docs/rtd/make.bat b/docs/make.bat index 6247f7e23..6247f7e23 100644 --- a/docs/rtd/make.bat +++ b/docs/make.bat diff --git a/docs/podman-remote.sh b/docs/remote-docs.sh index 2f8e76d1b..1440b0926 100755 --- a/docs/podman-remote.sh +++ b/docs/remote-docs.sh @@ -1,17 +1,17 @@ #!/bin/bash -e # Assemble remote man pages for darwin or windows from markdown files -PLATFORM=$1 ## windows or darwin -TARGET=$2 ## where to output files +PLATFORM=$1 ## linux, windows or darwin +TARGET=${2} ## where to output files SOURCES=${@:3} ## directories to find markdown files PODMAN=${PODMAN:-bin/podman-remote} ## location overridden for testing function usage() { echo >&2 "$0 PLATFORM TARGET SOURCES..." - echo >&2 "PLATFORM: Is either darwin or windows." - echo >&2 "TARGET: Is the directory where files will be staged." - echo >&2 "SOURCES: Are the directories to source markdown files." + echo >&2 "PLATFORM: Is either linux, darwin or windows." + echo >&2 "TARGET: Is the directory where files will be staged. eg, docs/build/remote/linux" + echo >&2 "SOURCES: Are the directories of source files. eg, docs/markdown" } function fail() { @@ -21,19 +21,17 @@ function fail() { } case $PLATFORM in -'darwin') - EXT=1 - PUBLISHER=darwin_fn +darwin|linux) + PUBLISHER=man_fn ;; -'windows') - EXT=1.md - PUBLISHER=windows_fn +windows) + PUBLISHER=html_fn ;; -'-help') +-help) usage exit 0 ;; -*) fail '"darwin" and "windows" are currently the only supported platforms.' ;; +*) fail '"linux", "darwin" and "windows" are the only supported platforms.' ;; esac if [[ -z $TARGET ]]; then @@ -48,20 +46,20 @@ if [[ ! -x $PODMAN ]]; then fail "$PODMAN does not exist" fi -## darwin_fn copies the markdown page or link to flattened directory -function darwin_fn() { - local markdown=$1 - local file=$(basename $markdown) - local dir=$(dirname $markdown) +## man_fn copies the man page or link to flattened directory +function man_fn() { + local page=$1 + local file=$(basename $page) + local dir=$(dirname $page) - if [[ -f $dir/links/$file ]]; then - markdown=$dir/links/$file + if [[ ! -f $page ]]; then + page=$dir/links/${file%.*}.1 fi - install $markdown $TARGET + install $page $TARGET/${file%%.*}.1 } -## windows_fn converts the markdown page or link to HTML -function windows_fn() { +## html_fn converts the markdown page or link to HTML +function html_fn() { local markdown=$1 local file=$(basename $markdown) local dir=$(dirname $markdown) @@ -70,21 +68,26 @@ function windows_fn() { local link=$(sed -e 's?.so man1/\(.*\)?\1?' <$dir/links/${file%.md}) markdown=$dir/$link.md fi - pandoc --ascii --lua-filter=$dir/links-to-html.lua -o $TARGET/${file%.$EXT}.html $markdown + pandoc --ascii --lua-filter=docs/links-to-html.lua -o $TARGET/${file%%.*}.html $markdown } ## pub_pages finds and publishes the remote manual pages function pub_pages() { local source=$1 local publisher=$2 - for f in $(ls $source/podman-remote*$EXT); do + for f in $(ls $source/podman-remote*); do $publisher $f done + # rename podman-remote.ext to podman.ext and copy + local remote=$(echo $TARGET/podman-remote.*) + local ext=${remote##*.} + cp -f $remote $TARGET/podman.$ext + for c in "container" "image" "pod" "volume" ""; do local cmd=${c:+-$c} for s in $($PODMAN $c --help | sed -n '/^Available Commands:/,/^Flags:/p' | sed -e '1d;$d' -e '/^$/d' | awk '{print $1}'); do - $publisher $source/podman$cmd-$s.$EXT + $publisher $(echo $source/podman$cmd-$s.*) done done } diff --git a/docs/rtd/requirements.txt b/docs/requirements.txt index 44af373ac..44af373ac 100644 --- a/docs/rtd/requirements.txt +++ b/docs/requirements.txt diff --git a/docs/rtd/Makefile b/docs/rtd/Makefile deleted file mode 100644 index 50af6490a..000000000 --- a/docs/rtd/Makefile +++ /dev/null @@ -1,123 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -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). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/rtd/source/Commands.rst b/docs/rtd/source/Commands.rst deleted file mode 100644 index f6ba5b20d..000000000 --- a/docs/rtd/source/Commands.rst +++ /dev/null @@ -1,107 +0,0 @@ -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/man/generate.rst b/docs/rtd/source/man/generate.rst deleted file mode 100644 index e82a15735..000000000 --- a/docs/rtd/source/man/generate.rst +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index 697c1358b..000000000 --- a/docs/rtd/source/man/healthcheck.rst +++ /dev/null @@ -1,4 +0,0 @@ -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 deleted file mode 100644 index ad963cd41..000000000 --- a/docs/rtd/source/man/image.rst +++ /dev/null @@ -1,35 +0,0 @@ -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 deleted file mode 100644 index 20e8c0679..000000000 --- a/docs/rtd/source/man/managecontainers.rst +++ /dev/null @@ -1,64 +0,0 @@ -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 deleted file mode 100644 index 6d6a4c022..000000000 --- a/docs/rtd/source/man/network.rst +++ /dev/null @@ -1,10 +0,0 @@ -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 deleted file mode 100644 index 93e1a9a1e..000000000 --- a/docs/rtd/source/man/play.rst +++ /dev/null @@ -1,4 +0,0 @@ -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 deleted file mode 100644 index 13c1740f8..000000000 --- a/docs/rtd/source/man/pod.rst +++ /dev/null @@ -1,30 +0,0 @@ -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 deleted file mode 100644 index 764ec01c1..000000000 --- a/docs/rtd/source/man/system.rst +++ /dev/null @@ -1,12 +0,0 @@ -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 deleted file mode 100644 index ee18e4b2e..000000000 --- a/docs/rtd/source/man/volume.rst +++ /dev/null @@ -1,11 +0,0 @@ -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/docs/source/Commands.rst b/docs/source/Commands.rst new file mode 100644 index 000000000..276a9c4fb --- /dev/null +++ b/docs/source/Commands.rst @@ -0,0 +1,107 @@ +Commands +======== + + +:doc:`attach <markdown/podman-attach.1>` Attach to a running container + +:doc:`build <markdown/podman-build.1>` Build an image using instructions from Containerfiles + +:doc:`commit <markdown/podman-commit.1>` Create new image based on the changed container + +:doc:`containers <managecontainers>` Manage Containers + +:doc:`cp <markdown/podman-cp.1>` Copy files/folders between a container and the local filesystem + +:doc:`create <markdown/podman-create.1>` Create but do not start a container + +:doc:`diff <markdown/podman-diff.1>` Inspect changes on container's file systems + +:doc:`events <markdown/podman-events.1>` Show podman events + +:doc:`exec <markdown/podman-exec.1>` Run a process in a running container + +:doc:`export <markdown/podman-export.1>` Export container's filesystem contents as a tar archive + +:doc:`generate <generate>` Generated structured data + +:doc:`healthcheck <healthcheck>` Manage Healthcheck + +:doc:`history <markdown/podman-history.1>` Show history of a specified image + +:doc:`image <image>` Manage images + +:doc:`images <markdown/podman-images.1>` List images in local storage + +:doc:`import <markdown/podman-import.1>` Import a tarball to create a filesystem image + +:doc:`info <markdown/podman-info.1>` Display podman system information + +:doc:`init <markdown/podman-init.1>` Initialize one or more containers + +:doc:`inspect <markdown/podman-inspect.1>` Display the configuration of a container or image + +:doc:`kill <markdown/podman-kill.1>` Kill one or more running containers with a specific signal + +:doc:`load <markdown/podman-load.1>` Load an image from container archive + +:doc:`login <markdown/podman-login.1>` Login to a container registry + +:doc:`logout <markdown/podman-logout.1>` Logout of a container registry + +:doc:`logs <markdown/podman-logs.1>` Fetch the logs of a container + +:doc:`mount <markdown/podman-mount.1>` Mount a working container's root filesystem + +:doc:`network <network>` Manage Networks + +:doc:`pause <markdown/podman-pause.1>` Pause all the processes in one or more containers + +:doc:`play <play>` Play a pod + +:doc:`pod <pod>` Manage pods + +:doc:`port <markdown/podman-port.1>` List port mappings or a specific mapping for the container + +:doc:`ps <markdown/podman-ps.1>` List containers + +:doc:`pull <markdown/podman-pull.1>` Pull an image from a registry + +:doc:`push <markdown/podman-push.1>` Push an image to a specified destination + +:doc:`restart <markdown/podman-restart.1>` Restart one or more containers + +:doc:`rm <markdown/podman-rm.1>` Remove one or more containers + +:doc:`rmi <markdown/podman-rmi.1>` Removes one or more images from local storage + +:doc:`run <markdown/podman-run.1>` Run a command in a new container + +:doc:`save <markdown/podman-save.1>` Save image to an archive + +:doc:`search <markdown/podman-search.1>` Search registry for image + +:doc:`start <markdown/podman-start.1>` Start one or more containers + +:doc:`stats <markdown/podman-stats.1>` Display a live stream of container resource usage statistics + +:doc:`stop <markdown/podman-stop.1>` Stop one or more containers + +:doc:`system <system>` Manage podman + +:doc:`tag <markdown/podman-tag.1>` Add an additional name to a local image + +:doc:`top <markdown/podman-top.1>` Display the running processes of a container + +:doc:`umount <markdown/podman-umount.1>` Unmounts working container's root filesystem + +:doc:`unpause <markdown/podman-unpause.1>` Unpause the processes in one or more containers + +:doc:`unshare <markdown/podman-unshare.1>` Run a command in a modified user namespace + +:doc:`varlink <markdown/podman-varlink.1>` Run varlink interface + +:doc:`version <markdown/podman-version.1>` Display the Podman Version Information + +:doc:`volume <volume>` Manage volumes + +:doc:`wait <markdown/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/source/Introduction.rst index c516b3317..c516b3317 100644 --- a/docs/rtd/source/Introduction.rst +++ b/docs/source/Introduction.rst diff --git a/docs/rtd/source/Reference.rst b/docs/source/Reference.rst index 9a771c87f..9a771c87f 100644 --- a/docs/rtd/source/Reference.rst +++ b/docs/source/Reference.rst diff --git a/docs/rtd/source/Tutorials.rst b/docs/source/Tutorials.rst index 0c7e28c3b..0c7e28c3b 100644 --- a/docs/rtd/source/Tutorials.rst +++ b/docs/source/Tutorials.rst diff --git a/docs/rtd/source/conf.py b/docs/source/conf.py index d95290f72..d95290f72 100644 --- a/docs/rtd/source/conf.py +++ b/docs/source/conf.py diff --git a/docs/source/generate.rst b/docs/source/generate.rst new file mode 100644 index 000000000..fd267ce62 --- /dev/null +++ b/docs/source/generate.rst @@ -0,0 +1,6 @@ +Generate +======== + +:doc:`kube <markdown/podman-generate-kube.1>` Generate Kubernetes pod YAML from a container or pod + +:doc:`systemd <markdown/podman-generate-systemd.1>` Generate a systemd unit file for a Podman container diff --git a/docs/source/healthcheck.rst b/docs/source/healthcheck.rst new file mode 100644 index 000000000..2e2f88fbc --- /dev/null +++ b/docs/source/healthcheck.rst @@ -0,0 +1,4 @@ +HealthCheck +=========== + +:doc:`run <markdown/podman-healthcheck-run.1>` run the health check of a container diff --git a/docs/source/image.rst b/docs/source/image.rst new file mode 100644 index 000000000..a8c6171e1 --- /dev/null +++ b/docs/source/image.rst @@ -0,0 +1,35 @@ +Image +===== + + +:doc:`build <markdown/podman-build.1>` Build an image using instructions from Containerfiles + +:doc:`exists <markdown/podman-image-exists.1>` Check if an image exists in local storage + +:doc:`history <markdown/podman-history.1>` Show history of a specified image + +:doc:`import <markdown/podman-import.1>` Import a tarball to create a filesystem image + +:doc:`inspect <markdown/podman-inspect.1>` Display the configuration of an image + +:doc:`list <markdown/podman-images.1>` List images in local storage + +:doc:`load <markdown/podman-load.1>` Load an image from container archive + +:doc:`prune <markdown/podman-image-prune.1>` Remove unused images + +:doc:`pull <markdown/podman-pull.1>` Pull an image from a registry + +:doc:`push <markdown/podman-push.1>` Push an image to a specified destination + +:doc:`rm <markdown/podman-rmi.1>` Removes one or more images from local storage + +:doc:`save <markdown/podman-save.1>` Save image to an archive + +:doc:`sign <markdown/podman-image-sign.1>` Sign an image + +:doc:`tag <markdown/podman-tag.1>` Add an additional name to a local image + +:doc:`tree <markdown/podman-image-tree.1>` Prints layer hierarchy of an image in a tree format + +:doc:`trust <markdown/podman-image-trust.1>` Manage container image trust policy diff --git a/docs/rtd/source/index.rst b/docs/source/index.rst index 9dd61a6a6..9dd61a6a6 100644 --- a/docs/rtd/source/index.rst +++ b/docs/source/index.rst diff --git a/docs/source/managecontainers.rst b/docs/source/managecontainers.rst new file mode 100644 index 000000000..5c5a83a82 --- /dev/null +++ b/docs/source/managecontainers.rst @@ -0,0 +1,64 @@ +Manage Containers +================= + +:doc:`attach <markdown/podman-attach.1>` Attach to a running container + +:doc:`checkpoint <markdown/podman-container-checkpoint.1>` Checkpoints one or more containers + +:doc:`cleanup <markdown/podman-container-cleanup.1>` Cleanup network and mountpoints of one or more containers + +:doc:`commit <markdown/podman-commit.1>` Create new image based on the changed container + +:doc:`cp <markdown/podman-cp.1>` Copy files/folders between a container and the local filesystem + +:doc:`create <markdown/podman-create.1>` Create but do not start a container + +:doc:`diff <markdown/podman-diff.1>` Inspect changes on container's file systems + +:doc:`exec <markdown/podman-exec.1>` Run a process in a running container + +:doc:`exists <markdown/podman-container-exists.1>` Check if a container exists in local storage + +:doc:`export <markdown/podman-export.1>` Export container's filesystem contents as a tar archive + +:doc:`init <markdown/podman-init.1>` Initialize one or more containers + +:doc:`inspect <markdown/podman-inspect.1>` Display the configuration of a container or image + +:doc:`kill <markdown/podman-kill.1>` Kill one or more running containers with a specific signal + +:doc:`list <markdown/podman-ps.1>` List containers + +:doc:`logs <markdown/podman-logs.1>` Fetch the logs of a container + +:doc:`mount <markdown/podman-mount.1>` Mount a working container's root filesystem + +:doc:`pause <markdown/podman-pause.1>` Pause all the processes in one or more containers + +:doc:`port <markdown/podman-port.1>` List port mappings or a specific mapping for the container + +:doc:`restart <markdown/podman-restart.1>` Restart one or more containers + +:doc:`prune <markdown/podman-container-prune.1>` Remove all stopped containers + +:doc:`restore <markdown/podman-container-restore.1>` Restores one or more containers from a checkpoint + +:doc:`rm <markdown/podman-rm.1>` Remove one or more containers + +:doc:`run <markdown/podman-run.1>` Run a command in a new container + +:doc:`runlabel <markdown/podman-container-runlabel.1>` Execute the command described by an image label + +:doc:`start <markdown/podman-start.1>` Start one or more containers + +:doc:`stats <markdown/podman-stats.1>` Display a live stream of container resource usage statistics + +:doc:`stop <markdown/podman-stop.1>` Stop one or more containers + +:doc:`top <markdown/podman-top.1>` Display the running processes of a container + +:doc:`umount <markdown/podman-umount.1>` Unmounts working container's root filesystem + +:doc:`unpause <markdown/podman-unpause.1>` Unpause the processes in one or more containers + +:doc:`wait <markdown/podman-wait.1>` Block on one or more containers diff --git a/docs/containers-mounts.conf.5.md b/docs/source/markdown/containers-mounts.conf.5.md index 130c1c523..130c1c523 100644 --- a/docs/containers-mounts.conf.5.md +++ b/docs/source/markdown/containers-mounts.conf.5.md diff --git a/docs/libpod.conf.5.md b/docs/source/markdown/libpod.conf.5.md index c28c80b56..c28c80b56 100644 --- a/docs/libpod.conf.5.md +++ b/docs/source/markdown/libpod.conf.5.md diff --git a/docs/links/podman-container-attach.1 b/docs/source/markdown/links/podman-container-attach.1 index be3b5efd3..be3b5efd3 100644 --- a/docs/links/podman-container-attach.1 +++ b/docs/source/markdown/links/podman-container-attach.1 diff --git a/docs/links/podman-container-commit.1 b/docs/source/markdown/links/podman-container-commit.1 index cdff06766..cdff06766 100644 --- a/docs/links/podman-container-commit.1 +++ b/docs/source/markdown/links/podman-container-commit.1 diff --git a/docs/links/podman-container-cp.1 b/docs/source/markdown/links/podman-container-cp.1 index 6ad859c84..6ad859c84 100644 --- a/docs/links/podman-container-cp.1 +++ b/docs/source/markdown/links/podman-container-cp.1 diff --git a/docs/links/podman-container-create.1 b/docs/source/markdown/links/podman-container-create.1 index f6b07d946..f6b07d946 100644 --- a/docs/links/podman-container-create.1 +++ b/docs/source/markdown/links/podman-container-create.1 diff --git a/docs/links/podman-container-diff.1 b/docs/source/markdown/links/podman-container-diff.1 index ac4881f98..ac4881f98 100644 --- a/docs/links/podman-container-diff.1 +++ b/docs/source/markdown/links/podman-container-diff.1 diff --git a/docs/links/podman-container-exec.1 b/docs/source/markdown/links/podman-container-exec.1 index 6bb98ec75..6bb98ec75 100644 --- a/docs/links/podman-container-exec.1 +++ b/docs/source/markdown/links/podman-container-exec.1 diff --git a/docs/links/podman-container-export.1 b/docs/source/markdown/links/podman-container-export.1 index 85b1d5438..85b1d5438 100644 --- a/docs/links/podman-container-export.1 +++ b/docs/source/markdown/links/podman-container-export.1 diff --git a/docs/links/podman-container-init.1 b/docs/source/markdown/links/podman-container-init.1 index 3a8bee249..3a8bee249 100644 --- a/docs/links/podman-container-init.1 +++ b/docs/source/markdown/links/podman-container-init.1 diff --git a/docs/links/podman-container-inspect.1 b/docs/source/markdown/links/podman-container-inspect.1 index 261043845..261043845 100644 --- a/docs/links/podman-container-inspect.1 +++ b/docs/source/markdown/links/podman-container-inspect.1 diff --git a/docs/links/podman-container-kill.1 b/docs/source/markdown/links/podman-container-kill.1 index 71960113d..71960113d 100644 --- a/docs/links/podman-container-kill.1 +++ b/docs/source/markdown/links/podman-container-kill.1 diff --git a/docs/links/podman-container-list.1 b/docs/source/markdown/links/podman-container-list.1 index f7f44c704..f7f44c704 100644 --- a/docs/links/podman-container-list.1 +++ b/docs/source/markdown/links/podman-container-list.1 diff --git a/docs/links/podman-container-logs.1 b/docs/source/markdown/links/podman-container-logs.1 index 7e0ce6307..7e0ce6307 100644 --- a/docs/links/podman-container-logs.1 +++ b/docs/source/markdown/links/podman-container-logs.1 diff --git a/docs/links/podman-container-ls.1 b/docs/source/markdown/links/podman-container-ls.1 index f7f44c704..f7f44c704 100644 --- a/docs/links/podman-container-ls.1 +++ b/docs/source/markdown/links/podman-container-ls.1 diff --git a/docs/links/podman-container-mount.1 b/docs/source/markdown/links/podman-container-mount.1 index b14e594a4..b14e594a4 100644 --- a/docs/links/podman-container-mount.1 +++ b/docs/source/markdown/links/podman-container-mount.1 diff --git a/docs/links/podman-container-pause.1 b/docs/source/markdown/links/podman-container-pause.1 index 3ed8d7cef..3ed8d7cef 100644 --- a/docs/links/podman-container-pause.1 +++ b/docs/source/markdown/links/podman-container-pause.1 diff --git a/docs/links/podman-container-port.1 b/docs/source/markdown/links/podman-container-port.1 index adfeda201..adfeda201 100644 --- a/docs/links/podman-container-port.1 +++ b/docs/source/markdown/links/podman-container-port.1 diff --git a/docs/links/podman-container-ps.1 b/docs/source/markdown/links/podman-container-ps.1 index f7f44c704..f7f44c704 100644 --- a/docs/links/podman-container-ps.1 +++ b/docs/source/markdown/links/podman-container-ps.1 diff --git a/docs/links/podman-container-restart.1 b/docs/source/markdown/links/podman-container-restart.1 index 9fb09ae50..9fb09ae50 100644 --- a/docs/links/podman-container-restart.1 +++ b/docs/source/markdown/links/podman-container-restart.1 diff --git a/docs/links/podman-container-rm.1 b/docs/source/markdown/links/podman-container-rm.1 index 6dfc6e98c..6dfc6e98c 100644 --- a/docs/links/podman-container-rm.1 +++ b/docs/source/markdown/links/podman-container-rm.1 diff --git a/docs/links/podman-container-run.1 b/docs/source/markdown/links/podman-container-run.1 index 6c70caa37..6c70caa37 100644 --- a/docs/links/podman-container-run.1 +++ b/docs/source/markdown/links/podman-container-run.1 diff --git a/docs/links/podman-container-start.1 b/docs/source/markdown/links/podman-container-start.1 index aa042cbfe..aa042cbfe 100644 --- a/docs/links/podman-container-start.1 +++ b/docs/source/markdown/links/podman-container-start.1 diff --git a/docs/links/podman-container-stats.1 b/docs/source/markdown/links/podman-container-stats.1 index 5f2e2e7d6..5f2e2e7d6 100644 --- a/docs/links/podman-container-stats.1 +++ b/docs/source/markdown/links/podman-container-stats.1 diff --git a/docs/links/podman-container-stop.1 b/docs/source/markdown/links/podman-container-stop.1 index 6b7e87c69..6b7e87c69 100644 --- a/docs/links/podman-container-stop.1 +++ b/docs/source/markdown/links/podman-container-stop.1 diff --git a/docs/links/podman-container-top.1 b/docs/source/markdown/links/podman-container-top.1 index ddcf7b5ec..ddcf7b5ec 100644 --- a/docs/links/podman-container-top.1 +++ b/docs/source/markdown/links/podman-container-top.1 diff --git a/docs/links/podman-container-umount.1 b/docs/source/markdown/links/podman-container-umount.1 index 789dabbb0..789dabbb0 100644 --- a/docs/links/podman-container-umount.1 +++ b/docs/source/markdown/links/podman-container-umount.1 diff --git a/docs/links/podman-container-unmount.1 b/docs/source/markdown/links/podman-container-unmount.1 index 789dabbb0..789dabbb0 100644 --- a/docs/links/podman-container-unmount.1 +++ b/docs/source/markdown/links/podman-container-unmount.1 diff --git a/docs/links/podman-container-unpause.1 b/docs/source/markdown/links/podman-container-unpause.1 index b8d970744..b8d970744 100644 --- a/docs/links/podman-container-unpause.1 +++ b/docs/source/markdown/links/podman-container-unpause.1 diff --git a/docs/links/podman-container-wait.1 b/docs/source/markdown/links/podman-container-wait.1 index bd2505dde..bd2505dde 100644 --- a/docs/links/podman-container-wait.1 +++ b/docs/source/markdown/links/podman-container-wait.1 diff --git a/docs/links/podman-help.1 b/docs/source/markdown/links/podman-help.1 index 6b7954b0d..6b7954b0d 100644 --- a/docs/links/podman-help.1 +++ b/docs/source/markdown/links/podman-help.1 diff --git a/docs/links/podman-image-build.1 b/docs/source/markdown/links/podman-image-build.1 index 27c751cf6..27c751cf6 100644 --- a/docs/links/podman-image-build.1 +++ b/docs/source/markdown/links/podman-image-build.1 diff --git a/docs/links/podman-image-history.1 b/docs/source/markdown/links/podman-image-history.1 index 6b6dc17e1..6b6dc17e1 100644 --- a/docs/links/podman-image-history.1 +++ b/docs/source/markdown/links/podman-image-history.1 diff --git a/docs/links/podman-image-import.1 b/docs/source/markdown/links/podman-image-import.1 index 4564fc6c9..4564fc6c9 100644 --- a/docs/links/podman-image-import.1 +++ b/docs/source/markdown/links/podman-image-import.1 diff --git a/docs/links/podman-image-inspect.1 b/docs/source/markdown/links/podman-image-inspect.1 index 261043845..261043845 100644 --- a/docs/links/podman-image-inspect.1 +++ b/docs/source/markdown/links/podman-image-inspect.1 diff --git a/docs/links/podman-image-list.1 b/docs/source/markdown/links/podman-image-list.1 index 17d6ca880..17d6ca880 100644 --- a/docs/links/podman-image-list.1 +++ b/docs/source/markdown/links/podman-image-list.1 diff --git a/docs/links/podman-image-load.1 b/docs/source/markdown/links/podman-image-load.1 index 21b6d8e9c..21b6d8e9c 100644 --- a/docs/links/podman-image-load.1 +++ b/docs/source/markdown/links/podman-image-load.1 diff --git a/docs/links/podman-image-ls.1 b/docs/source/markdown/links/podman-image-ls.1 index 17d6ca880..17d6ca880 100644 --- a/docs/links/podman-image-ls.1 +++ b/docs/source/markdown/links/podman-image-ls.1 diff --git a/docs/links/podman-image-pull.1 b/docs/source/markdown/links/podman-image-pull.1 index d14519be3..d14519be3 100644 --- a/docs/links/podman-image-pull.1 +++ b/docs/source/markdown/links/podman-image-pull.1 diff --git a/docs/links/podman-image-push.1 b/docs/source/markdown/links/podman-image-push.1 index 51d52ad11..51d52ad11 100644 --- a/docs/links/podman-image-push.1 +++ b/docs/source/markdown/links/podman-image-push.1 diff --git a/docs/links/podman-image-rm.1 b/docs/source/markdown/links/podman-image-rm.1 index 1007ad150..1007ad150 100644 --- a/docs/links/podman-image-rm.1 +++ b/docs/source/markdown/links/podman-image-rm.1 diff --git a/docs/links/podman-image-save.1 b/docs/source/markdown/links/podman-image-save.1 index 715d7d6ee..715d7d6ee 100644 --- a/docs/links/podman-image-save.1 +++ b/docs/source/markdown/links/podman-image-save.1 diff --git a/docs/links/podman-image-tag.1 b/docs/source/markdown/links/podman-image-tag.1 index e41c50de9..e41c50de9 100644 --- a/docs/links/podman-image-tag.1 +++ b/docs/source/markdown/links/podman-image-tag.1 diff --git a/docs/links/podman-list.1 b/docs/source/markdown/links/podman-list.1 index f7f44c704..f7f44c704 100644 --- a/docs/links/podman-list.1 +++ b/docs/source/markdown/links/podman-list.1 diff --git a/docs/links/podman-ls.1 b/docs/source/markdown/links/podman-ls.1 index f7f44c704..f7f44c704 100644 --- a/docs/links/podman-ls.1 +++ b/docs/source/markdown/links/podman-ls.1 diff --git a/docs/links/podman-system-info.1 b/docs/source/markdown/links/podman-system-info.1 index 809a71b8b..809a71b8b 100644 --- a/docs/links/podman-system-info.1 +++ b/docs/source/markdown/links/podman-system-info.1 diff --git a/docs/links/podman-unmount.1 b/docs/source/markdown/links/podman-unmount.1 index 789dabbb0..789dabbb0 100644 --- a/docs/links/podman-unmount.1 +++ b/docs/source/markdown/links/podman-unmount.1 diff --git a/docs/podman-attach.1.md b/docs/source/markdown/podman-attach.1.md index cef01f0f6..cef01f0f6 100644 --- a/docs/podman-attach.1.md +++ b/docs/source/markdown/podman-attach.1.md diff --git a/docs/podman-build.1.md b/docs/source/markdown/podman-build.1.md index 567d0ead3..567d0ead3 100644 --- a/docs/podman-build.1.md +++ b/docs/source/markdown/podman-build.1.md diff --git a/docs/podman-commit.1.md b/docs/source/markdown/podman-commit.1.md index 07a885ae2..07a885ae2 100644 --- a/docs/podman-commit.1.md +++ b/docs/source/markdown/podman-commit.1.md diff --git a/docs/podman-container-checkpoint.1.md b/docs/source/markdown/podman-container-checkpoint.1.md index 034d338bb..034d338bb 100644 --- a/docs/podman-container-checkpoint.1.md +++ b/docs/source/markdown/podman-container-checkpoint.1.md diff --git a/docs/podman-container-cleanup.1.md b/docs/source/markdown/podman-container-cleanup.1.md index 69e21ce9f..69e21ce9f 100644 --- a/docs/podman-container-cleanup.1.md +++ b/docs/source/markdown/podman-container-cleanup.1.md diff --git a/docs/podman-container-exists.1.md b/docs/source/markdown/podman-container-exists.1.md index 4d988132b..4d988132b 100644 --- a/docs/podman-container-exists.1.md +++ b/docs/source/markdown/podman-container-exists.1.md diff --git a/docs/podman-container-prune.1.md b/docs/source/markdown/podman-container-prune.1.md index d8a4b7f4e..d8a4b7f4e 100644 --- a/docs/podman-container-prune.1.md +++ b/docs/source/markdown/podman-container-prune.1.md diff --git a/docs/podman-container-restore.1.md b/docs/source/markdown/podman-container-restore.1.md index 1d2cf0b3e..1d2cf0b3e 100644 --- a/docs/podman-container-restore.1.md +++ b/docs/source/markdown/podman-container-restore.1.md diff --git a/docs/podman-container-runlabel.1.md b/docs/source/markdown/podman-container-runlabel.1.md index 8511dd5cd..8511dd5cd 100644 --- a/docs/podman-container-runlabel.1.md +++ b/docs/source/markdown/podman-container-runlabel.1.md diff --git a/docs/podman-container.1.md b/docs/source/markdown/podman-container.1.md index 4ea7c7acc..4ea7c7acc 100644 --- a/docs/podman-container.1.md +++ b/docs/source/markdown/podman-container.1.md diff --git a/docs/podman-cp.1.md b/docs/source/markdown/podman-cp.1.md index 0f54b2e8b..0f54b2e8b 100644 --- a/docs/podman-cp.1.md +++ b/docs/source/markdown/podman-cp.1.md diff --git a/docs/podman-create.1.md b/docs/source/markdown/podman-create.1.md index 6617850fd..2e0dd934c 100644 --- a/docs/podman-create.1.md +++ b/docs/source/markdown/podman-create.1.md @@ -67,12 +67,14 @@ Drop Linux capabilities **--cgroupns**=*mode* -Set the cgroup namespace mode for the container, by default **host** is used. +Set the cgroup namespace mode for the container. **host**: use the host's cgroup namespace inside the container. **container:<NAME|ID>**: join the namespace of the specified 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**. + **--cgroups**=*mode* Determines whether the container will create CGroups. diff --git a/docs/podman-diff.1.md b/docs/source/markdown/podman-diff.1.md index 5b0434a07..5b0434a07 100644 --- a/docs/podman-diff.1.md +++ b/docs/source/markdown/podman-diff.1.md diff --git a/docs/podman-events.1.md b/docs/source/markdown/podman-events.1.md index bb1923574..bb1923574 100644 --- a/docs/podman-events.1.md +++ b/docs/source/markdown/podman-events.1.md diff --git a/docs/podman-exec.1.md b/docs/source/markdown/podman-exec.1.md index 4c17c056a..4c17c056a 100644 --- a/docs/podman-exec.1.md +++ b/docs/source/markdown/podman-exec.1.md diff --git a/docs/podman-export.1.md b/docs/source/markdown/podman-export.1.md index 4286d0e2f..4286d0e2f 100644 --- a/docs/podman-export.1.md +++ b/docs/source/markdown/podman-export.1.md diff --git a/docs/podman-generate-kube.1.md b/docs/source/markdown/podman-generate-kube.1.md index f4b4cd482..f4b4cd482 100644 --- a/docs/podman-generate-kube.1.md +++ b/docs/source/markdown/podman-generate-kube.1.md diff --git a/docs/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md index b81e68a46..b81e68a46 100644 --- a/docs/podman-generate-systemd.1.md +++ b/docs/source/markdown/podman-generate-systemd.1.md diff --git a/docs/podman-generate.1.md b/docs/source/markdown/podman-generate.1.md index 50050f2c1..50050f2c1 100644 --- a/docs/podman-generate.1.md +++ b/docs/source/markdown/podman-generate.1.md diff --git a/docs/podman-healthcheck-run.1.md b/docs/source/markdown/podman-healthcheck-run.1.md index 21f2d9b20..21f2d9b20 100644 --- a/docs/podman-healthcheck-run.1.md +++ b/docs/source/markdown/podman-healthcheck-run.1.md diff --git a/docs/podman-healthcheck.1.md b/docs/source/markdown/podman-healthcheck.1.md index 91c3e4345..91c3e4345 100644 --- a/docs/podman-healthcheck.1.md +++ b/docs/source/markdown/podman-healthcheck.1.md diff --git a/docs/podman-history.1.md b/docs/source/markdown/podman-history.1.md index a67cb0286..a67cb0286 100644 --- a/docs/podman-history.1.md +++ b/docs/source/markdown/podman-history.1.md diff --git a/docs/podman-image-exists.1.md b/docs/source/markdown/podman-image-exists.1.md index f6a89e2aa..f6a89e2aa 100644 --- a/docs/podman-image-exists.1.md +++ b/docs/source/markdown/podman-image-exists.1.md diff --git a/docs/podman-image-prune.1.md b/docs/source/markdown/podman-image-prune.1.md index b844a9f63..b844a9f63 100644 --- a/docs/podman-image-prune.1.md +++ b/docs/source/markdown/podman-image-prune.1.md diff --git a/docs/podman-image-sign.1.md b/docs/source/markdown/podman-image-sign.1.md index 62845e715..62845e715 100644 --- a/docs/podman-image-sign.1.md +++ b/docs/source/markdown/podman-image-sign.1.md diff --git a/docs/podman-image-tree.1.md b/docs/source/markdown/podman-image-tree.1.md index c4624e05c..c4624e05c 100644 --- a/docs/podman-image-tree.1.md +++ b/docs/source/markdown/podman-image-tree.1.md diff --git a/docs/podman-image-trust.1.md b/docs/source/markdown/podman-image-trust.1.md index 3fe4f7f52..3fe4f7f52 100644 --- a/docs/podman-image-trust.1.md +++ b/docs/source/markdown/podman-image-trust.1.md diff --git a/docs/podman-image.1.md b/docs/source/markdown/podman-image.1.md index 339a531dd..339a531dd 100644 --- a/docs/podman-image.1.md +++ b/docs/source/markdown/podman-image.1.md diff --git a/docs/podman-images.1.md b/docs/source/markdown/podman-images.1.md index 3ac07fc43..3ac07fc43 100644 --- a/docs/podman-images.1.md +++ b/docs/source/markdown/podman-images.1.md diff --git a/docs/podman-import.1.md b/docs/source/markdown/podman-import.1.md index 946b680dd..946b680dd 100644 --- a/docs/podman-import.1.md +++ b/docs/source/markdown/podman-import.1.md diff --git a/docs/podman-info.1.md b/docs/source/markdown/podman-info.1.md index 9721755ef..9721755ef 100644 --- a/docs/podman-info.1.md +++ b/docs/source/markdown/podman-info.1.md diff --git a/docs/podman-init.1.md b/docs/source/markdown/podman-init.1.md index 3b49cfb99..3b49cfb99 100644 --- a/docs/podman-init.1.md +++ b/docs/source/markdown/podman-init.1.md diff --git a/docs/podman-inspect.1.md b/docs/source/markdown/podman-inspect.1.md index f1630c713..f1630c713 100644 --- a/docs/podman-inspect.1.md +++ b/docs/source/markdown/podman-inspect.1.md diff --git a/docs/podman-kill.1.md b/docs/source/markdown/podman-kill.1.md index 617d25b85..617d25b85 100644 --- a/docs/podman-kill.1.md +++ b/docs/source/markdown/podman-kill.1.md diff --git a/docs/podman-load.1.md b/docs/source/markdown/podman-load.1.md index deb4fb5ec..deb4fb5ec 100644 --- a/docs/podman-load.1.md +++ b/docs/source/markdown/podman-load.1.md diff --git a/docs/podman-login.1.md b/docs/source/markdown/podman-login.1.md index 9d368e9f2..9d368e9f2 100644 --- a/docs/podman-login.1.md +++ b/docs/source/markdown/podman-login.1.md diff --git a/docs/podman-logout.1.md b/docs/source/markdown/podman-logout.1.md index 01dc52ecd..01dc52ecd 100644 --- a/docs/podman-logout.1.md +++ b/docs/source/markdown/podman-logout.1.md diff --git a/docs/podman-logs.1.md b/docs/source/markdown/podman-logs.1.md index 405f180d9..5507ba13a 100644 --- a/docs/podman-logs.1.md +++ b/docs/source/markdown/podman-logs.1.md @@ -39,7 +39,7 @@ and 2006-01-02. **--tail**=*LINES* -Output the specified number of LINES at the end of the logs. LINES must be a positive integer. Defaults to 0, +Output the specified number of LINES at the end of the logs. LINES must be an integer. Defaults to -1, which prints all lines **--timestamps**, **-t** diff --git a/docs/podman-mount.1.md b/docs/source/markdown/podman-mount.1.md index 8f4deeca6..8f4deeca6 100644 --- a/docs/podman-mount.1.md +++ b/docs/source/markdown/podman-mount.1.md diff --git a/docs/podman-network-create.1.md b/docs/source/markdown/podman-network-create.1.md index c281d50d9..c281d50d9 100644 --- a/docs/podman-network-create.1.md +++ b/docs/source/markdown/podman-network-create.1.md diff --git a/docs/podman-network-inspect.1.md b/docs/source/markdown/podman-network-inspect.1.md index dfa7e4b0c..dfa7e4b0c 100644 --- a/docs/podman-network-inspect.1.md +++ b/docs/source/markdown/podman-network-inspect.1.md diff --git a/docs/podman-network-ls.1.md b/docs/source/markdown/podman-network-ls.1.md index 46e424593..46e424593 100644 --- a/docs/podman-network-ls.1.md +++ b/docs/source/markdown/podman-network-ls.1.md diff --git a/docs/podman-network-rm.1.md b/docs/source/markdown/podman-network-rm.1.md index c71f0d8fd..c71f0d8fd 100644 --- a/docs/podman-network-rm.1.md +++ b/docs/source/markdown/podman-network-rm.1.md diff --git a/docs/podman-network.1.md b/docs/source/markdown/podman-network.1.md index f05b2b78f..f05b2b78f 100644 --- a/docs/podman-network.1.md +++ b/docs/source/markdown/podman-network.1.md diff --git a/docs/podman-pause.1.md b/docs/source/markdown/podman-pause.1.md index dfd4da416..dfd4da416 100644 --- a/docs/podman-pause.1.md +++ b/docs/source/markdown/podman-pause.1.md diff --git a/docs/podman-play-kube.1.md b/docs/source/markdown/podman-play-kube.1.md index 2ac860a32..2ac860a32 100644 --- a/docs/podman-play-kube.1.md +++ b/docs/source/markdown/podman-play-kube.1.md diff --git a/docs/podman-play.1.md b/docs/source/markdown/podman-play.1.md index 364baad60..364baad60 100644 --- a/docs/podman-play.1.md +++ b/docs/source/markdown/podman-play.1.md diff --git a/docs/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md index cd1de6401..cd1de6401 100644 --- a/docs/podman-pod-create.1.md +++ b/docs/source/markdown/podman-pod-create.1.md diff --git a/docs/podman-pod-exists.1.md b/docs/source/markdown/podman-pod-exists.1.md index cf2852934..cf2852934 100644 --- a/docs/podman-pod-exists.1.md +++ b/docs/source/markdown/podman-pod-exists.1.md diff --git a/docs/podman-pod-inspect.1.md b/docs/source/markdown/podman-pod-inspect.1.md index 831d28259..831d28259 100644 --- a/docs/podman-pod-inspect.1.md +++ b/docs/source/markdown/podman-pod-inspect.1.md diff --git a/docs/podman-pod-kill.1.md b/docs/source/markdown/podman-pod-kill.1.md index 596e15cea..596e15cea 100644 --- a/docs/podman-pod-kill.1.md +++ b/docs/source/markdown/podman-pod-kill.1.md diff --git a/docs/podman-pod-pause.1.md b/docs/source/markdown/podman-pod-pause.1.md index 9533ed4a1..9533ed4a1 100644 --- a/docs/podman-pod-pause.1.md +++ b/docs/source/markdown/podman-pod-pause.1.md diff --git a/docs/podman-pod-prune.1.md b/docs/source/markdown/podman-pod-prune.1.md index f79961b2f..f79961b2f 100644 --- a/docs/podman-pod-prune.1.md +++ b/docs/source/markdown/podman-pod-prune.1.md diff --git a/docs/podman-pod-ps.1.md b/docs/source/markdown/podman-pod-ps.1.md index 65a7072ab..65a7072ab 100644 --- a/docs/podman-pod-ps.1.md +++ b/docs/source/markdown/podman-pod-ps.1.md diff --git a/docs/podman-pod-restart.1.md b/docs/source/markdown/podman-pod-restart.1.md index 57f479102..57f479102 100644 --- a/docs/podman-pod-restart.1.md +++ b/docs/source/markdown/podman-pod-restart.1.md diff --git a/docs/podman-pod-rm.1.md b/docs/source/markdown/podman-pod-rm.1.md index 6659534b4..6659534b4 100644 --- a/docs/podman-pod-rm.1.md +++ b/docs/source/markdown/podman-pod-rm.1.md diff --git a/docs/podman-pod-start.1.md b/docs/source/markdown/podman-pod-start.1.md index 29960d6aa..29960d6aa 100644 --- a/docs/podman-pod-start.1.md +++ b/docs/source/markdown/podman-pod-start.1.md diff --git a/docs/podman-pod-stats.1.md b/docs/source/markdown/podman-pod-stats.1.md index 962edbda0..962edbda0 100644 --- a/docs/podman-pod-stats.1.md +++ b/docs/source/markdown/podman-pod-stats.1.md diff --git a/docs/podman-pod-stop.1.md b/docs/source/markdown/podman-pod-stop.1.md index b3ce47d72..b3ce47d72 100644 --- a/docs/podman-pod-stop.1.md +++ b/docs/source/markdown/podman-pod-stop.1.md diff --git a/docs/podman-pod-top.1.md b/docs/source/markdown/podman-pod-top.1.md index 48f10055a..48f10055a 100644 --- a/docs/podman-pod-top.1.md +++ b/docs/source/markdown/podman-pod-top.1.md diff --git a/docs/podman-pod-unpause.1.md b/docs/source/markdown/podman-pod-unpause.1.md index e0a88c2e3..e0a88c2e3 100644 --- a/docs/podman-pod-unpause.1.md +++ b/docs/source/markdown/podman-pod-unpause.1.md diff --git a/docs/podman-pod.1.md b/docs/source/markdown/podman-pod.1.md index b3d002a06..b3d002a06 100644 --- a/docs/podman-pod.1.md +++ b/docs/source/markdown/podman-pod.1.md diff --git a/docs/podman-port.1.md b/docs/source/markdown/podman-port.1.md index c9833f447..c9833f447 100644 --- a/docs/podman-port.1.md +++ b/docs/source/markdown/podman-port.1.md diff --git a/docs/podman-ps.1.md b/docs/source/markdown/podman-ps.1.md index 298de0b2b..298de0b2b 100644 --- a/docs/podman-ps.1.md +++ b/docs/source/markdown/podman-ps.1.md diff --git a/docs/podman-pull.1.md b/docs/source/markdown/podman-pull.1.md index de9688f5e..de9688f5e 100644 --- a/docs/podman-pull.1.md +++ b/docs/source/markdown/podman-pull.1.md diff --git a/docs/podman-push.1.md b/docs/source/markdown/podman-push.1.md index 3f0350bcd..3f0350bcd 100644 --- a/docs/podman-push.1.md +++ b/docs/source/markdown/podman-push.1.md diff --git a/docs/podman-remote.1.md b/docs/source/markdown/podman-remote.1.md index 04010abaf..04010abaf 100644 --- a/docs/podman-remote.1.md +++ b/docs/source/markdown/podman-remote.1.md diff --git a/docs/podman-remote.conf.5.md b/docs/source/markdown/podman-remote.conf.5.md index e9cc05989..e9cc05989 100644 --- a/docs/podman-remote.conf.5.md +++ b/docs/source/markdown/podman-remote.conf.5.md diff --git a/docs/podman-restart.1.md b/docs/source/markdown/podman-restart.1.md index 08fa29244..08fa29244 100644 --- a/docs/podman-restart.1.md +++ b/docs/source/markdown/podman-restart.1.md diff --git a/docs/podman-rm.1.md b/docs/source/markdown/podman-rm.1.md index 207d9d61d..207d9d61d 100644 --- a/docs/podman-rm.1.md +++ b/docs/source/markdown/podman-rm.1.md diff --git a/docs/podman-rmi.1.md b/docs/source/markdown/podman-rmi.1.md index d911ee6cb..d911ee6cb 100644 --- a/docs/podman-rmi.1.md +++ b/docs/source/markdown/podman-rmi.1.md diff --git a/docs/podman-run.1.md b/docs/source/markdown/podman-run.1.md index d6d8f4c1e..8baa39570 100644 --- a/docs/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -81,12 +81,14 @@ Drop Linux capabilities **--cgroupns**=*mode* -Set the cgroup namespace mode for the container, by default **host** is used. +Set the cgroup namespace mode for the container. **host**: use the host's cgroup namespace inside the container. **container:<NAME|ID>**: join the namespace of the specified 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**. + **--cgroups**=*mode* Determines whether the container will create CGroups. diff --git a/docs/podman-save.1.md b/docs/source/markdown/podman-save.1.md index b2b0995d3..b2b0995d3 100644 --- a/docs/podman-save.1.md +++ b/docs/source/markdown/podman-save.1.md diff --git a/docs/podman-search.1.md b/docs/source/markdown/podman-search.1.md index 31de6f839..31de6f839 100644 --- a/docs/podman-search.1.md +++ b/docs/source/markdown/podman-search.1.md diff --git a/docs/podman-start.1.md b/docs/source/markdown/podman-start.1.md index 4c81d17bd..4c81d17bd 100644 --- a/docs/podman-start.1.md +++ b/docs/source/markdown/podman-start.1.md diff --git a/docs/podman-stats.1.md b/docs/source/markdown/podman-stats.1.md index 741873c3f..741873c3f 100644 --- a/docs/podman-stats.1.md +++ b/docs/source/markdown/podman-stats.1.md diff --git a/docs/podman-stop.1.md b/docs/source/markdown/podman-stop.1.md index b5ea670b0..b5ea670b0 100644 --- a/docs/podman-stop.1.md +++ b/docs/source/markdown/podman-stop.1.md diff --git a/docs/podman-system-df.1.md b/docs/source/markdown/podman-system-df.1.md index d0b1755ee..d0b1755ee 100644 --- a/docs/podman-system-df.1.md +++ b/docs/source/markdown/podman-system-df.1.md diff --git a/docs/podman-system-migrate.1.md b/docs/source/markdown/podman-system-migrate.1.md index d5e3bcb95..d5e3bcb95 100644 --- a/docs/podman-system-migrate.1.md +++ b/docs/source/markdown/podman-system-migrate.1.md diff --git a/docs/podman-system-prune.1.md b/docs/source/markdown/podman-system-prune.1.md index e6297dc0b..e6297dc0b 100644 --- a/docs/podman-system-prune.1.md +++ b/docs/source/markdown/podman-system-prune.1.md diff --git a/docs/podman-system-renumber.1.md b/docs/source/markdown/podman-system-renumber.1.md index 071eefe29..071eefe29 100644 --- a/docs/podman-system-renumber.1.md +++ b/docs/source/markdown/podman-system-renumber.1.md diff --git a/docs/podman-system.1.md b/docs/source/markdown/podman-system.1.md index bbd541066..bbd541066 100644 --- a/docs/podman-system.1.md +++ b/docs/source/markdown/podman-system.1.md diff --git a/docs/podman-tag.1.md b/docs/source/markdown/podman-tag.1.md index 291d95228..291d95228 100644 --- a/docs/podman-tag.1.md +++ b/docs/source/markdown/podman-tag.1.md diff --git a/docs/podman-top.1.md b/docs/source/markdown/podman-top.1.md index 1410aa651..1410aa651 100644 --- a/docs/podman-top.1.md +++ b/docs/source/markdown/podman-top.1.md diff --git a/docs/podman-umount.1.md b/docs/source/markdown/podman-umount.1.md index 100c47b32..100c47b32 100644 --- a/docs/podman-umount.1.md +++ b/docs/source/markdown/podman-umount.1.md diff --git a/docs/podman-unpause.1.md b/docs/source/markdown/podman-unpause.1.md index f5538d6d5..f5538d6d5 100644 --- a/docs/podman-unpause.1.md +++ b/docs/source/markdown/podman-unpause.1.md diff --git a/docs/podman-unshare.1.md b/docs/source/markdown/podman-unshare.1.md index 9052b97ab..9052b97ab 100644 --- a/docs/podman-unshare.1.md +++ b/docs/source/markdown/podman-unshare.1.md diff --git a/docs/podman-varlink.1.md b/docs/source/markdown/podman-varlink.1.md index 0d2ab1668..0d2ab1668 100644 --- a/docs/podman-varlink.1.md +++ b/docs/source/markdown/podman-varlink.1.md diff --git a/docs/podman-version.1.md b/docs/source/markdown/podman-version.1.md index 4499f6338..4499f6338 100644 --- a/docs/podman-version.1.md +++ b/docs/source/markdown/podman-version.1.md diff --git a/docs/podman-volume-create.1.md b/docs/source/markdown/podman-volume-create.1.md index b354f396f..b354f396f 100644 --- a/docs/podman-volume-create.1.md +++ b/docs/source/markdown/podman-volume-create.1.md diff --git a/docs/podman-volume-inspect.1.md b/docs/source/markdown/podman-volume-inspect.1.md index ac5b6c977..ac5b6c977 100644 --- a/docs/podman-volume-inspect.1.md +++ b/docs/source/markdown/podman-volume-inspect.1.md diff --git a/docs/podman-volume-ls.1.md b/docs/source/markdown/podman-volume-ls.1.md index d431c7c6e..d431c7c6e 100644 --- a/docs/podman-volume-ls.1.md +++ b/docs/source/markdown/podman-volume-ls.1.md diff --git a/docs/podman-volume-prune.1.md b/docs/source/markdown/podman-volume-prune.1.md index 25ea701a3..25ea701a3 100644 --- a/docs/podman-volume-prune.1.md +++ b/docs/source/markdown/podman-volume-prune.1.md diff --git a/docs/podman-volume-rm.1.md b/docs/source/markdown/podman-volume-rm.1.md index 9a2fe8c99..9a2fe8c99 100644 --- a/docs/podman-volume-rm.1.md +++ b/docs/source/markdown/podman-volume-rm.1.md diff --git a/docs/podman-volume.1.md b/docs/source/markdown/podman-volume.1.md index 288e57b82..288e57b82 100644 --- a/docs/podman-volume.1.md +++ b/docs/source/markdown/podman-volume.1.md diff --git a/docs/podman-wait.1.md b/docs/source/markdown/podman-wait.1.md index ce1c70a5f..ce1c70a5f 100644 --- a/docs/podman-wait.1.md +++ b/docs/source/markdown/podman-wait.1.md diff --git a/docs/podman.1.md b/docs/source/markdown/podman.1.md index f6fa1a457..f6fa1a457 100644 --- a/docs/podman.1.md +++ b/docs/source/markdown/podman.1.md diff --git a/docs/source/network.rst b/docs/source/network.rst new file mode 100644 index 000000000..c1c53bc34 --- /dev/null +++ b/docs/source/network.rst @@ -0,0 +1,10 @@ +Network +===== + +:doc:`create <markdown/podman-network-create.1>` network create + +:doc:`inspect <markdown/podman-network-inspect.1>` network inspect + +:doc:`ls <markdown/podman-network-ls.1>` network list + +:doc:`rm <markdown/podman-network-rm.1>` network rm
\ No newline at end of file diff --git a/docs/source/play.rst b/docs/source/play.rst new file mode 100644 index 000000000..8f00d2f45 --- /dev/null +++ b/docs/source/play.rst @@ -0,0 +1,4 @@ +Play +==== + +:doc:`kube <markdown/podman-play-kube.1>` Play a pod based on Kubernetes YAML diff --git a/docs/source/pod.rst b/docs/source/pod.rst new file mode 100644 index 000000000..391686ce5 --- /dev/null +++ b/docs/source/pod.rst @@ -0,0 +1,30 @@ +Pod +=== + +:doc:`create <markdown/podman-pod-create.1>` Create a new empty pod + +:doc:`exists <markdown/podman-pod-exists.1>` Check if a pod exists in local storage + +:doc:`inspect <markdown/podman-pod-inspect.1>` Displays a pod configuration + +:doc:`kill <markdown/podman-pod-kill.1>` Send the specified signal or SIGKILL to containers in pod + +:doc:`pause <markdown/podman-pause.1>` Pause one or more pods + +:doc:`prune <markdown/podman-pod-prune.1>` Remove all stopped pods + +:doc:`ps <markdown/podman-pod-ps.1>` List pods + +:doc:`restart <markdown/podman-pod-restart.1>` Restart one or more pods + +:doc:`rm <markdown/podman-pod-rm.1>` Remove one or more pods + +:doc:`start <markdown/podman-pod-start.1>` Start one or more pods + +:doc:`stats <markdown/podman-pod-stats.1>` Display a live stream of resource usage statistics for the containers in one or more pods + +:doc:`stop <markdown/podman-pod-stop.1>` Stop one or more pods + +:doc:`top <markdown/podman-pod-top.1>` Display the running processes of containers in a pod + +:doc:`unpause <markdown/podman-pod-unpause.1>` Unpause one or more pods diff --git a/docs/source/system.rst b/docs/source/system.rst new file mode 100644 index 000000000..2f2b7ea8f --- /dev/null +++ b/docs/source/system.rst @@ -0,0 +1,12 @@ +System +====== + +:doc:`df <markdown/podman-system-df.1>` Show podman disk usage + +:doc:`info <markdown/podman-info.1>` Display podman system information + +:doc:`migrate <markdown/podman-system-migrate.1>` Migrate containers + +:doc:`prune <markdown/podman-system-prune.1>` Remove unused data + +:doc:`renumber <markdown/podman-system-renumber.1>` Migrate lock numbers diff --git a/docs/source/volume.rst b/docs/source/volume.rst new file mode 100644 index 000000000..43fe87054 --- /dev/null +++ b/docs/source/volume.rst @@ -0,0 +1,11 @@ +Volume +====== +:doc:`create <markdown/podman-volume-create.1>` Create a new volume + +:doc:`inspect <markdown/podman-volume-inspect.1>` Display detailed information on one or more volumes + +:doc:`ls <markdown/podman-volume-ls.1>` List volumes + +:doc:`prune <markdown/podman-volume-prune.1>` Remove all unused volumes + +:doc:`rm <markdown/podman-volume-rm.1>` Remove one or more volumes
\ No newline at end of file @@ -11,7 +11,7 @@ require ( github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect github.com/containernetworking/cni v0.7.1 github.com/containernetworking/plugins v0.8.2 - github.com/containers/buildah v1.11.4-0.20191028173731-21b4778b359e + github.com/containers/buildah v1.11.5-0.20191031204705-20e92ffe0982 github.com/containers/image/v5 v5.0.0 github.com/containers/psgo v1.3.2 github.com/containers/storage v1.13.5 @@ -40,7 +40,7 @@ require ( github.com/json-iterator/go v1.1.7 github.com/mattn/go-isatty v0.0.8 // indirect github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 - github.com/onsi/ginkgo v1.10.1 + github.com/onsi/ginkgo v1.10.3 github.com/onsi/gomega v1.7.0 github.com/opencontainers/go-digest v1.0.0-rc1 github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 @@ -71,7 +71,7 @@ require ( google.golang.org/appengine v1.6.1 // indirect google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.2.4 + gopkg.in/yaml.v2 v2.2.5 k8s.io/api v0.0.0-20190813020757-36bff7324fb7 k8s.io/apimachinery v0.0.0-20190809020650-423f5d784010 k8s.io/client-go v0.0.0-20190620085101-78d2af792bab @@ -55,12 +55,10 @@ github.com/containernetworking/cni v0.7.1 h1:fE3r16wpSEyaqY4Z4oFrLMmIGfBYIKpPrHK github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/plugins v0.8.2 h1:5lnwfsAYO+V7yXhysJKy3E1A2Gy9oVut031zfdOzI9w= github.com/containernetworking/plugins v0.8.2/go.mod h1:TxALKWZpWL79BC3GOYKJzzXr7U8R23PdhwaLp6F3adc= -github.com/containers/buildah v1.11.3 h1:L5vFj+ao58IGq3G30jN94vRQrIgMU/uTOEKduDr3Nyg= -github.com/containers/buildah v1.11.3/go.mod h1:jqZmSU/PhFwTHHlOotnw4bbs1JbkRQLh8dut5DF4Qek= github.com/containers/buildah v1.11.4-0.20191028173731-21b4778b359e h1:iDavHEx5Yr7o+0l6495Ya6N0YEPplIUZuWC2e14baDM= github.com/containers/buildah v1.11.4-0.20191028173731-21b4778b359e/go.mod h1:Igrk75FAxLnzDaHUbtpWB8pwL+Bv+cnakWMvqAXW2v8= -github.com/containers/image/v4 v4.0.1 h1:idNGHChj0Pyv3vLrxul2oSVMZLeFqpoq3CjLeVgapSQ= -github.com/containers/image/v4 v4.0.1/go.mod h1:0ASJH1YgJiX/eqFZObqepgsvIA4XjCgpyfwn9pDGafA= +github.com/containers/buildah v1.11.5-0.20191031204705-20e92ffe0982 h1:5WUe09k2sJSbmxwLHZLHc41TrIPrP0GlbhX+WDJBqvs= +github.com/containers/buildah v1.11.5-0.20191031204705-20e92ffe0982/go.mod h1:eGWB4tLoo0hIBuytQpvgUC0hk2mvl2ofaYBeDsU/qoc= github.com/containers/image/v5 v5.0.0 h1:arnXgbt1ucsC/ndtSpiQY87rA0UjhF+/xQnPzqdBDn4= github.com/containers/image/v5 v5.0.0/go.mod h1:MgiLzCfIeo8lrHi+4Lb8HP+rh513sm0Mlk6RrhjFOLY= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE= @@ -102,8 +100,6 @@ github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BU github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v0.0.0-20171019062838-86f080cff091/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v0.0.0-20180522102801-da99009bbb11/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v1.4.2-0.20190710153559-aa8249ae1b8b h1:+Ga+YpCDpcY1fln6GI0fiiirpqHGcob5/Vk3oKNuGdU= -github.com/docker/docker v1.4.2-0.20190710153559-aa8249ae1b8b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20190927142053-ada3c14355ce h1:H3csZuxZESJeeEiOxq4YXPNmLFbjl7u2qVBrAAGX/sA= github.com/docker/docker v1.4.2-0.20190927142053-ada3c14355ce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.0/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= @@ -139,8 +135,6 @@ github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8 github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsouza/go-dockerclient v1.4.4 h1:Sd5nD4wdAgiPxvrbYUzT2ZZNmPk3z+GGnZ+frvw8z04= -github.com/fsouza/go-dockerclient v1.4.4/go.mod h1:PrwszSL5fbmsESocROrOGq/NULMXRw+bajY0ltzD6MA= github.com/fsouza/go-dockerclient v1.5.0 h1:7OtayOe5HnoG+KWMHgyyPymwaodnB2IDYuVfseKyxbA= github.com/fsouza/go-dockerclient v1.5.0/go.mod h1:AqZZK/zFO3phxYxlTsAaeAMSdQ9mgHuhy+bjN034Qds= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -210,8 +204,6 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd h1:anPrsicrIi2ColgWTVPk+TrN42hJIWlfPHSBP9S0ZkM= -github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd/go.mod h1:3LVOLeyx9XVvwPgrt2be44XgSqndprz1G18rSk8KD84= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -293,6 +285,9 @@ github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -322,8 +317,6 @@ github.com/opencontainers/selinux v1.3.0 h1:xsI95WzPZu5exzA6JzkLSfdr/DilzOhCJOqG github.com/opencontainers/selinux v1.3.0/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= github.com/openshift/api v3.9.1-0.20190810003144-27fb16909b15+incompatible h1:s55wx8JIG/CKnewev892HifTBrtKzMdvgB3rm4rxC2s= github.com/openshift/api v3.9.1-0.20190810003144-27fb16909b15+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= -github.com/openshift/imagebuilder v1.1.0 h1:oT704SkwMEzmIMU/+Uv1Wmvt+p10q3v2WuYMeFI18c4= -github.com/openshift/imagebuilder v1.1.0/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo= github.com/openshift/imagebuilder v1.1.1 h1:KAUR31p8UBJdfVO42azWgb+LeMAed2zaKQ19e0C0X2I= github.com/openshift/imagebuilder v1.1.1/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= @@ -444,8 +437,6 @@ golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad h1:5E5raQxcv+6CZ11RrBYQe5WRbUIWpScjh0kvHZkZIrQ= golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -495,7 +486,6 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190902133755-9109b7679e13 h1:tdsQdquKbTNMsSZLqnLELJGzCANp9oXhu6zFBW6ODx4= golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -552,6 +542,8 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v0.0.0-20190624233834-05ebafbffc79/go.mod h1:R//lfYlUuTOTfblYI3lGoAAAebUdzjvbmQsuB7Ykd90= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= diff --git a/hack/man-page-checker b/hack/man-page-checker index 30d0b2113..99d280539 100755 --- a/hack/man-page-checker +++ b/hack/man-page-checker @@ -18,7 +18,7 @@ die() { exit 1 } -cd $(dirname $0)/../docs || die "Please run me from top-level libpod dir" +cd $(dirname $0)/../docs/source/markdown || die "Please run me from top-level libpod dir" rc=0 diff --git a/hack/podman-commands.sh b/hack/podman-commands.sh index 7530e20d0..32f94fc7b 100755 --- a/hack/podman-commands.sh +++ b/hack/podman-commands.sh @@ -34,7 +34,7 @@ function podman_man() { # This md file has a table of the form: # | [podman-cmd(1)\[(podman-cmd.1.md) | Description ... | # For all such, print the 'cmd' portion (the one in brackets). - sed -ne 's/^|\s\+\[podman-\([a-z]\+\)(1.*/\1/p' <docs/$1.1.md + sed -ne 's/^|\s\+\[podman-\([a-z]\+\)(1.*/\1/p' <docs/source/markdown/$1.1.md # Special case: there is no podman-help man page, nor need for such. echo "help" @@ -48,7 +48,7 @@ function podman_man() { # | cmd | [podman-cmd(1)](podman-cmd.1.md) | Description ... | # For all such we find, with 'podman- in the second column, print the # first column (with whitespace trimmed) - awk -F\| '$3 ~ /podman-/ { gsub(" ","",$2); print $2 }' < docs/$1.1.md + awk -F\| '$3 ~ /podman-/ { gsub(" ","",$2); print $2 }' < docs/source/markdown/$1.1.md fi } @@ -93,7 +93,7 @@ if [ $rc -ne 0 ]; then * podman man pages. * * The 'checking:' header indicates the specific command (and possibly -* subcommand) being tested, e.g. podman --help vs docs/podman.1.md. +* subcommand) being tested, e.g. podman --help vs docs/source/podman.1.md. * * A '-' indicates a subcommand present in 'podman --help' but not the * corresponding man page. diff --git a/install.md b/install.md index 2583c4f9d..39b639176 100644 --- a/install.md +++ b/install.md @@ -72,6 +72,8 @@ sudo apt-get install -qq -y software-properties-common uidmap sudo add-apt-repository -y ppa:projectatomic/ppa sudo apt-get update -qq sudo apt-get -qq -y install podman +sudo mkdir -p /etc/containers +echo -e "[registries.search]\nregistries = ['docker.io', 'quay.io']" | sudo tee /etc/containers/registries.conf ``` #### Fedora diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go index 0bb1df7b8..608a279c3 100644 --- a/libpod/boltdb_state.go +++ b/libpod/boltdb_state.go @@ -6,6 +6,7 @@ import ( "strings" "sync" + "github.com/containers/libpod/libpod/config" "github.com/containers/libpod/libpod/define" bolt "github.com/etcd-io/bbolt" jsoniter "github.com/json-iterator/go" @@ -291,12 +292,12 @@ func (s *BoltState) Refresh() error { // GetDBConfig retrieves runtime configuration fields that were created when // the database was first initialized -func (s *BoltState) GetDBConfig() (*DBConfig, error) { +func (s *BoltState) GetDBConfig() (*config.DBConfig, error) { if !s.valid { return nil, define.ErrDBClosed } - cfg := new(DBConfig) + cfg := new(config.DBConfig) db, err := s.getDBCon() if err != nil { diff --git a/libpod/common_test.go b/libpod/common_test.go index 93ca7bc71..83b162c8a 100644 --- a/libpod/common_test.go +++ b/libpod/common_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/containers/libpod/libpod/config" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/lock" "github.com/cri-o/ocicni/pkg/ocicni" @@ -74,7 +75,7 @@ func getTestContainer(id, name string, manager lock.Manager) (*Container, error) }, }, runtime: &Runtime{ - config: &RuntimeConfig{ + config: &config.Config{ VolumePath: "/does/not/exist/tmp/volumes", }, }, diff --git a/libpod/config/config.go b/libpod/config/config.go new file mode 100644 index 000000000..5b4b57f3a --- /dev/null +++ b/libpod/config/config.go @@ -0,0 +1,549 @@ +package config + +import ( + "bytes" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "regexp" + "strconv" + "strings" + + "github.com/BurntSushi/toml" + "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/rootless" + "github.com/containers/libpod/pkg/util" + "github.com/containers/storage" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +const ( + // _defaultTransport is a prefix that we apply to an image name to check + // docker hub first for the image. + _defaultTransport = "docker://" + + // _rootlessConfigPath is the path to the rootless libpod.conf in $HOME. + _rootlessConfigPath = ".config/containers/libpod.conf" + + // _conmonMinMajorVersion is the major version required for conmon. + _conmonMinMajorVersion = 2 + + // _conmonMinMinorVersion is the minor version required for conmon. + _conmonMinMinorVersion = 0 + + // _conmonMinPatchVersion is the sub-minor version required for conmon. + _conmonMinPatchVersion = 1 + + // _conmonVersionFormatErr is used when the expected versio-format of conmon + // has changed. + _conmonVersionFormatErr = "conmon version changed format" + + // InstallPrefix is the prefix where podman will be installed. + // It can be overridden at build time. + _installPrefix = "/usr" + + // EtcDir is the sysconfdir where podman should look for system config files. + // It can be overridden at build time. + _etcDir = "/etc" + + // SeccompDefaultPath defines the default seccomp path. + SeccompDefaultPath = _installPrefix + "/share/containers/seccomp.json" + + // SeccompOverridePath if this exists it overrides the default seccomp path. + SeccompOverridePath = _etcDir + "/crio/seccomp.json" + + // _rootConfigPath is the path to the libpod configuration file + // This file is loaded to replace the builtin default config before + // runtime options (e.g. WithStorageConfig) are applied. + // If it is not present, the builtin default config is used instead + // This path can be overridden when the runtime is created by using + // NewRuntimeFromConfig() instead of NewRuntime(). + _rootConfigPath = _installPrefix + "/share/containers/libpod.conf" + + // _rootOverrideConfigPath is the path to an override for the default libpod + // configuration file. If OverrideConfigPath exists, it will be used in + // place of the configuration file pointed to by ConfigPath. + _rootOverrideConfigPath = _etcDir + "/containers/libpod.conf" +) + +// SetOptions contains a subset of options in a Config. It's used to indicate if +// a given option has either been set by the user or by a parsed libpod +// configuration file. If not, the corresponding option might be overwritten by +// values from the database. This behavior guarantess backwards compat with +// older version of libpod and Podman. +type SetOptions struct { + // StorageConfigRunRootSet indicates if the RunRoot has been explicitly set + // by the config or by the user. It's required to guarantee backwards + // compatibility with older versions of libpod for which we must query the + // database configuration. Not included in the on-disk config. + StorageConfigRunRootSet bool `toml:"-"` + + // StorageConfigGraphRootSet indicates if the RunRoot has been explicitly + // set by the config or by the user. It's required to guarantee backwards + // compatibility with older versions of libpod for which we must query the + // database configuration. Not included in the on-disk config. + StorageConfigGraphRootSet bool `toml:"-"` + + // StorageConfigGraphDriverNameSet indicates if the GraphDriverName has been + // explicitly set by the config or by the user. It's required to guarantee + // backwards compatibility with older versions of libpod for which we must + // query the database configuration. Not included in the on-disk config. + StorageConfigGraphDriverNameSet bool `toml:"-"` + + // VolumePathSet indicates if the VolumePath has been explicitly set by the + // config or by the user. It's required to guarantee backwards compatibility + // with older versions of libpod for which we must query the database + // configuration. Not included in the on-disk config. + VolumePathSet bool `toml:"-"` + + // StaticDirSet indicates if the StaticDir has been explicitly set by the + // config or by the user. It's required to guarantee backwards compatibility + // with older versions of libpod for which we must query the database + // configuration. Not included in the on-disk config. + StaticDirSet bool `toml:"-"` + + // TmpDirSet indicates if the TmpDir has been explicitly set by the config + // or by the user. It's required to guarantee backwards compatibility with + // older versions of libpod for which we must query the database + // configuration. Not included in the on-disk config. + TmpDirSet bool `toml:"-"` +} + +// Config contains configuration options used to set up a libpod runtime +type Config struct { + // NOTE: when changing this struct, make sure to update (*Config).Merge(). + + // SetOptions contains a subset of config options. It's used to indicate if + // a given option has either been set by the user or by a parsed libpod + // configuration file. If not, the corresponding option might be + // overwritten by values from the database. This behavior guarantess + // backwards compat with older version of libpod and Podman. + SetOptions + + // StateType is the type of the backing state store. Avoid using multiple + // values for this with the same containers/storage configuration on the + // same system. Different state types do not interact, and each will see a + // separate set of containers, which may cause conflicts in + // containers/storage. As such this is not exposed via the config file. + StateType define.RuntimeStateStore `toml:"-"` + + // StorageConfig is the configuration used by containers/storage Not + // included in the on-disk config, use the dedicated containers/storage + // configuration file instead. + StorageConfig storage.StoreOptions `toml:"-"` + + // VolumePath is the default location that named volumes will be created + // under. This convention is followed by the default volume driver, but + // may not be by other drivers. + VolumePath string `toml:"volume_path"` + + // ImageDefaultTransport is the default transport method used to fetch + // images. + ImageDefaultTransport string `toml:"image_default_transport"` + + // SignaturePolicyPath is the path to a signature policy to use for + // validating images. If left empty, the containers/image default signature + // policy will be used. + SignaturePolicyPath string `toml:"signature_policy_path,omitempty"` + + // OCIRuntime is the OCI runtime to use. + OCIRuntime string `toml:"runtime"` + + // OCIRuntimes are the set of configured OCI runtimes (default is runc). + OCIRuntimes map[string][]string `toml:"runtimes"` + + // RuntimeSupportsJSON is the list of the OCI runtimes that support + // --format=json. + RuntimeSupportsJSON []string `toml:"runtime_supports_json"` + + // RuntimeSupportsNoCgroups is a list of OCI runtimes that support + // running containers without CGroups. + RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroups"` + + // RuntimePath is the path to OCI runtime binary for launching containers. + // The first path pointing to a valid file will be used This is used only + // when there are no OCIRuntime/OCIRuntimes defined. It is used only to be + // backward compatible with older versions of Podman. + RuntimePath []string `toml:"runtime_path"` + + // ConmonPath is the path to the Conmon binary used for managing containers. + // The first path pointing to a valid file will be used. + ConmonPath []string `toml:"conmon_path"` + + // ConmonEnvVars are environment variables to pass to the Conmon binary + // when it is launched. + ConmonEnvVars []string `toml:"conmon_env_vars"` + + // CGroupManager is the CGroup Manager to use Valid values are "cgroupfs" + // and "systemd". + CgroupManager string `toml:"cgroup_manager"` + + // InitPath is the path to the container-init binary. + InitPath string `toml:"init_path"` + + // StaticDir is the path to a persistent directory to store container + // files. + StaticDir string `toml:"static_dir"` + + // TmpDir is the path to a temporary directory to store per-boot container + // files. Must be stored in a tmpfs. + TmpDir string `toml:"tmp_dir"` + + // MaxLogSize is the maximum size of container logfiles. + MaxLogSize int64 `toml:"max_log_size,omitempty"` + + // NoPivotRoot sets whether to set no-pivot-root in the OCI runtime. + NoPivotRoot bool `toml:"no_pivot_root"` + + // CNIConfigDir sets the directory where CNI configuration files are + // stored. + CNIConfigDir string `toml:"cni_config_dir"` + + // CNIPluginDir sets a number of directories where the CNI network + // plugins can be located. + CNIPluginDir []string `toml:"cni_plugin_dir"` + + // CNIDefaultNetwork is the network name of the default CNI network + // to attach pods to. + CNIDefaultNetwork string `toml:"cni_default_network,omitempty"` + + // HooksDir holds paths to the directories containing hooks + // configuration files. When the same filename is present in in + // multiple directories, the file in the directory listed last in + // this slice takes precedence. + HooksDir []string `toml:"hooks_dir"` + + // DefaultMountsFile is the path to the default mounts file for testing + // purposes only. + DefaultMountsFile string `toml:"-"` + + // Namespace is the libpod namespace to use. Namespaces are used to create + // scopes to separate containers and pods in the state. When namespace is + // set, libpod will only view containers and pods in the same namespace. All + // containers and pods created will default to the namespace set here. A + // namespace of "", the empty string, is equivalent to no namespace, and all + // containers and pods will be visible. The default namespace is "". + Namespace string `toml:"namespace,omitempty"` + + // InfraImage is the image a pod infra container will use to manage + // namespaces. + InfraImage string `toml:"infra_image"` + + // InfraCommand is the command run to start up a pod infra container. + InfraCommand string `toml:"infra_command"` + + // EnablePortReservation determines whether libpod will reserve ports on the + // host when they are forwarded to containers. When enabled, when ports are + // forwarded to containers, they are held open by conmon as long as the + // container is running, ensuring that they cannot be reused by other + // programs on the host. However, this can cause significant memory usage if + // a container has many ports forwarded to it. Disabling this can save + // memory. + EnablePortReservation bool `toml:"enable_port_reservation"` + + // EnableLabeling indicates whether libpod will support container labeling. + EnableLabeling bool `toml:"label"` + + // NetworkCmdPath is the path to the slirp4netns binary. + NetworkCmdPath string `toml:"network_cmd_path"` + + // NumLocks is the number of locks to make available for containers and + // pods. + NumLocks uint32 `toml:"num_locks,omitempty"` + + // LockType is the type of locking to use. + LockType string `toml:"lock_type,omitempty"` + + // EventsLogger determines where events should be logged. + EventsLogger string `toml:"events_logger"` + + // EventsLogFilePath is where the events log is stored. + EventsLogFilePath string `toml:"events_logfile_path"` + + //DetachKeys is the sequence of keys used to detach a container. + DetachKeys string `toml:"detach_keys"` + + // SDNotify tells Libpod to allow containers to notify the host systemd of + // readiness using the SD_NOTIFY mechanism. + SDNotify bool +} + +// DBConfig is a set of Libpod runtime configuration settings that are saved in +// a State when it is first created, and can subsequently be retrieved. +type DBConfig struct { + LibpodRoot string + LibpodTmp string + StorageRoot string + StorageTmp string + GraphDriver string + VolumePath string +} + +// readConfigFromFile reads the specified config file at `path` and attempts to +// unmarshal its content into a Config. +func readConfigFromFile(path string) (*Config, error) { + var config Config + + configBytes, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + + logrus.Debugf("Reading configuration file %q", path) + err = toml.Unmarshal(configBytes, &config) + + // For the sake of backwards compat we need to check if the config fields + // with *Set suffix are set in the config. Note that the storage-related + // fields are NOT set in the config here but in the storage.conf OR directly + // by the user. + if config.VolumePath != "" { + config.VolumePathSet = true + } + if config.StaticDir != "" { + config.StaticDirSet = true + } + if config.TmpDir != "" { + config.TmpDirSet = true + } + + return &config, err +} + +// Write decodes the config as TOML and writes it to the specified path. +func (c *Config) Write(path string) error { + f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0666) + if err != nil { + return errors.Wrapf(err, "error opening config file %q", path) + } + + buffer := new(bytes.Buffer) + if err := toml.NewEncoder(buffer).Encode(c); err != nil { + return errors.Wrapf(err, "error encoding config") + } + + if _, err := f.WriteString(buffer.String()); err != nil { + return errors.Wrapf(err, "error writing config %q", path) + } + return err +} + +// FindConmon iterates over (*Config).ConmonPath and returns the path to first +// (version) matching conmon binary. If non is found, we try to do a path lookup +// of "conmon". +func (c *Config) FindConmon() (string, error) { + foundOutdatedConmon := false + for _, path := range c.ConmonPath { + stat, err := os.Stat(path) + if err != nil { + continue + } + if stat.IsDir() { + continue + } + if err := probeConmon(path); err != nil { + logrus.Warnf("Conmon at %s invalid: %v", path, err) + foundOutdatedConmon = true + continue + } + logrus.Debugf("Using conmon: %q", path) + return path, nil + } + + // Search the $PATH as last fallback + if path, err := exec.LookPath("conmon"); err == nil { + if err := probeConmon(path); err != nil { + logrus.Warnf("Conmon at %s is invalid: %v", path, err) + foundOutdatedConmon = true + } else { + logrus.Debugf("Using conmon from $PATH: %q", path) + return path, nil + } + } + + if foundOutdatedConmon { + return "", errors.Wrapf(define.ErrConmonOutdated, + "please update to v%d.%d.%d or later", + _conmonMinMajorVersion, _conmonMinMinorVersion, _conmonMinPatchVersion) + } + + return "", errors.Wrapf(define.ErrInvalidArg, + "could not find a working conmon binary (configured options: %v)", + c.ConmonPath) +} + +// probeConmon calls conmon --version and verifies it is a new enough version for +// the runtime expectations podman currently has. +func probeConmon(conmonBinary string) error { + cmd := exec.Command(conmonBinary, "--version") + var out bytes.Buffer + cmd.Stdout = &out + err := cmd.Run() + if err != nil { + return err + } + r := regexp.MustCompile(`^conmon version (?P<Major>\d+).(?P<Minor>\d+).(?P<Patch>\d+)`) + + matches := r.FindStringSubmatch(out.String()) + if len(matches) != 4 { + return errors.Wrap(err, _conmonVersionFormatErr) + } + major, err := strconv.Atoi(matches[1]) + if err != nil { + return errors.Wrap(err, _conmonVersionFormatErr) + } + if major < _conmonMinMajorVersion { + return define.ErrConmonOutdated + } + if major > _conmonMinMajorVersion { + return nil + } + + minor, err := strconv.Atoi(matches[2]) + if err != nil { + return errors.Wrap(err, _conmonVersionFormatErr) + } + if minor < _conmonMinMinorVersion { + return define.ErrConmonOutdated + } + if minor > _conmonMinMinorVersion { + return nil + } + + patch, err := strconv.Atoi(matches[3]) + if err != nil { + return errors.Wrap(err, _conmonVersionFormatErr) + } + if patch < _conmonMinPatchVersion { + return define.ErrConmonOutdated + } + if patch > _conmonMinPatchVersion { + return nil + } + + return nil +} + +// NewConfig creates a new Config. It starts with an empty config and, if +// specified, merges the config at `userConfigPath` path. Depending if we're +// running as root or rootless, we then merge the system configuration followed +// by merging the default config (hard-coded default in memory). +// +// Note that the OCI runtime is hard-set to `crun` if we're running on a system +// with cgroupsv2. Other OCI runtimes are not yet supporting cgroupsv2. This +// might change in the future. +func NewConfig(userConfigPath string) (*Config, error) { + config := &Config{} // start with an empty config + + // First, try to read the user-specified config + if userConfigPath != "" { + var err error + config, err = readConfigFromFile(userConfigPath) + if err != nil { + return nil, errors.Wrapf(err, "error reading user config %q", userConfigPath) + } + } + + // Now, check if the user can access system configs and merge them if needed. + if configs, err := systemConfigs(); err != nil { + return nil, errors.Wrapf(err, "error finding config on system") + } else { + for _, path := range configs { + systemConfig, err := readConfigFromFile(path) + if err != nil { + return nil, errors.Wrapf(err, "error reading system config %q", path) + } + // Merge the it into the config. Any unset field in config will be + // over-written by the systemConfig. + if err := config.mergeConfig(systemConfig); err != nil { + return nil, errors.Wrapf(err, "error merging system config") + } + logrus.Debugf("Merged system config %q: %v", path, config) + } + } + + // Finally, create a default config from memory and forcefully merge it into + // the config. This way we try to make sure that all fields are properly set + // and that user AND system config can partially set. + if defaultConfig, err := defaultConfigFromMemory(); err != nil { + return nil, errors.Wrapf(err, "error generating default config from memory") + } else { + if err := config.mergeConfig(defaultConfig); err != nil { + return nil, errors.Wrapf(err, "error merging default config from memory") + } + } + + // Relative paths can cause nasty bugs, because core paths we use could + // shift between runs (or even parts of the program - the OCI runtime + // uses a different working directory than we do, for example. + if !filepath.IsAbs(config.StaticDir) { + return nil, errors.Wrapf(define.ErrInvalidArg, "static directory must be an absolute path - instead got %q", config.StaticDir) + } + if !filepath.IsAbs(config.TmpDir) { + return nil, errors.Wrapf(define.ErrInvalidArg, "temporary directory must be an absolute path - instead got %q", config.TmpDir) + } + if !filepath.IsAbs(config.VolumePath) { + return nil, errors.Wrapf(define.ErrInvalidArg, "volume path must be an absolute path - instead got %q", config.VolumePath) + } + + // Check if we need to switch to cgroupfs on rootless. + config.checkCgroupsAndAdjustConfig() + + return config, nil +} + +func rootlessConfigPath() (string, error) { + home, err := util.HomeDir() + if err != nil { + return "", err + } + + return filepath.Join(home, _rootlessConfigPath), nil +} + +func systemConfigs() ([]string, error) { + if rootless.IsRootless() { + path, err := rootlessConfigPath() + if err != nil { + return nil, err + } + if _, err := os.Stat(path); err == nil { + return []string{path}, nil + } + return nil, err + } + + configs := []string{} + if _, err := os.Stat(_rootOverrideConfigPath); err == nil { + configs = append(configs, _rootOverrideConfigPath) + } + if _, err := os.Stat(_rootConfigPath); err == nil { + configs = append(configs, _rootConfigPath) + } + return configs, nil +} + +// checkCgroupsAndAdjustConfig checks if we're running rootless with the systemd +// cgroup manager. In case the user session isn't available, we're switching the +// cgroup manager to cgroupfs. Note, this only applies to rootless. +func (c *Config) checkCgroupsAndAdjustConfig() { + if !rootless.IsRootless() || c.CgroupManager != define.SystemdCgroupsManager { + return + } + + 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` (possibly as root)", rootless.GetRootlessUID()) + logrus.Warningf("Falling back to --cgroup-manager=cgroupfs") + c.CgroupManager = define.CgroupfsCgroupsManager + } +} diff --git a/libpod/config/config_test.go b/libpod/config/config_test.go new file mode 100644 index 000000000..47c092440 --- /dev/null +++ b/libpod/config/config_test.go @@ -0,0 +1,64 @@ +package config + +import ( + "reflect" + "testing" + + "github.com/containers/libpod/libpod/define" + "github.com/containers/storage" + "github.com/stretchr/testify/assert" +) + +func TestEmptyConfig(t *testing.T) { + // Make sure that we can read empty configs + config, err := readConfigFromFile("testdata/empty.conf") + assert.NotNil(t, config) + assert.Nil(t, err) +} + +func TestDefaultLibpodConf(t *testing.T) { + // Make sure that we can read the default libpod.conf + config, err := readConfigFromFile("testdata/libpod.conf") + assert.NotNil(t, config) + assert.Nil(t, err) +} + +func TestMergeEmptyAndDefaultMemoryConfig(t *testing.T) { + // Make sure that when we merge the default config into an empty one that we + // effectively get the default config. + defaultConfig, err := defaultConfigFromMemory() + assert.NotNil(t, defaultConfig) + assert.Nil(t, err) + defaultConfig.StateType = define.InvalidStateStore + defaultConfig.StorageConfig = storage.StoreOptions{} + + emptyConfig, err := readConfigFromFile("testdata/empty.conf") + assert.NotNil(t, emptyConfig) + assert.Nil(t, err) + + err = emptyConfig.mergeConfig(defaultConfig) + assert.Nil(t, err) + + equal := reflect.DeepEqual(emptyConfig, defaultConfig) + assert.True(t, equal) +} + +func TestMergeEmptyAndLibpodConfig(t *testing.T) { + // Make sure that when we merge the default config into an empty one that we + // effectively get the default config. + libpodConfig, err := readConfigFromFile("testdata/libpod.conf") + assert.NotNil(t, libpodConfig) + assert.Nil(t, err) + libpodConfig.StateType = define.InvalidStateStore + libpodConfig.StorageConfig = storage.StoreOptions{} + + emptyConfig, err := readConfigFromFile("testdata/empty.conf") + assert.NotNil(t, emptyConfig) + assert.Nil(t, err) + + err = emptyConfig.mergeConfig(libpodConfig) + assert.Nil(t, err) + + equal := reflect.DeepEqual(emptyConfig, libpodConfig) + assert.True(t, equal) +} diff --git a/libpod/config/default.go b/libpod/config/default.go new file mode 100644 index 000000000..17574c059 --- /dev/null +++ b/libpod/config/default.go @@ -0,0 +1,137 @@ +package config + +import ( + "os" + "path/filepath" + + "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/libpod/events" + "github.com/containers/libpod/pkg/rootless" + "github.com/containers/libpod/pkg/util" + "github.com/containers/storage" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +const ( + // _defaultGraphRoot points to the default path of the graph root. + _defaultGraphRoot = "/var/lib/containers/storage" + // _defaultRootlessSignaturePolicyPath points to the default path of the + // rootless policy.json file. + _defaultRootlessSignaturePolicyPath = ".config/containers/policy.json" +) + +// defaultConfigFromMemory returns a default libpod configuration. Note that the +// config is different for root and rootless. It also parses the storage.conf. +func defaultConfigFromMemory() (*Config, error) { + c := new(Config) + if tmp, err := defaultTmpDir(); err != nil { + return nil, err + } else { + c.TmpDir = tmp + } + c.EventsLogFilePath = filepath.Join(c.TmpDir, "events", "events.log") + + storeOpts, err := storage.DefaultStoreOptions(rootless.IsRootless(), rootless.GetRootlessUID()) + if err != nil { + return nil, err + } + if storeOpts.GraphRoot == "" { + logrus.Warnf("Storage configuration is unset - using hardcoded default graph root %q", _defaultGraphRoot) + storeOpts.GraphRoot = _defaultGraphRoot + } + c.StaticDir = filepath.Join(storeOpts.GraphRoot, "libpod") + c.VolumePath = filepath.Join(storeOpts.GraphRoot, "volumes") + c.StorageConfig = storeOpts + + c.ImageDefaultTransport = _defaultTransport + c.StateType = define.BoltDBStateStore + c.OCIRuntime = "runc" + c.OCIRuntimes = map[string][]string{ + "runc": { + "/usr/bin/runc", + "/usr/sbin/runc", + "/usr/local/bin/runc", + "/usr/local/sbin/runc", + "/sbin/runc", + "/bin/runc", + "/usr/lib/cri-o-runc/sbin/runc", + "/run/current-system/sw/bin/runc", + }, + // TODO - should we add "crun" defaults here as well? + } + c.ConmonPath = []string{ + "/usr/libexec/podman/conmon", + "/usr/local/libexec/podman/conmon", + "/usr/local/lib/podman/conmon", + "/usr/bin/conmon", + "/usr/sbin/conmon", + "/usr/local/bin/conmon", + "/usr/local/sbin/conmon", + "/run/current-system/sw/bin/conmon", + } + c.ConmonEnvVars = []string{ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + } + c.RuntimeSupportsJSON = []string{ + "crun", + "runc", + } + c.RuntimeSupportsNoCgroups = []string{"crun"} + c.InitPath = define.DefaultInitPath + c.CgroupManager = define.SystemdCgroupsManager + c.MaxLogSize = -1 + c.NoPivotRoot = false + c.CNIConfigDir = _etcDir + "/cni/net.d/" + c.CNIPluginDir = []string{ + "/usr/libexec/cni", + "/usr/lib/cni", + "/usr/local/lib/cni", + "/opt/cni/bin", + } + c.CNIDefaultNetwork = "podman" + c.InfraCommand = define.DefaultInfraCommand + c.InfraImage = define.DefaultInfraImage + c.EnablePortReservation = true + c.EnableLabeling = true + c.NumLocks = 2048 + c.EventsLogger = events.DefaultEventerType.String() + c.DetachKeys = define.DefaultDetachKeys + // TODO - ideally we should expose a `type LockType string` along with + // constants. + c.LockType = "shm" + + if rootless.IsRootless() { + home, err := util.HomeDir() + if err != nil { + return nil, err + } + sigPath := filepath.Join(home, _defaultRootlessSignaturePolicyPath) + if _, err := os.Stat(sigPath); err == nil { + c.SignaturePolicyPath = sigPath + } + } + return c, nil +} + +func defaultTmpDir() (string, error) { + if !rootless.IsRootless() { + return "/var/run/libpod", nil + } + + runtimeDir, err := util.GetRuntimeDir() + if err != nil { + return "", err + } + libpodRuntimeDir := filepath.Join(runtimeDir, "libpod") + + if err := os.Mkdir(libpodRuntimeDir, 0700|os.ModeSticky); err != nil { + if !os.IsExist(err) { + return "", errors.Wrapf(err, "cannot mkdir %s", libpodRuntimeDir) + } else if err := os.Chmod(libpodRuntimeDir, 0700|os.ModeSticky); err != nil { + // The directory already exist, just set the sticky bit + return "", errors.Wrapf(err, "could not set sticky bit on %s", libpodRuntimeDir) + } + } + return filepath.Join(libpodRuntimeDir, "tmp"), nil +} diff --git a/libpod/config/merge.go b/libpod/config/merge.go new file mode 100644 index 000000000..798a63da7 --- /dev/null +++ b/libpod/config/merge.go @@ -0,0 +1,183 @@ +package config + +import ( + "path/filepath" + + "github.com/containers/libpod/libpod/define" + "github.com/sirupsen/logrus" +) + +// Merge merges the other config into the current one. Note that a field of the +// other config is only merged when it's not already set in the current one. +// +// Note that the StateType and the StorageConfig will NOT be changed. +func (c *Config) mergeConfig(other *Config) error { + // strings + c.CgroupManager = mergeStrings(c.CgroupManager, other.CgroupManager) + c.CNIConfigDir = mergeStrings(c.CNIConfigDir, other.CNIConfigDir) + c.CNIDefaultNetwork = mergeStrings(c.CNIDefaultNetwork, other.CNIDefaultNetwork) + c.DefaultMountsFile = mergeStrings(c.DefaultMountsFile, other.DefaultMountsFile) + c.DetachKeys = mergeStrings(c.DetachKeys, other.DetachKeys) + c.EventsLogFilePath = mergeStrings(c.EventsLogFilePath, other.EventsLogFilePath) + c.EventsLogger = mergeStrings(c.EventsLogger, other.EventsLogger) + c.ImageDefaultTransport = mergeStrings(c.ImageDefaultTransport, other.ImageDefaultTransport) + c.InfraCommand = mergeStrings(c.InfraCommand, other.InfraCommand) + c.InfraImage = mergeStrings(c.InfraImage, other.InfraImage) + c.InitPath = mergeStrings(c.InitPath, other.InitPath) + c.LockType = mergeStrings(c.LockType, other.LockType) + c.Namespace = mergeStrings(c.Namespace, other.Namespace) + c.NetworkCmdPath = mergeStrings(c.NetworkCmdPath, other.NetworkCmdPath) + c.OCIRuntime = mergeStrings(c.OCIRuntime, other.OCIRuntime) + c.SignaturePolicyPath = mergeStrings(c.SignaturePolicyPath, other.SignaturePolicyPath) + c.StaticDir = mergeStrings(c.StaticDir, other.StaticDir) + c.TmpDir = mergeStrings(c.TmpDir, other.TmpDir) + c.VolumePath = mergeStrings(c.VolumePath, other.VolumePath) + + // string map of slices + c.OCIRuntimes = mergeStringMaps(c.OCIRuntimes, other.OCIRuntimes) + + // string slices + c.CNIPluginDir = mergeStringSlices(c.CNIPluginDir, other.CNIPluginDir) + c.ConmonEnvVars = mergeStringSlices(c.ConmonEnvVars, other.ConmonEnvVars) + c.ConmonPath = mergeStringSlices(c.ConmonPath, other.ConmonPath) + c.HooksDir = mergeStringSlices(c.HooksDir, other.HooksDir) + c.RuntimePath = mergeStringSlices(c.RuntimePath, other.RuntimePath) + c.RuntimeSupportsJSON = mergeStringSlices(c.RuntimeSupportsJSON, other.RuntimeSupportsJSON) + c.RuntimeSupportsNoCgroups = mergeStringSlices(c.RuntimeSupportsNoCgroups, other.RuntimeSupportsNoCgroups) + + // int64s + c.MaxLogSize = mergeInt64s(c.MaxLogSize, other.MaxLogSize) + + // uint32s + c.NumLocks = mergeUint32s(c.NumLocks, other.NumLocks) + + // bools + c.EnableLabeling = mergeBools(c.EnableLabeling, other.EnableLabeling) + c.EnablePortReservation = mergeBools(c.EnablePortReservation, other.EnablePortReservation) + c.NoPivotRoot = mergeBools(c.NoPivotRoot, other.NoPivotRoot) + c.SDNotify = mergeBools(c.SDNotify, other.SDNotify) + + // state type + if c.StateType == define.InvalidStateStore { + c.StateType = other.StateType + } + + // store options - need to check all fields since some configs might only + // set it partially + c.StorageConfig.RunRoot = mergeStrings(c.StorageConfig.RunRoot, other.StorageConfig.RunRoot) + c.StorageConfig.GraphRoot = mergeStrings(c.StorageConfig.GraphRoot, other.StorageConfig.GraphRoot) + c.StorageConfig.GraphDriverName = mergeStrings(c.StorageConfig.GraphDriverName, other.StorageConfig.GraphDriverName) + c.StorageConfig.GraphDriverOptions = mergeStringSlices(c.StorageConfig.GraphDriverOptions, other.StorageConfig.GraphDriverOptions) + if c.StorageConfig.UIDMap == nil { + c.StorageConfig.UIDMap = other.StorageConfig.UIDMap + } + if c.StorageConfig.GIDMap == nil { + c.StorageConfig.GIDMap = other.StorageConfig.GIDMap + } + + // backwards compat *Set fields + c.StorageConfigRunRootSet = mergeBools(c.StorageConfigRunRootSet, other.StorageConfigRunRootSet) + c.StorageConfigGraphRootSet = mergeBools(c.StorageConfigGraphRootSet, other.StorageConfigGraphRootSet) + c.StorageConfigGraphDriverNameSet = mergeBools(c.StorageConfigGraphDriverNameSet, other.StorageConfigGraphDriverNameSet) + c.VolumePathSet = mergeBools(c.VolumePathSet, other.VolumePathSet) + c.StaticDirSet = mergeBools(c.StaticDirSet, other.StaticDirSet) + c.TmpDirSet = mergeBools(c.TmpDirSet, other.TmpDirSet) + + return nil +} + +// MergeDBConfig merges the configuration from the database. +func (c *Config) MergeDBConfig(dbConfig *DBConfig) error { + + if !c.StorageConfigRunRootSet && dbConfig.StorageTmp != "" { + if c.StorageConfig.RunRoot != dbConfig.StorageTmp && + c.StorageConfig.RunRoot != "" { + logrus.Debugf("Overriding run root %q with %q from database", + c.StorageConfig.RunRoot, dbConfig.StorageTmp) + } + c.StorageConfig.RunRoot = dbConfig.StorageTmp + } + + if !c.StorageConfigGraphRootSet && dbConfig.StorageRoot != "" { + if c.StorageConfig.GraphRoot != dbConfig.StorageRoot && + c.StorageConfig.GraphRoot != "" { + logrus.Debugf("Overriding graph root %q with %q from database", + c.StorageConfig.GraphRoot, dbConfig.StorageRoot) + } + c.StorageConfig.GraphRoot = dbConfig.StorageRoot + } + + if !c.StorageConfigGraphDriverNameSet && dbConfig.GraphDriver != "" { + if c.StorageConfig.GraphDriverName != dbConfig.GraphDriver && + c.StorageConfig.GraphDriverName != "" { + logrus.Errorf("User-selected graph driver %q overwritten by graph driver %q from database - delete libpod local files to resolve", + c.StorageConfig.GraphDriverName, dbConfig.GraphDriver) + } + c.StorageConfig.GraphDriverName = dbConfig.GraphDriver + } + + if !c.StaticDirSet && dbConfig.LibpodRoot != "" { + if c.StaticDir != dbConfig.LibpodRoot && c.StaticDir != "" { + logrus.Debugf("Overriding static dir %q with %q from database", c.StaticDir, dbConfig.LibpodRoot) + } + c.StaticDir = dbConfig.LibpodRoot + } + + if !c.TmpDirSet && dbConfig.LibpodTmp != "" { + if c.TmpDir != dbConfig.LibpodTmp && c.TmpDir != "" { + logrus.Debugf("Overriding tmp dir %q with %q from database", c.TmpDir, dbConfig.LibpodTmp) + } + c.TmpDir = dbConfig.LibpodTmp + c.EventsLogFilePath = filepath.Join(dbConfig.LibpodTmp, "events", "events.log") + } + + if !c.VolumePathSet && dbConfig.VolumePath != "" { + if c.VolumePath != dbConfig.VolumePath && c.VolumePath != "" { + logrus.Debugf("Overriding volume path %q with %q from database", c.VolumePath, dbConfig.VolumePath) + } + c.VolumePath = dbConfig.VolumePath + } + return nil +} + +func mergeStrings(a, b string) string { + if a == "" { + return b + } + return a +} + +func mergeStringSlices(a, b []string) []string { + if len(a) == 0 && b != nil { + return b + } + return a +} + +func mergeStringMaps(a, b map[string][]string) map[string][]string { + if len(a) == 0 && b != nil { + return b + } + return a +} + +func mergeInt64s(a, b int64) int64 { + if a == 0 { + return b + } + return a +} + +func mergeUint32s(a, b uint32) uint32 { + if a == 0 { + return b + } + return a +} + +func mergeBools(a, b bool) bool { + if !a { + return b + } + return a +} diff --git a/libpod/config/merge_test.go b/libpod/config/merge_test.go new file mode 100644 index 000000000..eb450b273 --- /dev/null +++ b/libpod/config/merge_test.go @@ -0,0 +1,157 @@ +package config + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMergeStrings(t *testing.T) { + testData := []struct { + a string + b string + res string + }{ + {"", "", ""}, + {"a", "", "a"}, + {"a", "b", "a"}, + {"", "b", "b"}, + } + for _, data := range testData { + res := mergeStrings(data.a, data.b) + assert.Equal(t, data.res, res) + } +} + +func TestMergeStringSlices(t *testing.T) { + testData := []struct { + a []string + b []string + res []string + }{ + { + nil, nil, nil, + }, + { + nil, + []string{}, + []string{}, + }, + { + []string{}, + nil, + []string{}, + }, + { + []string{}, + []string{}, + []string{}, + }, + { + []string{"a"}, + []string{}, + []string{"a"}, + }, + { + []string{"a"}, + []string{"b"}, + []string{"a"}, + }, + { + []string{}, + []string{"b"}, + []string{"b"}, + }, + } + for _, data := range testData { + res := mergeStringSlices(data.a, data.b) + assert.Equal(t, data.res, res) + } +} + +func TestMergeStringMaps(t *testing.T) { + testData := []struct { + a map[string][]string + b map[string][]string + res map[string][]string + }{ + { + nil, nil, nil, + }, + { + nil, + map[string][]string{}, + map[string][]string{}}, + { + map[string][]string{"a": {"a"}}, + nil, + map[string][]string{"a": {"a"}}, + }, + { + nil, + map[string][]string{"b": {"b"}}, + map[string][]string{"b": {"b"}}, + }, + { + map[string][]string{"a": {"a"}}, + map[string][]string{"b": {"b"}}, + map[string][]string{"a": {"a"}}, + }, + } + for _, data := range testData { + res := mergeStringMaps(data.a, data.b) + assert.Equal(t, data.res, res) + } +} + +func TestMergeInts64(t *testing.T) { + testData := []struct { + a int64 + b int64 + res int64 + }{ + {int64(0), int64(0), int64(0)}, + {int64(1), int64(0), int64(1)}, + {int64(0), int64(1), int64(1)}, + {int64(2), int64(1), int64(2)}, + {int64(-1), int64(1), int64(-1)}, + {int64(0), int64(-1), int64(-1)}, + } + for _, data := range testData { + res := mergeInt64s(data.a, data.b) + assert.Equal(t, data.res, res) + } +} +func TestMergeUint32(t *testing.T) { + testData := []struct { + a uint32 + b uint32 + res uint32 + }{ + {uint32(0), uint32(0), uint32(0)}, + {uint32(1), uint32(0), uint32(1)}, + {uint32(0), uint32(1), uint32(1)}, + {uint32(2), uint32(1), uint32(2)}, + } + for _, data := range testData { + res := mergeUint32s(data.a, data.b) + assert.Equal(t, data.res, res) + } +} + +func TestMergeBools(t *testing.T) { + testData := []struct { + a bool + b bool + res bool + }{ + {false, false, false}, + {true, false, true}, + {false, true, true}, + {true, true, true}, + } + for _, data := range testData { + res := mergeBools(data.a, data.b) + assert.Equal(t, data.res, res) + } +} diff --git a/libpod/config/testdata/empty.conf b/libpod/config/testdata/empty.conf new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/libpod/config/testdata/empty.conf diff --git a/libpod/config/testdata/libpod.conf b/libpod/config/testdata/libpod.conf new file mode 120000 index 000000000..17d09fe4a --- /dev/null +++ b/libpod/config/testdata/libpod.conf @@ -0,0 +1 @@ +../../../libpod.conf
\ No newline at end of file diff --git a/libpod/container.go b/libpod/container.go index 5a7cf202b..8e24391b9 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -1059,9 +1059,9 @@ func (c *Container) NamespacePath(linuxNS LinuxNS) (string, error) { //nolint:in // CGroupPath returns a cgroups "path" for a given container. func (c *Container) CGroupPath() (string, error) { switch c.runtime.config.CgroupManager { - case CgroupfsCgroupsManager: + case define.CgroupfsCgroupsManager: return filepath.Join(c.config.CgroupParent, fmt.Sprintf("libpod-%s", c.ID())), nil - case SystemdCgroupsManager: + case define.SystemdCgroupsManager: if rootless.IsRootless() { uid := rootless.GetRootlessUID() return filepath.Join(c.config.CgroupParent, fmt.Sprintf("user-%d.slice/user@%d.service/user.slice", uid, uid), createUnitName("libpod", c.ID())), nil diff --git a/libpod/container_api.go b/libpod/container_api.go index 1b2d52ce3..a6f5b54d5 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -1,6 +1,7 @@ package libpod import ( + "bufio" "context" "io" "io/ioutil" @@ -361,7 +362,7 @@ type AttachStreams struct { // ErrorStream will be attached to container's STDERR ErrorStream io.WriteCloser // InputStream will be attached to container's STDIN - InputStream io.Reader + InputStream *bufio.Reader // AttachOutput is whether to attach to STDOUT // If false, stdout will not be attached AttachOutput bool diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index d28d37937..66aca23ed 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -1322,9 +1322,9 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named // Need to check if it's the default, and not print if so. defaultCgroupParent := "" switch c.runtime.config.CgroupManager { - case CgroupfsCgroupsManager: + case define.CgroupfsCgroupsManager: defaultCgroupParent = CgroupfsDefaultCgroupParent - case SystemdCgroupsManager: + case define.SystemdCgroupsManager: defaultCgroupParent = SystemdDefaultCgroupParent } if c.config.CgroupParent != defaultCgroupParent { diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 283d38a0f..471648bc8 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -1088,7 +1088,7 @@ func (c *Container) makeBindMounts() error { } // Add Secret Mounts - secretMounts := secrets.SecretMountsWithUIDGID(c.config.MountLabel, c.state.RunDir, c.runtime.config.DefaultMountsFile, c.state.RunDir, c.RootUID(), c.RootGID(), rootless.IsRootless()) + secretMounts := secrets.SecretMountsWithUIDGID(c.config.MountLabel, c.state.RunDir, c.runtime.config.DefaultMountsFile, c.state.RunDir, c.RootUID(), c.RootGID(), rootless.IsRootless(), false) for _, mount := range secretMounts { if _, ok := c.state.BindMounts[mount.Destination]; !ok { c.state.BindMounts[mount.Destination] = mount.Source @@ -1326,14 +1326,14 @@ func (c *Container) getOCICgroupPath() (string, error) { } if (rootless.IsRootless() && !unified) || c.config.NoCgroups { return "", nil - } else if c.runtime.config.CgroupManager == SystemdCgroupsManager { + } else if c.runtime.config.CgroupManager == define.SystemdCgroupsManager { // When runc is set to use Systemd as a cgroup manager, it // expects cgroups to be passed as follows: // slice:prefix:name systemdCgroups := fmt.Sprintf("%s:libpod:%s", path.Base(c.config.CgroupParent), c.ID()) logrus.Debugf("Setting CGroups for container %s to %s", c.ID(), systemdCgroups) return systemdCgroups, nil - } else if c.runtime.config.CgroupManager == CgroupfsCgroupsManager { + } else if c.runtime.config.CgroupManager == define.CgroupfsCgroupsManager { cgroupPath, err := c.CGroupPath() if err != nil { return "", err diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go index 8a87a8796..c4acc3d4f 100644 --- a/libpod/container_log_linux.go +++ b/libpod/container_log_linux.go @@ -6,6 +6,7 @@ package libpod import ( "fmt" "io" + "math" "strings" "time" @@ -30,7 +31,11 @@ const ( func (c *Container) readFromJournal(options *logs.LogOptions, logChannel chan *logs.LogLine) error { var config journal.JournalReaderConfig - config.NumFromTail = options.Tail + if options.Tail < 0 { + config.NumFromTail = math.MaxUint64 + } else { + config.NumFromTail = uint64(options.Tail) + } config.Formatter = journalFormatter defaultTime := time.Time{} if options.Since != defaultTime { @@ -54,7 +59,7 @@ func (c *Container) readFromJournal(options *logs.LogOptions, logChannel chan *l if r == nil { return errors.Errorf("journal reader creation failed") } - if options.Tail == 0 { + if options.Tail == math.MaxInt64 { r.Rewind() } diff --git a/libpod/define/config.go b/libpod/define/config.go index c66f67feb..8bd59be75 100644 --- a/libpod/define/config.go +++ b/libpod/define/config.go @@ -7,11 +7,23 @@ var ( DefaultInfraImage = "k8s.gcr.io/pause:3.1" // DefaultInfraCommand to be run in an infra container DefaultInfraCommand = "/pause" + // DefaultSHMLockPath is the default path for SHM locks + DefaultSHMLockPath = "/libpod_lock" + // DefaultRootlessSHMLockPath is the default path for rootless SHM locks + DefaultRootlessSHMLockPath = "/libpod_rootless_lock" + // DefaultDetachKeys is the default keys sequence for detaching a + // container + DefaultDetachKeys = "ctrl-p,ctrl-q" ) -// CtrRemoveTimeout is the default number of seconds to wait after stopping a container -// before sending the kill signal -const CtrRemoveTimeout = 10 +const ( + // CtrRemoveTimeout is the default number of seconds to wait after stopping a container + // before sending the kill signal + CtrRemoveTimeout = 10 + // DefaultTransport is a prefix that we apply to an image name + // to check docker hub first for the image + DefaultTransport = "docker://" +) // InfoData holds the info type, i.e store, host etc and the data for each type type InfoData struct { diff --git a/libpod/define/runtime.go b/libpod/define/runtime.go new file mode 100644 index 000000000..4d8c6cb4d --- /dev/null +++ b/libpod/define/runtime.go @@ -0,0 +1,37 @@ +package define + +import "time" + +// RuntimeStateStore is a constant indicating which state store implementation +// should be used by libpod +type RuntimeStateStore int + +const ( + // InvalidStateStore is an invalid state store + InvalidStateStore RuntimeStateStore = iota + // InMemoryStateStore is an in-memory state that will not persist data + // on containers and pods between libpod instances or after system + // reboot + InMemoryStateStore RuntimeStateStore = iota + // SQLiteStateStore is a state backed by a SQLite database + // It is presently disabled + SQLiteStateStore RuntimeStateStore = iota + // BoltDBStateStore is a state backed by a BoltDB database + BoltDBStateStore RuntimeStateStore = iota + // CgroupfsCgroupsManager represents cgroupfs native cgroup manager + CgroupfsCgroupsManager = "cgroupfs" + // SystemdCgroupsManager represents systemd native cgroup manager + SystemdCgroupsManager = "systemd" + // ContainerCreateTimeout is the timeout before we decide we've failed + // to create a container. + // TODO: Make this generic - all OCI runtime operations should use the + // same timeout, this one. + // TODO: Consider dropping from 240 to 60 seconds. I don't think waiting + // 4 minutes versus 1 minute makes a real difference. + ContainerCreateTimeout = 240 * time.Second + // DefaultShmSize is the default shm size + DefaultShmSize = 64 * 1024 * 1024 + // NsRunDir is the default directory in which running network namespaces + // are stored + NsRunDir = "/var/run/netns" +) diff --git a/libpod/healthcheck.go b/libpod/healthcheck.go index 68ffc2349..e9c950713 100644 --- a/libpod/healthcheck.go +++ b/libpod/healthcheck.go @@ -133,7 +133,9 @@ func (c *Container) runHealthCheck() (HealthCheckStatus, error) { streams := new(AttachStreams) streams.OutputStream = hcw streams.ErrorStream = hcw - streams.InputStream = os.Stdin + + streams.InputStream = bufio.NewReader(os.Stdin) + streams.AttachOutput = true streams.AttachError = true streams.AttachInput = true diff --git a/libpod/image/pull.go b/libpod/image/pull.go index 7f5dc33b9..99c11e3ff 100644 --- a/libpod/image/pull.go +++ b/libpod/image/pull.go @@ -230,7 +230,12 @@ func (ir *Runtime) pullImageFromHeuristicSource(ctx context.Context, inputName s sc.BlobInfoCacheDir = filepath.Join(ir.store.GraphRoot(), "cache") srcRef, err := alltransports.ParseImageName(inputName) if err != nil { - // could be trying to pull from registry with short name + // We might be pulling with an unqualified image reference in which case + // we need to make sure that we're not using any other transport. + srcTransport := alltransports.TransportFromImageName(inputName) + if srcTransport != nil && srcTransport.Name() != DockerTransport { + return nil, err + } goal, err = ir.pullGoalFromPossiblyUnqualifiedName(inputName) if err != nil { return nil, errors.Wrap(err, "error getting default registries to try") @@ -347,6 +352,7 @@ func (ir *Runtime) pullGoalFromPossiblyUnqualifiedName(inputName string) (*pullG if err != nil { return nil, err } + if decomposedImage.hasRegistry { srcRef, err := docker.ParseReference("//" + inputName) if err != nil { diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go index 5ab258772..2144671a5 100644 --- a/libpod/in_memory_state.go +++ b/libpod/in_memory_state.go @@ -3,6 +3,7 @@ package libpod import ( "strings" + "github.com/containers/libpod/libpod/config" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/registrar" "github.com/containers/storage/pkg/truncindex" @@ -80,8 +81,8 @@ func (s *InMemoryState) Refresh() error { // GetDBConfig is not implemented for in-memory state. // As we do not store a config, return an empty one. -func (s *InMemoryState) GetDBConfig() (*DBConfig, error) { - return &DBConfig{}, nil +func (s *InMemoryState) GetDBConfig() (*config.DBConfig, error) { + return &config.DBConfig{}, nil } // ValidateDBConfig is not implemented for the in-memory state. diff --git a/libpod/logs/log.go b/libpod/logs/log.go index 0b1703567..0330df06a 100644 --- a/libpod/logs/log.go +++ b/libpod/logs/log.go @@ -31,7 +31,7 @@ type LogOptions struct { Details bool Follow bool Since time.Time - Tail uint64 + Tail int64 Timestamps bool Multi bool WaitGroup *sync.WaitGroup @@ -54,8 +54,10 @@ func GetLogFile(path string, options *LogOptions) (*tail.Tail, []*LogLine, error logTail []*LogLine ) // whence 0=origin, 2=end - if options.Tail > 0 { + if options.Tail >= 0 { whence = 2 + } + if options.Tail > 0 { logTail, err = getTailLog(path, int(options.Tail)) if err != nil { return nil, nil, err diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index daa0619a2..ac1144fbe 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -295,7 +295,7 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) { defer close(chWait) // wait that API socket file appears before trying to use it. - if _, err := WaitForFile(apiSocket, chWait, pidWaitTimeout*time.Millisecond); err != nil { + if _, err := WaitForFile(apiSocket, chWait, pidWaitTimeout); err != nil { return errors.Wrapf(err, "waiting for slirp4nets to create the api socket file %s", apiSocket) } diff --git a/libpod/oci_attach_linux.go b/libpod/oci_attach_linux.go index a383f6eab..eeaee6d43 100644 --- a/libpod/oci_attach_linux.go +++ b/libpod/oci_attach_linux.go @@ -152,7 +152,7 @@ func (c *Container) attachToExec(streams *AttachStreams, keys string, resize <-c func processDetachKeys(keys string) ([]byte, error) { // Check the validity of the provided keys first if len(keys) == 0 { - keys = DefaultDetachKeys + keys = define.DefaultDetachKeys } detachKeys, err := term.ToBytes(keys) if err != nil { diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index d9907c5b1..026b13129 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -16,6 +16,7 @@ import ( "syscall" "time" + "github.com/containers/libpod/libpod/config" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/cgroups" "github.com/containers/libpod/pkg/errorhandling" @@ -58,7 +59,7 @@ type ConmonOCIRuntime struct { // The first path that points to a valid executable will be used. // Deliberately private. Someone should not be able to construct this outside of // libpod. -func newConmonOCIRuntime(name string, paths []string, conmonPath string, runtimeCfg *RuntimeConfig, supportsJSON, supportsNoCgroups bool) (OCIRuntime, error) { +func newConmonOCIRuntime(name string, paths []string, conmonPath string, runtimeCfg *config.Config, supportsJSON, supportsNoCgroups bool) (OCIRuntime, error) { if name == "" { return nil, errors.Wrapf(define.ErrInvalidArg, "the OCI runtime must be provided a non-empty name") } @@ -114,7 +115,7 @@ func newConmonOCIRuntime(name string, paths []string, conmonPath string, runtime runtime.exitsDir = filepath.Join(runtime.tmpDir, "exits") runtime.socketsDir = filepath.Join(runtime.tmpDir, "socket") - if runtime.cgroupManager != CgroupfsCgroupsManager && runtime.cgroupManager != SystemdCgroupsManager { + if runtime.cgroupManager != define.CgroupfsCgroupsManager && runtime.cgroupManager != define.SystemdCgroupsManager { return nil, errors.Wrapf(define.ErrInvalidArg, "invalid cgroup manager specified: %s", runtime.cgroupManager) } @@ -1092,7 +1093,7 @@ func (r *ConmonOCIRuntime) configureConmonEnv(runtimeDir string) ([]string, []*o env = append(env, fmt.Sprintf("XDG_RUNTIME_DIR=%s", runtimeDir)) env = append(env, fmt.Sprintf("_CONTAINERS_USERNS_CONFIGURED=%s", os.Getenv("_CONTAINERS_USERNS_CONFIGURED"))) env = append(env, fmt.Sprintf("_CONTAINERS_ROOTLESS_UID=%s", os.Getenv("_CONTAINERS_ROOTLESS_UID"))) - home, err := homeDir() + home, err := util.HomeDir() if err != nil { return nil, nil, err } @@ -1118,7 +1119,7 @@ func (r *ConmonOCIRuntime) configureConmonEnv(runtimeDir string) ([]string, []*o func (r *ConmonOCIRuntime) sharedConmonArgs(ctr *Container, cuuid, bundlePath, pidPath, logPath, exitDir, ociLogPath string) []string { // set the conmon API version to be able to use the correct sync struct keys args := []string{"--api-version", "1"} - if r.cgroupManager == SystemdCgroupsManager && !ctr.config.NoCgroups { + if r.cgroupManager == define.SystemdCgroupsManager && !ctr.config.NoCgroups { args = append(args, "-s") } args = append(args, "-c", ctr.ID()) @@ -1222,7 +1223,7 @@ func (r *ConmonOCIRuntime) moveConmonToCgroupAndSignal(ctr *Container, cmd *exec if mustCreateCgroup { cgroupParent := ctr.CgroupParent() - if r.cgroupManager == SystemdCgroupsManager { + if r.cgroupManager == define.SystemdCgroupsManager { unitName := createUnitName("libpod-conmon", ctr.ID()) realCgroupParent := cgroupParent @@ -1345,7 +1346,7 @@ func readConmonPipeData(pipe *os.File, ociLog string) (int, error) { return ss.si.Data, errors.Wrapf(define.ErrInternal, "container create failed") } data = ss.si.Data - case <-time.After(ContainerCreateTimeout): + case <-time.After(define.ContainerCreateTimeout): return -1, errors.Wrapf(define.ErrInternal, "container creation timeout") } return data, nil diff --git a/libpod/oci_conmon_unsupported.go b/libpod/oci_conmon_unsupported.go index 77b06eed3..a2f52f527 100644 --- a/libpod/oci_conmon_unsupported.go +++ b/libpod/oci_conmon_unsupported.go @@ -3,6 +3,7 @@ package libpod import ( + "github.com/containers/libpod/libpod/config" "github.com/containers/libpod/libpod/define" ) @@ -15,7 +16,7 @@ type ConmonOCIRuntime struct { } // newConmonOCIRuntime is not supported on this OS. -func newConmonOCIRuntime(name string, paths []string, conmonPath string, runtimeCfg *RuntimeConfig, supportsJSON, supportsNoCgroups bool) (OCIRuntime, error) { +func newConmonOCIRuntime(name string, paths []string, conmonPath string, runtimeCfg *config.Config, supportsJSON, supportsNoCgroups bool) (OCIRuntime, error) { return nil, define.ErrNotImplemented } diff --git a/libpod/oci_util.go b/libpod/oci_util.go index cb85b153d..c1a7f1c9a 100644 --- a/libpod/oci_util.go +++ b/libpod/oci_util.go @@ -14,29 +14,9 @@ import ( "github.com/sirupsen/logrus" ) -const ( - // CgroupfsCgroupsManager represents cgroupfs native cgroup manager - CgroupfsCgroupsManager = "cgroupfs" - // SystemdCgroupsManager represents systemd native cgroup manager - SystemdCgroupsManager = "systemd" - - // ContainerCreateTimeout is the timeout before we decide we've failed - // to create a container. - // TODO: Make this generic - all OCI runtime operations should use the - // same timeout, this one. - // TODO: Consider dropping from 240 to 60 seconds. I don't think waiting - // 4 minutes versus 1 minute makes a real difference. - ContainerCreateTimeout = 240 * time.Second - - // Timeout before declaring that runtime has failed to kill a given - // container - killContainerTimeout = 5 * time.Second - // DefaultShmSize is the default shm size - DefaultShmSize = 64 * 1024 * 1024 - // NsRunDir is the default directory in which running network namespaces - // are stored - NsRunDir = "/var/run/netns" -) +// Timeout before declaring that runtime has failed to kill a given +// container +const killContainerTimeout = 5 * time.Second // ociError is used to parse the OCI runtime JSON log. It is not part of the // OCI runtime specifications, it follows what runc does diff --git a/libpod/options.go b/libpod/options.go index f79c75e98..66e8ef93c 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -39,30 +39,30 @@ func WithStorageConfig(config storage.StoreOptions) RuntimeOption { if config.RunRoot != "" { rt.config.StorageConfig.RunRoot = config.RunRoot - rt.configuredFrom.storageRunRootSet = true + rt.config.StorageConfigRunRootSet = true setField = true } if config.GraphRoot != "" { rt.config.StorageConfig.GraphRoot = config.GraphRoot - rt.configuredFrom.storageGraphRootSet = true + rt.config.StorageConfigGraphRootSet = true // Also set libpod static dir, so we are a subdirectory // of the c/storage store by default rt.config.StaticDir = filepath.Join(config.GraphRoot, "libpod") - rt.configuredFrom.libpodStaticDirSet = true + rt.config.StaticDirSet = true // Also set libpod volume path, so we are a subdirectory // of the c/storage store by default rt.config.VolumePath = filepath.Join(config.GraphRoot, "volumes") - rt.configuredFrom.volPathSet = true + rt.config.VolumePathSet = true setField = true } if config.GraphDriverName != "" { rt.config.StorageConfig.GraphDriverName = config.GraphDriverName - rt.configuredFrom.storageGraphDriverSet = true + rt.config.StorageConfigGraphDriverNameSet = true setField = true } @@ -135,13 +135,13 @@ func WithSignaturePolicy(path string) RuntimeOption { // Please note that information is not portable between backing states. // As such, if this differs between two libpods running on the same system, // they will not share containers, and unspecified behavior may occur. -func WithStateType(storeType RuntimeStateStore) RuntimeOption { +func WithStateType(storeType define.RuntimeStateStore) RuntimeOption { return func(rt *Runtime) error { if rt.valid { return define.ErrRuntimeFinalized } - if storeType == InvalidStateStore { + if storeType == define.InvalidStateStore { return errors.Wrapf(define.ErrInvalidArg, "must provide a valid state store type") } @@ -224,9 +224,9 @@ func WithCgroupManager(manager string) RuntimeOption { return define.ErrRuntimeFinalized } - if manager != CgroupfsCgroupsManager && manager != SystemdCgroupsManager { + if manager != define.CgroupfsCgroupsManager && manager != define.SystemdCgroupsManager { return errors.Wrapf(define.ErrInvalidArg, "CGroup manager must be one of %s and %s", - CgroupfsCgroupsManager, SystemdCgroupsManager) + define.CgroupfsCgroupsManager, define.SystemdCgroupsManager) } rt.config.CgroupManager = manager @@ -244,7 +244,7 @@ func WithStaticDir(dir string) RuntimeOption { } rt.config.StaticDir = dir - rt.configuredFrom.libpodStaticDirSet = true + rt.config.StaticDirSet = true return nil } @@ -295,7 +295,7 @@ func WithTmpDir(dir string) RuntimeOption { return define.ErrRuntimeFinalized } rt.config.TmpDir = dir - rt.configuredFrom.libpodTmpDirSet = true + rt.config.TmpDirSet = true return nil } @@ -395,7 +395,7 @@ func WithVolumePath(volPath string) RuntimeOption { } rt.config.VolumePath = volPath - rt.configuredFrom.volPathSet = true + rt.config.VolumePathSet = true return nil } diff --git a/libpod/pod_internal.go b/libpod/pod_internal.go index 7aacda482..b5895d133 100644 --- a/libpod/pod_internal.go +++ b/libpod/pod_internal.go @@ -66,13 +66,13 @@ func (p *Pod) refresh() error { // We need to recreate the pod's cgroup if p.config.UsePodCgroup { switch p.runtime.config.CgroupManager { - case SystemdCgroupsManager: + case define.SystemdCgroupsManager: cgroupPath, err := systemdSliceFromPath(p.config.CgroupParent, fmt.Sprintf("libpod_pod_%s", p.ID())) if err != nil { logrus.Errorf("Error creating CGroup for pod %s: %v", p.ID(), err) } p.state.CgroupPath = cgroupPath - case CgroupfsCgroupsManager: + case define.CgroupfsCgroupsManager: p.state.CgroupPath = filepath.Join(p.config.CgroupParent, p.ID()) logrus.Debugf("setting pod cgroup to %s", p.state.CgroupPath) diff --git a/libpod/runtime.go b/libpod/runtime.go index 300477c09..42e6782e9 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -1,28 +1,21 @@ package libpod import ( - "bytes" "context" "fmt" - "io/ioutil" "os" - "os/exec" - "os/user" "path/filepath" - "regexp" - "strconv" "strings" "sync" "syscall" - "github.com/BurntSushi/toml" is "github.com/containers/image/v5/storage" "github.com/containers/image/v5/types" + "github.com/containers/libpod/libpod/config" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/libpod/lock" - "github.com/containers/libpod/pkg/cgroups" sysreg "github.com/containers/libpod/pkg/registries" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/util" @@ -33,75 +26,13 @@ import ( "github.com/sirupsen/logrus" ) -// RuntimeStateStore is a constant indicating which state store implementation -// should be used by libpod -type RuntimeStateStore int - -const ( - // InvalidStateStore is an invalid state store - InvalidStateStore RuntimeStateStore = iota - // InMemoryStateStore is an in-memory state that will not persist data - // on containers and pods between libpod instances or after system - // reboot - InMemoryStateStore RuntimeStateStore = iota - // SQLiteStateStore is a state backed by a SQLite database - // It is presently disabled - SQLiteStateStore RuntimeStateStore = iota - // BoltDBStateStore is a state backed by a BoltDB database - BoltDBStateStore RuntimeStateStore = iota -) - -var ( - // InstallPrefix is the prefix where podman will be installed. - // It can be overridden at build time. - installPrefix = "/usr" - // EtcDir is the sysconfdir where podman should look for system config files. - // It can be overridden at build time. - etcDir = "/etc" - - // SeccompDefaultPath defines the default seccomp path - SeccompDefaultPath = installPrefix + "/share/containers/seccomp.json" - // SeccompOverridePath if this exists it overrides the default seccomp path - SeccompOverridePath = etcDir + "/crio/seccomp.json" - - // ConfigPath is the path to the libpod configuration file - // This file is loaded to replace the builtin default config before - // runtime options (e.g. WithStorageConfig) are applied. - // If it is not present, the builtin default config is used instead - // This path can be overridden when the runtime is created by using - // NewRuntimeFromConfig() instead of NewRuntime() - ConfigPath = installPrefix + "/share/containers/libpod.conf" - // OverrideConfigPath is the path to an override for the default libpod - // configuration file. If OverrideConfigPath exists, it will be used in - // place of the configuration file pointed to by ConfigPath. - OverrideConfigPath = etcDir + "/containers/libpod.conf" - - // DefaultSHMLockPath is the default path for SHM locks - DefaultSHMLockPath = "/libpod_lock" - // DefaultRootlessSHMLockPath is the default path for rootless SHM locks - DefaultRootlessSHMLockPath = "/libpod_rootless_lock" - - // DefaultDetachKeys is the default keys sequence for detaching a - // container - DefaultDetachKeys = "ctrl-p,ctrl-q" - - // minConmonMajor is the major version required for conmon - minConmonMajor = 2 - - // minConmonMinor is the minor version required for conmon - minConmonMinor = 0 - - // minConmonPatch is the sub-minor version required for conmon - minConmonPatch = 1 -) - // A RuntimeOption is a functional option which alters the Runtime created by // NewRuntime type RuntimeOption func(*Runtime) error // Runtime is the core libpod runtime type Runtime struct { - config *RuntimeConfig + config *config.Config state State store storage.Store @@ -113,7 +44,6 @@ type Runtime struct { conmonPath string imageRuntime *image.Runtime lockManager lock.Manager - configuredFrom *runtimeConfiguredFrom // doRenumber indicates that the runtime should perform a lock renumber // during initialization. @@ -141,223 +71,6 @@ type Runtime struct { noStore bool } -// RuntimeConfig contains configuration options used to set up the runtime -type RuntimeConfig struct { - // StorageConfig is the configuration used by containers/storage - // Not included in on-disk config, use the dedicated containers/storage - // configuration file instead - StorageConfig storage.StoreOptions `toml:"-"` - // VolumePath is the default location that named volumes will be created - // under. This convention is followed by the default volume driver, but - // may not be by other drivers. - VolumePath string `toml:"volume_path"` - // ImageDefaultTransport is the default transport method used to fetch - // images - ImageDefaultTransport string `toml:"image_default_transport"` - // SignaturePolicyPath is the path to a signature policy to use for - // validating images - // If left empty, the containers/image default signature policy will - // be used - SignaturePolicyPath string `toml:"signature_policy_path,omitempty"` - // StateType is the type of the backing state store. - // Avoid using multiple values for this with the same containers/storage - // configuration on the same system. Different state types do not - // interact, and each will see a separate set of containers, which may - // cause conflicts in containers/storage - // As such this is not exposed via the config file - StateType RuntimeStateStore `toml:"-"` - // OCIRuntime is the OCI runtime to use. - OCIRuntime string `toml:"runtime"` - // OCIRuntimes are the set of configured OCI runtimes (default is runc) - OCIRuntimes map[string][]string `toml:"runtimes"` - // RuntimeSupportsJSON is the list of the OCI runtimes that support - // --format=json. - RuntimeSupportsJSON []string `toml:"runtime_supports_json"` - // RuntimeSupportsNoCgroups is a list of OCI runtimes that support - // running containers without CGroups. - RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroups"` - // RuntimePath is the path to OCI runtime binary for launching - // containers. - // The first path pointing to a valid file will be used - // This is used only when there are no OCIRuntime/OCIRuntimes defined. It - // is used only to be backward compatible with older versions of Podman. - RuntimePath []string `toml:"runtime_path"` - // ConmonPath is the path to the Conmon binary used for managing - // containers - // The first path pointing to a valid file will be used - ConmonPath []string `toml:"conmon_path"` - // ConmonEnvVars are environment variables to pass to the Conmon binary - // when it is launched - ConmonEnvVars []string `toml:"conmon_env_vars"` - // CGroupManager is the CGroup Manager to use - // Valid values are "cgroupfs" and "systemd" - CgroupManager string `toml:"cgroup_manager"` - // InitPath is the path to the container-init binary. - InitPath string `toml:"init_path"` - // StaticDir is the path to a persistent directory to store container - // files - StaticDir string `toml:"static_dir"` - // TmpDir is the path to a temporary directory to store per-boot - // container files - // Must be stored in a tmpfs - TmpDir string `toml:"tmp_dir"` - // MaxLogSize is the maximum size of container logfiles - MaxLogSize int64 `toml:"max_log_size,omitempty"` - // NoPivotRoot sets whether to set no-pivot-root in the OCI runtime - NoPivotRoot bool `toml:"no_pivot_root"` - // CNIConfigDir sets the directory where CNI configuration files are - // stored - CNIConfigDir string `toml:"cni_config_dir"` - // CNIPluginDir sets a number of directories where the CNI network - // plugins can be located - CNIPluginDir []string `toml:"cni_plugin_dir"` - // CNIDefaultNetwork is the network name of the default CNI network - // to attach pods to - CNIDefaultNetwork string `toml:"cni_default_network,omitempty"` - // HooksDir holds paths to the directories containing hooks - // configuration files. When the same filename is present in in - // multiple directories, the file in the directory listed last in - // this slice takes precedence. - HooksDir []string `toml:"hooks_dir"` - // DefaultMountsFile is the path to the default mounts file for testing - // purposes only - DefaultMountsFile string `toml:"-"` - // Namespace is the libpod namespace to use. - // Namespaces are used to create scopes to separate containers and pods - // in the state. - // When namespace is set, libpod will only view containers and pods in - // the same namespace. All containers and pods created will default to - // the namespace set here. - // A namespace of "", the empty string, is equivalent to no namespace, - // and all containers and pods will be visible. - // The default namespace is "". - Namespace string `toml:"namespace,omitempty"` - - // InfraImage is the image a pod infra container will use to manage namespaces - InfraImage string `toml:"infra_image"` - // InfraCommand is the command run to start up a pod infra container - InfraCommand string `toml:"infra_command"` - // EnablePortReservation determines whether libpod will reserve ports on - // the host when they are forwarded to containers. - // When enabled, when ports are forwarded to containers, they are - // held open by conmon as long as the container is running, ensuring - // that they cannot be reused by other programs on the host. - // However, this can cause significant memory usage if a container has - // many ports forwarded to it. Disabling this can save memory. - EnablePortReservation bool `toml:"enable_port_reservation"` - // EnableLabeling indicates wether libpod will support container labeling - EnableLabeling bool `toml:"label"` - // NetworkCmdPath is the path to the slirp4netns binary - NetworkCmdPath string `toml:"network_cmd_path"` - - // NumLocks is the number of locks to make available for containers and - // pods. - NumLocks uint32 `toml:"num_locks,omitempty"` - - // LockType is the type of locking to use. - LockType string `toml:"lock_type,omitempty"` - - // EventsLogger determines where events should be logged - EventsLogger string `toml:"events_logger"` - // EventsLogFilePath is where the events log is stored. - EventsLogFilePath string `toml:"events_logfile_path"` - //DetachKeys is the sequence of keys used to detach a container - DetachKeys string `toml:"detach_keys"` - - // SDNotify tells Libpod to allow containers to notify the host - // systemd of readiness using the SD_NOTIFY mechanism - SDNotify bool - // CgroupCheck verifies if the cgroup check for correct OCI runtime has been done. - CgroupCheck bool `toml:"cgroup_check,omitempty"` -} - -// runtimeConfiguredFrom is a struct used during early runtime init to help -// assemble the full RuntimeConfig struct from defaults. -// It indicated whether several fields in the runtime configuration were set -// explicitly. -// If they were not, we may override them with information from the database, -// if it exists and differs from what is present in the system already. -type runtimeConfiguredFrom struct { - storageGraphDriverSet bool - storageGraphRootSet bool - storageRunRootSet bool - libpodStaticDirSet bool - libpodTmpDirSet bool - volPathSet bool - conmonPath bool - conmonEnvVars bool - initPath bool - ociRuntimes bool - runtimePath bool - cniPluginDir bool - noPivotRoot bool - runtimeSupportsJSON bool - runtimeSupportsNoCgroups bool - ociRuntime bool -} - -func defaultRuntimeConfig() (RuntimeConfig, error) { - storeOpts, err := storage.DefaultStoreOptions(rootless.IsRootless(), rootless.GetRootlessUID()) - if err != nil { - return RuntimeConfig{}, err - } - graphRoot := storeOpts.GraphRoot - if graphRoot == "" { - logrus.Warnf("Storage configuration is unset - using hardcoded default paths") - graphRoot = "/var/lib/containers/storage" - } - volumePath := filepath.Join(graphRoot, "volumes") - staticDir := filepath.Join(graphRoot, "libpod") - return RuntimeConfig{ - // Leave this empty so containers/storage will use its defaults - StorageConfig: storage.StoreOptions{}, - VolumePath: volumePath, - ImageDefaultTransport: DefaultTransport, - StateType: BoltDBStateStore, - OCIRuntime: "runc", - OCIRuntimes: map[string][]string{ - "runc": { - "/usr/bin/runc", - "/usr/sbin/runc", - "/usr/local/bin/runc", - "/usr/local/sbin/runc", - "/sbin/runc", - "/bin/runc", - "/usr/lib/cri-o-runc/sbin/runc", - "/run/current-system/sw/bin/runc", - }, - }, - ConmonPath: []string{ - "/usr/libexec/podman/conmon", - "/usr/local/lib/podman/conmon", - "/usr/bin/conmon", - "/usr/sbin/conmon", - "/usr/local/bin/conmon", - "/usr/local/sbin/conmon", - "/run/current-system/sw/bin/conmon", - }, - ConmonEnvVars: []string{ - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - }, - InitPath: define.DefaultInitPath, - CgroupManager: SystemdCgroupsManager, - StaticDir: staticDir, - TmpDir: "", - MaxLogSize: -1, - NoPivotRoot: false, - CNIConfigDir: etcDir + "/cni/net.d/", - CNIPluginDir: []string{"/usr/libexec/cni", "/usr/lib/cni", "/usr/local/lib/cni", "/opt/cni/bin"}, - InfraCommand: define.DefaultInfraCommand, - InfraImage: define.DefaultInfraImage, - EnablePortReservation: true, - EnableLabeling: true, - NumLocks: 2048, - EventsLogger: events.DefaultEventerType.String(), - DetachKeys: DefaultDetachKeys, - LockType: "shm", - }, nil -} - // SetXdgDirs ensures the XDG_RUNTIME_DIR env and XDG_CONFIG_HOME variables are set. // containers/image uses XDG_RUNTIME_DIR to locate the auth file, XDG_CONFIG_HOME is // use for the libpod.conf configuration file. @@ -400,28 +113,6 @@ func SetXdgDirs() error { return nil } -func getDefaultTmpDir() (string, error) { - if !rootless.IsRootless() { - return "/var/run/libpod", nil - } - - runtimeDir, err := util.GetRuntimeDir() - if err != nil { - return "", err - } - libpodRuntimeDir := filepath.Join(runtimeDir, "libpod") - - if err := os.Mkdir(libpodRuntimeDir, 0700|os.ModeSticky); err != nil { - if !os.IsExist(err) { - return "", errors.Wrapf(err, "cannot mkdir %s", libpodRuntimeDir) - } else if err := os.Chmod(libpodRuntimeDir, 0700|os.ModeSticky); err != nil { - // The directory already exist, just set the sticky bit - return "", errors.Wrapf(err, "could not set sticky bit on %s", libpodRuntimeDir) - } - } - return filepath.Join(libpodRuntimeDir, "tmp"), nil -} - // NewRuntime creates a new container runtime // Options can be passed to override the default configuration for the runtime func NewRuntime(ctx context.Context, options ...RuntimeOption) (runtime *Runtime, err error) { @@ -440,260 +131,14 @@ func NewRuntimeFromConfig(ctx context.Context, userConfigPath string, options .. return newRuntimeFromConfig(ctx, userConfigPath, options...) } -func homeDir() (string, error) { - home := os.Getenv("HOME") - if home == "" { - usr, err := user.LookupId(fmt.Sprintf("%d", rootless.GetRootlessUID())) - if err != nil { - return "", errors.Wrapf(err, "unable to resolve HOME directory") - } - home = usr.HomeDir - } - return home, nil -} - -func getRootlessConfigPath() (string, error) { - home, err := homeDir() - if err != nil { - return "", err - } - - return filepath.Join(home, ".config/containers/libpod.conf"), nil -} - -func getConfigPath() (string, error) { - if rootless.IsRootless() { - path, err := getRootlessConfigPath() - if err != nil { - return "", err - } - if _, err := os.Stat(path); err == nil { - return path, nil - } - return "", err - } - if _, err := os.Stat(OverrideConfigPath); err == nil { - // Use the override configuration path - return OverrideConfigPath, nil - } - if _, err := os.Stat(ConfigPath); err == nil { - return ConfigPath, nil - } - return "", nil -} - -// DefaultRuntimeConfig reads default config path and returns the RuntimeConfig -func DefaultRuntimeConfig() (*RuntimeConfig, error) { - configPath, err := getConfigPath() - if err != nil { - return nil, err - } - - contents, err := ioutil.ReadFile(configPath) - if err != nil { - return nil, errors.Wrapf(err, "error reading configuration file %s", configPath) - } - - // This is ugly, but we need to decode twice. - // Once to check if libpod static and tmp dirs were explicitly - // set (not enough to check if they're not the default value, - // might have been explicitly configured to the default). - // A second time to actually get a usable config. - tmpConfig := new(RuntimeConfig) - if _, err := toml.Decode(string(contents), tmpConfig); err != nil { - return nil, errors.Wrapf(err, "error decoding configuration file %s", - configPath) - } - return tmpConfig, nil -} - func newRuntimeFromConfig(ctx context.Context, userConfigPath string, options ...RuntimeOption) (runtime *Runtime, err error) { runtime = new(Runtime) - runtime.config = new(RuntimeConfig) - runtime.configuredFrom = new(runtimeConfiguredFrom) - - // Copy the default configuration - tmpDir, err := getDefaultTmpDir() - if err != nil { - return nil, err - } - - // storage.conf - storageConfFile, err := storage.DefaultConfigFile(rootless.IsRootless()) - if err != nil { - return nil, err - } - createStorageConfFile := false - if _, err := os.Stat(storageConfFile); os.IsNotExist(err) { - createStorageConfFile = true - } - - defRunConf, err := defaultRuntimeConfig() + conf, err := config.NewConfig(userConfigPath) if err != nil { return nil, err } - if err := JSONDeepCopy(defRunConf, runtime.config); err != nil { - return nil, errors.Wrapf(err, "error copying runtime default config") - } - runtime.config.TmpDir = tmpDir - - storageConf, err := storage.DefaultStoreOptions(rootless.IsRootless(), rootless.GetRootlessUID()) - if err != nil { - return nil, errors.Wrapf(err, "error retrieving storage config") - } - runtime.config.StorageConfig = storageConf - runtime.config.StaticDir = filepath.Join(storageConf.GraphRoot, "libpod") - runtime.config.VolumePath = filepath.Join(storageConf.GraphRoot, "volumes") - - configPath, err := getConfigPath() - if err != nil { - return nil, err - } - if rootless.IsRootless() { - home, err := homeDir() - if err != nil { - return nil, err - } - if runtime.config.SignaturePolicyPath == "" { - newPath := filepath.Join(home, ".config/containers/policy.json") - if _, err := os.Stat(newPath); err == nil { - runtime.config.SignaturePolicyPath = newPath - } - } - } - - if userConfigPath != "" { - configPath = userConfigPath - if _, err := os.Stat(configPath); err != nil { - // If the user specified a config file, we must fail immediately - // when it doesn't exist - return nil, errors.Wrapf(err, "cannot stat %s", configPath) - } - } - - // If we have a valid configuration file, load it in - if configPath != "" { - contents, err := ioutil.ReadFile(configPath) - if err != nil { - return nil, errors.Wrapf(err, "error reading configuration file %s", configPath) - } - - // This is ugly, but we need to decode twice. - // Once to check if libpod static and tmp dirs were explicitly - // set (not enough to check if they're not the default value, - // might have been explicitly configured to the default). - // A second time to actually get a usable config. - tmpConfig := new(RuntimeConfig) - if _, err := toml.Decode(string(contents), tmpConfig); err != nil { - return nil, errors.Wrapf(err, "error decoding configuration file %s", - configPath) - } - - if err := cgroupV2Check(configPath, tmpConfig); err != nil { - return nil, err - } - - if tmpConfig.StaticDir != "" { - runtime.configuredFrom.libpodStaticDirSet = true - } - if tmpConfig.TmpDir != "" { - runtime.configuredFrom.libpodTmpDirSet = true - } - if tmpConfig.VolumePath != "" { - runtime.configuredFrom.volPathSet = true - } - if tmpConfig.ConmonPath != nil { - runtime.configuredFrom.conmonPath = true - } - if tmpConfig.ConmonEnvVars != nil { - runtime.configuredFrom.conmonEnvVars = true - } - if tmpConfig.InitPath != "" { - runtime.configuredFrom.initPath = true - } - if tmpConfig.OCIRuntimes != nil { - runtime.configuredFrom.ociRuntimes = true - } - if tmpConfig.RuntimePath != nil { - runtime.configuredFrom.runtimePath = true - } - if tmpConfig.CNIPluginDir != nil { - runtime.configuredFrom.cniPluginDir = true - } - if tmpConfig.NoPivotRoot { - runtime.configuredFrom.noPivotRoot = true - } - if tmpConfig.RuntimeSupportsJSON != nil { - runtime.configuredFrom.runtimeSupportsJSON = true - } - if tmpConfig.RuntimeSupportsNoCgroups != nil { - runtime.configuredFrom.runtimeSupportsNoCgroups = true - } - if tmpConfig.OCIRuntime != "" { - runtime.configuredFrom.ociRuntime = true - } - - if _, err := toml.Decode(string(contents), runtime.config); err != nil { - return nil, errors.Wrapf(err, "error decoding configuration file %s", configPath) - } - } else if rootless.IsRootless() { - // If the configuration file was not found but we are running in rootless, a subset of the - // global config file is used. - for _, path := range []string{OverrideConfigPath, ConfigPath} { - contents, err := ioutil.ReadFile(path) - if err != nil { - // Ignore any error, the file might not be readable by us. - continue - } - tmpConfig := new(RuntimeConfig) - if _, err := toml.Decode(string(contents), tmpConfig); err != nil { - return nil, errors.Wrapf(err, "error decoding configuration file %s", path) - } - - // Cherry pick the settings we want from the global configuration - if !runtime.configuredFrom.conmonPath { - runtime.config.ConmonPath = tmpConfig.ConmonPath - } - if !runtime.configuredFrom.conmonEnvVars { - runtime.config.ConmonEnvVars = tmpConfig.ConmonEnvVars - } - if !runtime.configuredFrom.initPath { - runtime.config.InitPath = tmpConfig.InitPath - } - if !runtime.configuredFrom.ociRuntimes { - runtime.config.OCIRuntimes = tmpConfig.OCIRuntimes - } - if !runtime.configuredFrom.runtimePath { - runtime.config.RuntimePath = tmpConfig.RuntimePath - } - if !runtime.configuredFrom.cniPluginDir { - runtime.config.CNIPluginDir = tmpConfig.CNIPluginDir - } - if !runtime.configuredFrom.noPivotRoot { - runtime.config.NoPivotRoot = tmpConfig.NoPivotRoot - } - if !runtime.configuredFrom.runtimeSupportsJSON { - runtime.config.RuntimeSupportsJSON = tmpConfig.RuntimeSupportsJSON - } - if !runtime.configuredFrom.runtimeSupportsNoCgroups { - runtime.config.RuntimeSupportsNoCgroups = tmpConfig.RuntimeSupportsNoCgroups - } - if !runtime.configuredFrom.ociRuntime { - runtime.config.OCIRuntime = tmpConfig.OCIRuntime - } - - cgroupsV2, err := cgroups.IsCgroup2UnifiedMode() - if err != nil { - return nil, err - } - if cgroupsV2 { - runtime.config.CgroupCheck = true - } - - break - } - } + runtime.config = conf // Overwrite config with user-given configuration options for _, opt := range options { @@ -702,36 +147,6 @@ func newRuntimeFromConfig(ctx context.Context, userConfigPath string, options .. } } - if rootless.IsRootless() && configPath == "" { - if createStorageConfFile { - if err := util.WriteStorageConfigFile(&runtime.config.StorageConfig, storageConfFile); err != nil { - return nil, errors.Wrapf(err, "cannot write config file %s", storageConfFile) - } - } - - configPath, err := getRootlessConfigPath() - if err != nil { - return nil, err - } - if configPath != "" { - if err := os.MkdirAll(filepath.Dir(configPath), 0711); err != nil { - return nil, err - } - file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600) - if err != nil && !os.IsExist(err) { - return nil, errors.Wrapf(err, "cannot open file %s", configPath) - } - if err == nil { - defer file.Close() - enc := toml.NewEncoder(file) - if err := enc.Encode(runtime.config); err != nil { - if removeErr := os.Remove(configPath); removeErr != nil { - logrus.Debugf("unable to remove %s: %q", configPath, err) - } - } - } - } - } if err := makeRuntime(ctx, runtime); err != nil { return nil, err } @@ -758,9 +173,9 @@ func getLockManager(runtime *Runtime) (lock.Manager, error) { } case "", "shm": - lockPath := DefaultSHMLockPath + lockPath := define.DefaultSHMLockPath if rootless.IsRootless() { - lockPath = fmt.Sprintf("%s_%d", DefaultRootlessSHMLockPath, rootless.GetRootlessUID()) + lockPath = fmt.Sprintf("%s_%d", define.DefaultRootlessSHMLockPath, rootless.GetRootlessUID()) } // Set up the lock manager manager, err = lock.OpenSHMLockManager(lockPath, runtime.config.NumLocks) @@ -794,119 +209,14 @@ func getLockManager(runtime *Runtime) (lock.Manager, error) { return manager, nil } -// probeConmon calls conmon --version and verifies it is a new enough version for -// the runtime expectations podman currently has -func probeConmon(conmonBinary string) error { - versionFormatErr := "conmon version changed format" - cmd := exec.Command(conmonBinary, "--version") - var out bytes.Buffer - cmd.Stdout = &out - err := cmd.Run() - if err != nil { - return err - } - r := regexp.MustCompile(`^conmon version (?P<Major>\d+).(?P<Minor>\d+).(?P<Patch>\d+)`) - - matches := r.FindStringSubmatch(out.String()) - if len(matches) != 4 { - return errors.Wrapf(err, versionFormatErr) - } - major, err := strconv.Atoi(matches[1]) - if err != nil { - return errors.Wrapf(err, versionFormatErr) - } - if major < minConmonMajor { - return define.ErrConmonOutdated - } - if major > minConmonMajor { - return nil - } - - minor, err := strconv.Atoi(matches[2]) - if err != nil { - return errors.Wrapf(err, versionFormatErr) - } - if minor < minConmonMinor { - return define.ErrConmonOutdated - } - if minor > minConmonMinor { - return nil - } - - patch, err := strconv.Atoi(matches[3]) - if err != nil { - return errors.Wrapf(err, versionFormatErr) - } - if patch < minConmonPatch { - return define.ErrConmonOutdated - } - if patch > minConmonPatch { - return nil - } - - return nil -} - // Make a new runtime based on the given configuration // Sets up containers/storage, state store, OCI runtime func makeRuntime(ctx context.Context, runtime *Runtime) (err error) { - // Let's sanity-check some paths first. - // Relative paths can cause nasty bugs, because core paths we use could - // shift between runs (or even parts of the program - the OCI runtime - // uses a different working directory than we do, for example. - if !filepath.IsAbs(runtime.config.StaticDir) { - return errors.Wrapf(define.ErrInvalidArg, "static directory must be an absolute path - instead got %q", runtime.config.StaticDir) - } - if !filepath.IsAbs(runtime.config.TmpDir) { - return errors.Wrapf(define.ErrInvalidArg, "temporary directory must be an absolute path - instead got %q", runtime.config.TmpDir) - } - if !filepath.IsAbs(runtime.config.VolumePath) { - return errors.Wrapf(define.ErrInvalidArg, "volume path must be an absolute path - instead got %q", runtime.config.VolumePath) - } - // Find a working conmon binary - foundConmon := false - foundOutdatedConmon := false - for _, path := range runtime.config.ConmonPath { - stat, err := os.Stat(path) - if err != nil { - continue - } - if stat.IsDir() { - continue - } - if err := probeConmon(path); err != nil { - logrus.Warnf("conmon at %s invalid: %v", path, err) - foundOutdatedConmon = true - continue - } - foundConmon = true - runtime.conmonPath = path - logrus.Debugf("using conmon: %q", path) - break - } - - // Search the $PATH as last fallback - if !foundConmon { - if conmon, err := exec.LookPath("conmon"); err == nil { - if err := probeConmon(conmon); err != nil { - logrus.Warnf("conmon at %s is invalid: %v", conmon, err) - foundOutdatedConmon = true - } else { - foundConmon = true - runtime.conmonPath = conmon - logrus.Debugf("using conmon from $PATH: %q", conmon) - } - } - } - - if !foundConmon { - if foundOutdatedConmon { - return errors.Errorf("please update to v%d.%d.%d or later: %v", minConmonMajor, minConmonMinor, minConmonPatch, define.ErrConmonOutdated) - } - return errors.Wrapf(define.ErrInvalidArg, - "could not find a working conmon binary (configured options: %v)", - runtime.config.ConmonPath) + if cPath, err := runtime.config.FindConmon(); err != nil { + return err + } else { + runtime.conmonPath = cPath } // Make the static files directory if it does not exist @@ -918,17 +228,22 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (err error) { } } - // Set up the state + // Set up the state. + // + // TODO - if we further break out the state implementation into + // libpod/state, the config could take care of the code below. It + // would further allow to move the types and consts into a coherent + // package. switch runtime.config.StateType { - case InMemoryStateStore: + case define.InMemoryStateStore: state, err := NewInMemoryState() if err != nil { return err } runtime.state = state - case SQLiteStateStore: + case define.SQLiteStateStore: return errors.Wrapf(define.ErrInvalidArg, "SQLite state is currently disabled") - case BoltDBStateStore: + case define.BoltDBStateStore: dbPath := filepath.Join(runtime.config.StaticDir, "bolt_state.db") state, err := NewBoltState(dbPath, runtime) @@ -937,7 +252,7 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (err error) { } runtime.state = state default: - return errors.Wrapf(define.ErrInvalidArg, "unrecognized state type passed") + return errors.Wrapf(define.ErrInvalidArg, "unrecognized state type passed (%v)", runtime.config.StateType) } // Grab config from the database so we can reset some defaults @@ -946,51 +261,9 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (err error) { return errors.Wrapf(err, "error retrieving runtime configuration from database") } - // Reset defaults if they were not explicitly set - if !runtime.configuredFrom.storageGraphDriverSet && dbConfig.GraphDriver != "" { - if runtime.config.StorageConfig.GraphDriverName != dbConfig.GraphDriver && - runtime.config.StorageConfig.GraphDriverName != "" { - logrus.Errorf("User-selected graph driver %q overwritten by graph driver %q from database - delete libpod local files to resolve", - runtime.config.StorageConfig.GraphDriverName, dbConfig.GraphDriver) - } - runtime.config.StorageConfig.GraphDriverName = dbConfig.GraphDriver - } - if !runtime.configuredFrom.storageGraphRootSet && dbConfig.StorageRoot != "" { - if runtime.config.StorageConfig.GraphRoot != dbConfig.StorageRoot && - runtime.config.StorageConfig.GraphRoot != "" { - logrus.Debugf("Overriding graph root %q with %q from database", - runtime.config.StorageConfig.GraphRoot, dbConfig.StorageRoot) - } - runtime.config.StorageConfig.GraphRoot = dbConfig.StorageRoot + if err := runtime.config.MergeDBConfig(dbConfig); err != nil { + return errors.Wrapf(err, "error merging database config into runtime config") } - if !runtime.configuredFrom.storageRunRootSet && dbConfig.StorageTmp != "" { - if runtime.config.StorageConfig.RunRoot != dbConfig.StorageTmp && - runtime.config.StorageConfig.RunRoot != "" { - logrus.Debugf("Overriding run root %q with %q from database", - runtime.config.StorageConfig.RunRoot, dbConfig.StorageTmp) - } - runtime.config.StorageConfig.RunRoot = dbConfig.StorageTmp - } - if !runtime.configuredFrom.libpodStaticDirSet && dbConfig.LibpodRoot != "" { - if runtime.config.StaticDir != dbConfig.LibpodRoot && runtime.config.StaticDir != "" { - logrus.Debugf("Overriding static dir %q with %q from database", runtime.config.StaticDir, dbConfig.LibpodRoot) - } - runtime.config.StaticDir = dbConfig.LibpodRoot - } - if !runtime.configuredFrom.libpodTmpDirSet && dbConfig.LibpodTmp != "" { - if runtime.config.TmpDir != dbConfig.LibpodTmp && runtime.config.TmpDir != "" { - logrus.Debugf("Overriding tmp dir %q with %q from database", runtime.config.TmpDir, dbConfig.LibpodTmp) - } - runtime.config.TmpDir = dbConfig.LibpodTmp - } - if !runtime.configuredFrom.volPathSet && dbConfig.VolumePath != "" { - if runtime.config.VolumePath != dbConfig.VolumePath && runtime.config.VolumePath != "" { - logrus.Debugf("Overriding volume path %q with %q from database", runtime.config.VolumePath, dbConfig.VolumePath) - } - runtime.config.VolumePath = dbConfig.VolumePath - } - - runtime.config.EventsLogFilePath = filepath.Join(runtime.config.TmpDir, "events", "events.log") logrus.Debugf("Using graph driver %s", runtime.config.StorageConfig.GraphDriverName) logrus.Debugf("Using graph root %s", runtime.config.StorageConfig.GraphRoot) @@ -1269,7 +542,7 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (err error) { } // GetConfig returns a copy of the configuration used by the runtime -func (r *Runtime) GetConfig() (*RuntimeConfig, error) { +func (r *Runtime) GetConfig() (*config.Config, error) { r.lock.RLock() defer r.lock.RUnlock() @@ -1277,7 +550,7 @@ func (r *Runtime) GetConfig() (*RuntimeConfig, error) { return nil, define.ErrRuntimeStopped } - config := new(RuntimeConfig) + config := new(config.Config) // Copy so the caller won't be able to modify the actual config if err := JSONDeepCopy(r.config, config); err != nil { @@ -1499,56 +772,3 @@ func (r *Runtime) SystemContext() *types.SystemContext { func (r *Runtime) GetOCIRuntimePath() string { return r.defaultOCIRuntime.Path() } - -// Since runc does not currently support cgroupV2 -// Change to default crun on first running of libpod.conf -// 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 - } - if cgroupsV2 { - path, err := exec.LookPath("crun") - if err != nil { - logrus.Warnf("Can not find crun package on the host, containers might fail to run on cgroup V2 systems without crun: %q", err) - // Can't find crun path so do nothing - return nil - } - tmpConfig.CgroupCheck = true - tmpConfig.OCIRuntime = path - 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) - } - defer file.Close() - enc := toml.NewEncoder(file) - if err := enc.Encode(tmpConfig); err != nil { - if removeErr := os.Remove(configPath); removeErr != nil { - logrus.Debugf("unable to remove %s: %q", configPath, err) - } - } - } - } - return nil -} diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 2b214d572..7069d3494 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -75,7 +75,7 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf if config == nil { ctr.config.ID = stringid.GenerateNonCryptoID() - ctr.config.ShmSize = DefaultShmSize + ctr.config.ShmSize = define.DefaultShmSize } else { // This is a restore from an imported checkpoint ctr.restoreFromCheckpoint = true @@ -215,7 +215,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Contai // Only if we're actually configuring CGroups. if !ctr.config.NoCgroups { switch r.config.CgroupManager { - case CgroupfsCgroupsManager: + case define.CgroupfsCgroupsManager: if ctr.config.CgroupParent == "" { if pod != nil && pod.config.UsePodCgroup { podCgroup, err := pod.CgroupPath() @@ -232,7 +232,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Contai } else if strings.HasSuffix(path.Base(ctr.config.CgroupParent), ".slice") { return nil, errors.Wrapf(define.ErrInvalidArg, "systemd slice received as cgroup parent when using cgroupfs") } - case SystemdCgroupsManager: + case define.SystemdCgroupsManager: if ctr.config.CgroupParent == "" { if pod != nil && pod.config.UsePodCgroup { podCgroup, err := pod.CgroupPath() diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go index 05866d05a..704aaf9d0 100644 --- a/libpod/runtime_pod_linux.go +++ b/libpod/runtime_pod_linux.go @@ -76,7 +76,7 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po // Check CGroup parent sanity, and set it if it was not set switch r.config.CgroupManager { - case CgroupfsCgroupsManager: + case define.CgroupfsCgroupsManager: if pod.config.CgroupParent == "" { pod.config.CgroupParent = CgroupfsDefaultCgroupParent } else if strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") { @@ -89,7 +89,7 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po if pod.config.UsePodCgroup { pod.state.CgroupPath = filepath.Join(pod.config.CgroupParent, pod.ID()) } - case SystemdCgroupsManager: + case define.SystemdCgroupsManager: if pod.config.CgroupParent == "" { if rootless.IsRootless() { pod.config.CgroupParent = SystemdDefaultRootlessCgroupParent @@ -200,7 +200,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool) // the pod and conmon CGroups with a PID limit to prevent them from // spawning any further processes (particularly cleanup processes) which // would prevent removing the CGroups. - if p.runtime.config.CgroupManager == CgroupfsCgroupsManager { + if p.runtime.config.CgroupManager == define.CgroupfsCgroupsManager { // Get the conmon CGroup conmonCgroupPath := filepath.Join(p.state.CgroupPath, "conmon") conmonCgroup, err := cgroups.Load(conmonCgroupPath) @@ -251,7 +251,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool) logrus.Debugf("Removing pod cgroup %s", p.state.CgroupPath) switch p.runtime.config.CgroupManager { - case SystemdCgroupsManager: + case define.SystemdCgroupsManager: if err := deleteSystemdCgroup(p.state.CgroupPath); err != nil { if removalErr == nil { removalErr = errors.Wrapf(err, "error removing pod %s cgroup", p.ID()) @@ -259,7 +259,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool) logrus.Errorf("Error deleting pod %s cgroup %s: %v", p.ID(), p.state.CgroupPath, err) } } - case CgroupfsCgroupsManager: + case define.CgroupfsCgroupsManager: // Delete the cgroupfs cgroup // Make sure the conmon cgroup is deleted first // Since the pod is almost gone, don't bother failing diff --git a/libpod/state.go b/libpod/state.go index e38f820b5..b246b5eac 100644 --- a/libpod/state.go +++ b/libpod/state.go @@ -1,15 +1,6 @@ package libpod -// DBConfig is a set of Libpod runtime configuration settings that are saved -// in a State when it is first created, and can subsequently be retrieved. -type DBConfig struct { - LibpodRoot string - LibpodTmp string - StorageRoot string - StorageTmp string - GraphDriver string - VolumePath string -} +import "github.com/containers/libpod/libpod/config" // State is a storage backend for libpod's current state. // A State is only initialized once per instance of libpod. @@ -37,7 +28,7 @@ type State interface { // root and tmp dirs, and c/storage graph driver. // This is not implemented by the in-memory state, as it has no need to // validate runtime configuration. - GetDBConfig() (*DBConfig, error) + GetDBConfig() (*config.DBConfig, error) // ValidateDBConfig validates the config in the given Runtime struct // against paths stored in the configured database. diff --git a/libpod/state_test.go b/libpod/state_test.go index 5db1f301c..d4a4149f9 100644 --- a/libpod/state_test.go +++ b/libpod/state_test.go @@ -8,6 +8,7 @@ import ( "testing" "time" + "github.com/containers/libpod/libpod/config" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/lock" "github.com/containers/storage" @@ -52,7 +53,7 @@ func getEmptyBoltState() (s State, p string, m lock.Manager, err error) { } runtime := new(Runtime) - runtime.config = new(RuntimeConfig) + runtime.config = new(config.Config) runtime.config.StorageConfig = storage.StoreOptions{} runtime.lockManager = lockManager diff --git a/libpod/stats.go b/libpod/stats.go index 5513abce5..3b5e0958c 100644 --- a/libpod/stats.go +++ b/libpod/stats.go @@ -3,7 +3,6 @@ package libpod import ( - "runtime" "strings" "syscall" "time" @@ -56,8 +55,8 @@ func (c *Container) GetContainerStats(previousStats *ContainerStats) (*Container } previousCPU := previousStats.CPUNano - previousSystem := previousStats.SystemNano - stats.CPU = calculateCPUPercent(cgroupStats, previousCPU, previousSystem) + now := uint64(time.Now().UnixNano()) + stats.CPU = calculateCPUPercent(cgroupStats, previousCPU, now, previousStats.SystemNano) stats.MemUsage = cgroupStats.Memory.Usage.Usage stats.MemLimit = getMemLimit(cgroupStats.Memory.Usage.Limit) stats.MemPerc = (float64(stats.MemUsage) / float64(stats.MemLimit)) * 100 @@ -67,7 +66,7 @@ func (c *Container) GetContainerStats(previousStats *ContainerStats) (*Container } stats.BlockInput, stats.BlockOutput = calculateBlockIO(cgroupStats) stats.CPUNano = cgroupStats.CPU.Usage.Total - stats.SystemNano = cgroupStats.CPU.Usage.Kernel + stats.SystemNano = now // Handle case where the container is not in a network namespace if netStats != nil { stats.NetInput = netStats.TxBytes @@ -98,20 +97,19 @@ func getMemLimit(cgroupLimit uint64) uint64 { return cgroupLimit } -func calculateCPUPercent(stats *cgroups.Metrics, previousCPU, previousSystem uint64) float64 { +// calculateCPUPercent calculates the cpu usage using the latest measurement in stats. +// previousCPU is the last value of stats.CPU.Usage.Total measured at the time previousSystem. +// (now - previousSystem) is the time delta in nanoseconds, between the measurement in previousCPU +// and the updated value in stats. +func calculateCPUPercent(stats *cgroups.Metrics, previousCPU, now, previousSystem uint64) float64 { var ( cpuPercent = 0.0 cpuDelta = float64(stats.CPU.Usage.Total - previousCPU) - systemDelta = float64(uint64(time.Now().UnixNano()) - previousSystem) + systemDelta = float64(now - previousSystem) ) if systemDelta > 0.0 && cpuDelta > 0.0 { - // gets a ratio of container cpu usage total, multiplies it by the number of cores (4 cores running - // at 100% utilization should be 400% utilization), and multiplies that by 100 to get a percentage - nCPUS := len(stats.CPU.Usage.PerCPU) - if nCPUS == 0 { - nCPUS = runtime.NumCPU() - } - cpuPercent = (cpuDelta / systemDelta) * float64(nCPUS) * 100 + // gets a ratio of container cpu usage total, and multiplies that by 100 to get a percentage + cpuPercent = (cpuDelta / systemDelta) * 100 } return cpuPercent } diff --git a/libpod/util.go b/libpod/util.go index 5ae5ab491..bae2f4eb8 100644 --- a/libpod/util.go +++ b/libpod/util.go @@ -10,6 +10,7 @@ import ( "strings" "time" + "github.com/containers/libpod/libpod/config" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/utils" "github.com/fsnotify/fsnotify" @@ -19,10 +20,6 @@ import ( // Runtime API constants const ( - // DefaultTransport is a prefix that we apply to an image name - // to check docker hub first for the image - DefaultTransport = "docker://" - unknownPackage = "Unknown" ) @@ -190,19 +187,22 @@ func programVersion(mountProgram string) (string, error) { return strings.TrimSuffix(output, "\n"), nil } +// DefaultSeccompPath returns the path to the default seccomp.json file +// if it exists, first it checks OverrideSeccomp and then default. +// If neither exist function returns "" func DefaultSeccompPath() (string, error) { - _, err := os.Stat(SeccompOverridePath) + _, err := os.Stat(config.SeccompOverridePath) if err == nil { - return SeccompOverridePath, nil + return config.SeccompOverridePath, nil } if !os.IsNotExist(err) { - return "", errors.Wrapf(err, "can't check if %q exists", SeccompOverridePath) + return "", errors.Wrapf(err, "can't check if %q exists", config.SeccompOverridePath) } - if _, err := os.Stat(SeccompDefaultPath); err != nil { + if _, err := os.Stat(config.SeccompDefaultPath); err != nil { if !os.IsNotExist(err) { - return "", errors.Wrapf(err, "can't check if %q exists", SeccompDefaultPath) + return "", errors.Wrapf(err, "can't check if %q exists", config.SeccompDefaultPath) } return "", nil } - return SeccompDefaultPath, nil + return config.SeccompDefaultPath, nil } diff --git a/logo/podman-logo-source.svg b/logo/podman-logo-source.svg index 9e5cc6625..135624a42 100644 --- a/logo/podman-logo-source.svg +++ b/logo/podman-logo-source.svg @@ -251,7 +251,7 @@ ry="0.88143349" rx="0.8483994" cy="-8.3384542" - cx="967.05286" + cx="965.94666" id="ellipse10873" style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.68990111;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> </g> @@ -386,8 +386,8 @@ <ellipse ry="0.77958798" rx="0.75153452" - cy="8.4197426" - cx="954.63715" + cy="8.5291576" + cx="953.76178" id="ellipse10927" style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.95576686;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> </g> @@ -512,8 +512,8 @@ <ellipse style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.79374999;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="ellipse10977" - cx="974.20233" - cy="6.3892479" + cx="973.4754" + cy="6.4801154" rx="0.66728675" ry="0.69219536" /> </g> diff --git a/logo/podman-logo.png b/logo/podman-logo.png Binary files differindex 70c8b1191..90acf9cbc 100644 --- a/logo/podman-logo.png +++ b/logo/podman-logo.png diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index 430b6925d..64550f545 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -307,7 +307,11 @@ func (r *LocalRuntime) Log(c *cliconfig.LogsValues, options *logs.LogOptions) er if len(c.InputArgs) > 1 { options.Multi = true } - logChannel := make(chan *logs.LogLine, int(c.Tail)*len(c.InputArgs)+1) + tailLen := int(c.Tail) + if tailLen < 0 { + tailLen = 0 + } + logChannel := make(chan *logs.LogLine, tailLen*len(c.InputArgs)+1) containers, err := shortcuts.GetContainersByContext(false, c.Latest, c.InputArgs, r.Runtime) if err != nil { return err @@ -656,20 +660,25 @@ func (r *LocalRuntime) Start(ctx context.Context, c *cliconfig.StartValues, sigP return exitCode, nil } - if ctrRunning { - fmt.Println(ctr.ID()) - continue - } - // Handle non-attach start - // If the container is in a pod, also set to recursively start dependencies - if err := ctr.Start(ctx, ctr.PodID() != ""); err != nil { - if lastError != nil { - fmt.Fprintln(os.Stderr, lastError) + // Start the container if it's not running already. + if !ctrRunning { + // Handle non-attach start + // If the container is in a pod, also set to recursively start dependencies + if err := ctr.Start(ctx, ctr.PodID() != ""); err != nil { + if lastError != nil { + fmt.Fprintln(os.Stderr, lastError) + } + lastError = errors.Wrapf(err, "unable to start container %q", container) + continue } - lastError = errors.Wrapf(err, "unable to start container %q", container) - continue } - fmt.Println(ctr.ID()) + // Check if the container is referenced by ID or by name and print + // it accordingly. + if strings.HasPrefix(ctr.ID(), container) { + fmt.Println(ctr.ID()) + } else { + fmt.Println(container) + } } return exitCode, lastError } @@ -891,7 +900,7 @@ func (r *LocalRuntime) execPS(c *libpod.Container, args []string) ([]string, err streams := new(libpod.AttachStreams) streams.OutputStream = wPipe streams.ErrorStream = wPipe - streams.InputStream = os.Stdin + streams.InputStream = bufio.NewReader(os.Stdin) streams.AttachOutput = true streams.AttachError = true streams.AttachInput = true @@ -969,7 +978,7 @@ func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecVal streams.OutputStream = os.Stdout streams.ErrorStream = os.Stderr if cli.Interactive { - streams.InputStream = os.Stdin + streams.InputStream = bufio.NewReader(os.Stdin) streams.AttachInput = true } streams.AttachOutput = true diff --git a/pkg/adapter/pods.go b/pkg/adapter/pods.go index d8d5b884f..f6795970b 100644 --- a/pkg/adapter/pods.go +++ b/pkg/adapter/pods.go @@ -704,6 +704,24 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container } } + if seopt := containerYAML.SecurityContext.SELinuxOptions; seopt != nil { + if seopt.User != "" { + containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=user:%s", seopt.User)) + containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("user:%s", seopt.User)) + } + if seopt.Role != "" { + containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=role:%s", seopt.Role)) + containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("role:%s", seopt.Role)) + } + if seopt.Type != "" { + containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=type:%s", seopt.Type)) + containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("type:%s", seopt.Type)) + } + if seopt.Level != "" { + containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=level:%s", seopt.Level)) + containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("level:%s", seopt.Level)) + } + } if caps := containerYAML.SecurityContext.Capabilities; caps != nil { for _, capability := range caps.Add { containerConfig.CapAdd = append(containerConfig.CapAdd, string(capability)) diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go index 4f70e90f9..81a43853c 100644 --- a/pkg/adapter/runtime.go +++ b/pkg/adapter/runtime.go @@ -338,7 +338,7 @@ func (r *LocalRuntime) SaveImage(ctx context.Context, c *cliconfig.SaveValues) e return newImage.Save(ctx, source, c.Format, c.Output, additionalTags, c.Quiet, c.Compress) } -// LoadImage is a wrapper function for libpod PruneVolumes +// LoadImage is a wrapper function for libpod LoadImage func (r *LocalRuntime) LoadImage(ctx context.Context, name string, cli *cliconfig.LoadValues) (string, error) { var ( writer io.Writer diff --git a/pkg/adapter/terminal_linux.go b/pkg/adapter/terminal_linux.go index 16e552802..3dc5864e2 100644 --- a/pkg/adapter/terminal_linux.go +++ b/pkg/adapter/terminal_linux.go @@ -1,6 +1,7 @@ package adapter import ( + "bufio" "context" "fmt" "os" @@ -61,7 +62,7 @@ func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr, streams := new(libpod.AttachStreams) streams.OutputStream = stdout streams.ErrorStream = stderr - streams.InputStream = stdin + streams.InputStream = bufio.NewReader(stdin) streams.AttachOutput = true streams.AttachError = true streams.AttachInput = true diff --git a/pkg/cgroups/cpu.go b/pkg/cgroups/cpu.go index 03677f1ef..a43a76b22 100644 --- a/pkg/cgroups/cpu.go +++ b/pkg/cgroups/cpu.go @@ -81,14 +81,14 @@ func (c *cpuHandler) Stat(ctr *CgroupControl, m *Metrics) error { return err } if val, found := values["usage_usec"]; found { - usage.Kernel, err = strconv.ParseUint(cleanString(val[0]), 10, 0) + usage.Total, err = strconv.ParseUint(cleanString(val[0]), 10, 0) if err != nil { return err } usage.Kernel *= 1000 } if val, found := values["system_usec"]; found { - usage.Total, err = strconv.ParseUint(cleanString(val[0]), 10, 0) + usage.Kernel, err = strconv.ParseUint(cleanString(val[0]), 10, 0) if err != nil { return err } diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go index 9d1033b93..78b55bb2a 100644 --- a/pkg/namespaces/namespaces.go +++ b/pkg/namespaces/namespaces.go @@ -25,6 +25,11 @@ func (n CgroupMode) IsHost() bool { return n == hostType } +// IsDefaultValue indicates whether the cgroup namespace has the default value. +func (n CgroupMode) IsDefaultValue() bool { + return n == "" +} + // IsNS indicates a cgroup namespace passed in by path (ns:<path>) func (n CgroupMode) IsNS() bool { return strings.HasPrefix(string(n), nsType) diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c index 94933ddd0..9604de638 100644 --- a/pkg/rootless/rootless_linux.c +++ b/pkg/rootless/rootless_linux.c @@ -24,12 +24,16 @@ int renameat2 (int olddirfd, const char *oldpath, int newdirfd, const char *newpath, unsigned int flags) { -# ifdef __NR_renameat2 - return (int) syscall (__NR_renameat2, olddirfd, oldpath, newdirfd, newpath, flags); +# ifdef SYS_renameat2 + return (int) syscall (SYS_renameat2, olddirfd, oldpath, newdirfd, newpath, flags); # else - /* no way to implement it atomically. */ - errno = ENOSYS; - return -1; + /* This might be an issue if another process is trying to read the file while it is empty. */ + int fd = open (newpath, O_EXCL|O_CREAT, 0700); + if (fd < 0) + return fd; + close (fd); + /* We are sure we created the file, let's overwrite it. */ + return rename (oldpath, newpath); # endif } #endif diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go index da5c14948..33e9ec076 100644 --- a/pkg/spec/spec.go +++ b/pkg/spec/spec.go @@ -5,6 +5,8 @@ import ( "strings" "github.com/containers/libpod/libpod" + libpodconfig "github.com/containers/libpod/libpod/config" + "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/cgroups" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/sysinfo" @@ -300,7 +302,7 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM blockAccessToKernelFilesystems(config, &g) - var runtimeConfig *libpod.RuntimeConfig + var runtimeConfig *libpodconfig.Config if runtime != nil { runtimeConfig, err = runtime.GetConfig() @@ -321,7 +323,7 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM if err != nil { return nil, err } - if (!cgroup2 || (runtimeConfig != nil && runtimeConfig.CgroupManager != libpod.SystemdCgroupsManager)) && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() { + if (!cgroup2 || (runtimeConfig != nil && runtimeConfig.CgroupManager != define.SystemdCgroupsManager)) && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() { setPidLimit = false } } @@ -417,7 +419,7 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM configSpec.Linux.Resources = &spec.LinuxResources{} } - canUseResources := cgroup2 && runtimeConfig != nil && (runtimeConfig.CgroupManager == libpod.SystemdCgroupsManager) + canUseResources := cgroup2 && runtimeConfig != nil && (runtimeConfig.CgroupManager == define.SystemdCgroupsManager) if addedResources && !canUseResources { return nil, errors.New("invalid configuration, cannot specify resource limits without cgroups v2 and --cgroup-manager=systemd") @@ -629,6 +631,19 @@ func addIpcNS(config *CreateConfig, g *generate.Generator) error { func addCgroupNS(config *CreateConfig, g *generate.Generator) error { cgroupMode := config.CgroupMode + + if cgroupMode.IsDefaultValue() { + // If the value is not specified, default to "private" on cgroups v2 and "host" on cgroups v1. + unified, err := cgroups.IsCgroup2UnifiedMode() + if err != nil { + return err + } + if unified { + cgroupMode = "private" + } else { + cgroupMode = "host" + } + } if cgroupMode.IsNS() { return g.AddOrReplaceLinuxNamespace(string(spec.CgroupNamespace), NS(string(cgroupMode))) } diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 71f3e26dc..633d8a124 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -3,6 +3,7 @@ package util import ( "fmt" "os" + "os/user" "path/filepath" "regexp" "strings" @@ -440,3 +441,16 @@ func ExitCode(err error) int { return 126 } + +// HomeDir returns the home directory for the current user. +func HomeDir() (string, error) { + home := os.Getenv("HOME") + if home == "" { + usr, err := user.LookupId(fmt.Sprintf("%d", rootless.GetRootlessUID())) + if err != nil { + return "", errors.Wrapf(err, "unable to resolve HOME directory") + } + home = usr.HomeDir + } + return home, nil +} diff --git a/pkg/varlinkapi/attach.go b/pkg/varlinkapi/attach.go index 37adbbf55..5beca3c6f 100644 --- a/pkg/varlinkapi/attach.go +++ b/pkg/varlinkapi/attach.go @@ -32,7 +32,7 @@ func setupStreams(call iopodman.VarlinkCall) (*bufio.Reader, *bufio.Writer, *io. streams := libpod.AttachStreams{ OutputStream: stdoutWriter, - InputStream: pr, + InputStream: bufio.NewReader(pr), // Runc eats the error stream ErrorStream: stdoutWriter, AttachInput: true, diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go index b471ee2cf..94726bbbd 100644 --- a/pkg/varlinkapi/containers.go +++ b/pkg/varlinkapi/containers.go @@ -739,7 +739,7 @@ func (i *LibpodAPI) GetContainersLogs(call iopodman.VarlinkCall, names []string, options := logs.LogOptions{ Follow: follow, Since: sinceTime, - Tail: uint64(tail), + Tail: tail, Timestamps: timestamps, } @@ -747,7 +747,11 @@ func (i *LibpodAPI) GetContainersLogs(call iopodman.VarlinkCall, names []string, if len(names) > 1 { options.Multi = true } - logChannel := make(chan *logs.LogLine, int(tail)*len(names)+1) + tailLen := int(tail) + if tailLen < 0 { + tailLen = 0 + } + logChannel := make(chan *logs.LogLine, tailLen*len(names)+1) containers, err := shortcuts.GetContainersByContext(false, latest, names, i.Runtime) if err != nil { return call.ReplyErrorOccurred(err.Error()) diff --git a/rootless.md b/rootless.md index 8cccb86eb..4fb3c7deb 100644 --- a/rootless.md +++ b/rootless.md @@ -6,6 +6,7 @@ Contributors are more than welcomed to help with this work. If you decide to ca * Podman can not create containers that bind to ports < 1024. * The kernel does not allow processes without CAP_NET_BIND_SERVICE to bind to low ports. + * You can modify the `net.ipv4.ip_unprivileged_port_start` sysctl to change the lowest port. For example `sysctl net.ipv4.ip_unprivileged_port_start=443` allows rootless Podman containers to bind to ports >= 443. * “How To” documentation is patchy at best. * If /etc/subuid and /etc/subgid are not setup for a user, then podman commands can easily fail @@ -13,11 +14,11 @@ can easily fail * We are working to get support for NSSWITCH on the /etc/subuid and /etc/subgid files. * No cgroup V1 Support * cgroup V1 does not safely support cgroup delegation. - * However, cgroup V2 provides cgroup delegation and is available on Fedora starting with version 29 and other Linux distributions. -* Some systemd's unit configuration options do not work in the rootless container - * systemd fails to apply several options and failures are silently ignored (e.g. CPUShares, MemoryLimit). + * As of Fedora 31 defaults to cgroup V2, which has full support of rootless cgroup management. Note this requires the --cgroup-manager within rootless containers to use systemd, which new containers will get by default. +* Some system unit configuration options do not work in the rootless container + * systemd fails to apply several options and failures are silently ignored (e.g. CPUShares, MemoryLimit). Should work on cgroup V2. * Use of certain options will cause service startup failures (e.g. PrivateNetwork). -* Can not share container images with CRI-O or other users +* Can not share container images with CRI-O or other rootfull users * Difficult to use additional stores for sharing content * Does not work on NFS or parallel filesystem homedirs (e.g. [GPFS](https://www.ibm.com/support/knowledgecenter/en/SSFKCN/gpfs_welcome.html)) * NFS and parallel filesystems enforce file creation on different UIDs on the server side and does not understand User Namespace. @@ -35,9 +36,9 @@ can easily fail * Requires new shadow-utils (not found in older (RHEL7/Centos7 distros) Should be fixed in RHEL7.7 release) * A few commands do not work. * mount/unmount (on fuse-overlay) - * Only works if you enter the mount namespace with a tool like buildah unshare - * podman stats (Without cgroup V2 support) + * Only works if you enter the mount namespace with podman unshare + * podman stats (Works with cgroup V2 support) * Checkpoint and Restore (CRIU requires root) - * Pause and Unpause (no freezer cgroup) + * Pause and Unpause (Works with cgroup V2 support) * Issues with higher UIDs can cause builds to fail * If a build is attempting to use a UID that is not mapped into the user namespace mapping for a container, then builds will not be able to put the UID in an image. diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go index f34d85d76..e25364695 100644 --- a/test/e2e/logs_test.go +++ b/test/e2e/logs_test.go @@ -57,6 +57,18 @@ var _ = Describe("Podman logs", func() { Expect(len(results.OutputToStringArray())).To(Equal(2)) }) + It("podman logs tail zero lines", func() { + logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) + logc.WaitWithDefaultTimeout() + Expect(logc.ExitCode()).To(Equal(0)) + cid := logc.OutputToString() + + results := podmanTest.Podman([]string{"logs", "--tail", "0", cid}) + results.WaitWithDefaultTimeout() + Expect(results.ExitCode()).To(Equal(0)) + Expect(len(results.OutputToStringArray())).To(Equal(0)) + }) + It("podman logs tail 99 lines", func() { logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() diff --git a/test/e2e/run_cgroup_parent_test.go b/test/e2e/run_cgroup_parent_test.go index 1fb9f6871..14294eeac 100644 --- a/test/e2e/run_cgroup_parent_test.go +++ b/test/e2e/run_cgroup_parent_test.go @@ -40,7 +40,7 @@ var _ = Describe("Podman run with --cgroup-parent", func() { Skip("Must be containerized to run this test.") } cgroup := "/zzz" - run := podmanTest.Podman([]string{"run", "--cgroup-parent", cgroup, fedoraMinimal, "cat", "/proc/self/cgroup"}) + run := podmanTest.Podman([]string{"run", "--cgroupns=host", "--cgroup-parent", cgroup, fedoraMinimal, "cat", "/proc/self/cgroup"}) run.WaitWithDefaultTimeout() Expect(run.ExitCode()).To(Equal(0)) ok, _ := run.GrepString(cgroup) @@ -52,7 +52,7 @@ var _ = Describe("Podman run with --cgroup-parent", func() { if !Containerized() && podmanTest.CgroupManager != "cgroupfs" { cgroup = "/machine.slice" } - run := podmanTest.Podman([]string{"run", fedoraMinimal, "cat", "/proc/self/cgroup"}) + run := podmanTest.Podman([]string{"run", "--cgroupns=host", fedoraMinimal, "cat", "/proc/self/cgroup"}) run.WaitWithDefaultTimeout() Expect(run.ExitCode()).To(Equal(0)) ok, _ := run.GrepString(cgroup) @@ -64,7 +64,7 @@ var _ = Describe("Podman run with --cgroup-parent", func() { Skip("Requires Systemd cgroup manager support") } cgroup := "aaaa.slice" - run := podmanTest.Podman([]string{"run", "--cgroup-parent", cgroup, fedoraMinimal, "cat", "/proc/1/cgroup"}) + run := podmanTest.Podman([]string{"run", "--cgroupns=host", "--cgroup-parent", cgroup, fedoraMinimal, "cat", "/proc/1/cgroup"}) run.WaitWithDefaultTimeout() Expect(run.ExitCode()).To(Equal(0)) ok, _ := run.GrepString(cgroup) diff --git a/test/e2e/run_selinux_test.go b/test/e2e/run_selinux_test.go index ebc36b7f1..358137aa9 100644 --- a/test/e2e/run_selinux_test.go +++ b/test/e2e/run_selinux_test.go @@ -170,7 +170,7 @@ var _ = Describe("Podman run", func() { setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) - session := podmanTest.Podman([]string{"exec", "test1", "cat", "/proc/self/attr/current"}) + session := podmanTest.Podman([]string{"exec", "test1", "cat", "/proc/1/attr/current"}) session.WaitWithDefaultTimeout() session1 := podmanTest.Podman([]string{"exec", "test1", "cat", "/proc/self/attr/current"}) session1.WaitWithDefaultTimeout() diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go index da581f158..47b058845 100644 --- a/test/e2e/start_test.go +++ b/test/e2e/start_test.go @@ -57,15 +57,32 @@ var _ = Describe("Podman start", func() { session = podmanTest.Podman([]string{"container", "start", cid}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(Equal(cid)) + }) + + It("podman container start single container by short id", func() { + session := podmanTest.Podman([]string{"container", "create", "-d", ALPINE, "ls"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + cid := session.OutputToString() + session = podmanTest.Podman([]string{"container", "start", cid[0:10]}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(Equal(cid)) }) It("podman start single container by name", func() { - session := podmanTest.Podman([]string{"create", "-d", "--name", "foobar99", ALPINE, "ls"}) + name := "foobar99" + session := podmanTest.Podman([]string{"create", "-d", "--name", name, ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"start", "foobar99"}) + session = podmanTest.Podman([]string{"start", name}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + if podmanTest.RemoteTest { + Skip("Container-start name check doesn't work on remote client. It always returns the full ID.") + } + Expect(session.OutputToString()).To(Equal(name)) }) It("podman start multiple containers", func() { diff --git a/test/e2e/test.yaml b/test/e2e/test.yaml new file mode 100644 index 000000000..319d6a4a0 --- /dev/null +++ b/test/e2e/test.yaml @@ -0,0 +1,34 @@ +# Save the output of this file and use kubectl create -f to import +# it into Kubernetes. +# +# Created with podman-1.6.2 +apiVersion: v1 +kind: Pod +metadata: + labels: + app: test + name: test +spec: + containers: + - command: + - sleep + - "100" + env: + - name: PATH + value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + - name: TERM + value: xterm + - name: container + value: podman + image: docker.io/library/fedora:latest + name: test + resources: {} + securityContext: + allowPrivilegeEscalation: true + capabilities: {} + privileged: false + seLinuxOptions: + level: "s0:c1,c2" + readOnlyRootFilesystem: false + workingDir: / +status: {} diff --git a/vendor/github.com/containers/buildah/.cirrus.yml b/vendor/github.com/containers/buildah/.cirrus.yml index 1f7815073..66774c226 100644 --- a/vendor/github.com/containers/buildah/.cirrus.yml +++ b/vendor/github.com/containers/buildah/.cirrus.yml @@ -29,7 +29,7 @@ env: #### # Command to prefix every output line with a timestamp # (can't do inline awk script, Cirrus-CI or YAML mangles quoting) - _TIMESTAMP: 'awk --file ${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/timestamp.awk' + _TIMESTAMP: 'awk -f ${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/timestamp.awk' _DFCMD: 'df -lhTx tmpfs' _RAUDITCMD: 'cat /var/log/audit/audit.log' _UAUDITCMD: 'cat /var/log/kern.log' @@ -75,9 +75,37 @@ testing_task: failure_journal_log_script: '${_JOURNALCMD} || true' +# This task runs `make vendor` followed by ./hack/tree_status.sh to check +# whether the git tree is clean. The reasoning for that is to make sure +# that the vendor.conf, the code and the vendored packages in ./vendor are +# in sync at all times. +vendor_task: + + only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + + env: + CIRRUS_WORKING_DIR: "/var/tmp/go/src/github.com/containers/buildah" + GOPATH: "/go" + GOSRC: "/go/src/github.com/containers/buildah" + + # Runs within Cirrus's "community cluster" + container: + image: docker.io/library/golang:1.13 + cpu: 1 + memory: 1 + + timeout_in: 30m + + vendor_script: + - 'cd ${CIRRUS_WORKING_DIR} && make vendor' + - 'cd ${CIRRUS_WORKING_DIR} && ./hack/tree_status.sh' + # Update metadata on VM images referenced by this repository state meta_task: + depends_on: + - "vendor" + container: image: "quay.io/libpod/imgts:latest" # see contrib/imgts cpu: 1 diff --git a/vendor/github.com/containers/buildah/.golangci.yml b/vendor/github.com/containers/buildah/.golangci.yml index 044bc1f1b..dde37ad79 100644 --- a/vendor/github.com/containers/buildah/.golangci.yml +++ b/vendor/github.com/containers/buildah/.golangci.yml @@ -2,7 +2,6 @@ run: build-tags: - apparmor - - ostree - seccomp - selinux concurrency: 6 diff --git a/vendor/github.com/containers/buildah/.papr.sh b/vendor/github.com/containers/buildah/.papr.sh index 25ab4c29d..2795e9ec0 100644 --- a/vendor/github.com/containers/buildah/.papr.sh +++ b/vendor/github.com/containers/buildah/.papr.sh @@ -26,7 +26,6 @@ dnf install -y \ libselinux-utils \ make \ openssl \ - ostree-devel \ skopeo-containers \ which diff --git a/vendor/github.com/containers/buildah/.papr.yml b/vendor/github.com/containers/buildah/.papr.yml index 6eaba332c..4be12a18e 100644 --- a/vendor/github.com/containers/buildah/.papr.yml +++ b/vendor/github.com/containers/buildah/.papr.yml @@ -68,7 +68,6 @@ packages: - golang - libassuan-devel - make - - ostree-devel - skopeo-containers required: false diff --git a/vendor/github.com/containers/buildah/.travis.yml b/vendor/github.com/containers/buildah/.travis.yml index fbc0a7862..a74108230 100644 --- a/vendor/github.com/containers/buildah/.travis.yml +++ b/vendor/github.com/containers/buildah/.travis.yml @@ -2,8 +2,8 @@ language: go dist: xenial sudo: required go: - - 1.11.x - 1.12.x + - 1.13.x - tip go_import_path: github.com/containers/buildah @@ -40,9 +40,6 @@ matrix: services: - docker before_install: - - make vendor - - ./hack/tree_status.sh - - sudo apt-get update - sudo apt-get -qq install software-properties-common - sudo add-apt-repository -y ppa:duggan/bats - sudo apt-get update @@ -51,15 +48,6 @@ before_install: - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce - mkdir /home/travis/auth - sudo mkdir -p /var/lib/containers/storage/overlay - - > - OSTREE_VERSION=v2019.2; - git clone https://github.com/ostreedev/ostree && - pushd ostree && - git checkout $OSTREE_VERSION && - ./autogen.sh --prefix=/usr && - sudo make -j4 install && - popd && - sudo rm -rf ostree install: # Let's create a self signed certificate and get it in the right places - hostname @@ -98,7 +86,7 @@ script: # Setting up Docker Registry is complete, let's do Buildah testing! - make install.tools -j4 - make install.libseccomp.sudo all runc validate lint SECURITYTAGS="apparmor seccomp" - - go test -c -tags "apparmor seccomp `./btrfs_tag.sh` `./libdm_tag.sh` `./ostree_tag.sh` `./selinux_tag.sh`" ./cmd/buildah + - go test -c -tags "apparmor seccomp `./btrfs_tag.sh` `./libdm_tag.sh` `./selinux_tag.sh`" ./cmd/buildah - tmp=`mktemp -d`; mkdir $tmp/root $tmp/runroot; sudo PATH="$PATH" ./buildah.test -test.v --root $tmp/root --runroot $tmp/runroot --storage-driver vfs --signature-policy `pwd`/tests/policy.json --registries-conf `pwd`/tests/registries.conf - cd tests; sudo PATH="$PATH" ./test_runner.sh - cd .. diff --git a/vendor/github.com/containers/buildah/CHANGELOG.md b/vendor/github.com/containers/buildah/CHANGELOG.md index c75a055a6..b41ff8350 100644 --- a/vendor/github.com/containers/buildah/CHANGELOG.md +++ b/vendor/github.com/containers/buildah/CHANGELOG.md @@ -2,6 +2,28 @@ # Changelog +## v1.11.4 (2019-10-28) + buildah: add a "manifest" command + manifests: add the module + pkg/supplemented: add a package for grouping images together + pkg/manifests: add a manifest list build/manipulation API + Update for ErrUnauthorizedForCredentials API change in containers/image + Update for manifest-lists API changes in containers/image + version: also note the version of containers/image + Move to containers/image v5.0.0 + Enable --device directory as src device + Fix git build with branch specified + Bump github.com/openshift/imagebuilder from 1.1.0 to 1.1.1 + Bump github.com/fsouza/go-dockerclient from 1.4.4 to 1.5.0 + Add clarification to the Tutorial for new users + Silence "using cache" to ensure -q is fully quiet + Add OWNERS File to Buildah + Bump github.com/containers/storage from 1.13.4 to 1.13.5 + Move runtime flag to bud from common + Commit: check for storage.ErrImageUnknown using errors.Cause() + Fix crash when invalid COPY --from flag is specified. + Bump back to v1.12.0-dev + ## v1.11.3 (2019-10-04) Update c/image to v4.0.1 Bump github.com/spf13/pflag from 1.0.3 to 1.0.5 diff --git a/vendor/github.com/containers/buildah/Makefile b/vendor/github.com/containers/buildah/Makefile index cb0dfeb51..9d04177d0 100644 --- a/vendor/github.com/containers/buildah/Makefile +++ b/vendor/github.com/containers/buildah/Makefile @@ -2,7 +2,7 @@ export GOPROXY=https://proxy.golang.org SELINUXTAG := $(shell ./selinux_tag.sh) APPARMORTAG := $(shell hack/apparmor_tag.sh) -STORAGETAGS := $(shell ./btrfs_tag.sh) $(shell ./btrfs_installed_tag.sh) $(shell ./libdm_tag.sh) $(shell ./ostree_tag.sh) +STORAGETAGS := $(shell ./btrfs_tag.sh) $(shell ./btrfs_installed_tag.sh) $(shell ./libdm_tag.sh) SECURITYTAGS ?= seccomp $(SELINUXTAG) $(APPARMORTAG) TAGS ?= $(SECURITYTAGS) $(STORAGETAGS) BUILDTAGS += $(TAGS) @@ -24,7 +24,7 @@ endif GIT_COMMIT ?= $(if $(shell git rev-parse --short HEAD),$(shell git rev-parse --short HEAD),$(error "git failed")) SOURCE_DATE_EPOCH ?= $(if $(shell date +%s),$(shell date +%s),$(error "date failed")) -STATIC_STORAGETAGS = "containers_image_ostree_stub containers_image_openpgp exclude_graphdriver_devicemapper $(STORAGE_TAGS)" +STATIC_STORAGETAGS = "containers_image_openpgp exclude_graphdriver_devicemapper $(STORAGE_TAGS)" CNI_COMMIT := $(shell sed -n 's;\tgithub.com/containernetworking/cni \([^ \n]*\).*$\;\1;p' go.mod) #RUNC_COMMIT := $(shell sed -n 's;\tgithub.com/opencontainers/runc \([^ \n]*\).*$\;\1;p' go.mod) @@ -130,6 +130,9 @@ test-unit: tests/testreport/testreport mkdir -p $$tmp/root $$tmp/runroot; \ $(GO) test -v -tags "$(STORAGETAGS) $(SECURITYTAGS)" ./cmd/buildah -args -root $$tmp/root -runroot $$tmp/runroot -storage-driver vfs -signature-policy $(shell pwd)/tests/policy.json -registries-conf $(shell pwd)/tests/registries.conf +vendor-in-container: + podman run --privileged --rm --env HOME=/root -v `pwd`:/src -w /src docker.io/library/golang:1.13 make vendor + .PHONY: vendor vendor: export GO111MODULE=on \ diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go index 59b62925a..d57eea818 100644 --- a/vendor/github.com/containers/buildah/buildah.go +++ b/vendor/github.com/containers/buildah/buildah.go @@ -27,7 +27,7 @@ const ( Package = "buildah" // Version for the Package. Bump version in contrib/rpm/buildah.spec // too. - Version = "1.11.4" + Version = "1.12.0-dev" // The value we use to identify what type of information, currently a // serialized Builder structure, we are using as per-container state. // This should only be changed when we make incompatible changes to diff --git a/vendor/github.com/containers/buildah/go.mod b/vendor/github.com/containers/buildah/go.mod index 6bba4a1f8..c8741b781 100644 --- a/vendor/github.com/containers/buildah/go.mod +++ b/vendor/github.com/containers/buildah/go.mod @@ -21,7 +21,7 @@ require ( github.com/ishidawataru/sctp v0.0.0-20180918013207-6e2cb1366111 // indirect github.com/mattn/go-shellwords v1.0.6 github.com/morikuni/aec v1.0.0 // indirect - github.com/onsi/ginkgo v1.10.1 + github.com/onsi/ginkgo v1.10.2 github.com/onsi/gomega v1.7.0 github.com/opencontainers/go-digest v1.0.0-rc1 github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 diff --git a/vendor/github.com/containers/buildah/go.sum b/vendor/github.com/containers/buildah/go.sum index e5ce6a290..4a6673b04 100644 --- a/vendor/github.com/containers/buildah/go.sum +++ b/vendor/github.com/containers/buildah/go.sum @@ -212,6 +212,8 @@ github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.2 h1:uqH7bpe+ERSiDa34FDOF7RikN6RzXgduUF8yarlZp94= +github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= diff --git a/vendor/github.com/containers/buildah/install.md b/vendor/github.com/containers/buildah/install.md index 858364b45..f533b0fb2 100644 --- a/vendor/github.com/containers/buildah/install.md +++ b/vendor/github.com/containers/buildah/install.md @@ -139,7 +139,6 @@ Prior to installing Buildah, install the following packages on your Linux distro * glib2-devel * libassuan-devel * libseccomp-devel -* ostree-devel * runc (Requires version 1.0 RC4 or higher.) * containers-common @@ -158,7 +157,6 @@ In Fedora, you can use this command: gpgme-devel \ libassuan-devel \ libseccomp-devel \ - ostree-devel \ git \ bzip2 \ go-md2man \ @@ -196,7 +194,6 @@ run this command: gpgme-devel \ libassuan-devel \ libseccomp-devel \ - ostree-devel \ git \ bzip2 \ go-md2man \ @@ -241,7 +238,7 @@ In Ubuntu zesty and xenial, you can use these commands: add-apt-repository -y ppa:gophers/archive apt-add-repository -y ppa:projectatomic/ppa apt-get -y -qq update - apt-get -y install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libostree-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man + apt-get -y install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man apt-get -y install golang-1.10 ``` Then to install Buildah on Ubuntu follow the steps in this example: @@ -266,7 +263,7 @@ gpg --recv-keys 0x018BA5AD9DF57A4448F0E6CF8BECF1637AD8C79D gpg --export 0x018BA5AD9DF57A4448F0E6CF8BECF1637AD8C79D >> /usr/share/keyrings/projectatomic-ppa.gpg echo 'deb [signed-by=/usr/share/keyrings/projectatomic-ppa.gpg] http://ppa.launchpad.net/projectatomic/ppa/ubuntu zesty main' > /etc/apt/sources.list.d/projectatomic-ppa.list apt update -apt -y install -t stretch-backports libostree-dev golang +apt -y install -t stretch-backports golang apt -y install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man ``` @@ -274,7 +271,7 @@ The build steps on Debian are otherwise the same as Ubuntu, above. ## Vendoring - Dependency Management -This project is using [go modules](https://github.com/golang/go/wiki/Modules) for dependency management. If the CI is complaining about a pull request leaving behind an unclean state, it is very likely right about it. After changing dependencies, make sure to run `make vendor` to synchronize the code with the go module and repopulate the `./vendor` directory. +This project is using [go modules](https://github.com/golang/go/wiki/Modules) for dependency management. If the CI is complaining about a pull request leaving behind an unclean state, it is very likely right about it. After changing dependencies, make sure to run `make vendor-in-container` to synchronize the code with the go module and repopulate the `./vendor` directory. ## Configuration files @@ -381,7 +378,7 @@ Buildah uses Go Modules for vendoring purposes. If you need to update or add a * Enter into your sandbox `src/github.com/containers/buildah` and ensure that the GOPATH variable is set to the directory prior as noted above. * `export GO111MODULE=on` * Assuming you want to 'bump' the `github.com/containers/storage` package to version 1.12.13, use this command: `go get github.com/containers/storage@v1.12.13` - * `make vendor` + * `make vendor-in-container` * `make` * `make install` * Then add any updated or added files with `git add` then do a `git commit` and create a PR. @@ -391,10 +388,10 @@ Buildah uses Go Modules for vendoring purposes. If you need to update or add a If you wish to vendor in your personal fork to try changes out (assuming containers/storage in the below example): * `go mod edit -replace github.com/containers/storage=github.com/{mygithub_username}/storage@YOUR_BRANCH` - * `make vendor` + * `make vendor-in-container` To revert * `go mod edit -dropreplace github.com/containers/storage` - * `make vendor` + * `make vendor-in-container` To speed up fetching dependencies, you can use a [Go Module Proxy](https://proxy.golang.org) by setting `GOPROXY=https://proxy.golang.org`. diff --git a/vendor/github.com/containers/buildah/ostree_tag.sh b/vendor/github.com/containers/buildah/ostree_tag.sh deleted file mode 100644 index 537c17ff4..000000000 --- a/vendor/github.com/containers/buildah/ostree_tag.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -if pkg-config ostree-1 2> /dev/null ; then - echo containers_image_ostree -else - echo containers_image_ostree_stub -fi diff --git a/vendor/github.com/containers/buildah/pkg/cli/common.go b/vendor/github.com/containers/buildah/pkg/cli/common.go index a9bf94a32..e8979cd7f 100644 --- a/vendor/github.com/containers/buildah/pkg/cli/common.go +++ b/vendor/github.com/containers/buildah/pkg/cli/common.go @@ -7,7 +7,6 @@ package cli import ( "fmt" "os" - "path/filepath" "runtime" "strings" @@ -270,9 +269,5 @@ func GetDefaultAuthFile() string { if authfile != "" { return authfile } - runtimeDir := os.Getenv("XDG_RUNTIME_DIR") - if runtimeDir != "" { - return filepath.Join(runtimeDir, "containers/auth.json") - } return "" } diff --git a/vendor/github.com/containers/buildah/pkg/secrets/secrets.go b/vendor/github.com/containers/buildah/pkg/secrets/secrets.go index 9be9bb3b6..80ca05016 100644 --- a/vendor/github.com/containers/buildah/pkg/secrets/secrets.go +++ b/vendor/github.com/containers/buildah/pkg/secrets/secrets.go @@ -148,12 +148,12 @@ func getMountsMap(path string) (string, string, error) { } // SecretMounts copies, adds, and mounts the secrets to the container root filesystem -func SecretMounts(mountLabel, containerWorkingDir, mountFile string, rootless bool) []rspec.Mount { - return SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, containerWorkingDir, 0, 0, rootless) +func SecretMounts(mountLabel, containerWorkingDir, mountFile string, rootless, disableFips bool) []rspec.Mount { + return SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, containerWorkingDir, 0, 0, rootless, disableFips) } // SecretMountsWithUIDGID specifies the uid/gid of the owner -func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPrefix string, uid, gid int, rootless bool) []rspec.Mount { +func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPrefix string, uid, gid int, rootless, disableFips bool) []rspec.Mount { var ( secretMounts []rspec.Mount mountFiles []string @@ -180,6 +180,10 @@ func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPre } } + // Only add FIPS secret mount if disableFips=false + if disableFips { + return secretMounts + } // Add FIPS mode secret if /etc/system-fips exists on the host _, err := os.Stat("/etc/system-fips") if err == nil { diff --git a/vendor/github.com/containers/buildah/run_linux.go b/vendor/github.com/containers/buildah/run_linux.go index 624da9dae..4f507d1bc 100644 --- a/vendor/github.com/containers/buildah/run_linux.go +++ b/vendor/github.com/containers/buildah/run_linux.go @@ -460,7 +460,7 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st } // Get the list of secrets mounts. - secretMounts := secrets.SecretMountsWithUIDGID(b.MountLabel, cdir, b.DefaultMountsFilePath, cdir, int(rootUID), int(rootGID), unshare.IsRootless()) + secretMounts := secrets.SecretMountsWithUIDGID(b.MountLabel, cdir, b.DefaultMountsFilePath, cdir, int(rootUID), int(rootGID), unshare.IsRootless(), false) // Add temporary copies of the contents of volume locations at the // volume locations, unless we already have something there. diff --git a/vendor/github.com/containers/buildah/troubleshooting.md b/vendor/github.com/containers/buildah/troubleshooting.md index 96fa403f0..4ff2f06c4 100644 --- a/vendor/github.com/containers/buildah/troubleshooting.md +++ b/vendor/github.com/containers/buildah/troubleshooting.md @@ -82,9 +82,9 @@ the command with single quotes and use `bash -c`. The previous examples would b changed to: ```console -# buildah run bash -c '$whalecontainer /usr/games/fortune -a | cowsay' -# buildah run bash -c '$newcontainer echo "daemon off;" >> /etc/nginx/nginx.conf' -# buildah run bash -c '$newcontainer echo "nginx on Fedora" > /usr/share/nginx/html/index.html' +# buildah run $whalecontainer bash -c '/usr/games/fortune -a | cowsay' +# buildah run $newcontainer bash -c 'echo "daemon off;" >> /etc/nginx/nginx.conf' +# buildah run $newcontainer bash -c 'echo "nginx on Fedora" > /usr/share/nginx/html/index.html' ``` --- diff --git a/vendor/github.com/containers/buildah/util.go b/vendor/github.com/containers/buildah/util.go index 44db18b45..b4670e41c 100644 --- a/vendor/github.com/containers/buildah/util.go +++ b/vendor/github.com/containers/buildah/util.go @@ -248,28 +248,36 @@ func (b *Builder) copyWithTar(tarIDMappingOptions *IDMappingOptions, chownOpts * // location into our working container, mapping permissions using the // container's ID maps, possibly overridden using the passed-in chownOpts func (b *Builder) untarPath(chownOpts *idtools.IDPair, hasher io.Writer, dryRun bool) func(src, dest string) error { - if hasher != nil && b.ContentDigester.Hash() != nil { - hasher = io.MultiWriter(hasher, b.ContentDigester.Hash()) - } - if hasher == nil { - hasher = b.ContentDigester.Hash() - } convertedUIDMap, convertedGIDMap := convertRuntimeIDMaps(b.IDMappingOptions.UIDMap, b.IDMappingOptions.GIDMap) if dryRun { return func(src, dest string) error { - if hasher == nil { - hasher = ioutil.Discard + thisHasher := hasher + if thisHasher != nil && b.ContentDigester.Hash() != nil { + thisHasher = io.MultiWriter(thisHasher, b.ContentDigester.Hash()) + } + if thisHasher == nil { + thisHasher = b.ContentDigester.Hash() } f, err := os.Open(src) if err != nil { return errors.Wrapf(err, "error opening %q", src) } defer f.Close() - _, err = io.Copy(hasher, f) + _, err = io.Copy(thisHasher, f) return err } } - return chrootarchive.UntarPathAndChown(chownOpts, hasher, convertedUIDMap, convertedGIDMap) + return func(src, dest string) error { + thisHasher := hasher + if thisHasher != nil && b.ContentDigester.Hash() != nil { + thisHasher = io.MultiWriter(thisHasher, b.ContentDigester.Hash()) + } + if thisHasher == nil { + thisHasher = b.ContentDigester.Hash() + } + untarPathAndChown := chrootarchive.UntarPathAndChown(chownOpts, thisHasher, convertedUIDMap, convertedGIDMap) + return untarPathAndChown(src, dest) + } } // tarPath returns a function which creates an archive of a specified location, diff --git a/vendor/github.com/onsi/ginkgo/.travis.yml b/vendor/github.com/onsi/ginkgo/.travis.yml index 72e8ccf0b..9da4c5b5e 100644 --- a/vendor/github.com/onsi/ginkgo/.travis.yml +++ b/vendor/github.com/onsi/ginkgo/.travis.yml @@ -5,6 +5,9 @@ go: - 1.12.x - tip +# allow internal package imports, necessary for forked repositories +go_import_path: github.com/onsi/ginkgo + install: - go get -v -t ./... - go get golang.org/x/tools/cmd/cover diff --git a/vendor/github.com/onsi/ginkgo/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/CHANGELOG.md index aeadb66e0..020496c9d 100644 --- a/vendor/github.com/onsi/ginkgo/CHANGELOG.md +++ b/vendor/github.com/onsi/ginkgo/CHANGELOG.md @@ -1,20 +1,34 @@ +## 1.10.3 + +### Fixes +- Set go_import_path in travis.yml to allow internal packages in forks (#607) [3b721db] +- Add integration test [d90e0dc] +- Fix coverage files combining [e5dde8c] +- A new CLI option: -ginkgo.reportFile <file path> (#601) [034fd25] + +## 1.10.2 + +### Fixes +- speed up table entry generateIt() (#609) [5049dc5] +- Fix. Write errors to stderr instead of stdout (#610) [7bb3091] + ## 1.10.1 -## Fixes +### Fixes - stack backtrace: fix skipping (#600) [2a4c0bd] ## 1.10.0 -## Fixes +### Fixes - stack backtrace: fix alignment and skipping [66915d6] - fix typo in documentation [8f97b93] ## 1.9.0 -## Features +### Features - Option to print output into report, when tests have passed [0545415] -## Fixes +### Fixes - Fixed typos in comments [0ecbc58] - gofmt code [a7f8bfb] - Simplify code [7454d00] diff --git a/vendor/github.com/onsi/ginkgo/config/config.go b/vendor/github.com/onsi/ginkgo/config/config.go index ac55a5ad2..89ec2b29a 100644 --- a/vendor/github.com/onsi/ginkgo/config/config.go +++ b/vendor/github.com/onsi/ginkgo/config/config.go @@ -20,7 +20,7 @@ import ( "fmt" ) -const VERSION = "1.10.1" +const VERSION = "1.10.3" type GinkgoConfigType struct { RandomSeed int64 @@ -53,6 +53,7 @@ type DefaultReporterConfigType struct { Verbose bool FullTrace bool ReportPassed bool + ReportFile string } var DefaultReporterConfig = DefaultReporterConfigType{} @@ -100,6 +101,8 @@ func Flags(flagSet *flag.FlagSet, prefix string, includeParallelFlags bool) { flagSet.BoolVar(&(DefaultReporterConfig.Succinct), prefix+"succinct", false, "If set, default reporter prints out a very succinct report") flagSet.BoolVar(&(DefaultReporterConfig.FullTrace), prefix+"trace", false, "If set, default reporter prints out the full stack trace when a failure occurs") flagSet.BoolVar(&(DefaultReporterConfig.ReportPassed), prefix+"reportPassed", false, "If set, default reporter prints out captured output of passed tests.") + flagSet.StringVar(&(DefaultReporterConfig.ReportFile), prefix+"reportFile", "", "Override the default reporter output file path.") + } func BuildFlagArgs(prefix string, ginkgo GinkgoConfigType, reporter DefaultReporterConfigType) []string { @@ -202,5 +205,9 @@ func BuildFlagArgs(prefix string, ginkgo GinkgoConfigType, reporter DefaultRepor result = append(result, fmt.Sprintf("--%sreportPassed", prefix)) } + if reporter.ReportFile != "" { + result = append(result, fmt.Sprintf("--%sreportFile=%s", prefix, reporter.ReportFile)) + } + return result } diff --git a/vendor/github.com/onsi/ginkgo/extensions/table/table_entry.go b/vendor/github.com/onsi/ginkgo/extensions/table/table_entry.go index 5fa645bce..93f3bc3b0 100644 --- a/vendor/github.com/onsi/ginkgo/extensions/table/table_entry.go +++ b/vendor/github.com/onsi/ginkgo/extensions/table/table_entry.go @@ -22,18 +22,15 @@ func (t TableEntry) generateIt(itBody reflect.Value) { return } - values := []reflect.Value{} + values := make([]reflect.Value, len(t.Parameters)) + iBodyType := itBody.Type() for i, param := range t.Parameters { - var value reflect.Value - if param == nil { - inType := itBody.Type().In(i) - value = reflect.Zero(inType) + inType := iBodyType.In(i) + values[i] = reflect.Zero(inType) } else { - value = reflect.ValueOf(param) + values[i] = reflect.ValueOf(param) } - - values = append(values, value) } body := func() { diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/run_command.go b/vendor/github.com/onsi/ginkgo/ginkgo/run_command.go index 569b6a29c..1d06e08fd 100644 --- a/vendor/github.com/onsi/ginkgo/ginkgo/run_command.go +++ b/vendor/github.com/onsi/ginkgo/ginkgo/run_command.go @@ -5,6 +5,7 @@ import ( "fmt" "math/rand" "os" + "regexp" "strings" "time" @@ -163,17 +164,27 @@ func (r *SpecRunner) combineCoverprofiles(runners []*testrunner.TestRunner) erro fmt.Println("path is " + path) - combined, err := os.OpenFile(filepath.Join(path, r.getCoverprofile()), - os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0666) + combined, err := os.OpenFile( + filepath.Join(path, r.getCoverprofile()), + os.O_WRONLY|os.O_CREATE, + 0666, + ) if err != nil { fmt.Printf("Unable to create combined profile, %v\n", err) return nil // non-fatal error } - for _, runner := range runners { + modeRegex := regexp.MustCompile(`^mode: .*\n`) + for index, runner := range runners { contents, err := ioutil.ReadFile(runner.CoverageFile) + // remove the cover mode line from every file + // except the first one + if index > 0 { + contents = modeRegex.ReplaceAll(contents, []byte{}) + } + if err != nil { fmt.Printf("Unable to read coverage file %s to combine, %v\n", runner.CoverageFile, err) return nil // non-fatal error diff --git a/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go b/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go index 8734c061d..3cbf89a35 100644 --- a/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go +++ b/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go @@ -199,6 +199,11 @@ type Benchmarker interface { // ginkgo bootstrap func RunSpecs(t GinkgoTestingT, description string) bool { specReporters := []Reporter{buildDefaultReporter()} + if config.DefaultReporterConfig.ReportFile != "" { + reportFile := config.DefaultReporterConfig.ReportFile + specReporters[0] = reporters.NewJUnitReporter(reportFile) + return RunSpecsWithDefaultAndCustomReporters(t, description, specReporters) + } return RunSpecsWithCustomReporters(t, description, specReporters) } diff --git a/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go b/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go index 89a7c8465..d76e2fe77 100644 --- a/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go +++ b/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go @@ -13,6 +13,7 @@ import ( "fmt" "math" "os" + "path/filepath" "strings" "github.com/onsi/ginkgo/config" @@ -141,17 +142,29 @@ func (reporter *JUnitReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { reporter.suite.Time = math.Trunc(summary.RunTime.Seconds()*1000) / 1000 reporter.suite.Failures = summary.NumberOfFailedSpecs reporter.suite.Errors = 0 - file, err := os.Create(reporter.filename) + if reporter.ReporterConfig.ReportFile != "" { + reporter.filename = reporter.ReporterConfig.ReportFile + fmt.Printf("\nJUnit path was configured: %s\n", reporter.filename) + } + filePath, _ := filepath.Abs(reporter.filename) + dirPath := filepath.Dir(filePath) + err := os.MkdirAll(dirPath, os.ModePerm) + if err != nil { + fmt.Printf("\nFailed to create JUnit directory: %s\n\t%s", filePath, err.Error()) + } + file, err := os.Create(filePath) if err != nil { - fmt.Printf("Failed to create JUnit report file: %s\n\t%s", reporter.filename, err.Error()) + fmt.Fprintf(os.Stderr, "Failed to create JUnit report file: %s\n\t%s", filePath, err.Error()) } defer file.Close() file.WriteString(xml.Header) encoder := xml.NewEncoder(file) encoder.Indent(" ", " ") err = encoder.Encode(reporter.suite) - if err != nil { - fmt.Printf("Failed to generate JUnit report\n\t%s", err.Error()) + if err == nil { + fmt.Fprintf(os.Stdout, "\nJUnit report was created: %s\n", filePath) + } else { + fmt.Fprintf(os.Stderr,"\nFailed to generate JUnit report data:\n\t%s", err.Error()) } } diff --git a/vendor/gopkg.in/yaml.v2/decode.go b/vendor/gopkg.in/yaml.v2/decode.go index 531087655..129bc2a97 100644 --- a/vendor/gopkg.in/yaml.v2/decode.go +++ b/vendor/gopkg.in/yaml.v2/decode.go @@ -319,10 +319,14 @@ func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unm } const ( - // 400,000 decode operations is ~500kb of dense object declarations, or ~5kb of dense object declarations with 10000% alias expansion + // 400,000 decode operations is ~500kb of dense object declarations, or + // ~5kb of dense object declarations with 10000% alias expansion alias_ratio_range_low = 400000 - // 4,000,000 decode operations is ~5MB of dense object declarations, or ~4.5MB of dense object declarations with 10% alias expansion + + // 4,000,000 decode operations is ~5MB of dense object declarations, or + // ~4.5MB of dense object declarations with 10% alias expansion alias_ratio_range_high = 4000000 + // alias_ratio_range is the range over which we scale allowed alias ratios alias_ratio_range = float64(alias_ratio_range_high - alias_ratio_range_low) ) @@ -784,8 +788,7 @@ func (d *decoder) merge(n *node, out reflect.Value) { case mappingNode: d.unmarshal(n, out) case aliasNode: - an, ok := d.doc.anchors[n.value] - if ok && an.kind != mappingNode { + if n.alias != nil && n.alias.kind != mappingNode { failWantMap() } d.unmarshal(n, out) @@ -794,8 +797,7 @@ func (d *decoder) merge(n *node, out reflect.Value) { for i := len(n.children) - 1; i >= 0; i-- { ni := n.children[i] if ni.kind == aliasNode { - an, ok := d.doc.anchors[ni.value] - if ok && an.kind != mappingNode { + if ni.alias != nil && ni.alias.kind != mappingNode { failWantMap() } } else if ni.kind != mappingNode { diff --git a/vendor/modules.txt b/vendor/modules.txt index cda4bcd9e..53239b7cd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -55,7 +55,7 @@ github.com/containernetworking/plugins/pkg/ip github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator github.com/containernetworking/plugins/pkg/utils/hwaddr github.com/containernetworking/plugins/plugins/ipam/host-local/backend -# github.com/containers/buildah v1.11.4-0.20191028173731-21b4778b359e +# github.com/containers/buildah v1.11.5-0.20191031204705-20e92ffe0982 github.com/containers/buildah github.com/containers/buildah/imagebuildah github.com/containers/buildah/pkg/chrootuser @@ -317,7 +317,7 @@ github.com/morikuni/aec github.com/mrunalp/fileutils # github.com/mtrmac/gpgme v0.0.0-20170102180018-b2432428689c github.com/mtrmac/gpgme -# github.com/onsi/ginkgo v1.10.1 +# github.com/onsi/ginkgo v1.10.3 github.com/onsi/ginkgo/ginkgo github.com/onsi/ginkgo github.com/onsi/ginkgo/config @@ -566,7 +566,7 @@ gopkg.in/fsnotify.v1 gopkg.in/inf.v0 # gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 gopkg.in/tomb.v1 -# gopkg.in/yaml.v2 v2.2.4 +# gopkg.in/yaml.v2 v2.2.5 gopkg.in/yaml.v2 # k8s.io/api v0.0.0-20190813020757-36bff7324fb7 k8s.io/api/core/v1 diff --git a/version/version.go b/version/version.go index c0dbeadfe..129a2cd4b 100644 --- a/version/version.go +++ b/version/version.go @@ -4,7 +4,7 @@ package version // NOTE: remember to bump the version at the top // of the top-level README.md file when this is // bumped. -const Version = "1.6.3-dev" +const Version = "1.6.4-dev" // RemoteAPIVersion is the version for the remote // client API. It is used to determine compatibility |