summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xAPI.md9
-rw-r--r--Makefile20
-rw-r--r--RELEASE_NOTES.md56
-rw-r--r--changelog.txt193
-rw-r--r--cmd/podman/attach.go3
-rw-r--r--cmd/podman/cliconfig/config.go2
-rw-r--r--cmd/podman/common.go6
-rw-r--r--cmd/podman/exec.go5
-rw-r--r--cmd/podman/images.go81
-rw-r--r--cmd/podman/network_create.go11
-rw-r--r--cmd/podman/start.go3
-rw-r--r--cmd/podman/varlink/io.podman.varlink5
-rw-r--r--completions/bash/podman2
-rwxr-xr-xcontrib/build_rpm.sh1
-rw-r--r--contrib/spec/podman.spec.in9
-rw-r--r--docs/source/markdown/podman-exec.1.md4
-rw-r--r--docs/source/markdown/podman-network-create.1.md17
-rw-r--r--docs/source/markdown/podman-pod-top.1.md48
-rw-r--r--docs/source/markdown/podman-top.1.md4
-rw-r--r--go.mod6
-rw-r--r--go.sum12
-rwxr-xr-xhack/systemd_tag.sh7
-rw-r--r--libpod/config/config.go94
-rw-r--r--libpod/container_api.go7
-rw-r--r--libpod/container_commit.go169
-rw-r--r--libpod/container_internal.go40
-rw-r--r--libpod/image/filters.go (renamed from cmd/podman/imagefilters/filters.go)83
-rw-r--r--libpod/image/image.go13
-rw-r--r--libpod/oci.go6
-rw-r--r--libpod/oci_conmon_linux.go22
-rw-r--r--libpod/oci_missing.go5
-rw-r--r--libpod/runtime_img.go3
-rw-r--r--pkg/adapter/containers.go48
-rw-r--r--pkg/adapter/network.go51
-rw-r--r--pkg/adapter/runtime.go15
-rw-r--r--pkg/adapter/runtime_remote.go22
-rw-r--r--pkg/network/config.go16
-rw-r--r--pkg/network/netconflist.go12
-rw-r--r--pkg/util/utils.go310
-rw-r--r--pkg/util/utils_supported.go4
-rw-r--r--pkg/util/utils_test.go308
-rw-r--r--pkg/varlinkapi/images.go36
-rw-r--r--test/e2e/e2e.coverprofile11
-rw-r--r--test/e2e/import_test.go8
-rw-r--r--test/system/070-build.bats48
-rw-r--r--troubleshooting.md27
-rw-r--r--vendor/github.com/Microsoft/hcsshim/appveyor.yml2
-rw-r--r--vendor/github.com/Microsoft/hcsshim/container.go2
-rw-r--r--vendor/github.com/Microsoft/hcsshim/go.mod2
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go26
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go33
-rw-r--r--vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go2
-rw-r--r--vendor/github.com/containers/psgo/README.md2
-rw-r--r--vendor/github.com/containers/psgo/internal/process/process.go23
-rw-r--r--vendor/github.com/containers/psgo/psgo.go14
-rw-r--r--vendor/github.com/containers/storage/.gitignore1
-rw-r--r--vendor/github.com/containers/storage/VERSION2
-rw-r--r--vendor/github.com/containers/storage/drivers/overlay/overlay.go9
-rw-r--r--vendor/github.com/containers/storage/go.mod11
-rw-r--r--vendor/github.com/containers/storage/go.sum91
-rw-r--r--vendor/github.com/containers/storage/layers.go6
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/archive.go13
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/changes_linux.go5
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/copy.go3
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/diff.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/chrootarchive/archive_unix.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/config/config.go8
-rw-r--r--vendor/github.com/containers/storage/pkg/idtools/idtools_unix.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/idtools/idtools_windows.go4
-rw-r--r--vendor/github.com/containers/storage/pkg/loopback/attach_loopback.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/loopback/loopback.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/system/filesys.go67
-rw-r--r--vendor/github.com/containers/storage/pkg/system/filesys_windows.go298
-rw-r--r--vendor/github.com/containers/storage/pkg/system/xattrs_linux.go24
-rw-r--r--vendor/github.com/containers/storage/pkg/system/xattrs_unsupported.go3
-rw-r--r--vendor/github.com/containers/storage/pkg/tarlog/tarlogger.go16
-rw-r--r--vendor/github.com/containers/storage/storage.conf3
-rw-r--r--vendor/github.com/containers/storage/store.go11
-rw-r--r--vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go4
-rw-r--r--vendor/github.com/klauspost/compress/flate/huffman_code.go3
-rw-r--r--vendor/github.com/klauspost/compress/flate/stateless.go16
-rw-r--r--vendor/github.com/klauspost/compress/huff0/decompress.go119
-rw-r--r--vendor/github.com/klauspost/compress/zstd/README.md14
-rw-r--r--vendor/github.com/klauspost/compress/zstd/blockdec.go4
-rw-r--r--vendor/github.com/klauspost/compress/zstd/blockenc.go12
-rw-r--r--vendor/github.com/klauspost/compress/zstd/encoder.go4
-rw-r--r--vendor/github.com/klauspost/compress/zstd/encoder_options.go11
-rw-r--r--vendor/github.com/klauspost/compress/zstd/framedec.go3
-rw-r--r--vendor/github.com/klauspost/compress/zstd/snappy.go8
-rw-r--r--vendor/github.com/uber/jaeger-client-go/CHANGELOG.md10
-rw-r--r--vendor/github.com/uber/jaeger-client-go/config/config.go34
-rw-r--r--vendor/github.com/uber/jaeger-client-go/constants.go2
-rw-r--r--vendor/github.com/uber/jaeger-client-go/sampler.go3
-rw-r--r--vendor/github.com/uber/jaeger-client-go/sampler_remote.go3
-rw-r--r--vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go48
-rw-r--r--vendor/modules.txt10
-rw-r--r--version/version.go2
97 files changed, 1820 insertions, 1043 deletions
diff --git a/API.md b/API.md
index 3a66db83b..695f374d8 100755
--- a/API.md
+++ b/API.md
@@ -123,6 +123,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
[func ListImages() Image](#ListImages)
+[func ListImagesWithFilters(filters: []string) Image](#ListImagesWithFilters)
+
[func ListPods() ListPodData](#ListPods)
[func LoadImage(name: string, inputFile: string, quiet: bool, deleteFile: bool) MoreResponse](#LoadImage)
@@ -892,6 +894,13 @@ See also [GetContainer](#GetContainer).
method ListImages() [Image](#Image)</div>
ListImages returns information about the images that are currently in storage.
See also [InspectImage](#InspectImage).
+### <a name="ListImagesWithFilters"></a>func ListImagesWithFilters
+<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
+
+method ListImagesWithFilters(filters: [[]string](#[]string)) [Image](#Image)</div>
+ListImagesWithFilters returns information about the images that are currently in storage
+after one or more filters has been applied.
+See also [InspectImage](#InspectImage).
### <a name="ListPods"></a>func ListPods
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
diff --git a/Makefile b/Makefile
index 3f8820780..fb6e48585 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ export GOPROXY=https://proxy.golang.org
GO ?= go
DESTDIR ?=
-EPOCH_TEST_COMMIT ?= ac73fd3fe5dcbf2647d589f9c9f37fe9531ed663
+EPOCH_TEST_COMMIT ?= 11541aec80c0fc588f675decd0ce759a4e353684
HEAD ?= HEAD
CHANGELOG_BASE ?= HEAD~
CHANGELOG_TARGET ?= HEAD
@@ -45,7 +45,7 @@ endif
ifeq (,$(findstring systemd,$(BUILDTAGS)))
$(warning \
Podman is being compiled without the systemd build tag.\
- Install libsystemd for journald support)
+ Install libsystemd on Ubuntu or systemd-devel on rpm based distro for journald support)
endif
BUILDTAGS_CROSS ?= containers_image_openpgp exclude_graphdriver_btrfs exclude_graphdriver_devicemapper exclude_graphdriver_overlay
@@ -73,11 +73,12 @@ endif
LIBPOD := ${PROJECT}/libpod
GCFLAGS ?= all=-trimpath=${PWD}
ASMFLAGS ?= all=-trimpath=${PWD}
-LDFLAGS_PODMAN ?= $(LDFLAGS) \
+LDFLAGS_PODMAN ?= \
-X $(LIBPOD)/define.gitCommit=$(GIT_COMMIT) \
-X $(LIBPOD)/define.buildInfo=$(BUILD_INFO) \
-X $(LIBPOD)/config._installPrefix=$(PREFIX) \
- -X $(LIBPOD)/config._etcDir=$(ETCDIR)
+ -X $(LIBPOD)/config._etcDir=$(ETCDIR) \
+ -extldflags "$(LDFLAGS)"
#Update to LIBSECCOMP_COMMIT should reflect in Dockerfile too.
LIBSECCOMP_COMMIT := release-2.3
# Rarely if ever should integration tests take more than 50min,
@@ -158,10 +159,10 @@ gofmt: ## Verify the source code gofmt
git diff --exit-code
test/checkseccomp/checkseccomp: .gopathok $(wildcard test/checkseccomp/*.go)
- $(GO_BUILD) -ldflags '$(LDFLAGS)' -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/test/checkseccomp
+ $(GO_BUILD) -ldflags '$(LDFLAGS_PODMAN)' -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/test/checkseccomp
test/goecho/goecho: .gopathok $(wildcard test/goecho/*.go)
- $(GO_BUILD) -ldflags '$(LDFLAGS)' -o $@ $(PROJECT)/test/goecho
+ $(GO_BUILD) -ldflags '$(LDFLAGS_PODMAN)' -o $@ $(PROJECT)/test/goecho
podman: .gopathok $(PODMAN_VARLINK_DEPENDENCIES) ## Build with podman
$(GO_BUILD) $(BUILDFLAGS) -gcflags '$(GCFLAGS)' -asmflags '$(ASMFLAGS)' -ldflags '$(LDFLAGS_PODMAN)' -tags "$(BUILDTAGS)" -o bin/$@ $(PROJECT)/cmd/podman
@@ -240,6 +241,7 @@ testunit: libpodimage ## Run unittest on the built image
localunit: test/goecho/goecho varlink_generate
ginkgo \
-r \
+ $(TESTFLAGS) \
--skipPackage test/e2e,pkg/apparmor,test/endpoint \
--cover \
--covermode atomic \
@@ -247,13 +249,13 @@ localunit: test/goecho/goecho varlink_generate
--succinct
ginkgo:
- ginkgo -v -tags "$(BUILDTAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -nodes 3 -debug test/e2e/.
+ ginkgo -v $(TESTFLAGS) -tags "$(BUILDTAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -nodes 3 -debug test/e2e/.
ginkgo-remote:
- ginkgo -v -tags "$(BUILDTAGS) remoteclient" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor test/e2e/.
+ ginkgo -v $(TESTFLAGS) -tags "$(BUILDTAGS) remoteclient" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor test/e2e/.
endpoint:
- ginkgo -v -tags "$(BUILDTAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -debug test/endpoint/.
+ ginkgo -v $(TESTFLAGS) -tags "$(BUILDTAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -debug test/endpoint/.
localintegration: varlink_generate test-binaries ginkgo
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index c16be818a..c8dac9ee0 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -1,5 +1,61 @@
# Release Notes
+## 1.7.0
+### Features
+- Added support for setting a static MAC address for containers
+- Added support for creating `macvlan` networks with `podman network create`, allowing Podman containers to be attached directly to networks the host is connected to
+- The `podman image prune` and `podman container prune` commands now support the `--filter` flag to filter what will be pruned, and now prompts for confirmation when run without `--force` ([#4410](https://github.com/containers/libpod/issues/4410) and [#4411](https://github.com/containers/libpod/issues/4411))
+- Podman now creates CGroup namespaces by default on systems using CGroups v2 ([#4363](https://github.com/containers/libpod/issues/4363))
+- Added the `podman system reset` command to remove all Podman files and perform a factory reset of the Podman installation
+- Added the `--history` flag to `podman images` to display previous names used by images ([#4566](https://github.com/containers/libpod/issues/4566))
+- Added the `--ignore` flag to `podman rm` and `podman stop` to not error when requested containers no longer exist
+- Added the `--cidfile` flag to `podman rm` and `podman stop` to read the IDs of containers to be removed or stopped from a file
+- The `podman play kube` command now honors Seccomp annotations ([#3111](https://github.com/containers/libpod/issues/3111))
+- The `podman play kube` command now honors `RunAsUser`, `RunAsGroup`, and `selinuxOptions`
+- The output format of the `podman version` command has been changed to better match `docker version` when using the `--format` flag
+- Rootless Podman will no longer initialize containers/storage twice, removing a potential deadlock preventing Podman commands from running while an image was being pulled ([#4591](https://github.com/containers/libpod/issues/4591))
+- Added `tmpcopyup` and `notmpcopyup` options to the `--tmpfs` and `--mount type=tmpfs` flags to `podman create` and `podman run` to control whether the content of directories are copied into tmpfs filesystems mounted over them
+- Added support for disabling detaching from containers by setting empty detach keys via `--detach-keys=""`
+- The `podman build` command now supports the `--pull` and `--pull-never` flags to control when images are pulled during a build
+
+### Bugfixes
+- Fixed a bug where Podman would use an incorrect runtime directory as root, causing state to be deleted after root logged out and making Podman in systemd services not function properly
+- Fixed a bug where the `--change` flag to `podman import` and `podman commit` was not being parsed properly in many cases
+- Fixed a bug where detach keys specified in `libpod.conf` were not used by the `podman attach` and `podman exec` commands, which always used the global default `ctrl-p,ctrl-q` key combination ([#4556](https://github.com/containers/libpod/issues/4556))
+- Fixed a bug where rootless Podman was not able to run `podman pod stats` even on CGroups v2 enabled systems ([#4634](https://github.com/containers/libpod/issues/4634))
+- Fixed a bug where rootless Podman would fail on kernels without the `renameat2` syscall ([#4570](https://github.com/containers/libpod/issues/4570))
+- Fixed a bug where containers with chained network namespace dependencies (IE, container A using `--net container=B` and container B using `--net container=C`) would not properly mount `/etc/hosts` and `/etc/resolv.conf` into the container ([#4626](https://github.com/containers/libpod/issues/4626))
+- Fixed a bug where `podman run` with the `--rm` flag and without `-d` could, when run in the background, throw a 'container does not exist' error when attempting to remove the container after it exited
+- Fixed a bug where named volume locks were not properly reacquired after a reboot, potentially leading to deadlocks when trying to start containers using the volume ([#4605](https://github.com/containers/libpod/issues/4605) and [#4621](https://github.com/containers/libpod/issues/4621))
+- Fixed a bug where Podman could not completely remove containers if sent SIGKILL during removal, leaving the container name unusable without the `podman rm --storage` command to complete removal ([#3906](https://github.com/containers/libpod/issues/3906))
+- Fixed a bug where checkpointing containers started with `--rm` was allowed when `--export` was not specified (the container, and checkpoint, would be removed after checkpointing was complete by `--rm`) ([#3774](https://github.com/containers/libpod/issues/3774))
+- Fixed a bug where the `podman pod prune` command would fail if containers were present in the pods and the `--force` flag was not passed ([#4346](https://github.com/containers/libpod/issues/4346))
+- Fixed a bug where containers could not set a static IP or static MAC address if they joined a non-default CNI network ([#4500](https://github.com/containers/libpod/issues/4500))
+- Fixed a bug where `podman system renumber` would always throw an error if a container was mounted when it was run
+- Fixed a bug where `podman container restore` would fail with containers using a user namespace
+- Fixed a bug where rootless Podman would attempt to use the journald events backend even on systems without systemd installed
+- Fixed a bug where `podman history` would sometimes not properly identify the IDs of layers in an image ([#3359](https://github.com/containers/libpod/issues/3359))
+- Fixed a bug where containers could not be restarted when Conmon v2.0.3 or later was used
+- Fixed a bug where Podman did not check image OS and Architecture against the host when starting a container
+- Fixed a bug where containers in pods did not function properly with the Kata OCI runtime ([#4353](https://github.com/containers/libpod/issues/4353))
+- Fixed a bug where `podman info --format '{{ json . }}' would not produce JSON output ([#4391](https://github.com/containers/libpod/issues/4391))
+- Fixed a bug where Podman would not verify if files passed to `--authfile` existed ([#4328](https://github.com/containers/libpod/issues/4328))
+- Fixed a bug where `podman images --digest` would not always print digests when they were available
+- Fixed a bug where rootless `podman run` could hang due to a race with reading and writing events
+- Fixed a bug where rootless Podman would print warning-level logs despite not be instructed to do so ([#4456](https://github.com/containers/libpod/issues/4456))
+- Fixed a bug where `podman pull` would attempt to fetch from remote registries when pulling an unqualified image using the `docker-daemon` transport ([#4434](https://github.com/containers/libpod/issues/4434))
+- Fixed a bug where `podman cp` would not work if STDIN was a pipe
+- Fixed a bug where `podman exec` could stop accepting input if anything was typed between the command being run and the exec session starting ([#4397](https://github.com/containers/libpod/issues/4397))
+- Fixed a bug where `podman logs --tail 0` would print all lines of a container's logs, instead of no lines ([#4396](https://github.com/containers/libpod/issues/4396))
+- Fixed a bug where the timeout for `slirp4netns` was incorrectly set, resulting in an extremely long timeout ([#4344](https://github.com/containers/libpod/issues/4344))
+- Fixed a bug where the `podman stats` command would print CPU utilizations figures incorrectly ([#4409](https://github.com/containers/libpod/issues/4409))
+
+### Misc
+- The fixes to runtime directory path as root can cause strange behavior if an upgrade is performed while containers are running
+- Updated vendored Buildah to v1.11.6
+- Updated vendored containers/storage library to v1.15.3
+- Kata Containers runtimes (`kata-runtime`, `kata-qemu`, and `kata-fc`) are now present in the default libpod.conf, but will not be available unless Kata containers is installed on the system
+
## 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.
diff --git a/changelog.txt b/changelog.txt
index 615e2a135..a19c23934 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,196 @@
+- Changelog for v1.7.0-rc1 (2019-12-11)
+ * Update release notes for 1.7.0
+ * docs: update podman-{pod-,}top man pages
+ * build(deps): bump github.com/containers/psgo from 1.3.2 to 1.4.0
+ * Update containers/storage to v1.15.3
+ * move image filters under libpod/images
+ * Re-add Fedora 31 migration code.
+ * macvlan networks
+ * Return empty runtime directory if we're not rootless
+ * build(deps): bump github.com/containers/storage from 1.15.0 to 1.15.2
+ * Use terminal detach keys sequence specified in the config file
+ * Add ONBUILD support to --change
+ * Move Commit() to new parsing for --change
+ * test for #3920 (improper caching of tarballs in build)
+ * Enable multi-platform rpm building
+ * Completely rework --change parsing
+ * Avoid git warnings by using detach on checkout
+ * Improve hack/get_release_info.sh
+ * Bump Buildah to v1.11.6
+ * rootless: enable stats test on cgroup v2
+ * Improve dnf tests inside build_rpm.sh
+ * libpod: fix stats for rootless pods
+ * rootless: add fallback for renameat2 at runtime
+ * Attempt to install go-md2man only if missing
+ * Quick grammar touchup in rootless.md
+ * Allow chained network namespace containers
+ * Ensure volumes reacquire locks on state refresh
+ * Ignore ErrCtrRemoved when removing a container
+ * Add comment on rootless containers creating device nodes
+ * Updates on making doc building and debug optional
+ * troubleshooting: warn about secure boot
+ * libpod: fix case for executable file not found errors
+ * build: improved main makefile
+ * build: improved prepare.sh
+ * Fix podman-remote version to print client and server
+ * man page updated with examples of filter option
+ * install.md: added slirp4netns dependency to ubuntu
+ * Add podman system reset command
+ * fix commands.go to get links from correct directory
+ * Do not initialize store on rootless podman
+ * filter added to container prune command
+ * Disable checkpointing of containers started with --rm
+ * Make doc building in spec optional
+ * Donot install btrfs in RHEL/CentOS-8
+ * oci: print only matching part for the errors
+ * command output fixed as per docker equivalent
+ * Detect Python executable in Makefile
+ * Improved build_rpm.sh
+ * Add support for image name history
+ * Remove containers when pruning a stopped pod.
+ * Allow --ip and --mac to be set when joining a CNI net
+ * Document other bind options on --volumes flag
+ * podman {pod,} rm/stop: add --ignore flag
+ * Discard errors from Shutdown in `system renumber`
+ * e2e/prune: run two top containers
+ * build(deps): bump github.com/containers/storage from 1.13.5 to 1.14.0
+ * build(deps): bump gopkg.in/yaml.v2 from 2.2.5 to 2.2.7
+ * build(deps): bump github.com/pkg/profile from 1.3.0 to 1.4.0
+ * document updated for filter and until options
+ * filter added to image pruge command.
+ * config: use EventsLogger=file without systemd
+ * Error on netns not exist only when ctr is running
+ * Add ContainerStateRemoving
+ * play kube: handle seccomp labels
+ * podman rm/stop --cidfile
+ * container-restore: Fix restore with user namespace
+ * Add new test suite for build
+ * Also delete winsz fifo
+ * use pause image for check all
+ * timestamp related functions added
+ * Bump to Buildah v1.11.5
+ * container create: os/arch check
+ * history: rewrite mappings
+ * codespell: spelling corrections
+ * Cirrus: Use branch-specific container tags
+ * warning added before image prune command
+ * create a separate install target for seccomp
+ * Add annotations in play kube
+ * Add pod annotations to container
+ * Add missing information to podman.1 man page
+ * Add support for make vendor-in-container
+ * Split up create config handling of namespaces and security
+ * test: add tests for --mac-address
+ * mount: add new options nocopyup|copyup for tmpfs
+ * Bump github.com/uber/jaeger-client-go
+ * libpod/config: default: use `crun` on Cgroups v2
+ * podman images --digest: always list a digest
+ * events: make sure the write channel is always closed
+ * Add support for RunAsUser and RunAsGroup
+ * cni: enable tuning plugin
+ * podman: add support for specifying MAC
+ * vendor: updated ocicni for MAC address
+ * Makefile: add vendor-in-container
+ * rootless: provide workaround for missing renameat2
+ * rootless: use SYS_renameat2 instead of __NR_renameat2
+ * Add Kata Containers runtimes to libpod.conf
+ * help message: don't parse the config for cgroup-manager default
+ * fix bug check nonexist authfile
+ * Allow users to disable detach keys
+ * namespaces: by default create cgroupns on cgroups v2
+ * Update installation - Ubuntu. [skip ci]
+ * pulling unqualified reference: make sure it's a docker reference
+ * Bump gopkg.in/yaml.v2 from 2.2.4 to 2.2.5
+ * Set SELinux labels based on the security context in the kube.yaml
+ * Add links to readthedocs on docs/readme
+ * Bump development version to 1.6.4-dev
+ * Bump version in README to v1.6.3
+ * Add release notes for v1.6.3
+ * slirp4netns: fix timeout
+ * docs: Update "podman container rm -v" description
+ * logo: correct light source reflection
+ * stats: fix calculation for the CPU time
+ * [docs] Ensure we include section 5 documentation
+ * [Makefile] Fix docker documentation install and generation
+ * Fixed the JSON go template format for the 'info' action
+ * runtime: Fix typo
+ * Update link to Commands documentation
+ * cgroups: read correctly the CPU stats
+ * [CI:DOCS] make docs only prs
+ * Update rootless shortcomings with cgroup V2 information
+ * Bump github.com/onsi/gomega from 1.7.0 to 1.7.1
+ * Validate contextdir on build
+ * Vendor in latest containers/buildah
+ * Bump github.com/onsi/ginkgo from 1.10.1 to 1.10.3
+ * Refactor test to prevent panic
+ * logs: support --tail 0
+ * Update document formatting and packaging code
+ * Restructure documentation dir
+ * add libpod/config
+ * Switch to bufio Reader for exec streams
+ * container start: fix regression when using name
+ * Fix selinux test for exec
+ * Cirrus: Disable F29 testing
+ * Wait for `mount` command to finish when mounting volume
+ * Cirrus: Fix upload_release_archive on branch or tag
+ * Fix cp from pipe
+ * libpod, rootless: create cgroup for conmon
+ * Bump github.com/json-iterator/go from 1.1.7 to 1.1.8
+ * seccomp: use github.com/seccomp/containers-golang
+ * build: drop support for ostree
+ * stale action: add exempt-issue-label
+ * Processes execed into container should match container label
+ * Set default seccomp.json file for podman play kube
+ * images: distinguish between tags and digests
+ * API: report multiple digests for images
+ * pull/create: add --override-arch/--override-os flags
+ * image: don't get confused by lists
+ * Add e2e tests for manifest list support
+ * bump containers/image to v5.0.0, buildah to v1.11.4
+ * goland autocorrections
+ * Makefile: fix embedding gitCommit
+ * Cirrus: Fix minor python deprecation warning
+ * Cirrus: Only upload tagged releases
+ * Fix spelling mistakes
+ * libpod: if slirp4netns fails, return its output
+ * update conmon to v2.0.2 in in_podman image
+ * bump cirrus images
+ * require conmon v2.0.1
+ * require conmon v2.0.0
+ * GitHub stale action
+ * enable dnsplugin for network create
+ * Add ensureState helper for checking container state
+ * Cleanup man pages
+ * Log warn instead of error for removing nonexistant container
+ * systemd: mask /sys/fs/cgroup/systemd/release_agent
+ * Add multiple networks explanation to docs
+ * rootless: raise an error with --network=
+ * Initial dump of man pages and first menus
+ * Return a better error for volume name conflicts
+ * Add documentation on options to volume create manpage
+ * Image volumes should not be mounted noexec
+ * stats: list all running containers unless specified otherwise
+ * rootless: detect no system session with --cgroup-manager=systemd
+ * add pip requirements file for rtd
+ * Initial checking for readthedocs
+ * Fix sig-proxy=false test and use image cache
+ * Add parsing for UID, GID in volume "o" option
+ * exec: remove unused var
+ * Rewrite backend for remote 'volume inspect'
+ * rootless: write storage overrides to the conf file
+ * Markdown Formatting Fixes
+ * Show volume options in 'volume inspect'
+ * System tests: make sure exec pid hash w/o leaking
+ * Bump gitvalidation epoch
+ * Bump to v1.6.3-dev
+ * check existing bridge names when creating networks
+ * Add support for anonymous volumes to `podman run -v`
+ * troubleshooting.md: document lingering mode
+ * rootless: do not enable lingering mode
+ * Add ability to redirect bash for run -i
+ * play kube: Container->Ctr
+ * play kube: refactor test suite
+
- Changelog for v1.6.2 (2019-10-17)
* Finalize release notes for v1.6.2
* rootless: drop dependency on docker
diff --git a/cmd/podman/attach.go b/cmd/podman/attach.go
index eeedea8c8..7d32c57af 100644
--- a/cmd/podman/attach.go
+++ b/cmd/podman/attach.go
@@ -33,6 +33,9 @@ func init() {
attachCommand.SetUsageTemplate(UsageTemplate())
flags := attachCommand.Flags()
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 `_`")
+ // Clear the default, the value specified in the config file should have the
+ // priority
+ attachCommand.DetachKeys = ""
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/cliconfig/config.go b/cmd/podman/cliconfig/config.go
index c15ce8829..e81756808 100644
--- a/cmd/podman/cliconfig/config.go
+++ b/cmd/podman/cliconfig/config.go
@@ -128,6 +128,7 @@ type ExecValues struct {
PodmanCommand
DetachKeys string
Env []string
+ EnvFile []string
Privileged bool
Interactive bool
Tty bool
@@ -278,6 +279,7 @@ type NetworkCreateValues struct {
IPRange net.IPNet
IPV6 bool
Network net.IPNet
+ MacVLAN string
}
type NetworkListValues struct {
diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index 442823d2d..69365201e 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -208,10 +208,14 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"detach", "d", false,
"Run container in background and print container ID",
)
- createFlags.String(
+ detachKeys := createFlags.String(
"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 `_`",
)
+ // Clear the default, the value specified in the config file should have the
+ // priority
+ *detachKeys = ""
+
createFlags.StringSlice(
"device", []string{},
"Add a host device to the container (default [])",
diff --git a/cmd/podman/exec.go b/cmd/podman/exec.go
index afa701897..6e5799396 100644
--- a/cmd/podman/exec.go
+++ b/cmd/podman/exec.go
@@ -36,7 +36,11 @@ func init() {
flags := execCommand.Flags()
flags.SetInterspersed(false)
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 _")
+ // Clear the default, the value specified in the config file should have the
+ // priority
+ execCommand.DetachKeys = ""
flags.StringArrayVarP(&execCommand.Env, "env", "e", []string{}, "Set environment variables")
+ flags.StringSliceVar(&execCommand.EnvFile, "env-file", []string{}, "Read in a file of 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")
flags.BoolVar(&execCommand.Privileged, "privileged", false, "Give the process extended Linux capabilities inside the container. The default is false")
@@ -45,6 +49,7 @@ func init() {
flags.IntVar(&execCommand.PreserveFDs, "preserve-fds", 0, "Pass N additional file descriptors to the container")
flags.StringVarP(&execCommand.Workdir, "workdir", "w", "", "Working directory inside the container")
+ markFlagHiddenForRemoteClient("env-file", flags)
markFlagHiddenForRemoteClient("latest", flags)
markFlagHiddenForRemoteClient("preserve-fds", flags)
}
diff --git a/cmd/podman/images.go b/cmd/podman/images.go
index 6b16272f4..e42546a55 100644
--- a/cmd/podman/images.go
+++ b/cmd/podman/images.go
@@ -5,14 +5,12 @@ import (
"fmt"
"reflect"
"sort"
- "strconv"
"strings"
"time"
"unicode"
"github.com/containers/buildah/pkg/formats"
"github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/cmd/podman/imagefilters"
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/adapter"
"github.com/docker/go-units"
@@ -138,10 +136,10 @@ func init() {
func imagesCmd(c *cliconfig.ImagesValues) error {
var (
- filterFuncs []imagefilters.ResultFilter
- image string
+ image string
)
+ ctx := getContext()
runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "Could not get runtime")
@@ -156,15 +154,9 @@ func imagesCmd(c *cliconfig.ImagesValues) error {
if len(c.Filter) > 0 && image != "" {
return errors.New("can not specify an image and a filter")
}
- ctx := getContext()
-
- if len(c.Filter) > 0 {
- filterFuncs, err = CreateFilterFuncs(ctx, runtime, c.Filter, nil)
- } else {
- filterFuncs, err = CreateFilterFuncs(ctx, runtime, []string{fmt.Sprintf("reference=%s", image)}, nil)
- }
- if err != nil {
- return err
+ filters := c.Filter
+ if len(filters) < 1 {
+ filters = append(filters, fmt.Sprintf("reference=%s", image))
}
opts := imagesOptions{
@@ -179,26 +171,17 @@ func imagesCmd(c *cliconfig.ImagesValues) error {
}
opts.outputformat = opts.setOutputFormat()
- images, err := runtime.GetImages()
+ filteredImages, err := runtime.GetFilteredImages(filters, false)
if err != nil {
return errors.Wrapf(err, "unable to get images")
}
- for _, image := range images {
+ for _, image := range filteredImages {
if image.IsReadOnly() {
opts.outputformat += "{{.ReadOnly}}\t"
break
}
}
-
- var filteredImages []*adapter.ContainerImage
- //filter the images
- if len(c.Filter) > 0 || len(c.InputArgs) == 1 {
- filteredImages = imagefilters.FilterImages(images, filterFuncs)
- } else {
- filteredImages = images
- }
-
return generateImagesOutput(ctx, filteredImages, opts)
}
@@ -392,53 +375,3 @@ func GenImageOutputMap() map[string]string {
}
return values
}
-
-// CreateFilterFuncs returns an array of filter functions based on the user inputs
-// and is later used to filter images for output
-func CreateFilterFuncs(ctx context.Context, r *adapter.LocalRuntime, filters []string, img *adapter.ContainerImage) ([]imagefilters.ResultFilter, error) {
- var filterFuncs []imagefilters.ResultFilter
- for _, filter := range filters {
- splitFilter := strings.Split(filter, "=")
- if len(splitFilter) < 2 {
- return nil, errors.Errorf("invalid filter syntax %s", filter)
- }
- switch splitFilter[0] {
- case "before":
- before, err := r.NewImageFromLocal(splitFilter[1])
- if err != nil {
- return nil, errors.Wrapf(err, "unable to find image %s in local stores", splitFilter[1])
- }
- filterFuncs = append(filterFuncs, imagefilters.CreatedBeforeFilter(before.Created()))
- case "after":
- after, err := r.NewImageFromLocal(splitFilter[1])
- if err != nil {
- return nil, errors.Wrapf(err, "unable to find image %s in local stores", splitFilter[1])
- }
- filterFuncs = append(filterFuncs, imagefilters.CreatedAfterFilter(after.Created()))
- case "readonly":
- readonly, err := strconv.ParseBool(splitFilter[1])
- if err != nil {
- return nil, errors.Wrapf(err, "invalid filter readonly=%s", splitFilter[1])
- }
- filterFuncs = append(filterFuncs, imagefilters.ReadOnlyFilter(readonly))
- case "dangling":
- danglingImages, err := strconv.ParseBool(splitFilter[1])
- if err != nil {
- return nil, errors.Wrapf(err, "invalid filter dangling=%s", splitFilter[1])
- }
- filterFuncs = append(filterFuncs, imagefilters.DanglingFilter(danglingImages))
- case "label":
- labelFilter := strings.Join(splitFilter[1:], "=")
- filterFuncs = append(filterFuncs, imagefilters.LabelFilter(ctx, labelFilter))
- case "reference":
- referenceFilter := strings.Join(splitFilter[1:], "=")
- filterFuncs = append(filterFuncs, imagefilters.ReferenceFilter(ctx, referenceFilter))
- default:
- return nil, errors.Errorf("invalid filter %s ", splitFilter[0])
- }
- }
- if img != nil {
- filterFuncs = append(filterFuncs, imagefilters.OutputImageFilter(img))
- }
- return filterFuncs, nil
-}
diff --git a/cmd/podman/network_create.go b/cmd/podman/network_create.go
index 6710883ae..886607885 100644
--- a/cmd/podman/network_create.go
+++ b/cmd/podman/network_create.go
@@ -41,6 +41,7 @@ func init() {
flags.IPVar(&networkCreateCommand.Gateway, "gateway", nil, "IPv4 or IPv6 gateway for the subnet")
flags.BoolVar(&networkCreateCommand.Internal, "internal", false, "restrict external access from this network")
flags.IPNetVar(&networkCreateCommand.IPRange, "ip-range", net.IPNet{}, "allocate container IP from range")
+ flags.StringVar(&networkCreateCommand.MacVLAN, "macvlan", "", "create a Macvlan connection based on this device")
// TODO not supported yet
//flags.StringVar(&networkCreateCommand.IPamDriver, "ipam-driver", "", "IP Address Management Driver")
// TODO enable when IPv6 is working
@@ -50,6 +51,10 @@ func init() {
}
func networkcreateCmd(c *cliconfig.NetworkCreateValues) error {
+ var (
+ fileName string
+ err error
+ )
if err := network.IsSupportedDriver(c.Driver); err != nil {
return err
}
@@ -66,7 +71,11 @@ func networkcreateCmd(c *cliconfig.NetworkCreateValues) error {
if err != nil {
return err
}
- fileName, err := runtime.NetworkCreate(c)
+ if len(c.MacVLAN) > 0 {
+ fileName, err = runtime.NetworkCreateMacVLAN(c)
+ } else {
+ fileName, err = runtime.NetworkCreateBridge(c)
+ }
if err == nil {
fmt.Println(fileName)
}
diff --git a/cmd/podman/start.go b/cmd/podman/start.go
index d4b4534bb..a070cd18d 100644
--- a/cmd/podman/start.go
+++ b/cmd/podman/start.go
@@ -35,6 +35,9 @@ func init() {
startCommand.SetUsageTemplate(UsageTemplate())
flags := startCommand.Flags()
flags.BoolVarP(&startCommand.Attach, "attach", "a", false, "Attach container's STDOUT and STDERR")
+ // Clear the default, the value specified in the config file should have the
+ // priority
+ startCommand.DetachKeys = ""
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")
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index a3fd27ed6..2251050c3 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -784,6 +784,11 @@ method DeleteStoppedContainers() -> (containers: []string)
# See also [InspectImage](#InspectImage).
method ListImages() -> (images: []Image)
+# ListImagesWithFilters returns information about the images that are currently in storage
+# after one or more filters has been applied.
+# See also [InspectImage](#InspectImage).
+method ListImagesWithFilters(filters: []string) -> (images: []Image)
+
# GetImage returns information about a single image in storage.
# If the image caGetImage returns be found, [ImageNotFound](#ImageNotFound) will be returned.
method GetImage(id: string) -> (image: Image)
diff --git a/completions/bash/podman b/completions/bash/podman
index 18e2460ec..40be0018b 100644
--- a/completions/bash/podman
+++ b/completions/bash/podman
@@ -980,6 +980,7 @@ _podman_network_create() {
--driver
--gateway
--ip-range
+ --macvlan
--subnet
"
local boolean_options="
@@ -1358,6 +1359,7 @@ _podman_exec() {
--detach-keys
-e
--env
+ --env-file
--user
-u
--workdir
diff --git a/contrib/build_rpm.sh b/contrib/build_rpm.sh
index e41763fa7..088d8b7a5 100755
--- a/contrib/build_rpm.sh
+++ b/contrib/build_rpm.sh
@@ -26,6 +26,7 @@ declare -a PKGS=(device-mapper-devel \
make \
rpm-build \
go-compilers-golang-compiler \
+ systemd-devel \
)
if [[ $pkg_manager == *dnf ]]; then
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index 4a3704811..9676a3fb4 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -22,6 +22,9 @@
%define gobuild(o:) go build -tags="$BUILDTAGS" -ldflags "${LDFLAGS:-} -B 0x$(head -c20 /dev/urandom|od -An -tx1|tr -d ' \\n')" -a -v -x %{?**};
#% endif
+# libpod hack directory
+%define hackdir %{_builddir}/%{repo}-%{shortcommit0}
+
%global provider github
%global provider_tld com
%global project containers
@@ -40,7 +43,7 @@
%global shortcommit_conmon %(c=%{commit_conmon}; echo ${c:0:7})
Name: podman
-Version: 1.6.4
+Version: 1.7.0
Release: #COMMITDATE#.git%{shortcommit0}%{?dist}
Summary: Manage Pods, Containers and Container Images
License: ASL 2.0
@@ -384,7 +387,7 @@ ln -s ../../../../ src/%{import_path}
popd
ln -s vendor src
export GOPATH=$(pwd)/_build:$(pwd):$(pwd):%{gopath}
-export BUILDTAGS="varlink selinux seccomp $(hack/btrfs_installed_tag.sh) $(hack/btrfs_tag.sh) $(hack/libdm_tag.sh) exclude_graphdriver_devicemapper"
+export BUILDTAGS="varlink selinux seccomp $(%{hackdir}/hack/btrfs_installed_tag.sh) $(%{hackdir}/hack/btrfs_tag.sh) $(%{hackdir}/hack/libdm_tag.sh) exclude_graphdriver_devicemapper"
GOPATH=$GOPATH go generate ./cmd/podman/varlink/...
@@ -402,7 +405,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)"
+export BUILDTAGS="selinux seccomp $(%{hackdir}/hack/btrfs_installed_tag.sh) $(%{hackdir}/hack/btrfs_tag.sh)"
BUILDTAGS=$BUILDTAGS make
popd
diff --git a/docs/source/markdown/podman-exec.1.md b/docs/source/markdown/podman-exec.1.md
index 9624425dc..d46427c91 100644
--- a/docs/source/markdown/podman-exec.1.md
+++ b/docs/source/markdown/podman-exec.1.md
@@ -22,6 +22,10 @@ Specify the key sequence for detaching a container. Format is a single character
You may specify arbitrary environment variables that are available for the
command to be executed.
+**--env-file**=*file*
+
+Read in a line delimited file of environment variables.
+
**--interactive**, **-i**=*true|false*
When set to true, keep stdin open even if not attached. The default is *false*.
diff --git a/docs/source/markdown/podman-network-create.1.md b/docs/source/markdown/podman-network-create.1.md
index c281d50d9..2eca93adb 100644
--- a/docs/source/markdown/podman-network-create.1.md
+++ b/docs/source/markdown/podman-network-create.1.md
@@ -7,8 +7,10 @@ podman\-network-create - Create a Podman CNI network
**podman network create** [*options*] name
## DESCRIPTION
-Create a CNI-network configuration for use with Podman. At the time of this writing, the only network
-type that can be created is a *bridge* network.
+Create a CNI-network configuration for use with Podman. By default, Podman creates a bridge connection. A
+*Macvlan* connection can be created with the *macvlan* option. In the case of *Macvlan* connections, the
+CNI *dhcp* plugin needs to be activated or the container image must have a DHCP client to interact
+with the host network's DHCP server.
If no options are provided, Podman will assign a free subnet and name for your network.
@@ -38,6 +40,11 @@ Restrict external access of this network
Allocate container IP from a range. The range must be a complete subnet and in CIDR notation. The *ip-range* option
must be used with a *subnet* option.
+**--macvlan**
+
+Create a *Macvlan* based connection rather than a classic bridge. You must pass an interface name from the host for the
+Macvlan connection.
+
**--subnet**
The subnet in CIDR notation.
@@ -68,6 +75,12 @@ Create a network that uses a *192.168.55.0/24** subnet and has an IP address ran
/etc/cni/net.d/cni-podman-5.conflist
```
+Create a Macvlan based network using the host interface eth0
+```
+# podman network create --macvlan eth0 newnet
+/etc/cni/net.d/newnet.conflist
+```
+
## SEE ALSO
podman(1), podman-network(1), podman-network-inspect(1)
diff --git a/docs/source/markdown/podman-pod-top.1.md b/docs/source/markdown/podman-pod-top.1.md
index 48f10055a..6a1fa8c42 100644
--- a/docs/source/markdown/podman-pod-top.1.md
+++ b/docs/source/markdown/podman-pod-top.1.md
@@ -23,53 +23,11 @@ The latest option is not supported on the remote client.
## FORMAT DESCRIPTORS
-The following descriptors are supported in addition to the AIX format descriptors mentioned in ps (1):
-
-**args**, **capbnd**, **capeff**, **capinh**, **capprm**, **comm**, **etime**, **group**, **hgroup**, **hpid**, **huser**, **label**, **nice**, **pcpu**, **pgid**, **pid**, **ppid**, **rgroup**, **ruser**, **seccomp**, **state**, **time**, **tty**, **user**, **vsz**
-
-**capbnd**
-
- Set of bounding capabilities. See capabilities (7) for more information.
-
-**capeff**
-
- Set of effective capabilities. See capabilities (7) for more information.
-
-**capinh**
-
- Set of inheritable capabilities. See capabilities (7) for more information.
-
-**capprm**
-
- Set of permitted capabilities. See capabilities (7) for more information.
-
-**hgroup**
-
- The corresponding effective group of a container process on the host.
-
-**hpid**
-
- The corresponding host PID of a container process.
-
-**huser**
-
- The corresponding effective user of a container process on the host.
-
-**label**
-
- Current security attributes of the process.
-
-**seccomp**
-
- Seccomp mode of the process (i.e., disabled, strict or filter). See seccomp (2) for more information.
-
-**state**
-
- Process state codes (e.g, **R** for *running*, **S** for *sleeping*). See proc(5) for more information.
+Please refer to podman-top(1) for a full list of available descriptors.
## EXAMPLES
-By default, `podman-top` prints data similar to `ps -ef`:
+By default, `podman-pod-top` prints data similar to `ps -ef`:
```
$ podman pod top b031293491cc
@@ -88,7 +46,7 @@ PID SECCOMP COMMAND %CPU
```
## SEE ALSO
-podman-pod(1), ps(1), seccomp(2), proc(5), capabilities(7)
+podman-pod(1), podman-top(1), ps(1), seccomp(2), proc(5), capabilities(7)
## HISTORY
August 2018, Originally compiled by Peter Hunt <pehunt@redhat.com>
diff --git a/docs/source/markdown/podman-top.1.md b/docs/source/markdown/podman-top.1.md
index 1410aa651..6a04ab91a 100644
--- a/docs/source/markdown/podman-top.1.md
+++ b/docs/source/markdown/podman-top.1.md
@@ -70,6 +70,10 @@ The following descriptors are supported in addition to the AIX format descriptor
Process state codes (e.g, **R** for *running*, **S** for *sleeping*). See proc(5) for more information.
+**stime**
+
+ Process start time (e.g, "2019-12-09 10:50:36 +0100 CET).
+
## EXAMPLES
By default, `podman-top` prints data similar to `ps -ef`:
diff --git a/go.mod b/go.mod
index 96114830a..82649bda6 100644
--- a/go.mod
+++ b/go.mod
@@ -13,8 +13,8 @@ require (
github.com/containers/buildah v1.11.6
github.com/containers/conmon v2.0.2+incompatible // indirect
github.com/containers/image/v5 v5.0.0
- github.com/containers/psgo v1.3.2
- github.com/containers/storage v1.15.0
+ github.com/containers/psgo v1.4.0
+ github.com/containers/storage v1.15.3
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
github.com/cri-o/ocicni v0.1.1-0.20190920040751-deac903fd99b
@@ -59,7 +59,7 @@ require (
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.20.0+incompatible
+ github.com/uber/jaeger-client-go v2.20.1+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
diff --git a/go.sum b/go.sum
index caf28c425..2db8cce4a 100644
--- a/go.sum
+++ b/go.sum
@@ -21,6 +21,8 @@ github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/Microsoft/hcsshim v0.8.7-0.20191101173118-65519b62243c h1:YMP6olTU903X3gxQJckdmiP8/zkSMq4kN3uipsU9XjU=
github.com/Microsoft/hcsshim v0.8.7-0.20191101173118-65519b62243c/go.mod h1:7xhjOwRV2+0HXGmM0jxaEu+ZiXJFoVZOTfL/dmqbrD8=
+github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg=
+github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
@@ -86,6 +88,8 @@ github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDpl
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/psgo v1.3.2 h1:jYfppPih3S/j2Yi5O14AXjd8GfCx1ph9L3YsoK3adko=
github.com/containers/psgo v1.3.2/go.mod h1:ENXXLQ5E1At4K0EUsGogXBJi/C28gwqkONWeLPI9fJ8=
+github.com/containers/psgo v1.4.0 h1:D8B4fZCCZhYgc8hDyMPCiShOinmOB1TP1qe46sSC19k=
+github.com/containers/psgo v1.4.0/go.mod h1:ENXXLQ5E1At4K0EUsGogXBJi/C28gwqkONWeLPI9fJ8=
github.com/containers/storage v1.13.4 h1:j0bBaJDKbUHtAW1MXPFnwXJtqcH+foWeuXK1YaBV5GA=
github.com/containers/storage v1.13.4/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
github.com/containers/storage v1.13.5 h1:/SUzGeOP2HDijpF7Yur21Ch6WTZC1BNeZF917CWcp5c=
@@ -94,6 +98,10 @@ github.com/containers/storage v1.14.0 h1:LbX6WZaDmkXt4DT4xWIg3YXAWd6oA4K9Fi6/KG1
github.com/containers/storage v1.14.0/go.mod h1:qGPsti/qC1xxX+xcpHfiTMT+8ThVE2Jf83wFHHqkDAY=
github.com/containers/storage v1.15.0 h1:QNW7jJ94ccGcAbFIOSMHUAsUxvHceb71ecLye9EDrkk=
github.com/containers/storage v1.15.0/go.mod h1:qGPsti/qC1xxX+xcpHfiTMT+8ThVE2Jf83wFHHqkDAY=
+github.com/containers/storage v1.15.2 h1:hLgafU4tuyQk/smMkXZfHTS8FtAQsqQvfWCp4bsgjuw=
+github.com/containers/storage v1.15.2/go.mod h1:v0lq/3f+cXH3Y/HiDaFYRR0zilwDve7I4W7U5xQxvF8=
+github.com/containers/storage v1.15.3 h1:+lFSQZnnKUFyUEtguIgdoQLJfWSuYz+j/wg5GxLtsN4=
+github.com/containers/storage v1.15.3/go.mod h1:v0lq/3f+cXH3Y/HiDaFYRR0zilwDve7I4W7U5xQxvF8=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-iptables v0.4.2 h1:KH0EwId05JwWIfb96gWvkiT2cbuOu8ygqUaB+yPAwIg=
@@ -273,6 +281,8 @@ github.com/klauspost/compress v1.8.1 h1:oygt2ychZFHOB6M9gUgajzgKrwRgHbGC77NwA4CO
github.com/klauspost/compress v1.8.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.2 h1:LfVyl+ZlLlLDeQ/d2AqfGIIH4qEDu0Ed2S5GyhCWIWY=
github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/compress v1.9.4 h1:xhvAeUPQ2drNUhKtrGdTGNvV9nNafHMUkRyLkzxJoB4=
+github.com/klauspost/compress v1.9.4/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
@@ -456,6 +466,8 @@ github.com/uber/jaeger-client-go v2.19.0+incompatible h1:pbwbYfHUoaase0oPQOdZ1Gc
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-client-go v2.20.1+incompatible h1:HgqpYBng0n7tLJIlyT4kPCIv5XgCsF+kai1NnnrJzEU=
+github.com/uber/jaeger-client-go v2.20.1+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=
diff --git a/hack/systemd_tag.sh b/hack/systemd_tag.sh
index c59cad559..19a7bf6a6 100755
--- a/hack/systemd_tag.sh
+++ b/hack/systemd_tag.sh
@@ -1,4 +1,7 @@
#!/usr/bin/env bash
-if pkg-config --exists libsystemd; then
- echo systemd
+cc -E - > /dev/null 2> /dev/null << EOF
+#include <systemd/sd-daemon.h>
+EOF
+if test $? -eq 0 ; then
+ echo systemd
fi
diff --git a/libpod/config/config.go b/libpod/config/config.go
index f1fa70fbc..6240bccb0 100644
--- a/libpod/config/config.go
+++ b/libpod/config/config.go
@@ -12,6 +12,7 @@ import (
"github.com/BurntSushi/toml"
"github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/pkg/cgroups"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/util"
"github.com/containers/storage"
@@ -137,11 +138,11 @@ type Config struct {
// 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"`
+ VolumePath string `toml:"volume_path,omitempty"`
// ImageDefaultTransport is the default transport method used to fetch
// images.
- ImageDefaultTransport string `toml:"image_default_transport"`
+ ImageDefaultTransport string `toml:"image_default_transport,omitempty"`
// SignaturePolicyPath is the path to a signature policy to use for
// validating images. If left empty, the containers/image default signature
@@ -149,61 +150,61 @@ type Config struct {
SignaturePolicyPath string `toml:"signature_policy_path,omitempty"`
// OCIRuntime is the OCI runtime to use.
- OCIRuntime string `toml:"runtime"`
+ OCIRuntime string `toml:"runtime,omitempty"`
// OCIRuntimes are the set of configured OCI runtimes (default is runc).
- OCIRuntimes map[string][]string `toml:"runtimes"`
+ OCIRuntimes map[string][]string `toml:"runtimes,omitempty"`
// RuntimeSupportsJSON is the list of the OCI runtimes that support
// --format=json.
- RuntimeSupportsJSON []string `toml:"runtime_supports_json"`
+ RuntimeSupportsJSON []string `toml:"runtime_supports_json,omitempty"`
// RuntimeSupportsNoCgroups is a list of OCI runtimes that support
// running containers without CGroups.
- RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroups"`
+ RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroups,omitempty"`
// 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"`
+ RuntimePath []string `toml:"runtime_path,omitempty"`
// 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"`
+ ConmonPath []string `toml:"conmon_path,omitempty"`
// ConmonEnvVars are environment variables to pass to the Conmon binary
// when it is launched.
- ConmonEnvVars []string `toml:"conmon_env_vars"`
+ ConmonEnvVars []string `toml:"conmon_env_vars,omitempty"`
// CGroupManager is the CGroup Manager to use Valid values are "cgroupfs"
// and "systemd".
- CgroupManager string `toml:"cgroup_manager"`
+ CgroupManager string `toml:"cgroup_manager,omitempty"`
// InitPath is the path to the container-init binary.
- InitPath string `toml:"init_path"`
+ InitPath string `toml:"init_path,omitempty"`
// StaticDir is the path to a persistent directory to store container
// files.
- StaticDir string `toml:"static_dir"`
+ StaticDir string `toml:"static_dir,omitempty"`
// 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"`
+ TmpDir string `toml:"tmp_dir,omitempty"`
// 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"`
+ NoPivotRoot bool `toml:"no_pivot_root,omitempty"`
// CNIConfigDir sets the directory where CNI configuration files are
// stored.
- CNIConfigDir string `toml:"cni_config_dir"`
+ CNIConfigDir string `toml:"cni_config_dir,omitempty"`
// CNIPluginDir sets a number of directories where the CNI network
// plugins can be located.
- CNIPluginDir []string `toml:"cni_plugin_dir"`
+ CNIPluginDir []string `toml:"cni_plugin_dir,omitempty"`
// CNIDefaultNetwork is the network name of the default CNI network
// to attach pods to.
@@ -213,7 +214,7 @@ type Config struct {
// 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"`
+ HooksDir []string `toml:"hooks_dir,omitempty"`
// DefaultMountsFile is the path to the default mounts file for testing
// purposes only.
@@ -229,10 +230,10 @@ type Config struct {
// InfraImage is the image a pod infra container will use to manage
// namespaces.
- InfraImage string `toml:"infra_image"`
+ InfraImage string `toml:"infra_image,omitempty"`
// InfraCommand is the command run to start up a pod infra container.
- InfraCommand string `toml:"infra_command"`
+ InfraCommand string `toml:"infra_command,omitempty"`
// EnablePortReservation determines whether libpod will reserve ports on the
// host when they are forwarded to containers. When enabled, when ports are
@@ -241,13 +242,13 @@ type Config struct {
// 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"`
+ EnablePortReservation bool `toml:"enable_port_reservation,omitempty"`
// EnableLabeling indicates whether libpod will support container labeling.
- EnableLabeling bool `toml:"label"`
+ EnableLabeling bool `toml:"label,omitempty"`
// NetworkCmdPath is the path to the slirp4netns binary.
- NetworkCmdPath string `toml:"network_cmd_path"`
+ NetworkCmdPath string `toml:"network_cmd_path,omitempty"`
// NumLocks is the number of locks to make available for containers and
// pods.
@@ -257,17 +258,21 @@ type Config struct {
LockType string `toml:"lock_type,omitempty"`
// EventsLogger determines where events should be logged.
- EventsLogger string `toml:"events_logger"`
+ EventsLogger string `toml:"events_logger,omitempty"`
// EventsLogFilePath is where the events log is stored.
- EventsLogFilePath string `toml:"events_logfile_path"`
+ EventsLogFilePath string `toml:"events_logfile_path,omitempty"`
//DetachKeys is the sequence of keys used to detach a container.
- DetachKeys string `toml:"detach_keys"`
+ DetachKeys string `toml:"detach_keys,omitempty"`
// SDNotify tells Libpod to allow containers to notify the host systemd of
// readiness using the SD_NOTIFY mechanism.
- SDNotify bool
+ SDNotify bool `toml:",omitempty"`
+
+ // CgroupCheck indicates the configuration has been rewritten after an
+ // upgrade to Fedora 31 to change the default OCI runtime for cgroupsv2.
+ CgroupCheck bool `toml:"cgroup_check,omitempty"`
}
// DBConfig is a set of Libpod runtime configuration settings that are saved in
@@ -449,11 +454,21 @@ func NewConfig(userConfigPath string) (*Config, error) {
if configs, err := systemConfigs(); err != nil {
return nil, errors.Wrapf(err, "error finding config on system")
} else {
+ migrated := false
for _, path := range configs {
systemConfig, err := readConfigFromFile(path)
if err != nil {
return nil, errors.Wrapf(err, "error reading system config %q", path)
}
+ // Handle CGroups v2 configuration migration.
+ // Migrate only the first config, and do it before
+ // merging.
+ if !migrated {
+ if err := cgroupV2Check(path, systemConfig); err != nil {
+ return nil, errors.Wrapf(err, "error rewriting configuration file %s", userConfigPath)
+ }
+ migrated = true
+ }
// 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 {
@@ -550,3 +565,30 @@ func (c *Config) checkCgroupsAndLogger() {
c.EventsLogger = "file"
}
}
+
+// 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 *Config) error {
+ if !tmpConfig.CgroupCheck && rootless.IsRootless() {
+ logrus.Debugf("Rewriting %s for CGroup v2 upgrade", configPath)
+ 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
+ if err := tmpConfig.Write(configPath); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
diff --git a/libpod/container_api.go b/libpod/container_api.go
index 153a1d628..5168dbc68 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -594,7 +594,12 @@ func (c *Container) Cleanup(ctx context.Context) error {
// If we didn't restart, we perform a normal cleanup
- // Check if we have active exec sessions
+ // Reap exec sessions first.
+ if err := c.reapExecSessions(); err != nil {
+ return err
+ }
+
+ // Check if we have active exec sessions after reaping.
if len(c.state.ExecSessions) != 0 {
return errors.Wrapf(define.ErrCtrStateInvalid, "container %s has active exec sessions, refusing to clean up", c.ID())
}
diff --git a/libpod/container_commit.go b/libpod/container_commit.go
index 42f298a81..a0ba57f4f 100644
--- a/libpod/container_commit.go
+++ b/libpod/container_commit.go
@@ -3,7 +3,6 @@ package libpod
import (
"context"
"fmt"
- "os"
"strings"
"github.com/containers/buildah"
@@ -12,6 +11,7 @@ import (
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/libpod/image"
+ libpodutil "github.com/containers/libpod/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -32,10 +32,6 @@ type ContainerCommitOptions struct {
// Commit commits the changes between a container and its image, creating a new
// image
func (c *Container) Commit(ctx context.Context, destImage string, options ContainerCommitOptions) (*image.Image, error) {
- var (
- isEnvCleared, isLabelCleared, isExposeCleared, isVolumeCleared bool
- )
-
if c.config.Rootfs != "" {
return nil, errors.Errorf("cannot commit a container that uses an exploded rootfs")
}
@@ -51,7 +47,7 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai
if c.state.State == define.ContainerStateRunning && options.Pause {
if err := c.pause(); err != nil {
- return nil, errors.Wrapf(err, "error pausing container %q", c.ID())
+ return nil, errors.Wrapf(err, "error pausing container %q to commit", c.ID())
}
defer func() {
if err := c.unpause(); err != nil {
@@ -103,7 +99,7 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai
}
// Expose ports
for _, p := range c.config.PortMappings {
- importBuilder.SetPort(fmt.Sprintf("%d", p.ContainerPort))
+ importBuilder.SetPort(fmt.Sprintf("%d/%s", p.ContainerPort, p.Protocol))
}
// Labels
for k, v := range c.Labels() {
@@ -111,7 +107,9 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai
}
// No stop signal
// User
- importBuilder.SetUser(c.User())
+ if c.config.User != "" {
+ importBuilder.SetUser(c.config.User)
+ }
// Volumes
if options.IncludeVolumes {
for _, v := range c.config.UserVolumes {
@@ -119,107 +117,76 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai
importBuilder.AddVolume(v)
}
}
- }
- // Workdir
- importBuilder.SetWorkDir(c.Spec().Process.Cwd)
-
- genCmd := func(cmd string) []string {
- trim := func(cmd []string) []string {
- if len(cmd) == 0 {
- return cmd
+ } else {
+ // Only include anonymous named volumes added by the user by
+ // default.
+ for _, v := range c.config.NamedVolumes {
+ include := false
+ for _, userVol := range c.config.UserVolumes {
+ if userVol == v.Dest {
+ include = true
+ break
+ }
}
-
- retCmd := []string{}
- for _, c := range cmd {
- if len(c) >= 2 {
- if c[0] == '"' && c[len(c)-1] == '"' {
- retCmd = append(retCmd, c[1:len(c)-1])
- continue
- }
+ if include {
+ vol, err := c.runtime.GetVolume(v.Name)
+ if err != nil {
+ return nil, errors.Wrapf(err, "volume %s used in container %s has been removed", v.Name, c.ID())
+ }
+ if vol.IsCtrSpecific() {
+ importBuilder.AddVolume(v.Dest)
}
- retCmd = append(retCmd, c)
}
- return retCmd
}
- if strings.HasPrefix(cmd, "[") {
- cmd = strings.TrimPrefix(cmd, "[")
- cmd = strings.TrimSuffix(cmd, "]")
- return trim(strings.Split(cmd, ","))
- }
- return []string{"/bin/sh", "-c", cmd}
}
- // Process user changes
- for _, change := range options.Changes {
- splitChange := strings.SplitN(change, "=", 2)
- if len(splitChange) != 2 {
- splitChange = strings.SplitN(change, " ", 2)
- if len(splitChange) < 2 {
- return nil, errors.Errorf("invalid change %s format", change)
- }
- }
+ // Workdir
+ importBuilder.SetWorkDir(c.config.Spec.Process.Cwd)
- switch strings.ToUpper(splitChange[0]) {
- case "CMD":
- importBuilder.SetCmd(genCmd(splitChange[1]))
- case "ENTRYPOINT":
- importBuilder.SetEntrypoint(genCmd(splitChange[1]))
- case "ENV":
- change := strings.Split(splitChange[1], " ")
- name := change[0]
- val := ""
- if len(change) < 2 {
- change = strings.Split(change[0], "=")
- }
- if len(change) < 2 {
- var ok bool
- val, ok = os.LookupEnv(name)
- if !ok {
- return nil, errors.Errorf("invalid env variable %q: not defined in your environment", name)
- }
- } else {
- name = change[0]
- val = strings.Join(change[1:], " ")
- }
- if !isEnvCleared { // Multiple values are valid, only clear once.
- importBuilder.ClearEnv()
- isEnvCleared = true
- }
- importBuilder.SetEnv(name, val)
- case "EXPOSE":
- if !isExposeCleared { // Multiple values are valid, only clear once
- importBuilder.ClearPorts()
- isExposeCleared = true
- }
- importBuilder.SetPort(splitChange[1])
- case "LABEL":
- change := strings.Split(splitChange[1], " ")
- if len(change) < 2 {
- change = strings.Split(change[0], "=")
- }
- if len(change) < 2 {
- return nil, errors.Errorf("invalid label %s format, requires to NAME=VAL", splitChange[1])
- }
- if !isLabelCleared { // multiple values are valid, only clear once
- importBuilder.ClearLabels()
- isLabelCleared = true
- }
- importBuilder.SetLabel(change[0], strings.Join(change[1:], " "))
- case "ONBUILD":
- importBuilder.SetOnBuild(splitChange[1])
- case "STOPSIGNAL":
- // No Set StopSignal
- case "USER":
- importBuilder.SetUser(splitChange[1])
- case "VOLUME":
- if !isVolumeCleared { // multiple values are valid, only clear once
- importBuilder.ClearVolumes()
- isVolumeCleared = true
- }
- importBuilder.AddVolume(splitChange[1])
- case "WORKDIR":
- importBuilder.SetWorkDir(splitChange[1])
+ // Process user changes
+ newImageConfig, err := libpodutil.GetImageConfig(options.Changes)
+ if err != nil {
+ return nil, err
+ }
+ if newImageConfig.User != "" {
+ importBuilder.SetUser(newImageConfig.User)
+ }
+ // EXPOSE only appends
+ for port := range newImageConfig.ExposedPorts {
+ importBuilder.SetPort(port)
+ }
+ // ENV only appends
+ for _, env := range newImageConfig.Env {
+ splitEnv := strings.SplitN(env, "=", 2)
+ key := splitEnv[0]
+ value := ""
+ if len(splitEnv) == 2 {
+ value = splitEnv[1]
}
+ importBuilder.SetEnv(key, value)
}
+ if newImageConfig.Entrypoint != nil {
+ importBuilder.SetEntrypoint(newImageConfig.Entrypoint)
+ }
+ if newImageConfig.Cmd != nil {
+ importBuilder.SetCmd(newImageConfig.Cmd)
+ }
+ // VOLUME only appends
+ for vol := range newImageConfig.Volumes {
+ importBuilder.AddVolume(vol)
+ }
+ if newImageConfig.WorkingDir != "" {
+ importBuilder.SetWorkDir(newImageConfig.WorkingDir)
+ }
+ for k, v := range newImageConfig.Labels {
+ importBuilder.SetLabel(k, v)
+ }
+ if newImageConfig.StopSignal != "" {
+ importBuilder.SetStopSignal(newImageConfig.StopSignal)
+ }
+ for _, onbuild := range newImageConfig.OnBuild {
+ importBuilder.SetOnBuild(onbuild)
+ }
+
candidates, _, _, err := util.ResolveName(destImage, "", sc, c.runtime.store)
if err != nil {
return nil, errors.Wrapf(err, "error resolving name %q", destImage)
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 1e8a8a580..37801162a 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -1749,6 +1749,11 @@ func (c *Container) checkReadyForRemoval() error {
return errors.Wrapf(define.ErrCtrStateInvalid, "cannot remove container %s as it is %s - running or paused containers cannot be removed without force", c.ID(), c.state.State.String())
}
+ // Reap exec sessions
+ if err := c.reapExecSessions(); err != nil {
+ return err
+ }
+
if len(c.state.ExecSessions) != 0 {
return errors.Wrapf(define.ErrCtrStateInvalid, "cannot remove container %s as it has active exec sessions", c.ID())
}
@@ -1855,3 +1860,38 @@ func (c *Container) checkExitFile() error {
// Read the exit file to get our stopped time and exit code.
return c.handleExitFile(exitFile, info)
}
+
+// Reap dead exec sessions
+func (c *Container) reapExecSessions() error {
+ // Instead of saving once per iteration, use a defer to do it once at
+ // the end.
+ var lastErr error
+ needSave := false
+ for id := range c.state.ExecSessions {
+ alive, err := c.ociRuntime.ExecUpdateStatus(c, id)
+ if err != nil {
+ if lastErr != nil {
+ logrus.Errorf("Error reaping exec sessions for container %s: %v", c.ID(), lastErr)
+ }
+ lastErr = err
+ continue
+ }
+ if !alive {
+ // Clean up lingering files and remove the exec session
+ if err := c.ociRuntime.ExecContainerCleanup(c, id); err != nil {
+ return errors.Wrapf(err, "error cleaning up container %s exec session %s files", c.ID(), id)
+ }
+ delete(c.state.ExecSessions, id)
+ needSave = true
+ }
+ }
+ if needSave {
+ if err := c.save(); err != nil {
+ if lastErr != nil {
+ logrus.Errorf("Error reaping exec sessions for container %s: %v", c.ID(), lastErr)
+ }
+ lastErr = err
+ }
+ }
+ return lastErr
+}
diff --git a/cmd/podman/imagefilters/filters.go b/libpod/image/filters.go
index 0b08314ce..d545f1bfc 100644
--- a/cmd/podman/imagefilters/filters.go
+++ b/libpod/image/filters.go
@@ -1,29 +1,30 @@
-package imagefilters
+package image
import (
"context"
"fmt"
+ "github.com/pkg/errors"
"path/filepath"
+ "strconv"
"strings"
"time"
- "github.com/containers/libpod/pkg/adapter"
"github.com/containers/libpod/pkg/inspect"
"github.com/sirupsen/logrus"
)
// ResultFilter is a mock function for image filtering
-type ResultFilter func(*adapter.ContainerImage) bool
+type ResultFilter func(*Image) bool
// Filter is a function to determine whether an image is included in
// command output. Images to be outputted are tested using the function. A true
// return will include the image, a false return will exclude it.
-type Filter func(*adapter.ContainerImage, *inspect.ImageData) bool
+type Filter func(*Image, *inspect.ImageData) bool
// CreatedBeforeFilter allows you to filter on images created before
// the given time.Time
func CreatedBeforeFilter(createTime time.Time) ResultFilter {
- return func(i *adapter.ContainerImage) bool {
+ return func(i *Image) bool {
return i.Created().Before(createTime)
}
}
@@ -31,14 +32,14 @@ func CreatedBeforeFilter(createTime time.Time) ResultFilter {
// CreatedAfterFilter allows you to filter on images created after
// the given time.Time
func CreatedAfterFilter(createTime time.Time) ResultFilter {
- return func(i *adapter.ContainerImage) bool {
+ return func(i *Image) bool {
return i.Created().After(createTime)
}
}
// DanglingFilter allows you to filter images for dangling images
func DanglingFilter(danglingImages bool) ResultFilter {
- return func(i *adapter.ContainerImage) bool {
+ return func(i *Image) bool {
if danglingImages {
return i.Dangling()
}
@@ -48,7 +49,7 @@ func DanglingFilter(danglingImages bool) ResultFilter {
// ReadOnlyFilter allows you to filter images based on read/only and read/write
func ReadOnlyFilter(readOnly bool) ResultFilter {
- return func(i *adapter.ContainerImage) bool {
+ return func(i *Image) bool {
if readOnly {
return i.IsReadOnly()
}
@@ -59,7 +60,7 @@ func ReadOnlyFilter(readOnly bool) ResultFilter {
// LabelFilter allows you to filter by images labels key and/or value
func LabelFilter(ctx context.Context, labelfilter string) ResultFilter {
// We need to handle both label=key and label=key=value
- return func(i *adapter.ContainerImage) bool {
+ return func(i *Image) bool {
var value string
splitFilter := strings.Split(labelfilter, "=")
key := splitFilter[0]
@@ -83,7 +84,10 @@ func LabelFilter(ctx context.Context, labelfilter string) ResultFilter {
func ReferenceFilter(ctx context.Context, referenceFilter string) ResultFilter {
filter := fmt.Sprintf("*%s*", referenceFilter)
filter = strings.Replace(filter, "/", "|", -1)
- return func(i *adapter.ContainerImage) bool {
+ return func(i *Image) bool {
+ if len(referenceFilter) < 1 {
+ return true
+ }
for _, name := range i.Names() {
newName := strings.Replace(name, "/", "|", -1)
match, err := filepath.Match(filter, newName)
@@ -99,15 +103,15 @@ func ReferenceFilter(ctx context.Context, referenceFilter string) ResultFilter {
}
// OutputImageFilter allows you to filter by an a specific image name
-func OutputImageFilter(userImage *adapter.ContainerImage) ResultFilter {
- return func(i *adapter.ContainerImage) bool {
+func OutputImageFilter(userImage *Image) ResultFilter {
+ return func(i *Image) bool {
return userImage.ID() == i.ID()
}
}
// FilterImages filters images using a set of predefined filter funcs
-func FilterImages(images []*adapter.ContainerImage, filters []ResultFilter) []*adapter.ContainerImage {
- var filteredImages []*adapter.ContainerImage
+func FilterImages(images []*Image, filters []ResultFilter) []*Image {
+ var filteredImages []*Image
for _, image := range images {
include := true
for _, filter := range filters {
@@ -119,3 +123,54 @@ func FilterImages(images []*adapter.ContainerImage, filters []ResultFilter) []*a
}
return filteredImages
}
+
+// createFilterFuncs returns an array of filter functions based on the user inputs
+// and is later used to filter images for output
+func (ir *Runtime) createFilterFuncs(filters []string, img *Image) ([]ResultFilter, error) {
+ var filterFuncs []ResultFilter
+ ctx := context.Background()
+ for _, filter := range filters {
+ splitFilter := strings.Split(filter, "=")
+ if len(splitFilter) < 2 {
+ return nil, errors.Errorf("invalid filter syntax %s", filter)
+ }
+ switch splitFilter[0] {
+ case "before":
+ before, err := ir.NewFromLocal(splitFilter[1])
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to find image %s in local stores", splitFilter[1])
+ }
+ filterFuncs = append(filterFuncs, CreatedBeforeFilter(before.Created()))
+ case "after":
+ after, err := ir.NewFromLocal(splitFilter[1])
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to find image %s in local stores", splitFilter[1])
+ }
+ filterFuncs = append(filterFuncs, CreatedAfterFilter(after.Created()))
+ case "readonly":
+ readonly, err := strconv.ParseBool(splitFilter[1])
+ if err != nil {
+ return nil, errors.Wrapf(err, "invalid filter readonly=%s", splitFilter[1])
+ }
+ filterFuncs = append(filterFuncs, ReadOnlyFilter(readonly))
+ case "dangling":
+ danglingImages, err := strconv.ParseBool(splitFilter[1])
+ if err != nil {
+ return nil, errors.Wrapf(err, "invalid filter dangling=%s", splitFilter[1])
+ }
+ filterFuncs = append(filterFuncs, DanglingFilter(danglingImages))
+ case "label":
+ labelFilter := strings.Join(splitFilter[1:], "=")
+ filterFuncs = append(filterFuncs, LabelFilter(ctx, labelFilter))
+ case "reference":
+ referenceFilter := strings.Join(splitFilter[1:], "=")
+ filterFuncs = append(filterFuncs, ReferenceFilter(ctx, referenceFilter))
+ default:
+ return nil, errors.Errorf("invalid filter %s ", splitFilter[0])
+ }
+ }
+ if img != nil {
+ filterFuncs = append(filterFuncs, OutputImageFilter(img))
+ }
+ return filterFuncs, nil
+}
diff --git a/libpod/image/image.go b/libpod/image/image.go
index 129ccd376..c8583a1c5 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -216,6 +216,19 @@ func (ir *Runtime) Shutdown(force bool) error {
return err
}
+// GetImagesWithFilters gets images with a series of filters applied
+func (ir *Runtime) GetImagesWithFilters(filters []string) ([]*Image, error) {
+ filterFuncs, err := ir.createFilterFuncs(filters, nil)
+ if err != nil {
+ return nil, err
+ }
+ images, err := ir.GetImages()
+ if err != nil {
+ return nil, err
+ }
+ return FilterImages(images, filterFuncs), nil
+}
+
func (i *Image) reloadImage() error {
newImage, err := i.imageruntime.getImage(i.ID())
if err != nil {
diff --git a/libpod/oci.go b/libpod/oci.go
index 9e761788e..05a2f37db 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -23,9 +23,6 @@ type OCIRuntime interface {
// CreateContainer creates the container in the OCI runtime.
CreateContainer(ctr *Container, restoreOptions *ContainerCheckpointOptions) error
// UpdateContainerStatus updates the status of the given container.
- // It includes a switch for whether to perform a hard query of the
- // runtime. If unset, the exit file (if supported by the implementation)
- // will be used.
UpdateContainerStatus(ctr *Container) error
// StartContainer starts the given container.
StartContainer(ctr *Container) error
@@ -59,6 +56,9 @@ type OCIRuntime interface {
// If timeout is 0, SIGKILL will be sent immediately, and SIGTERM will
// be omitted.
ExecStopContainer(ctr *Container, sessionID string, timeout uint) error
+ // ExecUpdateStatus checks the status of a given exec session.
+ // Returns true if the session is still running, or false if it exited.
+ ExecUpdateStatus(ctr *Container, sessionID string) (bool, error)
// ExecContainerCleanup cleans up after an exec session exits.
// It removes any files left by the exec session that are no longer
// needed, including the attach socket.
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 026b13129..37aa71cbb 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -687,6 +687,28 @@ func (r *ConmonOCIRuntime) ExecStopContainer(ctr *Container, sessionID string, t
return nil
}
+// ExecUpdateStatus checks if the given exec session is still running.
+func (r *ConmonOCIRuntime) ExecUpdateStatus(ctr *Container, sessionID string) (bool, error) {
+ session, ok := ctr.state.ExecSessions[sessionID]
+ if !ok {
+ // TODO This should probably be a separate error
+ return false, errors.Wrapf(define.ErrInvalidArg, "no exec session with ID %s found in container %s", sessionID, ctr.ID())
+ }
+
+ logrus.Debugf("Checking status of container %s exec session %s", ctr.ID(), sessionID)
+
+ // Is the session dead?
+ // Ping the PID with signal 0 to see if it still exists.
+ if err := unix.Kill(session.PID, 0); err != nil {
+ if err == unix.ESRCH {
+ return false, nil
+ }
+ return false, errors.Wrapf(err, "error pinging container %s exec session %s PID %d with signal 0", ctr.ID(), sessionID, session.PID)
+ }
+
+ return true, nil
+}
+
// ExecCleanupContainer cleans up files created when a command is run via
// ExecContainer. This includes the attach socket for the exec session.
func (r *ConmonOCIRuntime) ExecContainerCleanup(ctr *Container, sessionID string) error {
diff --git a/libpod/oci_missing.go b/libpod/oci_missing.go
index d4524cd34..0faa1805b 100644
--- a/libpod/oci_missing.go
+++ b/libpod/oci_missing.go
@@ -120,6 +120,11 @@ func (r *MissingRuntime) ExecStopContainer(ctr *Container, sessionID string, tim
return r.printError()
}
+// ExecUpdateStatus is not available as the runtime is missing.
+func (r *MissingRuntime) ExecUpdateStatus(ctr *Container, sessionID string) (bool, error) {
+ return false, r.printError()
+}
+
// ExecContainerCleanup is not available as the runtime is missing
func (r *MissingRuntime) ExecContainerCleanup(ctr *Container, sessionID string) error {
return r.printError()
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index f2784c07d..abd8b581d 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -160,10 +160,11 @@ func (r *Runtime) Import(ctx context.Context, source string, reference string, c
ic := v1.ImageConfig{}
if len(changes) > 0 {
- ic, err = util.GetImageConfig(changes)
+ config, err := util.GetImageConfig(changes)
if err != nil {
return "", errors.Wrapf(err, "error adding config changes to image %q", source)
}
+ ic = config.ImageConfig
}
hist := []v1.History{
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 0c73977c7..3334e9fa1 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -367,6 +367,23 @@ func (r *LocalRuntime) CreateContainer(ctx context.Context, c *cliconfig.CreateV
return ctr.ID(), nil
}
+// Select the detach keys to use from user input flag, config file, or default value
+func (r *LocalRuntime) selectDetachKeys(flagValue string) (string, error) {
+ if flagValue != "" {
+ return flagValue, nil
+ }
+
+ config, err := r.GetConfig()
+ if err != nil {
+ return "", errors.Wrapf(err, "unable to retrive runtime config")
+ }
+ if config.DetachKeys != "" {
+ return config.DetachKeys, nil
+ }
+
+ return define.DefaultDetachKeys, nil
+}
+
// Run a libpod container
func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode int) (int, error) {
results := shared.NewIntermediateLayer(&c.PodmanCommand, false)
@@ -428,8 +445,13 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode
}
}
+ keys, err := r.selectDetachKeys(c.String("detach-keys"))
+ if err != nil {
+ return exitCode, err
+ }
+
// if the container was created as part of a pod, also start its dependencies, if any.
- if err := StartAttachCtr(ctx, ctr, outputStream, errorStream, inputStream, c.String("detach-keys"), c.Bool("sig-proxy"), true, c.IsSet("pod")); err != nil {
+ if err := StartAttachCtr(ctx, ctr, outputStream, errorStream, inputStream, 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
@@ -512,8 +534,14 @@ func (r *LocalRuntime) Attach(ctx context.Context, c *cliconfig.AttachValues) er
if c.NoStdin {
inputStream = nil
}
+
+ keys, err := r.selectDetachKeys(c.DetachKeys)
+ if err != nil {
+ return err
+ }
+
// If the container is in a pod, also set to recursively start dependencies
- if err := StartAttachCtr(ctx, ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, c.SigProxy, false, ctr.PodID() != ""); err != nil && errors.Cause(err) != define.ErrDetach {
+ if err := StartAttachCtr(ctx, ctr, os.Stdout, os.Stderr, inputStream, keys, c.SigProxy, false, ctr.PodID() != ""); err != nil && errors.Cause(err) != define.ErrDetach {
return errors.Wrapf(err, "error attaching to container %s", ctr.ID())
}
return nil
@@ -646,9 +674,14 @@ func (r *LocalRuntime) Start(ctx context.Context, c *cliconfig.StartValues, sigP
}
}
+ keys, err := r.selectDetachKeys(c.DetachKeys)
+ if err != nil {
+ return exitCode, err
+ }
+
// attach to the container and also start it not already running
// If the container is in a pod, also set to recursively start dependencies
- err = StartAttachCtr(ctx, ctr.Container, os.Stdout, os.Stderr, inputStream, c.DetachKeys, sigProxy, !ctrRunning, ctr.PodID() != "")
+ err = StartAttachCtr(ctx, ctr.Container, os.Stdout, os.Stderr, inputStream, keys, sigProxy, !ctrRunning, ctr.PodID() != "")
if errors.Cause(err) == define.ErrDetach {
// User manually detached
// Exit cleanly immediately
@@ -991,7 +1024,7 @@ func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecVal
// Validate given environment variables
env := map[string]string{}
- if err := parse.ReadKVStrings(env, []string{}, cli.Env); err != nil {
+ if err := parse.ReadKVStrings(env, cli.EnvFile, cli.Env); err != nil {
return ec, errors.Wrapf(err, "unable to process environment variables")
}
@@ -1005,7 +1038,12 @@ func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecVal
streams.AttachOutput = true
streams.AttachError = true
- ec, err = ExecAttachCtr(ctx, ctr.Container, cli.Tty, cli.Privileged, env, cmd, cli.User, cli.Workdir, streams, uint(cli.PreserveFDs), cli.DetachKeys)
+ keys, err := r.selectDetachKeys(cli.DetachKeys)
+ if err != nil {
+ return ec, err
+ }
+
+ ec, err = ExecAttachCtr(ctx, ctr.Container, cli.Tty, cli.Privileged, env, cmd, cli.User, cli.Workdir, streams, uint(cli.PreserveFDs), keys)
return define.TranslateExecErrorToExitCode(ec, err), err
}
diff --git a/pkg/adapter/network.go b/pkg/adapter/network.go
index 9659ae339..160e334e9 100644
--- a/pkg/adapter/network.go
+++ b/pkg/adapter/network.go
@@ -153,8 +153,8 @@ func (r *LocalRuntime) removeNetwork(ctx context.Context, name string, container
return nil
}
-// NetworkCreate creates a CNI network
-func (r *LocalRuntime) NetworkCreate(cli *cliconfig.NetworkCreateValues) (string, error) {
+// NetworkCreateBridge creates a CNI network
+func (r *LocalRuntime) NetworkCreateBridge(cli *cliconfig.NetworkCreateValues) (string, error) {
isGateway := true
ipMasq := true
subnet := &cli.Network
@@ -262,3 +262,50 @@ func (r *LocalRuntime) NetworkCreate(cli *cliconfig.NetworkCreateValues) (string
err = ioutil.WriteFile(cniPathName, b, 0644)
return cniPathName, err
}
+
+// NetworkCreateMacVLAN creates a CNI network
+func (r *LocalRuntime) NetworkCreateMacVLAN(cli *cliconfig.NetworkCreateValues) (string, error) {
+ var (
+ name string
+ plugins []network.CNIPlugins
+ )
+ liveNetNames, err := network.GetLiveNetworkNames()
+ if err != nil {
+ return "", err
+ }
+ // Make sure the host-device exists
+ if !util.StringInSlice(cli.MacVLAN, liveNetNames) {
+ return "", errors.Errorf("failed to find network interface %q", cli.MacVLAN)
+ }
+ if len(cli.InputArgs) > 0 {
+ name = cli.InputArgs[0]
+ netNames, err := network.GetNetworkNamesFromFileSystem()
+ if err != nil {
+ return "", err
+ }
+ if util.StringInSlice(name, netNames) {
+ return "", errors.Errorf("the network name %s is already used", name)
+ }
+ }
+ if len(name) < 1 {
+ name, err = network.GetFreeDeviceName()
+ if err != nil {
+ return "", err
+ }
+ }
+ ncList := network.NewNcList(name, cniversion.Current())
+ macvlan := network.NewMacVLANPlugin(cli.MacVLAN)
+ plugins = append(plugins, macvlan)
+ ncList["plugins"] = plugins
+ b, err := json.MarshalIndent(ncList, "", " ")
+ if err != nil {
+ return "", err
+ }
+ cniConfigPath, err := getCNIConfDir(r)
+ if err != nil {
+ return "", err
+ }
+ cniPathName := filepath.Join(cniConfigPath, fmt.Sprintf("%s.conflist", name))
+ err = ioutil.WriteFile(cniPathName, b, 0644)
+ return cniPathName, err
+}
diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go
index 069283bde..ac843b655 100644
--- a/pkg/adapter/runtime.go
+++ b/pkg/adapter/runtime.go
@@ -84,6 +84,15 @@ func getRuntime(runtime *libpod.Runtime) (*LocalRuntime, error) {
}, nil
}
+// GetFilterImages returns a slice of images in containerimages that are "filtered"
+func (r *LocalRuntime) GetFilteredImages(filters []string, rwOnly bool) ([]*ContainerImage, error) {
+ images, err := r.ImageRuntime().GetImagesWithFilters(filters)
+ if err != nil {
+ return nil, err
+ }
+ return r.ImagestoContainerImages(images, rwOnly)
+}
+
// GetImages returns a slice of images in containerimages
func (r *LocalRuntime) GetImages() ([]*ContainerImage, error) {
return r.getImages(false)
@@ -95,11 +104,15 @@ func (r *LocalRuntime) GetRWImages() ([]*ContainerImage, error) {
}
func (r *LocalRuntime) getImages(rwOnly bool) ([]*ContainerImage, error) {
- var containerImages []*ContainerImage
images, err := r.Runtime.ImageRuntime().GetImages()
if err != nil {
return nil, err
}
+ return r.ImagestoContainerImages(images, rwOnly)
+}
+
+func (r *LocalRuntime) ImagestoContainerImages(images []*image.Image, rwOnly bool) ([]*ContainerImage, error) {
+ var containerImages []*ContainerImage
for _, i := range images {
if rwOnly && i.IsReadOnly() {
continue
diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go
index f9232897c..87b4999ce 100644
--- a/pkg/adapter/runtime_remote.go
+++ b/pkg/adapter/runtime_remote.go
@@ -200,6 +200,28 @@ func (r *LocalRuntime) GetRWImages() ([]*ContainerImage, error) {
return r.getImages(true)
}
+func (r *LocalRuntime) GetFilteredImages(filters []string, rwOnly bool) ([]*ContainerImage, error) {
+ var newImages []*ContainerImage
+ images, err := iopodman.ListImagesWithFilters().Call(r.Conn, filters)
+ if err != nil {
+ return nil, err
+ }
+ for _, i := range images {
+ if rwOnly && i.ReadOnly {
+ continue
+ }
+ name := i.Id
+ if len(i.RepoTags) > 1 {
+ name = i.RepoTags[0]
+ }
+ newImage, err := imageInListToContainerImage(i, name, r)
+ if err != nil {
+ return nil, err
+ }
+ newImages = append(newImages, newImage)
+ }
+ return newImages, nil
+}
func (r *LocalRuntime) getImages(rwOnly bool) ([]*ContainerImage, error) {
var newImages []*ContainerImage
images, err := iopodman.ListImages().Call(r.Conn)
diff --git a/pkg/network/config.go b/pkg/network/config.go
index 37eb0dd64..e47b16143 100644
--- a/pkg/network/config.go
+++ b/pkg/network/config.go
@@ -90,6 +90,22 @@ func (p PortMapConfig) Bytes() ([]byte, error) {
return json.MarshalIndent(p, "", "\t")
}
+type IPAMDHCP struct {
+ DHCP string `json:"type"`
+}
+
+// MacVLANConfig describes the macvlan config
+type MacVLANConfig struct {
+ PluginType string `json:"type"`
+ Master string `json:"master"`
+ IPAM IPAMDHCP `json:"ipam"`
+}
+
+// Bytes outputs the configuration as []byte
+func (p MacVLANConfig) Bytes() ([]byte, error) {
+ return json.MarshalIndent(p, "", "\t")
+}
+
// FirewallConfig describes the firewall plugin
type FirewallConfig struct {
PluginType string `json:"type"`
diff --git a/pkg/network/netconflist.go b/pkg/network/netconflist.go
index e19051b88..a8217097a 100644
--- a/pkg/network/netconflist.go
+++ b/pkg/network/netconflist.go
@@ -132,3 +132,15 @@ func HasDNSNamePlugin(paths []string) bool {
}
return false
}
+
+// NewMacVLANPlugin creates a macvlanconfig with a given device name
+func NewMacVLANPlugin(device string) MacVLANConfig {
+ i := IPAMDHCP{DHCP: "dhcp"}
+
+ m := MacVLANConfig{
+ PluginType: "macvlan",
+ Master: device,
+ IPAM: i,
+ }
+ return m
+}
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index 6906b26d5..5b4dfe9fa 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -1,11 +1,12 @@
package util
import (
+ "encoding/json"
"fmt"
"os"
"os/user"
"path/filepath"
- "regexp"
+ "strconv"
"strings"
"sync"
"time"
@@ -18,6 +19,7 @@ import (
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/storage"
"github.com/containers/storage/pkg/idtools"
+ "github.com/docker/docker/pkg/signal"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -71,118 +73,236 @@ func StringInSlice(s string, sl []string) bool {
return false
}
-// ParseChanges returns key, value(s) pair for given option.
-func ParseChanges(option string) (key string, vals []string, err error) {
- // Supported format as below
- // 1. key=value
- // 2. key value
- // 3. key ["value","value1"]
- if strings.Contains(option, " ") {
- // This handles 2 & 3 conditions.
- var val string
- tokens := strings.SplitAfterN(option, " ", 2)
- if len(tokens) < 2 {
- return "", []string{}, fmt.Errorf("invalid key value %s", option)
- }
- key = strings.Trim(tokens[0], " ") // Need to trim whitespace part of delimiter.
- val = tokens[1]
- if strings.Contains(tokens[1], "[") && strings.Contains(tokens[1], "]") {
- //Trim '[',']' if exist.
- val = strings.TrimLeft(strings.TrimRight(tokens[1], "]"), "[")
- }
- vals = strings.Split(val, ",")
- } else if strings.Contains(option, "=") {
- // handles condition 1.
- tokens := strings.Split(option, "=")
- key = tokens[0]
- vals = tokens[1:]
- } else {
- // either ` ` or `=` must be provided after command
- return "", []string{}, fmt.Errorf("invalid format %s", option)
- }
-
- if len(vals) == 0 {
- return "", []string{}, errors.Errorf("no value given for instruction %q", key)
- }
-
- for _, v := range vals {
- //each option must not have ' '., `[`` or `]` & empty strings
- whitespaces := regexp.MustCompile(`[\[\s\]]`)
- if whitespaces.MatchString(v) || len(v) == 0 {
- return "", []string{}, fmt.Errorf("invalid value %s", v)
- }
- }
- return key, vals, nil
+// ImageConfig is a wrapper around the OCIv1 Image Configuration struct exported
+// by containers/image, but containing additional fields that are not supported
+// by OCIv1 (but are by Docker v2) - notably OnBuild.
+type ImageConfig struct {
+ v1.ImageConfig
+ OnBuild []string
}
-// GetImageConfig converts the --change flag values in the format "CMD=/bin/bash USER=example"
-// to a type v1.ImageConfig
-func GetImageConfig(changes []string) (v1.ImageConfig, error) {
- // USER=value | EXPOSE=value | ENV=value | ENTRYPOINT=value |
- // CMD=value | VOLUME=value | WORKDIR=value | LABEL=key=value | STOPSIGNAL=value
-
- var (
- user string
- env []string
- entrypoint []string
- cmd []string
- workingDir string
- stopSignal string
- )
-
- exposedPorts := make(map[string]struct{})
- volumes := make(map[string]struct{})
- labels := make(map[string]string)
- for _, ch := range changes {
- key, vals, err := ParseChanges(ch)
- if err != nil {
- return v1.ImageConfig{}, err
+// GetImageConfig produces a v1.ImageConfig from the --change flag that is
+// accepted by several Podman commands. It accepts a (limited subset) of
+// Dockerfile instructions.
+func GetImageConfig(changes []string) (ImageConfig, error) {
+ // Valid changes:
+ // USER
+ // EXPOSE
+ // ENV
+ // ENTRYPOINT
+ // CMD
+ // VOLUME
+ // WORKDIR
+ // LABEL
+ // STOPSIGNAL
+ // ONBUILD
+
+ config := ImageConfig{}
+
+ for _, change := range changes {
+ // First, let's assume proper Dockerfile format - space
+ // separator between instruction and value
+ split := strings.SplitN(change, " ", 2)
+
+ if len(split) != 2 {
+ split = strings.SplitN(change, "=", 2)
+ if len(split) != 2 {
+ return ImageConfig{}, errors.Errorf("invalid change %q - must be formatted as KEY VALUE", change)
+ }
}
- switch key {
+ outerKey := strings.ToUpper(strings.TrimSpace(split[0]))
+ value := strings.TrimSpace(split[1])
+ switch outerKey {
case "USER":
- user = vals[0]
+ // Assume literal contents are the user.
+ if value == "" {
+ return ImageConfig{}, errors.Errorf("invalid change %q - must provide a value to USER", change)
+ }
+ config.User = value
case "EXPOSE":
- var st struct{}
- exposedPorts[vals[0]] = st
+ // EXPOSE is either [portnum] or
+ // [portnum]/[proto]
+ // Protocol must be "tcp" or "udp"
+ splitPort := strings.Split(value, "/")
+ if len(splitPort) > 2 {
+ return ImageConfig{}, errors.Errorf("invalid change %q - EXPOSE port must be formatted as PORT[/PROTO]", change)
+ }
+ portNum, err := strconv.Atoi(splitPort[0])
+ if err != nil {
+ return ImageConfig{}, errors.Wrapf(err, "invalid change %q - EXPOSE port must be an integer", change)
+ }
+ if portNum > 65535 || portNum <= 0 {
+ return ImageConfig{}, errors.Errorf("invalid change %q - EXPOSE port must be a valid port number", change)
+ }
+ proto := "tcp"
+ if len(splitPort) > 1 {
+ testProto := strings.ToLower(splitPort[1])
+ switch testProto {
+ case "tcp", "udp":
+ proto = testProto
+ default:
+ return ImageConfig{}, errors.Errorf("invalid change %q - EXPOSE protocol must be TCP or UDP", change)
+ }
+ }
+ if config.ExposedPorts == nil {
+ config.ExposedPorts = make(map[string]struct{})
+ }
+ config.ExposedPorts[fmt.Sprintf("%d/%s", portNum, proto)] = struct{}{}
case "ENV":
- if len(vals) < 2 {
- return v1.ImageConfig{}, errors.Errorf("no value given for environment variable %q", vals[0])
+ // Format is either:
+ // ENV key=value
+ // ENV key=value key=value ...
+ // ENV key value
+ // Both keys and values can be surrounded by quotes to group them.
+ // For now: we only support key=value
+ // We will attempt to strip quotation marks if present.
+
+ var (
+ key, val string
+ )
+
+ splitEnv := strings.SplitN(value, "=", 2)
+ key = splitEnv[0]
+ // We do need a key
+ if key == "" {
+ return ImageConfig{}, errors.Errorf("invalid change %q - ENV must have at least one argument", change)
+ }
+ // Perfectly valid to not have a value
+ if len(splitEnv) == 2 {
+ val = splitEnv[1]
+ }
+
+ if strings.HasPrefix(key, `"`) && strings.HasSuffix(key, `"`) {
+ key = strings.TrimPrefix(strings.TrimSuffix(key, `"`), `"`)
+ }
+ if strings.HasPrefix(val, `"`) && strings.HasSuffix(val, `"`) {
+ val = strings.TrimPrefix(strings.TrimSuffix(val, `"`), `"`)
}
- env = append(env, strings.Join(vals[0:], "="))
+ config.Env = append(config.Env, fmt.Sprintf("%s=%s", key, val))
case "ENTRYPOINT":
- // ENTRYPOINT and CMD can have array of strings
- entrypoint = append(entrypoint, vals...)
+ // Two valid forms.
+ // First, JSON array.
+ // Second, not a JSON array - we interpret this as an
+ // argument to `sh -c`, unless empty, in which case we
+ // just use a blank entrypoint.
+ testUnmarshal := []string{}
+ if err := json.Unmarshal([]byte(value), &testUnmarshal); err != nil {
+ // It ain't valid JSON, so assume it's an
+ // argument to sh -c if not empty.
+ if value != "" {
+ config.Entrypoint = []string{"/bin/sh", "-c", value}
+ } else {
+ config.Entrypoint = []string{}
+ }
+ } else {
+ // Valid JSON
+ config.Entrypoint = testUnmarshal
+ }
case "CMD":
- // ENTRYPOINT and CMD can have array of strings
- cmd = append(cmd, vals...)
+ // Same valid forms as entrypoint.
+ // However, where ENTRYPOINT assumes that 'ENTRYPOINT '
+ // means no entrypoint, CMD assumes it is 'sh -c' with
+ // no third argument.
+ testUnmarshal := []string{}
+ if err := json.Unmarshal([]byte(value), &testUnmarshal); err != nil {
+ // It ain't valid JSON, so assume it's an
+ // argument to sh -c.
+ // Only include volume if it's not ""
+ config.Cmd = []string{"/bin/sh", "-c"}
+ if value != "" {
+ config.Cmd = append(config.Cmd, value)
+ }
+ } else {
+ // Valid JSON
+ config.Cmd = testUnmarshal
+ }
case "VOLUME":
- var st struct{}
- volumes[vals[0]] = st
+ // Either a JSON array or a set of space-separated
+ // paths.
+ // Acts rather similar to ENTRYPOINT and CMD, but always
+ // appends rather than replacing, and no sh -c prepend.
+ testUnmarshal := []string{}
+ if err := json.Unmarshal([]byte(value), &testUnmarshal); err != nil {
+ // Not valid JSON, so split on spaces
+ testUnmarshal = strings.Split(value, " ")
+ }
+ if len(testUnmarshal) == 0 {
+ return ImageConfig{}, errors.Errorf("invalid change %q - must provide at least one argument to VOLUME", change)
+ }
+ for _, vol := range testUnmarshal {
+ if vol == "" {
+ return ImageConfig{}, errors.Errorf("invalid change %q - VOLUME paths must not be empty", change)
+ }
+ if config.Volumes == nil {
+ config.Volumes = make(map[string]struct{})
+ }
+ config.Volumes[vol] = struct{}{}
+ }
case "WORKDIR":
- workingDir = vals[0]
+ // This can be passed multiple times.
+ // Each successive invocation is treated as relative to
+ // the previous one - so WORKDIR /A, WORKDIR b,
+ // WORKDIR c results in /A/b/c
+ // Just need to check it's not empty...
+ if value == "" {
+ return ImageConfig{}, errors.Errorf("invalid change %q - must provide a non-empty WORKDIR", change)
+ }
+ config.WorkingDir = filepath.Join(config.WorkingDir, value)
case "LABEL":
- if len(vals) == 2 {
- labels[vals[0]] = vals[1]
- } else {
- labels[vals[0]] = ""
+ // Same general idea as ENV, but we no longer allow " "
+ // as a separator.
+ // We didn't do that for ENV either, so nice and easy.
+ // Potentially problematic: LABEL might theoretically
+ // allow an = in the key? If people really do this, we
+ // may need to investigate more advanced parsing.
+ var (
+ key, val string
+ )
+
+ splitLabel := strings.SplitN(value, "=", 2)
+ // Unlike ENV, LABEL must have a value
+ if len(splitLabel) != 2 {
+ return ImageConfig{}, errors.Errorf("invalid change %q - LABEL must be formatted key=value", change)
+ }
+ key = splitLabel[0]
+ val = splitLabel[1]
+
+ if strings.HasPrefix(key, `"`) && strings.HasSuffix(key, `"`) {
+ key = strings.TrimPrefix(strings.TrimSuffix(key, `"`), `"`)
+ }
+ if strings.HasPrefix(val, `"`) && strings.HasSuffix(val, `"`) {
+ val = strings.TrimPrefix(strings.TrimSuffix(val, `"`), `"`)
+ }
+ // Check key after we strip quotations
+ if key == "" {
+ return ImageConfig{}, errors.Errorf("invalid change %q - LABEL must have a non-empty key", change)
}
+ if config.Labels == nil {
+ config.Labels = make(map[string]string)
+ }
+ config.Labels[key] = val
case "STOPSIGNAL":
- stopSignal = vals[0]
+ // Check the provided signal for validity.
+ // TODO: Worth checking range? ParseSignal allows
+ // negative numbers.
+ killSignal, err := signal.ParseSignal(value)
+ if err != nil {
+ return ImageConfig{}, errors.Wrapf(err, "invalid change %q - KILLSIGNAL must be given a valid signal", change)
+ }
+ config.StopSignal = fmt.Sprintf("%d", killSignal)
+ case "ONBUILD":
+ // Onbuild always appends.
+ if value == "" {
+ return ImageConfig{}, errors.Errorf("invalid change %q - ONBUILD must be given an argument", change)
+ }
+ config.OnBuild = append(config.OnBuild, value)
+ default:
+ return ImageConfig{}, errors.Errorf("invalid change %q - invalid instruction %s", change, outerKey)
}
}
- return v1.ImageConfig{
- User: user,
- ExposedPorts: exposedPorts,
- Env: env,
- Entrypoint: entrypoint,
- Cmd: cmd,
- Volumes: volumes,
- WorkingDir: workingDir,
- Labels: labels,
- StopSignal: stopSignal,
- }, nil
+ return config, nil
}
// ParseIDMapping takes idmappings and subuid and subgid maps and returns a storage mapping
diff --git a/pkg/util/utils_supported.go b/pkg/util/utils_supported.go
index 253460686..0b78a8150 100644
--- a/pkg/util/utils_supported.go
+++ b/pkg/util/utils_supported.go
@@ -20,6 +20,10 @@ import (
func GetRuntimeDir() (string, error) {
var rootlessRuntimeDirError error
+ if !rootless.IsRootless() {
+ return "", nil
+ }
+
rootlessRuntimeDirOnce.Do(func() {
runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
uid := fmt.Sprintf("%d", rootless.GetRootlessUID())
diff --git a/pkg/util/utils_test.go b/pkg/util/utils_test.go
index c938dc592..f4b03599d 100644
--- a/pkg/util/utils_test.go
+++ b/pkg/util/utils_test.go
@@ -4,6 +4,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
var (
@@ -19,70 +20,247 @@ func TestStringInSlice(t *testing.T) {
assert.False(t, StringInSlice("one", []string{}))
}
-func TestParseChanges(t *testing.T) {
- // CMD=/bin/sh
- _, vals, err := ParseChanges("CMD=/bin/sh")
- assert.EqualValues(t, []string{"/bin/sh"}, vals)
- assert.NoError(t, err)
-
- // CMD [/bin/sh]
- _, vals, err = ParseChanges("CMD [/bin/sh]")
- assert.EqualValues(t, []string{"/bin/sh"}, vals)
- assert.NoError(t, err)
-
- // CMD ["/bin/sh"]
- _, vals, err = ParseChanges(`CMD ["/bin/sh"]`)
- assert.EqualValues(t, []string{`"/bin/sh"`}, vals)
- assert.NoError(t, err)
-
- // CMD ["/bin/sh","-c","ls"]
- _, vals, err = ParseChanges(`CMD ["/bin/sh","c","ls"]`)
- assert.EqualValues(t, []string{`"/bin/sh"`, `"c"`, `"ls"`}, vals)
- assert.NoError(t, err)
-
- // CMD ["/bin/sh","arg-with,comma"]
- _, vals, err = ParseChanges(`CMD ["/bin/sh","arg-with,comma"]`)
- assert.EqualValues(t, []string{`"/bin/sh"`, `"arg-with`, `comma"`}, vals)
- assert.NoError(t, err)
-
- // CMD "/bin/sh"]
- _, _, err = ParseChanges(`CMD "/bin/sh"]`)
- assert.Error(t, err)
- assert.Equal(t, `invalid value "/bin/sh"]`, err.Error())
-
- // CMD [bin/sh
- _, _, err = ParseChanges(`CMD "/bin/sh"]`)
- assert.Error(t, err)
- assert.Equal(t, `invalid value "/bin/sh"]`, err.Error())
-
- // CMD ["/bin /sh"]
- _, _, err = ParseChanges(`CMD ["/bin /sh"]`)
- assert.Error(t, err)
- assert.Equal(t, `invalid value "/bin /sh"`, err.Error())
-
- // CMD ["/bin/sh", "-c","ls"] whitespace between values
- _, vals, err = ParseChanges(`CMD ["/bin/sh", "c","ls"]`)
- assert.Error(t, err)
- assert.Equal(t, `invalid value "c"`, err.Error())
-
- // CMD?
- _, _, err = ParseChanges(`CMD?`)
- assert.Error(t, err)
- assert.Equal(t, `invalid format CMD?`, err.Error())
-
- // empty values for CMD
- _, _, err = ParseChanges(`CMD `)
- assert.Error(t, err)
- assert.Equal(t, `invalid value `, err.Error())
-
- // LABEL=blue=image
- _, vals, err = ParseChanges(`LABEL=blue=image`)
- assert.EqualValues(t, []string{"blue", "image"}, vals)
- assert.NoError(t, err)
-
- // LABEL = blue=image
- _, vals, err = ParseChanges(`LABEL = blue=image`)
- assert.Error(t, err)
- assert.Equal(t, `invalid value = blue=image`, err.Error())
+func TestGetImageConfigUser(t *testing.T) {
+ validUser, err := GetImageConfig([]string{"USER valid"})
+ require.Nil(t, err)
+ assert.Equal(t, validUser.User, "valid")
+ validUser2, err := GetImageConfig([]string{"USER test_user_2"})
+ require.Nil(t, err)
+ assert.Equal(t, validUser2.User, "test_user_2")
+
+ _, err = GetImageConfig([]string{"USER "})
+ assert.NotNil(t, err)
+}
+
+func TestGetImageConfigExpose(t *testing.T) {
+ validPortNoProto, err := GetImageConfig([]string{"EXPOSE 80"})
+ require.Nil(t, err)
+ _, exists := validPortNoProto.ExposedPorts["80/tcp"]
+ assert.True(t, exists)
+
+ validPortTCP, err := GetImageConfig([]string{"EXPOSE 80/tcp"})
+ require.Nil(t, err)
+ _, exists = validPortTCP.ExposedPorts["80/tcp"]
+ assert.True(t, exists)
+
+ validPortUDP, err := GetImageConfig([]string{"EXPOSE 80/udp"})
+ require.Nil(t, err)
+ _, exists = validPortUDP.ExposedPorts["80/udp"]
+ assert.True(t, exists)
+
+ _, err = GetImageConfig([]string{"EXPOSE 99999"})
+ assert.NotNil(t, err)
+
+ _, err = GetImageConfig([]string{"EXPOSE 80/notaproto"})
+ assert.NotNil(t, err)
+
+ _, err = GetImageConfig([]string{"EXPOSE "})
+ assert.NotNil(t, err)
+
+ _, err = GetImageConfig([]string{"EXPOSE thisisnotanumber"})
+ assert.NotNil(t, err)
+}
+
+func TestGetImageConfigEnv(t *testing.T) {
+ validEnvNoValue, err := GetImageConfig([]string{"ENV key"})
+ require.Nil(t, err)
+ assert.True(t, StringInSlice("key=", validEnvNoValue.Env))
+
+ validEnvBareEquals, err := GetImageConfig([]string{"ENV key="})
+ require.Nil(t, err)
+ assert.True(t, StringInSlice("key=", validEnvBareEquals.Env))
+
+ validEnvKeyValue, err := GetImageConfig([]string{"ENV key=value"})
+ require.Nil(t, err)
+ assert.True(t, StringInSlice("key=value", validEnvKeyValue.Env))
+
+ validEnvKeyMultiEntryValue, err := GetImageConfig([]string{`ENV key="value1 value2"`})
+ require.Nil(t, err)
+ assert.True(t, StringInSlice("key=value1 value2", validEnvKeyMultiEntryValue.Env))
+
+ _, err = GetImageConfig([]string{"ENV "})
+ assert.NotNil(t, err)
+}
+
+func TestGetImageConfigEntrypoint(t *testing.T) {
+ binShEntrypoint, err := GetImageConfig([]string{"ENTRYPOINT /bin/bash"})
+ require.Nil(t, err)
+ require.Equal(t, 3, len(binShEntrypoint.Entrypoint))
+ assert.Equal(t, binShEntrypoint.Entrypoint[0], "/bin/sh")
+ assert.Equal(t, binShEntrypoint.Entrypoint[1], "-c")
+ assert.Equal(t, binShEntrypoint.Entrypoint[2], "/bin/bash")
+
+ entrypointWithSpaces, err := GetImageConfig([]string{"ENTRYPOINT ls -al"})
+ require.Nil(t, err)
+ require.Equal(t, 3, len(entrypointWithSpaces.Entrypoint))
+ assert.Equal(t, entrypointWithSpaces.Entrypoint[0], "/bin/sh")
+ assert.Equal(t, entrypointWithSpaces.Entrypoint[1], "-c")
+ assert.Equal(t, entrypointWithSpaces.Entrypoint[2], "ls -al")
+
+ jsonArrayEntrypoint, err := GetImageConfig([]string{`ENTRYPOINT ["ls", "-al"]`})
+ require.Nil(t, err)
+ require.Equal(t, 2, len(jsonArrayEntrypoint.Entrypoint))
+ assert.Equal(t, jsonArrayEntrypoint.Entrypoint[0], "ls")
+ assert.Equal(t, jsonArrayEntrypoint.Entrypoint[1], "-al")
+
+ emptyEntrypoint, err := GetImageConfig([]string{"ENTRYPOINT "})
+ require.Nil(t, err)
+ assert.Equal(t, 0, len(emptyEntrypoint.Entrypoint))
+
+ emptyEntrypointArray, err := GetImageConfig([]string{"ENTRYPOINT []"})
+ require.Nil(t, err)
+ assert.Equal(t, 0, len(emptyEntrypointArray.Entrypoint))
+}
+
+func TestGetImageConfigCmd(t *testing.T) {
+ binShCmd, err := GetImageConfig([]string{"CMD /bin/bash"})
+ require.Nil(t, err)
+ require.Equal(t, 3, len(binShCmd.Cmd))
+ assert.Equal(t, binShCmd.Cmd[0], "/bin/sh")
+ assert.Equal(t, binShCmd.Cmd[1], "-c")
+ assert.Equal(t, binShCmd.Cmd[2], "/bin/bash")
+
+ cmdWithSpaces, err := GetImageConfig([]string{"CMD ls -al"})
+ require.Nil(t, err)
+ require.Equal(t, 3, len(cmdWithSpaces.Cmd))
+ assert.Equal(t, cmdWithSpaces.Cmd[0], "/bin/sh")
+ assert.Equal(t, cmdWithSpaces.Cmd[1], "-c")
+ assert.Equal(t, cmdWithSpaces.Cmd[2], "ls -al")
+
+ jsonArrayCmd, err := GetImageConfig([]string{`CMD ["ls", "-al"]`})
+ require.Nil(t, err)
+ require.Equal(t, 2, len(jsonArrayCmd.Cmd))
+ assert.Equal(t, jsonArrayCmd.Cmd[0], "ls")
+ assert.Equal(t, jsonArrayCmd.Cmd[1], "-al")
+
+ emptyCmd, err := GetImageConfig([]string{"CMD "})
+ require.Nil(t, err)
+ require.Equal(t, 2, len(emptyCmd.Cmd))
+ assert.Equal(t, emptyCmd.Cmd[0], "/bin/sh")
+ assert.Equal(t, emptyCmd.Cmd[1], "-c")
+
+ blankCmd, err := GetImageConfig([]string{"CMD []"})
+ require.Nil(t, err)
+ assert.Equal(t, 0, len(blankCmd.Cmd))
+}
+
+func TestGetImageConfigVolume(t *testing.T) {
+ oneLenJSONArrayVol, err := GetImageConfig([]string{`VOLUME ["/test1"]`})
+ require.Nil(t, err)
+ _, exists := oneLenJSONArrayVol.Volumes["/test1"]
+ assert.True(t, exists)
+ assert.Equal(t, 1, len(oneLenJSONArrayVol.Volumes))
+
+ twoLenJSONArrayVol, err := GetImageConfig([]string{`VOLUME ["/test1", "/test2"]`})
+ require.Nil(t, err)
+ assert.Equal(t, 2, len(twoLenJSONArrayVol.Volumes))
+ _, exists = twoLenJSONArrayVol.Volumes["/test1"]
+ assert.True(t, exists)
+ _, exists = twoLenJSONArrayVol.Volumes["/test2"]
+ assert.True(t, exists)
+
+ oneLenVol, err := GetImageConfig([]string{"VOLUME /test1"})
+ require.Nil(t, err)
+ _, exists = oneLenVol.Volumes["/test1"]
+ assert.True(t, exists)
+ assert.Equal(t, 1, len(oneLenVol.Volumes))
+
+ twoLenVol, err := GetImageConfig([]string{"VOLUME /test1 /test2"})
+ require.Nil(t, err)
+ assert.Equal(t, 2, len(twoLenVol.Volumes))
+ _, exists = twoLenVol.Volumes["/test1"]
+ assert.True(t, exists)
+ _, exists = twoLenVol.Volumes["/test2"]
+ assert.True(t, exists)
+
+ _, err = GetImageConfig([]string{"VOLUME []"})
+ assert.NotNil(t, err)
+
+ _, err = GetImageConfig([]string{"VOLUME "})
+ assert.NotNil(t, err)
+
+ _, err = GetImageConfig([]string{`VOLUME [""]`})
+ assert.NotNil(t, err)
+}
+
+func TestGetImageConfigWorkdir(t *testing.T) {
+ singleWorkdir, err := GetImageConfig([]string{"WORKDIR /testdir"})
+ require.Nil(t, err)
+ assert.Equal(t, singleWorkdir.WorkingDir, "/testdir")
+
+ twoWorkdirs, err := GetImageConfig([]string{"WORKDIR /testdir", "WORKDIR a"})
+ require.Nil(t, err)
+ assert.Equal(t, twoWorkdirs.WorkingDir, "/testdir/a")
+
+ _, err = GetImageConfig([]string{"WORKDIR "})
+ assert.NotNil(t, err)
+}
+
+func TestGetImageConfigLabel(t *testing.T) {
+ labelNoQuotes, err := GetImageConfig([]string{"LABEL key1=value1"})
+ require.Nil(t, err)
+ assert.Equal(t, labelNoQuotes.Labels["key1"], "value1")
+
+ labelWithQuotes, err := GetImageConfig([]string{`LABEL "key 1"="value 2"`})
+ require.Nil(t, err)
+ assert.Equal(t, labelWithQuotes.Labels["key 1"], "value 2")
+
+ labelNoValue, err := GetImageConfig([]string{"LABEL key="})
+ require.Nil(t, err)
+ contents, exists := labelNoValue.Labels["key"]
+ assert.True(t, exists)
+ assert.Equal(t, contents, "")
+
+ _, err = GetImageConfig([]string{"LABEL key"})
+ assert.NotNil(t, err)
+
+ _, err = GetImageConfig([]string{"LABEL "})
+ assert.NotNil(t, err)
+}
+
+func TestGetImageConfigStopSignal(t *testing.T) {
+ stopSignalValidInt, err := GetImageConfig([]string{"STOPSIGNAL 9"})
+ require.Nil(t, err)
+ assert.Equal(t, stopSignalValidInt.StopSignal, "9")
+
+ stopSignalValidString, err := GetImageConfig([]string{"STOPSIGNAL SIGKILL"})
+ require.Nil(t, err)
+ assert.Equal(t, stopSignalValidString.StopSignal, "9")
+
+ _, err = GetImageConfig([]string{"STOPSIGNAL 0"})
+ assert.NotNil(t, err)
+
+ _, err = GetImageConfig([]string{"STOPSIGNAL garbage"})
+ assert.NotNil(t, err)
+
+ _, err = GetImageConfig([]string{"STOPSIGNAL "})
+ assert.NotNil(t, err)
+}
+
+func TestGetImageConfigOnBuild(t *testing.T) {
+ onBuildOne, err := GetImageConfig([]string{"ONBUILD ADD /testdir1"})
+ require.Nil(t, err)
+ require.Equal(t, 1, len(onBuildOne.OnBuild))
+ assert.Equal(t, onBuildOne.OnBuild[0], "ADD /testdir1")
+
+ onBuildTwo, err := GetImageConfig([]string{"ONBUILD ADD /testdir1", "ONBUILD ADD /testdir2"})
+ require.Nil(t, err)
+ require.Equal(t, 2, len(onBuildTwo.OnBuild))
+ assert.Equal(t, onBuildTwo.OnBuild[0], "ADD /testdir1")
+ assert.Equal(t, onBuildTwo.OnBuild[1], "ADD /testdir2")
+
+ _, err = GetImageConfig([]string{"ONBUILD "})
+ assert.NotNil(t, err)
+}
+
+func TestGetImageConfigMisc(t *testing.T) {
+ _, err := GetImageConfig([]string{""})
+ assert.NotNil(t, err)
+
+ _, err = GetImageConfig([]string{"USER"})
+ assert.NotNil(t, err)
+
+ _, err = GetImageConfig([]string{"BADINST testvalue"})
+ assert.NotNil(t, err)
}
diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go
index 7abffa42a..1d46c5b71 100644
--- a/pkg/varlinkapi/images.go
+++ b/pkg/varlinkapi/images.go
@@ -35,26 +35,34 @@ import (
"github.com/sirupsen/logrus"
)
-// ListImages lists all the images in the store
-// It requires no inputs.
-func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error {
- images, err := i.Runtime.ImageRuntime().GetImages()
+// ListImagesWithFilters returns a list of images that have been filtered
+func (i *LibpodAPI) ListImagesWithFilters(call iopodman.VarlinkCall, filters []string) error {
+ images, err := i.Runtime.ImageRuntime().GetImagesWithFilters(filters)
if err != nil {
return call.ReplyErrorOccurred(fmt.Sprintf("unable to get list of images %q", err))
}
+ imageList, err := imagesToImageList(images)
+ if err != nil {
+ return call.ReplyErrorOccurred(fmt.Sprintf("unable to parse response", err))
+ }
+ return call.ReplyListImagesWithFilters(imageList)
+}
+
+// imagesToImageList converts a slice of Images to an imagelist for varlink responses
+func imagesToImageList(images []*image.Image) ([]iopodman.Image, error) {
var imageList []iopodman.Image
for _, image := range images {
labels, _ := image.Labels(getContext())
containers, _ := image.Containers()
repoDigests, err := image.RepoDigests()
if err != nil {
- return err
+ return nil, err
}
size, _ := image.Size(getContext())
isParent, err := image.IsParent(context.TODO())
if err != nil {
- return call.ReplyErrorOccurred(err.Error())
+ return nil, err
}
i := iopodman.Image{
@@ -74,6 +82,20 @@ func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error {
}
imageList = append(imageList, i)
}
+ return imageList, nil
+}
+
+// ListImages lists all the images in the store
+// It requires no inputs.
+func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error {
+ images, err := i.Runtime.ImageRuntime().GetImages()
+ if err != nil {
+ return call.ReplyErrorOccurred(fmt.Sprintf("unable to get list of images %q", err))
+ }
+ imageList, err := imagesToImageList(images)
+ if err != nil {
+ return call.ReplyErrorOccurred(fmt.Sprintf("unable to parse response", err))
+ }
return call.ReplyListImages(imageList)
}
@@ -602,7 +624,7 @@ func (i *LibpodAPI) ImportImage(call iopodman.VarlinkCall, source, reference, me
{Comment: message},
}
config := v1.Image{
- Config: configChanges,
+ Config: configChanges.ImageConfig,
History: history,
}
newImage, err := i.Runtime.ImageRuntime().Import(getContext(), source, reference, nil, image.SigningOptions{}, config)
diff --git a/test/e2e/e2e.coverprofile b/test/e2e/e2e.coverprofile
deleted file mode 100644
index d413679ea..000000000
--- a/test/e2e/e2e.coverprofile
+++ /dev/null
@@ -1,11 +0,0 @@
-mode: atomic
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:14.46,21.20 2 3
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:32.2,32.19 1 3
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:39.2,39.53 1 3
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:66.2,66.52 1 3
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:21.20,23.17 2 6
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:26.3,29.36 4 6
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:23.17,25.4 1 0
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:32.19,37.3 3 6
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:39.53,64.3 20 3
-github.com/containers/libpod/test/e2e/pod_pod_namespaces.go:66.52,91.3 20 3 \ No newline at end of file
diff --git a/test/e2e/import_test.go b/test/e2e/import_test.go
index 979440a50..bceb30f7c 100644
--- a/test/e2e/import_test.go
+++ b/test/e2e/import_test.go
@@ -105,7 +105,9 @@ var _ = Describe("Podman import", func() {
results.WaitWithDefaultTimeout()
Expect(results.ExitCode()).To(Equal(0))
imageData := results.InspectImageJSON()
- Expect(imageData[0].Config.Cmd[0]).To(Equal("/bin/bash"))
+ Expect(imageData[0].Config.Cmd[0]).To(Equal("/bin/sh"))
+ Expect(imageData[0].Config.Cmd[1]).To(Equal("-c"))
+ Expect(imageData[0].Config.Cmd[2]).To(Equal("/bin/bash"))
})
It("podman import with change flag CMD <path>", func() {
@@ -126,6 +128,8 @@ var _ = Describe("Podman import", func() {
Expect(results.ExitCode()).To(Equal(0))
imageData := results.InspectImageJSON()
Expect(imageData[0].Config.Cmd[0]).To(Equal("/bin/sh"))
+ Expect(imageData[0].Config.Cmd[1]).To(Equal("-c"))
+ Expect(imageData[0].Config.Cmd[2]).To(Equal("/bin/sh"))
})
It("podman import with change flag CMD [\"path\",\"path'\"", func() {
@@ -137,7 +141,7 @@ var _ = Describe("Podman import", func() {
export.WaitWithDefaultTimeout()
Expect(export.ExitCode()).To(Equal(0))
- importImage := podmanTest.Podman([]string{"import", "--change", "CMD [/bin/bash]", outfile, "imported-image"})
+ importImage := podmanTest.Podman([]string{"import", "--change", "CMD [\"/bin/bash\"]", outfile, "imported-image"})
importImage.WaitWithDefaultTimeout()
Expect(importImage.ExitCode()).To(Equal(0))
diff --git a/test/system/070-build.bats b/test/system/070-build.bats
index a9d2ed1b7..7c39da72c 100644
--- a/test/system/070-build.bats
+++ b/test/system/070-build.bats
@@ -32,6 +32,54 @@ EOF
run_podman rmi -f build_test
}
+# Regression from v1.5.0. This test passes fine in v1.5.0, fails in 1.6
+@test "podman build - cache (#3920)" {
+ if is_remote && is_rootless; then
+ skip "unreliable with podman-remote and rootless; #2972"
+ fi
+
+ # Make an empty test directory, with a subdirectory used for tar
+ tmpdir=$PODMAN_TMPDIR/build-test
+ run mkdir -p $tmpdir/subtest || die "Could not mkdir $tmpdir/subtest"
+
+ echo "This is the ORIGINAL file" > $tmpdir/subtest/myfile1
+ run tar -C $tmpdir -cJf $tmpdir/myfile.tar.xz subtest
+
+ cat >$tmpdir/Dockerfile <<EOF
+FROM $IMAGE
+ADD myfile.tar.xz /
+EOF
+
+ # One of: ADD myfile /myfile or COPY . .
+ run_podman build -t build_test -f $tmpdir/Dockerfile $tmpdir
+ is "$output" ".*STEP 3: COMMIT" "COMMIT seen in log"
+ if [[ "$output" =~ "Using cache" ]]; then
+ is "$output" "[no instance of 'Using cache']" "no cache used"
+ fi
+ iid=${lines[-1]}
+
+ run_podman run --rm build_test cat /subtest/myfile1
+ is "$output" "This is the ORIGINAL file" "file contents, first time"
+
+ # Step 2: Recreate the tarfile, with new content. Rerun podman build.
+ echo "This is a NEW file" >| $tmpdir/subtest/myfile2
+ run tar -C $tmpdir -cJf $tmpdir/myfile.tar.xz subtest
+
+ run_podman build -t build_test -f $tmpdir/Dockerfile $tmpdir
+ is "$output" ".*STEP 3: COMMIT" "COMMIT seen in log"
+
+ # Since the tarfile is modified, podman SHOULD NOT use a cached layer.
+ if [[ "$output" =~ "Using cache" ]]; then
+ is "$output" "[no instance of 'Using cache']" "no cache used"
+ fi
+
+ # Pre-buildah-1906, this fails with ENOENT because the tarfile was cached
+ run_podman run --rm build_test cat /subtest/myfile2
+ is "$output" "This is a NEW file" "file contents, second time"
+
+ run_podman rmi -f build_test $iid
+}
+
function teardown() {
# A timeout or other error in 'build' can leave behind stale images
# that podman can't even see and which will cascade into subsequent
diff --git a/troubleshooting.md b/troubleshooting.md
index 9def0e08b..432c0e32b 100644
--- a/troubleshooting.md
+++ b/troubleshooting.md
@@ -442,3 +442,30 @@ Attempts to run podman result in
#### Solution
One workaround is to disable Secure Boot in your BIOS.
+
+### 19) error creating libpod runtime: there might not be enough IDs available in the namespace
+
+Unable to pull images
+
+#### Symptom
+
+```console
+$ podman unshare cat /proc/self/uid_map
+ 0 1000 1
+```
+
+#### Solution
+
+```console
+$ podman system migrate
+```
+
+Original command now returns
+
+```
+$ podman unshare cat /proc/self/uid_map
+ 0 1000 1
+ 1 100000 65536
+```
+
+Reference [subuid](http://man7.org/linux/man-pages/man5/subuid.5.html) and [subgid](http://man7.org/linux/man-pages/man5/subgid.5.html) man pages for more detail. \ No newline at end of file
diff --git a/vendor/github.com/Microsoft/hcsshim/appveyor.yml b/vendor/github.com/Microsoft/hcsshim/appveyor.yml
index 7f0f81632..661bc406f 100644
--- a/vendor/github.com/Microsoft/hcsshim/appveyor.yml
+++ b/vendor/github.com/Microsoft/hcsshim/appveyor.yml
@@ -8,7 +8,7 @@ environment:
GOPATH: c:\gopath
PATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;%GOPATH%\bin;C:\gometalinter-2.0.12-windows-amd64;%PATH%
-stack: go 1.12.9
+stack: go 1.13.4
build_script:
- appveyor DownloadFile https://github.com/alecthomas/gometalinter/releases/download/v2.0.12/gometalinter-2.0.12-windows-amd64.zip
diff --git a/vendor/github.com/Microsoft/hcsshim/container.go b/vendor/github.com/Microsoft/hcsshim/container.go
index 53c0a3854..7205a62c5 100644
--- a/vendor/github.com/Microsoft/hcsshim/container.go
+++ b/vendor/github.com/Microsoft/hcsshim/container.go
@@ -196,7 +196,7 @@ func (container *container) MappedVirtualDisks() (map[int]MappedVirtualDiskContr
// CreateProcess launches a new process within the container.
func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
- p, err := container.system.CreateProcessNoStdio(c)
+ p, err := container.system.CreateProcess(context.Background(), c)
if err != nil {
return nil, convertSystemError(err, container)
}
diff --git a/vendor/github.com/Microsoft/hcsshim/go.mod b/vendor/github.com/Microsoft/hcsshim/go.mod
index 5f76d444d..72d253dad 100644
--- a/vendor/github.com/Microsoft/hcsshim/go.mod
+++ b/vendor/github.com/Microsoft/hcsshim/go.mod
@@ -1,6 +1,6 @@
module github.com/Microsoft/hcsshim
-go 1.12
+go 1.13
require (
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go
index d366f629f..2ad978f29 100644
--- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go
@@ -20,6 +20,8 @@ type Process struct {
handle vmcompute.HcsProcess
processID int
system *System
+ hasCachedStdio bool
+ stdioLock sync.Mutex
stdin io.WriteCloser
stdout io.ReadCloser
stderr io.ReadCloser
@@ -272,8 +274,8 @@ func (process *Process) ExitCode() (int, error) {
}
// StdioLegacy returns the stdin, stdout, and stderr pipes, respectively. Closing
-// these pipes does not close the underlying pipes; but this function can only
-// be called once on each Process.
+// these pipes does not close the underlying pipes. Once returned, these pipes
+// are the responsibility of the caller to close.
func (process *Process) StdioLegacy() (_ io.WriteCloser, _ io.ReadCloser, _ io.ReadCloser, err error) {
operation := "hcsshim::Process::StdioLegacy"
ctx, span := trace.StartSpan(context.Background(), operation)
@@ -290,6 +292,15 @@ func (process *Process) StdioLegacy() (_ io.WriteCloser, _ io.ReadCloser, _ io.R
return nil, nil, nil, makeProcessError(process, operation, ErrAlreadyClosed, nil)
}
+ process.stdioLock.Lock()
+ defer process.stdioLock.Unlock()
+ if process.hasCachedStdio {
+ stdin, stdout, stderr := process.stdin, process.stdout, process.stderr
+ process.stdin, process.stdout, process.stderr = nil, nil, nil
+ process.hasCachedStdio = false
+ return stdin, stdout, stderr, nil
+ }
+
processInfo, resultJSON, err := vmcompute.HcsGetProcessInfo(ctx, process.handle)
events := processHcsResult(ctx, resultJSON)
if err != nil {
@@ -307,6 +318,8 @@ func (process *Process) StdioLegacy() (_ io.WriteCloser, _ io.ReadCloser, _ io.R
// Stdio returns the stdin, stdout, and stderr pipes, respectively.
// To close them, close the process handle.
func (process *Process) Stdio() (stdin io.Writer, stdout, stderr io.Reader) {
+ process.stdioLock.Lock()
+ defer process.stdioLock.Unlock()
return process.stdin, process.stdout, process.stderr
}
@@ -340,9 +353,13 @@ func (process *Process) CloseStdin(ctx context.Context) error {
return makeProcessError(process, operation, err, events)
}
+ process.stdioLock.Lock()
if process.stdin != nil {
process.stdin.Close()
+ process.stdin = nil
}
+ process.stdioLock.Unlock()
+
return nil
}
@@ -365,15 +382,20 @@ func (process *Process) Close() (err error) {
return nil
}
+ process.stdioLock.Lock()
if process.stdin != nil {
process.stdin.Close()
+ process.stdin = nil
}
if process.stdout != nil {
process.stdout.Close()
+ process.stdout = nil
}
if process.stderr != nil {
process.stderr.Close()
+ process.stderr = nil
}
+ process.stdioLock.Unlock()
if err = process.unregisterCallback(ctx); err != nil {
return makeProcessError(process, operation, err, nil)
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go
index 98df25bd5..6300a7974 100644
--- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go
@@ -482,38 +482,6 @@ func (computeSystem *System) createProcess(ctx context.Context, operation string
return newProcess(processHandle, int(processInfo.ProcessId), computeSystem), &processInfo, nil
}
-// CreateProcessNoStdio launches a new process within the computeSystem. The
-// Stdio handles are not cached on the process struct.
-func (computeSystem *System) CreateProcessNoStdio(c interface{}) (_ cow.Process, err error) {
- operation := "hcsshim::System::CreateProcessNoStdio"
- ctx, span := trace.StartSpan(context.Background(), operation)
- defer span.End()
- defer func() { oc.SetSpanStatus(span, err) }()
- span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
-
- process, processInfo, err := computeSystem.createProcess(ctx, operation, c)
- if err != nil {
- return nil, err
- }
- defer func() {
- if err != nil {
- process.Close()
- }
- }()
-
- // We don't do anything with these handles. Close them so they don't leak.
- syscall.Close(processInfo.StdInput)
- syscall.Close(processInfo.StdOutput)
- syscall.Close(processInfo.StdError)
-
- if err = process.registerCallback(ctx); err != nil {
- return nil, makeSystemError(computeSystem, operation, "", err, nil)
- }
- go process.waitBackground()
-
- return process, nil
-}
-
// CreateProcess launches a new process within the computeSystem.
func (computeSystem *System) CreateProcess(ctx context.Context, c interface{}) (cow.Process, error) {
operation := "hcsshim::System::CreateProcess"
@@ -534,6 +502,7 @@ func (computeSystem *System) CreateProcess(ctx context.Context, c interface{}) (
process.stdin = pipes[0]
process.stdout = pipes[1]
process.stderr = pipes[2]
+ process.hasCachedStdio = true
if err = process.registerCallback(ctx); err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, nil)
diff --git a/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go b/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go
index 3488cc451..726d1c8c1 100644
--- a/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go
+++ b/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go
@@ -21,7 +21,7 @@ const (
// 2019 (ltsc2019), and Windows 10 (October 2018 Update).
RS5 = 17763
- // V19H1 (version 1903) corresponds to Windows Sever 1903 (semi-annual
+ // V19H1 (version 1903) corresponds to Windows Server 1903 (semi-annual
// channel).
V19H1 = 18362
)
diff --git a/vendor/github.com/containers/psgo/README.md b/vendor/github.com/containers/psgo/README.md
index 55cb73a71..fed42c683 100644
--- a/vendor/github.com/containers/psgo/README.md
+++ b/vendor/github.com/containers/psgo/README.md
@@ -85,6 +85,8 @@ The ps library is compatible with all AIX format descriptors of the ps command-l
- Seccomp mode of the process (i.e., disabled, strict or filter). See seccomp(2) for more information.
- **state**
- Process state codes (e.g, **R** for *running*, **S** for *sleeping*). See proc(5) for more information.
+- **stime**
+ - Process start time (e.g, "2019-12-09 10:50:36 +0100 CET).
We can try out different format descriptors with the psgo binary:
diff --git a/vendor/github.com/containers/psgo/internal/process/process.go b/vendor/github.com/containers/psgo/internal/process/process.go
index 20e40163f..a936cc4ef 100644
--- a/vendor/github.com/containers/psgo/internal/process/process.go
+++ b/vendor/github.com/containers/psgo/internal/process/process.go
@@ -188,23 +188,30 @@ func (p *Process) SetHostData() error {
// ElapsedTime returns the time.Duration since process p was created.
func (p *Process) ElapsedTime() (time.Duration, error) {
- sinceBoot, err := strconv.ParseInt(p.Stat.Starttime, 10, 64)
+ startTime, err := p.StartTime()
if err != nil {
return 0, err
}
+ return (time.Now()).Sub(startTime), nil
+}
+
+// StarTime returns the time.Time when process p was started.
+func (p *Process) StartTime() (time.Time, error) {
+ sinceBoot, err := strconv.ParseInt(p.Stat.Starttime, 10, 64)
+ if err != nil {
+ return time.Time{}, err
+ }
clockTicks, err := host.ClockTicks()
if err != nil {
- return 0, err
+ return time.Time{}, err
}
-
- sinceBoot = sinceBoot / clockTicks
-
bootTime, err := host.BootTime()
if err != nil {
- return 0, err
+ return time.Time{}, err
}
- created := time.Unix(sinceBoot+bootTime, 0)
- return (time.Now()).Sub(created), nil
+
+ sinceBoot = sinceBoot / clockTicks
+ return time.Unix(sinceBoot+bootTime, 0), nil
}
// CPUTime returns the cumlative CPU time of process p as a time.Duration.
diff --git a/vendor/github.com/containers/psgo/psgo.go b/vendor/github.com/containers/psgo/psgo.go
index 4986c9c71..30b8b74ce 100644
--- a/vendor/github.com/containers/psgo/psgo.go
+++ b/vendor/github.com/containers/psgo/psgo.go
@@ -310,6 +310,11 @@ var (
header: "STATE",
procFn: processState,
},
+ {
+ normal: "stime",
+ header: "STIME",
+ procFn: processStartTime,
+ },
}
)
@@ -715,6 +720,15 @@ func processTIME(p *process.Process, ctx *psContext) (string, error) {
return fmt.Sprintf("%v", cpu), nil
}
+// processStartTime returns the start time of process p.
+func processStartTime(p *process.Process, ctx *psContext) (string, error) {
+ sTime, err := p.StartTime()
+ if err != nil {
+ return "", err
+ }
+ return fmt.Sprintf("%v", sTime), nil
+}
+
// processTTY returns the controlling tty (terminal) of process p.
func processTTY(p *process.Process, ctx *psContext) (string, error) {
ttyNr, err := strconv.ParseUint(p.Stat.TtyNr, 10, 64)
diff --git a/vendor/github.com/containers/storage/.gitignore b/vendor/github.com/containers/storage/.gitignore
index 1896698e4..64b9a98bd 100644
--- a/vendor/github.com/containers/storage/.gitignore
+++ b/vendor/github.com/containers/storage/.gitignore
@@ -2,6 +2,7 @@
# if you want to ignore files created by your editor/tools,
# please consider a global .gitignore https://help.github.com/articles/ignoring-files
*.1
+*.5
*.exe
*~
*.orig
diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION
index 141f2e805..f2380cc7a 100644
--- a/vendor/github.com/containers/storage/VERSION
+++ b/vendor/github.com/containers/storage/VERSION
@@ -1 +1 @@
-1.15.0
+1.15.3
diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
index 13cd65fa5..16549e88b 100644
--- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go
+++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
@@ -676,9 +676,6 @@ func (d *Driver) getLower(parent string) (string, error) {
parentLowers := strings.Split(string(parentLower), ":")
lowers = append(lowers, parentLowers...)
}
- if len(lowers) > maxDepth {
- return "", errors.New("max depth exceeded")
- }
return strings.Join(lowers, ":"), nil
}
@@ -828,6 +825,10 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
if err != nil && !os.IsNotExist(err) {
return "", err
}
+ splitLowers := strings.Split(string(lowers), ":")
+ if len(splitLowers) > maxDepth {
+ return "", errors.New("max depth exceeded")
+ }
// absLowers is the list of lowers as absolute paths, which works well with additional stores.
absLowers := []string{}
@@ -851,7 +852,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
// For each lower, resolve its path, and append it and any additional diffN
// directories to the lowers list.
- for _, l := range strings.Split(string(lowers), ":") {
+ for _, l := range splitLowers {
if l == "" {
continue
}
diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod
index f9d7a199c..378b427de 100644
--- a/vendor/github.com/containers/storage/go.mod
+++ b/vendor/github.com/containers/storage/go.mod
@@ -3,11 +3,11 @@ module github.com/containers/storage
require (
github.com/BurntSushi/toml v0.3.1
github.com/DataDog/zstd v1.4.0 // indirect
- github.com/Microsoft/go-winio v0.4.14
- github.com/Microsoft/hcsshim v0.8.6
+ github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
+ github.com/Microsoft/hcsshim v0.8.7
github.com/docker/docker v0.0.0-20171019062838-86f080cff091 // indirect
github.com/docker/go-units v0.4.0
- github.com/klauspost/compress v1.9.2
+ github.com/klauspost/compress v1.9.4
github.com/klauspost/cpuid v1.2.1 // indirect
github.com/klauspost/pgzip v1.2.1
github.com/mattn/go-shellwords v1.0.6
@@ -18,13 +18,14 @@ require (
github.com/pkg/errors v0.8.1
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7
github.com/sirupsen/logrus v1.4.2
+ github.com/spf13/pflag v1.0.3 // indirect
github.com/stretchr/testify v1.4.0
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
github.com/tchap/go-patricia v2.3.0+incompatible
github.com/vbatts/tar-split v0.11.1
golang.org/x/net v0.0.0-20190628185345-da137c7871d7
- golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb
- gotest.tools v0.0.0-20190624233834-05ebafbffc79
+ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3
+ gotest.tools v2.2.0+incompatible
)
go 1.13
diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum
index 6a81628bf..f31828d2a 100644
--- a/vendor/github.com/containers/storage/go.sum
+++ b/vendor/github.com/containers/storage/go.sum
@@ -1,3 +1,4 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DataDog/zstd v1.4.0 h1:vhoV+DUHnRZdKW1i5UMjAk2G4JY8wN4ayRfYDNdEhwo=
@@ -6,12 +7,28 @@ github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiU
github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
+github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
+github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
+github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg=
+github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
+github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b h1:T4nWG1TXIxeor8mAu5bFguPJgSIGhZqv/f0z55KCrJM=
github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b/go.mod h1:TrMrLQfeENAPYPRsJuq3jsqdlRh3lvi6trTZJG8+tho=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s=
+github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
+github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50 h1:WMpHmC6AxwWb9hMqhudkqG7A/p14KiMnl6d3r1iUMjU=
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
+github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
+github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
+github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
+github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
+github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
+github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
@@ -25,18 +42,37 @@ github.com/docker/docker v0.0.0-20171019062838-86f080cff091 h1:QpxpTw4MJeOzbC7X0
github.com/docker/docker v0.0.0-20171019062838-86f080cff091/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4=
github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
+github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
+github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.7.2 h1:liMOoeIvFpr9kEvalrZ7VVBA4wGf7zfOgwBjzz/5g2Y=
github.com/klauspost/compress v1.7.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.1 h1:TWy0o9J9c6LK9C8t7Msh6IAJNXbsU/nvKLTQUU5HdaY=
github.com/klauspost/compress v1.9.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.2 h1:LfVyl+ZlLlLDeQ/d2AqfGIIH4qEDu0Ed2S5GyhCWIWY=
github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/compress v1.9.3 h1:hkFELABwacUEgBfiguNeQydKv3M9pawBq8o24Ypw9+M=
+github.com/klauspost/compress v1.9.3/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/compress v1.9.4 h1:xhvAeUPQ2drNUhKtrGdTGNvV9nNafHMUkRyLkzxJoB4=
+github.com/klauspost/compress v1.9.4/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
@@ -51,16 +87,20 @@ github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJd
github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 h1:7InQ7/zrOh6SlFjaXFubv0xX0HsuC9qJsdqm7bNQpYM=
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
+github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
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/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8 h1:dDCFes8Hj1r/i5qnypONo5jdOme/8HWZC/aNDyhECt0=
github.com/opencontainers/runc v1.0.0-rc8/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc9 h1:/k06BMULKF5hidyoZymkoDCzdJzltZpz/UU4LguQVtc=
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.1 h1:wY4pOY8fBdSIvs9+IDHC55thBuEulhzfSgKeC1yFvzQ=
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
+github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/selinux v1.2.2 h1:Kx9J6eDG5/24A6DtUquGSpJQ+m2MUTahn4FtGEe8bFg=
github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
github.com/opencontainers/selinux v1.3.0 h1:xsI95WzPZu5exzA6JzkLSfdr/DilzOhCJOqGe5TgR0g=
@@ -72,6 +112,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7 h1:gGBSHPOU7g8YjTbhwn+lvFm2VDEhhA+PwDIlstkgSxE=
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
+github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo=
@@ -90,10 +131,12 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs=
github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
+github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE=
@@ -102,19 +145,67 @@ github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCO
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f h1:nBX3nTcmxEtHSERBJaIo1Qa26VwRaopnZmfDQUXsF4I=
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
+github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
+go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
+go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/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-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo=
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339 h1:zSqWKgm/o7HAnlAzBQ+aetp9fpuyytsXnKA8eiLHYQM=
+golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2 h1:/J2nHFg1MTqaRLFO7M+J78ASNsJoz3r0cvHBPQ77fsE=
+golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180810170437-e96c4e24768d/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v0.0.0-20190624233834-05ebafbffc79 h1:C+K4iPg1rIvmCf4JjelkbWv2jeWevEwp05Lz8XfTYgE=
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=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go
index ac905b0b4..3db94e880 100644
--- a/vendor/github.com/containers/storage/layers.go
+++ b/vendor/github.com/containers/storage/layers.go
@@ -475,7 +475,7 @@ func (r *layerStore) saveMounts() error {
return r.loadMounts()
}
-func newLayerStore(rundir string, layerdir string, driver drivers.Driver, uidMap, gidMap []idtools.IDMap) (LayerStore, error) {
+func (s *store) newLayerStore(rundir string, layerdir string, driver drivers.Driver) (LayerStore, error) {
if err := os.MkdirAll(rundir, 0700); err != nil {
return nil, err
}
@@ -501,8 +501,8 @@ func newLayerStore(rundir string, layerdir string, driver drivers.Driver, uidMap
byid: make(map[string]*Layer),
bymount: make(map[string]*Layer),
byname: make(map[string]*Layer),
- uidMap: copyIDMap(uidMap),
- gidMap: copyIDMap(gidMap),
+ uidMap: copyIDMap(s.uidMap),
+ gidMap: copyIDMap(s.gidMap),
}
if err := rlstore.Load(); err != nil {
return nil, err
diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go
index d2752ae7c..6e2618d1e 100644
--- a/vendor/github.com/containers/storage/pkg/archive/archive.go
+++ b/vendor/github.com/containers/storage/pkg/archive/archive.go
@@ -407,6 +407,10 @@ func ReadUserXattrToTarHeader(path string, hdr *tar.Header) error {
for _, key := range xattrs {
if strings.HasPrefix(key, "user.") {
value, err := system.Lgetxattr(path, key)
+ if err == system.E2BIG {
+ logrus.Errorf("archive: Skipping xattr for file %s since value is too big: %s", path, key)
+ continue
+ }
if err != nil {
return err
}
@@ -567,10 +571,7 @@ func (ta *tarAppender) addTarFile(path, name string) error {
}
if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 {
- // We use system.OpenSequential to ensure we use sequential file
- // access on Windows to avoid depleting the standby list.
- // On Linux, this equates to a regular os.Open.
- file, err := system.OpenSequential(path)
+ file, err := os.Open(path)
if err != nil {
return err
}
@@ -611,7 +612,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L
// Source is regular file. We use system.OpenFileSequential to use sequential
// file access to avoid depleting the standby list on Windows.
// On Linux, this equates to a regular os.OpenFile
- file, err := system.OpenFileSequential(path, os.O_CREATE|os.O_WRONLY, hdrInfo.Mode())
+ file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, hdrInfo.Mode())
if err != nil {
return err
}
@@ -1192,7 +1193,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
dst = filepath.Join(dst, filepath.Base(src))
}
// Create the holding directory if necessary
- if err := system.MkdirAll(filepath.Dir(dst), 0700, ""); err != nil {
+ if err := os.MkdirAll(filepath.Dir(dst), 0700); err != nil {
return err
}
diff --git a/vendor/github.com/containers/storage/pkg/archive/changes_linux.go b/vendor/github.com/containers/storage/pkg/archive/changes_linux.go
index ceec53ada..ecfa45d73 100644
--- a/vendor/github.com/containers/storage/pkg/archive/changes_linux.go
+++ b/vendor/github.com/containers/storage/pkg/archive/changes_linux.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/system"
+ "github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@@ -95,6 +96,10 @@ func walkchunk(path string, fi os.FileInfo, dir string, root *FileInfo) error {
for _, key := range xattrs {
if strings.HasPrefix(key, "user.") {
value, err := system.Lgetxattr(cpath, key)
+ if err == system.E2BIG {
+ logrus.Errorf("archive: Skipping xattr for file %s since value is too big: %s", cpath, key)
+ continue
+ }
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/storage/pkg/archive/copy.go b/vendor/github.com/containers/storage/pkg/archive/copy.go
index ea012b2d9..6298a674d 100644
--- a/vendor/github.com/containers/storage/pkg/archive/copy.go
+++ b/vendor/github.com/containers/storage/pkg/archive/copy.go
@@ -9,7 +9,6 @@ import (
"path/filepath"
"strings"
- "github.com/containers/storage/pkg/system"
"github.com/sirupsen/logrus"
)
@@ -198,7 +197,7 @@ func CopyInfoDestinationPath(path string) (info CopyInfo, err error) {
return CopyInfo{}, err
}
- if !system.IsAbs(linkTarget) {
+ if !filepath.IsAbs(linkTarget) {
// Join with the parent directory.
dstParent, _ := SplitPathDirEntry(path)
linkTarget = filepath.Join(dstParent, linkTarget)
diff --git a/vendor/github.com/containers/storage/pkg/archive/diff.go b/vendor/github.com/containers/storage/pkg/archive/diff.go
index b8ec876dd..3c2601dee 100644
--- a/vendor/github.com/containers/storage/pkg/archive/diff.go
+++ b/vendor/github.com/containers/storage/pkg/archive/diff.go
@@ -84,7 +84,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
parentPath := filepath.Join(dest, parent)
if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
- err = system.MkdirAll(parentPath, 0600, "")
+ err = os.MkdirAll(parentPath, 0600)
if err != nil {
return 0, err
}
diff --git a/vendor/github.com/containers/storage/pkg/chrootarchive/archive_unix.go b/vendor/github.com/containers/storage/pkg/chrootarchive/archive_unix.go
index ca9fb10d7..630826db1 100644
--- a/vendor/github.com/containers/storage/pkg/chrootarchive/archive_unix.go
+++ b/vendor/github.com/containers/storage/pkg/chrootarchive/archive_unix.go
@@ -96,11 +96,13 @@ func invokeUnpack(decompressedArchive io.Reader, dest string, options *archive.T
cmd.Stderr = output
if err := cmd.Start(); err != nil {
+ w.Close()
return fmt.Errorf("Untar error on re-exec cmd: %v", err)
}
//write the options to the pipe for the untar exec to read
if err := json.NewEncoder(w).Encode(options); err != nil {
+ w.Close()
return fmt.Errorf("Untar json encode to pipe failed: %v", err)
}
w.Close()
diff --git a/vendor/github.com/containers/storage/pkg/config/config.go b/vendor/github.com/containers/storage/pkg/config/config.go
index 18a65bc0a..f3f855c32 100644
--- a/vendor/github.com/containers/storage/pkg/config/config.go
+++ b/vendor/github.com/containers/storage/pkg/config/config.go
@@ -2,6 +2,8 @@ package config
import (
"fmt"
+
+ "github.com/sirupsen/logrus"
)
// ThinpoolOptionsConfig represents the "storage.options.thinpool"
@@ -256,10 +258,8 @@ func GetGraphDriverOptions(driverName string, options OptionsConfig) []string {
doptions = append(doptions, fmt.Sprintf("%s.size=%s", driverName, options.Size))
}
- if options.Overlay.SkipMountHome != "" {
- doptions = append(doptions, fmt.Sprintf("%s.skip_mount_home=%s", driverName, options.Overlay.SkipMountHome))
- } else if options.SkipMountHome != "" {
- doptions = append(doptions, fmt.Sprintf("%s.skip_mount_home=%s", driverName, options.SkipMountHome))
+ if options.Overlay.SkipMountHome != "" || options.SkipMountHome != "" {
+ logrus.Warn("skip_mount_home option is no longer supported, ignoring option")
}
case "vfs":
diff --git a/vendor/github.com/containers/storage/pkg/idtools/idtools_unix.go b/vendor/github.com/containers/storage/pkg/idtools/idtools_unix.go
index bdbdf1b50..6b0f55030 100644
--- a/vendor/github.com/containers/storage/pkg/idtools/idtools_unix.go
+++ b/vendor/github.com/containers/storage/pkg/idtools/idtools_unix.go
@@ -49,7 +49,7 @@ func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chown
paths = append(paths, dirPath)
}
}
- if err := system.MkdirAll(path, mode, ""); err != nil && !os.IsExist(err) {
+ if err := os.MkdirAll(path, mode); err != nil && !os.IsExist(err) {
return err
}
} else {
diff --git a/vendor/github.com/containers/storage/pkg/idtools/idtools_windows.go b/vendor/github.com/containers/storage/pkg/idtools/idtools_windows.go
index dbf6bc4c9..9c8508397 100644
--- a/vendor/github.com/containers/storage/pkg/idtools/idtools_windows.go
+++ b/vendor/github.com/containers/storage/pkg/idtools/idtools_windows.go
@@ -4,14 +4,12 @@ package idtools
import (
"os"
-
- "github.com/containers/storage/pkg/system"
)
// Platforms such as Windows do not support the UID/GID concept. So make this
// just a wrapper around system.MkdirAll.
func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chownExisting bool) error {
- if err := system.MkdirAll(path, mode, ""); err != nil && !os.IsExist(err) {
+ if err := os.MkdirAll(path, mode); err != nil && !os.IsExist(err) {
return err
}
return nil
diff --git a/vendor/github.com/containers/storage/pkg/loopback/attach_loopback.go b/vendor/github.com/containers/storage/pkg/loopback/attach_loopback.go
index be8680fbc..e2cf30b41 100644
--- a/vendor/github.com/containers/storage/pkg/loopback/attach_loopback.go
+++ b/vendor/github.com/containers/storage/pkg/loopback/attach_loopback.go
@@ -93,7 +93,7 @@ func openNextAvailableLoopback(index int, sparseName string, sparseFile *os.File
logrus.Errorf("Error getting loopback backing file: %s", err)
return nil, ErrGetLoopbackBackingFile
}
- if dev != st.Dev || ino != st.Ino {
+ if dev != uint64(st.Dev) || ino != st.Ino {
logrus.Errorf("Loopback device and filesystem disagree on device/inode for %q: %#x(%d):%#x(%d) vs %#x(%d):%#x(%d)", sparseName, dev, dev, ino, ino, st.Dev, st.Dev, st.Ino, st.Ino)
}
diff --git a/vendor/github.com/containers/storage/pkg/loopback/loopback.go b/vendor/github.com/containers/storage/pkg/loopback/loopback.go
index 05d537dc8..f4cf2826e 100644
--- a/vendor/github.com/containers/storage/pkg/loopback/loopback.go
+++ b/vendor/github.com/containers/storage/pkg/loopback/loopback.go
@@ -53,7 +53,7 @@ func FindLoopDeviceFor(file *os.File) *os.File {
}
dev, inode, err := getLoopbackBackingFile(file)
- if err == nil && dev == targetDevice && inode == targetInode {
+ if err == nil && dev == uint64(targetDevice) && inode == targetInode {
return file
}
file.Close()
diff --git a/vendor/github.com/containers/storage/pkg/system/filesys.go b/vendor/github.com/containers/storage/pkg/system/filesys.go
deleted file mode 100644
index 102565f76..000000000
--- a/vendor/github.com/containers/storage/pkg/system/filesys.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// +build !windows
-
-package system
-
-import (
- "io/ioutil"
- "os"
- "path/filepath"
-)
-
-// MkdirAllWithACL is a wrapper for MkdirAll on unix systems.
-func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
- return MkdirAll(path, perm, sddl)
-}
-
-// MkdirAll creates a directory named path along with any necessary parents,
-// with permission specified by attribute perm for all dir created.
-func MkdirAll(path string, perm os.FileMode, sddl string) error {
- return os.MkdirAll(path, perm)
-}
-
-// IsAbs is a platform-specific wrapper for filepath.IsAbs.
-func IsAbs(path string) bool {
- return filepath.IsAbs(path)
-}
-
-// The functions below here are wrappers for the equivalents in the os and ioutils packages.
-// They are passthrough on Unix platforms, and only relevant on Windows.
-
-// CreateSequential creates the named file with mode 0666 (before umask), truncating
-// it if it already exists. If successful, methods on the returned
-// File can be used for I/O; the associated file descriptor has mode
-// O_RDWR.
-// If there is an error, it will be of type *PathError.
-func CreateSequential(name string) (*os.File, error) {
- return os.Create(name)
-}
-
-// OpenSequential opens the named file for reading. If successful, methods on
-// the returned file can be used for reading; the associated file
-// descriptor has mode O_RDONLY.
-// If there is an error, it will be of type *PathError.
-func OpenSequential(name string) (*os.File, error) {
- return os.Open(name)
-}
-
-// OpenFileSequential is the generalized open call; most users will use Open
-// or Create instead. It opens the named file with specified flag
-// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful,
-// methods on the returned File can be used for I/O.
-// If there is an error, it will be of type *PathError.
-func OpenFileSequential(name string, flag int, perm os.FileMode) (*os.File, error) {
- return os.OpenFile(name, flag, perm)
-}
-
-// TempFileSequential creates a new temporary file in the directory dir
-// with a name beginning with prefix, opens the file for reading
-// and writing, and returns the resulting *os.File.
-// If dir is the empty string, TempFile uses the default directory
-// for temporary files (see os.TempDir).
-// Multiple programs calling TempFile simultaneously
-// will not choose the same file. The caller can use f.Name()
-// to find the pathname of the file. It is the caller's responsibility
-// to remove the file when no longer needed.
-func TempFileSequential(dir, prefix string) (f *os.File, err error) {
- return ioutil.TempFile(dir, prefix)
-}
diff --git a/vendor/github.com/containers/storage/pkg/system/filesys_windows.go b/vendor/github.com/containers/storage/pkg/system/filesys_windows.go
deleted file mode 100644
index a61b53d0b..000000000
--- a/vendor/github.com/containers/storage/pkg/system/filesys_windows.go
+++ /dev/null
@@ -1,298 +0,0 @@
-// +build windows
-
-package system
-
-import (
- "os"
- "path/filepath"
- "regexp"
- "strconv"
- "strings"
- "sync"
- "syscall"
- "time"
- "unsafe"
-
- winio "github.com/Microsoft/go-winio"
- "golang.org/x/sys/windows"
-)
-
-const (
- // SddlAdministratorsLocalSystem is local administrators plus NT AUTHORITY\System
- SddlAdministratorsLocalSystem = "D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
- // SddlNtvmAdministratorsLocalSystem is NT VIRTUAL MACHINE\Virtual Machines plus local administrators plus NT AUTHORITY\System
- SddlNtvmAdministratorsLocalSystem = "D:P(A;OICI;GA;;;S-1-5-83-0)(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
-)
-
-// MkdirAllWithACL is a wrapper for MkdirAll that creates a directory
-// with an appropriate SDDL defined ACL.
-func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
- return mkdirall(path, true, sddl)
-}
-
-// MkdirAll implementation that is volume path aware for Windows.
-func MkdirAll(path string, _ os.FileMode, sddl string) error {
- return mkdirall(path, false, sddl)
-}
-
-// mkdirall is a custom version of os.MkdirAll modified for use on Windows
-// so that it is both volume path aware, and can create a directory with
-// a DACL.
-func mkdirall(path string, applyACL bool, sddl string) error {
- if re := regexp.MustCompile(`^\\\\\?\\Volume{[a-z0-9-]+}$`); re.MatchString(path) {
- return nil
- }
-
- // The rest of this method is largely copied from os.MkdirAll and should be kept
- // as-is to ensure compatibility.
-
- // Fast path: if we can tell whether path is a directory or file, stop with success or error.
- dir, err := os.Stat(path)
- if err == nil {
- if dir.IsDir() {
- return nil
- }
- return &os.PathError{
- Op: "mkdir",
- Path: path,
- Err: syscall.ENOTDIR,
- }
- }
-
- // Slow path: make sure parent exists and then call Mkdir for path.
- i := len(path)
- for i > 0 && os.IsPathSeparator(path[i-1]) { // Skip trailing path separator.
- i--
- }
-
- j := i
- for j > 0 && !os.IsPathSeparator(path[j-1]) { // Scan backward over element.
- j--
- }
-
- if j > 1 {
- // Create parent
- err = mkdirall(path[0:j-1], false, sddl)
- if err != nil {
- return err
- }
- }
-
- // Parent now exists; invoke os.Mkdir or mkdirWithACL and use its result.
- if applyACL {
- err = mkdirWithACL(path, sddl)
- } else {
- err = os.Mkdir(path, 0)
- }
-
- if err != nil {
- // Handle arguments like "foo/." by
- // double-checking that directory doesn't exist.
- dir, err1 := os.Lstat(path)
- if err1 == nil && dir.IsDir() {
- return nil
- }
- return err
- }
- return nil
-}
-
-// mkdirWithACL creates a new directory. If there is an error, it will be of
-// type *PathError. .
-//
-// This is a modified and combined version of os.Mkdir and windows.Mkdir
-// in golang to cater for creating a directory am ACL permitting full
-// access, with inheritance, to any subfolder/file for Built-in Administrators
-// and Local System.
-func mkdirWithACL(name string, sddl string) error {
- sa := windows.SecurityAttributes{Length: 0}
- sd, err := winio.SddlToSecurityDescriptor(sddl)
- if err != nil {
- return &os.PathError{Op: "mkdir", Path: name, Err: err}
- }
- sa.Length = uint32(unsafe.Sizeof(sa))
- sa.InheritHandle = 1
- sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
-
- namep, err := windows.UTF16PtrFromString(name)
- if err != nil {
- return &os.PathError{Op: "mkdir", Path: name, Err: err}
- }
-
- e := windows.CreateDirectory(namep, &sa)
- if e != nil {
- return &os.PathError{Op: "mkdir", Path: name, Err: e}
- }
- return nil
-}
-
-// IsAbs is a platform-specific wrapper for filepath.IsAbs. On Windows,
-// golang filepath.IsAbs does not consider a path \windows\system32 as absolute
-// as it doesn't start with a drive-letter/colon combination. However, in
-// docker we need to verify things such as WORKDIR /windows/system32 in
-// a Dockerfile (which gets translated to \windows\system32 when being processed
-// by the daemon. This SHOULD be treated as absolute from a docker processing
-// perspective.
-func IsAbs(path string) bool {
- if !filepath.IsAbs(path) {
- if !strings.HasPrefix(path, string(os.PathSeparator)) {
- return false
- }
- }
- return true
-}
-
-// The origin of the functions below here are the golang OS and windows packages,
-// slightly modified to only cope with files, not directories due to the
-// specific use case.
-//
-// The alteration is to allow a file on Windows to be opened with
-// FILE_FLAG_SEQUENTIAL_SCAN (particular for docker load), to avoid eating
-// the standby list, particularly when accessing large files such as layer.tar.
-
-// CreateSequential creates the named file with mode 0666 (before umask), truncating
-// it if it already exists. If successful, methods on the returned
-// File can be used for I/O; the associated file descriptor has mode
-// O_RDWR.
-// If there is an error, it will be of type *PathError.
-func CreateSequential(name string) (*os.File, error) {
- return OpenFileSequential(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0)
-}
-
-// OpenSequential opens the named file for reading. If successful, methods on
-// the returned file can be used for reading; the associated file
-// descriptor has mode O_RDONLY.
-// If there is an error, it will be of type *PathError.
-func OpenSequential(name string) (*os.File, error) {
- return OpenFileSequential(name, os.O_RDONLY, 0)
-}
-
-// OpenFileSequential is the generalized open call; most users will use Open
-// or Create instead.
-// If there is an error, it will be of type *PathError.
-func OpenFileSequential(name string, flag int, _ os.FileMode) (*os.File, error) {
- if name == "" {
- return nil, &os.PathError{Op: "open", Path: name, Err: syscall.ENOENT}
- }
- r, errf := windowsOpenFileSequential(name, flag, 0)
- if errf == nil {
- return r, nil
- }
- return nil, &os.PathError{Op: "open", Path: name, Err: errf}
-}
-
-func windowsOpenFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) {
- r, e := windowsOpenSequential(name, flag|windows.O_CLOEXEC, 0)
- if e != nil {
- return nil, e
- }
- return os.NewFile(uintptr(r), name), nil
-}
-
-func makeInheritSa() *windows.SecurityAttributes {
- var sa windows.SecurityAttributes
- sa.Length = uint32(unsafe.Sizeof(sa))
- sa.InheritHandle = 1
- return &sa
-}
-
-func windowsOpenSequential(path string, mode int, _ uint32) (fd windows.Handle, err error) {
- if len(path) == 0 {
- return windows.InvalidHandle, windows.ERROR_FILE_NOT_FOUND
- }
- pathp, err := windows.UTF16PtrFromString(path)
- if err != nil {
- return windows.InvalidHandle, err
- }
- var access uint32
- switch mode & (windows.O_RDONLY | windows.O_WRONLY | windows.O_RDWR) {
- case windows.O_RDONLY:
- access = windows.GENERIC_READ
- case windows.O_WRONLY:
- access = windows.GENERIC_WRITE
- case windows.O_RDWR:
- access = windows.GENERIC_READ | windows.GENERIC_WRITE
- }
- if mode&windows.O_CREAT != 0 {
- access |= windows.GENERIC_WRITE
- }
- if mode&windows.O_APPEND != 0 {
- access &^= windows.GENERIC_WRITE
- access |= windows.FILE_APPEND_DATA
- }
- sharemode := uint32(windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE)
- var sa *windows.SecurityAttributes
- if mode&windows.O_CLOEXEC == 0 {
- sa = makeInheritSa()
- }
- var createmode uint32
- switch {
- case mode&(windows.O_CREAT|windows.O_EXCL) == (windows.O_CREAT | windows.O_EXCL):
- createmode = windows.CREATE_NEW
- case mode&(windows.O_CREAT|windows.O_TRUNC) == (windows.O_CREAT | windows.O_TRUNC):
- createmode = windows.CREATE_ALWAYS
- case mode&windows.O_CREAT == windows.O_CREAT:
- createmode = windows.OPEN_ALWAYS
- case mode&windows.O_TRUNC == windows.O_TRUNC:
- createmode = windows.TRUNCATE_EXISTING
- default:
- createmode = windows.OPEN_EXISTING
- }
- // Use FILE_FLAG_SEQUENTIAL_SCAN rather than FILE_ATTRIBUTE_NORMAL as implemented in golang.
- //https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
- const fileFlagSequentialScan = 0x08000000 // FILE_FLAG_SEQUENTIAL_SCAN
- h, e := windows.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0)
- return h, e
-}
-
-// Helpers for TempFileSequential
-var rand uint32
-var randmu sync.Mutex
-
-func reseed() uint32 {
- return uint32(time.Now().UnixNano() + int64(os.Getpid()))
-}
-func nextSuffix() string {
- randmu.Lock()
- r := rand
- if r == 0 {
- r = reseed()
- }
- r = r*1664525 + 1013904223 // constants from Numerical Recipes
- rand = r
- randmu.Unlock()
- return strconv.Itoa(int(1e9 + r%1e9))[1:]
-}
-
-// TempFileSequential is a copy of ioutil.TempFile, modified to use sequential
-// file access. Below is the original comment from golang:
-// TempFile creates a new temporary file in the directory dir
-// with a name beginning with prefix, opens the file for reading
-// and writing, and returns the resulting *os.File.
-// If dir is the empty string, TempFile uses the default directory
-// for temporary files (see os.TempDir).
-// Multiple programs calling TempFile simultaneously
-// will not choose the same file. The caller can use f.Name()
-// to find the pathname of the file. It is the caller's responsibility
-// to remove the file when no longer needed.
-func TempFileSequential(dir, prefix string) (f *os.File, err error) {
- if dir == "" {
- dir = os.TempDir()
- }
-
- nconflict := 0
- for i := 0; i < 10000; i++ {
- name := filepath.Join(dir, prefix+nextSuffix())
- f, err = OpenFileSequential(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
- if os.IsExist(err) {
- if nconflict++; nconflict > 10 {
- randmu.Lock()
- rand = reseed()
- randmu.Unlock()
- }
- continue
- }
- break
- }
- return
-}
diff --git a/vendor/github.com/containers/storage/pkg/system/xattrs_linux.go b/vendor/github.com/containers/storage/pkg/system/xattrs_linux.go
index 0d6cd95e3..24c3f37ef 100644
--- a/vendor/github.com/containers/storage/pkg/system/xattrs_linux.go
+++ b/vendor/github.com/containers/storage/pkg/system/xattrs_linux.go
@@ -8,6 +8,9 @@ import (
)
const (
+ // Value is larger than the maximum size allowed
+ E2BIG syscall.Errno = unix.E2BIG
+
// Operation not supported
EOPNOTSUPP syscall.Errno = unix.EOPNOTSUPP
)
@@ -16,19 +19,28 @@ const (
// and associated with the given path in the file system.
// It will returns a nil slice and nil error if the xattr is not set.
func Lgetxattr(path string, attr string) ([]byte, error) {
+ // Start with a 128 length byte array
dest := make([]byte, 128)
sz, errno := unix.Lgetxattr(path, attr, dest)
- if errno == unix.ENODATA {
+
+ switch {
+ case errno == unix.ENODATA:
return nil, nil
- }
- if errno == unix.ERANGE {
+ case errno == unix.ERANGE:
+ // 128 byte array might just not be good enough. A dummy buffer is used
+ // to get the real size of the xattrs on disk
+ sz, errno = unix.Lgetxattr(path, attr, []byte{})
+ if errno != nil {
+ return nil, errno
+ }
dest = make([]byte, sz)
sz, errno = unix.Lgetxattr(path, attr, dest)
- }
- if errno != nil {
+ if errno != nil {
+ return nil, errno
+ }
+ case errno != nil:
return nil, errno
}
-
return dest[:sz], nil
}
diff --git a/vendor/github.com/containers/storage/pkg/system/xattrs_unsupported.go b/vendor/github.com/containers/storage/pkg/system/xattrs_unsupported.go
index b4cf4e6ca..bc8b8e3a5 100644
--- a/vendor/github.com/containers/storage/pkg/system/xattrs_unsupported.go
+++ b/vendor/github.com/containers/storage/pkg/system/xattrs_unsupported.go
@@ -5,6 +5,9 @@ package system
import "syscall"
const (
+ // Value is larger than the maximum size allowed
+ E2BIG syscall.Errno = syscall.Errno(0)
+
// Operation not supported
EOPNOTSUPP syscall.Errno = syscall.Errno(0)
)
diff --git a/vendor/github.com/containers/storage/pkg/tarlog/tarlogger.go b/vendor/github.com/containers/storage/pkg/tarlog/tarlogger.go
index c6985d757..26cd8504c 100644
--- a/vendor/github.com/containers/storage/pkg/tarlog/tarlogger.go
+++ b/vendor/github.com/containers/storage/pkg/tarlog/tarlogger.go
@@ -11,7 +11,6 @@ import (
type tarLogger struct {
writer *io.PipeWriter
closeMutex *sync.Mutex
- stateMutex *sync.Mutex
closed bool
}
@@ -22,7 +21,6 @@ func NewLogger(logger func(*tar.Header)) (io.WriteCloser, error) {
t := &tarLogger{
writer: writer,
closeMutex: new(sync.Mutex),
- stateMutex: new(sync.Mutex),
closed: false,
}
tr := tar.NewReader(reader)
@@ -35,12 +33,9 @@ func NewLogger(logger func(*tar.Header)) (io.WriteCloser, error) {
}
// Make sure to avoid writes after the reader has been closed.
- t.stateMutex.Lock()
- t.closed = true
if err := reader.Close(); err != nil {
logrus.Errorf("error closing tarlogger reader: %v", err)
}
- t.stateMutex.Unlock()
// Unblock the Close().
t.closeMutex.Unlock()
}()
@@ -48,16 +43,19 @@ func NewLogger(logger func(*tar.Header)) (io.WriteCloser, error) {
}
func (t *tarLogger) Write(b []byte) (int, error) {
- t.stateMutex.Lock()
if t.closed {
// We cannot use os.Pipe() as this alters the tar's digest. Using
// io.Pipe() requires this workaround as it does not allow for writes
// after close.
- t.stateMutex.Unlock()
return len(b), nil
}
- t.stateMutex.Unlock()
- return t.writer.Write(b)
+ n, err := t.writer.Write(b)
+ if err == io.ErrClosedPipe {
+ // The pipe got closed. Track it and avoid to call Write in future.
+ t.closed = true
+ return len(b), nil
+ }
+ return n, err
}
func (t *tarLogger) Close() error {
diff --git a/vendor/github.com/containers/storage/storage.conf b/vendor/github.com/containers/storage/storage.conf
index db6d35768..b7b73ed38 100644
--- a/vendor/github.com/containers/storage/storage.conf
+++ b/vendor/github.com/containers/storage/storage.conf
@@ -58,9 +58,6 @@ additionalimagestores = [
# mountopt specifies comma separated list of extra mount options
mountopt = "nodev"
-# Set to skip a PRIVATE bind mount on the storage home directory.
-skip_mount_home = "false"
-
# Size is used to set a maximum size of the container image.
# size = ""
diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go
index 654e86880..65808b8a0 100644
--- a/vendor/github.com/containers/storage/store.go
+++ b/vendor/github.com/containers/storage/store.go
@@ -667,15 +667,6 @@ func (s *store) load() error {
s.graphDriverName = driver.String()
driverPrefix := s.graphDriverName + "-"
- rls, err := s.LayerStore()
- if err != nil {
- return err
- }
- s.layerStore = rls
- if _, err := s.ROLayerStores(); err != nil {
- return err
- }
-
gipath := filepath.Join(s.graphRoot, driverPrefix+"images")
if err := os.MkdirAll(gipath, 0700); err != nil {
return err
@@ -774,7 +765,7 @@ func (s *store) LayerStore() (LayerStore, error) {
if err := os.MkdirAll(glpath, 0700); err != nil {
return nil, err
}
- rls, err := newLayerStore(rlpath, glpath, driver, s.uidMap, s.gidMap)
+ rls, err := s.newLayerStore(rlpath, glpath, driver)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go b/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go
index 5ed476aa0..dd74ffb87 100644
--- a/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go
+++ b/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go
@@ -135,7 +135,6 @@ func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter {
func (w *huffmanBitWriter) reset(writer io.Writer) {
w.writer = writer
w.bits, w.nbits, w.nbytes, w.err = 0, 0, 0, nil
- w.bytes = [256]byte{}
w.lastHeader = 0
w.lastHuffMan = false
}
@@ -463,15 +462,12 @@ func (w *huffmanBitWriter) writeDynamicHeader(numLiterals int, numOffsets int, n
case 16:
w.writeBits(int32(w.codegen[i]), 2)
i++
- break
case 17:
w.writeBits(int32(w.codegen[i]), 3)
i++
- break
case 18:
w.writeBits(int32(w.codegen[i]), 7)
i++
- break
}
}
}
diff --git a/vendor/github.com/klauspost/compress/flate/huffman_code.go b/vendor/github.com/klauspost/compress/flate/huffman_code.go
index d0099599c..1810c6898 100644
--- a/vendor/github.com/klauspost/compress/flate/huffman_code.go
+++ b/vendor/github.com/klauspost/compress/flate/huffman_code.go
@@ -85,17 +85,14 @@ func generateFixedLiteralEncoding() *huffmanEncoder {
// size 8, 000110000 .. 10111111
bits = ch + 48
size = 8
- break
case ch < 256:
// size 9, 110010000 .. 111111111
bits = ch + 400 - 144
size = 9
- break
case ch < 280:
// size 7, 0000000 .. 0010111
bits = ch - 256
size = 7
- break
default:
// size 8, 11000000 .. 11000111
bits = ch + 192 - 280
diff --git a/vendor/github.com/klauspost/compress/flate/stateless.go b/vendor/github.com/klauspost/compress/flate/stateless.go
index 524ee0ae3..a47051197 100644
--- a/vendor/github.com/klauspost/compress/flate/stateless.go
+++ b/vendor/github.com/klauspost/compress/flate/stateless.go
@@ -3,6 +3,7 @@ package flate
import (
"io"
"math"
+ "sync"
)
const (
@@ -49,11 +50,24 @@ func NewStatelessWriter(dst io.Writer) io.WriteCloser {
return &statelessWriter{dst: dst}
}
+// bitWriterPool contains bit writers that can be reused.
+var bitWriterPool = sync.Pool{
+ New: func() interface{} {
+ return newHuffmanBitWriter(nil)
+ },
+}
+
// StatelessDeflate allows to compress directly to a Writer without retaining state.
// When returning everything will be flushed.
func StatelessDeflate(out io.Writer, in []byte, eof bool) error {
var dst tokens
- bw := newHuffmanBitWriter(out)
+ bw := bitWriterPool.Get().(*huffmanBitWriter)
+ bw.reset(out)
+ defer func() {
+ // don't keep a reference to our output
+ bw.reset(nil)
+ bitWriterPool.Put(bw)
+ }()
if eof && len(in) == 0 {
// Just write an EOF block.
// Could be faster...
diff --git a/vendor/github.com/klauspost/compress/huff0/decompress.go b/vendor/github.com/klauspost/compress/huff0/decompress.go
index 7e68a4eb4..97ae66a4a 100644
--- a/vendor/github.com/klauspost/compress/huff0/decompress.go
+++ b/vendor/github.com/klauspost/compress/huff0/decompress.go
@@ -15,8 +15,7 @@ type dTable struct {
// single-symbols decoding
type dEntrySingle struct {
- byte uint8
- nBits uint8
+ entry uint16
}
// double-symbols decoding
@@ -76,14 +75,15 @@ func ReadTable(in []byte, s *Scratch) (s2 *Scratch, remain []byte, err error) {
}
// collect weight stats
- var rankStats [tableLogMax + 1]uint32
+ var rankStats [16]uint32
weightTotal := uint32(0)
for _, v := range s.huffWeight[:s.symbolLen] {
if v > tableLogMax {
return s, nil, errors.New("corrupt input: weight too large")
}
- rankStats[v]++
- weightTotal += (1 << (v & 15)) >> 1
+ v2 := v & 15
+ rankStats[v2]++
+ weightTotal += (1 << v2) >> 1
}
if weightTotal == 0 {
return s, nil, errors.New("corrupt input: weights zero")
@@ -134,15 +134,17 @@ func ReadTable(in []byte, s *Scratch) (s2 *Scratch, remain []byte, err error) {
if len(s.dt.single) != tSize {
s.dt.single = make([]dEntrySingle, tSize)
}
-
for n, w := range s.huffWeight[:s.symbolLen] {
+ if w == 0 {
+ continue
+ }
length := (uint32(1) << w) >> 1
d := dEntrySingle{
- byte: uint8(n),
- nBits: s.actualTableLog + 1 - w,
+ entry: uint16(s.actualTableLog+1-w) | (uint16(n) << 8),
}
- for u := rankStats[w]; u < rankStats[w]+length; u++ {
- s.dt.single[u] = d
+ single := s.dt.single[rankStats[w] : rankStats[w]+length]
+ for i := range single {
+ single[i] = d
}
rankStats[w] += length
}
@@ -167,12 +169,12 @@ func (s *Scratch) Decompress1X(in []byte) (out []byte, err error) {
decode := func() byte {
val := br.peekBitsFast(s.actualTableLog) /* note : actualTableLog >= 1 */
v := s.dt.single[val]
- br.bitsRead += v.nBits
- return v.byte
+ br.bitsRead += uint8(v.entry)
+ return uint8(v.entry >> 8)
}
hasDec := func(v dEntrySingle) byte {
- br.bitsRead += v.nBits
- return v.byte
+ br.bitsRead += uint8(v.entry)
+ return uint8(v.entry >> 8)
}
// Avoid bounds check by always having full sized table.
@@ -269,8 +271,8 @@ func (s *Scratch) Decompress4X(in []byte, dstSize int) (out []byte, err error) {
decode := func(br *bitReader) byte {
val := br.peekBitsFast(s.actualTableLog) /* note : actualTableLog >= 1 */
v := single[val&tlMask]
- br.bitsRead += v.nBits
- return v.byte
+ br.bitsRead += uint8(v.entry)
+ return uint8(v.entry >> 8)
}
// Use temp table to avoid bound checks/append penalty.
@@ -283,20 +285,67 @@ func (s *Scratch) Decompress4X(in []byte, dstSize int) (out []byte, err error) {
bigloop:
for {
for i := range br {
- if br[i].off < 4 {
+ br := &br[i]
+ if br.off < 4 {
break bigloop
}
- br[i].fillFast()
+ br.fillFast()
+ }
+
+ {
+ const stream = 0
+ val := br[stream].peekBitsFast(s.actualTableLog)
+ v := single[val&tlMask]
+ br[stream].bitsRead += uint8(v.entry)
+
+ val2 := br[stream].peekBitsFast(s.actualTableLog)
+ v2 := single[val2&tlMask]
+ tmp[off+bufoff*stream+1] = uint8(v2.entry >> 8)
+ tmp[off+bufoff*stream] = uint8(v.entry >> 8)
+ br[stream].bitsRead += uint8(v2.entry)
+ }
+
+ {
+ const stream = 1
+ val := br[stream].peekBitsFast(s.actualTableLog)
+ v := single[val&tlMask]
+ br[stream].bitsRead += uint8(v.entry)
+
+ val2 := br[stream].peekBitsFast(s.actualTableLog)
+ v2 := single[val2&tlMask]
+ tmp[off+bufoff*stream+1] = uint8(v2.entry >> 8)
+ tmp[off+bufoff*stream] = uint8(v.entry >> 8)
+ br[stream].bitsRead += uint8(v2.entry)
+ }
+
+ {
+ const stream = 2
+ val := br[stream].peekBitsFast(s.actualTableLog)
+ v := single[val&tlMask]
+ br[stream].bitsRead += uint8(v.entry)
+
+ val2 := br[stream].peekBitsFast(s.actualTableLog)
+ v2 := single[val2&tlMask]
+ tmp[off+bufoff*stream+1] = uint8(v2.entry >> 8)
+ tmp[off+bufoff*stream] = uint8(v.entry >> 8)
+ br[stream].bitsRead += uint8(v2.entry)
}
- tmp[off] = decode(&br[0])
- tmp[off+bufoff] = decode(&br[1])
- tmp[off+bufoff*2] = decode(&br[2])
- tmp[off+bufoff*3] = decode(&br[3])
- tmp[off+1] = decode(&br[0])
- tmp[off+1+bufoff] = decode(&br[1])
- tmp[off+1+bufoff*2] = decode(&br[2])
- tmp[off+1+bufoff*3] = decode(&br[3])
+
+ {
+ const stream = 3
+ val := br[stream].peekBitsFast(s.actualTableLog)
+ v := single[val&tlMask]
+ br[stream].bitsRead += uint8(v.entry)
+
+ val2 := br[stream].peekBitsFast(s.actualTableLog)
+ v2 := single[val2&tlMask]
+ tmp[off+bufoff*stream+1] = uint8(v2.entry >> 8)
+ tmp[off+bufoff*stream] = uint8(v.entry >> 8)
+ br[stream].bitsRead += uint8(v2.entry)
+ }
+
off += 2
+
if off == bufoff {
if bufoff > dstEvery {
return nil, errors.New("corruption detected: stream overrun 1")
@@ -367,7 +416,7 @@ func (s *Scratch) matches(ct cTable, w io.Writer) {
broken++
if enc.nBits == 0 {
for _, dec := range dt {
- if dec.byte == byte(sym) {
+ if uint8(dec.entry>>8) == byte(sym) {
fmt.Fprintf(w, "symbol %x has decoder, but no encoder\n", sym)
errs++
break
@@ -383,12 +432,12 @@ func (s *Scratch) matches(ct cTable, w io.Writer) {
top := enc.val << ub
// decoder looks at top bits.
dec := dt[top]
- if dec.nBits != enc.nBits {
- fmt.Fprintf(w, "symbol 0x%x bit size mismatch (enc: %d, dec:%d).\n", sym, enc.nBits, dec.nBits)
+ if uint8(dec.entry) != enc.nBits {
+ fmt.Fprintf(w, "symbol 0x%x bit size mismatch (enc: %d, dec:%d).\n", sym, enc.nBits, uint8(dec.entry))
errs++
}
- if dec.byte != uint8(sym) {
- fmt.Fprintf(w, "symbol 0x%x decoder output mismatch (enc: %d, dec:%d).\n", sym, sym, dec.byte)
+ if uint8(dec.entry>>8) != uint8(sym) {
+ fmt.Fprintf(w, "symbol 0x%x decoder output mismatch (enc: %d, dec:%d).\n", sym, sym, uint8(dec.entry>>8))
errs++
}
if errs > 0 {
@@ -399,12 +448,12 @@ func (s *Scratch) matches(ct cTable, w io.Writer) {
for i := uint16(0); i < (1 << ub); i++ {
vval := top | i
dec := dt[vval]
- if dec.nBits != enc.nBits {
- fmt.Fprintf(w, "symbol 0x%x bit size mismatch (enc: %d, dec:%d).\n", vval, enc.nBits, dec.nBits)
+ if uint8(dec.entry) != enc.nBits {
+ fmt.Fprintf(w, "symbol 0x%x bit size mismatch (enc: %d, dec:%d).\n", vval, enc.nBits, uint8(dec.entry))
errs++
}
- if dec.byte != uint8(sym) {
- fmt.Fprintf(w, "symbol 0x%x decoder output mismatch (enc: %d, dec:%d).\n", vval, sym, dec.byte)
+ if uint8(dec.entry>>8) != uint8(sym) {
+ fmt.Fprintf(w, "symbol 0x%x decoder output mismatch (enc: %d, dec:%d).\n", vval, sym, uint8(dec.entry>>8))
errs++
}
if errs > 20 {
diff --git a/vendor/github.com/klauspost/compress/zstd/README.md b/vendor/github.com/klauspost/compress/zstd/README.md
index d9d38b23f..52dc0aee3 100644
--- a/vendor/github.com/klauspost/compress/zstd/README.md
+++ b/vendor/github.com/klauspost/compress/zstd/README.md
@@ -26,8 +26,12 @@ Godoc Documentation: https://godoc.org/github.com/klauspost/compress/zstd
### Status:
-BETA - there may still be subtle bugs, but a wide variety of content has been tested.
-There may still be implementation specific stuff in regards to error handling that could lead to edge cases.
+STABLE - there may always be subtle bugs, a wide variety of content has been tested and the library is actively
+used by several projects. This library is being continuously [fuzz-tested](https://github.com/klauspost/compress-fuzz),
+kindly supplied by [fuzzit.dev](https://fuzzit.dev/).
+
+There may still be specific combinations of data types/size/settings that could lead to edge cases,
+so as always, testing is recommended.
For now, a high speed (fastest) and medium-fast (default) compressor has been implemented.
@@ -251,8 +255,12 @@ The converter `s` can be reused to avoid allocations, even after errors.
## Decompressor
-STATUS: Release Candidate - there may still be subtle bugs, but a wide variety of content has been tested.
+Staus: STABLE - there may still be subtle bugs, but a wide variety of content has been tested.
+This library is being continuously [fuzz-tested](https://github.com/klauspost/compress-fuzz),
+kindly supplied by [fuzzit.dev](https://fuzzit.dev/).
+The main purpose of the fuzz testing is to ensure that it is not possible to crash the decoder,
+or run it past its limits with ANY input provided.
### Usage
diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go
index 47cc21d6d..ed670bcc7 100644
--- a/vendor/github.com/klauspost/compress/zstd/blockdec.go
+++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go
@@ -89,6 +89,7 @@ type blockDec struct {
sequenceBuf []seq
tmp [4]byte
err error
+ decWG sync.WaitGroup
}
func (b *blockDec) String() string {
@@ -105,6 +106,7 @@ func newBlockDec(lowMem bool) *blockDec {
input: make(chan struct{}, 1),
history: make(chan *history, 1),
}
+ b.decWG.Add(1)
go b.startDecoder()
return &b
}
@@ -183,11 +185,13 @@ func (b *blockDec) Close() {
close(b.input)
close(b.history)
close(b.result)
+ b.decWG.Wait()
}
// decodeAsync will prepare decoding the block when it receives input.
// This will separate output and history.
func (b *blockDec) startDecoder() {
+ defer b.decWG.Done()
for range b.input {
//println("blockDec: Got block input")
switch b.Type {
diff --git a/vendor/github.com/klauspost/compress/zstd/blockenc.go b/vendor/github.com/klauspost/compress/zstd/blockenc.go
index 8383279d2..99eccda11 100644
--- a/vendor/github.com/klauspost/compress/zstd/blockenc.go
+++ b/vendor/github.com/klauspost/compress/zstd/blockenc.go
@@ -300,13 +300,13 @@ func (b *blockEnc) encodeRaw(a []byte) {
}
// encodeLits can be used if the block is only litLen.
-func (b *blockEnc) encodeLits() error {
+func (b *blockEnc) encodeLits(raw bool) error {
var bh blockHeader
bh.setLast(b.last)
bh.setSize(uint32(len(b.literals)))
// Don't compress extremely small blocks
- if len(b.literals) < 32 {
+ if len(b.literals) < 32 || raw {
if debug {
println("Adding RAW block, length", len(b.literals))
}
@@ -438,9 +438,9 @@ func fuzzFseEncoder(data []byte) int {
}
// encode will encode the block and put the output in b.output.
-func (b *blockEnc) encode() error {
+func (b *blockEnc) encode(raw bool) error {
if len(b.sequences) == 0 {
- return b.encodeLits()
+ return b.encodeLits(raw)
}
// We want some difference
if len(b.literals) > (b.size - (b.size >> 5)) {
@@ -458,10 +458,10 @@ func (b *blockEnc) encode() error {
reUsed, single bool
err error
)
- if len(b.literals) >= 1024 {
+ if len(b.literals) >= 1024 && !raw {
// Use 4 Streams.
out, reUsed, err = huff0.Compress4X(b.literals, b.litEnc)
- } else if len(b.literals) > 32 {
+ } else if len(b.literals) > 32 && !raw {
// Use 1 stream
single = true
out, reUsed, err = huff0.Compress1X(b.literals, b.litEnc)
diff --git a/vendor/github.com/klauspost/compress/zstd/encoder.go b/vendor/github.com/klauspost/compress/zstd/encoder.go
index d79188271..f413042f4 100644
--- a/vendor/github.com/klauspost/compress/zstd/encoder.go
+++ b/vendor/github.com/klauspost/compress/zstd/encoder.go
@@ -262,7 +262,7 @@ func (e *Encoder) nextBlock(final bool) error {
// If we got the exact same number of literals as input,
// assume the literals cannot be compressed.
if len(src) != len(blk.literals) || len(src) != e.o.blockSize {
- err = blk.encode()
+ err = blk.encode(e.o.noEntropy)
}
switch err {
case errIncompressible:
@@ -473,7 +473,7 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte {
// If we got the exact same number of literals as input,
// assume the literals cannot be compressed.
if len(blk.literals) != len(todo) || len(todo) != e.o.blockSize {
- err = blk.encode()
+ err = blk.encode(e.o.noEntropy)
}
switch err {
diff --git a/vendor/github.com/klauspost/compress/zstd/encoder_options.go b/vendor/github.com/klauspost/compress/zstd/encoder_options.go
index 0f83a325a..40eb45733 100644
--- a/vendor/github.com/klauspost/compress/zstd/encoder_options.go
+++ b/vendor/github.com/klauspost/compress/zstd/encoder_options.go
@@ -20,6 +20,7 @@ type encoderOptions struct {
windowSize int
level EncoderLevel
fullZero bool
+ noEntropy bool
}
func (o *encoderOptions) setDefault() {
@@ -202,6 +203,16 @@ func WithZeroFrames(b bool) EOption {
}
}
+// WithNoEntropyCompression will always skip entropy compression of literals.
+// This can be useful if content has matches, but unlikely to benefit from entropy
+// compression. Usually the slight speed improvement is not worth enabling this.
+func WithNoEntropyCompression(b bool) EOption {
+ return func(o *encoderOptions) error {
+ o.noEntropy = b
+ return nil
+ }
+}
+
// WithSingleSegment will set the "single segment" flag when EncodeAll is used.
// If this flag is set, data must be regenerated within a single continuous memory segment.
// In this case, Window_Descriptor byte is skipped, but Frame_Content_Size is necessarily present.
diff --git a/vendor/github.com/klauspost/compress/zstd/framedec.go b/vendor/github.com/klauspost/compress/zstd/framedec.go
index 9e00437a2..40790747a 100644
--- a/vendor/github.com/klauspost/compress/zstd/framedec.go
+++ b/vendor/github.com/klauspost/compress/zstd/framedec.go
@@ -478,9 +478,10 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) {
if err == nil {
if n != len(dst)-crcStart {
err = io.ErrShortWrite
+ } else {
+ err = d.checkCRC()
}
}
- err = d.checkCRC()
}
}
d.history.b = saved
diff --git a/vendor/github.com/klauspost/compress/zstd/snappy.go b/vendor/github.com/klauspost/compress/zstd/snappy.go
index a048818f9..356956ba2 100644
--- a/vendor/github.com/klauspost/compress/zstd/snappy.go
+++ b/vendor/github.com/klauspost/compress/zstd/snappy.go
@@ -111,7 +111,7 @@ func (r *SnappyConverter) Convert(in io.Reader, w io.Writer) (int64, error) {
// Add empty last block
r.block.reset(nil)
r.block.last = true
- err := r.block.encodeLits()
+ err := r.block.encodeLits(false)
if err != nil {
return written, err
}
@@ -178,7 +178,7 @@ func (r *SnappyConverter) Convert(in io.Reader, w io.Writer) (int64, error) {
r.err = ErrSnappyCorrupt
return written, r.err
}
- err = r.block.encode()
+ err = r.block.encode(false)
switch err {
case errIncompressible:
r.block.popOffsets()
@@ -188,7 +188,7 @@ func (r *SnappyConverter) Convert(in io.Reader, w io.Writer) (int64, error) {
println("snappy.Decode:", err)
return written, err
}
- err = r.block.encodeLits()
+ err = r.block.encodeLits(false)
if err != nil {
return written, err
}
@@ -235,7 +235,7 @@ func (r *SnappyConverter) Convert(in io.Reader, w io.Writer) (int64, error) {
r.err = ErrSnappyCorrupt
return written, r.err
}
- err := r.block.encodeLits()
+ err := r.block.encodeLits(false)
if err != nil {
return written, err
}
diff --git a/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md b/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md
index c4590bf93..5e7e9d5e5 100644
--- a/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md
+++ b/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md
@@ -1,6 +1,16 @@
Changes by Version
==================
+2.20.1 (2019-11-08)
+-------------------
+
+Minor patch via https://github.com/jaegertracing/jaeger-client-go/pull/468
+
+- Make `AdaptiveSamplerUpdater` usable with default values; Resolves #467
+- Create `OperationNameLateBinding` sampler option and config option
+- Make `SamplerOptions` var of public type, so that its functions are discoverable via godoc
+
+
2.20.0 (2019-11-06)
-------------------
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 965f7c3ee..a0c32d804 100644
--- a/vendor/github.com/uber/jaeger-client-go/config/config.go
+++ b/vendor/github.com/uber/jaeger-client-go/config/config.go
@@ -76,17 +76,26 @@ type SamplerConfig struct {
// Can be set by exporting an environment variable named JAEGER_SAMPLER_MANAGER_HOST_PORT
SamplingServerURL string `yaml:"samplingServerURL"`
- // MaxOperations is the maximum number of operations that the sampler
- // will keep track of. If an operation is not tracked, a default probabilistic
- // sampler will be used rather than the per operation specific sampler.
- // Can be set by exporting an environment variable named JAEGER_SAMPLER_MAX_OPERATIONS
- MaxOperations int `yaml:"maxOperations"`
-
// SamplingRefreshInterval controls how often the remotely controlled sampler will poll
// 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"`
+ // MaxOperations is the maximum number of operations that the PerOperationSampler
+ // will keep track of. If an operation is not tracked, a default probabilistic
+ // sampler will be used rather than the per operation specific sampler.
+ // Can be set by exporting an environment variable named JAEGER_SAMPLER_MAX_OPERATIONS.
+ MaxOperations int `yaml:"maxOperations"`
+
+ // Opt-in feature for applications that require late binding of span name via explicit
+ // call to SetOperationName when using PerOperationSampler. 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 `yaml:"operationNameLateBinding"`
+
// Options can be used to programmatically pass additional options to the Remote sampler.
Options []jaeger.SamplerOption
}
@@ -335,7 +344,7 @@ func (sc *SamplerConfig) NewSampler(
return jaeger.NewProbabilisticSampler(sc.Param)
}
return nil, fmt.Errorf(
- "Invalid Param for probabilistic sampler: %v. Expecting value between 0 and 1",
+ "invalid Param for probabilistic sampler; expecting value between 0 and 1, received %v",
sc.Param,
)
}
@@ -353,17 +362,14 @@ func (sc *SamplerConfig) NewSampler(
jaeger.SamplerOptions.Metrics(metrics),
jaeger.SamplerOptions.InitialSampler(initSampler),
jaeger.SamplerOptions.SamplingServerURL(sc.SamplingServerURL),
- }
- if sc.MaxOperations != 0 {
- options = append(options, jaeger.SamplerOptions.MaxOperations(sc.MaxOperations))
- }
- if sc.SamplingRefreshInterval != 0 {
- options = append(options, jaeger.SamplerOptions.SamplingRefreshInterval(sc.SamplingRefreshInterval))
+ jaeger.SamplerOptions.MaxOperations(sc.MaxOperations),
+ jaeger.SamplerOptions.OperationNameLateBinding(sc.OperationNameLateBinding),
+ 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)
+ return nil, fmt.Errorf("unknown sampler type (%s)", sc.Type)
}
// NewReporter instantiates a new reporter that submits spans to the collector
diff --git a/vendor/github.com/uber/jaeger-client-go/constants.go b/vendor/github.com/uber/jaeger-client-go/constants.go
index 0da47b02f..5d27b628d 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.20.0"
+ JaegerClientVersion = "Go-2.20.1"
// 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/sampler.go b/vendor/github.com/uber/jaeger-client-go/sampler.go
index 6195d59c5..f47004b1f 100644
--- a/vendor/github.com/uber/jaeger-client-go/sampler.go
+++ b/vendor/github.com/uber/jaeger-client-go/sampler.go
@@ -363,6 +363,9 @@ type PerOperationSamplerParams struct {
// NewPerOperationSampler returns a new PerOperationSampler.
func NewPerOperationSampler(params PerOperationSamplerParams) *PerOperationSampler {
+ if params.MaxOperations <= 0 {
+ params.MaxOperations = defaultMaxOperations
+ }
samplers := make(map[string]*GuaranteedThroughputProbabilisticSampler)
for _, strategy := range params.Strategies.PerOperationStrategies {
sampler := newGuaranteedThroughputProbabilisticSampler(
diff --git a/vendor/github.com/uber/jaeger-client-go/sampler_remote.go b/vendor/github.com/uber/jaeger-client-go/sampler_remote.go
index 9bd0c9822..4448b8f64 100644
--- a/vendor/github.com/uber/jaeger-client-go/sampler_remote.go
+++ b/vendor/github.com/uber/jaeger-client-go/sampler_remote.go
@@ -258,8 +258,9 @@ func (u *RateLimitingSamplerUpdater) Update(sampler SamplerV2, strategy interfac
// -----------------------
// AdaptiveSamplerUpdater is used by RemotelyControlledSampler to parse sampling configuration.
+// Fields have the same meaning as in PerOperationSamplerParams.
type AdaptiveSamplerUpdater struct {
- MaxOperations int // required
+ MaxOperations int
OperationNameLateBinding bool
}
diff --git a/vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go b/vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go
index 7a292effc..3b5c6aa9c 100644
--- a/vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go
+++ b/vendor/github.com/uber/jaeger-client-go/sampler_remote_options.go
@@ -23,12 +23,17 @@ import (
// SamplerOption is a function that sets some option on the sampler
type SamplerOption func(options *samplerOptions)
-// SamplerOptions is a factory for all available SamplerOption's
-var SamplerOptions samplerOptions
+// SamplerOptions is a factory for all available SamplerOption's.
+var SamplerOptions SamplerOptionsFactory
+
+// SamplerOptionsFactory is a factory for all available SamplerOption's.
+// The type acts as a namespace for factory functions. It is public to
+// make the functions discoverable via godoc. Recommended to be used
+// via global SamplerOptions variable.
+type SamplerOptionsFactory struct{}
type samplerOptions struct {
metrics *Metrics
- maxOperations int
sampler SamplerV2
logger Logger
samplingServerURL string
@@ -36,11 +41,12 @@ type samplerOptions struct {
samplingFetcher SamplingStrategyFetcher
samplingParser SamplingStrategyParser
updaters []SamplerUpdater
+ posParams PerOperationSamplerParams
}
// Metrics creates a SamplerOption that initializes Metrics on the sampler,
// which is used to emit statistics.
-func (samplerOptions) Metrics(m *Metrics) SamplerOption {
+func (SamplerOptionsFactory) Metrics(m *Metrics) SamplerOption {
return func(o *samplerOptions) {
o.metrics = m
}
@@ -48,22 +54,30 @@ func (samplerOptions) Metrics(m *Metrics) SamplerOption {
// MaxOperations creates a SamplerOption that sets the maximum number of
// operations the sampler will keep track of.
-func (samplerOptions) MaxOperations(maxOperations int) SamplerOption {
+func (SamplerOptionsFactory) MaxOperations(maxOperations int) SamplerOption {
+ return func(o *samplerOptions) {
+ o.posParams.MaxOperations = maxOperations
+ }
+}
+
+// OperationNameLateBinding creates a SamplerOption that sets the respective
+// field in the PerOperationSamplerParams.
+func (SamplerOptionsFactory) OperationNameLateBinding(enable bool) SamplerOption {
return func(o *samplerOptions) {
- o.maxOperations = maxOperations
+ o.posParams.OperationNameLateBinding = enable
}
}
// InitialSampler creates a SamplerOption that sets the initial sampler
// to use before a remote sampler is created and used.
-func (samplerOptions) InitialSampler(sampler Sampler) SamplerOption {
+func (SamplerOptionsFactory) InitialSampler(sampler Sampler) SamplerOption {
return func(o *samplerOptions) {
o.sampler = samplerV1toV2(sampler)
}
}
// Logger creates a SamplerOption that sets the logger used by the sampler.
-func (samplerOptions) Logger(logger Logger) SamplerOption {
+func (SamplerOptionsFactory) Logger(logger Logger) SamplerOption {
return func(o *samplerOptions) {
o.logger = logger
}
@@ -71,7 +85,7 @@ func (samplerOptions) Logger(logger Logger) SamplerOption {
// SamplingServerURL creates a SamplerOption that sets the sampling server url
// of the local agent that contains the sampling strategies.
-func (samplerOptions) SamplingServerURL(samplingServerURL string) SamplerOption {
+func (SamplerOptionsFactory) SamplingServerURL(samplingServerURL string) SamplerOption {
return func(o *samplerOptions) {
o.samplingServerURL = samplingServerURL
}
@@ -79,28 +93,28 @@ func (samplerOptions) SamplingServerURL(samplingServerURL string) SamplerOption
// SamplingRefreshInterval creates a SamplerOption that sets how often the
// sampler will poll local agent for the appropriate sampling strategy.
-func (samplerOptions) SamplingRefreshInterval(samplingRefreshInterval time.Duration) SamplerOption {
+func (SamplerOptionsFactory) SamplingRefreshInterval(samplingRefreshInterval time.Duration) SamplerOption {
return func(o *samplerOptions) {
o.samplingRefreshInterval = samplingRefreshInterval
}
}
// SamplingStrategyFetcher creates a SamplerOption that initializes sampling strategy fetcher.
-func (samplerOptions) SamplingStrategyFetcher(fetcher SamplingStrategyFetcher) SamplerOption {
+func (SamplerOptionsFactory) 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 {
+func (SamplerOptionsFactory) 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 {
+func (SamplerOptionsFactory) Updaters(updaters ...SamplerUpdater) SamplerOption {
return func(o *samplerOptions) {
o.updaters = updaters
}
@@ -116,9 +130,6 @@ func (o *samplerOptions) applyOptionsAndDefaults(opts ...SamplerOption) *sampler
if o.logger == nil {
o.logger = log.NullLogger
}
- if o.maxOperations <= 0 {
- o.maxOperations = defaultMaxOperations
- }
if o.samplingServerURL == "" {
o.samplingServerURL = DefaultSamplingServerURL
}
@@ -139,7 +150,10 @@ func (o *samplerOptions) applyOptionsAndDefaults(opts ...SamplerOption) *sampler
}
if o.updaters == nil {
o.updaters = []SamplerUpdater{
- &AdaptiveSamplerUpdater{MaxOperations: o.maxOperations},
+ &AdaptiveSamplerUpdater{
+ MaxOperations: o.posParams.MaxOperations,
+ OperationNameLateBinding: o.posParams.OperationNameLateBinding,
+ },
new(ProbabilisticSamplerUpdater),
new(RateLimitingSamplerUpdater),
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 3337bae80..ba692e089 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -8,7 +8,7 @@ github.com/Microsoft/go-winio
github.com/Microsoft/go-winio/archive/tar
github.com/Microsoft/go-winio/backuptar
github.com/Microsoft/go-winio/pkg/guid
-# github.com/Microsoft/hcsshim v0.8.7-0.20191101173118-65519b62243c
+# github.com/Microsoft/hcsshim v0.8.7
github.com/Microsoft/hcsshim
github.com/Microsoft/hcsshim/internal/cow
github.com/Microsoft/hcsshim/internal/hcs
@@ -117,7 +117,7 @@ github.com/containers/image/v5/types
github.com/containers/image/v5/version
# github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b
github.com/containers/libtrust
-# github.com/containers/psgo v1.3.2
+# github.com/containers/psgo v1.4.0
github.com/containers/psgo
github.com/containers/psgo/internal/capabilities
github.com/containers/psgo/internal/cgroups
@@ -125,7 +125,7 @@ github.com/containers/psgo/internal/dev
github.com/containers/psgo/internal/host
github.com/containers/psgo/internal/proc
github.com/containers/psgo/internal/process
-# github.com/containers/storage v1.15.0
+# github.com/containers/storage v1.15.3
github.com/containers/storage
github.com/containers/storage/drivers
github.com/containers/storage/drivers/aufs
@@ -295,7 +295,7 @@ github.com/inconshreveable/mousetrap
github.com/ishidawataru/sctp
# github.com/json-iterator/go v1.1.8
github.com/json-iterator/go
-# github.com/klauspost/compress v1.9.2
+# github.com/klauspost/compress v1.9.4
github.com/klauspost/compress/flate
github.com/klauspost/compress/fse
github.com/klauspost/compress/huff0
@@ -451,7 +451,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.20.0+incompatible
+# github.com/uber/jaeger-client-go v2.20.1+incompatible
github.com/uber/jaeger-client-go
github.com/uber/jaeger-client-go/config
github.com/uber/jaeger-client-go/internal/baggage
diff --git a/version/version.go b/version/version.go
index 129a2cd4b..e75d1e713 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.4-dev"
+const Version = "1.7.0-dev"
// RemoteAPIVersion is the version for the remote
// client API. It is used to determine compatibility