summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml79
-rw-r--r--.github/workflows/stale.yml1
-rw-r--r--.gitignore2
-rw-r--r--.golangci.yml1
-rw-r--r--Dockerfile1
-rw-r--r--Dockerfile.centos1
-rw-r--r--Dockerfile.fedora1
-rw-r--r--Makefile84
-rw-r--r--README.md4
-rw-r--r--RELEASE_NOTES.md29
-rw-r--r--cmd/podman/attach.go3
-rw-r--r--cmd/podman/build.go7
-rw-r--r--cmd/podman/cliconfig/config.go2
-rw-r--r--cmd/podman/common.go4
-rw-r--r--cmd/podman/cp.go11
-rw-r--r--cmd/podman/exec.go3
-rw-r--r--cmd/podman/images.go4
-rw-r--r--cmd/podman/import.go2
-rw-r--r--cmd/podman/logs.go2
-rw-r--r--cmd/podman/main_local.go11
-rw-r--r--cmd/podman/start.go2
-rw-r--r--cmd/podman/utils.go13
-rw-r--r--contrib/build_rpm.sh1
-rw-r--r--contrib/cirrus/container_test.sh2
-rw-r--r--contrib/cirrus/lib.sh46
-rwxr-xr-xcontrib/cirrus/lib.sh.t17
-rw-r--r--contrib/cirrus/packer/Makefile2
-rw-r--r--contrib/cirrus/packer/fedora_setup.sh2
-rw-r--r--contrib/cirrus/packer/ubuntu_setup.sh1
-rw-r--r--contrib/gate/Dockerfile1
-rw-r--r--contrib/podmanimage/upstream/Dockerfile1
-rw-r--r--contrib/spec/podman.spec.in6
-rw-r--r--docs/Makefile23
-rw-r--r--docs/Readme.md21
-rw-r--r--docs/make.bat (renamed from docs/rtd/make.bat)0
-rwxr-xr-xdocs/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/Makefile123
-rw-r--r--docs/rtd/source/Commands.rst107
-rw-r--r--docs/rtd/source/man/generate.rst6
-rw-r--r--docs/rtd/source/man/healthcheck.rst4
-rw-r--r--docs/rtd/source/man/image.rst35
-rw-r--r--docs/rtd/source/man/managecontainers.rst64
-rw-r--r--docs/rtd/source/man/network.rst10
-rw-r--r--docs/rtd/source/man/play.rst4
-rw-r--r--docs/rtd/source/man/pod.rst30
-rw-r--r--docs/rtd/source/man/system.rst12
-rw-r--r--docs/rtd/source/man/volume.rst11
-rw-r--r--docs/source/Commands.rst107
-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.rst6
-rw-r--r--docs/source/healthcheck.rst4
-rw-r--r--docs/source/image.rst35
-rw-r--r--docs/source/index.rst (renamed from docs/rtd/source/index.rst)0
-rw-r--r--docs/source/managecontainers.rst64
-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)4
-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)8
-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)2
-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)3
-rw-r--r--docs/source/markdown/podman-push.1.md (renamed from docs/podman-push.1.md)5
-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)8
-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)4
-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.rst10
-rw-r--r--docs/source/play.rst4
-rw-r--r--docs/source/pod.rst30
-rw-r--r--docs/source/system.rst12
-rw-r--r--docs/source/volume.rst11
-rw-r--r--go.mod12
-rw-r--r--go.sum26
-rwxr-xr-xhack/man-page-checker2
-rwxr-xr-xhack/ostree_tag.sh6
-rwxr-xr-xhack/podman-commands.sh6
-rw-r--r--install.md34
-rw-r--r--libpod.conf32
-rw-r--r--libpod/boltdb_state.go5
-rw-r--r--libpod/common_test.go3
-rw-r--r--libpod/config/config.go549
-rw-r--r--libpod/config/config_test.go64
-rw-r--r--libpod/config/default.go152
-rw-r--r--libpod/config/merge.go183
-rw-r--r--libpod/config/merge_test.go157
-rw-r--r--libpod/config/testdata/empty.conf0
l---------libpod/config/testdata/libpod.conf1
-rw-r--r--libpod/container.go4
-rw-r--r--libpod/container_api.go3
-rw-r--r--libpod/container_inspect.go4
-rw-r--r--libpod/container_internal_linux.go6
-rw-r--r--libpod/container_log_linux.go9
-rw-r--r--libpod/define/config.go18
-rw-r--r--libpod/define/runtime.go37
-rw-r--r--libpod/events/journal_linux.go2
-rw-r--r--libpod/events/logfile.go2
-rw-r--r--libpod/healthcheck.go4
-rw-r--r--libpod/image/pull.go8
-rw-r--r--libpod/in_memory_state.go5
-rw-r--r--libpod/kube.go9
-rw-r--r--libpod/logs/log.go6
-rw-r--r--libpod/networking_linux.go2
-rw-r--r--libpod/oci_attach_linux.go2
-rw-r--r--libpod/oci_conmon_linux.go23
-rw-r--r--libpod/oci_conmon_unsupported.go3
-rw-r--r--libpod/oci_util.go26
-rw-r--r--libpod/options.go24
-rw-r--r--libpod/pod_internal.go4
-rw-r--r--libpod/runtime.go828
-rw-r--r--libpod/runtime_ctr.go6
-rw-r--r--libpod/runtime_pod_linux.go10
-rw-r--r--libpod/state.go13
-rw-r--r--libpod/state_test.go3
-rw-r--r--libpod/stats.go24
-rw-r--r--libpod/util.go20
-rw-r--r--libpod/volume_internal_linux.go16
-rw-r--r--logo/podman-logo-source.svg10
-rw-r--r--logo/podman-logo.pngbin37056 -> 37991 bytes
-rw-r--r--pkg/adapter/containers.go50
-rw-r--r--pkg/adapter/containers_remote.go2
-rw-r--r--pkg/adapter/pods.go75
-rw-r--r--pkg/adapter/runtime.go2
-rw-r--r--pkg/adapter/terminal_linux.go3
-rw-r--r--pkg/cgroups/cpu.go4
-rw-r--r--pkg/namespaces/namespaces.go5
-rw-r--r--pkg/network/subnet.go4
-rw-r--r--pkg/rootless/rootless_linux.c14
-rw-r--r--pkg/spec/config_linux_cgo.go2
-rw-r--r--pkg/spec/spec.go21
-rw-r--r--pkg/util/utils.go14
-rw-r--r--pkg/varlinkapi/attach.go2
-rw-r--r--pkg/varlinkapi/containers.go8
-rw-r--r--rootless.md15
-rw-r--r--test/e2e/create_test.go2
-rw-r--r--test/e2e/exec_test.go1
-rw-r--r--test/e2e/generate_kube_test.go33
-rw-r--r--test/e2e/logs_test.go12
-rw-r--r--test/e2e/push_test.go17
-rw-r--r--test/e2e/run_cgroup_parent_test.go6
-rw-r--r--test/e2e/run_selinux_test.go12
-rw-r--r--test/e2e/run_volume_test.go11
-rw-r--r--test/e2e/start_test.go21
-rw-r--r--test/e2e/test.yaml37
-rw-r--r--vendor/github.com/containers/buildah/.cirrus.yml30
-rw-r--r--vendor/github.com/containers/buildah/.golangci.yml1
-rw-r--r--vendor/github.com/containers/buildah/.papr.sh1
-rw-r--r--vendor/github.com/containers/buildah/.papr.yml1
-rw-r--r--vendor/github.com/containers/buildah/.travis.yml16
-rw-r--r--vendor/github.com/containers/buildah/CHANGELOG.md22
-rw-r--r--vendor/github.com/containers/buildah/Makefile7
-rw-r--r--vendor/github.com/containers/buildah/buildah.go2
-rw-r--r--vendor/github.com/containers/buildah/go.mod2
-rw-r--r--vendor/github.com/containers/buildah/go.sum2
-rw-r--r--vendor/github.com/containers/buildah/install.md15
-rw-r--r--vendor/github.com/containers/buildah/ostree_tag.sh6
-rw-r--r--vendor/github.com/containers/buildah/pkg/cli/common.go5
-rw-r--r--vendor/github.com/containers/buildah/pkg/secrets/secrets.go10
-rw-r--r--vendor/github.com/containers/buildah/run_linux.go2
-rw-r--r--vendor/github.com/containers/buildah/troubleshooting.md6
-rw-r--r--vendor/github.com/containers/buildah/util.go28
-rw-r--r--vendor/github.com/docker/docker/pkg/parsers/kernel/kernel.go74
-rw-r--r--vendor/github.com/docker/docker/pkg/parsers/kernel/kernel_darwin.go56
-rw-r--r--vendor/github.com/docker/docker/pkg/parsers/kernel/kernel_unix.go35
-rw-r--r--vendor/github.com/docker/docker/pkg/parsers/kernel/kernel_windows.go51
-rw-r--r--vendor/github.com/docker/docker/pkg/parsers/kernel/uname_linux.go17
-rw-r--r--vendor/github.com/docker/docker/pkg/parsers/kernel/uname_unsupported.go18
-rw-r--r--vendor/github.com/docker/docker/profiles/seccomp/default.json798
-rw-r--r--vendor/github.com/docker/docker/profiles/seccomp/generate.go32
-rw-r--r--vendor/github.com/docker/docker/profiles/seccomp/seccomp.go189
-rw-r--r--vendor/github.com/docker/docker/profiles/seccomp/seccomp_default.go674
-rw-r--r--vendor/github.com/docker/docker/profiles/seccomp/seccomp_unsupported.go12
-rw-r--r--vendor/github.com/onsi/ginkgo/.travis.yml3
-rw-r--r--vendor/github.com/onsi/ginkgo/CHANGELOG.md22
-rw-r--r--vendor/github.com/onsi/ginkgo/config/config.go9
-rw-r--r--vendor/github.com/onsi/ginkgo/extensions/table/table_entry.go13
-rw-r--r--vendor/github.com/onsi/ginkgo/ginkgo/run_command.go17
-rw-r--r--vendor/github.com/onsi/ginkgo/ginkgo_dsl.go5
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go21
-rw-r--r--vendor/github.com/onsi/gomega/CHANGELOG.md5
-rw-r--r--vendor/github.com/onsi/gomega/go.mod3
-rw-r--r--vendor/github.com/onsi/gomega/go.sum4
-rw-r--r--vendor/github.com/onsi/gomega/gomega_dsl.go2
-rw-r--r--vendor/github.com/uber/jaeger-client-go/.travis.yml9
-rw-r--r--vendor/github.com/uber/jaeger-client-go/CHANGELOG.md39
-rw-r--r--vendor/github.com/uber/jaeger-client-go/Gopkg.lock125
-rw-r--r--vendor/github.com/uber/jaeger-client-go/Gopkg.toml2
-rw-r--r--vendor/github.com/uber/jaeger-client-go/Makefile3
-rw-r--r--vendor/github.com/uber/jaeger-client-go/README.md23
-rw-r--r--vendor/github.com/uber/jaeger-client-go/config/config.go4
-rw-r--r--vendor/github.com/uber/jaeger-client-go/config/config_env.go24
-rw-r--r--vendor/github.com/uber/jaeger-client-go/constants.go2
-rw-r--r--vendor/github.com/uber/jaeger-client-go/jaeger_thrift_span.go2
-rw-r--r--vendor/github.com/uber/jaeger-client-go/metrics.go20
-rw-r--r--vendor/github.com/uber/jaeger-client-go/propagation.go8
-rw-r--r--vendor/github.com/uber/jaeger-client-go/reporter.go2
-rw-r--r--vendor/github.com/uber/jaeger-client-go/sampler.go446
-rw-r--r--vendor/github.com/uber/jaeger-client-go/sampler_remote.go334
-rw-r--r--vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go (renamed from vendor/github.com/uber/jaeger-client-go/sampler_options.go)71
-rw-r--r--vendor/github.com/uber/jaeger-client-go/sampler_v2.go93
-rw-r--r--vendor/github.com/uber/jaeger-client-go/span.go144
-rw-r--r--vendor/github.com/uber/jaeger-client-go/span_context.go (renamed from vendor/github.com/uber/jaeger-client-go/context.go)161
-rw-r--r--vendor/github.com/uber/jaeger-client-go/tracer.go127
-rw-r--r--vendor/github.com/uber/jaeger-client-go/utils/rate_limiter.go93
-rw-r--r--vendor/github.com/uber/jaeger-client-go/zipkin.go5
-rw-r--r--vendor/go.uber.org/atomic/.codecov.yml15
-rw-r--r--vendor/go.uber.org/atomic/.gitignore11
-rw-r--r--vendor/go.uber.org/atomic/.travis.yml27
-rw-r--r--vendor/go.uber.org/atomic/LICENSE.txt19
-rw-r--r--vendor/go.uber.org/atomic/Makefile51
-rw-r--r--vendor/go.uber.org/atomic/README.md36
-rw-r--r--vendor/go.uber.org/atomic/atomic.go351
-rw-r--r--vendor/go.uber.org/atomic/error.go55
-rw-r--r--vendor/go.uber.org/atomic/glide.lock17
-rw-r--r--vendor/go.uber.org/atomic/glide.yaml6
-rw-r--r--vendor/go.uber.org/atomic/string.go49
-rw-r--r--vendor/golang.org/x/sys/windows/registry/key.go198
-rw-r--r--vendor/golang.org/x/sys/windows/registry/mksyscall.go9
-rw-r--r--vendor/golang.org/x/sys/windows/registry/syscall.go32
-rw-r--r--vendor/golang.org/x/sys/windows/registry/value.go387
-rw-r--r--vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go120
-rw-r--r--vendor/gopkg.in/yaml.v2/decode.go14
-rw-r--r--vendor/modules.txt19
-rw-r--r--version/version.go2
359 files changed, 4342 insertions, 4935 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/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 44cb82ff0..1015b92b0 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -22,4 +22,5 @@ jobs:
stale-pr-label: 'stale-pr'
days-before-stale: 30
days-before-close: 7
+ exempt-issue-label: 'do-not-close'
exempt-pr-label: 'do-not-close'
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*
diff --git a/.golangci.yml b/.golangci.yml
index 9fcf08a43..fcf2582e8 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -2,7 +2,6 @@
run:
build-tags:
- apparmor
- - ostree
- seccomp
- selinux
concurrency: 6
diff --git a/Dockerfile b/Dockerfile
index 4b3130245..a7d795b29 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -19,7 +19,6 @@ RUN apt-get update && apt-get install -y \
libfuse-dev \
libnet-dev \
libnl-3-dev \
- libostree-dev \
libprotobuf-dev \
libprotobuf-c-dev \
libseccomp2 \
diff --git a/Dockerfile.centos b/Dockerfile.centos
index 9af7ef7f1..7c2a05dd1 100644
--- a/Dockerfile.centos
+++ b/Dockerfile.centos
@@ -22,7 +22,6 @@ RUN yum -y install btrfs-progs-devel \
containers-common \
runc \
make \
- ostree-devel \
lsof \
which\
golang-github-cpuguy83-go-md2man \
diff --git a/Dockerfile.fedora b/Dockerfile.fedora
index 8769b5c18..ef9a718dc 100644
--- a/Dockerfile.fedora
+++ b/Dockerfile.fedora
@@ -22,7 +22,6 @@ RUN dnf -y install btrfs-progs-devel \
containers-common \
runc \
make \
- ostree-devel \
lsof \
which\
golang-github-cpuguy83-go-md2man \
diff --git a/Makefile b/Makefile
index 731ad29c5..feb8e0ca3 100644
--- a/Makefile
+++ b/Makefile
@@ -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
@@ -27,7 +27,6 @@ BUILDTAGS ?= \
$(shell hack/apparmor_tag.sh) \
$(shell hack/btrfs_installed_tag.sh) \
$(shell hack/btrfs_tag.sh) \
- $(shell hack/ostree_tag.sh) \
$(shell hack/selinux_tag.sh) \
$(shell hack/systemd_tag.sh) \
exclude_graphdriver_devicemapper \
@@ -46,7 +45,7 @@ $(warning \
Install libsystemd for journald support)
endif
-BUILDTAGS_CROSS ?= containers_image_openpgp containers_image_ostree_stub exclude_graphdriver_btrfs exclude_graphdriver_devicemapper exclude_graphdriver_overlay
+BUILDTAGS_CROSS ?= containers_image_openpgp exclude_graphdriver_btrfs exclude_graphdriver_devicemapper exclude_graphdriver_overlay
ifneq (,$(findstring varlink,$(BUILDTAGS)))
PODMAN_VARLINK_DEPENDENCIES = cmd/podman/varlink/iopodman.go
endif
@@ -74,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,
@@ -156,7 +155,7 @@ gofmt: ## Verify the source code gofmt
git diff --exit-code
test/checkseccomp/checkseccomp: .gopathok $(wildcard test/checkseccomp/*.go)
- $(GO_BUILD) -ldflags '$(LDFLAGS)' -tags "$(BUILDTAGS) containers_image_ostree_stub" -o $@ $(PROJECT)/test/checkseccomp
+ $(GO_BUILD) -ldflags '$(LDFLAGS)' -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/test/checkseccomp
test/goecho/goecho: .gopathok $(wildcard test/goecho/*.go)
$(GO_BUILD) -ldflags '$(LDFLAGS)' -o $@ $(PROJECT)/test/goecho
@@ -168,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"))
@@ -197,7 +194,6 @@ clean: ## Clean artifacts
$(wildcard podman*.tar.gz) \
bin \
build \
- docs/remote \
test/checkseccomp/checkseccomp \
test/goecho/goecho \
test/testdata/redis-image \
@@ -206,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} .
@@ -313,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
@@ -350,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))
@@ -360,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)"
@@ -382,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)"
@@ -409,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)
@@ -431,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}
@@ -445,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
@@ -493,14 +487,6 @@ endef
$(call go-get,github.com/cpuguy83/go-md2man); \
fi
-.install.ostree: .gopathok
- if ! pkg-config ostree-1 2> /dev/null ; then \
- git clone https://github.com/ostreedev/ostree $(FIRST_GOPATH)/src/github.com/ostreedev/ostree ; \
- cd $(FIRST_GOPATH)src/github.com/ostreedev/ostree ; \
- ./autogen.sh --prefix=/usr/local; \
- make all install; \
- fi
-
varlink_generate: .gopathok cmd/podman/varlink/iopodman.go ## Generate varlink
varlink_api_generate: .gopathok API.md
@@ -528,7 +514,7 @@ build-all-new-commits:
git rebase $(GIT_BASE_BRANCH) -x make
build-no-cgo:
- env BUILDTAGS="containers_image_openpgp containers_image_ostree_stub exclude_graphdriver_btrfs exclude_graphdriver_devicemapper exclude_disk_quota" CGO_ENABLED=0 $(MAKE)
+ env BUILDTAGS="containers_image_openpgp exclude_graphdriver_btrfs exclude_graphdriver_devicemapper exclude_disk_quota" CGO_ENABLED=0 $(MAKE)
vendor:
export GO111MODULE=on \
diff --git a/README.md b/README.md
index 166a4bebe..8f7e7facd 100644
--- a/README.md
+++ b/README.md
@@ -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/attach.go b/cmd/podman/attach.go
index b78633ed6..b03673f29 100644
--- a/cmd/podman/attach.go
+++ b/cmd/podman/attach.go
@@ -2,6 +2,7 @@ package main
import (
"github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/adapter"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@@ -31,7 +32,7 @@ func init() {
attachCommand.SetHelpTemplate(HelpTemplate())
attachCommand.SetUsageTemplate(UsageTemplate())
flags := attachCommand.Flags()
- flags.StringVar(&attachCommand.DetachKeys, "detach-keys", "", "Override the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`")
+ flags.StringVar(&attachCommand.DetachKeys, "detach-keys", define.DefaultDetachKeys, "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`")
flags.BoolVar(&attachCommand.NoStdin, "no-stdin", false, "Do not attach STDIN. The default is false")
flags.BoolVar(&attachCommand.SigProxy, "sig-proxy", true, "Proxy received signals to the process")
flags.BoolVarP(&attachCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
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..8afbe2e0b 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(
@@ -188,7 +188,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"Run container in background and print container ID",
)
createFlags.String(
- "detach-keys", "",
+ "detach-keys", define.DefaultDetachKeys,
"Override the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`",
)
createFlags.StringSlice(
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/exec.go b/cmd/podman/exec.go
index 649a7b0db..afa701897 100644
--- a/cmd/podman/exec.go
+++ b/cmd/podman/exec.go
@@ -2,6 +2,7 @@ package main
import (
"github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/adapter"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@@ -34,7 +35,7 @@ func init() {
execCommand.SetUsageTemplate(UsageTemplate())
flags := execCommand.Flags()
flags.SetInterspersed(false)
- flags.StringVar(&execCommand.DetachKeys, "detach-keys", "", "Override the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _")
+ flags.StringVar(&execCommand.DetachKeys, "detach-keys", define.DefaultDetachKeys, "Select the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _")
flags.StringArrayVarP(&execCommand.Env, "env", "e", []string{}, "Set environment variables")
flags.BoolVarP(&execCommand.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached")
flags.BoolVarP(&execCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
diff --git a/cmd/podman/images.go b/cmd/podman/images.go
index 6157fda2a..7d498517c 100644
--- a/cmd/podman/images.go
+++ b/cmd/podman/images.go
@@ -291,6 +291,10 @@ func getImagesTemplateOutput(ctx context.Context, images []*adapter.ContainerIma
if len(tag) == 71 && strings.HasPrefix(tag, "sha256:") {
imageDigest = digest.Digest(tag)
tag = ""
+ } else {
+ if img.Digest() != "" {
+ imageDigest = img.Digest()
+ }
}
params := imagesTemplateParams{
Repository: repo,
diff --git a/cmd/podman/import.go b/cmd/podman/import.go
index 027fa7299..5a21e5cc1 100644
--- a/cmd/podman/import.go
+++ b/cmd/podman/import.go
@@ -6,7 +6,7 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/shared/parse"
"github.com/containers/libpod/pkg/adapter"
- multierror "github.com/hashicorp/go-multierror"
+ "github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
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/start.go b/cmd/podman/start.go
index 2d2cf74d2..d4b4534bb 100644
--- a/cmd/podman/start.go
+++ b/cmd/podman/start.go
@@ -35,7 +35,7 @@ func init() {
startCommand.SetUsageTemplate(UsageTemplate())
flags := startCommand.Flags()
flags.BoolVarP(&startCommand.Attach, "attach", "a", false, "Attach container's STDOUT and STDERR")
- flags.StringVar(&startCommand.DetachKeys, "detach-keys", "", "Override the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`")
+ flags.StringVar(&startCommand.DetachKeys, "detach-keys", define.DefaultDetachKeys, "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`")
flags.BoolVarP(&startCommand.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached")
flags.BoolVarP(&startCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.BoolVar(&startCommand.SigProxy, "sig-proxy", false, "Proxy received signals to the process (default true if attaching, false otherwise)")
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/build_rpm.sh b/contrib/build_rpm.sh
index 7075e3c79..1132ef380 100644
--- a/contrib/build_rpm.sh
+++ b/contrib/build_rpm.sh
@@ -28,7 +28,6 @@ declare -a PKGS=(device-mapper-devel \
libseccomp-devel \
libselinux-devel \
make \
- ostree-devel \
golang-github-cpuguy83-go-md2man \
rpm-build \
btrfs-progs-devel \
diff --git a/contrib/cirrus/container_test.sh b/contrib/cirrus/container_test.sh
index 9d3f09f60..4624868f1 100644
--- a/contrib/cirrus/container_test.sh
+++ b/contrib/cirrus/container_test.sh
@@ -89,7 +89,7 @@ if [ "${CONTAINER_RUNTIME}" == "none" ]; then
fi
-export TAGS="seccomp $($GOSRC/hack/btrfs_tag.sh) $($GOSRC/hack/libdm_tag.sh) $($GOSRC/hack/btrfs_installed_tag.sh) $($GOSRC/hack/ostree_tag.sh) $($GOSRC/hack/selinux_tag.sh)"
+export TAGS="seccomp $($GOSRC/hack/btrfs_tag.sh) $($GOSRC/hack/libdm_tag.sh) $($GOSRC/hack/btrfs_installed_tag.sh) $($GOSRC/hack/selinux_tag.sh)"
# Validate
if [ $validate -eq 1 ]; then
diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh
index 051157702..297ed49ce 100644
--- a/contrib/cirrus/lib.sh
+++ b/contrib/cirrus/lib.sh
@@ -238,34 +238,46 @@ ircmsg() {
# there is at least one release tag not having any '-' characters (return 0)
# or otherwise (return non-0).
is_release() {
- req_env_var CIRRUS_BASE_SHA CIRRUS_CHANGE_IN_REPO
- local range="${CIRRUS_BASE_SHA}..${CIRRUS_CHANGE_IN_REPO}"
- # Easy check first, default non-useful values
- if echo "${range}$CIRRUS_TAG" | grep -iq 'unknown'; then
- die 11 "is_release() unusable range ${range} or tag $CIRRUS_TAG"
- fi
- # Next easy check, is CIRRUS_TAG set
unset RELVER
+ local ret
+ req_env_var CIRRUS_CHANGE_IN_REPO
if [[ -n "$CIRRUS_TAG" ]]; then
RELVER="$CIRRUS_TAG"
- else # Lastly, look through the range for tags
- git fetch --all --tags &> /dev/null|| \
- die 12 "is_release() failed to fetch tags"
- RELVER=$(git log --pretty='format:%d' $range | \
- grep '(tag:' | sed -r -e 's/\s+[(]tag:\s+(v[0-9].*)[)]/\1/' | \
- sort -uV | tail -1)
- [[ "$?" -eq "0" ]] || \
+ elif [[ ! "$CIRRUS_BASE_SHA" =~ "unknown" ]]
+ then
+ # Normally not possible for this to be empty, except when unittesting.
+ req_env_var CIRRUS_BASE_SHA
+ local range="${CIRRUS_BASE_SHA}..${CIRRUS_CHANGE_IN_REPO}"
+ if echo "${range}$CIRRUS_TAG" | grep -iq 'unknown'; then
+ die 11 "is_release() unusable range ${range} or tag $CIRRUS_TAG"
+ fi
+
+ if type -P git &> /dev/null
+ then
+ git fetch --all --tags &> /dev/null|| \
+ die 12 "is_release() failed to fetch tags"
+ RELVER=$(git log --pretty='format:%d' $range | \
+ grep '(tag:' | sed -r -e 's/\s+[(]tag:\s+(v[0-9].*)[)]/\1/' | \
+ sort -uV | tail -1)
+ ret=$?
+ else
+ warn -1 "Git command not found while checking for release"
+ ret="-1"
+ fi
+ [[ "$ret" -eq "0" ]] || \
die 13 "is_release() failed to parse tags"
+ else # Not testing a PR, but neither CIRRUS_BASE_SHA or CIRRUS_TAG are set
+ return 1
fi
- echo "Found \$RELVER $RELVER"
if [[ -n "$RELVER" ]]; then
+ echo "Found \$RELVER $RELVER"
if echo "$RELVER" | grep -q '-'; then
- return 2
+ return 2 # development tag
else
return 0
fi
else
- return 1
+ return 1 # not a release
fi
}
diff --git a/contrib/cirrus/lib.sh.t b/contrib/cirrus/lib.sh.t
index 9915b42a4..8f4080dd5 100755
--- a/contrib/cirrus/lib.sh.t
+++ b/contrib/cirrus/lib.sh.t
@@ -138,16 +138,19 @@ function test_is_release() {
}
# FROM TO TAG RET MSG
-#test_is_release "" "" "" "" ""
-
-test_is_release "" "" "" "9" "FATAL: is_release() requires \$CIRRUS_BASE_SHA to be non-empty"
+test_is_release "" "" "" "9" "FATAL: is_release() requires \$CIRRUS_CHANGE_IN_REPO to be non-empty"
test_is_release "x" "" "" "9" "FATAL: is_release() requires \$CIRRUS_CHANGE_IN_REPO to be non-empty"
-test_is_release "unknown" "x" "" "11" "is_release() unusable range unknown..x or tag "
-test_is_release "x" "unknown" "" "11" "is_release() unusable range x..unknown or tag "
-test_is_release "x" "x" "unknown" "11" "is_release() unusable range x..x or tag unknown"
+# post-merge / tag-push testing, FROM will be set 'unknown' by (lib.sh default)
+test_is_release "unknown" "x" "" "1" ""
+# post-merge / tag-push testing, oddball tag is set, FROM will be set 'unknown'
+test_is_release "unknown" "unknown" "test-tag" "2" "Found \$RELVER test-tag"
+# post-merge / tag-push testing, sane tag is set, FROM will be set 'unknown'
+test_is_release "unknown" "unknown" "0.0.0" "0" "Found \$RELVER 0.0.0"
+# hack/get_ci_vm or PR testing, FROM and TO are set, no tag is set
+test_is_release "x" "x" "" "1" ""
-# Negative-testing git with this function is very difficult, assume it works
+# Negative-testing git with this function is very difficult, assume git works
# test_is_release ... "is_release() failed to fetch tags"
# test_is_release ... "is_release() failed to parse tags"
diff --git a/contrib/cirrus/packer/Makefile b/contrib/cirrus/packer/Makefile
index 947a2a1e9..fa87d7019 100644
--- a/contrib/cirrus/packer/Makefile
+++ b/contrib/cirrus/packer/Makefile
@@ -34,7 +34,7 @@ guard-%:
fi;
%.json: %.yml
- @python3 -c 'import json,yaml; json.dump( yaml.load(open("$<").read()), open("$@","w"), indent=2);'
+ @python3 -c 'import json,yaml; json.dump( yaml.safe_load(open("$<").read()), open("$@","w"), indent=2);'
${PACKER_DIST_FILENAME}:
@curl -L --silent --show-error \
diff --git a/contrib/cirrus/packer/fedora_setup.sh b/contrib/cirrus/packer/fedora_setup.sh
index 38b9e6860..6cfaa05ce 100644
--- a/contrib/cirrus/packer/fedora_setup.sh
+++ b/contrib/cirrus/packer/fedora_setup.sh
@@ -69,8 +69,6 @@ ooe.sh sudo dnf install -y \
make \
msitools \
nmap-ncat \
- ostree \
- ostree-devel \
pandoc \
podman \
procps-ng \
diff --git a/contrib/cirrus/packer/ubuntu_setup.sh b/contrib/cirrus/packer/ubuntu_setup.sh
index 2f54da9ed..118ee062a 100644
--- a/contrib/cirrus/packer/ubuntu_setup.sh
+++ b/contrib/cirrus/packer/ubuntu_setup.sh
@@ -83,7 +83,6 @@ $BIGTO $SUDOAPTGET install \
libnet1 \
libnet1-dev \
libnl-3-dev \
- libostree-dev \
libvarlink \
libprotobuf-c-dev \
libprotobuf-dev \
diff --git a/contrib/gate/Dockerfile b/contrib/gate/Dockerfile
index c886fc9aa..1939d7ad1 100644
--- a/contrib/gate/Dockerfile
+++ b/contrib/gate/Dockerfile
@@ -19,7 +19,6 @@ RUN dnf -y install \
lsof \
make \
nmap-ncat \
- ostree-devel \
procps-ng \
python \
python3-dateutil \
diff --git a/contrib/podmanimage/upstream/Dockerfile b/contrib/podmanimage/upstream/Dockerfile
index 82b88b50b..58e54b5b5 100644
--- a/contrib/podmanimage/upstream/Dockerfile
+++ b/contrib/podmanimage/upstream/Dockerfile
@@ -36,7 +36,6 @@ RUN dnf -y install --exclude container-selinux \
libseccomp-devel \
libselinux-devel \
make \
- ostree-devel \
pkgconfig \
runc \
fuse-overlayfs \
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index d5247f689..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
@@ -63,7 +63,6 @@ BuildRequires: libassuan-devel
BuildRequires: libgpg-error-devel
BuildRequires: libseccomp-devel
BuildRequires: libselinux-devel
-BuildRequires: ostree-devel
BuildRequires: pkgconfig
BuildRequires: make
BuildRequires: systemd-devel
@@ -139,7 +138,6 @@ Provides: bundled(golang(github.com/opencontainers/runtime-spec)) = v1.0.0
Provides: bundled(golang(github.com/opencontainers/runtime-tools)) = 625e2322645b151a7cbb93a8b42920933e72167f
Provides: bundled(golang(github.com/opencontainers/selinux)) = b6fa367ed7f534f9ba25391cc2d467085dbb445a
Provides: bundled(golang(github.com/openshift/imagebuilder)) = master
-Provides: bundled(golang(github.com/ostreedev/ostree-go)) = master
Provides: bundled(golang(github.com/pkg/errors)) = v0.8.0
Provides: bundled(golang(github.com/pmezard/go-difflib)) = 792786c7400a136282c1664665ae0a8db921c6c2
Provides: bundled(golang(github.com/pquerna/ffjson)) = d49c2bc1aa135aad0c6f4fc2056623ec78f5d5ac
@@ -383,7 +381,7 @@ mkdir -p src/%{provider}.%{provider_tld}/{containers,opencontainers}
ln -s $(dirs +1 -l) src/%{import_path_conmon}
popd
-export BUILDTAGS="selinux seccomp $(hack/btrfs_installed_tag.sh) $(hack/btrfs_tag.sh) containers_image_ostree_stub"
+export BUILDTAGS="selinux seccomp $(hack/btrfs_installed_tag.sh) $(hack/btrfs_tag.sh)"
BUILDTAGS=$BUILDTAGS make
popd
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..1ac2e49a9 100644
--- a/docs/podman-attach.1.md
+++ b/docs/source/markdown/podman-attach.1.md
@@ -20,9 +20,7 @@ it in the **libpod.conf** file: see **libpod.conf(5)** for more information.
## OPTIONS
**--detach-keys**=*sequence*
-Override the key sequence for detaching a container. Format is a single character `[a-Z]` or
-a comma separated sequence of `ctrl-<value>`, where `<value>` is one of:
-`a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`.
+Specify the key sequence for detaching a container. Format is a single character `[a-Z]` or one or more `ctrl-<value>` characters where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`. Specifying "" will disable this feature. The default is *ctrl-p,ctrl-q*.
**--latest**, **-l**
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..c10cf2cfa 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.
@@ -196,9 +198,7 @@ it in the **libpod.conf** file: see **libpod.conf(5)** for more information.
**--detach-keys**=*sequence*
-Override the key sequence for detaching a container. Format is a single character `[a-Z]` or
-a comma separated sequence of `ctrl-<value>`, where `<value>` is one of:
-`a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`.
+Specify the key sequence for detaching a container. Format is a single character `[a-Z]` or one or more `ctrl-<value>` characters where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`. Specifying "" will disable this feature. The default is *ctrl-p,ctrl-q*.
**--device**=*device*
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..9624425dc 100644
--- a/docs/podman-exec.1.md
+++ b/docs/source/markdown/podman-exec.1.md
@@ -15,7 +15,7 @@ podman\-exec - Execute a command in a running container
**--detach-keys**=*sequence*
-Override the key sequence for detaching a container. Format is a single character `[a-Z]` or `ctrl-<value>` where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`.
+Specify the key sequence for detaching a container. Format is a single character `[a-Z]` or one or more `ctrl-<value>` characters where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`. Specifying "" will disable this feature. The default is *ctrl-p,ctrl-q*.
**--env**, **-e**
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 9976bc586..de9688f5e 100644
--- a/docs/podman-pull.1.md
+++ b/docs/source/markdown/podman-pull.1.md
@@ -42,9 +42,6 @@ Image stored in local container/storage
**oci-archive:**_path_**:**_tag_
An image _tag_ in a directory compliant with "Open Container Image Layout Specification" at _path_.
- **ostree:**_image_[**@**_/absolute/repo/path_]
- An image in local OSTree repository. _/absolute/repo/path_ defaults to _/ostree/repo_.
-
## OPTIONS
**--all-tags**, **a**
diff --git a/docs/podman-push.1.md b/docs/source/markdown/podman-push.1.md
index 1cf8fd1a6..3f0350bcd 100644
--- a/docs/podman-push.1.md
+++ b/docs/source/markdown/podman-push.1.md
@@ -12,7 +12,7 @@ podman\-push - Push an image from local storage to elsewhere
Pushes an image from local storage to a specified destination.
Push is mainly used to push images to registries, however **podman push**
can be used to save images to tarballs and directories using the following
-transports: **dir:**, **docker-archive:**, **docker-daemon:**, **oci-archive:**, and **ostree:**.
+transports: **dir:**, **docker-archive:**, **docker-daemon:** and **oci-archive:**.
## imageID
Image stored in local container/storage
@@ -41,9 +41,6 @@ Image stored in local container/storage
**oci-archive:**_path_**:**_tag_
An image _tag_ in a directory compliant with "Open Container Image Layout Specification" at _path_.
- **ostree:**_image_[**@**_/absolute/repo/path_]
- An image in local OSTree repository. _/absolute/repo/path_ defaults to _/ostree/repo_.
-
## OPTIONS
**--authfile**=*path*
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..75f1f94ce 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.
@@ -202,9 +204,7 @@ it in the **libpod.conf** file: see **libpod.conf(5)** for more information.
**--detach-keys**=*sequence*
-Override the key sequence for detaching a container. Format is a single character `[a-Z]` or
-a comma separated sequence of `ctrl-<value>`, where `<value>` is one of:
-`a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`.
+Specify the key sequence for detaching a container. Format is a single character `[a-Z]` or one or more `ctrl-<value>` characters where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`. Specifying "" will disable this feature. The default is *ctrl-p,ctrl-q*.
**--device**=*device*
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..84af9d800 100644
--- a/docs/podman-start.1.md
+++ b/docs/source/markdown/podman-start.1.md
@@ -23,9 +23,7 @@ starting multiple containers.
**--detach-keys**=*sequence*
-Override the key sequence for detaching a container. Format is a single character `[a-Z]` or
-a comma separated sequence of `ctrl-<value>`, where `<value>` is one of:
-`a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`.
+Specify the key sequence for detaching a container. Format is a single character `[a-Z]` or one or more `ctrl-<value>` characters where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`. Specifying "" will disable this feature. The default is *ctrl-p,ctrl-q*.
**--interactive**, **-i**
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
diff --git a/go.mod b/go.mod
index f8272560d..9d8777e4c 100644
--- a/go.mod
+++ b/go.mod
@@ -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,8 +40,8 @@ require (
github.com/json-iterator/go v1.1.8
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/gomega v1.7.0
+ github.com/onsi/ginkgo v1.10.3
+ github.com/onsi/gomega v1.7.1
github.com/opencontainers/go-digest v1.0.0-rc1
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6
github.com/opencontainers/runc v1.0.0-rc8.0.20190827142921-dd075602f158
@@ -52,14 +52,14 @@ require (
github.com/pkg/errors v0.8.1
github.com/pkg/profile v1.3.0
github.com/pmezard/go-difflib v1.0.0
- github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f // indirect
+ github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f
github.com/sirupsen/logrus v1.4.2
github.com/spf13/cobra v0.0.5
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.4.0
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
github.com/uber-go/atomic v1.4.0 // indirect
- github.com/uber/jaeger-client-go v2.19.0+incompatible
+ github.com/uber/jaeger-client-go v2.20.0+incompatible
github.com/uber/jaeger-lib v0.0.0-20190122222657-d036253de8f5 // indirect
github.com/varlink/go v0.0.0-20190502142041-0f1d566d194b
github.com/vishvananda/netlink v1.0.0
@@ -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
diff --git a/go.sum b/go.sum
index 5f7d42046..891270aea 100644
--- a/go.sum
+++ b/go.sum
@@ -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=
@@ -295,6 +287,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=
@@ -302,6 +297,8 @@ github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
@@ -324,8 +321,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=
@@ -408,6 +403,8 @@ github.com/uber-go/atomic v1.4.0 h1:yOuPqEq4ovnhEjpHmfFwsqBXDYbQeT6Nb0bwD6XnD5o=
github.com/uber-go/atomic v1.4.0/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
github.com/uber/jaeger-client-go v2.19.0+incompatible h1:pbwbYfHUoaase0oPQOdZ1GcaUjImYGimUXSQ/+8+Z8Q=
github.com/uber/jaeger-client-go v2.19.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
+github.com/uber/jaeger-client-go v2.20.0+incompatible h1:ttG9wKdl2ikV/BGOtu+eb+VPp+R7jMeuM177Ihs5Fdc=
+github.com/uber/jaeger-client-go v2.20.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v0.0.0-20190122222657-d036253de8f5 h1:CwmGyzHTzCqCdZJkWR0A7ucZXgrCY7spRcpvm7ci//s=
github.com/uber/jaeger-lib v0.0.0-20190122222657-d036253de8f5/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
@@ -446,8 +443,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=
@@ -497,7 +492,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=
@@ -554,6 +548,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/ostree_tag.sh b/hack/ostree_tag.sh
deleted file mode 100755
index 06a5bc68c..000000000
--- a/hack/ostree_tag.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-if ! pkg-config glib-2.0 gobject-2.0 ostree-1 libselinux 2> /dev/null ; then
- echo containers_image_ostree_stub
-else
- echo containers_image_ostree
-fi
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 b90f20395..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
@@ -114,7 +116,6 @@ sudo yum install -y \
libseccomp-devel \
libselinux-devel \
make \
- ostree-devel \
pkgconfig \
runc \
containers-common
@@ -136,7 +137,6 @@ sudo apt-get install \
libglib2.0-dev \
libgpgme-dev \
libgpg-error-dev \
- libostree-dev \
libprotobuf-dev \
libprotobuf-c0-dev \
libseccomp-dev \
@@ -178,34 +178,6 @@ echo 'kernel.unprivileged_userns_clone=1' > /etc/sysctl.d/userns.conf
If any dependencies cannot be installed or are not sufficiently current, they have to be built from source.
This will mainly affect Debian, Ubuntu, and related distributions, or RHEL where no subscription is active (e.g. Cloud VMs).
-#### ostree
-
-A copy of the development libraries for `ostree` is necessary, either in the form of the `libostree-dev` package
-from the [flatpak](https://launchpad.net/~alexlarsson/+archive/ubuntu/flatpak) PPA,
-or built [from source](https://github.com/ostreedev/ostree/blob/master/docs/contributing-tutorial.md)
-(see also [here](https://ostree.readthedocs.io/en/latest/#building)). As of Ubuntu 18.04, `libostree-dev` is available in the main repositories,
-and the PPA is no longer required.
-
-To build, use the following (running `make` can take a while):
-```bash
-git clone https://github.com/ostreedev/ostree ~/ostree
-cd ~/ostree
-git submodule update --init
-
-# for Fedora, CentOS, RHEL
-sudo yum install -y automake bison e2fsprogs-devel fuse-devel gpgme-devel libseccomp-devel libtool systemd-devel xz-devel zlib-devel
-
-# for Debian, Ubuntu etc.
-sudo apt-get install -y automake bison e2fsprogs e2fslibs-dev fuse libfuse-dev libgpgme-dev liblzma-dev libseccomp-dev libsystemd-dev libtool zlib1g
-
-# for all distributions
-./autogen.sh --prefix=/usr --libdir=/usr/lib64 --sysconfdir=/etc
-# remove --nonet option due to https:/github.com/ostreedev/ostree/issues/1374
-sed -i '/.*--nonet.*/d' ./Makefile-man.am
-make
-sudo make install
-```
-
#### golang
Be careful to double-check that the version of golang is new enough (i.e. `go version`), version 1.10.x or higher is required.
@@ -324,8 +296,6 @@ make BUILDTAGS='seccomp apparmor'
| exclude_graphdriver_btrfs | exclude btrfs | libbtrfs |
| exclude_graphdriver_devicemapper | exclude device-mapper | libdm |
| libdm_no_deferred_remove | exclude deferred removal in libdm | libdm |
-| ostree | ostree support (requires selinux) | ostree-1, libselinux |
-| containers_image_ostree_stub | exclude ostree | |
| seccomp | syscall filtering | libseccomp |
| selinux | selinux process and mount labeling | |
| systemd | journald logging | libsystemd |
diff --git a/libpod.conf b/libpod.conf
index 47f66ecc1..7e0228c19 100644
--- a/libpod.conf
+++ b/libpod.conf
@@ -142,8 +142,36 @@ runc = [
]
crun = [
- "/usr/bin/crun",
- "/usr/local/bin/crun",
+ "/usr/bin/crun",
+ "/usr/sbin/crun",
+ "/usr/local/bin/crun",
+ "/usr/local/sbin/crun",
+ "/sbin/crun",
+ "/bin/crun",
+ "/run/current-system/sw/bin/crun",
+]
+
+# Kata Containers is an OCI runtime, where containers are run inside lightweight
+# Virtual Machines (VMs). Kata provides additional isolation towards the host,
+# minimizing the host attack surface and mitigating the consequences of
+# containers breakout.
+# Please notes that Kata does not support rootless podman yet, but we can leave
+# the paths below blank to let them be discovered by the $PATH environment
+# variable.
+
+# Kata Containers with the default configured VMM
+kata-runtime = [
+ "/usr/bin/kata-runtime",
+]
+
+# Kata Containers with the QEMU VMM
+kata-qemu = [
+ "/usr/bin/kata-qemu",
+]
+
+# Kata Containers with the Firecracker VMM
+kata-fc = [
+ "/usr/bin/kata-fc",
]
# The [runtimes] table MUST be the last thing in this file.
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..5decaeab7
--- /dev/null
+++ b/libpod/config/default.go
@@ -0,0 +1,152 @@
+package config
+
+import (
+ "os"
+ "path/filepath"
+
+ "github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/libpod/events"
+ "github.com/containers/libpod/pkg/cgroups"
+ "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"
+
+ // If we're running on cgroups v2, default to using crun.
+ if onCgroupsv2, _ := cgroups.IsCgroup2UnifiedMode(); onCgroupsv2 {
+ c.OCIRuntime = "crun"
+ }
+
+ 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",
+ },
+ "crun": {
+ "/usr/bin/crun",
+ "/usr/sbin/crun",
+ "/usr/local/bin/crun",
+ "/usr/local/sbin/crun",
+ "/sbin/crun",
+ "/bin/crun",
+ "/run/current-system/sw/bin/crun",
+ },
+ }
+ 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/events/journal_linux.go b/libpod/events/journal_linux.go
index 470c76959..9e6fffc29 100644
--- a/libpod/events/journal_linux.go
+++ b/libpod/events/journal_linux.go
@@ -54,6 +54,7 @@ func (e EventJournalD) Write(ee Event) error {
// Read reads events from the journal and sends qualified events to the event channel
func (e EventJournalD) Read(options ReadOptions) error {
+ defer close(options.EventChannel)
eventOptions, err := generateEventOptions(options.Filters, options.Since, options.Until)
if err != nil {
return errors.Wrapf(err, "failed to generate event options")
@@ -87,7 +88,6 @@ func (e EventJournalD) Read(options ReadOptions) error {
if err != nil {
return err
}
- defer close(options.EventChannel)
for {
if _, err := j.Next(); err != nil {
return err
diff --git a/libpod/events/logfile.go b/libpod/events/logfile.go
index 4b65b0ad0..93e6fa3c9 100644
--- a/libpod/events/logfile.go
+++ b/libpod/events/logfile.go
@@ -41,6 +41,7 @@ func (e EventLogFile) Write(ee Event) error {
// Reads from the log file
func (e EventLogFile) Read(options ReadOptions) error {
+ defer close(options.EventChannel)
eventOptions, err := generateEventOptions(options.Filters, options.Since, options.Until)
if err != nil {
return errors.Wrapf(err, "unable to generate event options")
@@ -68,7 +69,6 @@ func (e EventLogFile) Read(options ReadOptions) error {
options.EventChannel <- event
}
}
- close(options.EventChannel)
return nil
}
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/kube.go b/libpod/kube.go
index d0e7baf95..47a77991e 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -487,13 +487,16 @@ func generateKubeSecurityContext(c *Container) (*v1.SecurityContext, error) {
if err := c.syncContainer(); err != nil {
return nil, errors.Wrapf(err, "unable to sync container during YAML generation")
}
+
logrus.Debugf("Looking in container for user: %s", c.User())
- u, err := lookup.GetUser(c.state.Mountpoint, c.User())
+ execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.User(), nil)
if err != nil {
return nil, err
}
- user := int64(u.Uid)
- sc.RunAsUser = &user
+ uid := int64(execUser.Uid)
+ gid := int64(execUser.Gid)
+ sc.RunAsUser = &uid
+ sc.RunAsGroup = &gid
}
return &sc, nil
}
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..46c70e7eb 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
+ return []byte{}, nil
}
detachKeys, err := term.ToBytes(keys)
if err != nil {
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 448e05bdf..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)
}
@@ -1023,8 +1024,8 @@ func prepareProcessExec(c *Container, cmd, env []string, tty bool, cwd, user, se
if err != nil {
return nil, err
}
-
pspec := c.config.Spec.Process
+ pspec.SelinuxLabel = c.config.ProcessLabel
pspec.Args = cmd
// We need to default this to false else it will inherit terminal as true
// from the container.
@@ -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())
@@ -1220,17 +1221,9 @@ func (r *ConmonOCIRuntime) moveConmonToCgroupAndSignal(ctr *Container, cmd *exec
mustCreateCgroup = false
}
- if rootless.IsRootless() {
- ownsCgroup, err := cgroups.UserOwnsCurrentSystemdCgroup()
- if err != nil {
- return err
- }
- mustCreateCgroup = !ownsCgroup
- }
-
if mustCreateCgroup {
cgroupParent := ctr.CgroupParent()
- if r.cgroupManager == SystemdCgroupsManager {
+ if r.cgroupManager == define.SystemdCgroupsManager {
unitName := createUnitName("libpod-conmon", ctr.ID())
realCgroupParent := cgroupParent
@@ -1353,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/libpod/volume_internal_linux.go b/libpod/volume_internal_linux.go
index 4c0332018..70eccbecb 100644
--- a/libpod/volume_internal_linux.go
+++ b/libpod/volume_internal_linux.go
@@ -3,8 +3,8 @@
package libpod
import (
- "io/ioutil"
"os/exec"
+ "strings"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/rootless"
@@ -72,16 +72,10 @@ func (v *Volume) mount() error {
mountArgs = append(mountArgs, volDevice, v.config.MountPoint)
mountCmd := exec.Command(mountPath, mountArgs...)
- errPipe, err := mountCmd.StderrPipe()
- if err != nil {
- return errors.Wrapf(err, "error getting stderr pipe for mount")
- }
- if err := mountCmd.Start(); err != nil {
- out, err2 := ioutil.ReadAll(errPipe)
- if err2 != nil {
- return errors.Wrapf(err2, "error reading mount STDERR")
- }
- return errors.Wrapf(errors.New(string(out)), "error mounting volume %s", v.Name())
+ logrus.Debugf("Running mount command: %s %s", mountPath, strings.Join(mountArgs, " "))
+ if output, err := mountCmd.CombinedOutput(); err != nil {
+ logrus.Debugf("Mount failed with %v", err)
+ return errors.Wrapf(errors.Errorf(string(output)), "error mounting volume %s", v.Name())
}
logrus.Debugf("Mounted volume %s", v.Name())
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
index 70c8b1191..90acf9cbc 100644
--- a/logo/podman-logo.png
+++ b/logo/podman-logo.png
Binary files differ
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 430b6925d..a09466243 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
@@ -396,17 +400,8 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode
}
}
- config, err := r.Runtime.GetConfig()
- if err != nil {
- return exitCode, err
- }
- detachKeys := c.String("detach-keys")
- if detachKeys == "" {
- detachKeys = config.DetachKeys
- }
-
// if the container was created as part of a pod, also start its dependencies, if any.
- if err := StartAttachCtr(ctx, ctr, outputStream, errorStream, inputStream, detachKeys, c.Bool("sig-proxy"), true, c.IsSet("pod")); err != nil {
+ if err := StartAttachCtr(ctx, ctr, outputStream, errorStream, inputStream, c.String("detach-keys"), c.Bool("sig-proxy"), true, c.IsSet("pod")); err != nil {
// We've manually detached from the container
// Do not perform cleanup, or wait for container exit code
// Just exit immediately
@@ -656,20 +651,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 +891,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 +969,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/containers_remote.go b/pkg/adapter/containers_remote.go
index f4e83a975..20471d895 100644
--- a/pkg/adapter/containers_remote.go
+++ b/pkg/adapter/containers_remote.go
@@ -1021,7 +1021,7 @@ func (r *LocalRuntime) Commit(ctx context.Context, c *cliconfig.CommitValues, co
func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecValues) (int, error) {
var (
oldTermState *term.State
- ec int = define.ExecErrorCodeGeneric
+ ec = define.ExecErrorCodeGeneric
)
// default invalid command exit code
// Validate given environment variables
diff --git a/pkg/adapter/pods.go b/pkg/adapter/pods.go
index d8d5b884f..6648edc82 100644
--- a/pkg/adapter/pods.go
+++ b/pkg/adapter/pods.go
@@ -666,6 +666,58 @@ func getPodPorts(containers []v1.Container) []ocicni.PortMapping {
return infraPorts
}
+func setupSecurityContext(containerConfig *createconfig.CreateConfig, containerYAML v1.Container) {
+ if containerYAML.SecurityContext == nil {
+ return
+ }
+ if containerYAML.SecurityContext.ReadOnlyRootFilesystem != nil {
+ containerConfig.ReadOnlyRootfs = *containerYAML.SecurityContext.ReadOnlyRootFilesystem
+ }
+ if containerYAML.SecurityContext.Privileged != nil {
+ containerConfig.Privileged = *containerYAML.SecurityContext.Privileged
+ }
+
+ if containerYAML.SecurityContext.AllowPrivilegeEscalation != nil {
+ containerConfig.NoNewPrivs = !*containerYAML.SecurityContext.AllowPrivilegeEscalation
+ }
+
+ 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))
+ }
+ for _, capability := range caps.Drop {
+ containerConfig.CapDrop = append(containerConfig.CapDrop, string(capability))
+ }
+ }
+ if containerYAML.SecurityContext.RunAsUser != nil {
+ containerConfig.User = fmt.Sprintf("%d", *containerYAML.SecurityContext.RunAsUser)
+ }
+ if containerYAML.SecurityContext.RunAsGroup != nil {
+ if containerConfig.User == "" {
+ containerConfig.User = "0"
+ }
+ containerConfig.User = fmt.Sprintf("%s:%d", containerConfig.User, *containerYAML.SecurityContext.RunAsGroup)
+ }
+}
+
// kubeContainerToCreateConfig takes a v1.Container and returns a createconfig describing a container
func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container, runtime *libpod.Runtime, newImage *image.Image, namespaces map[string]string, volumes map[string]string, podID string) (*createconfig.CreateConfig, error) {
var (
@@ -690,29 +742,8 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container
containerConfig.User = imageData.Config.User
}
- if containerYAML.SecurityContext != nil {
- if containerConfig.SecurityOpts != nil {
- if containerYAML.SecurityContext.ReadOnlyRootFilesystem != nil {
- containerConfig.ReadOnlyRootfs = *containerYAML.SecurityContext.ReadOnlyRootFilesystem
- }
- if containerYAML.SecurityContext.Privileged != nil {
- containerConfig.Privileged = *containerYAML.SecurityContext.Privileged
- }
-
- if containerYAML.SecurityContext.AllowPrivilegeEscalation != nil {
- containerConfig.NoNewPrivs = !*containerYAML.SecurityContext.AllowPrivilegeEscalation
- }
+ setupSecurityContext(&containerConfig, containerYAML)
- }
- if caps := containerYAML.SecurityContext.Capabilities; caps != nil {
- for _, capability := range caps.Add {
- containerConfig.CapAdd = append(containerConfig.CapAdd, string(capability))
- }
- for _, capability := range caps.Drop {
- containerConfig.CapDrop = append(containerConfig.CapDrop, string(capability))
- }
- }
- }
var err error
containerConfig.SeccompProfilePath, err = libpod.DefaultSeccompPath()
if err != nil {
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/network/subnet.go b/pkg/network/subnet.go
index 82ab9a8c8..90f0cdfce 100644
--- a/pkg/network/subnet.go
+++ b/pkg/network/subnet.go
@@ -18,7 +18,7 @@ func incByte(subnet *net.IPNet, idx int, shift uint) error {
subnet.IP[idx] = 0
return incByte(subnet, idx-1, 0)
}
- subnet.IP[idx] += (1 << shift)
+ subnet.IP[idx] += 1 << shift
return nil
}
@@ -58,7 +58,7 @@ func LastIPInSubnet(addr *net.IPNet) (net.IP, error) { //nolint:interfacer
}
hostStart := ones / 8
// Handle the first host byte
- cidr.IP[hostStart] |= (0xff & cidr.Mask[hostStart])
+ cidr.IP[hostStart] |= 0xff & cidr.Mask[hostStart]
// Fill the rest with ones
for i := hostStart; i < len(cidr.IP); i++ {
cidr.IP[i] = 0xff
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/config_linux_cgo.go b/pkg/spec/config_linux_cgo.go
index e6e92a7cc..a1527752a 100644
--- a/pkg/spec/config_linux_cgo.go
+++ b/pkg/spec/config_linux_cgo.go
@@ -5,9 +5,9 @@ package createconfig
import (
"io/ioutil"
- "github.com/docker/docker/profiles/seccomp"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
+ seccomp "github.com/seccomp/containers-golang"
)
func getSeccompConfig(config *CreateConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) {
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/create_test.go b/test/e2e/create_test.go
index f2020547f..f5dca321c 100644
--- a/test/e2e/create_test.go
+++ b/test/e2e/create_test.go
@@ -239,7 +239,7 @@ var _ = Describe("Podman create", func() {
session = podmanTest.PodmanNoCache([]string{"create", "--pull", "always", "--name=foo", "nginx"})
session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To((Equal(0)))
+ Expect(session.ExitCode()).To(Equal(0))
})
It("podman create using image list by tag", func() {
diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go
index 1c4a9adb9..ed4eb3335 100644
--- a/test/e2e/exec_test.go
+++ b/test/e2e/exec_test.go
@@ -243,4 +243,5 @@ var _ = Describe("Podman exec", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
+
})
diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go
index 5d3b1238a..603edbe6b 100644
--- a/test/e2e/generate_kube_test.go
+++ b/test/e2e/generate_kube_test.go
@@ -208,6 +208,39 @@ var _ = Describe("Podman generate kube", func() {
Expect(psOut).To(ContainSubstring("test2"))
})
+ It("podman generate with user and reimport kube on pod", func() {
+ podName := "toppod"
+ _, rc, _ := podmanTest.CreatePod(podName)
+ Expect(rc).To(Equal(0))
+
+ session := podmanTest.Podman([]string{"create", "--pod", podName, "--name", "test1", "--user", "100:200", ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ inspect := podmanTest.Podman([]string{"inspect", "--format", "{{.Config.User}}", "test1"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(Equal(0))
+ Expect(inspect.OutputToString()).To(ContainSubstring("100:200"))
+
+ outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml")
+ kube := podmanTest.Podman([]string{"generate", "kube", "-f", outputFile, podName})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"pod", "rm", "-af"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"play", "kube", outputFile})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ inspect1 := podmanTest.Podman([]string{"inspect", "--format", "{{.Config.User}}", "test1"})
+ inspect1.WaitWithDefaultTimeout()
+ Expect(inspect1.ExitCode()).To(Equal(0))
+ Expect(inspect1.OutputToString()).To(ContainSubstring(inspect.OutputToString()))
+ })
+
It("podman generate kube with volume", func() {
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
err := os.MkdirAll(vol1, 0755)
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/push_test.go b/test/e2e/push_test.go
index 50f0ca6d9..0747257be 100644
--- a/test/e2e/push_test.go
+++ b/test/e2e/push_test.go
@@ -203,23 +203,6 @@ var _ = Describe("Podman push", func() {
Expect(session.ExitCode()).To(Equal(0))
})
- It("podman push to local ostree", func() {
- if !IsCommandAvailable("ostree") {
- Skip("ostree is not installed")
- }
-
- ostreePath := filepath.Join(podmanTest.TempDir, "ostree/repo")
- os.MkdirAll(ostreePath, os.ModePerm)
-
- setup := SystemExec("ostree", []string{strings.Join([]string{"--repo=", ostreePath}, ""), "init"})
- Expect(setup.ExitCode()).To(Equal(0))
-
- session := podmanTest.PodmanNoCache([]string{"push", ALPINE, strings.Join([]string{"ostree:alp@", ostreePath}, "")})
- session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(Equal(0))
-
- })
-
It("podman push to docker-archive no reference", func() {
tarfn := filepath.Join(podmanTest.TempDir, "alp.tar")
session := podmanTest.PodmanNoCache([]string{"push", ALPINE,
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 0c78ab15b..358137aa9 100644
--- a/test/e2e/run_selinux_test.go
+++ b/test/e2e/run_selinux_test.go
@@ -165,4 +165,16 @@ var _ = Describe("Podman run", func() {
Expect(session.ExitCode()).To(Equal(126))
})
+ It("podman exec selinux check", func() {
+ setup := podmanTest.RunTopContainer("test1")
+ setup.WaitWithDefaultTimeout()
+ Expect(setup.ExitCode()).To(Equal(0))
+
+ 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()
+ Expect(session.OutputToString()).To(Equal(session1.OutputToString()))
+ })
+
})
diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go
index c96059787..8e5de85e4 100644
--- a/test/e2e/run_volume_test.go
+++ b/test/e2e/run_volume_test.go
@@ -364,4 +364,15 @@ var _ = Describe("Podman run with volumes", func() {
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Not(ContainSubstring("noexec")))
})
+
+ It("podman mount with invalid option fails", func() {
+ volName := "testVol"
+ volCreate := podmanTest.Podman([]string{"volume", "create", "--opt", "type=tmpfs", "--opt", "device=tmpfs", "--opt", "o=invalid", volName})
+ volCreate.WaitWithDefaultTimeout()
+ Expect(volCreate.ExitCode()).To(Equal(0))
+
+ volMount := podmanTest.Podman([]string{"run", "--rm", "-v", fmt.Sprintf("%s:/tmp", volName), ALPINE, "ls"})
+ volMount.WaitWithDefaultTimeout()
+ Expect(volMount.ExitCode()).To(Not(Equal(0)))
+ })
})
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..98d2c91df
--- /dev/null
+++ b/test/e2e/test.yaml
@@ -0,0 +1,37 @@
+# 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:
+ runAsUser: 1000
+ runAsGroup: 3000
+ fsGroup: 2000
+ 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/docker/docker/pkg/parsers/kernel/kernel.go b/vendor/github.com/docker/docker/pkg/parsers/kernel/kernel.go
deleted file mode 100644
index 94780ef61..000000000
--- a/vendor/github.com/docker/docker/pkg/parsers/kernel/kernel.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// +build !windows
-
-// Package kernel provides helper function to get, parse and compare kernel
-// versions for different platforms.
-package kernel // import "github.com/docker/docker/pkg/parsers/kernel"
-
-import (
- "errors"
- "fmt"
-)
-
-// VersionInfo holds information about the kernel.
-type VersionInfo struct {
- Kernel int // Version of the kernel (e.g. 4.1.2-generic -> 4)
- Major int // Major part of the kernel version (e.g. 4.1.2-generic -> 1)
- Minor int // Minor part of the kernel version (e.g. 4.1.2-generic -> 2)
- Flavor string // Flavor of the kernel version (e.g. 4.1.2-generic -> generic)
-}
-
-func (k *VersionInfo) String() string {
- return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor)
-}
-
-// CompareKernelVersion compares two kernel.VersionInfo structs.
-// Returns -1 if a < b, 0 if a == b, 1 it a > b
-func CompareKernelVersion(a, b VersionInfo) int {
- if a.Kernel < b.Kernel {
- return -1
- } else if a.Kernel > b.Kernel {
- return 1
- }
-
- if a.Major < b.Major {
- return -1
- } else if a.Major > b.Major {
- return 1
- }
-
- if a.Minor < b.Minor {
- return -1
- } else if a.Minor > b.Minor {
- return 1
- }
-
- return 0
-}
-
-// ParseRelease parses a string and creates a VersionInfo based on it.
-func ParseRelease(release string) (*VersionInfo, error) {
- var (
- kernel, major, minor, parsed int
- flavor, partial string
- )
-
- // Ignore error from Sscanf to allow an empty flavor. Instead, just
- // make sure we got all the version numbers.
- parsed, _ = fmt.Sscanf(release, "%d.%d%s", &kernel, &major, &partial)
- if parsed < 2 {
- return nil, errors.New("Can't parse kernel version " + release)
- }
-
- // sometimes we have 3.12.25-gentoo, but sometimes we just have 3.12-1-amd64
- parsed, _ = fmt.Sscanf(partial, ".%d%s", &minor, &flavor)
- if parsed < 1 {
- flavor = partial
- }
-
- return &VersionInfo{
- Kernel: kernel,
- Major: major,
- Minor: minor,
- Flavor: flavor,
- }, nil
-}
diff --git a/vendor/github.com/docker/docker/pkg/parsers/kernel/kernel_darwin.go b/vendor/github.com/docker/docker/pkg/parsers/kernel/kernel_darwin.go
deleted file mode 100644
index 6a302dcee..000000000
--- a/vendor/github.com/docker/docker/pkg/parsers/kernel/kernel_darwin.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// +build darwin
-
-// Package kernel provides helper function to get, parse and compare kernel
-// versions for different platforms.
-package kernel // import "github.com/docker/docker/pkg/parsers/kernel"
-
-import (
- "fmt"
- "os/exec"
- "strings"
-
- shellwords "github.com/mattn/go-shellwords"
-)
-
-// GetKernelVersion gets the current kernel version.
-func GetKernelVersion() (*VersionInfo, error) {
- release, err := getRelease()
- if err != nil {
- return nil, err
- }
-
- return ParseRelease(release)
-}
-
-// getRelease uses `system_profiler SPSoftwareDataType` to get OSX kernel version
-func getRelease() (string, error) {
- cmd := exec.Command("system_profiler", "SPSoftwareDataType")
- osName, err := cmd.Output()
- if err != nil {
- return "", err
- }
-
- var release string
- data := strings.Split(string(osName), "\n")
- for _, line := range data {
- if strings.Contains(line, "Kernel Version") {
- // It has the format like ' Kernel Version: Darwin 14.5.0'
- content := strings.SplitN(line, ":", 2)
- if len(content) != 2 {
- return "", fmt.Errorf("Kernel Version is invalid")
- }
-
- prettyNames, err := shellwords.Parse(content[1])
- if err != nil {
- return "", fmt.Errorf("Kernel Version is invalid: %s", err.Error())
- }
-
- if len(prettyNames) != 2 {
- return "", fmt.Errorf("Kernel Version needs to be 'Darwin x.x.x' ")
- }
- release = prettyNames[1]
- }
- }
-
- return release, nil
-}
diff --git a/vendor/github.com/docker/docker/pkg/parsers/kernel/kernel_unix.go b/vendor/github.com/docker/docker/pkg/parsers/kernel/kernel_unix.go
deleted file mode 100644
index 8a9aa3122..000000000
--- a/vendor/github.com/docker/docker/pkg/parsers/kernel/kernel_unix.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// +build linux freebsd openbsd
-
-// Package kernel provides helper function to get, parse and compare kernel
-// versions for different platforms.
-package kernel // import "github.com/docker/docker/pkg/parsers/kernel"
-
-import (
- "bytes"
-
- "github.com/sirupsen/logrus"
-)
-
-// GetKernelVersion gets the current kernel version.
-func GetKernelVersion() (*VersionInfo, error) {
- uts, err := uname()
- if err != nil {
- return nil, err
- }
-
- // Remove the \x00 from the release for Atoi to parse correctly
- return ParseRelease(string(uts.Release[:bytes.IndexByte(uts.Release[:], 0)]))
-}
-
-// CheckKernelVersion checks if current kernel is newer than (or equal to)
-// the given version.
-func CheckKernelVersion(k, major, minor int) bool {
- if v, err := GetKernelVersion(); err != nil {
- logrus.Warnf("error getting kernel version: %s", err)
- } else {
- if CompareKernelVersion(*v, VersionInfo{Kernel: k, Major: major, Minor: minor}) < 0 {
- return false
- }
- }
- return true
-}
diff --git a/vendor/github.com/docker/docker/pkg/parsers/kernel/kernel_windows.go b/vendor/github.com/docker/docker/pkg/parsers/kernel/kernel_windows.go
deleted file mode 100644
index a04763872..000000000
--- a/vendor/github.com/docker/docker/pkg/parsers/kernel/kernel_windows.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package kernel // import "github.com/docker/docker/pkg/parsers/kernel"
-
-import (
- "fmt"
-
- "golang.org/x/sys/windows"
- "golang.org/x/sys/windows/registry"
-)
-
-// VersionInfo holds information about the kernel.
-type VersionInfo struct {
- kvi string // Version of the kernel (e.g. 6.1.7601.17592 -> 6)
- major int // Major part of the kernel version (e.g. 6.1.7601.17592 -> 1)
- minor int // Minor part of the kernel version (e.g. 6.1.7601.17592 -> 7601)
- build int // Build number of the kernel version (e.g. 6.1.7601.17592 -> 17592)
-}
-
-func (k *VersionInfo) String() string {
- return fmt.Sprintf("%d.%d %d (%s)", k.major, k.minor, k.build, k.kvi)
-}
-
-// GetKernelVersion gets the current kernel version.
-func GetKernelVersion() (*VersionInfo, error) {
-
- KVI := &VersionInfo{"Unknown", 0, 0, 0}
-
- k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
- if err != nil {
- return KVI, err
- }
- defer k.Close()
-
- blex, _, err := k.GetStringValue("BuildLabEx")
- if err != nil {
- return KVI, err
- }
- KVI.kvi = blex
-
- // Important - dockerd.exe MUST be manifested for this API to return
- // the correct information.
- dwVersion, err := windows.GetVersion()
- if err != nil {
- return KVI, err
- }
-
- KVI.major = int(dwVersion & 0xFF)
- KVI.minor = int((dwVersion & 0xFF00) >> 8)
- KVI.build = int((dwVersion & 0xFFFF0000) >> 16)
-
- return KVI, nil
-}
diff --git a/vendor/github.com/docker/docker/pkg/parsers/kernel/uname_linux.go b/vendor/github.com/docker/docker/pkg/parsers/kernel/uname_linux.go
deleted file mode 100644
index 212ff4502..000000000
--- a/vendor/github.com/docker/docker/pkg/parsers/kernel/uname_linux.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package kernel // import "github.com/docker/docker/pkg/parsers/kernel"
-
-import "golang.org/x/sys/unix"
-
-// Utsname represents the system name structure.
-// It is passthrough for unix.Utsname in order to make it portable with
-// other platforms where it is not available.
-type Utsname unix.Utsname
-
-func uname() (*unix.Utsname, error) {
- uts := &unix.Utsname{}
-
- if err := unix.Uname(uts); err != nil {
- return nil, err
- }
- return uts, nil
-}
diff --git a/vendor/github.com/docker/docker/pkg/parsers/kernel/uname_unsupported.go b/vendor/github.com/docker/docker/pkg/parsers/kernel/uname_unsupported.go
deleted file mode 100644
index 97906e4cd..000000000
--- a/vendor/github.com/docker/docker/pkg/parsers/kernel/uname_unsupported.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// +build !linux
-
-package kernel // import "github.com/docker/docker/pkg/parsers/kernel"
-
-import (
- "errors"
-)
-
-// Utsname represents the system name structure.
-// It is defined here to make it portable as it is available on linux but not
-// on windows.
-type Utsname struct {
- Release [65]byte
-}
-
-func uname() (*Utsname, error) {
- return nil, errors.New("Kernel version detection is available only on linux")
-}
diff --git a/vendor/github.com/docker/docker/profiles/seccomp/default.json b/vendor/github.com/docker/docker/profiles/seccomp/default.json
deleted file mode 100644
index 71ac412df..000000000
--- a/vendor/github.com/docker/docker/profiles/seccomp/default.json
+++ /dev/null
@@ -1,798 +0,0 @@
-{
- "defaultAction": "SCMP_ACT_ERRNO",
- "archMap": [
- {
- "architecture": "SCMP_ARCH_X86_64",
- "subArchitectures": [
- "SCMP_ARCH_X86",
- "SCMP_ARCH_X32"
- ]
- },
- {
- "architecture": "SCMP_ARCH_AARCH64",
- "subArchitectures": [
- "SCMP_ARCH_ARM"
- ]
- },
- {
- "architecture": "SCMP_ARCH_MIPS64",
- "subArchitectures": [
- "SCMP_ARCH_MIPS",
- "SCMP_ARCH_MIPS64N32"
- ]
- },
- {
- "architecture": "SCMP_ARCH_MIPS64N32",
- "subArchitectures": [
- "SCMP_ARCH_MIPS",
- "SCMP_ARCH_MIPS64"
- ]
- },
- {
- "architecture": "SCMP_ARCH_MIPSEL64",
- "subArchitectures": [
- "SCMP_ARCH_MIPSEL",
- "SCMP_ARCH_MIPSEL64N32"
- ]
- },
- {
- "architecture": "SCMP_ARCH_MIPSEL64N32",
- "subArchitectures": [
- "SCMP_ARCH_MIPSEL",
- "SCMP_ARCH_MIPSEL64"
- ]
- },
- {
- "architecture": "SCMP_ARCH_S390X",
- "subArchitectures": [
- "SCMP_ARCH_S390"
- ]
- }
- ],
- "syscalls": [
- {
- "names": [
- "accept",
- "accept4",
- "access",
- "adjtimex",
- "alarm",
- "bind",
- "brk",
- "capget",
- "capset",
- "chdir",
- "chmod",
- "chown",
- "chown32",
- "clock_getres",
- "clock_gettime",
- "clock_nanosleep",
- "close",
- "connect",
- "copy_file_range",
- "creat",
- "dup",
- "dup2",
- "dup3",
- "epoll_create",
- "epoll_create1",
- "epoll_ctl",
- "epoll_ctl_old",
- "epoll_pwait",
- "epoll_wait",
- "epoll_wait_old",
- "eventfd",
- "eventfd2",
- "execve",
- "execveat",
- "exit",
- "exit_group",
- "faccessat",
- "fadvise64",
- "fadvise64_64",
- "fallocate",
- "fanotify_mark",
- "fchdir",
- "fchmod",
- "fchmodat",
- "fchown",
- "fchown32",
- "fchownat",
- "fcntl",
- "fcntl64",
- "fdatasync",
- "fgetxattr",
- "flistxattr",
- "flock",
- "fork",
- "fremovexattr",
- "fsetxattr",
- "fstat",
- "fstat64",
- "fstatat64",
- "fstatfs",
- "fstatfs64",
- "fsync",
- "ftruncate",
- "ftruncate64",
- "futex",
- "futimesat",
- "getcpu",
- "getcwd",
- "getdents",
- "getdents64",
- "getegid",
- "getegid32",
- "geteuid",
- "geteuid32",
- "getgid",
- "getgid32",
- "getgroups",
- "getgroups32",
- "getitimer",
- "getpeername",
- "getpgid",
- "getpgrp",
- "getpid",
- "getppid",
- "getpriority",
- "getrandom",
- "getresgid",
- "getresgid32",
- "getresuid",
- "getresuid32",
- "getrlimit",
- "get_robust_list",
- "getrusage",
- "getsid",
- "getsockname",
- "getsockopt",
- "get_thread_area",
- "gettid",
- "gettimeofday",
- "getuid",
- "getuid32",
- "getxattr",
- "inotify_add_watch",
- "inotify_init",
- "inotify_init1",
- "inotify_rm_watch",
- "io_cancel",
- "ioctl",
- "io_destroy",
- "io_getevents",
- "io_pgetevents",
- "ioprio_get",
- "ioprio_set",
- "io_setup",
- "io_submit",
- "io_uring_enter",
- "io_uring_register",
- "io_uring_setup",
- "ipc",
- "kill",
- "lchown",
- "lchown32",
- "lgetxattr",
- "link",
- "linkat",
- "listen",
- "listxattr",
- "llistxattr",
- "_llseek",
- "lremovexattr",
- "lseek",
- "lsetxattr",
- "lstat",
- "lstat64",
- "madvise",
- "memfd_create",
- "mincore",
- "mkdir",
- "mkdirat",
- "mknod",
- "mknodat",
- "mlock",
- "mlock2",
- "mlockall",
- "mmap",
- "mmap2",
- "mprotect",
- "mq_getsetattr",
- "mq_notify",
- "mq_open",
- "mq_timedreceive",
- "mq_timedsend",
- "mq_unlink",
- "mremap",
- "msgctl",
- "msgget",
- "msgrcv",
- "msgsnd",
- "msync",
- "munlock",
- "munlockall",
- "munmap",
- "nanosleep",
- "newfstatat",
- "_newselect",
- "open",
- "openat",
- "pause",
- "pipe",
- "pipe2",
- "poll",
- "ppoll",
- "prctl",
- "pread64",
- "preadv",
- "preadv2",
- "prlimit64",
- "pselect6",
- "pwrite64",
- "pwritev",
- "pwritev2",
- "read",
- "readahead",
- "readlink",
- "readlinkat",
- "readv",
- "recv",
- "recvfrom",
- "recvmmsg",
- "recvmsg",
- "remap_file_pages",
- "removexattr",
- "rename",
- "renameat",
- "renameat2",
- "restart_syscall",
- "rmdir",
- "rt_sigaction",
- "rt_sigpending",
- "rt_sigprocmask",
- "rt_sigqueueinfo",
- "rt_sigreturn",
- "rt_sigsuspend",
- "rt_sigtimedwait",
- "rt_tgsigqueueinfo",
- "sched_getaffinity",
- "sched_getattr",
- "sched_getparam",
- "sched_get_priority_max",
- "sched_get_priority_min",
- "sched_getscheduler",
- "sched_rr_get_interval",
- "sched_setaffinity",
- "sched_setattr",
- "sched_setparam",
- "sched_setscheduler",
- "sched_yield",
- "seccomp",
- "select",
- "semctl",
- "semget",
- "semop",
- "semtimedop",
- "send",
- "sendfile",
- "sendfile64",
- "sendmmsg",
- "sendmsg",
- "sendto",
- "setfsgid",
- "setfsgid32",
- "setfsuid",
- "setfsuid32",
- "setgid",
- "setgid32",
- "setgroups",
- "setgroups32",
- "setitimer",
- "setpgid",
- "setpriority",
- "setregid",
- "setregid32",
- "setresgid",
- "setresgid32",
- "setresuid",
- "setresuid32",
- "setreuid",
- "setreuid32",
- "setrlimit",
- "set_robust_list",
- "setsid",
- "setsockopt",
- "set_thread_area",
- "set_tid_address",
- "setuid",
- "setuid32",
- "setxattr",
- "shmat",
- "shmctl",
- "shmdt",
- "shmget",
- "shutdown",
- "sigaltstack",
- "signalfd",
- "signalfd4",
- "sigprocmask",
- "sigreturn",
- "socket",
- "socketcall",
- "socketpair",
- "splice",
- "stat",
- "stat64",
- "statfs",
- "statfs64",
- "statx",
- "symlink",
- "symlinkat",
- "sync",
- "sync_file_range",
- "syncfs",
- "sysinfo",
- "tee",
- "tgkill",
- "time",
- "timer_create",
- "timer_delete",
- "timerfd_create",
- "timerfd_gettime",
- "timerfd_settime",
- "timer_getoverrun",
- "timer_gettime",
- "timer_settime",
- "times",
- "tkill",
- "truncate",
- "truncate64",
- "ugetrlimit",
- "umask",
- "uname",
- "unlink",
- "unlinkat",
- "utime",
- "utimensat",
- "utimes",
- "vfork",
- "vmsplice",
- "wait4",
- "waitid",
- "waitpid",
- "write",
- "writev"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {},
- "excludes": {}
- },
- {
- "names": [
- "ptrace"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": null,
- "comment": "",
- "includes": {
- "minKernel": "4.8"
- },
- "excludes": {}
- },
- {
- "names": [
- "personality"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [
- {
- "index": 0,
- "value": 0,
- "valueTwo": 0,
- "op": "SCMP_CMP_EQ"
- }
- ],
- "comment": "",
- "includes": {},
- "excludes": {}
- },
- {
- "names": [
- "personality"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [
- {
- "index": 0,
- "value": 8,
- "valueTwo": 0,
- "op": "SCMP_CMP_EQ"
- }
- ],
- "comment": "",
- "includes": {},
- "excludes": {}
- },
- {
- "names": [
- "personality"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [
- {
- "index": 0,
- "value": 131072,
- "valueTwo": 0,
- "op": "SCMP_CMP_EQ"
- }
- ],
- "comment": "",
- "includes": {},
- "excludes": {}
- },
- {
- "names": [
- "personality"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [
- {
- "index": 0,
- "value": 131080,
- "valueTwo": 0,
- "op": "SCMP_CMP_EQ"
- }
- ],
- "comment": "",
- "includes": {},
- "excludes": {}
- },
- {
- "names": [
- "personality"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [
- {
- "index": 0,
- "value": 4294967295,
- "valueTwo": 0,
- "op": "SCMP_CMP_EQ"
- }
- ],
- "comment": "",
- "includes": {},
- "excludes": {}
- },
- {
- "names": [
- "sync_file_range2"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "arches": [
- "ppc64le"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "arm_fadvise64_64",
- "arm_sync_file_range",
- "sync_file_range2",
- "breakpoint",
- "cacheflush",
- "set_tls"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "arches": [
- "arm",
- "arm64"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "arch_prctl"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "arches": [
- "amd64",
- "x32"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "modify_ldt"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "arches": [
- "amd64",
- "x32",
- "x86"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "s390_pci_mmio_read",
- "s390_pci_mmio_write",
- "s390_runtime_instr"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "arches": [
- "s390",
- "s390x"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "open_by_handle_at"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_DAC_READ_SEARCH"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "bpf",
- "clone",
- "fanotify_init",
- "lookup_dcookie",
- "mount",
- "name_to_handle_at",
- "perf_event_open",
- "quotactl",
- "setdomainname",
- "sethostname",
- "setns",
- "syslog",
- "umount",
- "umount2",
- "unshare"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_SYS_ADMIN"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "clone"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [
- {
- "index": 0,
- "value": 2114060288,
- "valueTwo": 0,
- "op": "SCMP_CMP_MASKED_EQ"
- }
- ],
- "comment": "",
- "includes": {},
- "excludes": {
- "caps": [
- "CAP_SYS_ADMIN"
- ],
- "arches": [
- "s390",
- "s390x"
- ]
- }
- },
- {
- "names": [
- "clone"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [
- {
- "index": 1,
- "value": 2114060288,
- "valueTwo": 0,
- "op": "SCMP_CMP_MASKED_EQ"
- }
- ],
- "comment": "s390 parameter ordering for clone is different",
- "includes": {
- "arches": [
- "s390",
- "s390x"
- ]
- },
- "excludes": {
- "caps": [
- "CAP_SYS_ADMIN"
- ]
- }
- },
- {
- "names": [
- "reboot"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_SYS_BOOT"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "chroot"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_SYS_CHROOT"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "delete_module",
- "init_module",
- "finit_module",
- "query_module"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_SYS_MODULE"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "acct"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_SYS_PACCT"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "kcmp",
- "process_vm_readv",
- "process_vm_writev",
- "ptrace"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_SYS_PTRACE"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "iopl",
- "ioperm"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_SYS_RAWIO"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "settimeofday",
- "stime",
- "clock_settime"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_SYS_TIME"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "vhangup"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_SYS_TTY_CONFIG"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "get_mempolicy",
- "mbind",
- "set_mempolicy"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_SYS_NICE"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "syslog"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_SYSLOG"
- ]
- },
- "excludes": {}
- }
- ]
-} \ No newline at end of file
diff --git a/vendor/github.com/docker/docker/profiles/seccomp/generate.go b/vendor/github.com/docker/docker/profiles/seccomp/generate.go
deleted file mode 100644
index 32f22bb37..000000000
--- a/vendor/github.com/docker/docker/profiles/seccomp/generate.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// +build ignore
-
-package main
-
-import (
- "encoding/json"
- "io/ioutil"
- "os"
- "path/filepath"
-
- "github.com/docker/docker/profiles/seccomp"
-)
-
-// saves the default seccomp profile as a json file so people can use it as a
-// base for their own custom profiles
-func main() {
- wd, err := os.Getwd()
- if err != nil {
- panic(err)
- }
- f := filepath.Join(wd, "default.json")
-
- // write the default profile to the file
- b, err := json.MarshalIndent(seccomp.DefaultProfile(), "", "\t")
- if err != nil {
- panic(err)
- }
-
- if err := ioutil.WriteFile(f, b, 0644); err != nil {
- panic(err)
- }
-}
diff --git a/vendor/github.com/docker/docker/profiles/seccomp/seccomp.go b/vendor/github.com/docker/docker/profiles/seccomp/seccomp.go
deleted file mode 100644
index 12721a120..000000000
--- a/vendor/github.com/docker/docker/profiles/seccomp/seccomp.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// +build linux
-
-package seccomp // import "github.com/docker/docker/profiles/seccomp"
-
-import (
- "encoding/json"
- "errors"
- "fmt"
-
- "github.com/docker/docker/api/types"
- "github.com/docker/docker/pkg/parsers/kernel"
- specs "github.com/opencontainers/runtime-spec/specs-go"
- libseccomp "github.com/seccomp/libseccomp-golang"
-)
-
-//go:generate go run -tags 'seccomp' generate.go
-
-// GetDefaultProfile returns the default seccomp profile.
-func GetDefaultProfile(rs *specs.Spec) (*specs.LinuxSeccomp, error) {
- return setupSeccomp(DefaultProfile(), rs)
-}
-
-// LoadProfile takes a json string and decodes the seccomp profile.
-func LoadProfile(body string, rs *specs.Spec) (*specs.LinuxSeccomp, error) {
- var config types.Seccomp
- if err := json.Unmarshal([]byte(body), &config); err != nil {
- return nil, fmt.Errorf("Decoding seccomp profile failed: %v", err)
- }
- return setupSeccomp(&config, rs)
-}
-
-var nativeToSeccomp = map[string]types.Arch{
- "amd64": types.ArchX86_64,
- "arm64": types.ArchAARCH64,
- "mips64": types.ArchMIPS64,
- "mips64n32": types.ArchMIPS64N32,
- "mipsel64": types.ArchMIPSEL64,
- "mipsel64n32": types.ArchMIPSEL64N32,
- "s390x": types.ArchS390X,
-}
-
-// inSlice tests whether a string is contained in a slice of strings or not.
-// Comparison is case sensitive
-func inSlice(slice []string, s string) bool {
- for _, ss := range slice {
- if s == ss {
- return true
- }
- }
- return false
-}
-
-func setupSeccomp(config *types.Seccomp, rs *specs.Spec) (*specs.LinuxSeccomp, error) {
- if config == nil {
- return nil, nil
- }
-
- // No default action specified, no syscalls listed, assume seccomp disabled
- if config.DefaultAction == "" && len(config.Syscalls) == 0 {
- return nil, nil
- }
-
- newConfig := &specs.LinuxSeccomp{}
-
- var arch string
- var native, err = libseccomp.GetNativeArch()
- if err == nil {
- arch = native.String()
- }
-
- if len(config.Architectures) != 0 && len(config.ArchMap) != 0 {
- return nil, errors.New("'architectures' and 'archMap' were specified in the seccomp profile, use either 'architectures' or 'archMap'")
- }
-
- // if config.Architectures == 0 then libseccomp will figure out the architecture to use
- if len(config.Architectures) != 0 {
- for _, a := range config.Architectures {
- newConfig.Architectures = append(newConfig.Architectures, specs.Arch(a))
- }
- }
-
- if len(config.ArchMap) != 0 {
- for _, a := range config.ArchMap {
- seccompArch, ok := nativeToSeccomp[arch]
- if ok {
- if a.Arch == seccompArch {
- newConfig.Architectures = append(newConfig.Architectures, specs.Arch(a.Arch))
- for _, sa := range a.SubArches {
- newConfig.Architectures = append(newConfig.Architectures, specs.Arch(sa))
- }
- break
- }
- }
- }
- }
-
- newConfig.DefaultAction = specs.LinuxSeccompAction(config.DefaultAction)
-
-Loop:
- // Loop through all syscall blocks and convert them to libcontainer format after filtering them
- for _, call := range config.Syscalls {
- if len(call.Excludes.Arches) > 0 {
- if inSlice(call.Excludes.Arches, arch) {
- continue Loop
- }
- }
- if len(call.Excludes.Caps) > 0 {
- for _, c := range call.Excludes.Caps {
- if inSlice(rs.Process.Capabilities.Bounding, c) {
- continue Loop
- }
- }
- }
- if call.Excludes.MinKernel != "" {
- if ok, err := kernelGreaterEqualThan(call.Excludes.MinKernel); err != nil {
- return nil, err
- } else if ok {
- continue Loop
- }
- }
- if len(call.Includes.Arches) > 0 {
- if !inSlice(call.Includes.Arches, arch) {
- continue Loop
- }
- }
- if len(call.Includes.Caps) > 0 {
- for _, c := range call.Includes.Caps {
- if !inSlice(rs.Process.Capabilities.Bounding, c) {
- continue Loop
- }
- }
- }
- if call.Includes.MinKernel != "" {
- if ok, err := kernelGreaterEqualThan(call.Includes.MinKernel); err != nil {
- return nil, err
- } else if !ok {
- continue Loop
- }
- }
-
- if call.Name != "" && len(call.Names) != 0 {
- return nil, errors.New("'name' and 'names' were specified in the seccomp profile, use either 'name' or 'names'")
- }
-
- if call.Name != "" {
- newConfig.Syscalls = append(newConfig.Syscalls, createSpecsSyscall([]string{call.Name}, call.Action, call.Args))
- } else {
- newConfig.Syscalls = append(newConfig.Syscalls, createSpecsSyscall(call.Names, call.Action, call.Args))
- }
- }
-
- return newConfig, nil
-}
-
-func createSpecsSyscall(names []string, action types.Action, args []*types.Arg) specs.LinuxSyscall {
- newCall := specs.LinuxSyscall{
- Names: names,
- Action: specs.LinuxSeccompAction(action),
- }
-
- // Loop through all the arguments of the syscall and convert them
- for _, arg := range args {
- newArg := specs.LinuxSeccompArg{
- Index: arg.Index,
- Value: arg.Value,
- ValueTwo: arg.ValueTwo,
- Op: specs.LinuxSeccompOperator(arg.Op),
- }
-
- newCall.Args = append(newCall.Args, newArg)
- }
- return newCall
-}
-
-var currentKernelVersion *kernel.VersionInfo
-
-func kernelGreaterEqualThan(v string) (bool, error) {
- version, err := kernel.ParseRelease(v)
- if err != nil {
- return false, err
- }
- if currentKernelVersion == nil {
- currentKernelVersion, err = kernel.GetKernelVersion()
- if err != nil {
- return false, err
- }
- }
- return kernel.CompareKernelVersion(*version, *currentKernelVersion) <= 0, nil
-}
diff --git a/vendor/github.com/docker/docker/profiles/seccomp/seccomp_default.go b/vendor/github.com/docker/docker/profiles/seccomp/seccomp_default.go
deleted file mode 100644
index 16148b408..000000000
--- a/vendor/github.com/docker/docker/profiles/seccomp/seccomp_default.go
+++ /dev/null
@@ -1,674 +0,0 @@
-// +build linux,seccomp
-
-package seccomp // import "github.com/docker/docker/profiles/seccomp"
-
-import (
- "github.com/docker/docker/api/types"
- "golang.org/x/sys/unix"
-)
-
-func arches() []types.Architecture {
- return []types.Architecture{
- {
- Arch: types.ArchX86_64,
- SubArches: []types.Arch{types.ArchX86, types.ArchX32},
- },
- {
- Arch: types.ArchAARCH64,
- SubArches: []types.Arch{types.ArchARM},
- },
- {
- Arch: types.ArchMIPS64,
- SubArches: []types.Arch{types.ArchMIPS, types.ArchMIPS64N32},
- },
- {
- Arch: types.ArchMIPS64N32,
- SubArches: []types.Arch{types.ArchMIPS, types.ArchMIPS64},
- },
- {
- Arch: types.ArchMIPSEL64,
- SubArches: []types.Arch{types.ArchMIPSEL, types.ArchMIPSEL64N32},
- },
- {
- Arch: types.ArchMIPSEL64N32,
- SubArches: []types.Arch{types.ArchMIPSEL, types.ArchMIPSEL64},
- },
- {
- Arch: types.ArchS390X,
- SubArches: []types.Arch{types.ArchS390},
- },
- }
-}
-
-// DefaultProfile defines the whitelist for the default seccomp profile.
-func DefaultProfile() *types.Seccomp {
- syscalls := []*types.Syscall{
- {
- Names: []string{
- "accept",
- "accept4",
- "access",
- "adjtimex",
- "alarm",
- "bind",
- "brk",
- "capget",
- "capset",
- "chdir",
- "chmod",
- "chown",
- "chown32",
- "clock_getres",
- "clock_gettime",
- "clock_nanosleep",
- "close",
- "connect",
- "copy_file_range",
- "creat",
- "dup",
- "dup2",
- "dup3",
- "epoll_create",
- "epoll_create1",
- "epoll_ctl",
- "epoll_ctl_old",
- "epoll_pwait",
- "epoll_wait",
- "epoll_wait_old",
- "eventfd",
- "eventfd2",
- "execve",
- "execveat",
- "exit",
- "exit_group",
- "faccessat",
- "fadvise64",
- "fadvise64_64",
- "fallocate",
- "fanotify_mark",
- "fchdir",
- "fchmod",
- "fchmodat",
- "fchown",
- "fchown32",
- "fchownat",
- "fcntl",
- "fcntl64",
- "fdatasync",
- "fgetxattr",
- "flistxattr",
- "flock",
- "fork",
- "fremovexattr",
- "fsetxattr",
- "fstat",
- "fstat64",
- "fstatat64",
- "fstatfs",
- "fstatfs64",
- "fsync",
- "ftruncate",
- "ftruncate64",
- "futex",
- "futimesat",
- "getcpu",
- "getcwd",
- "getdents",
- "getdents64",
- "getegid",
- "getegid32",
- "geteuid",
- "geteuid32",
- "getgid",
- "getgid32",
- "getgroups",
- "getgroups32",
- "getitimer",
- "getpeername",
- "getpgid",
- "getpgrp",
- "getpid",
- "getppid",
- "getpriority",
- "getrandom",
- "getresgid",
- "getresgid32",
- "getresuid",
- "getresuid32",
- "getrlimit",
- "get_robust_list",
- "getrusage",
- "getsid",
- "getsockname",
- "getsockopt",
- "get_thread_area",
- "gettid",
- "gettimeofday",
- "getuid",
- "getuid32",
- "getxattr",
- "inotify_add_watch",
- "inotify_init",
- "inotify_init1",
- "inotify_rm_watch",
- "io_cancel",
- "ioctl",
- "io_destroy",
- "io_getevents",
- "io_pgetevents",
- "ioprio_get",
- "ioprio_set",
- "io_setup",
- "io_submit",
- "io_uring_enter",
- "io_uring_register",
- "io_uring_setup",
- "ipc",
- "kill",
- "lchown",
- "lchown32",
- "lgetxattr",
- "link",
- "linkat",
- "listen",
- "listxattr",
- "llistxattr",
- "_llseek",
- "lremovexattr",
- "lseek",
- "lsetxattr",
- "lstat",
- "lstat64",
- "madvise",
- "memfd_create",
- "mincore",
- "mkdir",
- "mkdirat",
- "mknod",
- "mknodat",
- "mlock",
- "mlock2",
- "mlockall",
- "mmap",
- "mmap2",
- "mprotect",
- "mq_getsetattr",
- "mq_notify",
- "mq_open",
- "mq_timedreceive",
- "mq_timedsend",
- "mq_unlink",
- "mremap",
- "msgctl",
- "msgget",
- "msgrcv",
- "msgsnd",
- "msync",
- "munlock",
- "munlockall",
- "munmap",
- "nanosleep",
- "newfstatat",
- "_newselect",
- "open",
- "openat",
- "pause",
- "pipe",
- "pipe2",
- "poll",
- "ppoll",
- "prctl",
- "pread64",
- "preadv",
- "preadv2",
- "prlimit64",
- "pselect6",
- "pwrite64",
- "pwritev",
- "pwritev2",
- "read",
- "readahead",
- "readlink",
- "readlinkat",
- "readv",
- "recv",
- "recvfrom",
- "recvmmsg",
- "recvmsg",
- "remap_file_pages",
- "removexattr",
- "rename",
- "renameat",
- "renameat2",
- "restart_syscall",
- "rmdir",
- "rt_sigaction",
- "rt_sigpending",
- "rt_sigprocmask",
- "rt_sigqueueinfo",
- "rt_sigreturn",
- "rt_sigsuspend",
- "rt_sigtimedwait",
- "rt_tgsigqueueinfo",
- "sched_getaffinity",
- "sched_getattr",
- "sched_getparam",
- "sched_get_priority_max",
- "sched_get_priority_min",
- "sched_getscheduler",
- "sched_rr_get_interval",
- "sched_setaffinity",
- "sched_setattr",
- "sched_setparam",
- "sched_setscheduler",
- "sched_yield",
- "seccomp",
- "select",
- "semctl",
- "semget",
- "semop",
- "semtimedop",
- "send",
- "sendfile",
- "sendfile64",
- "sendmmsg",
- "sendmsg",
- "sendto",
- "setfsgid",
- "setfsgid32",
- "setfsuid",
- "setfsuid32",
- "setgid",
- "setgid32",
- "setgroups",
- "setgroups32",
- "setitimer",
- "setpgid",
- "setpriority",
- "setregid",
- "setregid32",
- "setresgid",
- "setresgid32",
- "setresuid",
- "setresuid32",
- "setreuid",
- "setreuid32",
- "setrlimit",
- "set_robust_list",
- "setsid",
- "setsockopt",
- "set_thread_area",
- "set_tid_address",
- "setuid",
- "setuid32",
- "setxattr",
- "shmat",
- "shmctl",
- "shmdt",
- "shmget",
- "shutdown",
- "sigaltstack",
- "signalfd",
- "signalfd4",
- "sigprocmask",
- "sigreturn",
- "socket",
- "socketcall",
- "socketpair",
- "splice",
- "stat",
- "stat64",
- "statfs",
- "statfs64",
- "statx",
- "symlink",
- "symlinkat",
- "sync",
- "sync_file_range",
- "syncfs",
- "sysinfo",
- "tee",
- "tgkill",
- "time",
- "timer_create",
- "timer_delete",
- "timerfd_create",
- "timerfd_gettime",
- "timerfd_settime",
- "timer_getoverrun",
- "timer_gettime",
- "timer_settime",
- "times",
- "tkill",
- "truncate",
- "truncate64",
- "ugetrlimit",
- "umask",
- "uname",
- "unlink",
- "unlinkat",
- "utime",
- "utimensat",
- "utimes",
- "vfork",
- "vmsplice",
- "wait4",
- "waitid",
- "waitpid",
- "write",
- "writev",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- },
- {
- Names: []string{"ptrace"},
- Action: types.ActAllow,
- Includes: types.Filter{
- MinKernel: "4.8",
- },
- },
- {
- Names: []string{"personality"},
- Action: types.ActAllow,
- Args: []*types.Arg{
- {
- Index: 0,
- Value: 0x0,
- Op: types.OpEqualTo,
- },
- },
- },
- {
- Names: []string{"personality"},
- Action: types.ActAllow,
- Args: []*types.Arg{
- {
- Index: 0,
- Value: 0x0008,
- Op: types.OpEqualTo,
- },
- },
- },
- {
- Names: []string{"personality"},
- Action: types.ActAllow,
- Args: []*types.Arg{
- {
- Index: 0,
- Value: 0x20000,
- Op: types.OpEqualTo,
- },
- },
- },
- {
- Names: []string{"personality"},
- Action: types.ActAllow,
- Args: []*types.Arg{
- {
- Index: 0,
- Value: 0x20008,
- Op: types.OpEqualTo,
- },
- },
- },
- {
- Names: []string{"personality"},
- Action: types.ActAllow,
- Args: []*types.Arg{
- {
- Index: 0,
- Value: 0xffffffff,
- Op: types.OpEqualTo,
- },
- },
- },
- {
- Names: []string{
- "sync_file_range2",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Arches: []string{"ppc64le"},
- },
- },
- {
- Names: []string{
- "arm_fadvise64_64",
- "arm_sync_file_range",
- "sync_file_range2",
- "breakpoint",
- "cacheflush",
- "set_tls",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Arches: []string{"arm", "arm64"},
- },
- },
- {
- Names: []string{
- "arch_prctl",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Arches: []string{"amd64", "x32"},
- },
- },
- {
- Names: []string{
- "modify_ldt",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Arches: []string{"amd64", "x32", "x86"},
- },
- },
- {
- Names: []string{
- "s390_pci_mmio_read",
- "s390_pci_mmio_write",
- "s390_runtime_instr",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Arches: []string{"s390", "s390x"},
- },
- },
- {
- Names: []string{
- "open_by_handle_at",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Caps: []string{"CAP_DAC_READ_SEARCH"},
- },
- },
- {
- Names: []string{
- "bpf",
- "clone",
- "fanotify_init",
- "lookup_dcookie",
- "mount",
- "name_to_handle_at",
- "perf_event_open",
- "quotactl",
- "setdomainname",
- "sethostname",
- "setns",
- "syslog",
- "umount",
- "umount2",
- "unshare",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Caps: []string{"CAP_SYS_ADMIN"},
- },
- },
- {
- Names: []string{
- "clone",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{
- {
- Index: 0,
- Value: unix.CLONE_NEWNS | unix.CLONE_NEWUTS | unix.CLONE_NEWIPC | unix.CLONE_NEWUSER | unix.CLONE_NEWPID | unix.CLONE_NEWNET | unix.CLONE_NEWCGROUP,
- ValueTwo: 0,
- Op: types.OpMaskedEqual,
- },
- },
- Excludes: types.Filter{
- Caps: []string{"CAP_SYS_ADMIN"},
- Arches: []string{"s390", "s390x"},
- },
- },
- {
- Names: []string{
- "clone",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{
- {
- Index: 1,
- Value: unix.CLONE_NEWNS | unix.CLONE_NEWUTS | unix.CLONE_NEWIPC | unix.CLONE_NEWUSER | unix.CLONE_NEWPID | unix.CLONE_NEWNET | unix.CLONE_NEWCGROUP,
- ValueTwo: 0,
- Op: types.OpMaskedEqual,
- },
- },
- Comment: "s390 parameter ordering for clone is different",
- Includes: types.Filter{
- Arches: []string{"s390", "s390x"},
- },
- Excludes: types.Filter{
- Caps: []string{"CAP_SYS_ADMIN"},
- },
- },
- {
- Names: []string{
- "reboot",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Caps: []string{"CAP_SYS_BOOT"},
- },
- },
- {
- Names: []string{
- "chroot",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Caps: []string{"CAP_SYS_CHROOT"},
- },
- },
- {
- Names: []string{
- "delete_module",
- "init_module",
- "finit_module",
- "query_module",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Caps: []string{"CAP_SYS_MODULE"},
- },
- },
- {
- Names: []string{
- "acct",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Caps: []string{"CAP_SYS_PACCT"},
- },
- },
- {
- Names: []string{
- "kcmp",
- "process_vm_readv",
- "process_vm_writev",
- "ptrace",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Caps: []string{"CAP_SYS_PTRACE"},
- },
- },
- {
- Names: []string{
- "iopl",
- "ioperm",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Caps: []string{"CAP_SYS_RAWIO"},
- },
- },
- {
- Names: []string{
- "settimeofday",
- "stime",
- "clock_settime",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Caps: []string{"CAP_SYS_TIME"},
- },
- },
- {
- Names: []string{
- "vhangup",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Caps: []string{"CAP_SYS_TTY_CONFIG"},
- },
- },
- {
- Names: []string{
- "get_mempolicy",
- "mbind",
- "set_mempolicy",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Caps: []string{"CAP_SYS_NICE"},
- },
- },
- {
- Names: []string{
- "syslog",
- },
- Action: types.ActAllow,
- Args: []*types.Arg{},
- Includes: types.Filter{
- Caps: []string{"CAP_SYSLOG"},
- },
- },
- }
-
- return &types.Seccomp{
- DefaultAction: types.ActErrno,
- ArchMap: arches(),
- Syscalls: syscalls,
- }
-}
diff --git a/vendor/github.com/docker/docker/profiles/seccomp/seccomp_unsupported.go b/vendor/github.com/docker/docker/profiles/seccomp/seccomp_unsupported.go
deleted file mode 100644
index 67e06401f..000000000
--- a/vendor/github.com/docker/docker/profiles/seccomp/seccomp_unsupported.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// +build linux,!seccomp
-
-package seccomp // import "github.com/docker/docker/profiles/seccomp"
-
-import (
- "github.com/docker/docker/api/types"
-)
-
-// DefaultProfile returns a nil pointer on unsupported systems.
-func DefaultProfile() *types.Seccomp {
- return nil
-}
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/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md
index f67074016..ecbdd2734 100644
--- a/vendor/github.com/onsi/gomega/CHANGELOG.md
+++ b/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.7.1
+
+### Fixes
+- Bump go-yaml version to cover fixed ddos heuristic (#362) [95e431e]
+
## 1.7.0
### Features
diff --git a/vendor/github.com/onsi/gomega/go.mod b/vendor/github.com/onsi/gomega/go.mod
index 65eedf696..177a541c4 100644
--- a/vendor/github.com/onsi/gomega/go.mod
+++ b/vendor/github.com/onsi/gomega/go.mod
@@ -11,5 +11,6 @@ require (
golang.org/x/text v0.3.0 // indirect
gopkg.in/fsnotify.v1 v1.4.7 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
- gopkg.in/yaml.v2 v2.2.1
+ gopkg.in/yaml.v2 v2.2.4
)
+
diff --git a/vendor/github.com/onsi/gomega/go.sum b/vendor/github.com/onsi/gomega/go.sum
index b23f6ef02..bbcc05d3e 100644
--- a/vendor/github.com/onsi/gomega/go.sum
+++ b/vendor/github.com/onsi/gomega/go.sum
@@ -20,5 +20,5 @@ gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
-gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
-gopkg.in/yaml.v2 v2.2.1/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=
diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go
index b145768cf..85505f2ec 100644
--- a/vendor/github.com/onsi/gomega/gomega_dsl.go
+++ b/vendor/github.com/onsi/gomega/gomega_dsl.go
@@ -24,7 +24,7 @@ import (
"github.com/onsi/gomega/types"
)
-const GOMEGA_VERSION = "1.7.0"
+const GOMEGA_VERSION = "1.7.1"
const nilFailHandlerPanic = `You are trying to make an assertion, but Gomega's fail handler is nil.
If you're using Ginkgo then you probably forgot to put your assertion in an It().
diff --git a/vendor/github.com/uber/jaeger-client-go/.travis.yml b/vendor/github.com/uber/jaeger-client-go/.travis.yml
index 0d7bdd9ab..e81cc8805 100644
--- a/vendor/github.com/uber/jaeger-client-go/.travis.yml
+++ b/vendor/github.com/uber/jaeger-client-go/.travis.yml
@@ -7,21 +7,22 @@ dist: trusty
matrix:
include:
- - go: 1.12.x
+ - go: 1.13.x
env:
- TESTS=true
- USE_DEP=true
- COVERAGE=true
- - go: 1.12.x
+ - go: 1.13.x
env:
- USE_DEP=true
- CROSSDOCK=true
- - go: 1.12.x
+ - go: 1.13.x
env:
- TESTS=true
- USE_DEP=false
- USE_GLIDE=true
- - go: 1.11.x
+ # test with previous version of Go
+ - go: 1.12.x
env:
- TESTS=true
- USE_DEP=true
diff --git a/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md b/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md
index 31b22e40c..c4590bf93 100644
--- a/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md
+++ b/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md
@@ -1,6 +1,45 @@
Changes by Version
==================
+2.20.0 (2019-11-06)
+-------------------
+
+## New Features
+
+- Allow all in-process spans of a trace to share sampling state (#443) -- Prithvi Raj
+
+ Sampling state is shared between all spans of the trace that are still in memory.
+ This allows implementation of delayed sampling decisions (see below).
+
+- Support delayed sampling decisions (#449) -- Yuri Shkuro
+
+ This is a large structural change to how the samplers work.
+ It allows some samplers to be executed multiple times on different
+ span events (like setting a tag) and make a positive sampling decision
+ later in the span life cycle, or even based on children spans.
+ See [README](./README.md#delayed-sampling) for more details.
+
+ There is a related minor change in behavior of the adaptive (per-operation) sampler,
+ which will no longer re-sample the trace when `span.SetOperation()` is called, i.e. the
+ operation used to make the sampling decision is always the one provided at span creation.
+
+- Add experimental tag matching sampler (#452) -- Yuri Shkuro
+
+ A sampler that can sample a trace based on a certain tag added to the root
+ span or one of its local (in-process) children. The sampler can be used with
+ another experimental `PrioritySampler` that allows multiple samplers to try
+ to make a sampling decision, in a certain priority order.
+
+- [log/zap] Report whether a trace was sampled (#445) -- Abhinav Gupta
+- Allow config.FromEnv() to enrich an existing config object (#436) -- Vineeth Reddy
+
+## Minor patches
+
+- Expose Sampler on Tracer and accept sampler options via Configuration (#460) -- Yuri Shkuro
+- Fix github.com/uber-go/atomic import (#464) -- Yuri Shkuro
+- Add nodejs to crossdock tests (#441) -- Bhavin Gandhi
+- Bump Go compiler version to 1.13 (#453) -- Yuri Shkuro
+
2.19.0 (2019-09-23)
-------------------
diff --git a/vendor/github.com/uber/jaeger-client-go/Gopkg.lock b/vendor/github.com/uber/jaeger-client-go/Gopkg.lock
index 1ed86f4a7..5a42ebf16 100644
--- a/vendor/github.com/uber/jaeger-client-go/Gopkg.lock
+++ b/vendor/github.com/uber/jaeger-client-go/Gopkg.lock
@@ -2,6 +2,14 @@
[[projects]]
+ digest = "1:9f3b30d9f8e0d7040f729b82dcbc8f0dead820a133b3147ce355fc451f32d761"
+ name = "github.com/BurntSushi/toml"
+ packages = ["."]
+ pruneopts = "UT"
+ revision = "3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005"
+ version = "v0.3.1"
+
+[[projects]]
digest = "1:d6afaeed1502aa28e80a4ed0981d570ad91b2579193404256ce672ed0a609e0d"
name = "github.com/beorn7/perks"
packages = ["quantile"]
@@ -138,14 +146,6 @@
version = "v1.4.0"
[[projects]]
- digest = "1:a5158647b553c61877aa9ae74f4015000294e47981e6b8b07525edcbb0747c81"
- name = "github.com/uber-go/atomic"
- packages = ["."]
- pruneopts = "UT"
- revision = "df976f2515e274675050de7b3f42545de80594fd"
- version = "v1.4.0"
-
-[[projects]]
digest = "1:0ec60ffd594af00ba1660bc746aa0e443d27dd4003dee55f9d08a0b4ff5431a3"
name = "github.com/uber/jaeger-lib"
packages = [
@@ -158,23 +158,31 @@
version = "v2.2.0"
[[projects]]
- digest = "1:a5158647b553c61877aa9ae74f4015000294e47981e6b8b07525edcbb0747c81"
+ digest = "1:0bdcb0c740d79d400bd3f7946ac22a715c94db62b20bfd2e01cd50693aba0600"
name = "go.uber.org/atomic"
packages = ["."]
pruneopts = "UT"
- revision = "df976f2515e274675050de7b3f42545de80594fd"
- version = "v1.4.0"
+ revision = "9dc4df04d0d1c39369750a9f6c32c39560672089"
+ version = "v1.5.0"
[[projects]]
- digest = "1:60bf2a5e347af463c42ed31a493d817f8a72f102543060ed992754e689805d1a"
+ digest = "1:002ebc50f3ef475ac325e1904be931d9dcba6dc6d73b5682afce0c63436e3902"
name = "go.uber.org/multierr"
packages = ["."]
pruneopts = "UT"
- revision = "3c4937480c32f4c13a875a1829af76c98ca3d40a"
- version = "v1.1.0"
+ revision = "c3fc3d02ec864719d8e25be2d7dde1e35a36aa27"
+ version = "v1.3.0"
+
+[[projects]]
+ branch = "master"
+ digest = "1:3032e90a153750ea149f68bf081f97ca738f041fba45c41c80737f572ffdf2f4"
+ name = "go.uber.org/tools"
+ packages = ["update-license"]
+ pruneopts = "UT"
+ revision = "2cfd321de3ee5d5f8a5fda2521d1703478334d98"
[[projects]]
- digest = "1:676160e6a4722b08e0e26b11521d575c2cb2b6f0c679e1ee6178c5d8dee51e5e"
+ digest = "1:6be13632ab4bd5842a097abb3aabac045a8601e19a10da4239e7d8bd83d4b83c"
name = "go.uber.org/zap"
packages = [
".",
@@ -185,8 +193,19 @@
"zapcore",
]
pruneopts = "UT"
- revision = "27376062155ad36be76b0f12cf1572a221d3a48c"
- version = "v1.10.0"
+ revision = "a6015e13fab9b744d96085308ce4e8f11bad1996"
+ version = "v1.12.0"
+
+[[projects]]
+ branch = "master"
+ digest = "1:21d7bad9b7da270fd2d50aba8971a041bd691165c95096a2a4c68db823cbc86a"
+ name = "golang.org/x/lint"
+ packages = [
+ ".",
+ "golint",
+ ]
+ pruneopts = "UT"
+ revision = "16217165b5de779cb6a5e4fc81fa9c1166fda457"
[[projects]]
branch = "master"
@@ -197,23 +216,81 @@
"context/ctxhttp",
]
pruneopts = "UT"
- revision = "aa69164e4478b84860dc6769c710c699c67058a3"
+ revision = "0deb6923b6d97481cb43bc1043fe5b72a0143032"
[[projects]]
branch = "master"
- digest = "1:712252802d318c8107d8f2136b99aa10feb17eca715245ed915199fbfc260155"
+ digest = "1:5dfb17d45415b7b8927382f53955a66f55f9d9d11557aa82f7f481d642ab247a"
name = "golang.org/x/sys"
packages = ["windows"]
pruneopts = "UT"
- revision = "0a153f010e6963173baba2306531d173aa843137"
+ revision = "f43be2a4598cf3a47be9f94f0c28197ed9eae611"
+
+[[projects]]
+ branch = "master"
+ digest = "1:bae8b3bf837d9d7f601776f37f44e031d46943677beff8fb2eb9c7317d44de2f"
+ name = "golang.org/x/tools"
+ packages = [
+ "go/analysis",
+ "go/analysis/passes/inspect",
+ "go/ast/astutil",
+ "go/ast/inspector",
+ "go/buildutil",
+ "go/gcexportdata",
+ "go/internal/gcimporter",
+ "go/internal/packagesdriver",
+ "go/packages",
+ "go/types/objectpath",
+ "go/types/typeutil",
+ "internal/fastwalk",
+ "internal/gopathwalk",
+ "internal/semver",
+ "internal/span",
+ ]
+ pruneopts = "UT"
+ revision = "8dbcdeb83d3faec5315146800b375c4962a42fc6"
[[projects]]
- digest = "1:4d2e5a73dc1500038e504a8d78b986630e3626dc027bc030ba5c75da257cdb96"
+ digest = "1:59f10c1537d2199d9115d946927fe31165959a95190849c82ff11e05803528b0"
name = "gopkg.in/yaml.v2"
packages = ["."]
pruneopts = "UT"
- revision = "51d6538a90f86fe93ac480b35f37b2be17fef232"
- version = "v2.2.2"
+ revision = "f221b8435cfb71e54062f6c6e99e9ade30b124d5"
+ version = "v2.2.4"
+
+[[projects]]
+ digest = "1:131158a88aad1f94854d0aa21a64af2802d0a470fb0f01cb33c04fafd2047111"
+ name = "honnef.co/go/tools"
+ packages = [
+ "arg",
+ "cmd/staticcheck",
+ "config",
+ "deprecated",
+ "facts",
+ "functions",
+ "go/types/typeutil",
+ "internal/cache",
+ "internal/passes/buildssa",
+ "internal/renameio",
+ "internal/sharedcheck",
+ "lint",
+ "lint/lintdsl",
+ "lint/lintutil",
+ "lint/lintutil/format",
+ "loader",
+ "printf",
+ "simple",
+ "ssa",
+ "ssautil",
+ "staticcheck",
+ "staticcheck/vrp",
+ "stylecheck",
+ "unused",
+ "version",
+ ]
+ pruneopts = "UT"
+ revision = "afd67930eec2a9ed3e9b19f684d17a062285f16a"
+ version = "2019.2.3"
[solve-meta]
analyzer-name = "dep"
@@ -229,10 +306,10 @@
"github.com/stretchr/testify/assert",
"github.com/stretchr/testify/require",
"github.com/stretchr/testify/suite",
- "github.com/uber-go/atomic",
"github.com/uber/jaeger-lib/metrics",
"github.com/uber/jaeger-lib/metrics/metricstest",
"github.com/uber/jaeger-lib/metrics/prometheus",
+ "go.uber.org/atomic",
"go.uber.org/zap",
"go.uber.org/zap/zapcore",
]
diff --git a/vendor/github.com/uber/jaeger-client-go/Gopkg.toml b/vendor/github.com/uber/jaeger-client-go/Gopkg.toml
index 3e6ac35ae..1fed7f814 100644
--- a/vendor/github.com/uber/jaeger-client-go/Gopkg.toml
+++ b/vendor/github.com/uber/jaeger-client-go/Gopkg.toml
@@ -15,7 +15,7 @@
version = "^1.1.3"
[[constraint]]
- name = "github.com/uber-go/atomic"
+ name = "go.uber.org/atomic"
version = "^1"
[[constraint]]
diff --git a/vendor/github.com/uber/jaeger-client-go/Makefile b/vendor/github.com/uber/jaeger-client-go/Makefile
index 74e11787a..0cfe6a5f6 100644
--- a/vendor/github.com/uber/jaeger-client-go/Makefile
+++ b/vendor/github.com/uber/jaeger-client-go/Makefile
@@ -1,5 +1,5 @@
PROJECT_ROOT=github.com/uber/jaeger-client-go
-PACKAGES := $(shell go list ./... | awk -F/ 'NR>1 {print "./"$$4"/..."}' | grep -v -e ./thrift-gen/... -e ./thrift/... | sort -u)
+PACKAGES := . $(shell go list ./... | awk -F/ 'NR>1 {print "./"$$4"/..."}' | grep -v -e ./thrift-gen/... -e ./thrift/... | sort -u)
# all .go files that don't exist in hidden directories
ALL_SRC := $(shell find . -name "*.go" | grep -v -e vendor -e thrift-gen -e ./thrift/ \
-e ".*/\..*" \
@@ -125,3 +125,4 @@ ifeq ($(CI_SKIP_LINT),true)
else
make lint
endif
+
diff --git a/vendor/github.com/uber/jaeger-client-go/README.md b/vendor/github.com/uber/jaeger-client-go/README.md
index 604d4b571..a3366114d 100644
--- a/vendor/github.com/uber/jaeger-client-go/README.md
+++ b/vendor/github.com/uber/jaeger-client-go/README.md
@@ -182,6 +182,29 @@ are available:
1. `RateLimitingSampler` can be used to allow only a certain fixed
number of traces to be sampled per second.
+#### Delayed sampling
+
+Version 2.20 introduced the ability to delay sampling decisions in the life cycle
+of the root span. It involves several features and architectural changes:
+ * **Shared sampling state**: the sampling state is shared across all local
+ (i.e. in-process) spans for a given trace.
+ * **New `SamplerV2` API** allows the sampler to be called at multiple points
+ in the life cycle of a span:
+ * on span creation
+ * on overwriting span operation name
+ * on setting span tags
+ * on finishing the span
+ * **Final/non-final sampling state**: the new `SamplerV2` API allows the sampler
+ to indicate if the negative sampling decision is final or not (positive sampling
+ decisions are always final). If the decision is not final, the sampler will be
+ called again on further span life cycle events, like setting tags.
+
+These new features are used in the experimental `x.TagMatchingSampler`, which
+can sample a trace based on a certain tag added to the root
+span or one of its local (in-process) children. The sampler can be used with
+another experimental `x.PrioritySampler` that allows multiple samplers to try
+to make a sampling decision, in a certain priority order.
+
### Baggage Injection
The OpenTracing spec allows for [baggage][baggage], which are key value pairs that are added
diff --git a/vendor/github.com/uber/jaeger-client-go/config/config.go b/vendor/github.com/uber/jaeger-client-go/config/config.go
index 6bce1b3b0..965f7c3ee 100644
--- a/vendor/github.com/uber/jaeger-client-go/config/config.go
+++ b/vendor/github.com/uber/jaeger-client-go/config/config.go
@@ -86,6 +86,9 @@ type SamplerConfig struct {
// jaeger-agent for the appropriate sampling strategy.
// Can be set by exporting an environment variable named JAEGER_SAMPLER_REFRESH_INTERVAL
SamplingRefreshInterval time.Duration `yaml:"samplingRefreshInterval"`
+
+ // Options can be used to programmatically pass additional options to the Remote sampler.
+ Options []jaeger.SamplerOption
}
// ReporterConfig configures the reporter. All fields are optional.
@@ -357,6 +360,7 @@ func (sc *SamplerConfig) NewSampler(
if sc.SamplingRefreshInterval != 0 {
options = append(options, jaeger.SamplerOptions.SamplingRefreshInterval(sc.SamplingRefreshInterval))
}
+ options = append(options, sc.Options...)
return jaeger.NewRemotelyControlledSampler(serviceName, options...), nil
}
return nil, fmt.Errorf("Unknown sampler type %v", sc.Type)
diff --git a/vendor/github.com/uber/jaeger-client-go/config/config_env.go b/vendor/github.com/uber/jaeger-client-go/config/config_env.go
index 14d69b11d..a729bd8fe 100644
--- a/vendor/github.com/uber/jaeger-client-go/config/config_env.go
+++ b/vendor/github.com/uber/jaeger-client-go/config/config_env.go
@@ -52,7 +52,11 @@ const (
// FromEnv uses environment variables to set the tracer's Configuration
func FromEnv() (*Configuration, error) {
c := &Configuration{}
+ return c.FromEnv()
+}
+// FromEnv uses environment variables and overrides existing tracer's Configuration
+func (c *Configuration) FromEnv() (*Configuration, error) {
if e := os.Getenv(envServiceName); e != "" {
c.ServiceName = e
}
@@ -77,13 +81,21 @@ func FromEnv() (*Configuration, error) {
c.Tags = parseTags(e)
}
- if s, err := samplerConfigFromEnv(); err == nil {
+ if c.Sampler == nil {
+ c.Sampler = &SamplerConfig{}
+ }
+
+ if s, err := c.Sampler.samplerConfigFromEnv(); err == nil {
c.Sampler = s
} else {
return nil, errors.Wrap(err, "cannot obtain sampler config from env")
}
- if r, err := reporterConfigFromEnv(); err == nil {
+ if c.Reporter == nil {
+ c.Reporter = &ReporterConfig{}
+ }
+
+ if r, err := c.Reporter.reporterConfigFromEnv(); err == nil {
c.Reporter = r
} else {
return nil, errors.Wrap(err, "cannot obtain reporter config from env")
@@ -93,9 +105,7 @@ func FromEnv() (*Configuration, error) {
}
// samplerConfigFromEnv creates a new SamplerConfig based on the environment variables
-func samplerConfigFromEnv() (*SamplerConfig, error) {
- sc := &SamplerConfig{}
-
+func (sc *SamplerConfig) samplerConfigFromEnv() (*SamplerConfig, error) {
if e := os.Getenv(envSamplerType); e != "" {
sc.Type = e
}
@@ -135,9 +145,7 @@ func samplerConfigFromEnv() (*SamplerConfig, error) {
}
// reporterConfigFromEnv creates a new ReporterConfig based on the environment variables
-func reporterConfigFromEnv() (*ReporterConfig, error) {
- rc := &ReporterConfig{}
-
+func (rc *ReporterConfig) reporterConfigFromEnv() (*ReporterConfig, error) {
if e := os.Getenv(envReporterMaxQueueSize); e != "" {
if value, err := strconv.ParseInt(e, 10, 0); err == nil {
rc.QueueSize = int(value)
diff --git a/vendor/github.com/uber/jaeger-client-go/constants.go b/vendor/github.com/uber/jaeger-client-go/constants.go
index e95b2ba09..0da47b02f 100644
--- a/vendor/github.com/uber/jaeger-client-go/constants.go
+++ b/vendor/github.com/uber/jaeger-client-go/constants.go
@@ -22,7 +22,7 @@ import (
const (
// JaegerClientVersion is the version of the client library reported as Span tag.
- JaegerClientVersion = "Go-2.19.0"
+ JaegerClientVersion = "Go-2.20.0"
// JaegerClientVersionTagKey is the name of the tag used to report client version.
JaegerClientVersionTagKey = "jaeger.version"
diff --git a/vendor/github.com/uber/jaeger-client-go/jaeger_thrift_span.go b/vendor/github.com/uber/jaeger-client-go/jaeger_thrift_span.go
index 6ce1caf87..f0f1afe2f 100644
--- a/vendor/github.com/uber/jaeger-client-go/jaeger_thrift_span.go
+++ b/vendor/github.com/uber/jaeger-client-go/jaeger_thrift_span.go
@@ -35,7 +35,7 @@ func BuildJaegerThrift(span *Span) *j.Span {
SpanId: int64(span.context.spanID),
ParentSpanId: int64(span.context.parentID),
OperationName: span.operationName,
- Flags: int32(span.context.flags),
+ Flags: int32(span.context.samplingState.flags()),
StartTime: startTime,
Duration: duration,
Tags: buildTags(span.tags, span.tracer.options.maxTagValueLength),
diff --git a/vendor/github.com/uber/jaeger-client-go/metrics.go b/vendor/github.com/uber/jaeger-client-go/metrics.go
index e56db9b73..50e4e22d6 100644
--- a/vendor/github.com/uber/jaeger-client-go/metrics.go
+++ b/vendor/github.com/uber/jaeger-client-go/metrics.go
@@ -26,6 +26,9 @@ type Metrics struct {
// Number of traces started by this tracer as not sampled
TracesStartedNotSampled metrics.Counter `metric:"traces" tags:"state=started,sampled=n" help:"Number of traces started by this tracer as not sampled"`
+ // Number of traces started by this tracer with delayed sampling
+ TracesStartedDelayedSampling metrics.Counter `metric:"traces" tags:"state=started,sampled=n" help:"Number of traces started by this tracer with delayed sampling"`
+
// Number of externally started sampled traces this tracer joined
TracesJoinedSampled metrics.Counter `metric:"traces" tags:"state=joined,sampled=y" help:"Number of externally started sampled traces this tracer joined"`
@@ -33,13 +36,22 @@ type Metrics struct {
TracesJoinedNotSampled metrics.Counter `metric:"traces" tags:"state=joined,sampled=n" help:"Number of externally started not-sampled traces this tracer joined"`
// Number of sampled spans started by this tracer
- SpansStartedSampled metrics.Counter `metric:"started_spans" tags:"sampled=y" help:"Number of sampled spans started by this tracer"`
+ SpansStartedSampled metrics.Counter `metric:"started_spans" tags:"sampled=y" help:"Number of spans started by this tracer as sampled"`
+
+ // Number of not sampled spans started by this tracer
+ SpansStartedNotSampled metrics.Counter `metric:"started_spans" tags:"sampled=n" help:"Number of spans started by this tracer as not sampled"`
+
+ // Number of spans with delayed sampling started by this tracer
+ SpansStartedDelayedSampling metrics.Counter `metric:"started_spans" tags:"sampled=delayed" help:"Number of spans started by this tracer with delayed sampling"`
- // Number of unsampled spans started by this tracer
- SpansStartedNotSampled metrics.Counter `metric:"started_spans" tags:"sampled=n" help:"Number of unsampled spans started by this tracer"`
+ // Number of spans finished by this tracer
+ SpansFinishedSampled metrics.Counter `metric:"finished_spans" tags:"sampled=y" help:"Number of sampled spans finished by this tracer"`
+
+ // Number of spans finished by this tracer
+ SpansFinishedNotSampled metrics.Counter `metric:"finished_spans" tags:"sampled=n" help:"Number of not-sampled spans finished by this tracer"`
// Number of spans finished by this tracer
- SpansFinished metrics.Counter `metric:"finished_spans" help:"Number of spans finished by this tracer"`
+ SpansFinishedDelayedSampling metrics.Counter `metric:"finished_spans" tags:"sampled=delayed" help:"Number of spans with delayed sampling finished by this tracer"`
// Number of errors decoding tracing context
DecodingErrors metrics.Counter `metric:"span_context_decoding_errors" help:"Number of errors decoding tracing context"`
diff --git a/vendor/github.com/uber/jaeger-client-go/propagation.go b/vendor/github.com/uber/jaeger-client-go/propagation.go
index 5b50cfb71..42fd64b58 100644
--- a/vendor/github.com/uber/jaeger-client-go/propagation.go
+++ b/vendor/github.com/uber/jaeger-client-go/propagation.go
@@ -193,7 +193,7 @@ func (p *BinaryPropagator) Inject(
if err := binary.Write(carrier, binary.BigEndian, sc.parentID); err != nil {
return err
}
- if err := binary.Write(carrier, binary.BigEndian, sc.flags); err != nil {
+ if err := binary.Write(carrier, binary.BigEndian, sc.samplingState.flags()); err != nil {
return err
}
@@ -222,6 +222,7 @@ func (p *BinaryPropagator) Extract(abstractCarrier interface{}) (SpanContext, er
return emptyContext, opentracing.ErrInvalidCarrier
}
var ctx SpanContext
+ ctx.samplingState = &samplingState{}
if err := binary.Read(carrier, binary.BigEndian, &ctx.traceID); err != nil {
return emptyContext, opentracing.ErrSpanContextCorrupted
@@ -232,9 +233,12 @@ func (p *BinaryPropagator) Extract(abstractCarrier interface{}) (SpanContext, er
if err := binary.Read(carrier, binary.BigEndian, &ctx.parentID); err != nil {
return emptyContext, opentracing.ErrSpanContextCorrupted
}
- if err := binary.Read(carrier, binary.BigEndian, &ctx.flags); err != nil {
+
+ var flags byte
+ if err := binary.Read(carrier, binary.BigEndian, &flags); err != nil {
return emptyContext, opentracing.ErrSpanContextCorrupted
}
+ ctx.samplingState.setFlags(flags)
// Handle the baggage items
var numBaggage int32
diff --git a/vendor/github.com/uber/jaeger-client-go/reporter.go b/vendor/github.com/uber/jaeger-client-go/reporter.go
index 27163ebe4..0b78cec20 100644
--- a/vendor/github.com/uber/jaeger-client-go/reporter.go
+++ b/vendor/github.com/uber/jaeger-client-go/reporter.go
@@ -28,6 +28,8 @@ import (
// Reporter is called by the tracer when a span is completed to report the span to the tracing collector.
type Reporter interface {
// Report submits a new span to collectors, possibly asynchronously and/or with buffering.
+ // If the reporter is processing Span asynchronously then it needs to Retain() the span,
+ // and then Release() it when no longer needed, to avoid span data corruption.
Report(span *Span)
// Close does a clean shutdown of the reporter, flushing any traces that may be buffered in memory.
diff --git a/vendor/github.com/uber/jaeger-client-go/sampler.go b/vendor/github.com/uber/jaeger-client-go/sampler.go
index ea6984e02..6195d59c5 100644
--- a/vendor/github.com/uber/jaeger-client-go/sampler.go
+++ b/vendor/github.com/uber/jaeger-client-go/sampler.go
@@ -17,19 +17,14 @@ package jaeger
import (
"fmt"
"math"
- "net/url"
"sync"
- "sync/atomic"
- "time"
- "github.com/uber/jaeger-client-go/log"
"github.com/uber/jaeger-client-go/thrift-gen/sampling"
"github.com/uber/jaeger-client-go/utils"
)
const (
- defaultSamplingRefreshInterval = time.Minute
- defaultMaxOperations = 2000
+ defaultMaxOperations = 2000
)
// Sampler decides whether a new trace should be sampled or not.
@@ -47,9 +42,7 @@ type Sampler interface {
// Equal checks if the `other` sampler is functionally equivalent
// to this sampler.
- // TODO remove this function. This function is used to determine if 2 samplers are equivalent
- // which does not bode well with the adaptive sampler which has to create all the composite samplers
- // for the comparison to occur. This is expensive to do if only one sampler has changed.
+ // TODO (breaking change) remove this function. See PerOperationSampler.Equals for explanation.
Equal(other Sampler) bool
}
@@ -57,17 +50,23 @@ type Sampler interface {
// ConstSampler is a sampler that always makes the same decision.
type ConstSampler struct {
+ legacySamplerV1Base
Decision bool
tags []Tag
}
// NewConstSampler creates a ConstSampler.
-func NewConstSampler(sample bool) Sampler {
+func NewConstSampler(sample bool) *ConstSampler {
tags := []Tag{
{key: SamplerTypeTagKey, value: SamplerTypeConst},
{key: SamplerParamTagKey, value: sample},
}
- return &ConstSampler{Decision: sample, tags: tags}
+ s := &ConstSampler{
+ Decision: sample,
+ tags: tags,
+ }
+ s.delegate = s.IsSampled
+ return s
}
// IsSampled implements IsSampled() of Sampler.
@@ -88,11 +87,17 @@ func (s *ConstSampler) Equal(other Sampler) bool {
return false
}
+// String is used to log sampler details.
+func (s *ConstSampler) String() string {
+ return fmt.Sprintf("ConstSampler(decision=%t)", s.Decision)
+}
+
// -----------------------
// ProbabilisticSampler is a sampler that randomly samples a certain percentage
// of traces.
type ProbabilisticSampler struct {
+ legacySamplerV1Base
samplingRate float64
samplingBoundary uint64
tags []Tag
@@ -114,16 +119,19 @@ func NewProbabilisticSampler(samplingRate float64) (*ProbabilisticSampler, error
}
func newProbabilisticSampler(samplingRate float64) *ProbabilisticSampler {
- samplingRate = math.Max(0.0, math.Min(samplingRate, 1.0))
- tags := []Tag{
+ s := new(ProbabilisticSampler)
+ s.delegate = s.IsSampled
+ return s.init(samplingRate)
+}
+
+func (s *ProbabilisticSampler) init(samplingRate float64) *ProbabilisticSampler {
+ s.samplingRate = math.Max(0.0, math.Min(samplingRate, 1.0))
+ s.samplingBoundary = uint64(float64(maxRandomNumber) * s.samplingRate)
+ s.tags = []Tag{
{key: SamplerTypeTagKey, value: SamplerTypeProbabilistic},
- {key: SamplerParamTagKey, value: samplingRate},
- }
- return &ProbabilisticSampler{
- samplingRate: samplingRate,
- samplingBoundary: uint64(float64(maxRandomNumber) * samplingRate),
- tags: tags,
+ {key: SamplerParamTagKey, value: s.samplingRate},
}
+ return s
}
// SamplingRate returns the sampling probability this sampled was constructed with.
@@ -149,65 +157,104 @@ func (s *ProbabilisticSampler) Equal(other Sampler) bool {
return false
}
+// Update modifies in-place the sampling rate. Locking must be done externally.
+func (s *ProbabilisticSampler) Update(samplingRate float64) error {
+ if samplingRate < 0.0 || samplingRate > 1.0 {
+ return fmt.Errorf("Sampling Rate must be between 0.0 and 1.0, received %f", samplingRate)
+ }
+ s.init(samplingRate)
+ return nil
+}
+
+// String is used to log sampler details.
+func (s *ProbabilisticSampler) String() string {
+ return fmt.Sprintf("ProbabilisticSampler(samplingRate=%v)", s.samplingRate)
+}
+
// -----------------------
-type rateLimitingSampler struct {
+// RateLimitingSampler samples at most maxTracesPerSecond. The distribution of sampled traces follows
+// burstiness of the service, i.e. a service with uniformly distributed requests will have those
+// requests sampled uniformly as well, but if requests are bursty, especially sub-second, then a
+// number of sequential requests can be sampled each second.
+type RateLimitingSampler struct {
+ legacySamplerV1Base
maxTracesPerSecond float64
- rateLimiter utils.RateLimiter
+ rateLimiter *utils.ReconfigurableRateLimiter
tags []Tag
}
-// NewRateLimitingSampler creates a sampler that samples at most maxTracesPerSecond. The distribution of sampled
-// traces follows burstiness of the service, i.e. a service with uniformly distributed requests will have those
-// requests sampled uniformly as well, but if requests are bursty, especially sub-second, then a number of
-// sequential requests can be sampled each second.
-func NewRateLimitingSampler(maxTracesPerSecond float64) Sampler {
- tags := []Tag{
+// NewRateLimitingSampler creates new RateLimitingSampler.
+func NewRateLimitingSampler(maxTracesPerSecond float64) *RateLimitingSampler {
+ s := new(RateLimitingSampler)
+ s.delegate = s.IsSampled
+ return s.init(maxTracesPerSecond)
+}
+
+func (s *RateLimitingSampler) init(maxTracesPerSecond float64) *RateLimitingSampler {
+ if s.rateLimiter == nil {
+ s.rateLimiter = utils.NewRateLimiter(maxTracesPerSecond, math.Max(maxTracesPerSecond, 1.0))
+ } else {
+ s.rateLimiter.Update(maxTracesPerSecond, math.Max(maxTracesPerSecond, 1.0))
+ }
+ s.maxTracesPerSecond = maxTracesPerSecond
+ s.tags = []Tag{
{key: SamplerTypeTagKey, value: SamplerTypeRateLimiting},
{key: SamplerParamTagKey, value: maxTracesPerSecond},
}
- return &rateLimitingSampler{
- maxTracesPerSecond: maxTracesPerSecond,
- rateLimiter: utils.NewRateLimiter(maxTracesPerSecond, math.Max(maxTracesPerSecond, 1.0)),
- tags: tags,
- }
+ return s
}
// IsSampled implements IsSampled() of Sampler.
-func (s *rateLimitingSampler) IsSampled(id TraceID, operation string) (bool, []Tag) {
+func (s *RateLimitingSampler) IsSampled(id TraceID, operation string) (bool, []Tag) {
return s.rateLimiter.CheckCredit(1.0), s.tags
}
-func (s *rateLimitingSampler) Close() {
+// Update reconfigures the rate limiter, while preserving its accumulated balance.
+// Locking must be done externally.
+func (s *RateLimitingSampler) Update(maxTracesPerSecond float64) {
+ if s.maxTracesPerSecond != maxTracesPerSecond {
+ s.init(maxTracesPerSecond)
+ }
+}
+
+// Close does nothing.
+func (s *RateLimitingSampler) Close() {
// nothing to do
}
-func (s *rateLimitingSampler) Equal(other Sampler) bool {
- if o, ok := other.(*rateLimitingSampler); ok {
+// Equal compares with another sampler.
+func (s *RateLimitingSampler) Equal(other Sampler) bool {
+ if o, ok := other.(*RateLimitingSampler); ok {
return s.maxTracesPerSecond == o.maxTracesPerSecond
}
return false
}
+// String is used to log sampler details.
+func (s *RateLimitingSampler) String() string {
+ return fmt.Sprintf("RateLimitingSampler(maxTracesPerSecond=%v)", s.maxTracesPerSecond)
+}
+
// -----------------------
-// GuaranteedThroughputProbabilisticSampler is a sampler that leverages both probabilisticSampler and
-// rateLimitingSampler. The rateLimitingSampler is used as a guaranteed lower bound sampler such that
+// GuaranteedThroughputProbabilisticSampler is a sampler that leverages both ProbabilisticSampler and
+// RateLimitingSampler. The RateLimitingSampler is used as a guaranteed lower bound sampler such that
// every operation is sampled at least once in a time interval defined by the lowerBound. ie a lowerBound
// of 1.0 / (60 * 10) will sample an operation at least once every 10 minutes.
//
-// The probabilisticSampler is given higher priority when tags are emitted, ie. if IsSampled() for both
-// samplers return true, the tags for probabilisticSampler will be used.
+// The ProbabilisticSampler is given higher priority when tags are emitted, ie. if IsSampled() for both
+// samplers return true, the tags for ProbabilisticSampler will be used.
type GuaranteedThroughputProbabilisticSampler struct {
probabilisticSampler *ProbabilisticSampler
- lowerBoundSampler Sampler
+ lowerBoundSampler *RateLimitingSampler
tags []Tag
samplingRate float64
lowerBound float64
}
// NewGuaranteedThroughputProbabilisticSampler returns a delegating sampler that applies both
-// probabilisticSampler and rateLimitingSampler.
+// ProbabilisticSampler and RateLimitingSampler.
func NewGuaranteedThroughputProbabilisticSampler(
lowerBound, samplingRate float64,
) (*GuaranteedThroughputProbabilisticSampler, error) {
@@ -224,8 +271,14 @@ func newGuaranteedThroughputProbabilisticSampler(lowerBound, samplingRate float6
}
func (s *GuaranteedThroughputProbabilisticSampler) setProbabilisticSampler(samplingRate float64) {
- if s.probabilisticSampler == nil || s.samplingRate != samplingRate {
+ if s.probabilisticSampler == nil {
s.probabilisticSampler = newProbabilisticSampler(samplingRate)
+ } else if s.samplingRate != samplingRate {
+ s.probabilisticSampler.init(samplingRate)
+ }
+ // since we don't validate samplingRate, sampler may have clamped it to [0, 1] interval
+ samplingRate = s.probabilisticSampler.SamplingRate()
+ if s.samplingRate != samplingRate || s.tags == nil {
s.samplingRate = s.probabilisticSampler.SamplingRate()
s.tags = []Tag{
{key: SamplerTypeTagKey, value: SamplerTypeLowerBound},
@@ -252,7 +305,7 @@ func (s *GuaranteedThroughputProbabilisticSampler) Close() {
// Equal implements Equal() of Sampler.
func (s *GuaranteedThroughputProbabilisticSampler) Equal(other Sampler) bool {
- // NB The Equal() function is expensive and will be removed. See adaptiveSampler.Equal() for
+ // NB The Equal() function is expensive and will be removed. See PerOperationSampler.Equal() for
// more information.
return false
}
@@ -261,52 +314,116 @@ func (s *GuaranteedThroughputProbabilisticSampler) Equal(other Sampler) bool {
func (s *GuaranteedThroughputProbabilisticSampler) update(lowerBound, samplingRate float64) {
s.setProbabilisticSampler(samplingRate)
if s.lowerBound != lowerBound {
- s.lowerBoundSampler = NewRateLimitingSampler(lowerBound)
+ s.lowerBoundSampler.Update(lowerBound)
s.lowerBound = lowerBound
}
}
// -----------------------
-type adaptiveSampler struct {
+// PerOperationSampler is a delegating sampler that applies GuaranteedThroughputProbabilisticSampler
+// on a per-operation basis.
+type PerOperationSampler struct {
sync.RWMutex
samplers map[string]*GuaranteedThroughputProbabilisticSampler
defaultSampler *ProbabilisticSampler
lowerBound float64
maxOperations int
+
+ // see description in PerOperationSamplerParams
+ operationNameLateBinding bool
}
-// NewAdaptiveSampler returns a delegating sampler that applies both probabilisticSampler and
-// rateLimitingSampler via the guaranteedThroughputProbabilisticSampler. This sampler keeps track of all
-// operations and delegates calls to the respective guaranteedThroughputProbabilisticSampler.
-func NewAdaptiveSampler(strategies *sampling.PerOperationSamplingStrategies, maxOperations int) (Sampler, error) {
- return newAdaptiveSampler(strategies, maxOperations), nil
+// NewAdaptiveSampler returns a new PerOperationSampler.
+// Deprecated: please use NewPerOperationSampler.
+func NewAdaptiveSampler(strategies *sampling.PerOperationSamplingStrategies, maxOperations int) (*PerOperationSampler, error) {
+ return NewPerOperationSampler(PerOperationSamplerParams{
+ MaxOperations: maxOperations,
+ Strategies: strategies,
+ }), nil
}
-func newAdaptiveSampler(strategies *sampling.PerOperationSamplingStrategies, maxOperations int) Sampler {
+// PerOperationSamplerParams defines parameters when creating PerOperationSampler.
+type PerOperationSamplerParams struct {
+ // Max number of operations that will be tracked. Other operations will be given default strategy.
+ MaxOperations int
+
+ // Opt-in feature for applications that require late binding of span name via explicit call to SetOperationName.
+ // When this feature is enabled, the sampler will return retryable=true from OnCreateSpan(), thus leaving
+ // the sampling decision as non-final (and the span as writeable). This may lead to degraded performance
+ // in applications that always provide the correct span name on trace creation.
+ //
+ // For backwards compatibility this option is off by default.
+ OperationNameLateBinding bool
+
+ // Initial configuration of the sampling strategies (usually retrieved from the backend by Remote Sampler).
+ Strategies *sampling.PerOperationSamplingStrategies
+}
+
+// NewPerOperationSampler returns a new PerOperationSampler.
+func NewPerOperationSampler(params PerOperationSamplerParams) *PerOperationSampler {
samplers := make(map[string]*GuaranteedThroughputProbabilisticSampler)
- for _, strategy := range strategies.PerOperationStrategies {
+ for _, strategy := range params.Strategies.PerOperationStrategies {
sampler := newGuaranteedThroughputProbabilisticSampler(
- strategies.DefaultLowerBoundTracesPerSecond,
+ params.Strategies.DefaultLowerBoundTracesPerSecond,
strategy.ProbabilisticSampling.SamplingRate,
)
samplers[strategy.Operation] = sampler
}
- return &adaptiveSampler{
- samplers: samplers,
- defaultSampler: newProbabilisticSampler(strategies.DefaultSamplingProbability),
- lowerBound: strategies.DefaultLowerBoundTracesPerSecond,
- maxOperations: maxOperations,
+ return &PerOperationSampler{
+ samplers: samplers,
+ defaultSampler: newProbabilisticSampler(params.Strategies.DefaultSamplingProbability),
+ lowerBound: params.Strategies.DefaultLowerBoundTracesPerSecond,
+ maxOperations: params.MaxOperations,
+ operationNameLateBinding: params.OperationNameLateBinding,
}
}
-func (s *adaptiveSampler) IsSampled(id TraceID, operation string) (bool, []Tag) {
+// IsSampled is not used and only exists to match Sampler V1 API.
+// TODO (breaking change) remove when upgrading everything to SamplerV2
+func (s *PerOperationSampler) IsSampled(id TraceID, operation string) (bool, []Tag) {
+ return false, nil
+}
+
+func (s *PerOperationSampler) trySampling(span *Span, operationName string) (bool, []Tag) {
+ samplerV1 := s.getSamplerForOperation(operationName)
+ var sampled bool
+ var tags []Tag
+ if span.context.samplingState.isLocalRootSpan(span.context.spanID) {
+ sampled, tags = samplerV1.IsSampled(span.context.TraceID(), operationName)
+ }
+ return sampled, tags
+}
+
+// OnCreateSpan implements OnCreateSpan of SamplerV2.
+func (s *PerOperationSampler) OnCreateSpan(span *Span) SamplingDecision {
+ sampled, tags := s.trySampling(span, span.OperationName())
+ return SamplingDecision{Sample: sampled, Retryable: s.operationNameLateBinding, Tags: tags}
+}
+
+// OnSetOperationName implements OnSetOperationName of SamplerV2.
+func (s *PerOperationSampler) OnSetOperationName(span *Span, operationName string) SamplingDecision {
+ sampled, tags := s.trySampling(span, operationName)
+ return SamplingDecision{Sample: sampled, Retryable: false, Tags: tags}
+}
+
+// OnSetTag implements OnSetTag of SamplerV2.
+func (s *PerOperationSampler) OnSetTag(span *Span, key string, value interface{}) SamplingDecision {
+ return SamplingDecision{Sample: false, Retryable: true}
+}
+
+// OnFinishSpan implements OnFinishSpan of SamplerV2.
+func (s *PerOperationSampler) OnFinishSpan(span *Span) SamplingDecision {
+ return SamplingDecision{Sample: false, Retryable: true}
+}
+
+func (s *PerOperationSampler) getSamplerForOperation(operation string) Sampler {
s.RLock()
sampler, ok := s.samplers[operation]
if ok {
defer s.RUnlock()
- return sampler.IsSampled(id, operation)
+ return sampler
}
s.RUnlock()
s.Lock()
@@ -315,18 +432,19 @@ func (s *adaptiveSampler) IsSampled(id TraceID, operation string) (bool, []Tag)
// Check if sampler has already been created
sampler, ok = s.samplers[operation]
if ok {
- return sampler.IsSampled(id, operation)
+ return sampler
}
// Store only up to maxOperations of unique ops.
if len(s.samplers) >= s.maxOperations {
- return s.defaultSampler.IsSampled(id, operation)
+ return s.defaultSampler
}
newSampler := newGuaranteedThroughputProbabilisticSampler(s.lowerBound, s.defaultSampler.SamplingRate())
s.samplers[operation] = newSampler
- return newSampler.IsSampled(id, operation)
+ return newSampler
}
-func (s *adaptiveSampler) Close() {
+// Close invokes Close on all underlying samplers.
+func (s *PerOperationSampler) Close() {
s.Lock()
defer s.Unlock()
for _, sampler := range s.samplers {
@@ -335,16 +453,18 @@ func (s *adaptiveSampler) Close() {
s.defaultSampler.Close()
}
-func (s *adaptiveSampler) Equal(other Sampler) bool {
- // NB The Equal() function is overly expensive for adaptiveSampler since it's composed of multiple
+// Equal is not used.
+// TODO (breaking change) remove this in the future
+func (s *PerOperationSampler) Equal(other Sampler) bool {
+ // NB The Equal() function is overly expensive for PerOperationSampler since it's composed of multiple
// samplers which all need to be initialized before this function can be called for a comparison.
- // Therefore, adaptiveSampler uses the update() function to only alter the samplers that need
+ // Therefore, PerOperationSampler uses the update() function to only alter the samplers that need
// changing. Hence this function always returns false so that the update function can be called.
// Once the Equal() function is removed from the Sampler API, this will no longer be needed.
return false
}
-func (s *adaptiveSampler) update(strategies *sampling.PerOperationSamplingStrategies) {
+func (s *PerOperationSampler) update(strategies *sampling.PerOperationSamplingStrategies) {
s.Lock()
defer s.Unlock()
newSamplers := map[string]*GuaranteedThroughputProbabilisticSampler{}
@@ -369,191 +489,3 @@ func (s *adaptiveSampler) update(strategies *sampling.PerOperationSamplingStrate
}
s.samplers = newSamplers
}
-
-// -----------------------
-
-// RemotelyControlledSampler is a delegating sampler that polls a remote server
-// for the appropriate sampling strategy, constructs a corresponding sampler and
-// delegates to it for sampling decisions.
-type RemotelyControlledSampler struct {
- // These fields must be first in the struct because `sync/atomic` expects 64-bit alignment.
- // Cf. https://github.com/uber/jaeger-client-go/issues/155, https://goo.gl/zW7dgq
- closed int64 // 0 - not closed, 1 - closed
-
- sync.RWMutex
- samplerOptions
-
- serviceName string
- manager sampling.SamplingManager
- doneChan chan *sync.WaitGroup
-}
-
-type httpSamplingManager struct {
- serverURL string
-}
-
-func (s *httpSamplingManager) GetSamplingStrategy(serviceName string) (*sampling.SamplingStrategyResponse, error) {
- var out sampling.SamplingStrategyResponse
- v := url.Values{}
- v.Set("service", serviceName)
- if err := utils.GetJSON(s.serverURL+"?"+v.Encode(), &out); err != nil {
- return nil, err
- }
- return &out, nil
-}
-
-// NewRemotelyControlledSampler creates a sampler that periodically pulls
-// the sampling strategy from an HTTP sampling server (e.g. jaeger-agent).
-func NewRemotelyControlledSampler(
- serviceName string,
- opts ...SamplerOption,
-) *RemotelyControlledSampler {
- options := applySamplerOptions(opts...)
- sampler := &RemotelyControlledSampler{
- samplerOptions: options,
- serviceName: serviceName,
- manager: &httpSamplingManager{serverURL: options.samplingServerURL},
- doneChan: make(chan *sync.WaitGroup),
- }
- go sampler.pollController()
- return sampler
-}
-
-func applySamplerOptions(opts ...SamplerOption) samplerOptions {
- options := samplerOptions{}
- for _, option := range opts {
- option(&options)
- }
- if options.sampler == nil {
- options.sampler = newProbabilisticSampler(0.001)
- }
- if options.logger == nil {
- options.logger = log.NullLogger
- }
- if options.maxOperations <= 0 {
- options.maxOperations = defaultMaxOperations
- }
- if options.samplingServerURL == "" {
- options.samplingServerURL = DefaultSamplingServerURL
- }
- if options.metrics == nil {
- options.metrics = NewNullMetrics()
- }
- if options.samplingRefreshInterval <= 0 {
- options.samplingRefreshInterval = defaultSamplingRefreshInterval
- }
- return options
-}
-
-// IsSampled implements IsSampled() of Sampler.
-func (s *RemotelyControlledSampler) IsSampled(id TraceID, operation string) (bool, []Tag) {
- s.RLock()
- defer s.RUnlock()
- return s.sampler.IsSampled(id, operation)
-}
-
-// Close implements Close() of Sampler.
-func (s *RemotelyControlledSampler) Close() {
- if swapped := atomic.CompareAndSwapInt64(&s.closed, 0, 1); !swapped {
- s.logger.Error("Repeated attempt to close the sampler is ignored")
- return
- }
-
- var wg sync.WaitGroup
- wg.Add(1)
- s.doneChan <- &wg
- wg.Wait()
-}
-
-// Equal implements Equal() of Sampler.
-func (s *RemotelyControlledSampler) Equal(other Sampler) bool {
- // NB The Equal() function is expensive and will be removed. See adaptiveSampler.Equal() for
- // more information.
- if o, ok := other.(*RemotelyControlledSampler); ok {
- s.RLock()
- o.RLock()
- defer s.RUnlock()
- defer o.RUnlock()
- return s.sampler.Equal(o.sampler)
- }
- return false
-}
-
-func (s *RemotelyControlledSampler) pollController() {
- ticker := time.NewTicker(s.samplingRefreshInterval)
- defer ticker.Stop()
- s.pollControllerWithTicker(ticker)
-}
-
-func (s *RemotelyControlledSampler) pollControllerWithTicker(ticker *time.Ticker) {
- for {
- select {
- case <-ticker.C:
- s.updateSampler()
- case wg := <-s.doneChan:
- wg.Done()
- return
- }
- }
-}
-
-func (s *RemotelyControlledSampler) getSampler() Sampler {
- s.Lock()
- defer s.Unlock()
- return s.sampler
-}
-
-func (s *RemotelyControlledSampler) setSampler(sampler Sampler) {
- s.Lock()
- defer s.Unlock()
- s.sampler = sampler
-}
-
-func (s *RemotelyControlledSampler) updateSampler() {
- res, err := s.manager.GetSamplingStrategy(s.serviceName)
- if err != nil {
- s.metrics.SamplerQueryFailure.Inc(1)
- s.logger.Infof("Unable to query sampling strategy: %v", err)
- return
- }
- s.Lock()
- defer s.Unlock()
-
- s.metrics.SamplerRetrieved.Inc(1)
- if strategies := res.GetOperationSampling(); strategies != nil {
- s.updateAdaptiveSampler(strategies)
- } else {
- err = s.updateRateLimitingOrProbabilisticSampler(res)
- }
- if err != nil {
- s.metrics.SamplerUpdateFailure.Inc(1)
- s.logger.Infof("Unable to handle sampling strategy response %+v. Got error: %v", res, err)
- return
- }
- s.metrics.SamplerUpdated.Inc(1)
-}
-
-// NB: this function should only be called while holding a Write lock
-func (s *RemotelyControlledSampler) updateAdaptiveSampler(strategies *sampling.PerOperationSamplingStrategies) {
- if adaptiveSampler, ok := s.sampler.(*adaptiveSampler); ok {
- adaptiveSampler.update(strategies)
- } else {
- s.sampler = newAdaptiveSampler(strategies, s.maxOperations)
- }
-}
-
-// NB: this function should only be called while holding a Write lock
-func (s *RemotelyControlledSampler) updateRateLimitingOrProbabilisticSampler(res *sampling.SamplingStrategyResponse) error {
- var newSampler Sampler
- if probabilistic := res.GetProbabilisticSampling(); probabilistic != nil {
- newSampler = newProbabilisticSampler(probabilistic.SamplingRate)
- } else if rateLimiting := res.GetRateLimitingSampling(); rateLimiting != nil {
- newSampler = NewRateLimitingSampler(float64(rateLimiting.MaxTracesPerSecond))
- } else {
- return fmt.Errorf("Unsupported sampling strategy type %v", res.GetStrategyType())
- }
- if !s.sampler.Equal(newSampler) {
- s.sampler = newSampler
- }
- return nil
-}
diff --git a/vendor/github.com/uber/jaeger-client-go/sampler_remote.go b/vendor/github.com/uber/jaeger-client-go/sampler_remote.go
new file mode 100644
index 000000000..9bd0c9822
--- /dev/null
+++ b/vendor/github.com/uber/jaeger-client-go/sampler_remote.go
@@ -0,0 +1,334 @@
+// Copyright (c) 2017 Uber Technologies, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package jaeger
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/uber/jaeger-client-go/thrift-gen/sampling"
+)
+
+const (
+ defaultSamplingRefreshInterval = time.Minute
+)
+
+// SamplingStrategyFetcher is used to fetch sampling strategy updates from remote server.
+type SamplingStrategyFetcher interface {
+ Fetch(service string) ([]byte, error)
+}
+
+// SamplingStrategyParser is used to parse sampling strategy updates. The output object
+// should be of the type that is recognized by the SamplerUpdaters.
+type SamplingStrategyParser interface {
+ Parse(response []byte) (interface{}, error)
+}
+
+// SamplerUpdater is used by RemotelyControlledSampler to apply sampling strategies,
+// retrieved from remote config server, to the current sampler. The updater can modify
+// the sampler in-place if sampler supports it, or create a new one.
+//
+// If the strategy does not contain configuration for the sampler in question,
+// updater must return modifiedSampler=nil to give other updaters a chance to inspect
+// the sampling strategy response.
+//
+// RemotelyControlledSampler invokes the updaters while holding a lock on the main sampler.
+type SamplerUpdater interface {
+ Update(sampler SamplerV2, strategy interface{}) (modified SamplerV2, err error)
+}
+
+// RemotelyControlledSampler is a delegating sampler that polls a remote server
+// for the appropriate sampling strategy, constructs a corresponding sampler and
+// delegates to it for sampling decisions.
+type RemotelyControlledSampler struct {
+ // These fields must be first in the struct because `sync/atomic` expects 64-bit alignment.
+ // Cf. https://github.com/uber/jaeger-client-go/issues/155, https://goo.gl/zW7dgq
+ closed int64 // 0 - not closed, 1 - closed
+
+ sync.RWMutex
+ samplerOptions
+
+ serviceName string
+ doneChan chan *sync.WaitGroup
+}
+
+// NewRemotelyControlledSampler creates a sampler that periodically pulls
+// the sampling strategy from an HTTP sampling server (e.g. jaeger-agent).
+func NewRemotelyControlledSampler(
+ serviceName string,
+ opts ...SamplerOption,
+) *RemotelyControlledSampler {
+ options := new(samplerOptions).applyOptionsAndDefaults(opts...)
+ sampler := &RemotelyControlledSampler{
+ samplerOptions: *options,
+ serviceName: serviceName,
+ doneChan: make(chan *sync.WaitGroup),
+ }
+ go sampler.pollController()
+ return sampler
+}
+
+// IsSampled implements IsSampled() of Sampler.
+// TODO (breaking change) remove when Sampler V1 is removed
+func (s *RemotelyControlledSampler) IsSampled(id TraceID, operation string) (bool, []Tag) {
+ return false, nil
+}
+
+// OnCreateSpan implements OnCreateSpan of SamplerV2.
+func (s *RemotelyControlledSampler) OnCreateSpan(span *Span) SamplingDecision {
+ return s.sampler.OnCreateSpan(span)
+}
+
+// OnSetOperationName implements OnSetOperationName of SamplerV2.
+func (s *RemotelyControlledSampler) OnSetOperationName(span *Span, operationName string) SamplingDecision {
+ return s.sampler.OnSetOperationName(span, operationName)
+}
+
+// OnSetTag implements OnSetTag of SamplerV2.
+func (s *RemotelyControlledSampler) OnSetTag(span *Span, key string, value interface{}) SamplingDecision {
+ return s.sampler.OnSetTag(span, key, value)
+}
+
+// OnFinishSpan implements OnFinishSpan of SamplerV2.
+func (s *RemotelyControlledSampler) OnFinishSpan(span *Span) SamplingDecision {
+ return s.sampler.OnFinishSpan(span)
+}
+
+// Close implements Close() of Sampler.
+func (s *RemotelyControlledSampler) Close() {
+ if swapped := atomic.CompareAndSwapInt64(&s.closed, 0, 1); !swapped {
+ s.logger.Error("Repeated attempt to close the sampler is ignored")
+ return
+ }
+
+ var wg sync.WaitGroup
+ wg.Add(1)
+ s.doneChan <- &wg
+ wg.Wait()
+}
+
+// Equal implements Equal() of Sampler.
+func (s *RemotelyControlledSampler) Equal(other Sampler) bool {
+ // NB The Equal() function is expensive and will be removed. See PerOperationSampler.Equal() for
+ // more information.
+ return false
+}
+
+func (s *RemotelyControlledSampler) pollController() {
+ ticker := time.NewTicker(s.samplingRefreshInterval)
+ defer ticker.Stop()
+ s.pollControllerWithTicker(ticker)
+}
+
+func (s *RemotelyControlledSampler) pollControllerWithTicker(ticker *time.Ticker) {
+ for {
+ select {
+ case <-ticker.C:
+ s.UpdateSampler()
+ case wg := <-s.doneChan:
+ wg.Done()
+ return
+ }
+ }
+}
+
+// Sampler returns the currently active sampler.
+func (s *RemotelyControlledSampler) Sampler() SamplerV2 {
+ s.Lock()
+ defer s.Unlock()
+ return s.sampler
+}
+
+func (s *RemotelyControlledSampler) setSampler(sampler SamplerV2) {
+ s.Lock()
+ defer s.Unlock()
+ s.sampler = sampler
+}
+
+// UpdateSampler forces the sampler to fetch sampling strategy from backend server.
+// This function is called automatically on a timer, but can also be safely called manually, e.g. from tests.
+func (s *RemotelyControlledSampler) UpdateSampler() {
+ res, err := s.samplingFetcher.Fetch(s.serviceName)
+ if err != nil {
+ s.metrics.SamplerQueryFailure.Inc(1)
+ s.logger.Infof("failed to fetch sampling strategy: %v", err)
+ return
+ }
+ strategy, err := s.samplingParser.Parse(res)
+ if err != nil {
+ s.metrics.SamplerUpdateFailure.Inc(1)
+ s.logger.Infof("failed to parse sampling strategy response: %v", err)
+ return
+ }
+
+ s.Lock()
+ defer s.Unlock()
+
+ s.metrics.SamplerRetrieved.Inc(1)
+ if err := s.updateSamplerViaUpdaters(strategy); err != nil {
+ s.metrics.SamplerUpdateFailure.Inc(1)
+ s.logger.Infof("failed to handle sampling strategy response %+v. Got error: %v", res, err)
+ return
+ }
+ s.metrics.SamplerUpdated.Inc(1)
+}
+
+// NB: this function should only be called while holding a Write lock
+func (s *RemotelyControlledSampler) updateSamplerViaUpdaters(strategy interface{}) error {
+ for _, updater := range s.updaters {
+ sampler, err := updater.Update(s.sampler, strategy)
+ if err != nil {
+ return err
+ }
+ if sampler != nil {
+ s.sampler = sampler
+ return nil
+ }
+ }
+ return fmt.Errorf("unsupported sampling strategy %+v", strategy)
+}
+
+// -----------------------
+
+// ProbabilisticSamplerUpdater is used by RemotelyControlledSampler to parse sampling configuration.
+type ProbabilisticSamplerUpdater struct{}
+
+// Update implements Update of SamplerUpdater.
+func (u *ProbabilisticSamplerUpdater) Update(sampler SamplerV2, strategy interface{}) (SamplerV2, error) {
+ type response interface {
+ GetProbabilisticSampling() *sampling.ProbabilisticSamplingStrategy
+ }
+ var _ response = new(sampling.SamplingStrategyResponse) // sanity signature check
+ if resp, ok := strategy.(response); ok {
+ if probabilistic := resp.GetProbabilisticSampling(); probabilistic != nil {
+ if ps, ok := sampler.(*ProbabilisticSampler); ok {
+ if err := ps.Update(probabilistic.SamplingRate); err != nil {
+ return nil, err
+ }
+ return sampler, nil
+ }
+ return newProbabilisticSampler(probabilistic.SamplingRate), nil
+ }
+ }
+ return nil, nil
+}
+
+// -----------------------
+
+// RateLimitingSamplerUpdater is used by RemotelyControlledSampler to parse sampling configuration.
+type RateLimitingSamplerUpdater struct{}
+
+// Update implements Update of SamplerUpdater.
+func (u *RateLimitingSamplerUpdater) Update(sampler SamplerV2, strategy interface{}) (SamplerV2, error) {
+ type response interface {
+ GetRateLimitingSampling() *sampling.RateLimitingSamplingStrategy
+ }
+ var _ response = new(sampling.SamplingStrategyResponse) // sanity signature check
+ if resp, ok := strategy.(response); ok {
+ if rateLimiting := resp.GetRateLimitingSampling(); rateLimiting != nil {
+ rateLimit := float64(rateLimiting.MaxTracesPerSecond)
+ if rl, ok := sampler.(*RateLimitingSampler); ok {
+ rl.Update(rateLimit)
+ return rl, nil
+ }
+ return NewRateLimitingSampler(rateLimit), nil
+ }
+ }
+ return nil, nil
+}
+
+// -----------------------
+
+// AdaptiveSamplerUpdater is used by RemotelyControlledSampler to parse sampling configuration.
+type AdaptiveSamplerUpdater struct {
+ MaxOperations int // required
+ OperationNameLateBinding bool
+}
+
+// Update implements Update of SamplerUpdater.
+func (u *AdaptiveSamplerUpdater) Update(sampler SamplerV2, strategy interface{}) (SamplerV2, error) {
+ type response interface {
+ GetOperationSampling() *sampling.PerOperationSamplingStrategies
+ }
+ var _ response = new(sampling.SamplingStrategyResponse) // sanity signature check
+ if p, ok := strategy.(response); ok {
+ if operations := p.GetOperationSampling(); operations != nil {
+ if as, ok := sampler.(*PerOperationSampler); ok {
+ as.update(operations)
+ return as, nil
+ }
+ return NewPerOperationSampler(PerOperationSamplerParams{
+ MaxOperations: u.MaxOperations,
+ OperationNameLateBinding: u.OperationNameLateBinding,
+ Strategies: operations,
+ }), nil
+ }
+ }
+ return nil, nil
+}
+
+// -----------------------
+
+type httpSamplingStrategyFetcher struct {
+ serverURL string
+ logger Logger
+}
+
+func (f *httpSamplingStrategyFetcher) Fetch(serviceName string) ([]byte, error) {
+ v := url.Values{}
+ v.Set("service", serviceName)
+ uri := f.serverURL + "?" + v.Encode()
+
+ // TODO create and reuse http.Client with proper timeout settings, etc.
+ resp, err := http.Get(uri)
+ if err != nil {
+ return nil, err
+ }
+
+ defer func() {
+ if err := resp.Body.Close(); err != nil {
+ f.logger.Error(fmt.Sprintf("failed to close HTTP response body: %+v", err))
+ }
+ }()
+
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ if resp.StatusCode >= 400 {
+ return nil, fmt.Errorf("StatusCode: %d, Body: %s", resp.StatusCode, body)
+ }
+
+ return body, nil
+}
+
+// -----------------------
+
+type samplingStrategyParser struct{}
+
+func (p *samplingStrategyParser) Parse(response []byte) (interface{}, error) {
+ strategy := new(sampling.SamplingStrategyResponse)
+ if err := json.Unmarshal(response, strategy); err != nil {
+ return nil, err
+ }
+ return strategy, nil
+}
diff --git a/vendor/github.com/uber/jaeger-client-go/sampler_options.go b/vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go
index 75d28a561..7a292effc 100644
--- a/vendor/github.com/uber/jaeger-client-go/sampler_options.go
+++ b/vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go
@@ -16,6 +16,8 @@ package jaeger
import (
"time"
+
+ "github.com/uber/jaeger-client-go/log"
)
// SamplerOption is a function that sets some option on the sampler
@@ -27,10 +29,13 @@ var SamplerOptions samplerOptions
type samplerOptions struct {
metrics *Metrics
maxOperations int
- sampler Sampler
+ sampler SamplerV2
logger Logger
samplingServerURL string
samplingRefreshInterval time.Duration
+ samplingFetcher SamplingStrategyFetcher
+ samplingParser SamplingStrategyParser
+ updaters []SamplerUpdater
}
// Metrics creates a SamplerOption that initializes Metrics on the sampler,
@@ -53,7 +58,7 @@ func (samplerOptions) MaxOperations(maxOperations int) SamplerOption {
// to use before a remote sampler is created and used.
func (samplerOptions) InitialSampler(sampler Sampler) SamplerOption {
return func(o *samplerOptions) {
- o.sampler = sampler
+ o.sampler = samplerV1toV2(sampler)
}
}
@@ -79,3 +84,65 @@ func (samplerOptions) SamplingRefreshInterval(samplingRefreshInterval time.Durat
o.samplingRefreshInterval = samplingRefreshInterval
}
}
+
+// SamplingStrategyFetcher creates a SamplerOption that initializes sampling strategy fetcher.
+func (samplerOptions) SamplingStrategyFetcher(fetcher SamplingStrategyFetcher) SamplerOption {
+ return func(o *samplerOptions) {
+ o.samplingFetcher = fetcher
+ }
+}
+
+// SamplingStrategyParser creates a SamplerOption that initializes sampling strategy parser.
+func (samplerOptions) SamplingStrategyParser(parser SamplingStrategyParser) SamplerOption {
+ return func(o *samplerOptions) {
+ o.samplingParser = parser
+ }
+}
+
+// Updaters creates a SamplerOption that initializes sampler updaters.
+func (samplerOptions) Updaters(updaters ...SamplerUpdater) SamplerOption {
+ return func(o *samplerOptions) {
+ o.updaters = updaters
+ }
+}
+
+func (o *samplerOptions) applyOptionsAndDefaults(opts ...SamplerOption) *samplerOptions {
+ for _, option := range opts {
+ option(o)
+ }
+ if o.sampler == nil {
+ o.sampler = newProbabilisticSampler(0.001)
+ }
+ if o.logger == nil {
+ o.logger = log.NullLogger
+ }
+ if o.maxOperations <= 0 {
+ o.maxOperations = defaultMaxOperations
+ }
+ if o.samplingServerURL == "" {
+ o.samplingServerURL = DefaultSamplingServerURL
+ }
+ if o.metrics == nil {
+ o.metrics = NewNullMetrics()
+ }
+ if o.samplingRefreshInterval <= 0 {
+ o.samplingRefreshInterval = defaultSamplingRefreshInterval
+ }
+ if o.samplingFetcher == nil {
+ o.samplingFetcher = &httpSamplingStrategyFetcher{
+ serverURL: o.samplingServerURL,
+ logger: o.logger,
+ }
+ }
+ if o.samplingParser == nil {
+ o.samplingParser = new(samplingStrategyParser)
+ }
+ if o.updaters == nil {
+ o.updaters = []SamplerUpdater{
+ &AdaptiveSamplerUpdater{MaxOperations: o.maxOperations},
+ new(ProbabilisticSamplerUpdater),
+ new(RateLimitingSamplerUpdater),
+ }
+ }
+ return o
+}
diff --git a/vendor/github.com/uber/jaeger-client-go/sampler_v2.go b/vendor/github.com/uber/jaeger-client-go/sampler_v2.go
new file mode 100644
index 000000000..a50671a23
--- /dev/null
+++ b/vendor/github.com/uber/jaeger-client-go/sampler_v2.go
@@ -0,0 +1,93 @@
+// Copyright (c) 2019 Uber Technologies, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package jaeger
+
+// SamplingDecision is returned by the V2 samplers.
+type SamplingDecision struct {
+ Sample bool
+ Retryable bool
+ Tags []Tag
+}
+
+// SamplerV2 is an extension of the V1 samplers that allows sampling decisions
+// be made at different points of the span lifecycle.
+type SamplerV2 interface {
+ OnCreateSpan(span *Span) SamplingDecision
+ OnSetOperationName(span *Span, operationName string) SamplingDecision
+ OnSetTag(span *Span, key string, value interface{}) SamplingDecision
+ OnFinishSpan(span *Span) SamplingDecision
+
+ // Close does a clean shutdown of the sampler, stopping any background
+ // go-routines it may have started.
+ Close()
+}
+
+// samplerV1toV2 wraps legacy V1 sampler into an adapter that make it look like V2.
+func samplerV1toV2(s Sampler) SamplerV2 {
+ if s2, ok := s.(SamplerV2); ok {
+ return s2
+ }
+ type legacySamplerV1toV2Adapter struct {
+ legacySamplerV1Base
+ }
+ return &legacySamplerV1toV2Adapter{
+ legacySamplerV1Base: legacySamplerV1Base{
+ delegate: s.IsSampled,
+ },
+ }
+}
+
+// SamplerV2Base can be used by V2 samplers to implement dummy V1 methods.
+// Supporting V1 API is required because Tracer configuration only accepts V1 Sampler
+// for backwards compatibility reasons.
+// TODO (breaking change) remove this in the next major release
+type SamplerV2Base struct{}
+
+// IsSampled implements IsSampled of Sampler.
+func (SamplerV2Base) IsSampled(id TraceID, operation string) (sampled bool, tags []Tag) {
+ return false, nil
+}
+
+// Close implements Close of Sampler.
+func (SamplerV2Base) Close() {}
+
+// Equal implements Equal of Sampler.
+func (SamplerV2Base) Equal(other Sampler) bool { return false }
+
+// legacySamplerV1Base is used as a base for simple samplers that only implement
+// the legacy isSampled() function that is not sensitive to its arguments.
+type legacySamplerV1Base struct {
+ delegate func(id TraceID, operation string) (sampled bool, tags []Tag)
+}
+
+func (s *legacySamplerV1Base) OnCreateSpan(span *Span) SamplingDecision {
+ isSampled, tags := s.delegate(span.context.traceID, span.operationName)
+ return SamplingDecision{Sample: isSampled, Retryable: false, Tags: tags}
+}
+
+func (s *legacySamplerV1Base) OnSetOperationName(span *Span, operationName string) SamplingDecision {
+ isSampled, tags := s.delegate(span.context.traceID, span.operationName)
+ return SamplingDecision{Sample: isSampled, Retryable: false, Tags: tags}
+}
+
+func (s *legacySamplerV1Base) OnSetTag(span *Span, key string, value interface{}) SamplingDecision {
+ return SamplingDecision{Sample: false, Retryable: true}
+}
+
+func (s *legacySamplerV1Base) OnFinishSpan(span *Span) SamplingDecision {
+ return SamplingDecision{Sample: false, Retryable: true}
+}
+
+func (s *legacySamplerV1Base) Close() {}
diff --git a/vendor/github.com/uber/jaeger-client-go/span.go b/vendor/github.com/uber/jaeger-client-go/span.go
index 9df8b6017..bbf6fb068 100644
--- a/vendor/github.com/uber/jaeger-client-go/span.go
+++ b/vendor/github.com/uber/jaeger-client-go/span.go
@@ -34,6 +34,7 @@ type Span struct {
tracer *Tracer
+ // TODO: (breaking change) change to use a pointer
context SpanContext
// The name of the "operation" this span is an instance of.
@@ -65,18 +66,26 @@ type Span struct {
}
// Tag is a simple key value wrapper.
-// TODO deprecate in the next major release, use opentracing.Tag instead.
+// TODO (breaking change) deprecate in the next major release, use opentracing.Tag instead.
type Tag struct {
key string
value interface{}
}
+// NewTag creates a new Tag.
+// TODO (breaking change) deprecate in the next major release, use opentracing.Tag instead.
+func NewTag(key string, value interface{}) Tag {
+ return Tag{key: key, value: value}
+}
+
// SetOperationName sets or changes the operation name.
func (s *Span) SetOperationName(operationName string) opentracing.Span {
s.Lock()
- defer s.Unlock()
- if s.context.IsSampled() {
- s.operationName = operationName
+ s.operationName = operationName
+ s.Unlock()
+ if !s.isSamplingFinalized() {
+ decision := s.tracer.sampler.OnSetOperationName(s, operationName)
+ s.applySamplingDecision(decision, true)
}
s.observer.OnSetOperationName(operationName)
return s
@@ -84,14 +93,24 @@ func (s *Span) SetOperationName(operationName string) opentracing.Span {
// SetTag implements SetTag() of opentracing.Span
func (s *Span) SetTag(key string, value interface{}) opentracing.Span {
+ return s.setTagInternal(key, value, true)
+}
+
+func (s *Span) setTagInternal(key string, value interface{}, lock bool) opentracing.Span {
s.observer.OnSetTag(key, value)
if key == string(ext.SamplingPriority) && !setSamplingPriority(s, value) {
return s
}
- s.Lock()
- defer s.Unlock()
- if s.context.IsSampled() {
- s.setTagNoLocking(key, value)
+ if !s.isSamplingFinalized() {
+ decision := s.tracer.sampler.OnSetTag(s, key, value)
+ s.applySamplingDecision(decision, lock)
+ }
+ if s.isWriteable() {
+ if lock {
+ s.Lock()
+ defer s.Unlock()
+ }
+ s.appendTagNoLocking(key, value)
}
return s
}
@@ -121,14 +140,38 @@ func (s *Span) Duration() time.Duration {
func (s *Span) Tags() opentracing.Tags {
s.Lock()
defer s.Unlock()
- var result = make(opentracing.Tags)
+ var result = make(opentracing.Tags, len(s.tags))
for _, tag := range s.tags {
result[tag.key] = tag.value
}
return result
}
-func (s *Span) setTagNoLocking(key string, value interface{}) {
+// Logs returns micro logs for span
+func (s *Span) Logs() []opentracing.LogRecord {
+ s.Lock()
+ defer s.Unlock()
+
+ return append([]opentracing.LogRecord(nil), s.logs...)
+}
+
+// References returns references for this span
+func (s *Span) References() []opentracing.SpanReference {
+ s.Lock()
+ defer s.Unlock()
+
+ if s.references == nil || len(s.references) == 0 {
+ return nil
+ }
+
+ result := make([]opentracing.SpanReference, len(s.references))
+ for i, r := range s.references {
+ result[i] = opentracing.SpanReference{Type: r.Type, ReferencedContext: r.Context}
+ }
+ return result
+}
+
+func (s *Span) appendTagNoLocking(key string, value interface{}) {
s.tags = append(s.tags, Tag{key: key, value: value})
}
@@ -148,7 +191,7 @@ func (s *Span) logFieldsNoLocking(fields ...log.Field) {
Fields: fields,
Timestamp: time.Now(),
}
- s.appendLog(lr)
+ s.appendLogNoLocking(lr)
}
// LogKV implements opentracing.Span API
@@ -185,12 +228,12 @@ func (s *Span) Log(ld opentracing.LogData) {
if ld.Timestamp.IsZero() {
ld.Timestamp = s.tracer.timeNow()
}
- s.appendLog(ld.ToLogRecord())
+ s.appendLogNoLocking(ld.ToLogRecord())
}
}
// this function should only be called while holding a Write lock
-func (s *Span) appendLog(lr opentracing.LogRecord) {
+func (s *Span) appendLogNoLocking(lr opentracing.LogRecord) {
// TODO add logic to limit number of logs per span (issue #46)
s.logs = append(s.logs, lr)
}
@@ -224,17 +267,25 @@ func (s *Span) FinishWithOptions(options opentracing.FinishOptions) {
}
s.observer.OnFinish(options)
s.Lock()
+ s.duration = options.FinishTime.Sub(s.startTime)
+ s.Unlock()
+ if !s.isSamplingFinalized() {
+ decision := s.tracer.sampler.OnFinishSpan(s)
+ s.applySamplingDecision(decision, true)
+ }
if s.context.IsSampled() {
- s.duration = options.FinishTime.Sub(s.startTime)
- // Note: bulk logs are not subject to maxLogsPerSpan limit
- if options.LogRecords != nil {
- s.logs = append(s.logs, options.LogRecords...)
- }
- for _, ld := range options.BulkLogData {
- s.logs = append(s.logs, ld.ToLogRecord())
+ if len(options.LogRecords) > 0 || len(options.BulkLogData) > 0 {
+ s.Lock()
+ // Note: bulk logs are not subject to maxLogsPerSpan limit
+ if options.LogRecords != nil {
+ s.logs = append(s.logs, options.LogRecords...)
+ }
+ for _, ld := range options.BulkLogData {
+ s.logs = append(s.logs, ld.ToLogRecord())
+ }
+ s.Unlock()
}
}
- s.Unlock()
// call reportSpan even for non-sampled traces, to return span to the pool
// and update metrics counter
s.tracer.reportSpan(s)
@@ -300,23 +351,62 @@ func (s *Span) serviceName() string {
return s.tracer.serviceName
}
+func (s *Span) applySamplingDecision(decision SamplingDecision, lock bool) {
+ if !decision.Retryable {
+ s.context.samplingState.setFinal()
+ }
+ if decision.Sample {
+ s.context.samplingState.setSampled()
+ if len(decision.Tags) > 0 {
+ if lock {
+ s.Lock()
+ defer s.Unlock()
+ }
+ for _, tag := range decision.Tags {
+ s.appendTagNoLocking(tag.key, tag.value)
+ }
+ }
+ }
+}
+
+// Span can be written to if it is sampled or the sampling decision has not been finalized.
+func (s *Span) isWriteable() bool {
+ state := s.context.samplingState
+ return !state.isFinal() || state.isSampled()
+}
+
+func (s *Span) isSamplingFinalized() bool {
+ return s.context.samplingState.isFinal()
+}
+
// setSamplingPriority returns true if the flag was updated successfully, false otherwise.
+// The behavior of setSamplingPriority is surprising
+// If noDebugFlagOnForcedSampling is set
+// setSamplingPriority(span, 1) always sets only flagSampled
+// If noDebugFlagOnForcedSampling is unset, and isDebugAllowed passes
+// setSamplingPriority(span, 1) sets both flagSampled and flagDebug
+// However,
+// setSamplingPriority(span, 0) always only resets flagSampled
+//
+// This means that doing a setSamplingPriority(span, 1) followed by setSamplingPriority(span, 0) can
+// leave flagDebug set
func setSamplingPriority(s *Span, value interface{}) bool {
val, ok := value.(uint16)
if !ok {
return false
}
- s.Lock()
- defer s.Unlock()
if val == 0 {
- s.context.flags = s.context.flags & (^flagSampled)
+ s.context.samplingState.unsetSampled()
+ s.context.samplingState.setFinal()
return true
}
if s.tracer.options.noDebugFlagOnForcedSampling {
- s.context.flags = s.context.flags | flagSampled
+ s.context.samplingState.setSampled()
+ s.context.samplingState.setFinal()
return true
} else if s.tracer.isDebugAllowed(s.operationName) {
- s.context.flags = s.context.flags | flagDebug | flagSampled
+ s.context.samplingState.setDebugAndSampled()
+ s.context.samplingState.setFinal()
return true
}
return false
@@ -326,5 +416,5 @@ func setSamplingPriority(s *Span, value interface{}) bool {
func EnableFirehose(s *Span) {
s.Lock()
defer s.Unlock()
- s.context.flags |= flagFirehose
+ s.context.samplingState.setFirehose()
}
diff --git a/vendor/github.com/uber/jaeger-client-go/context.go b/vendor/github.com/uber/jaeger-client-go/span_context.go
index 43553655a..b7230abfe 100644
--- a/vendor/github.com/uber/jaeger-client-go/context.go
+++ b/vendor/github.com/uber/jaeger-client-go/span_context.go
@@ -19,12 +19,15 @@ import (
"fmt"
"strconv"
"strings"
+ "sync"
+
+ "go.uber.org/atomic"
)
const (
- flagSampled = byte(1)
- flagDebug = byte(2)
- flagFirehose = byte(8)
+ flagSampled = 1
+ flagDebug = 2
+ flagFirehose = 8
)
var (
@@ -56,9 +59,6 @@ type SpanContext struct {
// Should be 0 if the current span is a root span.
parentID SpanID
- // flags is a bitmap containing such bits as 'sampled' and 'debug'.
- flags byte
-
// Distributed Context baggage. The is a snapshot in time.
baggage map[string]string
@@ -67,6 +67,102 @@ type SpanContext struct {
//
// See JaegerDebugHeader in constants.go
debugID string
+
+ // samplingState is shared across all spans
+ samplingState *samplingState
+
+ // remote indicates that span context represents a remote parent
+ remote bool
+}
+
+type samplingState struct {
+ // Span context's state flags that are propagated across processes. Only lower 8 bits are used.
+ // We use an int32 instead of byte to be able to use CAS operations.
+ stateFlags atomic.Int32
+
+ // When state is not final, sampling will be retried on other span write operations,
+ // like SetOperationName / SetTag, and the spans will remain writable.
+ final atomic.Bool
+
+ // localRootSpan stores the SpanID of the first span created in this process for a given trace.
+ localRootSpan SpanID
+
+ // extendedState allows samplers to keep intermediate state.
+ // The keys and values in this map are completely opaque: interface{} -> interface{}.
+ extendedState sync.Map
+}
+
+func (s *samplingState) isLocalRootSpan(id SpanID) bool {
+ return id == s.localRootSpan
+}
+
+func (s *samplingState) setFlag(newFlag int32) {
+ swapped := false
+ for !swapped {
+ old := s.stateFlags.Load()
+ swapped = s.stateFlags.CAS(old, old|newFlag)
+ }
+}
+
+func (s *samplingState) unsetFlag(newFlag int32) {
+ swapped := false
+ for !swapped {
+ old := s.stateFlags.Load()
+ swapped = s.stateFlags.CAS(old, old&^newFlag)
+ }
+}
+
+func (s *samplingState) setSampled() {
+ s.setFlag(flagSampled)
+}
+
+func (s *samplingState) unsetSampled() {
+ s.unsetFlag(flagSampled)
+}
+
+func (s *samplingState) setDebugAndSampled() {
+ s.setFlag(flagDebug | flagSampled)
+}
+
+func (s *samplingState) setFirehose() {
+ s.setFlag(flagFirehose)
+}
+
+func (s *samplingState) setFlags(flags byte) {
+ s.stateFlags.Store(int32(flags))
+}
+
+func (s *samplingState) setFinal() {
+ s.final.Store(true)
+}
+
+func (s *samplingState) flags() byte {
+ return byte(s.stateFlags.Load())
+}
+
+func (s *samplingState) isSampled() bool {
+ return s.stateFlags.Load()&flagSampled == flagSampled
+}
+
+func (s *samplingState) isDebug() bool {
+ return s.stateFlags.Load()&flagDebug == flagDebug
+}
+
+func (s *samplingState) isFirehose() bool {
+ return s.stateFlags.Load()&flagFirehose == flagFirehose
+}
+
+func (s *samplingState) isFinal() bool {
+ return s.final.Load()
+}
+
+func (s *samplingState) extendedStateForKey(key interface{}, initValue func() interface{}) interface{} {
+ if value, ok := s.extendedState.Load(key); ok {
+ return value
+ }
+ value := initValue()
+ value, _ = s.extendedState.LoadOrStore(key, value)
+ return value
}
// ForeachBaggageItem implements ForeachBaggageItem() of opentracing.SpanContext
@@ -81,17 +177,28 @@ func (c SpanContext) ForeachBaggageItem(handler func(k, v string) bool) {
// IsSampled returns whether this trace was chosen for permanent storage
// by the sampling mechanism of the tracer.
func (c SpanContext) IsSampled() bool {
- return (c.flags & flagSampled) == flagSampled
+ return c.samplingState.isSampled()
}
// IsDebug indicates whether sampling was explicitly requested by the service.
func (c SpanContext) IsDebug() bool {
- return (c.flags & flagDebug) == flagDebug
+ return c.samplingState.isDebug()
+}
+
+// IsSamplingFinalized indicates whether the sampling decision has been finalized.
+func (c SpanContext) IsSamplingFinalized() bool {
+ return c.samplingState.isFinal()
}
// IsFirehose indicates whether the firehose flag was set
func (c SpanContext) IsFirehose() bool {
- return (c.flags & flagFirehose) == flagFirehose
+ return c.samplingState.isFirehose()
+}
+
+// ExtendedSamplingState returns the custom state object for a given key. If the value for this key does not exist,
+// it is initialized via initValue function. This state can be used by samplers (e.g. x.PrioritySampler).
+func (c SpanContext) ExtendedSamplingState(key interface{}, initValue func() interface{}) interface{} {
+ return c.samplingState.extendedStateForKey(key, initValue)
}
// IsValid indicates whether this context actually represents a valid trace.
@@ -99,11 +206,16 @@ func (c SpanContext) IsValid() bool {
return c.traceID.IsValid() && c.spanID != 0
}
+// SetFirehose enables firehose mode for this trace.
+func (c SpanContext) SetFirehose() {
+ c.samplingState.setFirehose()
+}
+
func (c SpanContext) String() string {
if c.traceID.High == 0 {
- return fmt.Sprintf("%x:%x:%x:%x", c.traceID.Low, uint64(c.spanID), uint64(c.parentID), c.flags)
+ return fmt.Sprintf("%x:%x:%x:%x", c.traceID.Low, uint64(c.spanID), uint64(c.parentID), c.samplingState.stateFlags.Load())
}
- return fmt.Sprintf("%x%016x:%x:%x:%x", c.traceID.High, c.traceID.Low, uint64(c.spanID), uint64(c.parentID), c.flags)
+ return fmt.Sprintf("%x%016x:%x:%x:%x", c.traceID.High, c.traceID.Low, uint64(c.spanID), uint64(c.parentID), c.samplingState.stateFlags.Load())
}
// ContextFromString reconstructs the Context encoded in a string
@@ -130,7 +242,8 @@ func ContextFromString(value string) (SpanContext, error) {
if err != nil {
return emptyContext, err
}
- context.flags = byte(flags)
+ context.samplingState = &samplingState{}
+ context.samplingState.setFlags(byte(flags))
return context, nil
}
@@ -149,18 +262,24 @@ func (c SpanContext) ParentID() SpanID {
return c.parentID
}
+// Flags returns the bitmap containing such bits as 'sampled' and 'debug'.
+func (c SpanContext) Flags() byte {
+ return c.samplingState.flags()
+}
+
// NewSpanContext creates a new instance of SpanContext
func NewSpanContext(traceID TraceID, spanID, parentID SpanID, sampled bool, baggage map[string]string) SpanContext {
- flags := byte(0)
+ samplingState := &samplingState{}
if sampled {
- flags = flagSampled
+ samplingState.setSampled()
}
+
return SpanContext{
- traceID: traceID,
- spanID: spanID,
- parentID: parentID,
- flags: flags,
- baggage: baggage}
+ traceID: traceID,
+ spanID: spanID,
+ parentID: parentID,
+ samplingState: samplingState,
+ baggage: baggage}
}
// CopyFrom copies data from ctx into this context, including span identity and baggage.
@@ -169,7 +288,7 @@ func (c *SpanContext) CopyFrom(ctx *SpanContext) {
c.traceID = ctx.traceID
c.spanID = ctx.spanID
c.parentID = ctx.parentID
- c.flags = ctx.flags
+ c.samplingState = ctx.samplingState
if l := len(ctx.baggage); l > 0 {
c.baggage = make(map[string]string, l)
for k, v := range ctx.baggage {
@@ -193,7 +312,7 @@ func (c SpanContext) WithBaggageItem(key, value string) SpanContext {
newBaggage[key] = value
}
// Use positional parameters so the compiler will help catch new fields.
- return SpanContext{c.traceID, c.spanID, c.parentID, c.flags, newBaggage, ""}
+ return SpanContext{c.traceID, c.spanID, c.parentID, newBaggage, "", c.samplingState, c.remote}
}
// isDebugIDContainerOnly returns true when the instance of the context is only
diff --git a/vendor/github.com/uber/jaeger-client-go/tracer.go b/vendor/github.com/uber/jaeger-client-go/tracer.go
index 745a0c38a..f03372dc7 100644
--- a/vendor/github.com/uber/jaeger-client-go/tracer.go
+++ b/vendor/github.com/uber/jaeger-client-go/tracer.go
@@ -38,7 +38,7 @@ type Tracer struct {
serviceName string
hostIPv4 uint32 // this is for zipkin endpoint conversion
- sampler Sampler
+ sampler SamplerV2
reporter Reporter
metrics Metrics
logger log.Logger
@@ -74,6 +74,7 @@ type Tracer struct {
// NewTracer creates Tracer implementation that reports tracing to Jaeger.
// The returned io.Closer can be used in shutdown hooks to ensure that the internal
// queue of the Reporter is drained and all buffered spans are submitted to collectors.
+// TODO (breaking change) return *Tracer only, without closer.
func NewTracer(
serviceName string,
sampler Sampler,
@@ -82,7 +83,7 @@ func NewTracer(
) (opentracing.Tracer, io.Closer) {
t := &Tracer{
serviceName: serviceName,
- sampler: sampler,
+ sampler: samplerV1toV2(sampler),
reporter: reporter,
injectors: make(map[interface{}]Injector),
extractors: make(map[interface{}]Extractor),
@@ -261,7 +262,7 @@ func (t *Tracer) startSpanWithOptions(
rpcServer = (v == ext.SpanKindRPCServerEnum || v == string(ext.SpanKindRPCServerEnum))
}
- var samplerTags []Tag
+ var internalTags []Tag
newTrace := false
if !isSelfRef {
if !hasParent || !parent.IsValid() {
@@ -272,13 +273,12 @@ func (t *Tracer) startSpanWithOptions(
}
ctx.spanID = SpanID(ctx.traceID.Low)
ctx.parentID = 0
- ctx.flags = byte(0)
+ ctx.samplingState = &samplingState{
+ localRootSpan: ctx.spanID,
+ }
if hasParent && parent.isDebugIDContainerOnly() && t.isDebugAllowed(operationName) {
- ctx.flags |= (flagSampled | flagDebug)
- samplerTags = []Tag{{key: JaegerDebugHeader, value: parent.debugID}}
- } else if sampled, tags := t.sampler.IsSampled(ctx.traceID, operationName); sampled {
- ctx.flags |= flagSampled
- samplerTags = tags
+ ctx.samplingState.setDebugAndSampled()
+ internalTags = append(internalTags, Tag{key: JaegerDebugHeader, value: parent.debugID})
}
} else {
ctx.traceID = parent.traceID
@@ -290,7 +290,11 @@ func (t *Tracer) startSpanWithOptions(
ctx.spanID = SpanID(t.randomID())
ctx.parentID = parent.spanID
}
- ctx.flags = parent.flags
+ ctx.samplingState = parent.samplingState
+ if parent.remote {
+ ctx.samplingState.setFinal()
+ ctx.samplingState.localRootSpan = ctx.spanID
+ }
}
if hasParent {
// copy baggage items
@@ -305,17 +309,30 @@ func (t *Tracer) startSpanWithOptions(
sp := t.newSpan()
sp.context = ctx
+ sp.tracer = t
+ sp.operationName = operationName
+ sp.startTime = options.StartTime
+ sp.duration = 0
+ sp.references = references
+ sp.firstInProcess = rpcServer || sp.context.parentID == 0
+
+ if !sp.isSamplingFinalized() {
+ decision := t.sampler.OnCreateSpan(sp)
+ sp.applySamplingDecision(decision, false)
+ }
sp.observer = t.observer.OnStartSpan(sp, operationName, options)
- return t.startSpanInternal(
- sp,
- operationName,
- options.StartTime,
- samplerTags,
- options.Tags,
- newTrace,
- rpcServer,
- references,
- )
+
+ if tagsTotalLength := len(options.Tags) + len(internalTags); tagsTotalLength > 0 {
+ if sp.tags == nil || cap(sp.tags) < tagsTotalLength {
+ sp.tags = make([]Tag, 0, tagsTotalLength)
+ }
+ sp.tags = append(sp.tags, internalTags...)
+ for k, v := range options.Tags {
+ sp.setTagInternal(k, v, false)
+ }
+ }
+ t.emitNewSpanMetrics(sp, newTrace)
+ return sp
}
// Inject implements Inject() method of opentracing.Tracer
@@ -340,6 +357,7 @@ func (t *Tracer) Extract(
if err != nil {
return nil, err // ensure returned spanCtx is nil
}
+ spanCtx.remote = true
return spanCtx, nil
}
return nil, opentracing.ErrUnsupportedFormat
@@ -350,10 +368,10 @@ func (t *Tracer) Close() error {
t.reporter.Close()
t.sampler.Close()
if mgr, ok := t.baggageRestrictionManager.(io.Closer); ok {
- mgr.Close()
+ _ = mgr.Close()
}
if throttler, ok := t.debugThrottler.(io.Closer); ok {
- throttler.Close()
+ _ = throttler.Close()
}
return nil
}
@@ -368,6 +386,7 @@ func (t *Tracer) Tags() []opentracing.Tag {
}
// getTag returns the value of specific tag, if not exists, return nil.
+// TODO only used by tests, move there.
func (t *Tracer) getTag(key string) (interface{}, bool) {
for _, tag := range t.tags {
if tag.key == key {
@@ -383,41 +402,21 @@ func (t *Tracer) newSpan() *Span {
return t.spanAllocator.Get()
}
-func (t *Tracer) startSpanInternal(
- sp *Span,
- operationName string,
- startTime time.Time,
- internalTags []Tag,
- tags opentracing.Tags,
- newTrace bool,
- rpcServer bool,
- references []Reference,
-) *Span {
- sp.tracer = t
- sp.operationName = operationName
- sp.startTime = startTime
- sp.duration = 0
- sp.references = references
- sp.firstInProcess = rpcServer || sp.context.parentID == 0
- if len(tags) > 0 || len(internalTags) > 0 {
- sp.tags = make([]Tag, len(internalTags), len(tags)+len(internalTags))
- copy(sp.tags, internalTags)
- for k, v := range tags {
- sp.observer.OnSetTag(k, v)
- if k == string(ext.SamplingPriority) && !setSamplingPriority(sp, v) {
- continue
- }
- sp.setTagNoLocking(k, v)
+// emitNewSpanMetrics generates metrics on the number of started spans and traces.
+// newTrace param: we cannot simply check for parentID==0 because in Zipkin model the
+// server-side RPC span has the exact same trace/span/parent IDs as the
+// calling client-side span, but obviously the server side span is
+// no longer a root span of the trace.
+func (t *Tracer) emitNewSpanMetrics(sp *Span, newTrace bool) {
+ if !sp.isSamplingFinalized() {
+ t.metrics.SpansStartedDelayedSampling.Inc(1)
+ if newTrace {
+ t.metrics.TracesStartedDelayedSampling.Inc(1)
}
- }
- // emit metrics
- if sp.context.IsSampled() {
+ // joining a trace is not possible, because sampling decision inherited from upstream is final
+ } else if sp.context.IsSampled() {
t.metrics.SpansStartedSampled.Inc(1)
if newTrace {
- // We cannot simply check for parentID==0 because in Zipkin model the
- // server-side RPC span has the exact same trace/span/parent IDs as the
- // calling client-side span, but obviously the server side span is
- // no longer a root span of the trace.
t.metrics.TracesStartedSampled.Inc(1)
} else if sp.firstInProcess {
t.metrics.TracesJoinedSampled.Inc(1)
@@ -430,15 +429,20 @@ func (t *Tracer) startSpanInternal(
t.metrics.TracesJoinedNotSampled.Inc(1)
}
}
- return sp
}
func (t *Tracer) reportSpan(sp *Span) {
- t.metrics.SpansFinished.Inc(1)
+ if !sp.isSamplingFinalized() {
+ t.metrics.SpansFinishedDelayedSampling.Inc(1)
+ } else if sp.context.IsSampled() {
+ t.metrics.SpansFinishedSampled.Inc(1)
+ } else {
+ t.metrics.SpansFinishedNotSampled.Inc(1)
+ }
- // Note: if the reporter is processing Span asynchronously need to Retain() it
- // otherwise, in the racing condition will be rewritten span data before it will be sent
- // * To remove object use method span.Release()
+ // Note: if the reporter is processing Span asynchronously then it needs to Retain() the span,
+ // and then Release() it when no longer needed.
+ // Otherwise, the span may be reused for another trace and its data may be overwritten.
if sp.context.IsSampled() {
t.reporter.Report(sp)
}
@@ -466,6 +470,11 @@ func (t *Tracer) isDebugAllowed(operation string) bool {
return t.debugThrottler.IsAllowed(operation)
}
+// Sampler returns the sampler given to the tracer at creation.
+func (t *Tracer) Sampler() SamplerV2 {
+ return t.sampler
+}
+
// SelfRef creates an opentracing compliant SpanReference from a jaeger
// SpanContext. This is a factory function in order to encapsulate jaeger specific
// types.
diff --git a/vendor/github.com/uber/jaeger-client-go/utils/rate_limiter.go b/vendor/github.com/uber/jaeger-client-go/utils/rate_limiter.go
index 1b8db9758..bf2f13165 100644
--- a/vendor/github.com/uber/jaeger-client-go/utils/rate_limiter.go
+++ b/vendor/github.com/uber/jaeger-client-go/utils/rate_limiter.go
@@ -20,22 +20,15 @@ import (
)
// RateLimiter is a filter used to check if a message that is worth itemCost units is within the rate limits.
+//
+// TODO (breaking change) remove this interface in favor of public struct below
+//
+// Deprecated, use ReconfigurableRateLimiter.
type RateLimiter interface {
CheckCredit(itemCost float64) bool
}
-type rateLimiter struct {
- sync.Mutex
-
- creditsPerSecond float64
- balance float64
- maxBalance float64
- lastTick time.Time
-
- timeNow func() time.Time
-}
-
-// NewRateLimiter creates a new rate limiter based on leaky bucket algorithm, formulated in terms of a
+// ReconfigurableRateLimiter is a rate limiter based on leaky bucket algorithm, formulated in terms of a
// credits balance that is replenished every time CheckCredit() method is called (tick) by the amount proportional
// to the time elapsed since the last tick, up to max of creditsPerSecond. A call to CheckCredit() takes a cost
// of an item we want to pay with the balance. If the balance exceeds the cost of the item, the item is "purchased"
@@ -47,31 +40,73 @@ type rateLimiter struct {
//
// It can also be used to limit the rate of traffic in bytes, by setting creditsPerSecond to desired throughput
// as bytes/second, and calling CheckCredit() with the actual message size.
-func NewRateLimiter(creditsPerSecond, maxBalance float64) RateLimiter {
- return &rateLimiter{
+//
+// TODO (breaking change) rename to RateLimiter once the interface is removed
+type ReconfigurableRateLimiter struct {
+ lock sync.Mutex
+
+ creditsPerSecond float64
+ balance float64
+ maxBalance float64
+ lastTick time.Time
+
+ timeNow func() time.Time
+}
+
+// NewRateLimiter creates a new ReconfigurableRateLimiter.
+func NewRateLimiter(creditsPerSecond, maxBalance float64) *ReconfigurableRateLimiter {
+ return &ReconfigurableRateLimiter{
creditsPerSecond: creditsPerSecond,
balance: maxBalance,
maxBalance: maxBalance,
lastTick: time.Now(),
- timeNow: time.Now}
+ timeNow: time.Now,
+ }
}
-func (b *rateLimiter) CheckCredit(itemCost float64) bool {
- b.Lock()
- defer b.Unlock()
- // calculate how much time passed since the last tick, and update current tick
- currentTime := b.timeNow()
- elapsedTime := currentTime.Sub(b.lastTick)
- b.lastTick = currentTime
- // calculate how much credit have we accumulated since the last tick
- b.balance += elapsedTime.Seconds() * b.creditsPerSecond
- if b.balance > b.maxBalance {
- b.balance = b.maxBalance
- }
+// CheckCredit tries to reduce the current balance by itemCost provided that the current balance
+// is not lest than itemCost.
+func (rl *ReconfigurableRateLimiter) CheckCredit(itemCost float64) bool {
+ rl.lock.Lock()
+ defer rl.lock.Unlock()
+
// if we have enough credits to pay for current item, then reduce balance and allow
- if b.balance >= itemCost {
- b.balance -= itemCost
+ if rl.balance >= itemCost {
+ rl.balance -= itemCost
+ return true
+ }
+ // otherwise check if balance can be increased due to time elapsed, and try again
+ rl.updateBalance()
+ if rl.balance >= itemCost {
+ rl.balance -= itemCost
return true
}
return false
}
+
+// updateBalance recalculates current balance based on time elapsed. Must be called while holding a lock.
+func (rl *ReconfigurableRateLimiter) updateBalance() {
+ // calculate how much time passed since the last tick, and update current tick
+ currentTime := rl.timeNow()
+ elapsedTime := currentTime.Sub(rl.lastTick)
+ rl.lastTick = currentTime
+ // calculate how much credit have we accumulated since the last tick
+ rl.balance += elapsedTime.Seconds() * rl.creditsPerSecond
+ if rl.balance > rl.maxBalance {
+ rl.balance = rl.maxBalance
+ }
+}
+
+// Update changes the main parameters of the rate limiter in-place, while retaining
+// the current accumulated balance (pro-rated to the new maxBalance value). Using this method
+// instead of creating a new rate limiter helps to avoid thundering herd when sampling
+// strategies are updated.
+func (rl *ReconfigurableRateLimiter) Update(creditsPerSecond, maxBalance float64) {
+ rl.lock.Lock()
+ defer rl.lock.Unlock()
+
+ rl.updateBalance() // get up to date balance
+ rl.balance = rl.balance * maxBalance / rl.maxBalance
+ rl.creditsPerSecond = creditsPerSecond
+ rl.maxBalance = maxBalance
+}
diff --git a/vendor/github.com/uber/jaeger-client-go/zipkin.go b/vendor/github.com/uber/jaeger-client-go/zipkin.go
index 636952b7f..98cab4b6e 100644
--- a/vendor/github.com/uber/jaeger-client-go/zipkin.go
+++ b/vendor/github.com/uber/jaeger-client-go/zipkin.go
@@ -55,7 +55,7 @@ func (p *zipkinPropagator) Inject(
carrier.SetTraceID(ctx.TraceID().Low) // TODO this cannot work with 128bit IDs
carrier.SetSpanID(uint64(ctx.SpanID()))
carrier.SetParentID(uint64(ctx.ParentID()))
- carrier.SetFlags(ctx.flags)
+ carrier.SetFlags(ctx.samplingState.flags())
return nil
}
@@ -71,6 +71,7 @@ func (p *zipkinPropagator) Extract(abstractCarrier interface{}) (SpanContext, er
ctx.traceID.Low = carrier.TraceID()
ctx.spanID = SpanID(carrier.SpanID())
ctx.parentID = SpanID(carrier.ParentID())
- ctx.flags = carrier.Flags()
+ ctx.samplingState = &samplingState{}
+ ctx.samplingState.setFlags(carrier.Flags())
return ctx, nil
}
diff --git a/vendor/go.uber.org/atomic/.codecov.yml b/vendor/go.uber.org/atomic/.codecov.yml
new file mode 100644
index 000000000..6d4d1be7b
--- /dev/null
+++ b/vendor/go.uber.org/atomic/.codecov.yml
@@ -0,0 +1,15 @@
+coverage:
+ range: 80..100
+ round: down
+ precision: 2
+
+ status:
+ project: # measuring the overall project coverage
+ default: # context, you can create multiple ones with custom titles
+ enabled: yes # must be yes|true to enable this status
+ target: 100 # specify the target coverage for each commit status
+ # option: "auto" (must increase from parent commit or pull request base)
+ # option: "X%" a static target percentage to hit
+ if_not_found: success # if parent is not found report status as success, error, or failure
+ if_ci_failed: error # if ci fails report status as success, error, or failure
+
diff --git a/vendor/go.uber.org/atomic/.gitignore b/vendor/go.uber.org/atomic/.gitignore
new file mode 100644
index 000000000..0a4504f11
--- /dev/null
+++ b/vendor/go.uber.org/atomic/.gitignore
@@ -0,0 +1,11 @@
+.DS_Store
+/vendor
+/cover
+cover.out
+lint.log
+
+# Binaries
+*.test
+
+# Profiling output
+*.prof
diff --git a/vendor/go.uber.org/atomic/.travis.yml b/vendor/go.uber.org/atomic/.travis.yml
new file mode 100644
index 000000000..0f3769e5f
--- /dev/null
+++ b/vendor/go.uber.org/atomic/.travis.yml
@@ -0,0 +1,27 @@
+sudo: false
+language: go
+go_import_path: go.uber.org/atomic
+
+go:
+ - 1.11.x
+ - 1.12.x
+
+matrix:
+ include:
+ - go: 1.12.x
+ env: NO_TEST=yes LINT=yes
+
+cache:
+ directories:
+ - vendor
+
+install:
+ - make install_ci
+
+script:
+ - test -n "$NO_TEST" || make test_ci
+ - test -n "$NO_TEST" || scripts/test-ubergo.sh
+ - test -z "$LINT" || make install_lint lint
+
+after_success:
+ - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/go.uber.org/atomic/LICENSE.txt b/vendor/go.uber.org/atomic/LICENSE.txt
new file mode 100644
index 000000000..8765c9fbc
--- /dev/null
+++ b/vendor/go.uber.org/atomic/LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright (c) 2016 Uber Technologies, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/go.uber.org/atomic/Makefile b/vendor/go.uber.org/atomic/Makefile
new file mode 100644
index 000000000..1ef263075
--- /dev/null
+++ b/vendor/go.uber.org/atomic/Makefile
@@ -0,0 +1,51 @@
+# Many Go tools take file globs or directories as arguments instead of packages.
+PACKAGE_FILES ?= *.go
+
+# For pre go1.6
+export GO15VENDOREXPERIMENT=1
+
+
+.PHONY: build
+build:
+ go build -i ./...
+
+
+.PHONY: install
+install:
+ glide --version || go get github.com/Masterminds/glide
+ glide install
+
+
+.PHONY: test
+test:
+ go test -cover -race ./...
+
+
+.PHONY: install_ci
+install_ci: install
+ go get github.com/wadey/gocovmerge
+ go get github.com/mattn/goveralls
+ go get golang.org/x/tools/cmd/cover
+
+.PHONY: install_lint
+install_lint:
+ go get golang.org/x/lint/golint
+
+
+.PHONY: lint
+lint:
+ @rm -rf lint.log
+ @echo "Checking formatting..."
+ @gofmt -d -s $(PACKAGE_FILES) 2>&1 | tee lint.log
+ @echo "Checking vet..."
+ @go vet ./... 2>&1 | tee -a lint.log;)
+ @echo "Checking lint..."
+ @golint $$(go list ./...) 2>&1 | tee -a lint.log
+ @echo "Checking for unresolved FIXMEs..."
+ @git grep -i fixme | grep -v -e vendor -e Makefile | tee -a lint.log
+ @[ ! -s lint.log ]
+
+
+.PHONY: test_ci
+test_ci: install_ci build
+ ./scripts/cover.sh $(shell go list $(PACKAGES))
diff --git a/vendor/go.uber.org/atomic/README.md b/vendor/go.uber.org/atomic/README.md
new file mode 100644
index 000000000..62eb8e576
--- /dev/null
+++ b/vendor/go.uber.org/atomic/README.md
@@ -0,0 +1,36 @@
+# atomic [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Go Report Card][reportcard-img]][reportcard]
+
+Simple wrappers for primitive types to enforce atomic access.
+
+## Installation
+`go get -u go.uber.org/atomic`
+
+## Usage
+The standard library's `sync/atomic` is powerful, but it's easy to forget which
+variables must be accessed atomically. `go.uber.org/atomic` preserves all the
+functionality of the standard library, but wraps the primitive types to
+provide a safer, more convenient API.
+
+```go
+var atom atomic.Uint32
+atom.Store(42)
+atom.Sub(2)
+atom.CAS(40, 11)
+```
+
+See the [documentation][doc] for a complete API specification.
+
+## Development Status
+Stable.
+
+___
+Released under the [MIT License](LICENSE.txt).
+
+[doc-img]: https://godoc.org/github.com/uber-go/atomic?status.svg
+[doc]: https://godoc.org/go.uber.org/atomic
+[ci-img]: https://travis-ci.com/uber-go/atomic.svg?branch=master
+[ci]: https://travis-ci.com/uber-go/atomic
+[cov-img]: https://codecov.io/gh/uber-go/atomic/branch/master/graph/badge.svg
+[cov]: https://codecov.io/gh/uber-go/atomic
+[reportcard-img]: https://goreportcard.com/badge/go.uber.org/atomic
+[reportcard]: https://goreportcard.com/report/go.uber.org/atomic
diff --git a/vendor/go.uber.org/atomic/atomic.go b/vendor/go.uber.org/atomic/atomic.go
new file mode 100644
index 000000000..1db6849fc
--- /dev/null
+++ b/vendor/go.uber.org/atomic/atomic.go
@@ -0,0 +1,351 @@
+// Copyright (c) 2016 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// Package atomic provides simple wrappers around numerics to enforce atomic
+// access.
+package atomic
+
+import (
+ "math"
+ "sync/atomic"
+ "time"
+)
+
+// Int32 is an atomic wrapper around an int32.
+type Int32 struct{ v int32 }
+
+// NewInt32 creates an Int32.
+func NewInt32(i int32) *Int32 {
+ return &Int32{i}
+}
+
+// Load atomically loads the wrapped value.
+func (i *Int32) Load() int32 {
+ return atomic.LoadInt32(&i.v)
+}
+
+// Add atomically adds to the wrapped int32 and returns the new value.
+func (i *Int32) Add(n int32) int32 {
+ return atomic.AddInt32(&i.v, n)
+}
+
+// Sub atomically subtracts from the wrapped int32 and returns the new value.
+func (i *Int32) Sub(n int32) int32 {
+ return atomic.AddInt32(&i.v, -n)
+}
+
+// Inc atomically increments the wrapped int32 and returns the new value.
+func (i *Int32) Inc() int32 {
+ return i.Add(1)
+}
+
+// Dec atomically decrements the wrapped int32 and returns the new value.
+func (i *Int32) Dec() int32 {
+ return i.Sub(1)
+}
+
+// CAS is an atomic compare-and-swap.
+func (i *Int32) CAS(old, new int32) bool {
+ return atomic.CompareAndSwapInt32(&i.v, old, new)
+}
+
+// Store atomically stores the passed value.
+func (i *Int32) Store(n int32) {
+ atomic.StoreInt32(&i.v, n)
+}
+
+// Swap atomically swaps the wrapped int32 and returns the old value.
+func (i *Int32) Swap(n int32) int32 {
+ return atomic.SwapInt32(&i.v, n)
+}
+
+// Int64 is an atomic wrapper around an int64.
+type Int64 struct{ v int64 }
+
+// NewInt64 creates an Int64.
+func NewInt64(i int64) *Int64 {
+ return &Int64{i}
+}
+
+// Load atomically loads the wrapped value.
+func (i *Int64) Load() int64 {
+ return atomic.LoadInt64(&i.v)
+}
+
+// Add atomically adds to the wrapped int64 and returns the new value.
+func (i *Int64) Add(n int64) int64 {
+ return atomic.AddInt64(&i.v, n)
+}
+
+// Sub atomically subtracts from the wrapped int64 and returns the new value.
+func (i *Int64) Sub(n int64) int64 {
+ return atomic.AddInt64(&i.v, -n)
+}
+
+// Inc atomically increments the wrapped int64 and returns the new value.
+func (i *Int64) Inc() int64 {
+ return i.Add(1)
+}
+
+// Dec atomically decrements the wrapped int64 and returns the new value.
+func (i *Int64) Dec() int64 {
+ return i.Sub(1)
+}
+
+// CAS is an atomic compare-and-swap.
+func (i *Int64) CAS(old, new int64) bool {
+ return atomic.CompareAndSwapInt64(&i.v, old, new)
+}
+
+// Store atomically stores the passed value.
+func (i *Int64) Store(n int64) {
+ atomic.StoreInt64(&i.v, n)
+}
+
+// Swap atomically swaps the wrapped int64 and returns the old value.
+func (i *Int64) Swap(n int64) int64 {
+ return atomic.SwapInt64(&i.v, n)
+}
+
+// Uint32 is an atomic wrapper around an uint32.
+type Uint32 struct{ v uint32 }
+
+// NewUint32 creates a Uint32.
+func NewUint32(i uint32) *Uint32 {
+ return &Uint32{i}
+}
+
+// Load atomically loads the wrapped value.
+func (i *Uint32) Load() uint32 {
+ return atomic.LoadUint32(&i.v)
+}
+
+// Add atomically adds to the wrapped uint32 and returns the new value.
+func (i *Uint32) Add(n uint32) uint32 {
+ return atomic.AddUint32(&i.v, n)
+}
+
+// Sub atomically subtracts from the wrapped uint32 and returns the new value.
+func (i *Uint32) Sub(n uint32) uint32 {
+ return atomic.AddUint32(&i.v, ^(n - 1))
+}
+
+// Inc atomically increments the wrapped uint32 and returns the new value.
+func (i *Uint32) Inc() uint32 {
+ return i.Add(1)
+}
+
+// Dec atomically decrements the wrapped int32 and returns the new value.
+func (i *Uint32) Dec() uint32 {
+ return i.Sub(1)
+}
+
+// CAS is an atomic compare-and-swap.
+func (i *Uint32) CAS(old, new uint32) bool {
+ return atomic.CompareAndSwapUint32(&i.v, old, new)
+}
+
+// Store atomically stores the passed value.
+func (i *Uint32) Store(n uint32) {
+ atomic.StoreUint32(&i.v, n)
+}
+
+// Swap atomically swaps the wrapped uint32 and returns the old value.
+func (i *Uint32) Swap(n uint32) uint32 {
+ return atomic.SwapUint32(&i.v, n)
+}
+
+// Uint64 is an atomic wrapper around a uint64.
+type Uint64 struct{ v uint64 }
+
+// NewUint64 creates a Uint64.
+func NewUint64(i uint64) *Uint64 {
+ return &Uint64{i}
+}
+
+// Load atomically loads the wrapped value.
+func (i *Uint64) Load() uint64 {
+ return atomic.LoadUint64(&i.v)
+}
+
+// Add atomically adds to the wrapped uint64 and returns the new value.
+func (i *Uint64) Add(n uint64) uint64 {
+ return atomic.AddUint64(&i.v, n)
+}
+
+// Sub atomically subtracts from the wrapped uint64 and returns the new value.
+func (i *Uint64) Sub(n uint64) uint64 {
+ return atomic.AddUint64(&i.v, ^(n - 1))
+}
+
+// Inc atomically increments the wrapped uint64 and returns the new value.
+func (i *Uint64) Inc() uint64 {
+ return i.Add(1)
+}
+
+// Dec atomically decrements the wrapped uint64 and returns the new value.
+func (i *Uint64) Dec() uint64 {
+ return i.Sub(1)
+}
+
+// CAS is an atomic compare-and-swap.
+func (i *Uint64) CAS(old, new uint64) bool {
+ return atomic.CompareAndSwapUint64(&i.v, old, new)
+}
+
+// Store atomically stores the passed value.
+func (i *Uint64) Store(n uint64) {
+ atomic.StoreUint64(&i.v, n)
+}
+
+// Swap atomically swaps the wrapped uint64 and returns the old value.
+func (i *Uint64) Swap(n uint64) uint64 {
+ return atomic.SwapUint64(&i.v, n)
+}
+
+// Bool is an atomic Boolean.
+type Bool struct{ v uint32 }
+
+// NewBool creates a Bool.
+func NewBool(initial bool) *Bool {
+ return &Bool{boolToInt(initial)}
+}
+
+// Load atomically loads the Boolean.
+func (b *Bool) Load() bool {
+ return truthy(atomic.LoadUint32(&b.v))
+}
+
+// CAS is an atomic compare-and-swap.
+func (b *Bool) CAS(old, new bool) bool {
+ return atomic.CompareAndSwapUint32(&b.v, boolToInt(old), boolToInt(new))
+}
+
+// Store atomically stores the passed value.
+func (b *Bool) Store(new bool) {
+ atomic.StoreUint32(&b.v, boolToInt(new))
+}
+
+// Swap sets the given value and returns the previous value.
+func (b *Bool) Swap(new bool) bool {
+ return truthy(atomic.SwapUint32(&b.v, boolToInt(new)))
+}
+
+// Toggle atomically negates the Boolean and returns the previous value.
+func (b *Bool) Toggle() bool {
+ return truthy(atomic.AddUint32(&b.v, 1) - 1)
+}
+
+func truthy(n uint32) bool {
+ return n&1 == 1
+}
+
+func boolToInt(b bool) uint32 {
+ if b {
+ return 1
+ }
+ return 0
+}
+
+// Float64 is an atomic wrapper around float64.
+type Float64 struct {
+ v uint64
+}
+
+// NewFloat64 creates a Float64.
+func NewFloat64(f float64) *Float64 {
+ return &Float64{math.Float64bits(f)}
+}
+
+// Load atomically loads the wrapped value.
+func (f *Float64) Load() float64 {
+ return math.Float64frombits(atomic.LoadUint64(&f.v))
+}
+
+// Store atomically stores the passed value.
+func (f *Float64) Store(s float64) {
+ atomic.StoreUint64(&f.v, math.Float64bits(s))
+}
+
+// Add atomically adds to the wrapped float64 and returns the new value.
+func (f *Float64) Add(s float64) float64 {
+ for {
+ old := f.Load()
+ new := old + s
+ if f.CAS(old, new) {
+ return new
+ }
+ }
+}
+
+// Sub atomically subtracts from the wrapped float64 and returns the new value.
+func (f *Float64) Sub(s float64) float64 {
+ return f.Add(-s)
+}
+
+// CAS is an atomic compare-and-swap.
+func (f *Float64) CAS(old, new float64) bool {
+ return atomic.CompareAndSwapUint64(&f.v, math.Float64bits(old), math.Float64bits(new))
+}
+
+// Duration is an atomic wrapper around time.Duration
+// https://godoc.org/time#Duration
+type Duration struct {
+ v Int64
+}
+
+// NewDuration creates a Duration.
+func NewDuration(d time.Duration) *Duration {
+ return &Duration{v: *NewInt64(int64(d))}
+}
+
+// Load atomically loads the wrapped value.
+func (d *Duration) Load() time.Duration {
+ return time.Duration(d.v.Load())
+}
+
+// Store atomically stores the passed value.
+func (d *Duration) Store(n time.Duration) {
+ d.v.Store(int64(n))
+}
+
+// Add atomically adds to the wrapped time.Duration and returns the new value.
+func (d *Duration) Add(n time.Duration) time.Duration {
+ return time.Duration(d.v.Add(int64(n)))
+}
+
+// Sub atomically subtracts from the wrapped time.Duration and returns the new value.
+func (d *Duration) Sub(n time.Duration) time.Duration {
+ return time.Duration(d.v.Sub(int64(n)))
+}
+
+// Swap atomically swaps the wrapped time.Duration and returns the old value.
+func (d *Duration) Swap(n time.Duration) time.Duration {
+ return time.Duration(d.v.Swap(int64(n)))
+}
+
+// CAS is an atomic compare-and-swap.
+func (d *Duration) CAS(old, new time.Duration) bool {
+ return d.v.CAS(int64(old), int64(new))
+}
+
+// Value shadows the type of the same name from sync/atomic
+// https://godoc.org/sync/atomic#Value
+type Value struct{ atomic.Value }
diff --git a/vendor/go.uber.org/atomic/error.go b/vendor/go.uber.org/atomic/error.go
new file mode 100644
index 000000000..0489d19ba
--- /dev/null
+++ b/vendor/go.uber.org/atomic/error.go
@@ -0,0 +1,55 @@
+// Copyright (c) 2016 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+// Error is an atomic type-safe wrapper around Value for errors
+type Error struct{ v Value }
+
+// errorHolder is non-nil holder for error object.
+// atomic.Value panics on saving nil object, so err object needs to be
+// wrapped with valid object first.
+type errorHolder struct{ err error }
+
+// NewError creates new atomic error object
+func NewError(err error) *Error {
+ e := &Error{}
+ if err != nil {
+ e.Store(err)
+ }
+ return e
+}
+
+// Load atomically loads the wrapped error
+func (e *Error) Load() error {
+ v := e.v.Load()
+ if v == nil {
+ return nil
+ }
+
+ eh := v.(errorHolder)
+ return eh.err
+}
+
+// Store atomically stores error.
+// NOTE: a holder object is allocated on each Store call.
+func (e *Error) Store(err error) {
+ e.v.Store(errorHolder{err: err})
+}
diff --git a/vendor/go.uber.org/atomic/glide.lock b/vendor/go.uber.org/atomic/glide.lock
new file mode 100644
index 000000000..3c72c5997
--- /dev/null
+++ b/vendor/go.uber.org/atomic/glide.lock
@@ -0,0 +1,17 @@
+hash: f14d51408e3e0e4f73b34e4039484c78059cd7fc5f4996fdd73db20dc8d24f53
+updated: 2016-10-27T00:10:51.16960137-07:00
+imports: []
+testImports:
+- name: github.com/davecgh/go-spew
+ version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
+ subpackages:
+ - spew
+- name: github.com/pmezard/go-difflib
+ version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
+ subpackages:
+ - difflib
+- name: github.com/stretchr/testify
+ version: d77da356e56a7428ad25149ca77381849a6a5232
+ subpackages:
+ - assert
+ - require
diff --git a/vendor/go.uber.org/atomic/glide.yaml b/vendor/go.uber.org/atomic/glide.yaml
new file mode 100644
index 000000000..4cf608ec0
--- /dev/null
+++ b/vendor/go.uber.org/atomic/glide.yaml
@@ -0,0 +1,6 @@
+package: go.uber.org/atomic
+testImport:
+- package: github.com/stretchr/testify
+ subpackages:
+ - assert
+ - require
diff --git a/vendor/go.uber.org/atomic/string.go b/vendor/go.uber.org/atomic/string.go
new file mode 100644
index 000000000..ede8136fa
--- /dev/null
+++ b/vendor/go.uber.org/atomic/string.go
@@ -0,0 +1,49 @@
+// Copyright (c) 2016 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+// String is an atomic type-safe wrapper around Value for strings.
+type String struct{ v Value }
+
+// NewString creates a String.
+func NewString(str string) *String {
+ s := &String{}
+ if str != "" {
+ s.Store(str)
+ }
+ return s
+}
+
+// Load atomically loads the wrapped string.
+func (s *String) Load() string {
+ v := s.v.Load()
+ if v == nil {
+ return ""
+ }
+ return v.(string)
+}
+
+// Store atomically stores the passed string.
+// Note: Converting the string to an interface{} to store in the Value
+// requires an allocation.
+func (s *String) Store(str string) {
+ s.v.Store(str)
+}
diff --git a/vendor/golang.org/x/sys/windows/registry/key.go b/vendor/golang.org/x/sys/windows/registry/key.go
deleted file mode 100644
index c25648343..000000000
--- a/vendor/golang.org/x/sys/windows/registry/key.go
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build windows
-
-// Package registry provides access to the Windows registry.
-//
-// Here is a simple example, opening a registry key and reading a string value from it.
-//
-// k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
-// if err != nil {
-// log.Fatal(err)
-// }
-// defer k.Close()
-//
-// s, _, err := k.GetStringValue("SystemRoot")
-// if err != nil {
-// log.Fatal(err)
-// }
-// fmt.Printf("Windows system root is %q\n", s)
-//
-package registry
-
-import (
- "io"
- "syscall"
- "time"
-)
-
-const (
- // Registry key security and access rights.
- // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724878.aspx
- // for details.
- ALL_ACCESS = 0xf003f
- CREATE_LINK = 0x00020
- CREATE_SUB_KEY = 0x00004
- ENUMERATE_SUB_KEYS = 0x00008
- EXECUTE = 0x20019
- NOTIFY = 0x00010
- QUERY_VALUE = 0x00001
- READ = 0x20019
- SET_VALUE = 0x00002
- WOW64_32KEY = 0x00200
- WOW64_64KEY = 0x00100
- WRITE = 0x20006
-)
-
-// Key is a handle to an open Windows registry key.
-// Keys can be obtained by calling OpenKey; there are
-// also some predefined root keys such as CURRENT_USER.
-// Keys can be used directly in the Windows API.
-type Key syscall.Handle
-
-const (
- // Windows defines some predefined root keys that are always open.
- // An application can use these keys as entry points to the registry.
- // Normally these keys are used in OpenKey to open new keys,
- // but they can also be used anywhere a Key is required.
- CLASSES_ROOT = Key(syscall.HKEY_CLASSES_ROOT)
- CURRENT_USER = Key(syscall.HKEY_CURRENT_USER)
- LOCAL_MACHINE = Key(syscall.HKEY_LOCAL_MACHINE)
- USERS = Key(syscall.HKEY_USERS)
- CURRENT_CONFIG = Key(syscall.HKEY_CURRENT_CONFIG)
- PERFORMANCE_DATA = Key(syscall.HKEY_PERFORMANCE_DATA)
-)
-
-// Close closes open key k.
-func (k Key) Close() error {
- return syscall.RegCloseKey(syscall.Handle(k))
-}
-
-// OpenKey opens a new key with path name relative to key k.
-// It accepts any open key, including CURRENT_USER and others,
-// and returns the new key and an error.
-// The access parameter specifies desired access rights to the
-// key to be opened.
-func OpenKey(k Key, path string, access uint32) (Key, error) {
- p, err := syscall.UTF16PtrFromString(path)
- if err != nil {
- return 0, err
- }
- var subkey syscall.Handle
- err = syscall.RegOpenKeyEx(syscall.Handle(k), p, 0, access, &subkey)
- if err != nil {
- return 0, err
- }
- return Key(subkey), nil
-}
-
-// OpenRemoteKey opens a predefined registry key on another
-// computer pcname. The key to be opened is specified by k, but
-// can only be one of LOCAL_MACHINE, PERFORMANCE_DATA or USERS.
-// If pcname is "", OpenRemoteKey returns local computer key.
-func OpenRemoteKey(pcname string, k Key) (Key, error) {
- var err error
- var p *uint16
- if pcname != "" {
- p, err = syscall.UTF16PtrFromString(`\\` + pcname)
- if err != nil {
- return 0, err
- }
- }
- var remoteKey syscall.Handle
- err = regConnectRegistry(p, syscall.Handle(k), &remoteKey)
- if err != nil {
- return 0, err
- }
- return Key(remoteKey), nil
-}
-
-// ReadSubKeyNames returns the names of subkeys of key k.
-// The parameter n controls the number of returned names,
-// analogous to the way os.File.Readdirnames works.
-func (k Key) ReadSubKeyNames(n int) ([]string, error) {
- names := make([]string, 0)
- // Registry key size limit is 255 bytes and described there:
- // https://msdn.microsoft.com/library/windows/desktop/ms724872.aspx
- buf := make([]uint16, 256) //plus extra room for terminating zero byte
-loopItems:
- for i := uint32(0); ; i++ {
- if n > 0 {
- if len(names) == n {
- return names, nil
- }
- }
- l := uint32(len(buf))
- for {
- err := syscall.RegEnumKeyEx(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
- if err == nil {
- break
- }
- if err == syscall.ERROR_MORE_DATA {
- // Double buffer size and try again.
- l = uint32(2 * len(buf))
- buf = make([]uint16, l)
- continue
- }
- if err == _ERROR_NO_MORE_ITEMS {
- break loopItems
- }
- return names, err
- }
- names = append(names, syscall.UTF16ToString(buf[:l]))
- }
- if n > len(names) {
- return names, io.EOF
- }
- return names, nil
-}
-
-// CreateKey creates a key named path under open key k.
-// CreateKey returns the new key and a boolean flag that reports
-// whether the key already existed.
-// The access parameter specifies the access rights for the key
-// to be created.
-func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool, err error) {
- var h syscall.Handle
- var d uint32
- err = regCreateKeyEx(syscall.Handle(k), syscall.StringToUTF16Ptr(path),
- 0, nil, _REG_OPTION_NON_VOLATILE, access, nil, &h, &d)
- if err != nil {
- return 0, false, err
- }
- return Key(h), d == _REG_OPENED_EXISTING_KEY, nil
-}
-
-// DeleteKey deletes the subkey path of key k and its values.
-func DeleteKey(k Key, path string) error {
- return regDeleteKey(syscall.Handle(k), syscall.StringToUTF16Ptr(path))
-}
-
-// A KeyInfo describes the statistics of a key. It is returned by Stat.
-type KeyInfo struct {
- SubKeyCount uint32
- MaxSubKeyLen uint32 // size of the key's subkey with the longest name, in Unicode characters, not including the terminating zero byte
- ValueCount uint32
- MaxValueNameLen uint32 // size of the key's longest value name, in Unicode characters, not including the terminating zero byte
- MaxValueLen uint32 // longest data component among the key's values, in bytes
- lastWriteTime syscall.Filetime
-}
-
-// ModTime returns the key's last write time.
-func (ki *KeyInfo) ModTime() time.Time {
- return time.Unix(0, ki.lastWriteTime.Nanoseconds())
-}
-
-// Stat retrieves information about the open key k.
-func (k Key) Stat() (*KeyInfo, error) {
- var ki KeyInfo
- err := syscall.RegQueryInfoKey(syscall.Handle(k), nil, nil, nil,
- &ki.SubKeyCount, &ki.MaxSubKeyLen, nil, &ki.ValueCount,
- &ki.MaxValueNameLen, &ki.MaxValueLen, nil, &ki.lastWriteTime)
- if err != nil {
- return nil, err
- }
- return &ki, nil
-}
diff --git a/vendor/golang.org/x/sys/windows/registry/mksyscall.go b/vendor/golang.org/x/sys/windows/registry/mksyscall.go
deleted file mode 100644
index cf843ce2b..000000000
--- a/vendor/golang.org/x/sys/windows/registry/mksyscall.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build generate
-
-package registry
-
-//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall.go
diff --git a/vendor/golang.org/x/sys/windows/registry/syscall.go b/vendor/golang.org/x/sys/windows/registry/syscall.go
deleted file mode 100644
index e66643cba..000000000
--- a/vendor/golang.org/x/sys/windows/registry/syscall.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build windows
-
-package registry
-
-import "syscall"
-
-const (
- _REG_OPTION_NON_VOLATILE = 0
-
- _REG_CREATED_NEW_KEY = 1
- _REG_OPENED_EXISTING_KEY = 2
-
- _ERROR_NO_MORE_ITEMS syscall.Errno = 259
-)
-
-func LoadRegLoadMUIString() error {
- return procRegLoadMUIStringW.Find()
-}
-
-//sys regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) = advapi32.RegCreateKeyExW
-//sys regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) = advapi32.RegDeleteKeyW
-//sys regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) = advapi32.RegSetValueExW
-//sys regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegEnumValueW
-//sys regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) = advapi32.RegDeleteValueW
-//sys regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) = advapi32.RegLoadMUIStringW
-//sys regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) = advapi32.RegConnectRegistryW
-
-//sys expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) = kernel32.ExpandEnvironmentStringsW
diff --git a/vendor/golang.org/x/sys/windows/registry/value.go b/vendor/golang.org/x/sys/windows/registry/value.go
deleted file mode 100644
index 7487e05f8..000000000
--- a/vendor/golang.org/x/sys/windows/registry/value.go
+++ /dev/null
@@ -1,387 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build windows
-
-package registry
-
-import (
- "errors"
- "io"
- "syscall"
- "unicode/utf16"
- "unsafe"
-)
-
-const (
- // Registry value types.
- NONE = 0
- SZ = 1
- EXPAND_SZ = 2
- BINARY = 3
- DWORD = 4
- DWORD_BIG_ENDIAN = 5
- LINK = 6
- MULTI_SZ = 7
- RESOURCE_LIST = 8
- FULL_RESOURCE_DESCRIPTOR = 9
- RESOURCE_REQUIREMENTS_LIST = 10
- QWORD = 11
-)
-
-var (
- // ErrShortBuffer is returned when the buffer was too short for the operation.
- ErrShortBuffer = syscall.ERROR_MORE_DATA
-
- // ErrNotExist is returned when a registry key or value does not exist.
- ErrNotExist = syscall.ERROR_FILE_NOT_FOUND
-
- // ErrUnexpectedType is returned by Get*Value when the value's type was unexpected.
- ErrUnexpectedType = errors.New("unexpected key value type")
-)
-
-// GetValue retrieves the type and data for the specified value associated
-// with an open key k. It fills up buffer buf and returns the retrieved
-// byte count n. If buf is too small to fit the stored value it returns
-// ErrShortBuffer error along with the required buffer size n.
-// If no buffer is provided, it returns true and actual buffer size n.
-// If no buffer is provided, GetValue returns the value's type only.
-// If the value does not exist, the error returned is ErrNotExist.
-//
-// GetValue is a low level function. If value's type is known, use the appropriate
-// Get*Value function instead.
-func (k Key) GetValue(name string, buf []byte) (n int, valtype uint32, err error) {
- pname, err := syscall.UTF16PtrFromString(name)
- if err != nil {
- return 0, 0, err
- }
- var pbuf *byte
- if len(buf) > 0 {
- pbuf = (*byte)(unsafe.Pointer(&buf[0]))
- }
- l := uint32(len(buf))
- err = syscall.RegQueryValueEx(syscall.Handle(k), pname, nil, &valtype, pbuf, &l)
- if err != nil {
- return int(l), valtype, err
- }
- return int(l), valtype, nil
-}
-
-func (k Key) getValue(name string, buf []byte) (data []byte, valtype uint32, err error) {
- p, err := syscall.UTF16PtrFromString(name)
- if err != nil {
- return nil, 0, err
- }
- var t uint32
- n := uint32(len(buf))
- for {
- err = syscall.RegQueryValueEx(syscall.Handle(k), p, nil, &t, (*byte)(unsafe.Pointer(&buf[0])), &n)
- if err == nil {
- return buf[:n], t, nil
- }
- if err != syscall.ERROR_MORE_DATA {
- return nil, 0, err
- }
- if n <= uint32(len(buf)) {
- return nil, 0, err
- }
- buf = make([]byte, n)
- }
-}
-
-// GetStringValue retrieves the string value for the specified
-// value name associated with an open key k. It also returns the value's type.
-// If value does not exist, GetStringValue returns ErrNotExist.
-// If value is not SZ or EXPAND_SZ, it will return the correct value
-// type and ErrUnexpectedType.
-func (k Key) GetStringValue(name string) (val string, valtype uint32, err error) {
- data, typ, err2 := k.getValue(name, make([]byte, 64))
- if err2 != nil {
- return "", typ, err2
- }
- switch typ {
- case SZ, EXPAND_SZ:
- default:
- return "", typ, ErrUnexpectedType
- }
- if len(data) == 0 {
- return "", typ, nil
- }
- u := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:]
- return syscall.UTF16ToString(u), typ, nil
-}
-
-// GetMUIStringValue retrieves the localized string value for
-// the specified value name associated with an open key k.
-// If the value name doesn't exist or the localized string value
-// can't be resolved, GetMUIStringValue returns ErrNotExist.
-// GetMUIStringValue panics if the system doesn't support
-// regLoadMUIString; use LoadRegLoadMUIString to check if
-// regLoadMUIString is supported before calling this function.
-func (k Key) GetMUIStringValue(name string) (string, error) {
- pname, err := syscall.UTF16PtrFromString(name)
- if err != nil {
- return "", err
- }
-
- buf := make([]uint16, 1024)
- var buflen uint32
- var pdir *uint16
-
- err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
- if err == syscall.ERROR_FILE_NOT_FOUND { // Try fallback path
-
- // Try to resolve the string value using the system directory as
- // a DLL search path; this assumes the string value is of the form
- // @[path]\dllname,-strID but with no path given, e.g. @tzres.dll,-320.
-
- // This approach works with tzres.dll but may have to be revised
- // in the future to allow callers to provide custom search paths.
-
- var s string
- s, err = ExpandString("%SystemRoot%\\system32\\")
- if err != nil {
- return "", err
- }
- pdir, err = syscall.UTF16PtrFromString(s)
- if err != nil {
- return "", err
- }
-
- err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
- }
-
- for err == syscall.ERROR_MORE_DATA { // Grow buffer if needed
- if buflen <= uint32(len(buf)) {
- break // Buffer not growing, assume race; break
- }
- buf = make([]uint16, buflen)
- err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
- }
-
- if err != nil {
- return "", err
- }
-
- return syscall.UTF16ToString(buf), nil
-}
-
-// ExpandString expands environment-variable strings and replaces
-// them with the values defined for the current user.
-// Use ExpandString to expand EXPAND_SZ strings.
-func ExpandString(value string) (string, error) {
- if value == "" {
- return "", nil
- }
- p, err := syscall.UTF16PtrFromString(value)
- if err != nil {
- return "", err
- }
- r := make([]uint16, 100)
- for {
- n, err := expandEnvironmentStrings(p, &r[0], uint32(len(r)))
- if err != nil {
- return "", err
- }
- if n <= uint32(len(r)) {
- u := (*[1 << 29]uint16)(unsafe.Pointer(&r[0]))[:]
- return syscall.UTF16ToString(u), nil
- }
- r = make([]uint16, n)
- }
-}
-
-// GetStringsValue retrieves the []string value for the specified
-// value name associated with an open key k. It also returns the value's type.
-// If value does not exist, GetStringsValue returns ErrNotExist.
-// If value is not MULTI_SZ, it will return the correct value
-// type and ErrUnexpectedType.
-func (k Key) GetStringsValue(name string) (val []string, valtype uint32, err error) {
- data, typ, err2 := k.getValue(name, make([]byte, 64))
- if err2 != nil {
- return nil, typ, err2
- }
- if typ != MULTI_SZ {
- return nil, typ, ErrUnexpectedType
- }
- if len(data) == 0 {
- return nil, typ, nil
- }
- p := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:len(data)/2]
- if len(p) == 0 {
- return nil, typ, nil
- }
- if p[len(p)-1] == 0 {
- p = p[:len(p)-1] // remove terminating null
- }
- val = make([]string, 0, 5)
- from := 0
- for i, c := range p {
- if c == 0 {
- val = append(val, string(utf16.Decode(p[from:i])))
- from = i + 1
- }
- }
- return val, typ, nil
-}
-
-// GetIntegerValue retrieves the integer value for the specified
-// value name associated with an open key k. It also returns the value's type.
-// If value does not exist, GetIntegerValue returns ErrNotExist.
-// If value is not DWORD or QWORD, it will return the correct value
-// type and ErrUnexpectedType.
-func (k Key) GetIntegerValue(name string) (val uint64, valtype uint32, err error) {
- data, typ, err2 := k.getValue(name, make([]byte, 8))
- if err2 != nil {
- return 0, typ, err2
- }
- switch typ {
- case DWORD:
- if len(data) != 4 {
- return 0, typ, errors.New("DWORD value is not 4 bytes long")
- }
- var val32 uint32
- copy((*[4]byte)(unsafe.Pointer(&val32))[:], data)
- return uint64(val32), DWORD, nil
- case QWORD:
- if len(data) != 8 {
- return 0, typ, errors.New("QWORD value is not 8 bytes long")
- }
- copy((*[8]byte)(unsafe.Pointer(&val))[:], data)
- return val, QWORD, nil
- default:
- return 0, typ, ErrUnexpectedType
- }
-}
-
-// GetBinaryValue retrieves the binary value for the specified
-// value name associated with an open key k. It also returns the value's type.
-// If value does not exist, GetBinaryValue returns ErrNotExist.
-// If value is not BINARY, it will return the correct value
-// type and ErrUnexpectedType.
-func (k Key) GetBinaryValue(name string) (val []byte, valtype uint32, err error) {
- data, typ, err2 := k.getValue(name, make([]byte, 64))
- if err2 != nil {
- return nil, typ, err2
- }
- if typ != BINARY {
- return nil, typ, ErrUnexpectedType
- }
- return data, typ, nil
-}
-
-func (k Key) setValue(name string, valtype uint32, data []byte) error {
- p, err := syscall.UTF16PtrFromString(name)
- if err != nil {
- return err
- }
- if len(data) == 0 {
- return regSetValueEx(syscall.Handle(k), p, 0, valtype, nil, 0)
- }
- return regSetValueEx(syscall.Handle(k), p, 0, valtype, &data[0], uint32(len(data)))
-}
-
-// SetDWordValue sets the data and type of a name value
-// under key k to value and DWORD.
-func (k Key) SetDWordValue(name string, value uint32) error {
- return k.setValue(name, DWORD, (*[4]byte)(unsafe.Pointer(&value))[:])
-}
-
-// SetQWordValue sets the data and type of a name value
-// under key k to value and QWORD.
-func (k Key) SetQWordValue(name string, value uint64) error {
- return k.setValue(name, QWORD, (*[8]byte)(unsafe.Pointer(&value))[:])
-}
-
-func (k Key) setStringValue(name string, valtype uint32, value string) error {
- v, err := syscall.UTF16FromString(value)
- if err != nil {
- return err
- }
- buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
- return k.setValue(name, valtype, buf)
-}
-
-// SetStringValue sets the data and type of a name value
-// under key k to value and SZ. The value must not contain a zero byte.
-func (k Key) SetStringValue(name, value string) error {
- return k.setStringValue(name, SZ, value)
-}
-
-// SetExpandStringValue sets the data and type of a name value
-// under key k to value and EXPAND_SZ. The value must not contain a zero byte.
-func (k Key) SetExpandStringValue(name, value string) error {
- return k.setStringValue(name, EXPAND_SZ, value)
-}
-
-// SetStringsValue sets the data and type of a name value
-// under key k to value and MULTI_SZ. The value strings
-// must not contain a zero byte.
-func (k Key) SetStringsValue(name string, value []string) error {
- ss := ""
- for _, s := range value {
- for i := 0; i < len(s); i++ {
- if s[i] == 0 {
- return errors.New("string cannot have 0 inside")
- }
- }
- ss += s + "\x00"
- }
- v := utf16.Encode([]rune(ss + "\x00"))
- buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
- return k.setValue(name, MULTI_SZ, buf)
-}
-
-// SetBinaryValue sets the data and type of a name value
-// under key k to value and BINARY.
-func (k Key) SetBinaryValue(name string, value []byte) error {
- return k.setValue(name, BINARY, value)
-}
-
-// DeleteValue removes a named value from the key k.
-func (k Key) DeleteValue(name string) error {
- return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name))
-}
-
-// ReadValueNames returns the value names of key k.
-// The parameter n controls the number of returned names,
-// analogous to the way os.File.Readdirnames works.
-func (k Key) ReadValueNames(n int) ([]string, error) {
- ki, err := k.Stat()
- if err != nil {
- return nil, err
- }
- names := make([]string, 0, ki.ValueCount)
- buf := make([]uint16, ki.MaxValueNameLen+1) // extra room for terminating null character
-loopItems:
- for i := uint32(0); ; i++ {
- if n > 0 {
- if len(names) == n {
- return names, nil
- }
- }
- l := uint32(len(buf))
- for {
- err := regEnumValue(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
- if err == nil {
- break
- }
- if err == syscall.ERROR_MORE_DATA {
- // Double buffer size and try again.
- l = uint32(2 * len(buf))
- buf = make([]uint16, l)
- continue
- }
- if err == _ERROR_NO_MORE_ITEMS {
- break loopItems
- }
- return names, err
- }
- names = append(names, syscall.UTF16ToString(buf[:l]))
- }
- if n > len(names) {
- return names, io.EOF
- }
- return names, nil
-}
diff --git a/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go
deleted file mode 100644
index 3778075da..000000000
--- a/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// Code generated by 'go generate'; DO NOT EDIT.
-
-package registry
-
-import (
- "syscall"
- "unsafe"
-
- "golang.org/x/sys/windows"
-)
-
-var _ unsafe.Pointer
-
-// Do the interface allocations only once for common
-// Errno values.
-const (
- errnoERROR_IO_PENDING = 997
-)
-
-var (
- errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
-)
-
-// errnoErr returns common boxed Errno values, to prevent
-// allocations at runtime.
-func errnoErr(e syscall.Errno) error {
- switch e {
- case 0:
- return nil
- case errnoERROR_IO_PENDING:
- return errERROR_IO_PENDING
- }
- // TODO: add more here, after collecting data on the common
- // error values see on Windows. (perhaps when running
- // all.bat?)
- return e
-}
-
-var (
- modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
- modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
-
- procRegCreateKeyExW = modadvapi32.NewProc("RegCreateKeyExW")
- procRegDeleteKeyW = modadvapi32.NewProc("RegDeleteKeyW")
- procRegSetValueExW = modadvapi32.NewProc("RegSetValueExW")
- procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW")
- procRegDeleteValueW = modadvapi32.NewProc("RegDeleteValueW")
- procRegLoadMUIStringW = modadvapi32.NewProc("RegLoadMUIStringW")
- procRegConnectRegistryW = modadvapi32.NewProc("RegConnectRegistryW")
- procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW")
-)
-
-func regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) {
- r0, _, _ := syscall.Syscall9(procRegCreateKeyExW.Addr(), 9, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(reserved), uintptr(unsafe.Pointer(class)), uintptr(options), uintptr(desired), uintptr(unsafe.Pointer(sa)), uintptr(unsafe.Pointer(result)), uintptr(unsafe.Pointer(disposition)))
- if r0 != 0 {
- regerrno = syscall.Errno(r0)
- }
- return
-}
-
-func regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) {
- r0, _, _ := syscall.Syscall(procRegDeleteKeyW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(subkey)), 0)
- if r0 != 0 {
- regerrno = syscall.Errno(r0)
- }
- return
-}
-
-func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) {
- r0, _, _ := syscall.Syscall6(procRegSetValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize))
- if r0 != 0 {
- regerrno = syscall.Errno(r0)
- }
- return
-}
-
-func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
- r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)), 0)
- if r0 != 0 {
- regerrno = syscall.Errno(r0)
- }
- return
-}
-
-func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) {
- r0, _, _ := syscall.Syscall(procRegDeleteValueW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(name)), 0)
- if r0 != 0 {
- regerrno = syscall.Errno(r0)
- }
- return
-}
-
-func regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) {
- r0, _, _ := syscall.Syscall9(procRegLoadMUIStringW.Addr(), 7, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(unsafe.Pointer(buflenCopied)), uintptr(flags), uintptr(unsafe.Pointer(dir)), 0, 0)
- if r0 != 0 {
- regerrno = syscall.Errno(r0)
- }
- return
-}
-
-func regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) {
- r0, _, _ := syscall.Syscall(procRegConnectRegistryW.Addr(), 3, uintptr(unsafe.Pointer(machinename)), uintptr(key), uintptr(unsafe.Pointer(result)))
- if r0 != 0 {
- regerrno = syscall.Errno(r0)
- }
- return
-}
-
-func expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) {
- r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size))
- n = uint32(r0)
- if n == 0 {
- if e1 != 0 {
- err = errnoErr(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
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 0fe662e0a..465e3c5cc 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
@@ -194,14 +194,11 @@ github.com/docker/docker/oci/caps
github.com/docker/docker/pkg/namesgenerator
github.com/docker/docker/pkg/term
github.com/docker/docker/pkg/ioutils
-github.com/docker/docker/profiles/seccomp
github.com/docker/docker/pkg/parsers
github.com/docker/docker/api/types/versions
github.com/docker/docker/errdefs
github.com/docker/docker/pkg/term/windows
github.com/docker/docker/pkg/longpath
-github.com/docker/docker/api/types
-github.com/docker/docker/pkg/parsers/kernel
github.com/docker/docker/api/types/registry
github.com/docker/docker/api/types/swarm
github.com/docker/docker/pkg/archive
@@ -211,7 +208,6 @@ github.com/docker/docker/pkg/stdcopy
github.com/docker/docker/pkg/system
github.com/docker/docker/client
github.com/docker/docker/api/types/container
-github.com/docker/docker/api/types/filters
github.com/docker/docker/api/types/mount
github.com/docker/docker/api/types/network
github.com/docker/docker/api/types/swarm/runtime
@@ -219,7 +215,9 @@ github.com/docker/docker/pkg/idtools
github.com/docker/docker/pkg/pools
github.com/docker/docker/pkg/mount
github.com/docker/docker/api
+github.com/docker/docker/api/types
github.com/docker/docker/api/types/events
+github.com/docker/docker/api/types/filters
github.com/docker/docker/api/types/image
github.com/docker/docker/api/types/time
github.com/docker/docker/api/types/volume
@@ -319,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
@@ -346,7 +344,7 @@ github.com/onsi/ginkgo/internal/containernode
github.com/onsi/ginkgo/internal/leafnodes
github.com/onsi/ginkgo/internal/spec
github.com/onsi/ginkgo/internal/specrunner
-# github.com/onsi/gomega v1.7.0
+# github.com/onsi/gomega v1.7.1
github.com/onsi/gomega
github.com/onsi/gomega/gexec
github.com/onsi/gomega/format
@@ -444,7 +442,7 @@ github.com/stretchr/testify/require
github.com/syndtr/gocapability/capability
# github.com/tchap/go-patricia v2.3.0+incompatible
github.com/tchap/go-patricia/patricia
-# github.com/uber/jaeger-client-go v2.19.0+incompatible
+# github.com/uber/jaeger-client-go v2.20.0+incompatible
github.com/uber/jaeger-client-go
github.com/uber/jaeger-client-go/config
github.com/uber/jaeger-client-go/internal/baggage
@@ -493,6 +491,8 @@ github.com/xeipuuv/gojsonpointer
github.com/xeipuuv/gojsonreference
# github.com/xeipuuv/gojsonschema v1.1.0
github.com/xeipuuv/gojsonschema
+# go.uber.org/atomic v1.4.0
+go.uber.org/atomic
# golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad
golang.org/x/crypto/ssh/terminal
golang.org/x/crypto/openpgp
@@ -523,7 +523,6 @@ golang.org/x/sync/errgroup
# golang.org/x/sys v0.0.0-20190902133755-9109b7679e13
golang.org/x/sys/unix
golang.org/x/sys/windows
-golang.org/x/sys/windows/registry
# golang.org/x/text v0.3.2
golang.org/x/text/encoding
golang.org/x/text/encoding/charmap
@@ -569,7 +568,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