summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml18
-rw-r--r--.github/workflows/multi-arch-build.yaml5
-rw-r--r--Makefile17
-rw-r--r--cmd/podman/containers/create.go61
-rw-r--r--cmd/podman/containers/mount.go12
-rw-r--r--cmd/podman/containers/ps.go17
-rw-r--r--cmd/podman/containers/stats.go29
-rw-r--r--cmd/podman/containers/top.go10
-rw-r--r--cmd/podman/images/history.go13
-rw-r--r--cmd/podman/images/list.go22
-rw-r--r--cmd/podman/images/mount.go13
-rw-r--r--cmd/podman/images/push.go2
-rw-r--r--cmd/podman/images/search.go15
-rw-r--r--cmd/podman/images/trust_show.go23
-rw-r--r--cmd/podman/inspect/inspect.go9
-rw-r--r--cmd/podman/machine/list.go15
-rw-r--r--cmd/podman/networks/list.go10
-rw-r--r--cmd/podman/parse/template.go22
-rw-r--r--cmd/podman/parse/template_test.go30
-rw-r--r--cmd/podman/pods/create.go53
-rw-r--r--cmd/podman/pods/inspect.go9
-rw-r--r--cmd/podman/pods/ps.go15
-rw-r--r--cmd/podman/pods/stats.go23
-rw-r--r--cmd/podman/pods/top.go8
-rw-r--r--cmd/podman/secrets/inspect.go13
-rw-r--r--cmd/podman/secrets/list.go15
-rw-r--r--cmd/podman/system/connection/list.go45
-rw-r--r--cmd/podman/system/df.go18
-rw-r--r--cmd/podman/system/events.go5
-rw-r--r--cmd/podman/system/info.go3
-rw-r--r--cmd/podman/system/version.go11
-rw-r--r--cmd/podman/volumes/list.go13
-rw-r--r--contrib/podmanimage/stable/Dockerfile1
-rw-r--r--contrib/podmanimage/testing/Dockerfile1
-rw-r--r--contrib/podmanimage/upstream/Dockerfile1
-rw-r--r--contrib/spec/podman.spec.in2
-rw-r--r--contrib/systemd/system/podman-restart.service12
-rw-r--r--contrib/systemd/system/podman.service3
-rw-r--r--contrib/tmpfile/podman.conf1
-rw-r--r--docs/source/markdown/podman-image-unmount.1.md2
-rw-r--r--docs/source/markdown/podman-image.1.md2
-rw-r--r--docs/source/markdown/podman-login.1.md46
-rw-r--r--docs/source/markdown/podman-pod-create.1.md16
-rw-r--r--docs/source/markdown/podman-pull.1.md48
-rw-r--r--docs/source/markdown/podman-push.1.md43
-rw-r--r--docs/source/markdown/podman-rmi.1.md1
-rw-r--r--docs/source/markdown/podman-run.1.md4
-rw-r--r--docs/source/markdown/podman-system-connection-list.1.md19
-rw-r--r--go.mod14
-rw-r--r--go.sum45
-rw-r--r--libpod/container_exec.go16
-rw-r--r--libpod/container_internal.go62
-rw-r--r--libpod/container_internal_linux.go84
-rw-r--r--libpod/container_internal_unsupported.go5
-rw-r--r--libpod/container_log.go24
-rw-r--r--libpod/container_validate.go1
-rw-r--r--libpod/define/containerstate.go10
-rw-r--r--libpod/define/pod_inspect.go12
-rw-r--r--libpod/networking_linux.go38
-rw-r--r--libpod/oci.go7
-rw-r--r--libpod/oci_attach_linux.go13
-rw-r--r--libpod/oci_conmon_exec_linux.go19
-rw-r--r--libpod/oci_missing.go5
-rw-r--r--libpod/options.go48
-rw-r--r--libpod/pod.go104
-rw-r--r--libpod/pod_api.go6
-rw-r--r--libpod/runtime.go7
-rw-r--r--libpod/runtime_pod_infra_linux.go8
-rw-r--r--libpod/stats.go10
-rw-r--r--pkg/api/handlers/compat/containers.go18
-rw-r--r--pkg/api/handlers/compat/exec.go10
-rw-r--r--pkg/api/handlers/compat/images.go25
-rw-r--r--pkg/api/handlers/compat/images_build.go4
-rw-r--r--pkg/api/handlers/compat/resize.go2
-rw-r--r--pkg/api/handlers/libpod/images_pull.go24
-rw-r--r--pkg/api/handlers/types.go6
-rw-r--r--pkg/api/server/register_exec.go10
-rw-r--r--pkg/api/server/register_images.go12
-rw-r--r--pkg/api/server/register_volumes.go6
-rw-r--r--pkg/bindings/containers/attach.go24
-rw-r--r--pkg/bindings/images/build.go16
-rw-r--r--pkg/bindings/images/pull.go10
-rw-r--r--pkg/bindings/images/types.go3
-rw-r--r--pkg/bindings/images/types_pull_options.go16
-rw-r--r--pkg/cgroups/cgroups.go5
-rw-r--r--pkg/domain/entities/images.go4
-rw-r--r--pkg/domain/entities/pods.go41
-rw-r--r--pkg/domain/filters/volumes.go15
-rw-r--r--pkg/domain/infra/abi/containers.go9
-rw-r--r--pkg/domain/infra/abi/images.go2
-rw-r--r--pkg/domain/infra/abi/terminal/terminal_linux.go4
-rw-r--r--pkg/domain/infra/tunnel/containers.go8
-rw-r--r--pkg/domain/infra/tunnel/images.go2
-rw-r--r--pkg/errorhandling/errorhandling.go9
-rw-r--r--pkg/specgen/generate/container.go3
-rw-r--r--pkg/specgen/generate/container_create.go4
-rw-r--r--pkg/specgen/generate/pod_create.go8
-rw-r--r--pkg/specgen/podspecgen.go12
-rw-r--r--pkg/specgen/specgen.go4
-rw-r--r--test/apiv2/30-volumes.at47
-rw-r--r--test/apiv2/python/rest_api/test_v2_0_0_container.py23
-rw-r--r--test/apiv2/python/rest_api/test_v2_0_0_image.py3
-rw-r--r--test/e2e/build_test.go34
-rw-r--r--test/e2e/info_test.go4
-rw-r--r--test/e2e/pod_create_test.go44
-rw-r--r--test/e2e/run_test.go23
-rw-r--r--test/e2e/stats_test.go11
-rw-r--r--test/e2e/system_connection_test.go6
-rw-r--r--test/system/010-images.bats15
-rw-r--r--test/system/045-start.bats11
-rw-r--r--test/system/070-build.bats23
-rw-r--r--test/system/255-auto-update.bats2
-rw-r--r--test/system/450-interactive.bats13
-rw-r--r--test/system/500-networking.bats14
-rw-r--r--utils/utils_supported.go4
-rw-r--r--vendor/github.com/containers/common/libimage/download.go4
-rw-r--r--vendor/github.com/containers/common/libimage/image.go34
-rw-r--r--vendor/github.com/containers/common/libimage/import.go10
-rw-r--r--vendor/github.com/containers/common/libimage/pull.go50
-rw-r--r--vendor/github.com/containers/common/libimage/runtime.go65
-rw-r--r--vendor/github.com/containers/common/pkg/auth/auth.go6
-rw-r--r--vendor/github.com/containers/common/pkg/auth/cli.go2
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go73
-rw-r--r--vendor/github.com/containers/common/pkg/config/containers.conf170
-rw-r--r--vendor/github.com/containers/common/pkg/config/default.go16
-rw-r--r--vendor/github.com/containers/common/pkg/report/template.go6
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/conversion.go1
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/default_linux.go180
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/filter.go2
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/seccomp.json207
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/seccomp_linux.go1
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/types.go3
-rw-r--r--vendor/github.com/containers/common/pkg/secrets/passdriver/passdriver.go176
-rw-r--r--vendor/github.com/containers/common/pkg/secrets/secrets.go6
-rw-r--r--vendor/github.com/containers/common/version/version.go2
-rw-r--r--vendor/github.com/containers/image/v5/copy/copy.go53
-rw-r--r--vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go2
-rw-r--r--vendor/github.com/containers/image/v5/internal/types/types.go4
-rw-r--r--vendor/github.com/containers/image/v5/pkg/docker/config/config.go50
-rw-r--r--vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go12
-rw-r--r--vendor/github.com/containers/image/v5/pkg/docker/config/config_unsupported.go8
-rw-r--r--vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go4
-rw-r--r--vendor/github.com/containers/image/v5/storage/storage_image.go91
-rw-r--r--vendor/github.com/containers/image/v5/version/version.go4
-rw-r--r--vendor/github.com/containers/storage/.cirrus.yml2
-rw-r--r--vendor/github.com/containers/storage/CODE-OF-CONDUCT.md2
-rw-r--r--vendor/github.com/containers/storage/SECURITY.md2
-rw-r--r--vendor/github.com/containers/storage/VERSION2
-rw-r--r--vendor/github.com/containers/storage/drivers/devmapper/deviceset.go2
-rw-r--r--vendor/github.com/containers/storage/go.mod2
-rw-r--r--vendor/github.com/containers/storage/go.sum4
-rw-r--r--vendor/github.com/containers/storage/layers.go51
-rw-r--r--vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go71
-rw-r--r--vendor/github.com/docker/docker-credential-helpers/client/command.go3
-rw-r--r--vendor/github.com/docker/docker-credential-helpers/credentials/version.go2
-rw-r--r--vendor/github.com/imdario/mergo/.travis.yml3
-rw-r--r--vendor/github.com/imdario/mergo/README.md2
-rw-r--r--vendor/github.com/imdario/mergo/merge.go9
-rw-r--r--vendor/github.com/jinzhu/copier/README.md9
-rw-r--r--vendor/github.com/jinzhu/copier/copier.go174
-rw-r--r--vendor/github.com/klauspost/compress/zstd/blockdec.go4
-rw-r--r--vendor/github.com/klauspost/compress/zstd/decoder_options.go25
-rw-r--r--vendor/github.com/klauspost/compress/zstd/framedec.go32
-rw-r--r--vendor/github.com/mattn/go-runewidth/go.mod2
-rw-r--r--vendor/github.com/mattn/go-runewidth/go.sum4
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/.gitignore5
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/.travis.yml11
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/README.md121
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/UNLICENSE24
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar.go492
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar_filler.go39
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar_filler_bar.go219
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar_filler_spinner.go87
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar_option.go153
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/container_option.go112
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/doc.go2
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/util_bsd.go7
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/util_linux.go7
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/util_solaris.go7
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go84
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go26
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/writer_windows.go73
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/any.go21
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/counters.go243
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/decorator.go191
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/doc.go19
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/elapsed.go35
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/eta.go203
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/merge.go107
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/moving_average.go68
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/name.go12
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go37
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/percentage.go58
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/size_type.go109
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/sizeb1000_string.go41
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/sizeb1024_string.go41
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/speed.go171
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/spinner.go21
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/doc.go2
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/go.mod10
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/go.sum10
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/internal/percentage.go19
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/internal/predicate.go6
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/internal/width.go10
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/priority_queue.go32
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/progress.go412
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/proxyreader.go90
-rw-r--r--vendor/golang.org/x/sys/unix/README.md6
-rw-r--r--vendor/golang.org/x/sys/unix/asm_bsd_386.s4
-rw-r--r--vendor/golang.org/x/sys/unix/asm_bsd_arm.s4
-rw-r--r--vendor/golang.org/x/sys/unix/mkerrors.sh8
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux.go71
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux_386.go4
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux_amd64.go4
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux_arm.go4
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux_arm64.go4
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go4
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go4
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux_ppc.go4
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go4
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go4
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux_s390x.go4
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go4
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux.go90
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_386.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_arm.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_mips.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go19
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go19
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux.go163
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_386.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_arm.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_mips.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go18
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go18
-rw-r--r--vendor/golang.org/x/sys/windows/exec_windows.go47
-rw-r--r--vendor/golang.org/x/sys/windows/syscall_windows.go1
-rw-r--r--vendor/golang.org/x/sys/windows/types_windows.go17
-rw-r--r--vendor/golang.org/x/sys/windows/zsyscall_windows.go13
-rw-r--r--vendor/modules.txt30
258 files changed, 6988 insertions, 1021 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 1eb516d84..d32275a39 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -30,17 +30,20 @@ env:
PRIOR_UBUNTU_NAME: "ubuntu-2010"
# Google-cloud VM Images
+ # TODO: At the time of this comment, an selinux-policy regression is blocking use of updated
+ # Fedora VM images: https://bugzilla.redhat.com/show_bug.cgi?id=1965743
+ IMAGE_SUFFIX_UBUNTU: "c5521575421149184"
IMAGE_SUFFIX: "c5348179051806720"
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}"
- UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX}"
- PRIOR_UBUNTU_CACHE_IMAGE_NAME: "prior-ubuntu-${IMAGE_SUFFIX}"
+ UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX_UBUNTU}"
+ PRIOR_UBUNTU_CACHE_IMAGE_NAME: "prior-ubuntu-${IMAGE_SUFFIX_UBUNTU}"
# Container FQIN's
FEDORA_CONTAINER_FQIN: "quay.io/libpod/fedora_podman:${IMAGE_SUFFIX}"
PRIOR_FEDORA_CONTAINER_FQIN: "quay.io/libpod/prior-fedora_podman:${IMAGE_SUFFIX}"
- UBUNTU_CONTAINER_FQIN: "quay.io/libpod/ubuntu_podman:${IMAGE_SUFFIX}"
- PRIOR_UBUNTU_CONTAINER_FQIN: "quay.io/libpod/prior-ubuntu_podman:${IMAGE_SUFFIX}"
+ UBUNTU_CONTAINER_FQIN: "quay.io/libpod/ubuntu_podman:${IMAGE_SUFFIX_UBUNTU}"
+ PRIOR_UBUNTU_CONTAINER_FQIN: "quay.io/libpod/prior-ubuntu_podman:${IMAGE_SUFFIX_UBUNTU}"
####
#### Control variables that determine what to run and how to run it.
@@ -670,11 +673,18 @@ meta_task:
image: quay.io/libpod/imgts:$IMAGE_SUFFIX
env:
# Space-separated list of images used by this repository state
+ # TODO: Protect commonly tagged ubuntu images from puning in case
+ # workaround for BZ1965743 remains in use beyond the 30-days.
+ # Ref sha 404d5edb155
IMGNAMES: >-
${FEDORA_CACHE_IMAGE_NAME}
${PRIOR_FEDORA_CACHE_IMAGE_NAME}
${UBUNTU_CACHE_IMAGE_NAME}
${PRIOR_UBUNTU_CACHE_IMAGE_NAME}
+ fedora-${IMAGE_SUFFIX_UBUNTU}
+ prior-fedora-${IMAGE_SUFFIX_UBUNTU}
+ ubuntu-${IMAGE_SUFFIX}
+ prior-ubuntu-${IMAGE_SUFFIX}
BUILDID: "${CIRRUS_BUILD_ID}"
REPOREF: "${CIRRUS_REPO_NAME}"
GCPJSON: ENCRYPTED[3a198350077849c8df14b723c0f4c9fece9ebe6408d35982e7adf2105a33f8e0e166ed3ed614875a0887e1af2b8775f4]
diff --git a/.github/workflows/multi-arch-build.yaml b/.github/workflows/multi-arch-build.yaml
index 2ade44ee6..9bd98078b 100644
--- a/.github/workflows/multi-arch-build.yaml
+++ b/.github/workflows/multi-arch-build.yaml
@@ -72,7 +72,10 @@ jobs:
if: matrix.source == 'stable'
id: sniff_test
run: |
- VERSION_OUTPUT="$(docker run localhost:5000/podman/${{ matrix.source }} \
+ podman pull --tls-verify=false \
+ localhost:5000/podman/${{ matrix.source }}
+ VERSION_OUTPUT="$(podman run \
+ localhost:5000/podman/${{ matrix.source }} \
podman --storage-driver=vfs version)"
echo "$VERSION_OUTPUT"
VERSION=$(grep -Em1 '^Version: ' <<<"$VERSION_OUTPUT" | awk '{print $2}')
diff --git a/Makefile b/Makefile
index 3e40881f3..53be33ea3 100644
--- a/Makefile
+++ b/Makefile
@@ -93,11 +93,14 @@ LIBPOD := ${PROJECT}/v3/libpod
GCFLAGS ?= all=-trimpath=$(CURDIR)
ASMFLAGS ?= all=-trimpath=$(CURDIR)
LDFLAGS_PODMAN ?= \
- -X $(LIBPOD)/define.gitCommit=$(GIT_COMMIT) \
- -X $(LIBPOD)/define.buildInfo=$(BUILD_INFO) \
- -X $(LIBPOD)/config._installPrefix=$(PREFIX) \
- -X $(LIBPOD)/config._etcDir=$(ETCDIR) \
- $(EXTRA_LDFLAGS)
+ -X $(LIBPOD)/define.gitCommit=$(GIT_COMMIT) \
+ -X $(LIBPOD)/define.buildInfo=$(BUILD_INFO) \
+ -X $(LIBPOD)/config._installPrefix=$(PREFIX) \
+ -X $(LIBPOD)/config._etcDir=$(ETCDIR) \
+ $(EXTRA_LDFLAGS)
+LDFLAGS_PODMAN_STATIC ?= \
+ $(LDFLAGS_PODMAN) \
+ -extldflags=-static
#Update to LIBSECCOMP_COMMIT should reflect in Dockerfile too.
LIBSECCOMP_COMMIT := v2.3.3
# Rarely if ever should integration tests take more than 50min,
@@ -314,7 +317,7 @@ $(SRCBINDIR)/podman$(BINSFX): $(SRCBINDIR) .gopathok $(SOURCES) go.mod go.sum
-o $@ ./cmd/podman
$(SRCBINDIR)/podman-remote-static: $(SRCBINDIR) .gopathok $(SOURCES) go.mod go.sum
- CGO_ENABLED=$(CGO_ENABLED) \
+ CGO_ENABLED=0 \
GOOS=$(GOOS) \
$(GO) build \
$(BUILDFLAGS) \
@@ -748,11 +751,13 @@ install.systemd:
install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.timer ${DESTDIR}${USERSYSTEMDDIR}/podman-auto-update.timer
install ${SELINUXOPT} -m 644 contrib/systemd/user/podman.socket ${DESTDIR}${USERSYSTEMDDIR}/podman.socket
install ${SELINUXOPT} -m 644 contrib/systemd/user/podman.service ${DESTDIR}${USERSYSTEMDDIR}/podman.service
+ install ${SELINUXOPT} -m 644 contrib/systemd/user/podman-restart.service ${DESTDIR}${USERSYSTEMDDIR}/podman-restart.service
# System services
install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.service ${DESTDIR}${SYSTEMDDIR}/podman-auto-update.service
install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.timer ${DESTDIR}${SYSTEMDDIR}/podman-auto-update.timer
install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.socket ${DESTDIR}${SYSTEMDDIR}/podman.socket
install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.service ${DESTDIR}${SYSTEMDDIR}/podman.service
+ install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-restart.service ${DESTDIR}${SYSTEMDDIR}/podman-restart.service
else
install.systemd:
endif
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 68a17abd0..1e11c53d5 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -8,7 +8,6 @@ import (
"strings"
"github.com/containers/common/pkg/config"
- storageTransport "github.com/containers/image/v5/storage"
"github.com/containers/image/v5/transports/alltransports"
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
@@ -16,9 +15,7 @@ import (
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
- "github.com/containers/storage"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@@ -225,7 +222,6 @@ func createInit(c *cobra.Command) error {
}
cliVals.Env = env
}
-
if c.Flag("cgroups").Changed && cliVals.CGroupsMode == "split" && registry.IsRemote() {
return errors.Errorf("the option --cgroups=%q is not supported in remote mode", cliVals.CGroupsMode)
}
@@ -236,30 +232,12 @@ func createInit(c *cobra.Command) error {
return nil
}
-// TODO: we should let the backend take care of the pull policy (which it
-// does!). The code below is at risk of causing regression and code divergence.
func pullImage(imageName string) (string, error) {
pullPolicy, err := config.ValidatePullPolicy(cliVals.Pull)
if err != nil {
return "", err
}
- // Check if the image is missing and hence if we need to pull it.
- imageMissing := true
- imageRef, err := alltransports.ParseImageName(imageName)
- switch {
- case err != nil:
- // Assume we specified a local image without the explicit storage transport.
- fallthrough
-
- case imageRef.Transport().Name() == storageTransport.Transport.Name():
- br, err := registry.ImageEngine().Exists(registry.GetContext(), imageName)
- if err != nil {
- return "", err
- }
- imageMissing = !br.Value
- }
-
if cliVals.Platform != "" || cliVals.Arch != "" || cliVals.OS != "" {
if cliVals.Platform != "" {
if cliVals.Arch != "" || cliVals.OS != "" {
@@ -271,31 +249,28 @@ func pullImage(imageName string) (string, error) {
cliVals.Arch = split[1]
}
}
+ }
- if pullPolicy != config.PullPolicyAlways {
- logrus.Info("--platform --arch and --os causes the pull policy to be \"always\"")
- pullPolicy = config.PullPolicyAlways
- }
+ pullReport, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{
+ Authfile: cliVals.Authfile,
+ Quiet: cliVals.Quiet,
+ Arch: cliVals.Arch,
+ OS: cliVals.OS,
+ Variant: cliVals.Variant,
+ SignaturePolicy: cliVals.SignaturePolicy,
+ PullPolicy: pullPolicy,
+ })
+ if pullErr != nil {
+ return "", pullErr
}
- if imageMissing || pullPolicy == config.PullPolicyAlways {
- if pullPolicy == config.PullPolicyNever {
- return "", errors.Wrap(storage.ErrImageUnknown, imageName)
- }
- pullReport, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{
- Authfile: cliVals.Authfile,
- Quiet: cliVals.Quiet,
- Arch: cliVals.Arch,
- OS: cliVals.OS,
- Variant: cliVals.Variant,
- SignaturePolicy: cliVals.SignaturePolicy,
- PullPolicy: pullPolicy,
- })
- if pullErr != nil {
- return "", pullErr
- }
+ // Return the input name such that the image resolves to correct
+ // repo/tag in the backend (see #8082). Unless we're referring to
+ // the image via a transport.
+ if _, err := alltransports.ParseImageName(imageName); err == nil {
imageName = pullReport.Images[0]
}
+
return imageName, nil
}
@@ -316,6 +291,8 @@ func createPodIfNecessary(s *specgen.SpecGenerator, netOpts *entities.NetOptions
Net: netOpts,
CreateCommand: os.Args,
Hostname: s.ContainerBasicConfig.Hostname,
+ Cpus: cliVals.CPUS,
+ CpusetCpus: cliVals.CPUSetCPUs,
}
// Unset config values we passed to the pod to prevent them being used twice for the container and pod.
s.ContainerBasicConfig.Hostname = ""
diff --git a/cmd/podman/containers/mount.go b/cmd/podman/containers/mount.go
index 8a7c542ba..55f6a1c34 100644
--- a/cmd/podman/containers/mount.go
+++ b/cmd/podman/containers/mount.go
@@ -3,8 +3,6 @@ package containers
import (
"fmt"
"os"
- "text/tabwriter"
- "text/template"
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
@@ -117,12 +115,16 @@ func mount(_ *cobra.Command, args []string) error {
mrs = append(mrs, mountReporter{r})
}
- format := "{{range . }}{{.ID}}\t{{.Path}}\n{{end}}"
- tmpl, err := template.New("mounts").Parse(format)
+ format := "{{range . }}{{.ID}}\t{{.Path}}\n{{end -}}"
+ tmpl, err := report.NewTemplate("mounts").Parse(format)
+ if err != nil {
+ return err
+ }
+
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer w.Flush()
return tmpl.Execute(w, mrs)
}
diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go
index 352f67f4e..a5b0795cd 100644
--- a/cmd/podman/containers/ps.go
+++ b/cmd/podman/containers/ps.go
@@ -6,15 +6,12 @@ import (
"sort"
"strconv"
"strings"
- "text/tabwriter"
- "text/template"
"time"
tm "github.com/buger/goterm"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
- "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/cmd/podman/validate"
@@ -226,18 +223,20 @@ func ps(cmd *cobra.Command, _ []string) error {
hdrs, format := createPsOut()
if cmd.Flags().Changed("format") {
format = report.NormalizeFormat(listOpts.Format)
- format = parse.EnforceRange(format)
+ format = report.EnforceRange(format)
}
ns := strings.NewReplacer(".Namespaces.", ".")
format = ns.Replace(format)
- tmpl, err := template.New("listContainers").
- Funcs(template.FuncMap(report.DefaultFuncs)).
- Parse(format)
+ tmpl, err := report.NewTemplate("list").Parse(format)
+ if err != nil {
+ return err
+ }
+
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer w.Flush()
headers := func() error { return nil }
@@ -320,7 +319,7 @@ func createPsOut() ([]map[string]string, string) {
row += "\t{{.Size}}"
}
}
- return hdrs, "{{range .}}" + row + "\n{{end}}"
+ return hdrs, "{{range .}}" + row + "\n{{end -}}"
}
type psReporter struct {
diff --git a/cmd/podman/containers/stats.go b/cmd/podman/containers/stats.go
index 568e410d2..208d5d58f 100644
--- a/cmd/podman/containers/stats.go
+++ b/cmd/podman/containers/stats.go
@@ -3,13 +3,10 @@ package containers
import (
"fmt"
"os"
- "text/tabwriter"
- "text/template"
tm "github.com/buger/goterm"
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
- "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/libpod/define"
@@ -146,7 +143,9 @@ func stats(cmd *cobra.Command, args []string) error {
func outputStats(reports []define.ContainerStats) error {
headers := report.Headers(define.ContainerStats{}, map[string]string{
"ID": "ID",
+ "UpTime": "CPU TIME",
"CPUPerc": "CPU %",
+ "AVGCPU": "Avg CPU %",
"MemUsage": "MEM USAGE / LIMIT",
"MemUsageBytes": "MEM USAGE / LIMIT",
"MemPerc": "MEM %",
@@ -166,17 +165,21 @@ func outputStats(reports []define.ContainerStats) error {
if report.IsJSON(statsOptions.Format) {
return outputJSON(stats)
}
- format := "{{.ID}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDS}}\n"
+ format := "{{.ID}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDS}}\t{{.UpTime}}\t{{.AVGCPU}}\n"
if len(statsOptions.Format) > 0 {
format = report.NormalizeFormat(statsOptions.Format)
}
- format = parse.EnforceRange(format)
+ format = report.EnforceRange(format)
- tmpl, err := template.New("stats").Parse(format)
+ tmpl, err := report.NewTemplate("stats").Parse(format)
+ if err != nil {
+ return err
+ }
+
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer w.Flush()
if len(statsOptions.Format) < 1 {
@@ -202,6 +205,14 @@ func (s *containerStats) CPUPerc() string {
return floatToPercentString(s.CPU)
}
+func (s *containerStats) AVGCPU() string {
+ return floatToPercentString(s.AvgCPU)
+}
+
+func (s *containerStats) Up() string {
+ return (s.UpTime.String())
+}
+
func (s *containerStats) MemPerc() string {
return floatToPercentString(s.ContainerStats.MemPerc)
}
@@ -257,7 +268,9 @@ func outputJSON(stats []containerStats) error {
type jstat struct {
Id string `json:"id"` // nolint
Name string `json:"name"`
+ CPUTime string `json:"cpu_time"`
CpuPercent string `json:"cpu_percent"` // nolint
+ AverageCPU string `json:"avg_cpu"`
MemUsage string `json:"mem_usage"`
MemPerc string `json:"mem_percent"`
NetIO string `json:"net_io"`
@@ -269,7 +282,9 @@ func outputJSON(stats []containerStats) error {
jstats = append(jstats, jstat{
Id: j.ID(),
Name: j.Name,
+ CPUTime: j.Up(),
CpuPercent: j.CPUPerc(),
+ AverageCPU: j.AVGCPU(),
MemUsage: j.MemUsage(),
MemPerc: j.MemPerc(),
NetIO: j.NetIO(),
diff --git a/cmd/podman/containers/top.go b/cmd/podman/containers/top.go
index 3fde2e954..808c6c494 100644
--- a/cmd/podman/containers/top.go
+++ b/cmd/podman/containers/top.go
@@ -5,8 +5,8 @@ import (
"fmt"
"os"
"strings"
- "text/tabwriter"
+ "github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
@@ -77,7 +77,7 @@ func init() {
validate.AddLatestFlag(containerTopCommand, &topOptions.Latest)
}
-func top(cmd *cobra.Command, args []string) error {
+func top(_ *cobra.Command, args []string) error {
if topOptions.ListDescriptors {
descriptors, err := util.GetContainerPidInformationDescriptors()
if err != nil {
@@ -103,7 +103,11 @@ func top(cmd *cobra.Command, args []string) error {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)
+ w, err := report.NewWriterDefault(os.Stdout)
+ if err != nil {
+ return err
+ }
+
for _, proc := range topResponse.Value {
if _, err := fmt.Fprintln(w, proc); err != nil {
return err
diff --git a/cmd/podman/images/history.go b/cmd/podman/images/history.go
index 69268c261..c065acfad 100644
--- a/cmd/podman/images/history.go
+++ b/cmd/podman/images/history.go
@@ -5,14 +5,11 @@ import (
"fmt"
"os"
"strings"
- "text/tabwriter"
- "text/template"
"time"
"unicode"
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
- "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/docker/go-units"
@@ -125,13 +122,17 @@ func history(cmd *cobra.Command, args []string) error {
case opts.quiet:
row = "{{.ID}}\n"
}
- format := parse.EnforceRange(row)
+ format := report.EnforceRange(row)
- tmpl, err := template.New("report").Parse(format)
+ tmpl, err := report.NewTemplate("history").Parse(format)
+ if err != nil {
+ return err
+ }
+
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer w.Flush()
if !opts.quiet && !cmd.Flags().Changed("format") {
diff --git a/cmd/podman/images/list.go b/cmd/podman/images/list.go
index cc38a45c7..01286daf2 100644
--- a/cmd/podman/images/list.go
+++ b/cmd/podman/images/list.go
@@ -5,8 +5,6 @@ import (
"os"
"sort"
"strings"
- "text/tabwriter"
- "text/template"
"time"
"unicode"
@@ -14,7 +12,6 @@ import (
"github.com/containers/common/pkg/report"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/podman/v3/cmd/podman/common"
- "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/docker/go-units"
@@ -140,7 +137,7 @@ func images(cmd *cobra.Command, args []string) error {
case listFlag.quiet:
return writeID(imgs)
default:
- if cmd.Flags().Changed("format") && !parse.HasTable(listFlag.format) {
+ if cmd.Flags().Changed("format") && !report.HasTable(listFlag.format) {
listFlag.noHeading = true
}
return writeTemplate(imgs)
@@ -195,20 +192,23 @@ func writeTemplate(imgs []imageReporter) error {
"ReadOnly": "R/O",
})
- var row string
+ var format string
if listFlag.format == "" {
- row = lsFormatFromFlags(listFlag)
+ format = lsFormatFromFlags(listFlag)
} else {
- row = report.NormalizeFormat(listFlag.format)
+ format = report.NormalizeFormat(listFlag.format)
+ format = report.EnforceRange(format)
}
- format := parse.EnforceRange(row)
- tmpl, err := template.New("list").Parse(format)
+ tmpl, err := report.NewTemplate("list").Parse(format)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
+ w, err := report.NewWriterDefault(os.Stdout)
+ if err != nil {
+ return err
+ }
defer w.Flush()
if !listFlag.noHeading {
@@ -337,7 +337,7 @@ func lsFormatFromFlags(flags listFlagType) string {
row = append(row, "{{.ReadOnly}}")
}
- return strings.Join(row, "\t") + "\n"
+ return "{{range . }}" + strings.Join(row, "\t") + "\n{{end -}}"
}
type imageReporter struct {
diff --git a/cmd/podman/images/mount.go b/cmd/podman/images/mount.go
index efcff8264..89c00cb70 100644
--- a/cmd/podman/images/mount.go
+++ b/cmd/podman/images/mount.go
@@ -3,8 +3,6 @@ package images
import (
"fmt"
"os"
- "text/tabwriter"
- "text/template"
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
@@ -99,13 +97,18 @@ func mount(cmd *cobra.Command, args []string) error {
mrs = append(mrs, mountReporter{r})
}
- row := "{{range . }}{{.ID}}\t{{.Path}}\n{{end}}"
- tmpl, err := template.New("mounts").Parse(row)
+ row := "{{range . }}{{.ID}}\t{{.Path}}\n{{end -}}"
+ tmpl, err := report.NewTemplate("mounts").Parse(row)
+ if err != nil {
+ return err
+ }
+
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer w.Flush()
+
return tmpl.Execute(w, mrs)
}
diff --git a/cmd/podman/images/push.go b/cmd/podman/images/push.go
index edf8e9203..a13976612 100644
--- a/cmd/podman/images/push.go
+++ b/cmd/podman/images/push.go
@@ -96,7 +96,7 @@ func pushFlags(cmd *cobra.Command) {
_ = cmd.RegisterFlagCompletionFunc(digestfileFlagName, completion.AutocompleteDefault)
formatFlagName := "format"
- flags.StringVarP(&pushOptions.Format, formatFlagName, "f", "", "Manifest type (oci, v2s2, or v2s1) to use when pushing an image using the 'dir' transport (default is manifest type of source)")
+ flags.StringVarP(&pushOptions.Format, formatFlagName, "f", "", "Manifest type (oci, v2s2, or v2s1) to use in the destination (default is manifest type of source, with fallbacks)")
_ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteManifestFormat)
flags.BoolVarP(&pushOptions.Quiet, "quiet", "q", false, "Suppress output information when pushing images")
diff --git a/cmd/podman/images/search.go b/cmd/podman/images/search.go
index 08bf3cf6b..11e54578a 100644
--- a/cmd/podman/images/search.go
+++ b/cmd/podman/images/search.go
@@ -3,14 +3,11 @@ package images
import (
"fmt"
"os"
- "text/tabwriter"
- "text/template"
"github.com/containers/common/pkg/auth"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report"
"github.com/containers/image/v5/types"
- "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/pkg/errors"
@@ -156,18 +153,22 @@ func imageSearch(cmd *cobra.Command, args []string) error {
case report.IsJSON(searchOptions.Format):
return printArbitraryJSON(searchReport)
case cmd.Flags().Changed("format"):
- renderHeaders = parse.HasTable(searchOptions.Format)
+ renderHeaders = report.HasTable(searchOptions.Format)
row = report.NormalizeFormat(searchOptions.Format)
default:
row = "{{.Index}}\t{{.Name}}\t{{.Description}}\t{{.Stars}}\t{{.Official}}\t{{.Automated}}\n"
}
- format := parse.EnforceRange(row)
+ format := report.EnforceRange(row)
- tmpl, err := template.New("search").Parse(format)
+ tmpl, err := report.NewTemplate("search").Parse(format)
+ if err != nil {
+ return err
+ }
+
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer w.Flush()
if renderHeaders {
diff --git a/cmd/podman/images/trust_show.go b/cmd/podman/images/trust_show.go
index 5d9376068..c0e56f504 100644
--- a/cmd/podman/images/trust_show.go
+++ b/cmd/podman/images/trust_show.go
@@ -3,9 +3,8 @@ package images
import (
"fmt"
"os"
- "text/tabwriter"
- "text/template"
+ "github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/pkg/domain/entities"
@@ -45,16 +44,16 @@ func init() {
}
func showTrust(cmd *cobra.Command, args []string) error {
- report, err := registry.ImageEngine().ShowTrust(registry.Context(), args, showTrustOptions)
+ trust, err := registry.ImageEngine().ShowTrust(registry.Context(), args, showTrustOptions)
if err != nil {
return err
}
if showTrustOptions.Raw {
- fmt.Println(string(report.Raw))
+ fmt.Println(string(trust.Raw))
return nil
}
if showTrustOptions.JSON {
- b, err := json.MarshalIndent(report.Policies, "", " ")
+ b, err := json.MarshalIndent(trust.Policies, "", " ")
if err != nil {
return err
}
@@ -62,14 +61,18 @@ func showTrust(cmd *cobra.Command, args []string) error {
return nil
}
- row := "{{.RepoName}}\t{{.Type}}\t{{.GPGId}}\t{{.SignatureStore}}\n"
- format := "{{range . }}" + row + "{{end}}"
- tmpl, err := template.New("listContainers").Parse(format)
+ format := "{{range . }}{{.RepoName}}\t{{.Type}}\t{{.GPGId}}\t{{.SignatureStore}}\n{{end -}}"
+ tmpl, err := report.NewTemplate("list").Parse(format)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
- if err := tmpl.Execute(w, report.Policies); err != nil {
+
+ w, err := report.NewWriterDefault(os.Stdout)
+ if err != nil {
+ return err
+ }
+
+ if err := tmpl.Execute(w, trust.Policies); err != nil {
return err
}
if err := w.Flush(); err != nil {
diff --git a/cmd/podman/inspect/inspect.go b/cmd/podman/inspect/inspect.go
index 351684af1..bd3060882 100644
--- a/cmd/podman/inspect/inspect.go
+++ b/cmd/podman/inspect/inspect.go
@@ -7,7 +7,6 @@ import (
"os"
"regexp"
"strings"
- "text/tabwriter"
"text/template"
"github.com/containers/common/pkg/completion"
@@ -217,7 +216,7 @@ func (i *inspector) inspect(namesOrIDs []string) error {
err = printJSON(data)
default:
row := inspectNormalize(i.options.Format)
- row = "{{range . }}" + report.NormalizeFormat(row) + "{{end}}"
+ row = "{{range . }}" + report.NormalizeFormat(row) + "{{end -}}"
err = printTmpl(tmpType, row, data)
}
if err != nil {
@@ -250,7 +249,11 @@ func printTmpl(typ, row string, data []interface{}) error {
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
+
+ w, err := report.NewWriterDefault(os.Stdout)
+ if err != nil {
+ return err
+ }
return t.Execute(w, data)
}
diff --git a/cmd/podman/machine/list.go b/cmd/podman/machine/list.go
index 77b47161a..134a081ab 100644
--- a/cmd/podman/machine/list.go
+++ b/cmd/podman/machine/list.go
@@ -5,14 +5,11 @@ package machine
import (
"os"
"sort"
- "text/tabwriter"
- "text/template"
"time"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/report"
- "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/machine"
@@ -93,16 +90,20 @@ func outputTemplate(cmd *cobra.Command, responses []*machineReporter) error {
})
row := report.NormalizeFormat(listFlag.format)
- format := parse.EnforceRange(row)
+ format := report.EnforceRange(row)
- tmpl, err := template.New("list machines").Parse(format)
+ tmpl, err := report.NewTemplate("list").Parse(format)
+ if err != nil {
+ return err
+ }
+
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 12, 2, 2, ' ', 0)
defer w.Flush()
- if cmd.Flags().Changed("format") && !parse.HasTable(listFlag.format) {
+ if cmd.Flags().Changed("format") && !report.HasTable(listFlag.format) {
listFlag.noHeading = true
}
diff --git a/cmd/podman/networks/list.go b/cmd/podman/networks/list.go
index 46872d078..0ac637ea5 100644
--- a/cmd/podman/networks/list.go
+++ b/cmd/podman/networks/list.go
@@ -4,8 +4,6 @@ import (
"fmt"
"os"
"strings"
- "text/tabwriter"
- "text/template"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report"
@@ -133,11 +131,15 @@ func templateOut(responses []*entities.NetworkListReport, cmd *cobra.Command) er
}
format = report.EnforceRange(row)
- tmpl, err := template.New("listNetworks").Parse(format)
+ tmpl, err := report.NewTemplate("list").Parse(format)
+ if err != nil {
+ return err
+ }
+
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer w.Flush()
noHeading, _ := cmd.Flags().GetBool("noheading")
diff --git a/cmd/podman/parse/template.go b/cmd/podman/parse/template.go
deleted file mode 100644
index 0b80f1b3a..000000000
--- a/cmd/podman/parse/template.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package parse
-
-import (
- "regexp"
- "strings"
-)
-
-var rangeRegex = regexp.MustCompile(`{{\s*range\s*\.\s*}}.*{{\s*end\s*}}`)
-
-// TODO move to github.com/containers/common/pkg/report
-// EnforceRange ensures that the format string contains a range
-func EnforceRange(format string) string {
- if !rangeRegex.MatchString(format) {
- return "{{range .}}" + format + "{{end}}"
- }
- return format
-}
-
-// EnforceRange ensures that the format string contains a range
-func HasTable(format string) bool {
- return strings.HasPrefix(format, "table ")
-}
diff --git a/cmd/podman/parse/template_test.go b/cmd/podman/parse/template_test.go
deleted file mode 100644
index 7880d9bec..000000000
--- a/cmd/podman/parse/template_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package parse
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestEnforceRange(t *testing.T) {
- tests := []struct {
- input string
- expected string
- }{
- {"{{range .}}{{.ID}}{{end}}", "{{range .}}{{.ID}}{{end}}"},
- {"{{.ID}}", "{{range .}}{{.ID}}{{end}}"},
- {"{{ range . }}{{ .ID }}{{ end }}", "{{ range . }}{{ .ID }}{{ end }}"},
- // EnforceRange does not verify syntax or semantics, that will happen later
- {"{{range .}}{{.ID}}", "{{range .}}{{range .}}{{.ID}}{{end}}"},
- {".ID", "{{range .}}.ID{{end}}"},
- }
-
- for _, tc := range tests {
- tc := tc
- label := "TestEnforceRange_" + tc.input
- t.Run(label, func(t *testing.T) {
- t.Parallel()
- assert.Equal(t, tc.expected, EnforceRange(tc.input))
- })
- }
-}
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index 735dfa78c..03e3ffaa0 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -5,9 +5,13 @@ import (
"fmt"
"io/ioutil"
"os"
+ "runtime"
+ "sort"
+ "strconv"
"strings"
"github.com/containers/common/pkg/completion"
+ "github.com/containers/common/pkg/sysinfo"
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
@@ -16,6 +20,7 @@ import (
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
+ "github.com/docker/docker/pkg/parsers"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -55,6 +60,14 @@ func init() {
common.DefineNetFlags(createCommand)
+ cpusetflagName := "cpuset-cpus"
+ flags.StringVar(&createOptions.CpusetCpus, cpusetflagName, "", "CPUs in which to allow execution")
+ _ = createCommand.RegisterFlagCompletionFunc(cpusetflagName, completion.AutocompleteDefault)
+
+ cpusflagName := "cpus"
+ flags.Float64Var(&createOptions.Cpus, cpusflagName, 0.000, "set amount of CPUs for the pod")
+ _ = createCommand.RegisterFlagCompletionFunc(cpusflagName, completion.AutocompleteDefault)
+
cgroupParentflagName := "cgroup-parent"
flags.StringVar(&createOptions.CGroupParent, cgroupParentflagName, "", "Set parent cgroup for the pod")
_ = createCommand.RegisterFlagCompletionFunc(cgroupParentflagName, completion.AutocompleteDefault)
@@ -185,6 +198,46 @@ func create(cmd *cobra.Command, args []string) error {
}
}
+ numCPU := sysinfo.NumCPU()
+ if numCPU == 0 {
+ numCPU = runtime.NumCPU()
+ }
+ if createOptions.Cpus > float64(numCPU) {
+ createOptions.Cpus = float64(numCPU)
+ }
+ copy := createOptions.CpusetCpus
+ cpuSet := createOptions.Cpus
+ if cpuSet == 0 {
+ cpuSet = float64(sysinfo.NumCPU())
+ }
+ ret, err := parsers.ParseUintList(copy)
+ copy = ""
+ if err != nil {
+ errors.Wrapf(err, "could not parse list")
+ }
+ var vals []int
+ for ind, val := range ret {
+ if val {
+ vals = append(vals, ind)
+ }
+ }
+ sort.Ints(vals)
+ for ind, core := range vals {
+ if core > int(cpuSet) {
+ if copy == "" {
+ copy = "0-" + strconv.Itoa(int(cpuSet))
+ createOptions.CpusetCpus = copy
+ break
+ } else {
+ createOptions.CpusetCpus = copy
+ break
+ }
+ } else if ind != 0 {
+ copy += "," + strconv.Itoa(core)
+ } else {
+ copy = "" + strconv.Itoa(core)
+ }
+ }
response, err := registry.ContainerEngine().PodCreate(context.Background(), createOptions)
if err != nil {
return err
diff --git a/cmd/podman/pods/inspect.go b/cmd/podman/pods/inspect.go
index d38f0062c..4bb88f48a 100644
--- a/cmd/podman/pods/inspect.go
+++ b/cmd/podman/pods/inspect.go
@@ -3,8 +3,6 @@ package pods
import (
"context"
"os"
- "text/tabwriter"
- "text/template"
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
@@ -73,11 +71,14 @@ func inspect(cmd *cobra.Command, args []string) error {
row := report.NormalizeFormat(inspectOptions.Format)
- t, err := template.New("pod inspect").Parse(row)
+ t, err := report.NewTemplate("inspect").Parse(row)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
+ w, err := report.NewWriterDefault(os.Stdout)
+ if err != nil {
+ return err
+ }
return t.Execute(w, *responses)
}
diff --git a/cmd/podman/pods/ps.go b/cmd/podman/pods/ps.go
index 0271930e8..3e5ab86f4 100644
--- a/cmd/podman/pods/ps.go
+++ b/cmd/podman/pods/ps.go
@@ -6,14 +6,11 @@ import (
"os"
"sort"
"strings"
- "text/tabwriter"
- "text/template"
"time"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
- "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
@@ -131,20 +128,24 @@ func pods(cmd *cobra.Command, _ []string) error {
renderHeaders := true
row := podPsFormat()
if cmd.Flags().Changed("format") {
- renderHeaders = parse.HasTable(psInput.Format)
+ renderHeaders = report.HasTable(psInput.Format)
row = report.NormalizeFormat(psInput.Format)
}
noHeading, _ := cmd.Flags().GetBool("noheading")
if noHeading {
renderHeaders = false
}
- format := parse.EnforceRange(row)
+ format := report.EnforceRange(row)
- tmpl, err := template.New("listPods").Parse(format)
+ tmpl, err := report.NewTemplate("list").Parse(format)
+ if err != nil {
+ return err
+ }
+
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer w.Flush()
if renderHeaders {
diff --git a/cmd/podman/pods/stats.go b/cmd/podman/pods/stats.go
index 057b3dead..ba2c1495b 100644
--- a/cmd/podman/pods/stats.go
+++ b/cmd/podman/pods/stats.go
@@ -4,14 +4,11 @@ import (
"context"
"fmt"
"os"
- "text/tabwriter"
- "text/template"
"time"
"github.com/buger/goterm"
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
- "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
@@ -123,8 +120,12 @@ func printJSONPodStats(stats []*entities.PodStatsReport) error {
return nil
}
-func printPodStatsLines(stats []*entities.PodStatsReport) {
- w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
+func printPodStatsLines(stats []*entities.PodStatsReport) error {
+ w, err := report.NewWriterDefault(os.Stdout)
+ if err != nil {
+ return err
+ }
+
outFormat := "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n"
fmt.Fprintf(w, outFormat, "POD", "CID", "NAME", "CPU %", "MEM USAGE/ LIMIT", "MEM %", "NET IO", "BLOCK IO", "PIDS")
if len(stats) == 0 {
@@ -134,7 +135,7 @@ func printPodStatsLines(stats []*entities.PodStatsReport) {
fmt.Fprintf(w, outFormat, i.Pod, i.CID, i.Name, i.CPU, i.MemUsage, i.Mem, i.NetIO, i.BlockIO, i.PIDS)
}
}
- w.Flush()
+ return w.Flush()
}
func printFormattedPodStatsLines(headerNames []map[string]string, row string, stats []*entities.PodStatsReport) error {
@@ -142,13 +143,17 @@ func printFormattedPodStatsLines(headerNames []map[string]string, row string, st
return nil
}
- row = parse.EnforceRange(row)
+ row = report.EnforceRange(row)
+
+ tmpl, err := report.NewTemplate("stats").Parse(row)
+ if err != nil {
+ return err
+ }
- tmpl, err := template.New("pod stats").Parse(row)
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
defer w.Flush()
if err := tmpl.Execute(w, headerNames); err != nil {
diff --git a/cmd/podman/pods/top.go b/cmd/podman/pods/top.go
index e26e281c8..a6e442b96 100644
--- a/cmd/podman/pods/top.go
+++ b/cmd/podman/pods/top.go
@@ -5,8 +5,8 @@ import (
"fmt"
"os"
"strings"
- "text/tabwriter"
+ "github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
@@ -82,7 +82,11 @@ func top(_ *cobra.Command, args []string) error {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)
+ w, err := report.NewWriterDefault(os.Stdout)
+ if err != nil {
+ return err
+ }
+
for _, proc := range topResponse.Value {
if _, err := fmt.Fprintln(w, proc); err != nil {
return err
diff --git a/cmd/podman/secrets/inspect.go b/cmd/podman/secrets/inspect.go
index 874456f29..d0a5328d8 100644
--- a/cmd/podman/secrets/inspect.go
+++ b/cmd/podman/secrets/inspect.go
@@ -4,13 +4,10 @@ import (
"context"
"encoding/json"
"fmt"
- "html/template"
"os"
- "text/tabwriter"
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
- "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/pkg/errors"
@@ -52,13 +49,17 @@ func inspect(cmd *cobra.Command, args []string) error {
if cmd.Flags().Changed("format") {
row := report.NormalizeFormat(format)
- formatted := parse.EnforceRange(row)
+ formatted := report.EnforceRange(row)
- tmpl, err := template.New("inspect secret").Parse(formatted)
+ tmpl, err := report.NewTemplate("inspect").Parse(formatted)
+ if err != nil {
+ return err
+ }
+
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 12, 2, 2, ' ', 0)
defer w.Flush()
tmpl.Execute(w, inspected)
} else {
diff --git a/cmd/podman/secrets/list.go b/cmd/podman/secrets/list.go
index 448a69994..e64990c6f 100644
--- a/cmd/podman/secrets/list.go
+++ b/cmd/podman/secrets/list.go
@@ -2,15 +2,12 @@ package secrets
import (
"context"
- "html/template"
"os"
- "text/tabwriter"
"time"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
- "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
@@ -75,16 +72,20 @@ func outputTemplate(cmd *cobra.Command, responses []*entities.SecretListReport)
})
row := report.NormalizeFormat(listFlag.format)
- format := parse.EnforceRange(row)
+ format := report.EnforceRange(row)
- tmpl, err := template.New("list secret").Parse(format)
+ tmpl, err := report.NewTemplate("list").Parse(format)
+ if err != nil {
+ return err
+ }
+
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 12, 2, 2, ' ', 0)
defer w.Flush()
- if cmd.Flags().Changed("format") && !parse.HasTable(listFlag.format) {
+ if cmd.Flags().Changed("format") && !report.HasTable(listFlag.format) {
listFlag.noHeading = true
}
diff --git a/cmd/podman/system/connection/list.go b/cmd/podman/system/connection/list.go
index ae88b0b30..2f74215c1 100644
--- a/cmd/podman/system/connection/list.go
+++ b/cmd/podman/system/connection/list.go
@@ -1,12 +1,13 @@
package connection
import (
+ "fmt"
"os"
- "text/tabwriter"
- "text/template"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/report"
+ "github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/system"
"github.com/containers/podman/v3/cmd/podman/validate"
@@ -15,13 +16,14 @@ import (
var (
listCmd = &cobra.Command{
- Use: "list",
+ Use: "list [options]",
Aliases: []string{"ls"},
Args: validate.NoArgs,
Short: "List destination for the Podman service(s)",
Long: `List destination information for the Podman service(s) in podman configuration`,
Example: `podman system connection list
- podman system connection ls`,
+ podman system connection ls
+ podman system connection ls --format=json`,
ValidArgsFunction: completion.AutocompleteNone,
RunE: list,
TraverseChildren: false,
@@ -33,6 +35,9 @@ func init() {
Command: listCmd,
Parent: system.ConnectionCmd,
})
+
+ listCmd.Flags().String("format", "", "Custom Go template for printing connections")
+ _ = listCmd.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(namedDestination{}))
}
type namedDestination struct {
@@ -40,7 +45,7 @@ type namedDestination struct {
config.Destination
}
-func list(_ *cobra.Command, _ []string) error {
+func list(cmd *cobra.Command, _ []string) error {
cfg, err := config.ReadCustomConfig()
if err != nil {
return err
@@ -72,16 +77,36 @@ func list(_ *cobra.Command, _ []string) error {
rows = append(rows, r)
}
- // TODO: Allow user to override format
- format := "{{range . }}{{.Name}}\t{{.Identity}}\t{{.URI}}\n{{end}}"
- tmpl, err := template.New("connection").Parse(format)
+ format := "{{.Name}}\t{{.Identity}}\t{{.URI}}\n"
+ switch {
+ case report.IsJSON(cmd.Flag("format").Value.String()):
+ buf, err := registry.JSONLibrary().MarshalIndent(rows, "", " ")
+ if err == nil {
+ fmt.Println(string(buf))
+ }
+ return err
+ default:
+ if cmd.Flag("format").Changed {
+ format = cmd.Flag("format").Value.String()
+ format = report.NormalizeFormat(format)
+ }
+ }
+ format = report.EnforceRange(format)
+
+ tmpl, err := report.NewTemplate("list").Parse(format)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
+ w, err := report.NewWriterDefault(os.Stdout)
+ if err != nil {
+ return err
+ }
defer w.Flush()
- _ = tmpl.Execute(w, hdrs)
+ isTable := report.HasTable(cmd.Flag("format").Value.String())
+ if !cmd.Flag("format").Changed || isTable {
+ _ = tmpl.Execute(w, hdrs)
+ }
return tmpl.Execute(w, rows)
}
diff --git a/cmd/podman/system/df.go b/cmd/podman/system/df.go
index de56c57d0..dfde3bc07 100644
--- a/cmd/podman/system/df.go
+++ b/cmd/podman/system/df.go
@@ -4,13 +4,10 @@ import (
"fmt"
"os"
"strings"
- "text/tabwriter"
- "text/template"
"time"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report"
- "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
@@ -57,7 +54,10 @@ func df(cmd *cobra.Command, args []string) error {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
+ w, err := report.NewWriterDefault(os.Stdout)
+ if err != nil {
+ return err
+ }
if dfOptions.Verbose {
return printVerbose(w, cmd, reports)
@@ -65,7 +65,7 @@ func df(cmd *cobra.Command, args []string) error {
return printSummary(w, cmd, reports)
}
-func printSummary(w *tabwriter.Writer, cmd *cobra.Command, reports *entities.SystemDfReport) error {
+func printSummary(w *report.Writer, cmd *cobra.Command, reports *entities.SystemDfReport) error {
var (
dfSummaries []*dfSummary
active int
@@ -143,7 +143,7 @@ func printSummary(w *tabwriter.Writer, cmd *cobra.Command, reports *entities.Sys
return writeTemplate(w, cmd, hdrs, row, dfSummaries)
}
-func printVerbose(w *tabwriter.Writer, cmd *cobra.Command, reports *entities.SystemDfReport) error {
+func printVerbose(w *report.Writer, cmd *cobra.Command, reports *entities.SystemDfReport) error {
defer w.Flush()
fmt.Fprint(w, "Images space usage:\n\n")
@@ -191,11 +191,11 @@ func printVerbose(w *tabwriter.Writer, cmd *cobra.Command, reports *entities.Sys
return writeTemplate(w, cmd, hdrs, volumeRow, dfVolumes)
}
-func writeTemplate(w *tabwriter.Writer, cmd *cobra.Command, hdrs []map[string]string, format string, output interface{}) error {
+func writeTemplate(w *report.Writer, cmd *cobra.Command, hdrs []map[string]string, format string, output interface{}) error {
defer w.Flush()
- format = parse.EnforceRange(format)
- tmpl, err := template.New("df").Parse(format)
+ format = report.EnforceRange(format)
+ tmpl, err := report.NewTemplate("df").Parse(format)
if err != nil {
return err
}
diff --git a/cmd/podman/system/events.go b/cmd/podman/system/events.go
index 4aa413ec6..677504cfc 100644
--- a/cmd/podman/system/events.go
+++ b/cmd/podman/system/events.go
@@ -4,7 +4,6 @@ import (
"context"
"fmt"
"os"
- "text/template"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report"
@@ -75,7 +74,7 @@ func eventsCmd(cmd *cobra.Command, _ []string) error {
errChannel := make(chan error)
var (
- tmpl *template.Template
+ tmpl *report.Template
doJSON bool
)
@@ -83,7 +82,7 @@ func eventsCmd(cmd *cobra.Command, _ []string) error {
doJSON = report.IsJSON(eventFormat)
if !doJSON {
var err error
- tmpl, err = template.New("events").Parse(eventFormat)
+ tmpl, err = report.NewTemplate("events").Parse(eventFormat)
if err != nil {
return err
}
diff --git a/cmd/podman/system/info.go b/cmd/podman/system/info.go
index 1dc90f79a..c3f543e6a 100644
--- a/cmd/podman/system/info.go
+++ b/cmd/podman/system/info.go
@@ -3,7 +3,6 @@ package system
import (
"fmt"
"os"
- "text/template"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report"
@@ -85,7 +84,7 @@ func info(cmd *cobra.Command, args []string) error {
}
fmt.Println(string(b))
case cmd.Flags().Changed("format"):
- tmpl, err := template.New("info").Parse(inFormat)
+ tmpl, err := report.NewTemplate("info").Parse(inFormat)
if err != nil {
return err
}
diff --git a/cmd/podman/system/version.go b/cmd/podman/system/version.go
index 5575fc87d..4502b156c 100644
--- a/cmd/podman/system/version.go
+++ b/cmd/podman/system/version.go
@@ -5,8 +5,6 @@ import (
"io"
"os"
"strings"
- "text/tabwriter"
- "text/template"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report"
@@ -55,19 +53,22 @@ func version(cmd *cobra.Command, args []string) error {
return nil
}
- w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
+ w, err := report.NewWriterDefault(os.Stdout)
+ if err != nil {
+ return err
+ }
defer w.Flush()
if cmd.Flag("format").Changed {
row := report.NormalizeFormat(versionFormat)
- tmpl, err := template.New("version 2.0.0").Parse(row)
+ tmpl, err := report.NewTemplate("version 2.0.0").Parse(row)
if err != nil {
return err
}
if err := tmpl.Execute(w, versions); err != nil {
// On Failure, assume user is using older version of podman version --format and check client
row = strings.Replace(row, ".Server.", ".", 1)
- tmpl, err := template.New("version 1.0.0").Parse(row)
+ tmpl, err := report.NewTemplate("version 1.0.0").Parse(row)
if err != nil {
return err
}
diff --git a/cmd/podman/volumes/list.go b/cmd/podman/volumes/list.go
index 990b39435..0243054af 100644
--- a/cmd/podman/volumes/list.go
+++ b/cmd/podman/volumes/list.go
@@ -5,13 +5,10 @@ import (
"fmt"
"os"
"strings"
- "text/tabwriter"
- "text/template"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v3/cmd/podman/common"
- "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/libpod/define"
@@ -104,13 +101,17 @@ func outputTemplate(cmd *cobra.Command, responses []*entities.VolumeListReport)
if cliOpts.Quiet {
row = "{{.Name}}\n"
}
- format := parse.EnforceRange(row)
+ format := report.EnforceRange(row)
- tmpl, err := template.New("list volume").Parse(format)
+ tmpl, err := report.NewTemplate("list").Parse(format)
+ if err != nil {
+ return err
+ }
+
+ w, err := report.NewWriterDefault(os.Stdout)
if err != nil {
return err
}
- w := tabwriter.NewWriter(os.Stdout, 12, 2, 2, ' ', 0)
defer w.Flush()
if !(noHeading || cliOpts.Quiet || cmd.Flag("format").Changed) {
diff --git a/contrib/podmanimage/stable/Dockerfile b/contrib/podmanimage/stable/Dockerfile
index 696268c85..2f86dd4ae 100644
--- a/contrib/podmanimage/stable/Dockerfile
+++ b/contrib/podmanimage/stable/Dockerfile
@@ -21,6 +21,7 @@ echo podman:10000:5000 > /etc/subgid;
VOLUME /var/lib/containers
VOLUME /home/podman/.local/share/containers
+RUN mkdir -p /home/podman/.local/share/containers
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/podman-containers.conf /home/podman/.config/containers/containers.conf
diff --git a/contrib/podmanimage/testing/Dockerfile b/contrib/podmanimage/testing/Dockerfile
index c20b26ac4..63b31252f 100644
--- a/contrib/podmanimage/testing/Dockerfile
+++ b/contrib/podmanimage/testing/Dockerfile
@@ -21,6 +21,7 @@ echo podman:10000:5000 > /etc/subgid;
VOLUME /var/lib/containers
VOLUME /home/podman/.local/share/containers
+RUN mkdir -p /home/podman/.local/share/containers
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/podman-containers.conf /home/podman/.config/containers/containers.conf
diff --git a/contrib/podmanimage/upstream/Dockerfile b/contrib/podmanimage/upstream/Dockerfile
index 1277f9ba8..922eee748 100644
--- a/contrib/podmanimage/upstream/Dockerfile
+++ b/contrib/podmanimage/upstream/Dockerfile
@@ -69,6 +69,7 @@ echo podman:10000:5000 > /etc/subgid;
VOLUME /var/lib/containers
VOLUME /home/podman/.local/share/containers
+RUN mkdir -p /home/podman/.local/share/containers
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/podman-containers.conf /home/podman/.config/containers/containers.conf
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index 6146a2c0e..ef8523f8c 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -531,10 +531,12 @@ export GOPATH=%{buildroot}/%{gopath}:$(pwd)/vendor:%{gopath}
%{_unitdir}/podman-auto-update.timer
%{_unitdir}/podman.service
%{_unitdir}/podman.socket
+%{_unitdir}/podman-restart.service
%{_usr}/lib/systemd/user/podman.service
%{_usr}/lib/systemd/user/podman.socket
%{_usr}/lib/systemd/user/podman-auto-update.service
%{_usr}/lib/systemd/user/podman-auto-update.timer
+%{_usr}/lib/systemd/user/podman-restart.service
%{_usr}/lib/tmpfiles.d/podman.conf
%if 0%{?with_devel}
diff --git a/contrib/systemd/system/podman-restart.service b/contrib/systemd/system/podman-restart.service
new file mode 100644
index 000000000..baf12b3ae
--- /dev/null
+++ b/contrib/systemd/system/podman-restart.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Podman Start All Containers With Restart Policy Set To Always
+Documentation=man:podman-start(1)
+StartLimitIntervalSec=0
+
+[Service]
+Type=oneshot
+Environment=LOGGING="--log-level=info"
+ExecStart=/usr/bin/podman $LOGGING start --all --filter restart-policy=always
+
+[Install]
+WantedBy=multi-user.target
diff --git a/contrib/systemd/system/podman.service b/contrib/systemd/system/podman.service
index 7e5195e7a..cefb13ae3 100644
--- a/contrib/systemd/system/podman.service
+++ b/contrib/systemd/system/podman.service
@@ -10,3 +10,6 @@ Type=exec
KillMode=process
Environment=LOGGING="--log-level=info"
ExecStart=/usr/bin/podman $LOGGING system service
+
+[Install]
+WantedBy=multi-user.target
diff --git a/contrib/tmpfile/podman.conf b/contrib/tmpfile/podman.conf
index 650678a21..bd7dec5ce 100644
--- a/contrib/tmpfile/podman.conf
+++ b/contrib/tmpfile/podman.conf
@@ -2,5 +2,6 @@
# for many days. This following line prevents systemd from removing this content.
x /tmp/podman-run-*
x /tmp/containers-user-*
+x /tmp/run-*/libpod
D! /run/podman 0700 root root
D! /var/lib/cni/networks
diff --git a/docs/source/markdown/podman-image-unmount.1.md b/docs/source/markdown/podman-image-unmount.1.md
index 62e879fa1..2fedb8f58 100644
--- a/docs/source/markdown/podman-image-unmount.1.md
+++ b/docs/source/markdown/podman-image-unmount.1.md
@@ -12,7 +12,7 @@ podman\-image\-unmount - Unmount an image's root filesystem
Unmounts the specified images' root file system, if no other processes
are using it.
-Image storage increments a mount counter each time a image is mounted.
+Image storage increments a mount counter each time an image is mounted.
When a image is unmounted, the mount counter is decremented, and the
image's root filesystem is physically unmounted only when the mount
counter reaches zero indicating no other processes are using the mount.
diff --git a/docs/source/markdown/podman-image.1.md b/docs/source/markdown/podman-image.1.md
index bbf5f6d84..1b0dc395d 100644
--- a/docs/source/markdown/podman-image.1.md
+++ b/docs/source/markdown/podman-image.1.md
@@ -18,7 +18,7 @@ The image command allows you to manage images
| exists | [podman-image-exists(1)](podman-image-exists.1.md) | Check if an image exists in local storage. |
| history | [podman-history(1)](podman-history.1.md) | Show the history of an image. |
| import | [podman-import(1)](podman-import.1.md) | Import a tarball and save it as a filesystem image. |
-| inspect | [podman-inspect(1)](podman-inspect.1.md) | Display a image or image's configuration. |
+| inspect | [podman-inspect(1)](podman-inspect.1.md) | Display an image or image's configuration. |
| list | [podman-images(1)](podman-images.1.md) | List the container images on the system.(alias ls) |
| load | [podman-load(1)](podman-load.1.md) | Load an image from the docker archive. |
| mount | [podman-image-mount(1)](podman-image-mount.1.md) | Mount an image's root filesystem. |
diff --git a/docs/source/markdown/podman-login.1.md b/docs/source/markdown/podman-login.1.md
index 88d025c70..3e23600fa 100644
--- a/docs/source/markdown/podman-login.1.md
+++ b/docs/source/markdown/podman-login.1.md
@@ -28,18 +28,6 @@ For more details about format and configurations of the auth.json file, please r
## OPTIONS
-#### **--password**, **-p**=*password*
-
-Password for registry
-
-#### **--password-stdin**
-
-Take the password from stdin
-
-#### **--username**, **-u**=*username*
-
-Username for registry
-
#### **--authfile**=*path*
Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
@@ -47,14 +35,26 @@ Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth
Note: You can also override the default path of the authentication file by setting the REGISTRY\_AUTH\_FILE
environment variable. `export REGISTRY_AUTH_FILE=path`
+#### **--cert-dir**=*path*
+
+Use certificates at *path* (\*.crt, \*.cert, \*.key) to connect to the registry.
+Please refer to containers-certs.d(5) for details. (This option is not available with the remote Podman client)
+
#### **--get-login**
Return the logged-in user for the registry. Return error if no login is found.
-#### **--cert-dir**=*path*
+#### **--help**, **-h**
-Use certificates at *path* (\*.crt, \*.cert, \*.key) to connect to the registry.
-Please refer to containers-certs.d(5) for details. (This option is not available with the remote Podman client)
+Print usage statement
+
+#### **--password**, **-p**=*password*
+
+Password for registry
+
+#### **--password-stdin**
+
+Take the password from stdin
#### **--tls-verify**=*true|false*
@@ -62,9 +62,13 @@ Require HTTPS and verify certificates when contacting registries (default: true)
then TLS verification will be used. If set to false, then TLS verification will not be used. If not specified,
TLS verification will be used unless the target registry is listed as an insecure registry in registries.conf.
-#### **--help**, **-h**
+#### **--username**, **-u**=*username*
-Print usage statement
+Username for registry
+
+#### **--verbose**, **-v**
+
+print detailed information about credential store
## EXAMPLES
@@ -107,6 +111,14 @@ $ echo $testpassword | podman login -u testuser --password-stdin docker.io
Login Succeeded!
```
+```
+$ podman login quay.io --verbose
+Username: myusername
+Password:
+Used: /run/user/1000/containers/auth.json
+Login Succeeded!
+```
+
## SEE ALSO
podman(1), podman-logout(1), containers-auth.json(5), containers-certs.d(5), containers-registries.conf(5)
diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md
index 4b890a7af..653b0f6f1 100644
--- a/docs/source/markdown/podman-pod-create.1.md
+++ b/docs/source/markdown/podman-pod-create.1.md
@@ -23,6 +23,22 @@ Add a host to the /etc/hosts file shared between all containers in the pod.
Path to cgroups under which the cgroup for the pod will be created. If the path is not absolute, the path is considered to be relative to the cgroups path of the init process. Cgroups will be created if they do not already exist.
+#### **--cpus**=*amount*
+
+Set the total number of CPUs delegated to the pod. Default is 0.000 which indicates that there is no limit on computation power.
+
+#### **--cpuset-cpus**=*amount*
+
+Limit the CPUs to support execution. First CPU is numbered 0. Unlike --cpus this is of type string and parsed as a list of numbers
+
+Format is 0-3,0,1
+
+Examples of the List Format:
+
+0-4,9 # bits 0, 1, 2, 3, 4, and 9 set
+0-2,7,12-14 # bits 0, 1, 2, 7, 12, 13, and 14 set
+
+
#### **--dns**=*ipaddr*
Set custom DNS servers in the /etc/resolv.conf file that will be shared between all containers in the pod. A special option, "none" is allowed which disables creation of /etc/resolv.conf for the pod.
diff --git a/docs/source/markdown/podman-pull.1.md b/docs/source/markdown/podman-pull.1.md
index 54f990601..084327efd 100644
--- a/docs/source/markdown/podman-pull.1.md
+++ b/docs/source/markdown/podman-pull.1.md
@@ -21,42 +21,30 @@ Images are stored in local image storage.
## SOURCE
- The SOURCE is the location from which the container images are pulled.
- The Image "SOURCE" uses a "transport":"details" format. Only the `docker` (container registry)
- transport is allowed for remote access.
+ SOURCE is the location from the container image is pulled from. It supports all transports from `containers-transports(5)`. If no transport is specified, the input is subject to short-name resolution and the `docker` (i.e., container registry) transport is used. For remote clients, `docker` is the only supported transport.
- Multiple transports are supported:
-
- **dir:**_path_
- An existing local directory _path_ storing the manifest, layer tarballs and signatures as individual files. This
- is a non-standardized format, primarily useful for debugging or noninvasive container inspection.
-
- $ podman pull dir:/tmp/myimage
-
- **docker://**_docker-reference_ (Default)
- An image reference stored in a remote container image registry. The reference can include a path to a
- specific registry; if it does not, the registries listed in registries.conf will be queried to find a matching
- image. By default, credentials from podman login (stored at $XDG_RUNTIME_DIR/containers/auth.json by default)
- will be used to authenticate; if these cannot be found, we will fall back to using credentials in
- $HOME/.docker/config.json.
-
- $ podman pull quay.io/username/myimage
+```
+# Pull from a container registry
+$ podman pull quay.io/username/myimage
- **docker-archive:**_path_[**:**_docker-reference_]
- An image is stored in the `docker save` formatted file. _docker-reference_ is only used when creating such a
- file, and it must not contain a digest.
+# Pull from a container registry with short-name resolution
+$ podman pull fedora
- $ podman pull docker-archive:/tmp/myimage
+# Pull from a container registry via the docker transport
+$ podman pull docker://quay.io/username/myimage
- **docker-daemon:**_docker-reference_
- An image in _docker-reference_ format stored in the docker daemon internal storage. The _docker-reference_ can also be an image ID (docker-daemon:algo:digest).
+# Pull from a local directory
+$ podman pull dir:/tmp/myimage
- $ sudo podman pull docker-daemon:docker.io/library/myimage:33
+# Pull from a tarball in the docker-archive format
+$ podman pull docker-archive:/tmp/myimage
- **oci-archive:**_path_**:**_tag_
- An image _tag_ in a directory compliant with "Open Container Image Layout Specification" at _path_.
+# Pull from a local docker daemon
+$ sudo podman pull docker-daemon:docker.io/library/myimage:33
- $ podman pull oci-archive:/tmp/myimage
+# Pull from a tarball in the OCI-archive format
+$ podman pull oci-archive:/tmp/myimage
+```
## OPTIONS
@@ -217,7 +205,7 @@ registries.conf is the configuration file which specifies which container regist
NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`.
## SEE ALSO
-podman(1), podman-push(1), podman-login(1), containers-certs.d(5), containers-registries.conf(5)
+podman(1), podman-push(1), podman-login(1), containers-certs.d(5), containers-registries.conf(5), containers-transports(5)
## HISTORY
July 2017, Originally compiled by Urvashi Mohnani <umohnani@redhat.com>
diff --git a/docs/source/markdown/podman-push.1.md b/docs/source/markdown/podman-push.1.md
index e26d73891..68478accd 100644
--- a/docs/source/markdown/podman-push.1.md
+++ b/docs/source/markdown/podman-push.1.md
@@ -20,37 +20,30 @@ Images are pushed from those stored in local image storage.
## DESTINATION
- The DESTINATION is a location to store container images
- The Image "DESTINATION" uses a "transport":"details" format.
- If a transport is not given, podman push will attempt to push
- to a registry.
+ DESTINATION is the location the container image is pushed to. It supports all transports from `containers-transports(5)`. If no transport is specified, the `docker` (i.e., container registry) transport is used. For remote clients, `docker` is the only supported transport.
- Multiple transports are supported:
-
- **dir:**_path_
- An existing local directory _path_ storing the manifest, layer tarballs and signatures as individual files. This is a non-standardized format, primarily useful for debugging or noninvasive container inspection.
-
- $ podman push myimage dir:/tmp/myimage
-
- **docker://**_docker-reference_
- An image in a registry implementing the "Docker Registry HTTP API V2". By default, uses the authorization state in `$XDG_RUNTIME_DIR/containers/auth.json`, which is set using `(podman login)`. If the authorization state is not found there, `$HOME/.docker/config.json` is checked, which is set using `(docker login)`.
-
- $ podman push myimage quay.io/username/myimage
+```
+# Push to a container registry
+$ podman push quay.io/podman/stable
- **docker-archive:**_path_[**:**_docker-reference_]
- An image is stored in the `docker save` formatted file. _docker-reference_ is only used when creating such a file, and it must not contain a digest.
+# Push to a container registry via the docker transport
+$ podman push docker://quay.io/podman/stable
- $ podman push myimage docker-archive:/tmp/myimage
+# Push to a container registry with another tag
+$ podman push myimage quay.io/username/myimage
- **docker-daemon:**_docker-reference_
- An image in _docker-reference_ format stored in the docker daemon internal storage. _docker-reference_ must contain a tag.
+# Push to a local directory
+$ podman push myimage dir:/tmp/myimage
- $ sudo podman push myimage docker-daemon:docker.io/library/myimage:33
+# Push to a tarball in the docker-archive format
+$ podman push myimage docker-archive:/tmp/myimage
- **oci-archive:**_path_**:**_tag_
- An image _tag_ in a directory compliant with "Open Container Image Layout Specification" at _path_.
+# Push to a local docker daemon
+$ sudo podman push myimage docker-daemon:docker.io/library/myimage:33
- $ podman push myimage oci-archive:/tmp/myimage
+# Push to a tarball in the OCI format
+$ podman push myimage oci-archive:/tmp/myimage
+```
## OPTIONS
@@ -161,4 +154,4 @@ Storing signatures
```
## SEE ALSO
-podman(1), podman-pull(1), podman-login(1), containers-certs.d(5)
+podman(1), podman-pull(1), podman-login(1), containers-certs.d(5), containers-transports(5)
diff --git a/docs/source/markdown/podman-rmi.1.md b/docs/source/markdown/podman-rmi.1.md
index 765c1bd6d..1f62d6133 100644
--- a/docs/source/markdown/podman-rmi.1.md
+++ b/docs/source/markdown/podman-rmi.1.md
@@ -10,6 +10,7 @@ podman\-rmi - Removes one or more locally stored images
## DESCRIPTION
Removes one or more locally stored images.
+Passing an argument _image_ deletes it, along with any of its dangling (untagged) parent images.
## OPTIONS
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 46e15d62f..6027a14a5 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -281,12 +281,10 @@ it in the **containers.conf** file: see **containers.conf(5)** for more informat
#### **--detach-keys**=*sequence*
-Specify the key sequence for detaching a container. Format is a single character `[a-Z]` or one or more `ctrl-<value>` characters where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`. Specifying "" will disable this feature. The default is *ctrl-p,ctrl-q*.
+Specify the key sequence for detaching a container. Format is a single character `[a-Z]` or one or more `ctrl-<value>` characters where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`. Specifying "" will set the sequence to the default value of *ctrl-p,ctrl-q*.
This option can also be set in **containers.conf**(5) file.
-Specifying "" will disable this feature. The default is **ctrl-p,ctrl-q**.
-
#### **--device**=_host-device_[**:**_container-device_][**:**_permissions_]
Add a host device to the container. Optional *permissions* parameter
diff --git a/docs/source/markdown/podman-system-connection-list.1.md b/docs/source/markdown/podman-system-connection-list.1.md
index f5fb5c8e3..6b25a045d 100644
--- a/docs/source/markdown/podman-system-connection-list.1.md
+++ b/docs/source/markdown/podman-system-connection-list.1.md
@@ -4,13 +4,28 @@
podman\-system\-connection\-list - List the destination for the Podman service(s)
## SYNOPSIS
-**podman system connection list**
+**podman system connection list** [*options*]
-**podman system connection ls**
+**podman system connection ls** [*options*]
## DESCRIPTION
List ssh destination(s) for podman service(s).
+## OPTIONS
+
+#### **--format**=*format*
+
+Change the default output format. This can be of a supported type like 'json' or a Go template.
+Valid placeholders for the Go template listed below:
+
+| **Placeholder** | **Description** |
+| --------------- | ----------------------------------------------------------------------------- |
+| *.Name* | Connection Name/Identifier |
+| *.Identity* | Path to file containing SSH identity |
+| *.URI* | URI to podman service. Valid schemes are ssh://[user@]*host*[:port]*Unix domain socket*[?secure=True], unix://*Unix domain socket*, and tcp://localhost[:*port*] |
+
+An asterisk is appended to the default connection.
+
## EXAMPLE
```
$ podman system connection list
diff --git a/go.mod b/go.mod
index 40464b8fb..e8ebb88fe 100644
--- a/go.mod
+++ b/go.mod
@@ -12,15 +12,15 @@ require (
github.com/containernetworking/cni v0.8.1
github.com/containernetworking/plugins v0.9.1
github.com/containers/buildah v1.21.1
- github.com/containers/common v0.39.1-0.20210527140106-e5800a20386a
+ github.com/containers/common v0.40.2-0.20210623133759-d13a31743aec
github.com/containers/conmon v2.0.20+incompatible
- github.com/containers/image/v5 v5.12.0
+ github.com/containers/image/v5 v5.13.2
github.com/containers/ocicrypt v1.1.1
github.com/containers/psgo v1.5.2
- github.com/containers/storage v1.32.2
+ github.com/containers/storage v1.32.3
github.com/coreos/go-systemd/v22 v22.3.2
github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3
- github.com/cri-o/ocicni v0.2.1-0.20210301205850-541cf7c703cf
+ github.com/cri-o/ocicni v0.2.1-0.20210621164014-d0acc7862283
github.com/cyphar/filepath-securejoin v0.2.2
github.com/davecgh/go-spew v1.1.1
github.com/digitalocean/go-qemu v0.0.0-20210209191958-152a1535e49f
@@ -64,8 +64,8 @@ require (
go.etcd.io/bbolt v1.3.6
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
- golang.org/x/sys v0.0.0-20210514084401-e8d321eab015
+ golang.org/x/sys v0.0.0-20210603125802-9665404d3644
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
- k8s.io/api v0.21.1
- k8s.io/apimachinery v0.21.1
+ k8s.io/api v0.21.2
+ k8s.io/apimachinery v0.21.2
)
diff --git a/go.sum b/go.sum
index 73b4af472..e2a83a95f 100644
--- a/go.sum
+++ b/go.sum
@@ -221,12 +221,13 @@ github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRD
github.com/containers/buildah v1.21.1 h1:e9LmTCUKUBLg72v5DnIOT/wc8ffkfB7LbpQBywLZo20=
github.com/containers/buildah v1.21.1/go.mod h1:yPdlpVd93T+i91yGxrJbW1YOWrqN64j5ZhHOZmHUejs=
github.com/containers/common v0.38.4/go.mod h1:egfpX/Y3+19Dz4Wa1eRZDdgzoEOeneieF9CQppKzLBg=
-github.com/containers/common v0.39.1-0.20210527140106-e5800a20386a h1:XzYOUf7qjgVJ59YGqAzehlbT63EgjUJhMnfhsPSSJV0=
-github.com/containers/common v0.39.1-0.20210527140106-e5800a20386a/go.mod h1:CxHAf4iQOZZ8nASIjMdYHHRyA8dMR4tINSS7WQWlv90=
+github.com/containers/common v0.40.2-0.20210623133759-d13a31743aec h1:ZcteA2klZSZAZgVonwJAqezF6hdO9SMKUy49ZHXZd38=
+github.com/containers/common v0.40.2-0.20210623133759-d13a31743aec/go.mod h1:J23CfuhN1fAg85q5HxS6SKYhKbGqmqieKQqoHaQbEI8=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
-github.com/containers/image/v5 v5.12.0 h1:1hNS2QkzFQ4lH3GYQLyAXB0acRMhS1Ubm6oV++8vw4w=
github.com/containers/image/v5 v5.12.0/go.mod h1:VasTuHmOw+uD0oHCfApQcMO2+36SfyncoSahU7513Xs=
+github.com/containers/image/v5 v5.13.2 h1:AgYunV/9d2fRkrmo23wH2MkqeHolFd6oQCkK+1PpuFA=
+github.com/containers/image/v5 v5.13.2/go.mod h1:GkWursKDlDcUIT7L7vZf70tADvZCk/Ga0wgS0MuF0ag=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
@@ -238,9 +239,9 @@ github.com/containers/psgo v1.5.2/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzP
github.com/containers/storage v1.23.5/go.mod h1:ha26Q6ngehFNhf3AWoXldvAvwI4jFe3ETQAf/CeZPyM=
github.com/containers/storage v1.30.1/go.mod h1:NDJkiwxnSHD1Is+4DGcyR3SIEYSDOa0xnAW+uGQFx9E=
github.com/containers/storage v1.31.1/go.mod h1:IFEf+yRTS0pvCGQt2tBv1Kzz2XUSPvED6uFBmWG7V/E=
-github.com/containers/storage v1.32.0/go.mod h1:J3q772EVbN9vgqoN/dkvInKnp4xK9ZXm7wHNfuiIDgE=
-github.com/containers/storage v1.32.2 h1:V1oKAKmH5e6OTgP7Uf8+T+ntVVYk2MNFnDDkPBI9kxU=
github.com/containers/storage v1.32.2/go.mod h1:YIBxxjfXZTi04Ah49sh1uSGfmT1V89+I5i3deRobzQo=
+github.com/containers/storage v1.32.3 h1:e/e8kUKrYCFpc6FFcItNCwWrZfj2YuyVI6K09ENG9So=
+github.com/containers/storage v1.32.3/go.mod h1:s1xFaWvj8qwm1+OnlbPE8RBzdTTpIWuHzVivOqzRKiQ=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@@ -269,14 +270,15 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/cri-o/ocicni v0.2.1-0.20210301205850-541cf7c703cf h1:k2wrxBiBseRfOD7h+9fABEuesABBQuUuW5fWwpARbeI=
-github.com/cri-o/ocicni v0.2.1-0.20210301205850-541cf7c703cf/go.mod h1:vingr1ztOAzP2WyTgGbpMov9dFhbjNxdLtDv0+PhAvY=
+github.com/cri-o/ocicni v0.2.1-0.20210621164014-d0acc7862283 h1:7FyIYKksGvRF8XjMkG5T6uIxg8PcgZoPyO+f6kHT5+s=
+github.com/cri-o/ocicni v0.2.1-0.20210621164014-d0acc7862283/go.mod h1:vingr1ztOAzP2WyTgGbpMov9dFhbjNxdLtDv0+PhAvY=
github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
+github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -300,8 +302,9 @@ github.com/docker/docker v20.10.3-0.20210216175712-646072ed6524+incompatible/go.
github.com/docker/docker v20.10.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
+github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o=
+github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
@@ -499,8 +502,9 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
-github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
+github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/insomniacslk/dhcp v0.0.0-20210120172423-cc9239ac6294/go.mod h1:TKl4jN3Voofo4UJIicyNhWGp/nlQqQkFxmwIFTvBkKI=
@@ -508,8 +512,9 @@ github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee h1:PAXLXk1heNZ5y
github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
github.com/jamescun/tuntap v0.0.0-20190712092105-cb1fb277045c/go.mod h1:zzwpsgcYhzzIP5WyF8g9ivCv38cY9uAV9Gu0m3lThhE=
-github.com/jinzhu/copier v0.3.0 h1:P5zN9OYSxmtzZmwgcVmt5Iu8egfP53BGMPAFgEksKPI=
github.com/jinzhu/copier v0.3.0/go.mod h1:24xnZezI2Yqac9J61UC6/dG/k76ttpq0DdJI3QmUvro=
+github.com/jinzhu/copier v0.3.2 h1:QdBOCbaouLDYaIPFfi1bKv5F5tPpeTwXe4sD0jqtz5w=
+github.com/jinzhu/copier v0.3.2/go.mod h1:24xnZezI2Yqac9J61UC6/dG/k76ttpq0DdJI3QmUvro=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
@@ -536,8 +541,9 @@ github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
-github.com/klauspost/compress v1.13.0 h1:2T7tUoQrQT+fQWdaY5rjWztFGAFwbGD04iPJg90ZiOs=
github.com/klauspost/compress v1.13.0/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
+github.com/klauspost/compress v1.13.1 h1:wXr2uRxZTJXHLly6qhJabee5JqIhTRoLBhDOA74hDEQ=
+github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -572,8 +578,9 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
-github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
+github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
+github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
@@ -848,6 +855,8 @@ github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpc
github.com/vbauerster/mpb/v6 v6.0.3/go.mod h1:5luBx4rDLWxpA4t6I5sdeeQuZhqDxc+wr5Nqf35+tnM=
github.com/vbauerster/mpb/v6 v6.0.4 h1:h6J5zM/2wimP5Hj00unQuV8qbo5EPcj6wbkCqgj7KcY=
github.com/vbauerster/mpb/v6 v6.0.4/go.mod h1:a/+JT57gqh6Du0Ay5jSR+uBMfXGdlR7VQlGP52fJxLM=
+github.com/vbauerster/mpb/v7 v7.0.2 h1:eN6AD/ytv1nqCO7Dm8MO0/pGMKmMyH/WMnTJhAUuc/w=
+github.com/vbauerster/mpb/v7 v7.0.2/go.mod h1:Mnq3gESXJ9eQhccbGZDggJ1faTCrmaA4iN57fUloRGE=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852 h1:cPXZWzzG0NllBLdjWoD1nDfaqu98YMv+OneaKc8sPOA=
@@ -1072,12 +1081,12 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210216224549-f992740a1bac/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I=
+golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201113234701-d7a72108b828/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1260,13 +1269,13 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
-k8s.io/api v0.21.1 h1:94bbZ5NTjdINJEdzOkpS4vdPhkb1VFpTYC9zh43f75c=
-k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s=
+k8s.io/api v0.21.2 h1:vz7DqmRsXTCSa6pNxXwQ1IYeAZgdIsua+DZU+o+SX3Y=
+k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU=
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
-k8s.io/apimachinery v0.21.1 h1:Q6XuHGlj2xc+hlMCvqyYfbv3H7SRGn2c8NycxJquDVs=
-k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
+k8s.io/apimachinery v0.21.2 h1:vezUc/BHqWlQDnZ+XkrpXSmnANSLbpnlpwo0Lhk0gpc=
+k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM=
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
diff --git a/libpod/container_exec.go b/libpod/container_exec.go
index 737bf74ad..5d4bcb422 100644
--- a/libpod/container_exec.go
+++ b/libpod/container_exec.go
@@ -277,9 +277,10 @@ func (c *Container) ExecStart(sessionID string) error {
}
// ExecStartAndAttach starts and attaches to an exec session in a container.
+// newSize resizes the tty to this size before the process is started, must be nil if the exec session has no tty
// TODO: Should we include detach keys in the signature to allow override?
// TODO: How do we handle AttachStdin/AttachStdout/AttachStderr?
-func (c *Container) ExecStartAndAttach(sessionID string, streams *define.AttachStreams) error {
+func (c *Container) ExecStartAndAttach(sessionID string, streams *define.AttachStreams, newSize *define.TerminalSize) error {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
@@ -310,7 +311,7 @@ func (c *Container) ExecStartAndAttach(sessionID string, streams *define.AttachS
return err
}
- pid, attachChan, err := c.ociRuntime.ExecContainer(c, session.ID(), opts, streams)
+ pid, attachChan, err := c.ociRuntime.ExecContainer(c, session.ID(), opts, streams, newSize)
if err != nil {
return err
}
@@ -373,7 +374,9 @@ func (c *Container) ExecStartAndAttach(sessionID string, streams *define.AttachS
}
// ExecHTTPStartAndAttach starts and performs an HTTP attach to an exec session.
-func (c *Container) ExecHTTPStartAndAttach(sessionID string, r *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, detachKeys *string, cancel <-chan bool, hijackDone chan<- bool) error {
+// newSize resizes the tty to this size before the process is started, must be nil if the exec session has no tty
+func (c *Container) ExecHTTPStartAndAttach(sessionID string, r *http.Request, w http.ResponseWriter,
+ streams *HTTPAttachStreams, detachKeys *string, cancel <-chan bool, hijackDone chan<- bool, newSize *define.TerminalSize) error {
// TODO: How do we combine streams with the default streams set in the exec session?
// Ensure that we don't leak a goroutine here
@@ -431,7 +434,7 @@ func (c *Container) ExecHTTPStartAndAttach(sessionID string, r *http.Request, w
close(holdConnOpen)
}()
- pid, attachChan, err := c.ociRuntime.ExecContainerHTTP(c, session.ID(), execOpts, r, w, streams, cancel, hijackDone, holdConnOpen)
+ pid, attachChan, err := c.ociRuntime.ExecContainerHTTP(c, session.ID(), execOpts, r, w, streams, cancel, hijackDone, holdConnOpen, newSize)
if err != nil {
session.State = define.ExecStateStopped
session.ExitCode = define.TranslateExecErrorToExitCode(define.ExecErrorCodeGeneric, err)
@@ -719,7 +722,10 @@ func (c *Container) Exec(config *ExecConfig, streams *define.AttachStreams, resi
// API there.
// TODO: Refactor so this is closed here, before we remove the exec
// session.
+ var size *define.TerminalSize
if resize != nil {
+ s := <-resize
+ size = &s
go func() {
logrus.Debugf("Sending resize events to exec session %s", sessionID)
for resizeRequest := range resize {
@@ -737,7 +743,7 @@ func (c *Container) Exec(config *ExecConfig, streams *define.AttachStreams, resi
}()
}
- if err := c.ExecStartAndAttach(sessionID, streams); err != nil {
+ if err := c.ExecStartAndAttach(sessionID, streams, size); err != nil {
return -1, err
}
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 3e4eea003..2555f15ec 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -1062,7 +1062,7 @@ func (c *Container) init(ctx context.Context, retainRetries bool) error {
}
for _, v := range c.config.NamedVolumes {
- if err := c.chownVolume(v.Name); err != nil {
+ if err := c.fixVolumePermissions(v); err != nil {
return err
}
}
@@ -1535,7 +1535,7 @@ func (c *Container) mountStorage() (_ string, deferredErr error) {
// If /etc/mtab does not exist in container image, then we need to
// create it, so that mount command within the container will work.
mtab := filepath.Join(mountPoint, "/etc/mtab")
- if err := os.MkdirAll(filepath.Dir(mtab), 0755); err != nil {
+ if err := idtools.MkdirAllAs(filepath.Dir(mtab), 0755, c.RootUID(), c.RootGID()); err != nil {
return "", errors.Wrap(err, "error creating mtab directory")
}
if err = os.Symlink("/proc/mounts", mtab); err != nil && !os.IsExist(err) {
@@ -1681,64 +1681,6 @@ func (c *Container) mountNamedVolume(v *ContainerNamedVolume, mountpoint string)
return vol, nil
}
-// Chown the specified volume if necessary.
-func (c *Container) chownVolume(volumeName string) error {
- vol, err := c.runtime.state.Volume(volumeName)
- if err != nil {
- return errors.Wrapf(err, "error retrieving named volume %s for container %s", volumeName, c.ID())
- }
-
- vol.lock.Lock()
- defer vol.lock.Unlock()
-
- // The volume may need a copy-up. Check the state.
- if err := vol.update(); err != nil {
- return err
- }
-
- // TODO: For now, I've disabled chowning volumes owned by non-Podman
- // drivers. This may be safe, but it's really going to be a case-by-case
- // thing, I think - safest to leave disabled now and re-enable later if
- // there is a demand.
- if vol.state.NeedsChown && !vol.UsesVolumeDriver() {
- vol.state.NeedsChown = false
-
- uid := int(c.config.Spec.Process.User.UID)
- gid := int(c.config.Spec.Process.User.GID)
-
- if c.config.IDMappings.UIDMap != nil {
- p := idtools.IDPair{
- UID: uid,
- GID: gid,
- }
- mappings := idtools.NewIDMappingsFromMaps(c.config.IDMappings.UIDMap, c.config.IDMappings.GIDMap)
- newPair, err := mappings.ToHost(p)
- if err != nil {
- return errors.Wrapf(err, "error mapping user %d:%d", uid, gid)
- }
- uid = newPair.UID
- gid = newPair.GID
- }
-
- vol.state.UIDChowned = uid
- vol.state.GIDChowned = gid
-
- if err := vol.save(); err != nil {
- return err
- }
-
- mountPoint, err := vol.MountPoint()
- if err != nil {
- return err
- }
-
- if err := os.Lchown(mountPoint, uid, gid); err != nil {
- return err
- }
- }
- return nil
-}
-
// cleanupStorage unmounts and cleans up the container's root filesystem
func (c *Container) cleanupStorage() error {
if !c.state.Mounted {
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index ddfccb999..25db3cff0 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -1661,9 +1661,13 @@ func (c *Container) generateResolvConf() (string, error) {
// check if systemd-resolved is used, assume it is used when 127.0.0.53 is the only nameserver
if len(ns) == 1 && ns[0] == "127.0.0.53" {
// read the actual resolv.conf file for systemd-resolved
- contents, err = ioutil.ReadFile("/run/systemd/resolve/resolv.conf")
+ resolvedContents, err := ioutil.ReadFile("/run/systemd/resolve/resolv.conf")
if err != nil {
- return "", errors.Wrapf(err, "detected that systemd-resolved is in use, but could not locate real resolv.conf")
+ if !os.IsNotExist(err) {
+ return "", errors.Wrapf(err, "detected that systemd-resolved is in use, but could not locate real resolv.conf")
+ }
+ } else {
+ contents = resolvedContents
}
}
@@ -1816,7 +1820,7 @@ func (c *Container) getHosts() string {
if c.Hostname() != "" {
if c.config.NetMode.IsSlirp4netns() {
// When using slirp4netns, the interface gets a static IP
- slirp4netnsIP, err := GetSlirp4netnsGateway(c.slirp4netnsSubnet)
+ slirp4netnsIP, err := GetSlirp4netnsIP(c.slirp4netnsSubnet)
if err != nil {
logrus.Warn("failed to determine slirp4netnsIP: ", err.Error())
} else {
@@ -2426,3 +2430,77 @@ func (c *Container) createSecretMountDir() error {
return err
}
+
+// Fix ownership and permissions of the specified volume if necessary.
+func (c *Container) fixVolumePermissions(v *ContainerNamedVolume) error {
+ vol, err := c.runtime.state.Volume(v.Name)
+ if err != nil {
+ return errors.Wrapf(err, "error retrieving named volume %s for container %s", v.Name, c.ID())
+ }
+
+ vol.lock.Lock()
+ defer vol.lock.Unlock()
+
+ // The volume may need a copy-up. Check the state.
+ if err := vol.update(); err != nil {
+ return err
+ }
+
+ // TODO: For now, I've disabled chowning volumes owned by non-Podman
+ // drivers. This may be safe, but it's really going to be a case-by-case
+ // thing, I think - safest to leave disabled now and re-enable later if
+ // there is a demand.
+ if vol.state.NeedsChown && !vol.UsesVolumeDriver() {
+ vol.state.NeedsChown = false
+
+ uid := int(c.config.Spec.Process.User.UID)
+ gid := int(c.config.Spec.Process.User.GID)
+
+ if c.config.IDMappings.UIDMap != nil {
+ p := idtools.IDPair{
+ UID: uid,
+ GID: gid,
+ }
+ mappings := idtools.NewIDMappingsFromMaps(c.config.IDMappings.UIDMap, c.config.IDMappings.GIDMap)
+ newPair, err := mappings.ToHost(p)
+ if err != nil {
+ return errors.Wrapf(err, "error mapping user %d:%d", uid, gid)
+ }
+ uid = newPair.UID
+ gid = newPair.GID
+ }
+
+ vol.state.UIDChowned = uid
+ vol.state.GIDChowned = gid
+
+ if err := vol.save(); err != nil {
+ return err
+ }
+
+ mountPoint, err := vol.MountPoint()
+ if err != nil {
+ return err
+ }
+
+ if err := os.Lchown(mountPoint, uid, gid); err != nil {
+ return err
+ }
+
+ // Make sure the new volume matches the permissions of the target directory.
+ // https://github.com/containers/podman/issues/10188
+ st, err := os.Lstat(filepath.Join(c.state.Mountpoint, v.Dest))
+ if err == nil {
+ if err := os.Chmod(mountPoint, st.Mode()|0111); err != nil {
+ return err
+ }
+ stat := st.Sys().(*syscall.Stat_t)
+ atime := time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec))
+ if err := os.Chtimes(mountPoint, atime, st.ModTime()); err != nil {
+ return err
+ }
+ } else if !os.IsNotExist(err) {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/libpod/container_internal_unsupported.go b/libpod/container_internal_unsupported.go
index f979bcbde..125329ce5 100644
--- a/libpod/container_internal_unsupported.go
+++ b/libpod/container_internal_unsupported.go
@@ -57,3 +57,8 @@ func (c *Container) reloadNetwork() error {
func (c *Container) getUserOverrides() *lookup.Overrides {
return nil
}
+
+// Fix ownership and permissions of the specified volume if necessary.
+func (c *Container) fixVolumePermissions(v *ContainerNamedVolume) error {
+ return define.ErrNotImplemented
+}
diff --git a/libpod/container_log.go b/libpod/container_log.go
index a30e4f5cc..43b3f7736 100644
--- a/libpod/container_log.go
+++ b/libpod/container_log.go
@@ -4,10 +4,12 @@ import (
"context"
"fmt"
"os"
+ "time"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/events"
"github.com/containers/podman/v3/libpod/logs"
+ "github.com/hpcloud/tail/watch"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -74,7 +76,7 @@ func (c *Container) readFromLogFile(ctx context.Context, options *logs.LogOption
}
nll, err := logs.NewLogLine(line.Text)
if err != nil {
- logrus.Error(err)
+ logrus.Errorf("Error getting new log line: %v", err)
continue
}
if nll.Partial() {
@@ -93,17 +95,20 @@ func (c *Container) readFromLogFile(ctx context.Context, options *logs.LogOption
}()
// Check if container is still running or paused
if options.Follow {
+ // If the container isn't running or if we encountered an error
+ // getting its state, instruct the logger to read the file
+ // until EOF.
state, err := c.State()
if err != nil || state != define.ContainerStateRunning {
- // If the container isn't running or if we encountered
- // an error getting its state, instruct the logger to
- // read the file until EOF.
+ // Make sure to wait at least for the poll duration
+ // before stopping the file logger (see #10675).
+ time.Sleep(watch.POLL_DURATION)
tailError := t.StopAtEOF()
if tailError != nil && fmt.Sprintf("%v", tailError) != "tail: stop at eof" {
- logrus.Error(tailError)
+ logrus.Errorf("Error stopping logger: %v", tailError)
}
- if errors.Cause(err) != define.ErrNoSuchCtr {
- logrus.Error(err)
+ if err != nil && errors.Cause(err) != define.ErrNoSuchCtr {
+ logrus.Errorf("Error getting container state: %v", err)
}
return nil
}
@@ -124,9 +129,12 @@ func (c *Container) readFromLogFile(ctx context.Context, options *logs.LogOption
// Now wait for the died event and signal to finish
// reading the log until EOF.
<-eventChannel
+ // Make sure to wait at least for the poll duration
+ // before stopping the file logger (see #10675).
+ time.Sleep(watch.POLL_DURATION)
tailError := t.StopAtEOF()
if tailError != nil && fmt.Sprintf("%v", tailError) != "tail: stop at eof" {
- logrus.Error(tailError)
+ logrus.Errorf("Error stopping logger: %v", tailError)
}
}()
}
diff --git a/libpod/container_validate.go b/libpod/container_validate.go
index aae96ae85..6ff46f1b1 100644
--- a/libpod/container_validate.go
+++ b/libpod/container_validate.go
@@ -131,6 +131,5 @@ func (c *Container) validate() error {
if c.config.User == "" && (c.config.Spec.Process.User.UID != 0 || c.config.Spec.Process.User.GID != 0) {
return errors.Wrapf(define.ErrInvalidArg, "please set User explicitly via WithUser() instead of in OCI spec directly")
}
-
return nil
}
diff --git a/libpod/define/containerstate.go b/libpod/define/containerstate.go
index 5d2bc9099..fc272beaa 100644
--- a/libpod/define/containerstate.go
+++ b/libpod/define/containerstate.go
@@ -1,6 +1,10 @@
package define
-import "github.com/pkg/errors"
+import (
+ "time"
+
+ "github.com/pkg/errors"
+)
// ContainerStatus represents the current state of a container
type ContainerStatus int
@@ -120,12 +124,14 @@ func (s ContainerExecStatus) String() string {
// ContainerStats contains the statistics information for a running container
type ContainerStats struct {
+ AvgCPU float64
ContainerID string
Name string
PerCPU []uint64
CPU float64
CPUNano uint64
CPUSystemNano uint64
+ DataPoints int64
SystemNano uint64
MemUsage uint64
MemLimit uint64
@@ -135,4 +141,6 @@ type ContainerStats struct {
BlockInput uint64
BlockOutput uint64
PIDs uint64
+ UpTime time.Duration
+ Duration uint64
}
diff --git a/libpod/define/pod_inspect.go b/libpod/define/pod_inspect.go
index 2fa91166f..67f075b3c 100644
--- a/libpod/define/pod_inspect.go
+++ b/libpod/define/pod_inspect.go
@@ -51,6 +51,12 @@ type InspectPodData struct {
// Containers gives a brief summary of all containers in the pod and
// their current status.
Containers []InspectPodContainerInfo `json:"Containers,omitempty"`
+ // CPUPeriod contains the CPU period of the pod
+ CPUPeriod uint64 `json:"cpu_period,omitempty"`
+ // CPUQuota contains the CPU quota of the pod
+ CPUQuota int64 `json:"cpu_quota,omitempty"`
+ // CPUSetCPUs contains linux specific CPU data for the pod
+ CPUSetCPUs string `json:"cpuset_cpus,omitempty"`
}
// InspectPodInfraConfig contains the configuration of the pod's infra
@@ -91,6 +97,12 @@ type InspectPodInfraConfig struct {
Networks []string
// NetworkOptions are additional options for each network
NetworkOptions map[string][]string
+ // CPUPeriod contains the CPU period of the pod
+ CPUPeriod uint64 `json:"cpu_period,omitempty"`
+ // CPUQuota contains the CPU quota of the pod
+ CPUQuota int64 `json:"cpu_quota,omitempty"`
+ // CPUSetCPUs contains linux specific CPU data for the container
+ CPUSetCPUs string `json:"cpuset_cpus,omitempty"`
}
// InspectPodContainerInfo contains information on a container in a pod.
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 5446841f6..1b775a4f3 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -46,6 +46,9 @@ const (
// rootlessCNINSName is the file name for the rootless network namespace bind mount
rootlessCNINSName = "rootless-cni-ns"
+
+ // persistentCNIDir is the directory where the CNI files are stored
+ persistentCNIDir = "/var/lib/cni"
)
// Get an OCICNI network config
@@ -150,14 +153,31 @@ func (r *RootlessCNI) Do(toRun func() error) error {
}
}
- // cni plugins need access to /var and /run
- runDir := filepath.Join(r.dir, "run")
- varDir := filepath.Join(r.dir, "var")
+ // cni plugins need access to /var/lib/cni and /run
+ varDir := ""
+ varTarget := persistentCNIDir
+ // we can only mount to a target dir which exists, check /var/lib/cni recursively
+ // while we could always use /var there are cases where a user might store the cni
+ // configs under /var/custom and this would break
+ for {
+ if _, err := os.Stat(varTarget); err == nil {
+ varDir = filepath.Join(r.dir, strings.TrimPrefix(varTarget, "/"))
+ break
+ }
+ varTarget = filepath.Base(varTarget)
+ if varTarget == "/" {
+ break
+ }
+ }
+ if varDir == "" {
+ return errors.New("failed to stat /var directory")
+ }
// make sure to mount var first
- err = unix.Mount(varDir, "/var", "none", unix.MS_BIND, "")
+ err = unix.Mount(varDir, varTarget, "none", unix.MS_BIND, "")
if err != nil {
- return errors.Wrap(err, "failed to mount /var for rootless cni")
+ return errors.Wrapf(err, "failed to mount %s for rootless cni", varTarget)
}
+ runDir := filepath.Join(r.dir, "run")
// recursive mount to keep the netns mount
err = unix.Mount(runDir, "/run", "none", unix.MS_BIND|unix.MS_REC, "")
if err != nil {
@@ -385,7 +405,7 @@ func (r *Runtime) GetRootlessCNINetNs(new bool) (*RootlessCNI, error) {
// create cni directories to store files
// they will be bind mounted to the correct location in a extra mount ns
- err = os.MkdirAll(filepath.Join(cniDir, "var"), 0700)
+ err = os.MkdirAll(filepath.Join(cniDir, strings.TrimPrefix(persistentCNIDir, "/")), 0700)
if err != nil {
return nil, errors.Wrap(err, "could not create rootless-cni var directory")
}
@@ -888,6 +908,10 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
if err != nil {
return nil, err
}
+ // see https://github.com/containers/podman/issues/10090
+ // the container has to be locked for syncContainer()
+ netNsCtr.lock.Lock()
+ defer netNsCtr.lock.Unlock()
// Have to sync to ensure that state is populated
if err := netNsCtr.syncContainer(); err != nil {
return nil, err
@@ -1043,7 +1067,7 @@ func resultToBasicNetworkConfig(result *cnitypes.Result) (define.InspectBasicNet
// after itself on an unclean reboot. Return what we're pretty sure is the path
// to CNI's internal files (it's not really exposed to us).
func getCNINetworksDir() (string, error) {
- return "/var/lib/cni/networks", nil
+ return filepath.Join(persistentCNIDir, "networks"), nil
}
type logrusDebugWriter struct {
diff --git a/libpod/oci.go b/libpod/oci.go
index 1f2c7dd71..c92d9a077 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -72,13 +72,16 @@ type OCIRuntime interface {
// has completed, as one might expect. The attach session will remain
// running, in a goroutine that will return via the chan error in the
// return signature.
- ExecContainer(ctr *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams) (int, chan error, error)
+ // newSize resizes the tty to this size before the process is started, must be nil if the exec session has no tty
+ ExecContainer(ctr *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams, newSize *define.TerminalSize) (int, chan error, error)
// ExecContainerHTTP executes a command in a running container and
// attaches its standard streams to a provided hijacked HTTP session.
// Maintains the same invariants as ExecContainer (returns on session
// start, with a goroutine running in the background to handle attach).
// The HTTP attach itself maintains the same invariants as HTTPAttach.
- ExecContainerHTTP(ctr *Container, sessionID string, options *ExecOptions, r *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool) (int, chan error, error)
+ // newSize resizes the tty to this size before the process is started, must be nil if the exec session has no tty
+ ExecContainerHTTP(ctr *Container, sessionID string, options *ExecOptions, r *http.Request, w http.ResponseWriter,
+ streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, newSize *define.TerminalSize) (int, chan error, error)
// ExecContainerDetached executes a command in a running container, but
// does not attach to it. Returns the PID of the exec session and an
// error (if starting the exec session failed)
diff --git a/libpod/oci_attach_linux.go b/libpod/oci_attach_linux.go
index b5040de3e..de435b58a 100644
--- a/libpod/oci_attach_linux.go
+++ b/libpod/oci_attach_linux.go
@@ -94,17 +94,18 @@ func (c *Container) attach(streams *define.AttachStreams, keys string, resize <-
// this ensures attachToExec gets all of the output of the called process
// conmon will then send the exit code of the exec process, or an error in the exec session
// startFd must be the input side of the fd.
+// newSize resizes the tty to this size before the process is started, must be nil if the exec session has no tty
// conmon will wait to start the exec session until the parent process has setup the console socket.
// Once attachToExec successfully attaches to the console socket, the child conmon process responsible for calling runtime exec
// will read from the output side of start fd, thus learning to start the child process.
// Thus, the order goes as follow:
// 1. conmon parent process sets up its console socket. sends on attachFd
-// 2. attachToExec attaches to the console socket after reading on attachFd
+// 2. attachToExec attaches to the console socket after reading on attachFd and resizes the tty
// 3. child waits on startFd for attachToExec to attach to said console socket
// 4. attachToExec sends on startFd, signalling it has attached to the socket and child is ready to go
// 5. child receives on startFd, runs the runtime exec command
// attachToExec is responsible for closing startFd and attachFd
-func (c *Container) attachToExec(streams *define.AttachStreams, keys *string, sessionID string, startFd, attachFd *os.File) error {
+func (c *Container) attachToExec(streams *define.AttachStreams, keys *string, sessionID string, startFd, attachFd *os.File, newSize *define.TerminalSize) error {
if !streams.AttachOutput && !streams.AttachError && !streams.AttachInput {
return errors.Wrapf(define.ErrInvalidArg, "must provide at least one stream to attach to")
}
@@ -137,6 +138,14 @@ func (c *Container) attachToExec(streams *define.AttachStreams, keys *string, se
return err
}
+ // resize before we start the container process
+ if newSize != nil {
+ err = c.ociRuntime.ExecAttachResize(c, sessionID, *newSize)
+ if err != nil {
+ logrus.Warn("resize failed", err)
+ }
+ }
+
// 2: then attach
conn, err := openUnixSocket(sockPath)
if err != nil {
diff --git a/libpod/oci_conmon_exec_linux.go b/libpod/oci_conmon_exec_linux.go
index 76338b86c..09d3d1833 100644
--- a/libpod/oci_conmon_exec_linux.go
+++ b/libpod/oci_conmon_exec_linux.go
@@ -25,7 +25,7 @@ import (
)
// ExecContainer executes a command in a running container
-func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams) (int, chan error, error) {
+func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams, newSize *define.TerminalSize) (int, chan error, error) {
if options == nil {
return -1, nil, errors.Wrapf(define.ErrInvalidArg, "must provide an ExecOptions struct to ExecContainer")
}
@@ -68,7 +68,7 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options
attachChan := make(chan error)
go func() {
// attachToExec is responsible for closing pipes
- attachChan <- c.attachToExec(streams, options.DetachKeys, sessionID, pipes.startPipe, pipes.attachPipe)
+ attachChan <- c.attachToExec(streams, options.DetachKeys, sessionID, pipes.startPipe, pipes.attachPipe, newSize)
close(attachChan)
}()
@@ -83,7 +83,8 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options
// ExecContainerHTTP executes a new command in an existing container and
// forwards its standard streams over an attach
-func (r *ConmonOCIRuntime) ExecContainerHTTP(ctr *Container, sessionID string, options *ExecOptions, req *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool) (int, chan error, error) {
+func (r *ConmonOCIRuntime) ExecContainerHTTP(ctr *Container, sessionID string, options *ExecOptions, req *http.Request, w http.ResponseWriter,
+ streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, newSize *define.TerminalSize) (int, chan error, error) {
if streams != nil {
if !streams.Stdin && !streams.Stdout && !streams.Stderr {
return -1, nil, errors.Wrapf(define.ErrInvalidArg, "must provide at least one stream to attach to")
@@ -133,7 +134,7 @@ func (r *ConmonOCIRuntime) ExecContainerHTTP(ctr *Container, sessionID string, o
conmonPipeDataChan := make(chan conmonPipeData)
go func() {
// attachToExec is responsible for closing pipes
- attachChan <- attachExecHTTP(ctr, sessionID, req, w, streams, pipes, detachKeys, options.Terminal, cancel, hijackDone, holdConnOpen, execCmd, conmonPipeDataChan, ociLog)
+ attachChan <- attachExecHTTP(ctr, sessionID, req, w, streams, pipes, detachKeys, options.Terminal, cancel, hijackDone, holdConnOpen, execCmd, conmonPipeDataChan, ociLog, newSize)
close(attachChan)
}()
@@ -486,7 +487,7 @@ func (r *ConmonOCIRuntime) startExec(c *Container, sessionID string, options *Ex
}
// Attach to a container over HTTP
-func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, pipes *execPipes, detachKeys []byte, isTerminal bool, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, execCmd *exec.Cmd, conmonPipeDataChan chan<- conmonPipeData, ociLog string) (deferredErr error) {
+func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, pipes *execPipes, detachKeys []byte, isTerminal bool, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, execCmd *exec.Cmd, conmonPipeDataChan chan<- conmonPipeData, ociLog string, newSize *define.TerminalSize) (deferredErr error) {
// NOTE: As you may notice, the attach code is quite complex.
// Many things happen concurrently and yet are interdependent.
// If you ever change this function, make sure to write to the
@@ -524,6 +525,14 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
return err
}
+ // resize before we start the container process
+ if newSize != nil {
+ err = c.ociRuntime.ExecAttachResize(c, sessionID, *newSize)
+ if err != nil {
+ logrus.Warn("resize failed", err)
+ }
+ }
+
// 2: then attach
conn, err := openUnixSocket(sockPath)
if err != nil {
diff --git a/libpod/oci_missing.go b/libpod/oci_missing.go
index 10526f368..fcf2ffca8 100644
--- a/libpod/oci_missing.go
+++ b/libpod/oci_missing.go
@@ -119,12 +119,13 @@ func (r *MissingRuntime) AttachResize(ctr *Container, newSize define.TerminalSiz
}
// ExecContainer is not available as the runtime is missing
-func (r *MissingRuntime) ExecContainer(ctr *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams) (int, chan error, error) {
+func (r *MissingRuntime) ExecContainer(ctr *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams, newSize *define.TerminalSize) (int, chan error, error) {
return -1, nil, r.printError()
}
// ExecContainerHTTP is not available as the runtime is missing
-func (r *MissingRuntime) ExecContainerHTTP(ctr *Container, sessionID string, options *ExecOptions, req *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool) (int, chan error, error) {
+func (r *MissingRuntime) ExecContainerHTTP(ctr *Container, sessionID string, options *ExecOptions, req *http.Request, w http.ResponseWriter,
+ streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, newSize *define.TerminalSize) (int, chan error, error) {
return -1, nil, r.printError()
}
diff --git a/libpod/options.go b/libpod/options.go
index d3be46ad8..b12153512 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -7,6 +7,7 @@ import (
"strings"
"syscall"
+ "github.com/containers/buildah/pkg/parse"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/secrets"
"github.com/containers/image/v5/manifest"
@@ -19,6 +20,7 @@ import (
"github.com/containers/storage"
"github.com/containers/storage/pkg/idtools"
"github.com/cri-o/ocicni/pkg/ocicni"
+ "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -268,8 +270,11 @@ func WithRegistriesConf(path string) RuntimeOption {
return errors.Wrap(err, "error locating specified registries.conf")
}
if rt.imageContext == nil {
- rt.imageContext = &types.SystemContext{}
+ rt.imageContext = &types.SystemContext{
+ BigFilesTemporaryDir: parse.GetTempDir(),
+ }
}
+
rt.imageContext.SystemRegistriesConfPath = path
return nil
}
@@ -555,7 +560,6 @@ func WithMaxLogSize(limit int64) CtrCreateOption {
if ctr.valid {
return define.ErrRuntimeFinalized
}
-
ctr.config.LogSize = limit
return nil
@@ -863,7 +867,6 @@ func WithMountNSFrom(nsCtr *Container) CtrCreateOption {
if err := checkDependencyContainer(nsCtr, ctr); err != nil {
return err
}
-
ctr.config.MountNsCtr = nsCtr.ID()
return nil
@@ -2355,3 +2358,42 @@ func WithVolatile() CtrCreateOption {
return nil
}
}
+
+// WithPodCPUPAQ takes the given cpu period and quota and inserts them in the proper place.
+func WithPodCPUPAQ(period uint64, quota int64) PodCreateOption {
+ return func(pod *Pod) error {
+ if pod.valid {
+ return define.ErrPodFinalized
+ }
+ if pod.CPUPeriod() != 0 && pod.CPUQuota() != 0 {
+ pod.config.InfraContainer.ResourceLimits.CPU = &specs.LinuxCPU{
+ Period: &period,
+ Quota: &quota,
+ }
+ } else {
+ pod.config.InfraContainer.ResourceLimits = &specs.LinuxResources{}
+ pod.config.InfraContainer.ResourceLimits.CPU = &specs.LinuxCPU{
+ Period: &period,
+ Quota: &quota,
+ }
+ }
+ return nil
+ }
+}
+
+// WithPodCPUSetCPUS computes and sets the Cpus linux resource string which determines the amount of cores, from those available, we are allowed to execute on
+func WithPodCPUSetCPUs(inp string) PodCreateOption {
+ return func(pod *Pod) error {
+ if pod.valid {
+ return define.ErrPodFinalized
+ }
+ if pod.ResourceLim().CPU.Period != nil {
+ pod.config.InfraContainer.ResourceLimits.CPU.Cpus = inp
+ } else {
+ pod.config.InfraContainer.ResourceLimits = &specs.LinuxResources{}
+ pod.config.InfraContainer.ResourceLimits.CPU = &specs.LinuxCPU{}
+ pod.config.InfraContainer.ResourceLimits.CPU.Cpus = inp
+ }
+ return nil
+ }
+}
diff --git a/libpod/pod.go b/libpod/pod.go
index dce2a0c1c..d7a9b15d9 100644
--- a/libpod/pod.go
+++ b/libpod/pod.go
@@ -1,12 +1,14 @@
package libpod
import (
+ "context"
"net"
"time"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/lock"
"github.com/cri-o/ocicni/pkg/ocicni"
+ "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@@ -91,25 +93,26 @@ type podState struct {
// Generally speaking, aside from those two exceptions, these options will set
// the equivalent field in the container's configuration.
type InfraContainerConfig struct {
- ConmonPidFile string `json:"conmonPidFile"`
- HasInfraContainer bool `json:"makeInfraContainer"`
- NoNetwork bool `json:"noNetwork,omitempty"`
- HostNetwork bool `json:"infraHostNetwork,omitempty"`
- PortBindings []ocicni.PortMapping `json:"infraPortBindings"`
- StaticIP net.IP `json:"staticIP,omitempty"`
- StaticMAC net.HardwareAddr `json:"staticMAC,omitempty"`
- UseImageResolvConf bool `json:"useImageResolvConf,omitempty"`
- DNSServer []string `json:"dnsServer,omitempty"`
- DNSSearch []string `json:"dnsSearch,omitempty"`
- DNSOption []string `json:"dnsOption,omitempty"`
- UseImageHosts bool `json:"useImageHosts,omitempty"`
- HostAdd []string `json:"hostsAdd,omitempty"`
- Networks []string `json:"networks,omitempty"`
- ExitCommand []string `json:"exitCommand,omitempty"`
- InfraImage string `json:"infraImage,omitempty"`
- InfraCommand []string `json:"infraCommand,omitempty"`
- Slirp4netns bool `json:"slirp4netns,omitempty"`
- NetworkOptions map[string][]string `json:"network_options,omitempty"`
+ ConmonPidFile string `json:"conmonPidFile"`
+ HasInfraContainer bool `json:"makeInfraContainer"`
+ NoNetwork bool `json:"noNetwork,omitempty"`
+ HostNetwork bool `json:"infraHostNetwork,omitempty"`
+ PortBindings []ocicni.PortMapping `json:"infraPortBindings"`
+ StaticIP net.IP `json:"staticIP,omitempty"`
+ StaticMAC net.HardwareAddr `json:"staticMAC,omitempty"`
+ UseImageResolvConf bool `json:"useImageResolvConf,omitempty"`
+ DNSServer []string `json:"dnsServer,omitempty"`
+ DNSSearch []string `json:"dnsSearch,omitempty"`
+ DNSOption []string `json:"dnsOption,omitempty"`
+ UseImageHosts bool `json:"useImageHosts,omitempty"`
+ HostAdd []string `json:"hostsAdd,omitempty"`
+ Networks []string `json:"networks,omitempty"`
+ ExitCommand []string `json:"exitCommand,omitempty"`
+ InfraImage string `json:"infraImage,omitempty"`
+ InfraCommand []string `json:"infraCommand,omitempty"`
+ Slirp4netns bool `json:"slirp4netns,omitempty"`
+ NetworkOptions map[string][]string `json:"network_options,omitempty"`
+ ResourceLimits *specs.LinuxResources `json:"resource_limits,omitempty"`
}
// ID retrieves the pod's ID
@@ -128,6 +131,45 @@ func (p *Pod) Namespace() string {
return p.config.Namespace
}
+// ResourceLim returns the cpuset resource limits for the pod
+func (p *Pod) ResourceLim() *specs.LinuxResources {
+ resCopy := &specs.LinuxResources{}
+ if err := JSONDeepCopy(p.config.InfraContainer.ResourceLimits, resCopy); err != nil {
+ return nil
+ }
+ if resCopy != nil && resCopy.CPU != nil {
+ return resCopy
+ }
+ empty := &specs.LinuxResources{
+ CPU: &specs.LinuxCPU{},
+ }
+ return empty
+}
+
+// CPUPeriod returns the pod CPU period
+func (p *Pod) CPUPeriod() uint64 {
+ resCopy := &specs.LinuxResources{}
+ if err := JSONDeepCopy(p.config.InfraContainer.ResourceLimits, resCopy); err != nil {
+ return 0
+ }
+ if resCopy != nil && resCopy.CPU != nil && resCopy.CPU.Period != nil {
+ return *resCopy.CPU.Period
+ }
+ return 0
+}
+
+// CPUQuota returns the pod CPU quota
+func (p *Pod) CPUQuota() int64 {
+ resCopy := &specs.LinuxResources{}
+ if err := JSONDeepCopy(p.config.InfraContainer.ResourceLimits, resCopy); err != nil {
+ return 0
+ }
+ if resCopy != nil && resCopy.CPU != nil && resCopy.CPU.Quota != nil {
+ return *resCopy.CPU.Quota
+ }
+ return 0
+}
+
// Labels returns the pod's labels
func (p *Pod) Labels() map[string]string {
labels := make(map[string]string)
@@ -208,7 +250,31 @@ func (p *Pod) CgroupPath() (string, error) {
if err := p.updatePod(); err != nil {
return "", err
}
+ if p.state.CgroupPath != "" {
+ return p.state.CgroupPath, nil
+ }
+ if !p.HasInfraContainer() {
+ return "", errors.Wrap(define.ErrNoSuchCtr, "pod has no infra container")
+ }
+
+ id := p.state.InfraContainerID
+ if id != "" {
+ ctr, err := p.runtime.state.Container(id)
+ if err != nil {
+ return "", errors.Wrapf(err, "could not get infra")
+ }
+ if ctr != nil {
+ ctr.Start(context.Background(), false)
+ cgroupPath, err := ctr.CGroupPath()
+ if err != nil {
+ return "", errors.Wrapf(err, "could not get container cgroup")
+ }
+ p.state.CgroupPath = cgroupPath
+ p.save()
+ return cgroupPath, nil
+ }
+ }
return p.state.CgroupPath, nil
}
diff --git a/libpod/pod_api.go b/libpod/pod_api.go
index 14fe8276c..d8f5d15f8 100644
--- a/libpod/pod_api.go
+++ b/libpod/pod_api.go
@@ -538,6 +538,9 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
infraConfig.StaticMAC = p.config.InfraContainer.StaticMAC.String()
infraConfig.NoManageResolvConf = p.config.InfraContainer.UseImageResolvConf
infraConfig.NoManageHosts = p.config.InfraContainer.UseImageHosts
+ infraConfig.CPUPeriod = p.CPUPeriod()
+ infraConfig.CPUQuota = p.CPUQuota()
+ infraConfig.CPUSetCPUs = p.ResourceLim().CPU.Cpus
if len(p.config.InfraContainer.DNSServer) > 0 {
infraConfig.DNSServer = make([]string, 0, len(p.config.InfraContainer.DNSServer))
@@ -581,6 +584,9 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
SharedNamespaces: sharesNS,
NumContainers: uint(len(containers)),
Containers: ctrs,
+ CPUSetCPUs: p.ResourceLim().CPU.Cpus,
+ CPUPeriod: p.CPUPeriod(),
+ CPUQuota: p.CPUQuota(),
}
return &inspectData, nil
diff --git a/libpod/runtime.go b/libpod/runtime.go
index d775b55e1..f53789e89 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -15,6 +15,7 @@ import (
"syscall"
"time"
+ "github.com/containers/buildah/pkg/parse"
"github.com/containers/common/libimage"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/defaultnet"
@@ -381,7 +382,9 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
// Set up containers/image
if runtime.imageContext == nil {
- runtime.imageContext = &types.SystemContext{}
+ runtime.imageContext = &types.SystemContext{
+ BigFilesTemporaryDir: parse.GetTempDir(),
+ }
}
runtime.imageContext.SignaturePolicyPath = runtime.config.Engine.SignaturePolicyPath
@@ -465,7 +468,7 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
}
// Set up the CNI net plugin
- netPlugin, err := ocicni.InitCNI(runtime.config.Network.DefaultNetwork, runtime.config.Network.NetworkConfigDir, runtime.config.Network.CNIPluginDirs...)
+ netPlugin, err := ocicni.InitCNINoInotify(runtime.config.Network.DefaultNetwork, runtime.config.Network.NetworkConfigDir, "", runtime.config.Network.CNIPluginDirs...)
if err != nil {
return errors.Wrapf(err, "error configuring CNI network plugin")
}
diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go
index c20153c8d..6b002f65a 100644
--- a/libpod/runtime_pod_infra_linux.go
+++ b/libpod/runtime_pod_infra_linux.go
@@ -146,7 +146,6 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
options = append(options, WithExitCommand(p.config.InfraContainer.ExitCommand))
}
}
-
g.SetRootReadonly(true)
g.SetProcessArgs(infraCtrCommand)
@@ -173,7 +172,6 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
// Ignore mqueue sysctls if not sharing IPC
if !p.config.UsePodIPC && strings.HasPrefix(sysctlKey, "fs.mqueue.") {
logrus.Infof("Sysctl %s=%s ignored in containers.conf, since IPC Namespace for pod is unused", sysctlKey, sysctlVal)
-
continue
}
@@ -188,7 +186,6 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
logrus.Infof("Sysctl %s=%s ignored in containers.conf, since UTS Namespace for pod is unused", sysctlKey, sysctlVal)
continue
}
-
g.AddLinuxSysctl(sysctlKey, sysctlVal)
}
@@ -200,7 +197,11 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
if len(p.config.InfraContainer.ConmonPidFile) > 0 {
options = append(options, WithConmonPidFile(p.config.InfraContainer.ConmonPidFile))
}
+ newRes := new(spec.LinuxResources)
+ newRes.CPU = new(spec.LinuxCPU)
+ newRes.CPU = p.ResourceLim().CPU
+ g.Config.Linux.Resources.CPU = newRes.CPU
return r.newContainer(ctx, g.Config, options...)
}
@@ -211,7 +212,6 @@ func (r *Runtime) createInfraContainer(ctx context.Context, p *Pod) (*Container,
if !r.valid {
return nil, define.ErrRuntimeStopped
}
-
imageName := p.config.InfraContainer.InfraImage
if imageName == "" {
imageName = r.config.Engine.InfraImage
diff --git a/libpod/stats.go b/libpod/stats.go
index f4732b4fc..6f0360ef1 100644
--- a/libpod/stats.go
+++ b/libpod/stats.go
@@ -56,7 +56,11 @@ func (c *Container) GetContainerStats(previousStats *define.ContainerStats) (*de
previousCPU := previousStats.CPUNano
now := uint64(time.Now().UnixNano())
+ stats.Duration = cgroupStats.CPU.Usage.Total
+ stats.UpTime = time.Duration(stats.Duration)
stats.CPU = calculateCPUPercent(cgroupStats, previousCPU, now, previousStats.SystemNano)
+ stats.AvgCPU = calculateAvgCPU(stats.CPU, previousStats.AvgCPU, previousStats.DataPoints)
+ stats.DataPoints = previousStats.DataPoints + 1
stats.MemUsage = cgroupStats.Memory.Usage.Usage
stats.MemLimit = getMemLimit(cgroupStats.Memory.Usage.Limit)
stats.MemPerc = (float64(stats.MemUsage) / float64(stats.MemLimit)) * 100
@@ -127,3 +131,9 @@ func calculateBlockIO(stats *cgroups.Metrics) (read uint64, write uint64) {
}
return
}
+
+// calculateAvgCPU calculates the avg CPU percentage given the previous average and the number of data points.
+func calculateAvgCPU(statsCPU float64, prevAvg float64, prevData int64) float64 {
+ avgPer := ((prevAvg * float64(prevData)) + statsCPU) / (float64(prevData) + 1)
+ return avgPer
+}
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index 6bc02dd2b..2a0a0b725 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -403,6 +403,24 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
state.Status = define.ContainerStateCreated.String()
}
+ state.Health = &types.Health{
+ Status: inspect.State.Healthcheck.Status,
+ FailingStreak: inspect.State.Healthcheck.FailingStreak,
+ }
+
+ log := inspect.State.Healthcheck.Log
+
+ for _, item := range log {
+ res := &types.HealthcheckResult{}
+ s, _ := time.Parse(time.RFC3339Nano, item.Start)
+ e, _ := time.Parse(time.RFC3339Nano, item.End)
+ res.Start = s
+ res.End = e
+ res.ExitCode = item.ExitCode
+ res.Output = item.Output
+ state.Health.Log = append(state.Health.Log, res)
+ }
+
formatCapabilities(inspect.HostConfig.CapDrop)
formatCapabilities(inspect.HostConfig.CapAdd)
diff --git a/pkg/api/handlers/compat/exec.go b/pkg/api/handlers/compat/exec.go
index 1b7b884e0..77e62c112 100644
--- a/pkg/api/handlers/compat/exec.go
+++ b/pkg/api/handlers/compat/exec.go
@@ -178,8 +178,16 @@ func ExecStartHandler(w http.ResponseWriter, r *http.Request) {
logrus.Error(errors.Wrapf(e, "error attaching to container %s exec session %s", sessionCtr.ID(), sessionID))
}
+ var size *define.TerminalSize
+ if bodyParams.Tty && (bodyParams.Height > 0 || bodyParams.Width > 0) {
+ size = &define.TerminalSize{
+ Height: bodyParams.Height,
+ Width: bodyParams.Width,
+ }
+ }
+
hijackChan := make(chan bool, 1)
- err = sessionCtr.ExecHTTPStartAndAttach(sessionID, r, w, nil, nil, nil, hijackChan)
+ err = sessionCtr.ExecHTTPStartAndAttach(sessionID, r, w, nil, nil, nil, hijackChan, size)
if <-hijackChan {
// If connection was Hijacked, we have to signal it's being closed
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index ac212474b..7baa1145a 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -166,10 +166,11 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
query := struct {
- FromSrc string `schema:"fromSrc"`
- Changes []string `schema:"changes"`
- Message string `schema:"message"`
- Repo string `shchema:"repo"`
+ Changes []string `schema:"changes"`
+ FromSrc string `schema:"fromSrc"`
+ Message string `schema:"message"`
+ Platform string `schema:"platform"`
+ Repo string `shchema:"repo"`
}{
// This is where you can override the golang default value for one of fields
}
@@ -192,9 +193,21 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file"))
}
}
+
+ platformSpecs := strings.Split(query.Platform, "/")
+ opts := entities.ImageImportOptions{
+ Source: source,
+ Changes: query.Changes,
+ Message: query.Message,
+ Reference: query.Repo,
+ OS: platformSpecs[0],
+ }
+ if len(platformSpecs) > 1 {
+ opts.Architecture = platformSpecs[1]
+ }
+
imageEngine := abi.ImageEngine{Libpod: runtime}
- // TODO: add support for ImageImportOptions to take a platform parameter. Also import https://github.com/opencontainers/image-spec/tree/master/specs-go/v1 either here or within imageEngine.Import to get default platform
- report, err := imageEngine.Import(r.Context(), entities.ImageImportOptions{Source: source, Changes: query.Changes, Message: query.Message, Reference: query.Repo})
+ report, err := imageEngine.Import(r.Context(), opts)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to import tarball"))
return
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index 9c4dd8638..e933b9811 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -189,8 +189,8 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
var devices = []string{}
if _, found := r.URL.Query()["devices"]; found {
var m = []string{}
- if err := json.Unmarshal([]byte(query.DropCapabilities), &m); err != nil {
- utils.BadRequest(w, "devices", query.DropCapabilities, err)
+ if err := json.Unmarshal([]byte(query.Devices), &m); err != nil {
+ utils.BadRequest(w, "devices", query.Devices, err)
return
}
devices = m
diff --git a/pkg/api/handlers/compat/resize.go b/pkg/api/handlers/compat/resize.go
index f65e313fc..844fb74c4 100644
--- a/pkg/api/handlers/compat/resize.go
+++ b/pkg/api/handlers/compat/resize.go
@@ -73,7 +73,7 @@ func ResizeTTY(w http.ResponseWriter, r *http.Request) {
return
}
if err := ctnr.ExecResize(name, sz); err != nil {
- if errors.Cause(err) != define.ErrCtrStateInvalid || !query.IgnoreNotRunning {
+ if errors.Cause(err) != define.ErrExecSessionStateInvalid || !query.IgnoreNotRunning {
utils.InternalServerError(w, errors.Wrapf(err, "cannot resize session"))
return
}
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go
index e88b53a4b..04b415638 100644
--- a/pkg/api/handlers/libpod/images_pull.go
+++ b/pkg/api/handlers/libpod/images_pull.go
@@ -26,14 +26,16 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- Reference string `schema:"reference"`
- OS string `schema:"OS"`
- Arch string `schema:"Arch"`
- Variant string `schema:"Variant"`
- TLSVerify bool `schema:"tlsVerify"`
- AllTags bool `schema:"allTags"`
+ Reference string `schema:"reference"`
+ OS string `schema:"OS"`
+ Arch string `schema:"Arch"`
+ Variant string `schema:"Variant"`
+ TLSVerify bool `schema:"tlsVerify"`
+ AllTags bool `schema:"allTags"`
+ PullPolicy string `schema:"policy"`
}{
- TLSVerify: true,
+ TLSVerify: true,
+ PullPolicy: "always",
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
@@ -83,12 +85,18 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
pullOptions.Writer = writer
+ pullPolicy, err := config.ParsePullPolicy(query.PullPolicy)
+ if err != nil {
+ utils.Error(w, "failed to parse pull policy", http.StatusBadRequest, err)
+ return
+ }
+
var pulledImages []*libimage.Image
var pullError error
runCtx, cancel := context.WithCancel(r.Context())
go func() {
defer cancel()
- pulledImages, pullError = runtime.LibimageRuntime().Pull(runCtx, query.Reference, config.PullPolicyAlways, pullOptions)
+ pulledImages, pullError = runtime.LibimageRuntime().Pull(runCtx, query.Reference, pullPolicy, pullOptions)
}()
flush := func() {
diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go
index f94c9a1f5..ee157cb56 100644
--- a/pkg/api/handlers/types.go
+++ b/pkg/api/handlers/types.go
@@ -157,8 +157,10 @@ type ExecCreateResponse struct {
}
type ExecStartConfig struct {
- Detach bool `json:"Detach"`
- Tty bool `json:"Tty"`
+ Detach bool `json:"Detach"`
+ Tty bool `json:"Tty"`
+ Height uint16 `json:"h"`
+ Width uint16 `json:"w"`
}
func ImageToImageSummary(l *libimage.Image) (*entities.ImageSummary, error) {
diff --git a/pkg/api/server/register_exec.go b/pkg/api/server/register_exec.go
index 3716ef6a2..e353d714c 100644
--- a/pkg/api/server/register_exec.go
+++ b/pkg/api/server/register_exec.go
@@ -269,10 +269,16 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error {
// properties:
// Detach:
// type: boolean
- // description: Detach from the command. Not presently supported.
+ // description: Detach from the command.
// Tty:
// type: boolean
- // description: Allocate a pseudo-TTY. Presently ignored.
+ // description: Allocate a pseudo-TTY.
+ // h:
+ // type: integer
+ // description: Height of the TTY session in characters. Tty must be set to true to use it.
+ // w:
+ // type: integer
+ // description: Width of the TTY session in characters. Tty must be set to true to use it.
// produces:
// - application/json
// responses:
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index b28818768..3410c53cd 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -962,10 +962,6 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: "Mandatory reference to the image (e.g., quay.io/image/name:tag)"
// type: string
// - in: query
- // name: credentials
- // description: "username:password for the registry"
- // type: string
- // - in: query
// name: Arch
// description: Pull image for the specified architecture.
// type: string
@@ -978,6 +974,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: Pull image for the specified variant.
// type: string
// - in: query
+ // name: policy
+ // description: Pull policy, "always" (default), "missing", "newer", "never".
+ // type: string
+ // - in: query
// name: tlsVerify
// description: Require TLS verification.
// type: boolean
@@ -986,6 +986,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// name: allTags
// description: Pull all tagged images in the repository.
// type: boolean
+ // - in: header
+ // name: X-Registry-Auth
+ // description: "base-64 encoded auth config. Must include the following four values: username, password, email and server address OR simply just an identity token."
+ // type: string
// produces:
// - application/json
// responses:
diff --git a/pkg/api/server/register_volumes.go b/pkg/api/server/register_volumes.go
index e5d6cf195..d58bf0662 100644
--- a/pkg/api/server/register_volumes.go
+++ b/pkg/api/server/register_volumes.go
@@ -88,7 +88,8 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
// description: |
// JSON encoded value of filters (a map[string][]string) to match volumes against before pruning.
// Available filters:
- // - label (label=<key>, label=<key>=<value>, label!=<key>, or label!=<key>=<value>) Prune volumes with (or without, in case label!=... is used) the specified labels.
+ // - `until=<timestamp>` Prune volumes created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time.
+ // - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune volumes with (or without, in case `label!=...` is used) the specified labels.
// responses:
// '200':
// "$ref": "#/responses/VolumePruneResponse"
@@ -268,7 +269,8 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
// description: |
// JSON encoded value of filters (a map[string][]string) to match volumes against before pruning.
// Available filters:
- // - label (label=<key>, label=<key>=<value>, label!=<key>, or label!=<key>=<value>) Prune volumes with (or without, in case label!=... is used) the specified labels.
+ // - `until=<timestamp>` Prune volumes created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time.
+ // - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune volumes with (or without, in case `label!=...` is used) the specified labels.
// responses:
// '200':
// "$ref": "#/responses/DockerVolumePruneResponse"
diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go
index adef1e7c8..cc12c8ab7 100644
--- a/pkg/bindings/containers/attach.go
+++ b/pkg/bindings/containers/attach.go
@@ -343,7 +343,7 @@ func attachHandleResize(ctx, winCtx context.Context, winChange chan os.Signal, i
resizeErr = ResizeContainerTTY(ctx, id, new(ResizeTTYOptions).WithHeight(h).WithWidth(w))
}
if resizeErr != nil {
- logrus.Warnf("failed to resize TTY: %v", resizeErr)
+ logrus.Infof("failed to resize TTY: %v", resizeErr)
}
}
@@ -408,6 +408,17 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar
// If we are in TTY mode, we need to set raw mode for the terminal.
// TODO: Share all of this with Attach() for containers.
needTTY := terminalFile != nil && terminal.IsTerminal(int(terminalFile.Fd())) && isTerm
+
+ body := struct {
+ Detach bool `json:"Detach"`
+ TTY bool `json:"Tty"`
+ Height uint16 `json:"h"`
+ Width uint16 `json:"w"`
+ }{
+ Detach: false,
+ TTY: needTTY,
+ }
+
if needTTY {
state, err := setRawTerminal(terminalFile)
if err != nil {
@@ -419,13 +430,14 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar
}
logrus.SetFormatter(&logrus.TextFormatter{})
}()
+ w, h, err := terminal.GetSize(int(terminalFile.Fd()))
+ if err != nil {
+ logrus.Warnf("failed to obtain TTY size: %v", err)
+ }
+ body.Width = uint16(w)
+ body.Height = uint16(h)
}
- body := struct {
- Detach bool `json:"Detach"`
- }{
- Detach: false,
- }
bodyJSON, err := json.Marshal(body)
if err != nil {
return err
diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go
index c7d432b16..937d05330 100644
--- a/pkg/bindings/images/build.go
+++ b/pkg/bindings/images/build.go
@@ -299,6 +299,22 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
tarContent := []string{options.ContextDirectory}
newContainerFiles := []string{}
for _, c := range containerFiles {
+ if c == "/dev/stdin" {
+ content, err := ioutil.ReadAll(os.Stdin)
+ if err != nil {
+ return nil, err
+ }
+ tmpFile, err := ioutil.TempFile("", "build")
+ if err != nil {
+ return nil, err
+ }
+ defer os.Remove(tmpFile.Name()) // clean up
+ defer tmpFile.Close()
+ if _, err := tmpFile.Write(content); err != nil {
+ return nil, err
+ }
+ c = tmpFile.Name()
+ }
containerfile, err := filepath.Abs(c)
if err != nil {
logrus.Errorf("cannot find absolute path of %v: %v", c, err)
diff --git a/pkg/bindings/images/pull.go b/pkg/bindings/images/pull.go
index 9780c3bff..7dfe9560c 100644
--- a/pkg/bindings/images/pull.go
+++ b/pkg/bindings/images/pull.go
@@ -13,7 +13,7 @@ import (
"github.com/containers/podman/v3/pkg/auth"
"github.com/containers/podman/v3/pkg/bindings"
"github.com/containers/podman/v3/pkg/domain/entities"
- "github.com/hashicorp/go-multierror"
+ "github.com/containers/podman/v3/pkg/errorhandling"
"github.com/pkg/errors"
)
@@ -65,7 +65,7 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
dec := json.NewDecoder(response.Body)
var images []string
- var mErr error
+ var pullErrors []error
for {
var report entities.ImagePullReport
if err := dec.Decode(&report); err != nil {
@@ -77,7 +77,7 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
select {
case <-response.Request.Context().Done():
- return images, mErr
+ break
default:
// non-blocking select
}
@@ -86,7 +86,7 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
case report.Stream != "":
fmt.Fprint(stderr, report.Stream)
case report.Error != "":
- mErr = multierror.Append(mErr, errors.New(report.Error))
+ pullErrors = append(pullErrors, errors.New(report.Error))
case len(report.Images) > 0:
images = report.Images
case report.ID != "":
@@ -94,5 +94,5 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
return images, errors.Errorf("failed to parse pull results stream, unexpected input: %v", report)
}
}
- return images, mErr
+ return images, errorhandling.JoinErrors(pullErrors)
}
diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go
index 1f3e46729..0aa75a81e 100644
--- a/pkg/bindings/images/types.go
+++ b/pkg/bindings/images/types.go
@@ -147,6 +147,9 @@ type PullOptions struct {
// OS will overwrite the local operating system (OS) for image
// pulls.
OS *string
+ // Policy is the pull policy. Supported values are "missing", "never",
+ // "newer", "always". An empty string defaults to "always".
+ Policy *string
// Password for authenticating against the registry.
Password *string
// Quiet can be specified to suppress pull progress when pulling. Ignored
diff --git a/pkg/bindings/images/types_pull_options.go b/pkg/bindings/images/types_pull_options.go
index 0611c4447..8fcf499eb 100644
--- a/pkg/bindings/images/types_pull_options.go
+++ b/pkg/bindings/images/types_pull_options.go
@@ -84,6 +84,22 @@ func (o *PullOptions) GetOS() string {
return *o.OS
}
+// WithPolicy
+func (o *PullOptions) WithPolicy(value string) *PullOptions {
+ v := &value
+ o.Policy = v
+ return o
+}
+
+// GetPolicy
+func (o *PullOptions) GetPolicy() string {
+ var policy string
+ if o.Policy == nil {
+ return policy
+ }
+ return *o.Policy
+}
+
// WithPassword
func (o *PullOptions) WithPassword(value string) *PullOptions {
v := &value
diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go
index 911edeb5b..9cb32a364 100644
--- a/pkg/cgroups/cgroups.go
+++ b/pkg/cgroups/cgroups.go
@@ -165,14 +165,13 @@ func getAvailableControllers(exclude map[string]controllerHandler, cgroup2 bool)
if _, found := exclude[name]; found {
continue
}
- isSymLink := false
fileInfo, err := os.Stat(cgroupRoot + "/" + name)
if err != nil {
- isSymLink = !fileInfo.IsDir()
+ continue
}
c := controller{
name: name,
- symlink: isSymLink,
+ symlink: !fileInfo.IsDir(),
}
controllers = append(controllers, c)
}
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index 3cc46ed0a..3140a47c5 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -184,7 +184,7 @@ type ImagePushOptions struct {
// image to the file. Ignored for remote calls.
DigestFile string
// Format is the Manifest type (oci, v2s1, or v2s2) to use when pushing an
- // image using the 'dir' transport. Default is manifest type of source.
+ // image. Default is manifest type of source, with fallbacks.
// Ignored for remote calls.
Format string
// Quiet can be specified to suppress pull progress when pulling. Ignored
@@ -271,8 +271,10 @@ type ImageLoadReport struct {
}
type ImageImportOptions struct {
+ Architecture string
Changes []string
Message string
+ OS string
Quiet bool
Reference string
SignaturePolicy string
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index 88055454f..35f940bca 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -7,6 +7,8 @@ import (
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/specgen"
+ "github.com/containers/podman/v3/pkg/util"
+ "github.com/opencontainers/runtime-spec/specs-go"
)
type PodKillOptions struct {
@@ -116,13 +118,35 @@ type PodCreateOptions struct {
Name string
Net *NetOptions
Share []string
+ Cpus float64
+ CpusetCpus string
}
type PodCreateReport struct {
Id string //nolint
}
-func (p PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) {
+func (p *PodCreateOptions) CPULimits() *specs.LinuxCPU {
+ cpu := &specs.LinuxCPU{}
+ hasLimits := false
+
+ if p.Cpus != 0 {
+ period, quota := util.CoresToPeriodAndQuota(p.Cpus)
+ cpu.Period = &period
+ cpu.Quota = &quota
+ hasLimits = true
+ }
+ if p.CpusetCpus != "" {
+ cpu.Cpus = p.CpusetCpus
+ hasLimits = true
+ }
+ if !hasLimits {
+ return cpu
+ }
+ return cpu
+}
+
+func (p *PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) error {
// Basic Config
s.Name = p.Name
s.Hostname = p.Hostname
@@ -156,6 +180,21 @@ func (p PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) {
// Cgroup
s.CgroupParent = p.CGroupParent
+
+ // Resource config
+ cpuDat := p.CPULimits()
+ if s.ResourceLimits == nil {
+ s.ResourceLimits = &specs.LinuxResources{}
+ s.ResourceLimits.CPU = &specs.LinuxCPU{}
+ }
+ if cpuDat != nil {
+ s.ResourceLimits.CPU = cpuDat
+ if p.Cpus != 0 {
+ s.CPUPeriod = *cpuDat.Period
+ s.CPUQuota = *cpuDat.Quota
+ }
+ }
+ return nil
}
type PodPruneOptions struct {
diff --git a/pkg/domain/filters/volumes.go b/pkg/domain/filters/volumes.go
index 9a08adf82..df23c31c0 100644
--- a/pkg/domain/filters/volumes.go
+++ b/pkg/domain/filters/volumes.go
@@ -86,11 +86,22 @@ func GeneratePruneVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, erro
var vf []libpod.VolumeFilter
for filter, v := range filters {
for _, val := range v {
+ filterVal := val
switch filter {
case "label":
- filter := val
vf = append(vf, func(v *libpod.Volume) bool {
- return util.MatchLabelFilters([]string{filter}, v.Labels())
+ return util.MatchLabelFilters([]string{filterVal}, v.Labels())
+ })
+ case "until":
+ until, err := util.ComputeUntilTimestamp([]string{filterVal})
+ if err != nil {
+ return nil, err
+ }
+ vf = append(vf, func(v *libpod.Volume) bool {
+ if !until.IsZero() && v.CreatedTime().Before(until) {
+ return true
+ }
+ return false
})
default:
return nil, errors.Errorf("%q is an invalid volume filter", filter)
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 5a953c047..e6dd19e63 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -702,7 +702,9 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
reports := []*entities.ContainerStartReport{}
var exitCode = define.ExecErrorCodeGeneric
containersNamesOrIds := namesOrIds
+ all := options.All
if len(options.Filters) > 0 {
+ all = false
filterFuncs := make([]libpod.ContainerFilter, 0, len(options.Filters))
if len(options.Filters) > 0 {
for k, v := range options.Filters {
@@ -719,6 +721,10 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
}
containersNamesOrIds = []string{}
for _, candidate := range candidates {
+ if options.All {
+ containersNamesOrIds = append(containersNamesOrIds, candidate.ID())
+ continue
+ }
for _, nameOrID := range namesOrIds {
if nameOrID == candidate.ID() || nameOrID == candidate.Name() {
containersNamesOrIds = append(containersNamesOrIds, nameOrID)
@@ -726,8 +732,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
}
}
}
-
- ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, containersNamesOrIds, ic.Libpod)
+ ctrs, rawInputs, err := getContainersAndInputByContext(all, options.Latest, containersNamesOrIds, ic.Libpod)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 083566201..5992181d3 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -388,6 +388,8 @@ func (ir *ImageEngine) Import(ctx context.Context, options entities.ImageImportO
importOptions.CommitMessage = options.Message
importOptions.Tag = options.Reference
importOptions.SignaturePolicyPath = options.SignaturePolicy
+ importOptions.OS = options.OS
+ importOptions.Architecture = options.Architecture
if !options.Quiet {
importOptions.Writer = os.Stderr
diff --git a/pkg/domain/infra/abi/terminal/terminal_linux.go b/pkg/domain/infra/abi/terminal/terminal_linux.go
index ab71f8f6f..09c0f802d 100644
--- a/pkg/domain/infra/abi/terminal/terminal_linux.go
+++ b/pkg/domain/infra/abi/terminal/terminal_linux.go
@@ -15,12 +15,13 @@ import (
// ExecAttachCtr execs and attaches to a container
func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpod.ExecConfig, streams *define.AttachStreams) (int, error) {
- resize := make(chan define.TerminalSize)
+ var resize chan define.TerminalSize
haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
// Check if we are attached to a terminal. If we are, generate resize
// events, and set the terminal to raw mode
if haveTerminal && execConfig.Terminal {
+ resize = make(chan define.TerminalSize)
cancel, oldTermState, err := handleTerminalAttach(ctx, resize)
if err != nil {
return -1, err
@@ -32,7 +33,6 @@ func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpo
}
}()
}
-
return ctr.Exec(execConfig, streams, resize)
}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 74ced300a..0047fc839 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -508,7 +508,9 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
reports := []*entities.ContainerStartReport{}
var exitCode = define.ExecErrorCodeGeneric
containersNamesOrIds := namesOrIds
+ all := options.All
if len(options.Filters) > 0 {
+ all = false
containersNamesOrIds = []string{}
opts := new(containers.ListOptions).WithFilters(options.Filters).WithAll(true)
candidates, listErr := containers.List(ic.ClientCtx, opts)
@@ -516,6 +518,10 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
return nil, listErr
}
for _, candidate := range candidates {
+ if options.All {
+ containersNamesOrIds = append(containersNamesOrIds, candidate.ID)
+ continue
+ }
for _, nameOrID := range namesOrIds {
if nameOrID == candidate.ID {
containersNamesOrIds = append(containersNamesOrIds, nameOrID)
@@ -530,7 +536,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
}
}
}
- ctrs, err := getContainersByContext(ic.ClientCtx, options.All, false, containersNamesOrIds)
+ ctrs, err := getContainersByContext(ic.ClientCtx, all, false, containersNamesOrIds)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 3fd9a755d..42027a2dc 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -107,7 +107,7 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, opts entities.
options := new(images.PullOptions)
options.WithAllTags(opts.AllTags).WithAuthfile(opts.Authfile).WithArch(opts.Arch).WithOS(opts.OS)
options.WithVariant(opts.Variant).WithPassword(opts.Password)
- options.WithQuiet(opts.Quiet).WithUsername(opts.Username)
+ options.WithQuiet(opts.Quiet).WithUsername(opts.Username).WithPolicy(opts.PullPolicy.String())
if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
if s == types.OptionalBoolTrue {
options.WithSkipTLSVerify(true)
diff --git a/pkg/errorhandling/errorhandling.go b/pkg/errorhandling/errorhandling.go
index 9b1740006..6adbc9f34 100644
--- a/pkg/errorhandling/errorhandling.go
+++ b/pkg/errorhandling/errorhandling.go
@@ -15,6 +15,12 @@ func JoinErrors(errs []error) error {
return nil
}
+ // If there's just one error, return it. This prevents the "%d errors
+ // occurred:" header plus list from the multierror package.
+ if len(errs) == 1 {
+ return errs[0]
+ }
+
// `multierror` appends new lines which we need to remove to prevent
// blank lines when printing the error.
var multiE *multierror.Error
@@ -24,9 +30,6 @@ func JoinErrors(errs []error) error {
if finalErr == nil {
return finalErr
}
- if len(multiE.WrappedErrors()) == 1 && logrus.IsLevelEnabled(logrus.TraceLevel) {
- return multiE.WrappedErrors()[0]
- }
return errors.New(strings.TrimSpace(finalErr.Error()))
}
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index d00e51e82..e7276892d 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -24,7 +24,8 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
var inspectData *libimage.ImageData
var err error
if s.Image != "" {
- newImage, _, err = r.LibimageRuntime().LookupImage(s.Image, nil)
+ lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true}
+ newImage, _, err = r.LibimageRuntime().LookupImage(s.Image, lookupOptions)
if err != nil {
return nil, err
}
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index a0f5cc7e6..e2901f0b6 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -92,7 +92,8 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
options = append(options, libpod.WithRootFS(s.Rootfs))
} else {
var resolvedImageName string
- newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, nil)
+ lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true}
+ newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, lookupOptions)
if err != nil {
return nil, err
}
@@ -346,7 +347,6 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
options = append(options, libpod.WithLogDriver(s.LogConfiguration.Driver))
}
}
-
// Security options
if len(s.SelinuxOpts) > 0 {
options = append(options, libpod.WithSecLabels(s.SelinuxOpts))
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index 07c56b799..023ebb41e 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -54,6 +54,14 @@ func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime) ([]libpod
if len(p.Name) > 0 {
options = append(options, libpod.WithPodName(p.Name))
}
+ if p.ResourceLimits != nil && p.ResourceLimits.CPU != nil && p.ResourceLimits.CPU.Period != nil && p.ResourceLimits.CPU.Quota != nil {
+ if *p.ResourceLimits.CPU.Period != 0 || *p.ResourceLimits.CPU.Quota != 0 {
+ options = append(options, libpod.WithPodCPUPAQ((*p.ResourceLimits.CPU.Period), (*p.ResourceLimits.CPU.Quota)))
+ }
+ }
+ if p.ResourceLimits != nil && p.ResourceLimits.CPU != nil && p.ResourceLimits.CPU.Cpus != "" {
+ options = append(options, libpod.WithPodCPUSetCPUs(p.ResourceLimits.CPU.Cpus))
+ }
if len(p.Hostname) > 0 {
options = append(options, libpod.WithPodHostname(p.Hostname))
}
diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go
index 7d771f5bb..000a787ea 100644
--- a/pkg/specgen/podspecgen.go
+++ b/pkg/specgen/podspecgen.go
@@ -2,6 +2,8 @@ package specgen
import (
"net"
+
+ spec "github.com/opencontainers/runtime-spec/specs-go"
)
// PodBasicConfig contains basic configuration options for pods.
@@ -155,6 +157,16 @@ type PodSpecGenerator struct {
PodBasicConfig
PodNetworkConfig
PodCgroupConfig
+ PodResourceConfig
+}
+
+type PodResourceConfig struct {
+ // ResourceLimits contains linux specific CPU data for the pod
+ ResourceLimits *spec.LinuxResources `json:"resource_limits,omitempty"`
+ // CPU period of the cpuset, determined by --cpus
+ CPUPeriod uint64 `json:"cpu_period,omitempty"`
+ // CPU quota of the cpuset, determined by --cpus
+ CPUQuota int64 `json:"cpu_quota,omitempty"`
}
// NewPodSpecGenerator creates a new pod spec
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index 2815bdebb..c5cc726d7 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -470,6 +470,10 @@ type ContainerResourceConfig struct {
// that are used to configure cgroup v2.
// Optional.
CgroupConf map[string]string `json:"unified,omitempty"`
+ // CPU period of the cpuset, determined by --cpus
+ CPUPeriod uint64 `json:"cpu_period,omitempty"`
+ // CPU quota of the cpuset, determined by --cpus
+ CPUQuota int64 `json:"cpu_quota,omitempty"`
}
// ContainerHealthCheckConfig describes a container healthcheck with attributes
diff --git a/test/apiv2/30-volumes.at b/test/apiv2/30-volumes.at
index ed606134a..5feceea7b 100644
--- a/test/apiv2/30-volumes.at
+++ b/test/apiv2/30-volumes.at
@@ -125,11 +125,6 @@ t POST libpod/volumes/prune?filters='{"label":["tes' 500 \
t POST libpod/volumes/prune?filters='{"label":["testlabel"]}' 200
t GET libpod/volumes/json?filters='{"label":["testlabel"]}' 200 length=0
-## Prune volumes
-t POST libpod/volumes/prune 200
-#After prune volumes, there should be no volume existing
-t GET libpod/volumes/json 200 length=0
-
# libpod api: do not use list filters for prune
t POST libpod/volumes/prune?filters='{"name":["anyname"]}' 500 \
.cause="\"name\" is an invalid volume filter"
@@ -146,4 +141,46 @@ t POST volumes/prune?filters='{"driver":["anydriver"]}' 500 \
t POST volumes/prune?filters='{"scope":["anyscope"]}' 500 \
.cause="\"scope\" is an invalid volume filter"
+## Prune volumes using until filter
+t POST libpod/volumes/create \
+ Name=foo5 \
+ Label='{"testuntil":""}' \
+ Options='{"type":"tmpfs","o":"nodev,noexec"}}' \
+ 201 \
+ .Name=foo5 \
+ .Labels.testuntil="" \
+ .Options.type=tmpfs \
+ .Options.o=nodev,noexec
+
+# with date way back in the past, volume should not be deleted
+t POST libpod/volumes/prune?filters='{"until":["500000"]}' 200
+t GET libpod/volumes/json?filters='{"label":["testuntil"]}' 200 length=1
+
+# with date far in the future, volume should be deleted
+t POST libpod/volumes/prune?filters='{"until":["5000000000"]}' 200
+t GET libpod/volumes/json?filters='{"label":["testuntil"]}' 200 length=0
+
+t POST libpod/volumes/create \
+ Name=foo6 \
+ Label='{"testuntilcompat":""}' \
+ Options='{"type":"tmpfs","o":"nodev,noexec"}}' \
+ 201 \
+ .Name=foo6 \
+ .Labels.testuntilcompat="" \
+ .Options.type=tmpfs \
+ .Options.o=nodev,noexec
+
+# with date way back in the past, volume should not be deleted (compat api)
+t POST volumes/prune?filters='{"until":["500000"]}' 200
+t GET libpod/volumes/json?filters='{"label":["testuntilcompat"]}' 200 length=1
+
+# with date far in the future, volume should be deleted (compat api)
+t POST volumes/prune?filters='{"until":["5000000000"]}' 200
+t GET libpod/volumes/json?filters='{"label":["testuntilcompat"]}' 200 length=0
+
+## Prune volumes
+t POST libpod/volumes/prune 200
+#After prune volumes, there should be no volume existing
+t GET libpod/volumes/json 200 length=0
+
# vim: filetype=sh
diff --git a/test/apiv2/python/rest_api/test_v2_0_0_container.py b/test/apiv2/python/rest_api/test_v2_0_0_container.py
index b4b3af2df..2fab4aeb9 100644
--- a/test/apiv2/python/rest_api/test_v2_0_0_container.py
+++ b/test/apiv2/python/rest_api/test_v2_0_0_container.py
@@ -14,6 +14,13 @@ class ContainerTestCase(APITestCase):
obj = r.json()
self.assertEqual(len(obj), 1)
+ def test_list_filters(self):
+ r = requests.get(self.podman_url + "/v1.40/containers/json?filters%3D%7B%22status%22%3A%5B%22running%22%5D%7D")
+ self.assertEqual(r.status_code, 200, r.text)
+ payload = r.json()
+ containerAmnt = len(payload)
+ self.assertGreater(containerAmnt, 0)
+
def test_list_all(self):
r = requests.get(self.uri("/containers/json?all=true"))
self.assertEqual(r.status_code, 200, r.text)
@@ -25,6 +32,22 @@ class ContainerTestCase(APITestCase):
self.assertId(r.content)
_ = parse(r.json()["Created"])
+ r = requests.post(
+ self.podman_url + "/v1.40/containers/create?name=topcontainer",
+ json={"Cmd": ["top"], "Image": "alpine:latest"},
+ )
+ self.assertEqual(r.status_code, 201, r.text)
+ payload = r.json()
+ container_id = payload["Id"]
+ self.assertIsNotNone(container_id)
+
+ r = requests.get(self.podman_url + f"/v1.40/containers/{payload['Id']}/json")
+ self.assertEqual(r.status_code, 200, r.text)
+ self.assertId(r.content)
+ out = r.json()
+ state = out["State"]["Health"]
+ self.assertIsInstance(state, dict)
+
def test_stats(self):
r = requests.get(self.uri(self.resolve_container("/containers/{}/stats?stream=false")))
self.assertIn(r.status_code, (200, 409), r.text)
diff --git a/test/apiv2/python/rest_api/test_v2_0_0_image.py b/test/apiv2/python/rest_api/test_v2_0_0_image.py
index cea34e2e7..3e8ecb1ef 100644
--- a/test/apiv2/python/rest_api/test_v2_0_0_image.py
+++ b/test/apiv2/python/rest_api/test_v2_0_0_image.py
@@ -94,7 +94,8 @@ class ImageTestCase(APITestCase):
)
self.assertEqual(r.status_code, 200, r.text)
r = requests.post(
- self.podman_url + "/v1.40/images/create?fromSrc=-&repo=fedora&message=testing123",
+ self.podman_url
+ + "/v1.40/images/create?fromSrc=-&repo=fedora&message=testing123&platform=linux/amd64",
timeout=15,
)
self.assertEqual(r.status_code, 200, r.text)
diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go
index 6255690b1..abaacdd5e 100644
--- a/test/e2e/build_test.go
+++ b/test/e2e/build_test.go
@@ -604,4 +604,38 @@ RUN echo hello`, ALPINE)
Expect(inspect.OutputToString()).To(Equal("windows"))
})
+
+ It("podman build device test", func() {
+ if _, err := os.Lstat("/dev/fuse"); err != nil {
+ Skip(fmt.Sprintf("test requires stat /dev/fuse to work: %v", err))
+ }
+ containerfile := fmt.Sprintf(`FROM %s
+RUN ls /dev/fuse`, ALPINE)
+ containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile")
+ err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755)
+ Expect(err).To(BeNil())
+ session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--file", containerfilePath, podmanTest.TempDir})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(125))
+
+ session = podmanTest.Podman([]string{"build", "--pull-never", "--device", "/dev/fuse", "-t", "test", "--file", containerfilePath, podmanTest.TempDir})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ })
+
+ It("podman build device rename test", func() {
+ SkipIfRootless("rootless builds do not currently support renaming devices")
+ containerfile := fmt.Sprintf(`FROM %s
+RUN ls /dev/test1`, ALPINE)
+ containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile")
+ err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755)
+ Expect(err).To(BeNil())
+ session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--file", containerfilePath, podmanTest.TempDir})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(125))
+
+ session = podmanTest.Podman([]string{"build", "--pull-never", "--device", "/dev/zero:/dev/test1", "-t", "test", "--file", containerfilePath, podmanTest.TempDir})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ })
})
diff --git a/test/e2e/info_test.go b/test/e2e/info_test.go
index f5b70d6bf..83d185be1 100644
--- a/test/e2e/info_test.go
+++ b/test/e2e/info_test.go
@@ -101,11 +101,11 @@ var _ = Describe("Podman Info", func() {
u, err := user.Current()
Expect(err).To(BeNil())
+ // Cannot use podmanTest.Podman() and test for storage path
expect := filepath.Join("/tmp", os.Getenv("HOME"), u.Username, u.Uid, "storage")
podmanPath := podmanTest.PodmanTest.PodmanBinary
- cmd := exec.Command(podmanPath, "info", "--format", "{{.Store.GraphRoot}}")
+ cmd := exec.Command(podmanPath, "info", "--format", "{{.Store.GraphRoot -}}")
out, err := cmd.CombinedOutput()
- fmt.Println(string(out))
Expect(err).To(BeNil())
Expect(string(out)).To(Equal(expect))
})
diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go
index a70d9f13f..e437c98e6 100644
--- a/test/e2e/pod_create_test.go
+++ b/test/e2e/pod_create_test.go
@@ -5,9 +5,12 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "strconv"
"strings"
+ "github.com/containers/common/pkg/sysinfo"
"github.com/containers/podman/v3/pkg/rootless"
+ "github.com/containers/podman/v3/pkg/util"
. "github.com/containers/podman/v3/test/utils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -515,4 +518,45 @@ ENTRYPOINT ["sleep","99999"]
Expect(create.ExitCode()).To(BeZero())
})
+ It("podman pod create --cpus", func() {
+ podName := "testPod"
+ numCPU := float64(sysinfo.NumCPU())
+ period, quota := util.CoresToPeriodAndQuota(numCPU)
+ numCPUStr := strconv.Itoa(int(numCPU))
+ podCreate := podmanTest.Podman([]string{"pod", "create", "--cpus", numCPUStr, "--name", podName})
+ podCreate.WaitWithDefaultTimeout()
+ Expect(podCreate.ExitCode()).To(Equal(0))
+
+ contCreate := podmanTest.Podman([]string{"container", "create", "--pod", podName, "alpine"})
+ contCreate.WaitWithDefaultTimeout()
+ Expect(podCreate.ExitCode()).To(Equal(0))
+
+ podInspect := podmanTest.Podman([]string{"pod", "inspect", podName})
+ podInspect.WaitWithDefaultTimeout()
+ Expect(podInspect.ExitCode()).To(Equal(0))
+ podJSON := podInspect.InspectPodToJSON()
+ Expect(podJSON.CPUPeriod).To(Equal(period))
+ Expect(podJSON.CPUQuota).To(Equal(quota))
+ })
+
+ It("podman pod create --cpuset-cpus", func() {
+ podName := "testPod"
+ ctrName := "testCtr"
+ numCPU := float64(sysinfo.NumCPU())
+ numCPUStr := strconv.Itoa(int(numCPU))
+ in := "0-" + numCPUStr
+ podCreate := podmanTest.Podman([]string{"pod", "create", "--cpuset-cpus", in, "--name", podName})
+ podCreate.WaitWithDefaultTimeout()
+ Expect(podCreate.ExitCode()).To(Equal(0))
+
+ contCreate := podmanTest.Podman([]string{"container", "create", "--name", ctrName, "--pod", podName, "alpine"})
+ contCreate.WaitWithDefaultTimeout()
+ Expect(podCreate.ExitCode()).To(Equal(0))
+
+ podInspect := podmanTest.Podman([]string{"pod", "inspect", podName})
+ podInspect.WaitWithDefaultTimeout()
+ Expect(podInspect.ExitCode()).To(Equal(0))
+ podJSON := podInspect.InspectPodToJSON()
+ Expect(podJSON.CPUSetCPUs).To(Equal(in))
+ })
})
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 58538b689..e71e7a248 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -904,6 +904,18 @@ USER bin`, BB)
Expect(session.ExitCode()).To(Equal(100))
})
+ It("podman run with named volume", func() {
+ session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "stat", "-c", "%a %Y", "/var/tmp"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ perms := session.OutputToString()
+
+ session = podmanTest.Podman([]string{"run", "--rm", "-v", "test:/var/tmp", ALPINE, "stat", "-c", "%a %Y", "/var/tmp"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal(perms))
+ })
+
It("podman run with built-in volume image", func() {
session := podmanTest.Podman([]string{"run", "--rm", redis, "ls"})
session.WaitWithDefaultTimeout()
@@ -921,17 +933,6 @@ USER mail`, BB)
Expect(session.OutputToString()).To(ContainSubstring("mail root"))
})
- It("podman run with incorect VOLUME", func() {
- dockerfile := fmt.Sprintf(`FROM %s
-VOLUME ['/etc/foo']
-WORKDIR /etc/foo`, BB)
- podmanTest.BuildImage(dockerfile, "test", "false")
- session := podmanTest.Podman([]string{"run", "--rm", "test", "echo", "test"})
- session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(Equal(0))
- Expect(session.OutputToString()).To(ContainSubstring("test"))
- })
-
It("podman run --volumes-from flag", func() {
vol := filepath.Join(podmanTest.TempDir, "vol-test")
err := os.MkdirAll(vol, 0755)
diff --git a/test/e2e/stats_test.go b/test/e2e/stats_test.go
index 2218d72b5..7ab3dabc9 100644
--- a/test/e2e/stats_test.go
+++ b/test/e2e/stats_test.go
@@ -83,6 +83,17 @@ var _ = Describe("Podman stats", func() {
Expect(session.ExitCode()).To(Equal(0))
})
+ It("podman stats only output CPU data", func() {
+ session := podmanTest.RunTopContainer("")
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ session = podmanTest.Podman([]string{"stats", "--all", "--no-stream", "--format", "\"{{.ID}} {{.UpTime}} {{.AVGCPU}}\""})
+ session.WaitWithDefaultTimeout()
+ Expect(session.LineInOutputContains("UpTime")).To(BeTrue())
+ Expect(session.LineInOutputContains("AVGCPU")).To(BeTrue())
+ Expect(session.ExitCode()).To(Equal(0))
+ })
+
It("podman stats with json output", func() {
var found bool
session := podmanTest.RunTopContainer("")
diff --git a/test/e2e/system_connection_test.go b/test/e2e/system_connection_test.go
index 4697cf860..7c922a648 100644
--- a/test/e2e/system_connection_test.go
+++ b/test/e2e/system_connection_test.go
@@ -147,6 +147,12 @@ var _ = Describe("podman system connection", func() {
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.Out).Should(Say("Name *Identity *URI"))
+
+ cmd = []string{"system", "connection", "list", "--format", "{{.Name}}"}
+ session = podmanTest.Podman(cmd)
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).Should(Equal("devl* qe"))
})
It("failed default", func() {
diff --git a/test/system/010-images.bats b/test/system/010-images.bats
index 2d7ac1e0c..649987dfd 100644
--- a/test/system/010-images.bats
+++ b/test/system/010-images.bats
@@ -19,21 +19,22 @@ load helpers
@test "podman images - custom formats" {
tests="
---format {{.ID}} | [0-9a-f]\\\{12\\\}
---format {{.ID}} --no-trunc | sha256:[0-9a-f]\\\{64\\\}
---format {{.Repository}}:{{.Tag}} | $PODMAN_TEST_IMAGE_FQN
---format {{.Labels.created_by}} | test/system/build-testimage
---format {{.Labels.created_at}} | 20[0-9-]\\\+T[0-9:]\\\+Z
+{{.ID}} | [0-9a-f]\\\{12\\\}
+{{.ID| upper}} | [0-9A-F]\\\{12\\\}
+{{.Repository}}:{{.Tag}} | $PODMAN_TEST_IMAGE_FQN
+{{.Labels.created_by}} | test/system/build-testimage
+{{.Labels.created_at}} | 20[0-9-]\\\+T[0-9:]\\\+Z
"
parse_table "$tests" | while read fmt expect; do
- run_podman images $fmt
+ run_podman images --format "$fmt"
is "$output" "$expect\$" "podman images $fmt"
done
+ run_podman images --format "{{.ID}}" --no-trunc
+ is "$output" "sha256:[0-9a-f]\\{64\\}\$" "podman images --no-trunc"
}
-
@test "podman images - json" {
# 'created': podman includes fractional seconds, podman-remote does not
tests="
diff --git a/test/system/045-start.bats b/test/system/045-start.bats
index 3e0118dba..7e4bbde8d 100644
--- a/test/system/045-start.bats
+++ b/test/system/045-start.bats
@@ -59,4 +59,15 @@ load helpers
is "$output" "Error: fakepolicy invalid restart policy"
}
+@test "podman start --all --filter" {
+ run_podman run -d $IMAGE /bin/true
+ cid_exited_0="$output"
+ run_podman run -d $IMAGE /bin/false
+ cid_exited_1="$output"
+
+ run_podman wait $cid_exited_0 $cid_exited_1
+ run_podman start --all --filter exited=0
+ is "$output" "$cid_exited_0"
+}
+
# vim: filetype=sh
diff --git a/test/system/070-build.bats b/test/system/070-build.bats
index 40622d6cc..6843e28a5 100644
--- a/test/system/070-build.bats
+++ b/test/system/070-build.bats
@@ -29,6 +29,29 @@ EOF
run_podman rmi -f build_test
}
+@test "podman build test -f -" {
+ rand_filename=$(random_string 20)
+ rand_content=$(random_string 50)
+
+ tmpdir=$PODMAN_TMPDIR/build-test
+ mkdir -p $tmpdir
+ containerfile=$PODMAN_TMPDIR/Containerfile
+ cat >$containerfile <<EOF
+FROM $IMAGE
+RUN apk add nginx
+RUN echo $rand_content > /$rand_filename
+EOF
+
+ # The 'apk' command can take a long time to fetch files; bump timeout
+ PODMAN_TIMEOUT=240 run_podman build -t build_test -f - --format=docker $tmpdir < $containerfile
+ is "$output" ".*STEP 4: COMMIT" "COMMIT seen in log"
+
+ run_podman run --rm build_test cat /$rand_filename
+ is "$output" "$rand_content" "reading generated file in image"
+
+ run_podman rmi -f build_test
+}
+
@test "podman build - global runtime flags test" {
skip_if_remote "--runtime-flag flag not supported for remote"
diff --git a/test/system/255-auto-update.bats b/test/system/255-auto-update.bats
index 9bfb44791..3713243d5 100644
--- a/test/system/255-auto-update.bats
+++ b/test/system/255-auto-update.bats
@@ -194,7 +194,7 @@ function _confirm_update() {
run_podman 125 auto-update
update_log=$output
is "$update_log" ".*invalid auto-update policy.*" "invalid policy setup"
- is "$update_log" ".*1 error occurred.*" "invalid policy setup"
+ is "$update_log" ".*Error: invalid auto-update policy.*" "invalid policy setup"
local n_updated=$(grep -c 'Trying to pull' <<<"$update_log")
is "$n_updated" "2" "Number of images updated from registry."
diff --git a/test/system/450-interactive.bats b/test/system/450-interactive.bats
index a2db39492..47bdff9ab 100644
--- a/test/system/450-interactive.bats
+++ b/test/system/450-interactive.bats
@@ -57,7 +57,18 @@ function teardown() {
# ...and make sure stty under podman reads that.
run_podman run -it --name mystty $IMAGE stty size <$PODMAN_TEST_PTY
- is "$output" "$rows $cols" "stty under podman reads the correct dimensions"
+ is "$output" "$rows $cols" "stty under podman run reads the correct dimensions"
+
+ run_podman rm -f mystty
+
+ # FIXME: the checks below are flaking a lot (see #10710).
+
+ # check that the same works for podman exec
+# run_podman run -d --name mystty $IMAGE top
+# run_podman exec -it mystty stty size <$PODMAN_TEST_PTY
+# is "$output" "$rows $cols" "stty under podman exec reads the correct dimensions"
+#
+# run_podman rm -f mystty
}
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index 55ec80bb2..d55a786f7 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -162,23 +162,25 @@ load helpers
done
}
-@test "podman run with slirp4ns assigns correct gateway address to host.containers.internal" {
+@test "podman run with slirp4ns assigns correct addresses to /etc/hosts" {
CIDR="$(random_rfc1918_subnet)"
- run_podman run --network slirp4netns:cidr="${CIDR}.0/24" \
- $IMAGE grep 'host.containers.internal' /etc/hosts
- is "$output" "${CIDR}.2 host.containers.internal" "host.containers.internal should be the cidr+2 address"
+ local conname=con-$(random_string 10)
+ run_podman run --rm --network slirp4netns:cidr="${CIDR}.0/24" \
+ --name $conname --hostname $conname $IMAGE cat /etc/hosts
+ is "$output" ".*${CIDR}.2 host.containers.internal" "host.containers.internal should be the cidr+2 address"
+ is "$output" ".*${CIDR}.100 $conname $conname" "$conname should be the cidr+100 address"
}
@test "podman run with slirp4ns adds correct dns address to resolv.conf" {
CIDR="$(random_rfc1918_subnet)"
- run_podman run --network slirp4netns:cidr="${CIDR}.0/24" \
+ run_podman run --rm --network slirp4netns:cidr="${CIDR}.0/24" \
$IMAGE grep "${CIDR}" /etc/resolv.conf
is "$output" "nameserver ${CIDR}.3" "resolv.conf should have slirp4netns cidr+3 as a nameserver"
}
@test "podman run with slirp4ns assigns correct ip address container" {
CIDR="$(random_rfc1918_subnet)"
- run_podman run --network slirp4netns:cidr="${CIDR}.0/24" \
+ run_podman run --rm --network slirp4netns:cidr="${CIDR}.0/24" \
$IMAGE sh -c "ip address | grep ${CIDR}"
is "$output" ".*inet ${CIDR}.100/24 \+" "container should have slirp4netns cidr+100 assigned to interface"
}
diff --git a/utils/utils_supported.go b/utils/utils_supported.go
index ad6192255..8668e3fba 100644
--- a/utils/utils_supported.go
+++ b/utils/utils_supported.go
@@ -172,7 +172,7 @@ func moveUnderCgroup(cgroup, subtree string, processes []uint32) error {
if len(processes) > 0 {
for _, pid := range processes {
if _, err := f.Write([]byte(fmt.Sprintf("%d\n", pid))); err != nil {
- logrus.Warnf("Cannot move process %d to cgroup %q", pid, newCgroup)
+ logrus.Debugf("Cannot move process %d to cgroup %q: %v", pid, newCgroup, err)
}
}
} else {
@@ -185,7 +185,7 @@ func moveUnderCgroup(cgroup, subtree string, processes []uint32) error {
continue
}
if _, err := f.Write(pid); err != nil {
- logrus.Warnf("Cannot move process %s to cgroup %q", string(pid), newCgroup)
+ logrus.Debugf("Cannot move process %s to cgroup %q: %v", string(pid), newCgroup, err)
}
}
}
diff --git a/vendor/github.com/containers/common/libimage/download.go b/vendor/github.com/containers/common/libimage/download.go
index 5ea11f084..54edf1b9a 100644
--- a/vendor/github.com/containers/common/libimage/download.go
+++ b/vendor/github.com/containers/common/libimage/download.go
@@ -11,7 +11,7 @@ import (
)
// tmpdir returns a path to a temporary directory.
-func (r *Runtime) tmpdir() string {
+func tmpdir() string {
tmpdir := os.Getenv("TMPDIR")
if tmpdir == "" {
tmpdir = "/var/tmp"
@@ -25,7 +25,7 @@ func (r *Runtime) tmpdir() string {
func (r *Runtime) downloadFromURL(source string) (string, error) {
fmt.Printf("Downloading from %q\n", source)
- outFile, err := ioutil.TempFile(r.tmpdir(), "import")
+ outFile, err := ioutil.TempFile(r.systemContext.BigFilesTemporaryDir, "import")
if err != nil {
return "", errors.Wrap(err, "error creating file")
}
diff --git a/vendor/github.com/containers/common/libimage/image.go b/vendor/github.com/containers/common/libimage/image.go
index de0b4b2c5..f1272f507 100644
--- a/vendor/github.com/containers/common/libimage/image.go
+++ b/vendor/github.com/containers/common/libimage/image.go
@@ -61,6 +61,24 @@ func (i *Image) reload() error {
return nil
}
+// isCorrupted returns an error if the image may be corrupted.
+func (i *Image) isCorrupted(name string) error {
+ // If it's a manifest list, we're good for now.
+ if _, err := i.getManifestList(); err == nil {
+ return nil
+ }
+
+ ref, err := i.StorageReference()
+ if err != nil {
+ return err
+ }
+
+ if _, err := ref.NewImage(context.Background(), nil); err != nil {
+ return errors.Errorf("Image %s exists in local storage but may be corrupted: %v", name, err)
+ }
+ return nil
+}
+
// Names returns associated names with the image which may be a mix of tags and
// digests.
func (i *Image) Names() []string {
@@ -329,17 +347,19 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport,
// an `rmi foo` will not untag "foo" but instead attempt to remove the
// entire image. If there's a container using "foo", we should get an
// error.
- if options.Force || referencedBy == "" || numNames == 1 {
+ if referencedBy == "" || numNames == 1 {
// DO NOTHING, the image will be removed
} else {
byID := strings.HasPrefix(i.ID(), referencedBy)
byDigest := strings.HasPrefix(referencedBy, "sha256:")
- if byID && numNames > 1 {
- return errors.Errorf("unable to delete image %q by ID with more than one tag (%s): please force removal", i.ID(), i.Names())
- } else if byDigest && numNames > 1 {
- // FIXME - Docker will remove the digest but containers storage
- // does not support that yet, so our hands are tied.
- return errors.Errorf("unable to delete image %q by digest with more than one tag (%s): please force removal", i.ID(), i.Names())
+ if !options.Force {
+ if byID && numNames > 1 {
+ return errors.Errorf("unable to delete image %q by ID with more than one tag (%s): please force removal", i.ID(), i.Names())
+ } else if byDigest && numNames > 1 {
+ // FIXME - Docker will remove the digest but containers storage
+ // does not support that yet, so our hands are tied.
+ return errors.Errorf("unable to delete image %q by digest with more than one tag (%s): please force removal", i.ID(), i.Names())
+ }
}
// Only try to untag if we know it's not an ID or digest.
diff --git a/vendor/github.com/containers/common/libimage/import.go b/vendor/github.com/containers/common/libimage/import.go
index 4cce4c9ca..2addfdf98 100644
--- a/vendor/github.com/containers/common/libimage/import.go
+++ b/vendor/github.com/containers/common/libimage/import.go
@@ -23,6 +23,10 @@ type ImportOptions struct {
CommitMessage string
// Tag the imported image with this value.
Tag string
+ // Overwrite OS of imported image.
+ OS string
+ // Overwrite Arch of imported image.
+ Arch string
}
// Import imports a custom tarball at the specified path. Returns the name of
@@ -48,8 +52,10 @@ func (r *Runtime) Import(ctx context.Context, path string, options *ImportOption
}
config := v1.Image{
- Config: ic,
- History: hist,
+ Config: ic,
+ History: hist,
+ OS: options.OS,
+ Architecture: options.Arch,
}
u, err := url.ParseRequestURI(path)
diff --git a/vendor/github.com/containers/common/libimage/pull.go b/vendor/github.com/containers/common/libimage/pull.go
index acf5c818f..0a5e49fd2 100644
--- a/vendor/github.com/containers/common/libimage/pull.go
+++ b/vendor/github.com/containers/common/libimage/pull.go
@@ -105,6 +105,20 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP
r.writeEvent(&Event{ID: "", Name: name, Time: time.Now(), Type: EventTypeImagePull})
}
+ // Some callers may set the platform via the system context at creation
+ // time of the runtime. We need this information to decide whether we
+ // need to enforce pulling from a registry (see
+ // containers/podman/issues/10682).
+ if options.Architecture == "" {
+ options.Architecture = r.systemContext.ArchitectureChoice
+ }
+ if options.OS == "" {
+ options.OS = r.systemContext.OSChoice
+ }
+ if options.Variant == "" {
+ options.Variant = r.systemContext.VariantChoice
+ }
+
var (
pulledImages []string
pullError error
@@ -333,7 +347,7 @@ func (r *Runtime) copyFromRegistry(ctx context.Context, ref types.ImageReference
// from a registry. On successful pull it returns the used fully-qualified
// name that can later be used to look up the image in the local containers
// storage.
-func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName string, pullPolicy config.PullPolicy, options *PullOptions) ([]string, error) {
+func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName string, pullPolicy config.PullPolicy, options *PullOptions) ([]string, error) { //nolint:gocyclo
// Sanity check.
if err := pullPolicy.Validate(); err != nil {
return nil, err
@@ -349,9 +363,39 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str
// resolved name for pulling. Assume we're doing a `pull foo`.
// If there's already a local image "localhost/foo", then we should
// attempt pulling that instead of doing the full short-name dance.
- localImage, resolvedImageName, err = r.LookupImage(imageName, nil)
+ lookupOptions := &LookupImageOptions{
+ // NOTE: we must ignore the platform of a local image when
+ // doing lookups. Some images set an incorrect or even invalid
+ // platform (see containers/podman/issues/10682). Doing the
+ // lookup while ignoring the platform checks prevents
+ // redundantly downloading the same image.
+ IgnorePlatform: true,
+ }
+ localImage, resolvedImageName, err = r.LookupImage(imageName, lookupOptions)
if err != nil && errors.Cause(err) != storage.ErrImageUnknown {
- return nil, errors.Wrap(err, "error looking up local image")
+ logrus.Errorf("Looking up %s in local storage: %v", imageName, err)
+ }
+
+ // If the local image is corrupted, we need to repull it.
+ if localImage != nil {
+ if err := localImage.isCorrupted(imageName); err != nil {
+ logrus.Error(err)
+ localImage = nil
+ }
+ }
+
+ // Unless the pull policy is "always", we must pessimistically assume
+ // that the local image has an invalid architecture (see
+ // containers/podman/issues/10682). Hence, whenever the user requests
+ // a custom platform, set the pull policy to "always" to make sure
+ // we're pulling down the image.
+ //
+ // NOTE that this is will even override --pull={false,never}. This is
+ // very likely a bug but a consistent one in Podman/Buildah and should
+ // be addressed at a later point.
+ if pullPolicy != config.PullPolicyAlways && len(options.Architecture)+len(options.OS)+len(options.Variant) > 0 {
+ logrus.Debugf("Enforcing pull policy to %q to support custom platform (arch: %q, os: %q, variant: %q)", "always", options.Architecture, options.OS, options.Variant)
+ pullPolicy = config.PullPolicyAlways
}
if pullPolicy == config.PullPolicyNever {
diff --git a/vendor/github.com/containers/common/libimage/runtime.go b/vendor/github.com/containers/common/libimage/runtime.go
index bbf1c2a61..3cbd3dcf4 100644
--- a/vendor/github.com/containers/common/libimage/runtime.go
+++ b/vendor/github.com/containers/common/libimage/runtime.go
@@ -84,6 +84,9 @@ func RuntimeFromStore(store storage.Store, options *RuntimeOptions) (*Runtime, e
} else {
systemContext = types.SystemContext{}
}
+ if systemContext.BigFilesTemporaryDir == "" {
+ systemContext.BigFilesTemporaryDir = tmpdir()
+ }
setRegistriesConfPath(&systemContext)
@@ -132,13 +135,20 @@ func (r *Runtime) storageToImage(storageImage *storage.Image, ref types.ImageRef
}
// Exists returns true if the specicifed image exists in the local containers
-// storage.
+// storage. Note that it may return false if an image corrupted.
func (r *Runtime) Exists(name string) (bool, error) {
image, _, err := r.LookupImage(name, &LookupImageOptions{IgnorePlatform: true})
if err != nil && errors.Cause(err) != storage.ErrImageUnknown {
return false, err
}
- return image != nil, nil
+ if image == nil {
+ return false, nil
+ }
+ if err := image.isCorrupted(name); err != nil {
+ logrus.Error(err)
+ return false, nil
+ }
+ return true, nil
}
// LookupImageOptions allow for customizing local image lookups.
@@ -148,6 +158,13 @@ type LookupImageOptions struct {
// the platform does not matter, for instance, for image removal.
IgnorePlatform bool
+ // Lookup an image matching the specified architecture.
+ Architecture string
+ // Lookup an image matching the specified OS.
+ OS string
+ // Lookup an image matching the specified variant.
+ Variant string
+
// If set, do not look for items/instances in the manifest list that
// match the current platform but return the manifest list as is.
lookupManifest bool
@@ -199,6 +216,25 @@ func (r *Runtime) LookupImage(name string, options *LookupImageOptions) (*Image,
name = strings.TrimPrefix(name, "sha256:")
}
+ // Set the platform for matching local images.
+ if !options.IgnorePlatform {
+ if options.Architecture == "" {
+ options.Architecture = r.systemContext.ArchitectureChoice
+ }
+ if options.Architecture == "" {
+ options.Architecture = runtime.GOARCH
+ }
+ if options.OS == "" {
+ options.OS = r.systemContext.OSChoice
+ }
+ if options.OS == "" {
+ options.OS = runtime.GOOS
+ }
+ if options.Variant == "" {
+ options.Variant = r.systemContext.VariantChoice
+ }
+ }
+
// First, check if we have an exact match in the storage. Maybe an ID
// or a fully-qualified image name.
img, err := r.lookupImageInLocalStorage(name, name, options)
@@ -284,7 +320,7 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo
if err != nil {
return nil, err
}
- instance, err := manifestList.LookupInstance(context.Background(), "", "", "")
+ instance, err := manifestList.LookupInstance(context.Background(), options.Architecture, options.OS, options.Variant)
if err != nil {
// NOTE: If we are not looking for a specific platform
// and already found the manifest list, then return it
@@ -305,7 +341,7 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo
return image, nil
}
- matches, err := imageReferenceMatchesContext(context.Background(), ref, &r.systemContext)
+ matches, err := r.imageReferenceMatchesContext(ref, options)
if err != nil {
return nil, err
}
@@ -417,12 +453,13 @@ func (r *Runtime) ResolveName(name string) (string, error) {
}
// imageReferenceMatchesContext return true if the specified reference matches
-// the platform (os, arch, variant) as specified by the system context.
-func imageReferenceMatchesContext(ctx context.Context, ref types.ImageReference, sys *types.SystemContext) (bool, error) {
- if sys == nil {
+// the platform (os, arch, variant) as specified by the lookup options.
+func (r *Runtime) imageReferenceMatchesContext(ref types.ImageReference, options *LookupImageOptions) (bool, error) {
+ if options.IgnorePlatform {
return true, nil
}
- img, err := ref.NewImage(ctx, sys)
+ ctx := context.Background()
+ img, err := ref.NewImage(ctx, &r.systemContext)
if err != nil {
return false, err
}
@@ -431,16 +468,8 @@ func imageReferenceMatchesContext(ctx context.Context, ref types.ImageReference,
if err != nil {
return false, err
}
- osChoice := sys.OSChoice
- if osChoice == "" {
- osChoice = runtime.GOOS
- }
- arch := sys.ArchitectureChoice
- if arch == "" {
- arch = runtime.GOARCH
- }
- if osChoice == data.Os && arch == data.Architecture {
- if sys.VariantChoice == "" || sys.VariantChoice == data.Variant {
+ if options.OS == data.Os && options.Architecture == data.Architecture {
+ if options.Variant == "" || options.Variant == data.Variant {
return true, nil
}
}
diff --git a/vendor/github.com/containers/common/pkg/auth/auth.go b/vendor/github.com/containers/common/pkg/auth/auth.go
index a9ad60f43..d2e75c1f7 100644
--- a/vendor/github.com/containers/common/pkg/auth/auth.go
+++ b/vendor/github.com/containers/common/pkg/auth/auth.go
@@ -134,9 +134,13 @@ func Login(ctx context.Context, systemContext *types.SystemContext, opts *LoginO
if err = docker.CheckAuth(ctx, systemContext, username, password, server); err == nil {
// Write the new credentials to the authfile
- if err := config.SetAuthentication(systemContext, server, username, password); err != nil {
+ desc, err := config.SetCredentials(systemContext, server, username, password)
+ if err != nil {
return err
}
+ if opts.Verbose {
+ fmt.Fprintln(opts.Stdout, "Used: ", desc)
+ }
}
if err == nil {
fmt.Fprintln(opts.Stdout, "Login Succeeded!")
diff --git a/vendor/github.com/containers/common/pkg/auth/cli.go b/vendor/github.com/containers/common/pkg/auth/cli.go
index 1d8eed4ac..5a7c1137c 100644
--- a/vendor/github.com/containers/common/pkg/auth/cli.go
+++ b/vendor/github.com/containers/common/pkg/auth/cli.go
@@ -20,6 +20,7 @@ type LoginOptions struct {
Username string
StdinPassword bool
GetLoginSet bool
+ Verbose bool // set to true for verbose output
// Options caller can set
Stdin io.Reader // set to os.Stdin
Stdout io.Writer // set to os.Stdout
@@ -47,6 +48,7 @@ func GetLoginFlags(flags *LoginOptions) *pflag.FlagSet {
fs.StringVarP(&flags.Username, "username", "u", "", "Username for registry")
fs.BoolVar(&flags.StdinPassword, "password-stdin", false, "Take the password from stdin")
fs.BoolVar(&flags.GetLoginSet, "get-login", false, "Return the current login user for the registry")
+ fs.BoolVarP(&flags.Verbose, "verbose", "v", false, "Write more detailed information to stdout")
return &fs
}
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index edd52f49d..af6efbbf2 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -5,6 +5,7 @@ import (
"os"
"os/exec"
"path/filepath"
+ "sort"
"strings"
"sync"
@@ -23,7 +24,7 @@ const (
_configPath = "containers/containers.conf"
// DefaultContainersConfig holds the default containers config path
DefaultContainersConfig = "/usr/share/" + _configPath
- // OverrideContainersConfig holds the default config paths overridden by the root user
+ // OverrideContainersConfig holds the default config path overridden by the root user
OverrideContainersConfig = "/etc/" + _configPath
// UserOverrideContainersConfig holds the containers config path overridden by the rootless user
UserOverrideContainersConfig = ".config/" + _configPath
@@ -55,6 +56,8 @@ type Config struct {
Engine EngineConfig `toml:"engine"`
// Network section defines the configuration of CNI Plugins
Network NetworkConfig `toml:"network"`
+ // Secret section defines configurations for the secret management
+ Secrets SecretConfig `toml:"secrets"`
}
// ContainersConfig represents the "containers" TOML config table
@@ -137,6 +140,11 @@ type ContainersConfig struct {
// Negative values indicate that the log file won't be truncated.
LogSizeMax int64 `toml:"log_size_max,omitempty"`
+ // Specifies default format tag for container log messages.
+ // This is useful for creating a specific tag for container log messages.
+ // Containers logs default to truncated container ID as a tag.
+ LogTag string `toml:"log_tag,omitempty"`
+
// NetNS indicates how to create a network namespace for the container
NetNS string `toml:"netns,omitempty"`
@@ -440,6 +448,17 @@ type NetworkConfig struct {
NetworkConfigDir string `toml:"network_config_dir,omitempty"`
}
+// SecretConfig represents the "secret" TOML config table
+type SecretConfig struct {
+ // Driver specifies the secret driver to use.
+ // Current valid value:
+ // * file
+ // * pass
+ Driver string `toml:"driver,omitempty"`
+ // Opts contains driver specific options
+ Opts map[string]string `toml:"opts,omitempty"`
+}
+
// Destination represents destination for remote service
type Destination struct {
// URI, required. Example: ssh://root@example.com:22/run/podman/podman.sock
@@ -513,10 +532,49 @@ func readConfigFromFile(path string, config *Config) error {
return nil
}
+// addConfigs will search one level in the config dirPath for config files
+// If the dirPath does not exist, addConfigs will return nil
+func addConfigs(dirPath string, configs []string) ([]string, error) {
+ newConfigs := []string{}
+
+ err := filepath.Walk(dirPath,
+ // WalkFunc to read additional configs
+ func(path string, info os.FileInfo, err error) error {
+ switch {
+ case err != nil:
+ // return error (could be a permission problem)
+ return err
+ case info == nil:
+ // this should only happen when err != nil but let's be sure
+ return nil
+ case info.IsDir():
+ if path != dirPath {
+ // make sure to not recurse into sub-directories
+ return filepath.SkipDir
+ }
+ // ignore directories
+ return nil
+ default:
+ // only add *.conf files
+ if strings.HasSuffix(path, ".conf") {
+ newConfigs = append(newConfigs, path)
+ }
+ return nil
+ }
+ },
+ )
+ if os.IsNotExist(err) {
+ err = nil
+ }
+ sort.Strings(newConfigs)
+ return append(configs, newConfigs...), err
+}
+
// Returns the list of configuration files, if they exist in order of hierarchy.
// The files are read in order and each new file can/will override previous
// file settings.
func systemConfigs() ([]string, error) {
+ var err error
configs := []string{}
path := os.Getenv("CONTAINERS_CONF")
if path != "" {
@@ -531,7 +589,12 @@ func systemConfigs() ([]string, error) {
if _, err := os.Stat(OverrideContainersConfig); err == nil {
configs = append(configs, OverrideContainersConfig)
}
- path, err := ifRootlessConfigPath()
+ configs, err = addConfigs(OverrideContainersConfig+".d", configs)
+ if err != nil {
+ return nil, err
+ }
+
+ path, err = ifRootlessConfigPath()
if err != nil {
return nil, err
}
@@ -539,6 +602,10 @@ func systemConfigs() ([]string, error) {
if _, err := os.Stat(path); err == nil {
configs = append(configs, path)
}
+ configs, err = addConfigs(path+".d", configs)
+ if err != nil {
+ return nil, err
+ }
}
return configs, nil
}
@@ -986,7 +1053,7 @@ func (c *Config) Write() error {
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
return err
}
- configFile, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0600)
+ configFile, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644)
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf
index d9b379eae..0c8c7532e 100644
--- a/vendor/github.com/containers/common/pkg/config/containers.conf
+++ b/vendor/github.com/containers/common/pkg/config/containers.conf
@@ -16,30 +16,16 @@
[containers]
-# List of devices. Specified as
-# "<device-on-host>:<device-on-container>:<permissions>", for example:
-# "/dev/sdc:/dev/xvdc:rwm".
-# If it is empty or commented out, only the default devices will be used
-#
-# devices = []
-
-# List of volumes. Specified as
-# "<directory-on-host>:<directory-in-container>:<options>", for example:
-# "/db:/var/lib/db:ro".
-# If it is empty or commented out, no volumes will be added
+# List of annotation. Specified as
+# "key = value"
+# If it is empty or commented out, no annotations will be added
#
-# volumes = []
+# annotations = []
# Used to change the name of the default AppArmor profile of container engine.
#
# apparmor_profile = "container-default"
-# List of annotation. Specified as
-# "key=value"
-# If it is empty or commented out, no annotations will be added
-#
-# annotations = []
-
# Default way to to create a cgroup namespace for the container
# Options are:
# `private` Create private Cgroup Namespace for the container.
@@ -93,6 +79,13 @@ default_sysctls = [
# "nofile=1280:2560",
# ]
+# List of devices. Specified as
+# "<device-on-host>:<device-on-container>:<permissions>", for example:
+# "/dev/sdc:/dev/xvdc:rwm".
+# If it is empty or commented out, only the default devices will be used
+#
+# devices = []
+
# List of default DNS options to be added to /etc/resolv.conf inside of the container.
#
# dns_options = []
@@ -166,6 +159,12 @@ default_sysctls = [
#
# log_size_max = -1
+# Specifies default format tag for container log messages.
+# This is useful for creating a specific tag for container log messages.
+# Containers logs default to truncated container ID as a tag.
+#
+# log_tag = ""
+
# Default way to to create a Network namespace for the container
# Options are:
# `private` Create private Network Namespace for the container.
@@ -179,10 +178,6 @@ default_sysctls = [
#
# no_hosts = false
-# Maximum number of processes allowed in a container.
-#
-# pids_limit = 2048
-
# Default way to to create a PID namespace for the container
# Options are:
# `private` Create private PID Namespace for the container.
@@ -190,6 +185,13 @@ default_sysctls = [
#
# pidns = "private"
+# Maximum number of processes allowed in a container.
+#
+# pids_limit = 2048
+
+# Indicates the networking to be used for rootless containers
+# rootless_networking = "slirp4netns"
+
# Path to the seccomp.json profile which is used as the default seccomp profile
# for the runtime.
#
@@ -209,14 +211,7 @@ default_sysctls = [
# Set umask inside the container
#
-# umask="0022"
-
-# Default way to to create a UTS namespace for the container
-# Options are:
-# `private` Create private UTS Namespace for the container.
-# `host` Share host UTS Namespace with the container.
-#
-# utsns = "private"
+# umask = "0022"
# Default way to to create a User namespace for the container
# Options are:
@@ -229,7 +224,21 @@ default_sysctls = [
# UIDs are allocated from the "container" UIDs listed in
# /etc/subuid & /etc/subgid
#
-# userns_size=65536
+# userns_size = 65536
+
+# Default way to to create a UTS namespace for the container
+# Options are:
+# `private` Create private UTS Namespace for the container.
+# `host` Share host UTS Namespace with the container.
+#
+# utsns = "private"
+
+# List of volumes. Specified as
+# "<directory-on-host>:<directory-in-container>:<options>", for example:
+# "/db:/var/lib/db:ro".
+# If it is empty or commented out, no volumes will be added
+#
+# volumes = []
# The network table contains settings pertaining to the management of
# CNI plugins.
@@ -254,14 +263,8 @@ default_sysctls = [
# network_config_dir = "/etc/cni/net.d/"
[engine]
-# Maximum number of image layers to be copied (pulled/pushed) simultaneously.
-# Not setting this field, or setting it to zero, will fall back to containers/image defaults.
-# image_parallel_copies=0
-
-# Manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building
-# container images. By default image pulled and pushed match the format of the
-# source image. Building/committing defaults to OCI.
-# image_default_format = ""
+# Index to the active service
+# active_service = production
# Cgroup management implementation used for the runtime.
# Valid options "systemd" or "cgroupfs"
@@ -319,10 +322,19 @@ default_sysctls = [
# "/usr/share/containers/oci/hooks.d",
# ]
+# Manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building
+# container images. By default image pulled and pushed match the format of the
+# source image. Building/committing defaults to OCI.
+# image_default_format = ""
+
# Default transport method for pulling and pushing for images
#
# image_default_transport = "docker://"
+# Maximum number of image layers to be copied (pulled/pushed) simultaneously.
+# Not setting this field, or setting it to zero, will fall back to containers/image defaults.
+# image_parallel_copies = 0
+
# Default command to run the infra container
#
# infra_command = "/pause"
@@ -345,7 +357,7 @@ default_sysctls = [
# Indicates if Podman is running inside a VM via Podman Machine.
# Podman uses this value to do extra setup around networking from the
# container inside the VM to to host.
-# machine_enabled=false
+# machine_enabled = false
# MultiImageArchive - if true, the container engine allows for storing archives
# (e.g., of the docker-archive transport) with multiple images. By default,
@@ -364,12 +376,12 @@ default_sysctls = [
# Path to the slirp4netns binary
#
-# network_cmd_path=""
+# network_cmd_path = ""
# Default options to pass to the slirp4netns binary.
# For example "allow_host_loopback=true"
#
-# network_cmd_options=[]
+# network_cmd_options = []
# Whether to use chroot instead of pivot_root in the runtime
#
@@ -389,27 +401,6 @@ default_sysctls = [
# `podman --remote=true` for access to the remote Podman service.
# remote = false
-# Indicates the networking to be used for rootless containers
-# rootless_networking="slirp4netns"
-
-# Directory for persistent engine files (database, etc)
-# By default, this will be configured relative to where the containers/storage
-# stores containers
-# Uncomment to change location from this default
-#
-# static_dir = "/var/lib/containers/storage/libpod"
-
-# Directory for temporary files. Must be tmpfs (wiped after reboot)
-#
-# tmp_dir = "/run/libpod"
-
-# Directory for libpod named volumes.
-# By default, this will be configured relative to where containers/storage
-# stores containers.
-# Uncomment to change location from this default.
-#
-# volume_path = "/var/lib/containers/storage/volumes"
-
# Default OCI runtime
#
# runtime = "crun"
@@ -419,20 +410,24 @@ default_sysctls = [
#
# runtime_supports_json = ["crun", "runc", "kata", "runsc"]
+# List of the OCI runtimes that supports running containers with KVM Separation.
+#
+# runtime_supports_kvm = ["kata"]
+
# List of the OCI runtimes that supports running containers without cgroups.
#
# runtime_supports_nocgroups = ["crun"]
-# List of the OCI runtimes that supports running containers with KVM Separation.
+# Directory for persistent engine files (database, etc)
+# By default, this will be configured relative to where the containers/storage
+# stores containers
+# Uncomment to change location from this default
#
-# runtime_supports_kvm = ["kata"]
+# static_dir = "/var/lib/containers/storage/libpod"
# Number of seconds to wait for container to exit before sending kill signal.
# stop_timeout = 10
-# Index to the active service
-# active_service = production
-
# map of service destinations
# [service_destinations]
# [service_destinations.production]
@@ -442,10 +437,21 @@ default_sysctls = [
# rootfull "unix://run/podman/podman.sock (Default)
# remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock
# remote rootfull ssh://root@10.10.1.136:22/run/podman/podman.sock
-# uri="ssh://user@production.example.com/run/user/1001/podman/podman.sock"
+# uri = "ssh://user@production.example.com/run/user/1001/podman/podman.sock"
# Path to file containing ssh identity key
# identity = "~/.ssh/id_rsa"
+# Directory for temporary files. Must be tmpfs (wiped after reboot)
+#
+# tmp_dir = "/run/libpod"
+
+# Directory for libpod named volumes.
+# By default, this will be configured relative to where containers/storage
+# stores containers.
+# Uncomment to change location from this default.
+#
+# volume_path = "/var/lib/containers/storage/volumes"
+
# Paths to look for a valid OCI runtime (crun, runc, kata, runsc, etc)
[engine.runtimes]
# crun = [
@@ -458,16 +464,6 @@ default_sysctls = [
# "/run/current-system/sw/bin/crun",
# ]
-# runc = [
-# "/usr/bin/runc",
-# "/usr/sbin/runc",
-# "/usr/local/bin/runc",
-# "/usr/local/sbin/runc",
-# "/sbin/runc",
-# "/bin/runc",
-# "/usr/lib/cri-o-runc/sbin/runc",
-# ]
-
# kata = [
# "/usr/bin/kata-runtime",
# "/usr/sbin/kata-runtime",
@@ -479,6 +475,16 @@ default_sysctls = [
# "/usr/bin/kata-fc",
# ]
+# runc = [
+# "/usr/bin/runc",
+# "/usr/sbin/runc",
+# "/usr/local/bin/runc",
+# "/usr/local/sbin/runc",
+# "/sbin/runc",
+# "/bin/runc",
+# "/usr/lib/cri-o-runc/sbin/runc",
+# ]
+
# runsc = [
# "/usr/bin/runsc",
# "/usr/sbin/runsc",
@@ -497,3 +503,9 @@ default_sysctls = [
# TOML does not provide a way to end a table other than a further table being
# defined, so every key hereafter will be part of [volume_plugins] and not the
# main config.
+
+[secret]
+# driver = "file"
+
+[secret.opts]
+# root = "/example/directory"
diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go
index d5a7d5b84..5abb6326f 100644
--- a/vendor/github.com/containers/common/pkg/config/default.go
+++ b/vendor/github.com/containers/common/pkg/config/default.go
@@ -144,8 +144,6 @@ func DefaultConfig() (*Config, error) {
return nil, err
}
- netns := "bridge"
-
cniConfig := _cniConfigDir
defaultEngineConfig.SignaturePolicyPath = DefaultSignaturePolicyPath
@@ -161,7 +159,6 @@ func DefaultConfig() (*Config, error) {
defaultEngineConfig.SignaturePolicyPath = DefaultSignaturePolicyPath
}
}
- netns = "slirp4netns"
cniConfig = filepath.Join(configHome, _cniConfigDirRootless)
}
@@ -197,12 +194,10 @@ func DefaultConfig() (*Config, error) {
IPCNS: "private",
LogDriver: defaultLogDriver(),
LogSizeMax: DefaultLogSizeMax,
- NetNS: netns,
NoHosts: false,
PidsLimit: DefaultPidsLimit,
PidNS: "private",
RootlessNetworking: DefaultRootlessNetwork,
- SeccompProfile: SeccompDefaultPath,
ShmSize: DefaultShmSize,
TZ: "",
Umask: "0022",
@@ -216,10 +211,19 @@ func DefaultConfig() (*Config, error) {
NetworkConfigDir: cniConfig,
CNIPluginDirs: cniBinDir,
},
- Engine: *defaultEngineConfig,
+ Engine: *defaultEngineConfig,
+ Secrets: defaultSecretConfig(),
}, nil
}
+// defaultSecretConfig returns the default secret configuration.
+// Please note that the default is choosing the "file" driver.
+func defaultSecretConfig() SecretConfig {
+ return SecretConfig{
+ Driver: "file",
+ }
+}
+
// defaultConfigFromMemory returns a default engine configuration. Note that the
// config is different for root and rootless. It also parses the storage.conf.
func defaultConfigFromMemory() (*EngineConfig, error) {
diff --git a/vendor/github.com/containers/common/pkg/report/template.go b/vendor/github.com/containers/common/pkg/report/template.go
index f7b4506bb..f86b07034 100644
--- a/vendor/github.com/containers/common/pkg/report/template.go
+++ b/vendor/github.com/containers/common/pkg/report/template.go
@@ -130,7 +130,7 @@ func NewTemplate(name string) *Template {
func (t *Template) Parse(text string) (*Template, error) {
if strings.HasPrefix(text, "table ") {
t.isTable = true
- text = "{{range .}}" + NormalizeFormat(text) + "{{end}}"
+ text = "{{range .}}" + NormalizeFormat(text) + "{{end -}}"
} else {
text = NormalizeFormat(text)
}
@@ -157,12 +157,12 @@ func (t *Template) IsTable() bool {
return t.isTable
}
-var rangeRegex = regexp.MustCompile(`{{\s*range\s*\.\s*}}.*{{\s*end\s*}}`)
+var rangeRegex = regexp.MustCompile(`{{\s*range\s*\.\s*}}.*{{\s*end\s*-?\s*}}`)
// EnforceRange ensures that the format string contains a range
func EnforceRange(format string) string {
if !rangeRegex.MatchString(format) {
- return "{{range .}}" + format + "{{end}}"
+ return "{{range .}}" + format + "{{end -}}"
}
return format
}
diff --git a/vendor/github.com/containers/common/pkg/seccomp/conversion.go b/vendor/github.com/containers/common/pkg/seccomp/conversion.go
index dfab381a5..4c25cb1b1 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/conversion.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/conversion.go
@@ -118,6 +118,7 @@ func specToSeccomp(spec *specs.LinuxSeccomp) (*Seccomp, error) {
return nil, errors.Wrap(err, "convert default action")
}
res.DefaultAction = newDefaultAction
+ res.DefaultErrnoRet = spec.DefaultErrnoRet
// Loop through all syscall blocks and convert them to the internal format
for _, call := range spec.Syscalls {
diff --git a/vendor/github.com/containers/common/pkg/seccomp/default_linux.go b/vendor/github.com/containers/common/pkg/seccomp/default_linux.go
index f86f3e2ba..725e0bfc7 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/default_linux.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/default_linux.go
@@ -44,10 +44,47 @@ func arches() []Architecture {
// DefaultProfile defines the allowlist for the default seccomp profile.
func DefaultProfile() *Seccomp {
einval := uint(unix.EINVAL)
+ enosys := uint(unix.ENOSYS)
+ eperm := uint(unix.EPERM)
syscalls := []*Syscall{
{
Names: []string{
+ "bdflush",
+ "io_pgetevents",
+ "kexec_file_load",
+ "kexec_load",
+ "migrate_pages",
+ "move_pages",
+ "nfsservctl",
+ "nice",
+ "oldfstat",
+ "oldlstat",
+ "oldolduname",
+ "oldstat",
+ "olduname",
+ "pciconfig_iobase",
+ "pciconfig_read",
+ "pciconfig_write",
+ "sgetmask",
+ "ssetmask",
+ "swapcontext",
+ "swapoff",
+ "swapon",
+ "sysfs",
+ "uselib",
+ "userfaultfd",
+ "ustat",
+ "vm86",
+ "vm86old",
+ "vmsplice",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ },
+ {
+ Names: []string{
"_llseek",
"_newselect",
"accept",
@@ -72,6 +109,7 @@ func DefaultProfile() *Seccomp {
"clock_nanosleep",
"clock_nanosleep_time64",
"clone",
+ "clone3",
"close",
"close_range",
"connect",
@@ -128,6 +166,7 @@ func DefaultProfile() *Seccomp {
"ftruncate",
"ftruncate64",
"futex",
+ "futex_time64",
"futimesat",
"get_robust_list",
"get_thread_area",
@@ -144,6 +183,7 @@ func DefaultProfile() *Seccomp {
"getgroups",
"getgroups32",
"getitimer",
+ "get_mempolicy",
"getpeername",
"getpgid",
"getpgrp",
@@ -194,6 +234,7 @@ func DefaultProfile() *Seccomp {
"lstat",
"lstat64",
"madvise",
+ "mbind",
"memfd_create",
"mincore",
"mkdir",
@@ -212,7 +253,9 @@ func DefaultProfile() *Seccomp {
"mq_notify",
"mq_open",
"mq_timedreceive",
+ "mq_timedreceive_time64",
"mq_timedsend",
+ "mq_timedsend_time64",
"mq_unlink",
"mremap",
"msgctl",
@@ -237,6 +280,9 @@ func DefaultProfile() *Seccomp {
"pipe",
"pipe2",
"pivot_root",
+ "pkey_alloc",
+ "pkey_free",
+ "pkey_mprotect",
"poll",
"ppoll",
"ppoll_time64",
@@ -252,6 +298,7 @@ func DefaultProfile() *Seccomp {
"pwritev2",
"read",
"readahead",
+ "readdir",
"readlink",
"readlinkat",
"readv",
@@ -259,6 +306,7 @@ func DefaultProfile() *Seccomp {
"recv",
"recvfrom",
"recvmmsg",
+ "recvmmsg_time64",
"recvmsg",
"remap_file_pages",
"removexattr",
@@ -267,6 +315,7 @@ func DefaultProfile() *Seccomp {
"renameat2",
"restart_syscall",
"rmdir",
+ "rseq",
"rt_sigaction",
"rt_sigpending",
"rt_sigprocmask",
@@ -274,6 +323,7 @@ func DefaultProfile() *Seccomp {
"rt_sigreturn",
"rt_sigsuspend",
"rt_sigtimedwait",
+ "rt_sigtimedwait_time64",
"rt_tgsigqueueinfo",
"sched_get_priority_max",
"sched_get_priority_min",
@@ -282,6 +332,7 @@ func DefaultProfile() *Seccomp {
"sched_getparam",
"sched_getscheduler",
"sched_rr_get_interval",
+ "sched_rr_get_interval_time64",
"sched_setaffinity",
"sched_setattr",
"sched_setparam",
@@ -293,6 +344,7 @@ func DefaultProfile() *Seccomp {
"semget",
"semop",
"semtimedop",
+ "semtimedop_time64",
"send",
"sendfile",
"sendfile64",
@@ -300,6 +352,7 @@ func DefaultProfile() *Seccomp {
"sendmsg",
"sendto",
"setns",
+ "set_mempolicy",
"set_robust_list",
"set_thread_area",
"set_tid_address",
@@ -361,6 +414,7 @@ func DefaultProfile() *Seccomp {
"timer_gettime",
"timer_gettime64",
"timer_settime",
+ "timer_settime64",
"timerfd_create",
"timerfd_gettime",
"timerfd_gettime64",
@@ -516,6 +570,17 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "open_by_handle_at",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_DAC_READ_SEARCH"},
+ },
+ },
+ {
+ Names: []string{
"bpf",
"fanotify_init",
"lookup_dcookie",
@@ -533,6 +598,24 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "bpf",
+ "fanotify_init",
+ "lookup_dcookie",
+ "perf_event_open",
+ "quotactl",
+ "setdomainname",
+ "sethostname",
+ "setns",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_ADMIN"},
+ },
+ },
+ {
+ Names: []string{
"chroot",
},
Action: ActAllow,
@@ -543,6 +626,17 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "chroot",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_CHROOT"},
+ },
+ },
+ {
+ Names: []string{
"delete_module",
"init_module",
"finit_module",
@@ -556,14 +650,16 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
- "get_mempolicy",
- "mbind",
- "set_mempolicy",
+ "delete_module",
+ "init_module",
+ "finit_module",
+ "query_module",
},
- Action: ActAllow,
- Args: []*Arg{},
- Includes: Filter{
- Caps: []string{"CAP_SYS_NICE"},
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_MODULE"},
},
},
{
@@ -578,6 +674,17 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "acct",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_PACCT"},
+ },
+ },
+ {
+ Names: []string{
"kcmp",
"process_madvise",
"process_vm_readv",
@@ -592,6 +699,21 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "kcmp",
+ "process_madvise",
+ "process_vm_readv",
+ "process_vm_writev",
+ "ptrace",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_PTRACE"},
+ },
+ },
+ {
+ Names: []string{
"iopl",
"ioperm",
},
@@ -603,6 +725,18 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "iopl",
+ "ioperm",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_RAWIO"},
+ },
+ },
+ {
+ Names: []string{
"settimeofday",
"stime",
"clock_settime",
@@ -616,6 +750,20 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "settimeofday",
+ "stime",
+ "clock_settime",
+ "clock_settime64",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_TIME"},
+ },
+ },
+ {
+ Names: []string{
"vhangup",
},
Action: ActAllow,
@@ -626,6 +774,17 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "vhangup",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_TTY_CONFIG"},
+ },
+ },
+ {
+ Names: []string{
"socket",
},
Action: ActErrno,
@@ -706,8 +865,9 @@ func DefaultProfile() *Seccomp {
}
return &Seccomp{
- DefaultAction: ActErrno,
- ArchMap: arches(),
- Syscalls: syscalls,
+ DefaultAction: ActErrno,
+ DefaultErrnoRet: &enosys,
+ ArchMap: arches(),
+ Syscalls: syscalls,
}
}
diff --git a/vendor/github.com/containers/common/pkg/seccomp/filter.go b/vendor/github.com/containers/common/pkg/seccomp/filter.go
index ac9b2698f..90da99f0a 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/filter.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/filter.go
@@ -41,7 +41,7 @@ func BuildFilter(spec *specs.LinuxSeccomp) (*libseccomp.ScmpFilter, error) {
return nil, errors.Wrap(err, "convert spec to seccomp profile")
}
- defaultAction, err := toAction(profile.DefaultAction, nil)
+ defaultAction, err := toAction(profile.DefaultAction, profile.DefaultErrnoRet)
if err != nil {
return nil, errors.Wrapf(err, "convert default action %s", profile.DefaultAction)
}
diff --git a/vendor/github.com/containers/common/pkg/seccomp/seccomp.json b/vendor/github.com/containers/common/pkg/seccomp/seccomp.json
index 8d799fd02..eeb41d5d8 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/seccomp.json
+++ b/vendor/github.com/containers/common/pkg/seccomp/seccomp.json
@@ -1,5 +1,6 @@
{
"defaultAction": "SCMP_ACT_ERRNO",
+ "defaultErrnoRet": 38,
"archMap": [
{
"architecture": "SCMP_ARCH_X86_64",
@@ -52,6 +53,44 @@
"syscalls": [
{
"names": [
+ "bdflush",
+ "io_pgetevents",
+ "kexec_file_load",
+ "kexec_load",
+ "migrate_pages",
+ "move_pages",
+ "nfsservctl",
+ "nice",
+ "oldfstat",
+ "oldlstat",
+ "oldolduname",
+ "oldstat",
+ "olduname",
+ "pciconfig_iobase",
+ "pciconfig_read",
+ "pciconfig_write",
+ "sgetmask",
+ "ssetmask",
+ "swapcontext",
+ "swapoff",
+ "swapon",
+ "sysfs",
+ "uselib",
+ "userfaultfd",
+ "ustat",
+ "vm86",
+ "vm86old",
+ "vmsplice"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {},
+ "errnoRet": 1
+ },
+ {
+ "names": [
"_llseek",
"_newselect",
"accept",
@@ -76,6 +115,7 @@
"clock_nanosleep",
"clock_nanosleep_time64",
"clone",
+ "clone3",
"close",
"close_range",
"connect",
@@ -132,6 +172,7 @@
"ftruncate",
"ftruncate64",
"futex",
+ "futex_time64",
"futimesat",
"get_robust_list",
"get_thread_area",
@@ -148,6 +189,7 @@
"getgroups",
"getgroups32",
"getitimer",
+ "get_mempolicy",
"getpeername",
"getpgid",
"getpgrp",
@@ -198,6 +240,7 @@
"lstat",
"lstat64",
"madvise",
+ "mbind",
"memfd_create",
"mincore",
"mkdir",
@@ -216,7 +259,9 @@
"mq_notify",
"mq_open",
"mq_timedreceive",
+ "mq_timedreceive_time64",
"mq_timedsend",
+ "mq_timedsend_time64",
"mq_unlink",
"mremap",
"msgctl",
@@ -241,6 +286,9 @@
"pipe",
"pipe2",
"pivot_root",
+ "pkey_alloc",
+ "pkey_free",
+ "pkey_mprotect",
"poll",
"ppoll",
"ppoll_time64",
@@ -256,6 +304,7 @@
"pwritev2",
"read",
"readahead",
+ "readdir",
"readlink",
"readlinkat",
"readv",
@@ -263,6 +312,7 @@
"recv",
"recvfrom",
"recvmmsg",
+ "recvmmsg_time64",
"recvmsg",
"remap_file_pages",
"removexattr",
@@ -271,6 +321,7 @@
"renameat2",
"restart_syscall",
"rmdir",
+ "rseq",
"rt_sigaction",
"rt_sigpending",
"rt_sigprocmask",
@@ -278,6 +329,7 @@
"rt_sigreturn",
"rt_sigsuspend",
"rt_sigtimedwait",
+ "rt_sigtimedwait_time64",
"rt_tgsigqueueinfo",
"sched_get_priority_max",
"sched_get_priority_min",
@@ -286,6 +338,7 @@
"sched_getparam",
"sched_getscheduler",
"sched_rr_get_interval",
+ "sched_rr_get_interval_time64",
"sched_setaffinity",
"sched_setattr",
"sched_setparam",
@@ -297,6 +350,7 @@
"semget",
"semop",
"semtimedop",
+ "semtimedop_time64",
"send",
"sendfile",
"sendfile64",
@@ -304,6 +358,7 @@
"sendmsg",
"sendto",
"setns",
+ "set_mempolicy",
"set_robust_list",
"set_thread_area",
"set_tid_address",
@@ -365,6 +420,7 @@
"timer_gettime",
"timer_gettime64",
"timer_settime",
+ "timer_settime64",
"timerfd_create",
"timerfd_gettime",
"timerfd_gettime64",
@@ -582,6 +638,21 @@
},
{
"names": [
+ "open_by_handle_at"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_DAC_READ_SEARCH"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"bpf",
"fanotify_init",
"lookup_dcookie",
@@ -603,6 +674,28 @@
},
{
"names": [
+ "bpf",
+ "fanotify_init",
+ "lookup_dcookie",
+ "perf_event_open",
+ "quotactl",
+ "setdomainname",
+ "sethostname",
+ "setns"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_ADMIN"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"chroot"
],
"action": "SCMP_ACT_ALLOW",
@@ -617,6 +710,21 @@
},
{
"names": [
+ "chroot"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_CHROOT"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"delete_module",
"init_module",
"finit_module",
@@ -634,19 +742,21 @@
},
{
"names": [
- "get_mempolicy",
- "mbind",
- "set_mempolicy"
+ "delete_module",
+ "init_module",
+ "finit_module",
+ "query_module"
],
- "action": "SCMP_ACT_ALLOW",
+ "action": "SCMP_ACT_ERRNO",
"args": [],
"comment": "",
- "includes": {
+ "includes": {},
+ "excludes": {
"caps": [
- "CAP_SYS_NICE"
+ "CAP_SYS_MODULE"
]
},
- "excludes": {}
+ "errnoRet": 1
},
{
"names": [
@@ -664,6 +774,21 @@
},
{
"names": [
+ "acct"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_PACCT"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"kcmp",
"process_madvise",
"process_vm_readv",
@@ -682,6 +807,25 @@
},
{
"names": [
+ "kcmp",
+ "process_madvise",
+ "process_vm_readv",
+ "process_vm_writev",
+ "ptrace"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_PTRACE"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"iopl",
"ioperm"
],
@@ -697,6 +841,22 @@
},
{
"names": [
+ "iopl",
+ "ioperm"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_RAWIO"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"settimeofday",
"stime",
"clock_settime",
@@ -714,6 +874,24 @@
},
{
"names": [
+ "settimeofday",
+ "stime",
+ "clock_settime",
+ "clock_settime64"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_TIME"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"vhangup"
],
"action": "SCMP_ACT_ALLOW",
@@ -728,6 +906,21 @@
},
{
"names": [
+ "vhangup"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_TTY_CONFIG"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"socket"
],
"action": "SCMP_ACT_ERRNO",
diff --git a/vendor/github.com/containers/common/pkg/seccomp/seccomp_linux.go b/vendor/github.com/containers/common/pkg/seccomp/seccomp_linux.go
index 19500cc97..af36b9990 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/seccomp_linux.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/seccomp_linux.go
@@ -111,6 +111,7 @@ func setupSeccomp(config *Seccomp, rs *specs.Spec) (*specs.LinuxSeccomp, error)
}
newConfig.DefaultAction = specs.LinuxSeccompAction(config.DefaultAction)
+ newConfig.DefaultErrnoRet = config.DefaultErrnoRet
Loop:
// Loop through all syscall blocks and convert them to libcontainer format after filtering them
diff --git a/vendor/github.com/containers/common/pkg/seccomp/types.go b/vendor/github.com/containers/common/pkg/seccomp/types.go
index 7b0436dfc..36712458a 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/types.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/types.go
@@ -6,7 +6,8 @@ package seccomp
// Seccomp represents the config for a seccomp profile for syscall restriction.
type Seccomp struct {
- DefaultAction Action `json:"defaultAction"`
+ DefaultAction Action `json:"defaultAction"`
+ DefaultErrnoRet *uint `json:"defaultErrnoRet"`
// Architectures is kept to maintain backward compatibility with the old
// seccomp profile.
Architectures []Arch `json:"architectures,omitempty"`
diff --git a/vendor/github.com/containers/common/pkg/secrets/passdriver/passdriver.go b/vendor/github.com/containers/common/pkg/secrets/passdriver/passdriver.go
new file mode 100644
index 000000000..6dc00b34c
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/secrets/passdriver/passdriver.go
@@ -0,0 +1,176 @@
+package passdriver
+
+import (
+ "bytes"
+ "context"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "sort"
+ "strings"
+
+ "github.com/pkg/errors"
+)
+
+var (
+ // errNoSecretData indicates that there is not data associated with an id
+ errNoSecretData = errors.New("no secret data with ID")
+
+ // errNoSecretData indicates that there is secret data already associated with an id
+ errSecretIDExists = errors.New("secret data with ID already exists")
+
+ // errInvalidKey indicates that something about your key is wrong
+ errInvalidKey = errors.New("invalid key")
+)
+
+type driverConfig struct {
+ // Root contains the root directory where the secrets are stored
+ Root string
+ // KeyID contains the key id that will be used for encryption (i.e. user@domain.tld)
+ KeyID string
+}
+
+func (cfg *driverConfig) ParseOpts(opts map[string]string) {
+ if val, ok := opts["root"]; ok {
+ cfg.Root = val
+ cfg.findGpgID() // try to find a .gpg-id in the parent directories of Root
+ }
+ if val, ok := opts["key"]; ok {
+ cfg.KeyID = val
+ }
+}
+
+func defaultDriverConfig() *driverConfig {
+ cfg := &driverConfig{}
+
+ if home, err := os.UserHomeDir(); err == nil {
+ defaultLocations := []string{
+ filepath.Join(home, ".password-store"),
+ filepath.Join(home, ".local/share/gopass/stores/root"),
+ }
+ for _, path := range defaultLocations {
+ if stat, err := os.Stat(path); err != nil || !stat.IsDir() {
+ continue
+ }
+ cfg.Root = path
+ bs, err := ioutil.ReadFile(filepath.Join(path, ".gpg-id"))
+ if err != nil {
+ continue
+ }
+ cfg.KeyID = string(bytes.Trim(bs, "\r\n"))
+ break
+ }
+ }
+
+ return cfg
+}
+
+func (cfg *driverConfig) findGpgID() {
+ path := cfg.Root
+ for len(path) > 1 {
+ if _, err := os.Stat(filepath.Join(path, ".gpg-id")); err == nil {
+ bs, err := ioutil.ReadFile(filepath.Join(path, ".gpg-id"))
+ if err != nil {
+ continue
+ }
+ cfg.KeyID = string(bytes.Trim(bs, "\r\n"))
+ break
+ }
+ path = filepath.Dir(path)
+ }
+}
+
+// Driver is the passdriver object
+type Driver struct {
+ driverConfig
+}
+
+// NewDriver creates a new secret driver.
+func NewDriver(opts map[string]string) (*Driver, error) {
+ cfg := defaultDriverConfig()
+ cfg.ParseOpts(opts)
+
+ driver := &Driver{
+ driverConfig: *cfg,
+ }
+
+ return driver, nil
+}
+
+// List returns all secret IDs
+func (d *Driver) List() (secrets []string, err error) {
+ files, err := ioutil.ReadDir(d.Root)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to read secret directory")
+ }
+ for _, f := range files {
+ fileName := f.Name()
+ withoutSuffix := fileName[:len(fileName)-len(".gpg")]
+ secrets = append(secrets, withoutSuffix)
+ }
+ sort.Strings(secrets)
+ return secrets, nil
+}
+
+// Lookup returns the bytes associated with a secret ID
+func (d *Driver) Lookup(id string) ([]byte, error) {
+ out := &bytes.Buffer{}
+ key, err := d.getPath(id)
+ if err != nil {
+ return nil, err
+ }
+ if err := d.gpg(context.TODO(), nil, out, "--decrypt", key); err != nil {
+ return nil, errors.Wrapf(errNoSecretData, id)
+ }
+ if out.Len() == 0 {
+ return nil, errors.Wrapf(errNoSecretData, id)
+ }
+ return out.Bytes(), nil
+}
+
+// Store saves the bytes associated with an ID. An error is returned if the ID already exists
+func (d *Driver) Store(id string, data []byte) error {
+ if _, err := d.Lookup(id); err == nil {
+ return errors.Wrap(errSecretIDExists, id)
+ }
+ in := bytes.NewReader(data)
+ key, err := d.getPath(id)
+ if err != nil {
+ return err
+ }
+ return d.gpg(context.TODO(), in, nil, "--encrypt", "-r", d.KeyID, "-o", key)
+}
+
+// Delete removes the secret associated with the specified ID. An error is returned if no matching secret is found.
+func (d *Driver) Delete(id string) error {
+ key, err := d.getPath(id)
+ if err != nil {
+ return err
+ }
+ if err := os.Remove(key); err != nil {
+ return errors.Wrap(errNoSecretData, id)
+ }
+ return nil
+}
+
+func (d *Driver) gpg(ctx context.Context, in io.Reader, out io.Writer, args ...string) error {
+ cmd := exec.CommandContext(ctx, "gpg", args...)
+ cmd.Env = os.Environ()
+ cmd.Stdin = in
+ cmd.Stdout = out
+ cmd.Stderr = ioutil.Discard
+ return cmd.Run()
+}
+
+func (d *Driver) getPath(id string) (string, error) {
+ path, err := filepath.Abs(filepath.Join(d.Root, id))
+ if err != nil {
+ return "", errInvalidKey
+ }
+ if !strings.HasPrefix(path, d.Root) {
+ return "", errInvalidKey
+ }
+ return path + ".gpg", nil
+}
diff --git a/vendor/github.com/containers/common/pkg/secrets/secrets.go b/vendor/github.com/containers/common/pkg/secrets/secrets.go
index d27bb7472..2573b80e2 100644
--- a/vendor/github.com/containers/common/pkg/secrets/secrets.go
+++ b/vendor/github.com/containers/common/pkg/secrets/secrets.go
@@ -8,6 +8,7 @@ import (
"time"
"github.com/containers/common/pkg/secrets/filedriver"
+ "github.com/containers/common/pkg/secrets/passdriver"
"github.com/containers/storage/pkg/lockfile"
"github.com/containers/storage/pkg/stringid"
"github.com/pkg/errors"
@@ -271,12 +272,15 @@ func validateSecretName(name string) error {
// getDriver creates a new driver.
func getDriver(name string, opts map[string]string) (SecretsDriver, error) {
- if name == "file" {
+ switch name {
+ case "file":
if path, ok := opts["path"]; ok {
return filedriver.NewDriver(path)
} else {
return nil, errors.Wrap(errInvalidDriverOpt, "need path for filedriver")
}
+ case "pass":
+ return passdriver.NewDriver(opts)
}
return nil, errInvalidDriver
}
diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go
index ff3bf9a32..8907e21ab 100644
--- a/vendor/github.com/containers/common/version/version.go
+++ b/vendor/github.com/containers/common/version/version.go
@@ -1,4 +1,4 @@
package version
// Version is the version of the build.
-const Version = "0.39.1-dev"
+const Version = "0.40.2-dev"
diff --git a/vendor/github.com/containers/image/v5/copy/copy.go b/vendor/github.com/containers/image/v5/copy/copy.go
index ed76283f9..62f47c013 100644
--- a/vendor/github.com/containers/image/v5/copy/copy.go
+++ b/vendor/github.com/containers/image/v5/copy/copy.go
@@ -29,10 +29,10 @@ import (
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- "github.com/vbauerster/mpb/v6"
- "github.com/vbauerster/mpb/v6/decor"
- "golang.org/x/crypto/ssh/terminal"
+ "github.com/vbauerster/mpb/v7"
+ "github.com/vbauerster/mpb/v7/decor"
"golang.org/x/sync/semaphore"
+ "golang.org/x/term"
)
type digestingReader struct {
@@ -43,10 +43,6 @@ type digestingReader struct {
validationSucceeded bool
}
-// FIXME: disable early layer commits temporarily until a solid solution to
-// address #1205 has been found.
-const enableEarlyCommit = false
-
var (
// ErrDecryptParamsMissing is returned if there is missing decryption parameters
ErrDecryptParamsMissing = errors.New("Necessary DecryptParameters not present")
@@ -864,7 +860,7 @@ func (ic *imageCopier) noPendingManifestUpdates() bool {
// isTTY returns true if the io.Writer is a file and a tty.
func isTTY(w io.Writer) bool {
if f, ok := w.(*os.File); ok {
- return terminal.IsTerminal(int(f.Fd()))
+ return term.IsTerminal(int(f.Fd()))
}
return false
}
@@ -893,6 +889,18 @@ func (ic *imageCopier) copyLayers(ctx context.Context) error {
err error
}
+ // The manifest is used to extract the information whether a given
+ // layer is empty.
+ manifestBlob, manifestType, err := ic.src.Manifest(ctx)
+ if err != nil {
+ return err
+ }
+ man, err := manifest.FromBlob(manifestBlob, manifestType)
+ if err != nil {
+ return err
+ }
+ manifestLayerInfos := man.LayerInfos()
+
// copyGroup is used to determine if all layers are copied
copyGroup := sync.WaitGroup{}
@@ -925,7 +933,7 @@ func (ic *imageCopier) copyLayers(ctx context.Context) error {
logrus.Debugf("Skipping foreign layer %q copy to %s", cld.destInfo.Digest, ic.c.dest.Reference().Transport().Name())
}
} else {
- cld.destInfo, cld.diffID, cld.err = ic.copyLayer(ctx, srcLayer, toEncrypt, pool, index, srcRef)
+ cld.destInfo, cld.diffID, cld.err = ic.copyLayer(ctx, srcLayer, toEncrypt, pool, index, srcRef, manifestLayerInfos[index].EmptyLayer)
}
data[index] = cld
}
@@ -1094,8 +1102,9 @@ func (c *copier) createProgressBar(pool *mpb.Progress, info types.BlobInfo, kind
),
)
} else {
+ sstyle := mpb.SpinnerStyle(".", "..", "...", "....", "").PositionLeft()
bar = pool.Add(0,
- mpb.NewSpinnerFiller([]string{".", "..", "...", "....", ""}, mpb.SpinnerOnLeft),
+ sstyle.Build(),
mpb.BarFillerClearOnComplete(),
mpb.PrependDecorators(
decor.OnComplete(decor.Name(prefix), onComplete),
@@ -1121,7 +1130,7 @@ func (c *copier) copyConfig(ctx context.Context, src types.Image) error {
progressPool, progressCleanup := c.newProgressPool(ctx)
defer progressCleanup()
bar := c.createProgressBar(progressPool, srcInfo, "config", "done")
- destInfo, err := c.copyBlobFromStream(ctx, bytes.NewReader(configBlob), srcInfo, nil, false, true, false, bar, -1)
+ destInfo, err := c.copyBlobFromStream(ctx, bytes.NewReader(configBlob), srcInfo, nil, false, true, false, bar, -1, false)
if err != nil {
return types.BlobInfo{}, err
}
@@ -1148,7 +1157,7 @@ type diffIDResult struct {
// copyLayer copies a layer with srcInfo (with known Digest and Annotations and possibly known Size) in src to dest, perhaps (de/re/)compressing it,
// and returns a complete blobInfo of the copied layer, and a value for LayerDiffIDs if diffIDIsNeeded
// srcRef can be used as an additional hint to the destination during checking whehter a layer can be reused but srcRef can be nil.
-func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, toEncrypt bool, pool *mpb.Progress, layerIndex int, srcRef reference.Named) (types.BlobInfo, digest.Digest, error) {
+func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, toEncrypt bool, pool *mpb.Progress, layerIndex int, srcRef reference.Named, emptyLayer bool) (types.BlobInfo, digest.Digest, error) {
// If the srcInfo doesn't contain compression information, try to compute it from the
// MediaType, which was either read from a manifest by way of LayerInfos() or constructed
// by LayerInfosForCopy(), if it was supplied at all. If we succeed in copying the blob,
@@ -1195,10 +1204,9 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to
Cache: ic.c.blobInfoCache,
CanSubstitute: ic.canSubstituteBlobs,
SrcRef: srcRef,
+ EmptyLayer: emptyLayer,
}
- if enableEarlyCommit {
- options.LayerIndex = &layerIndex
- }
+ options.LayerIndex = &layerIndex
reused, blobInfo, err = dest.TryReusingBlobWithOptions(ctx, srcInfo, options)
} else {
reused, blobInfo, err = ic.c.dest.TryReusingBlob(ctx, srcInfo, ic.c.blobInfoCache, ic.canSubstituteBlobs)
@@ -1245,7 +1253,7 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to
bar := ic.c.createProgressBar(pool, srcInfo, "blob", "done")
- blobInfo, diffIDChan, err := ic.copyLayerFromStream(ctx, srcStream, types.BlobInfo{Digest: srcInfo.Digest, Size: srcBlobSize, MediaType: srcInfo.MediaType, Annotations: srcInfo.Annotations}, diffIDIsNeeded, toEncrypt, bar, layerIndex)
+ blobInfo, diffIDChan, err := ic.copyLayerFromStream(ctx, srcStream, types.BlobInfo{Digest: srcInfo.Digest, Size: srcBlobSize, MediaType: srcInfo.MediaType, Annotations: srcInfo.Annotations}, diffIDIsNeeded, toEncrypt, bar, layerIndex, emptyLayer)
if err != nil {
return types.BlobInfo{}, "", err
}
@@ -1276,7 +1284,7 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to
// perhaps (de/re/)compressing the stream,
// and returns a complete blobInfo of the copied blob and perhaps a <-chan diffIDResult if diffIDIsNeeded, to be read by the caller.
func (ic *imageCopier) copyLayerFromStream(ctx context.Context, srcStream io.Reader, srcInfo types.BlobInfo,
- diffIDIsNeeded bool, toEncrypt bool, bar *mpb.Bar, layerIndex int) (types.BlobInfo, <-chan diffIDResult, error) {
+ diffIDIsNeeded bool, toEncrypt bool, bar *mpb.Bar, layerIndex int, emptyLayer bool) (types.BlobInfo, <-chan diffIDResult, error) {
var getDiffIDRecorder func(compression.DecompressorFunc) io.Writer // = nil
var diffIDChan chan diffIDResult
@@ -1301,7 +1309,7 @@ func (ic *imageCopier) copyLayerFromStream(ctx context.Context, srcStream io.Rea
}
}
- blobInfo, err := ic.c.copyBlobFromStream(ctx, srcStream, srcInfo, getDiffIDRecorder, ic.canModifyManifest, false, toEncrypt, bar, layerIndex) // Sets err to nil on success
+ blobInfo, err := ic.c.copyBlobFromStream(ctx, srcStream, srcInfo, getDiffIDRecorder, ic.canModifyManifest, false, toEncrypt, bar, layerIndex, emptyLayer) // Sets err to nil on success
return blobInfo, diffIDChan, err
// We need the defer … pipeWriter.CloseWithError() to happen HERE so that the caller can block on reading from diffIDChan
}
@@ -1353,7 +1361,7 @@ func (r errorAnnotationReader) Read(b []byte) (n int, err error) {
// and returns a complete blobInfo of the copied blob.
func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, srcInfo types.BlobInfo,
getOriginalLayerCopyWriter func(decompressor compression.DecompressorFunc) io.Writer,
- canModifyBlob bool, isConfig bool, toEncrypt bool, bar *mpb.Bar, layerIndex int) (types.BlobInfo, error) {
+ canModifyBlob bool, isConfig bool, toEncrypt bool, bar *mpb.Bar, layerIndex int, emptyLayer bool) (types.BlobInfo, error) {
if isConfig { // This is guaranteed by the caller, but set it here to be explicit.
canModifyBlob = false
}
@@ -1556,10 +1564,11 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr
dest, ok := c.dest.(internalTypes.ImageDestinationWithOptions)
if ok {
options := internalTypes.PutBlobOptions{
- Cache: c.blobInfoCache,
- IsConfig: isConfig,
+ Cache: c.blobInfoCache,
+ IsConfig: isConfig,
+ EmptyLayer: emptyLayer,
}
- if !isConfig && enableEarlyCommit {
+ if !isConfig {
options.LayerIndex = &layerIndex
}
uploadedInfo, err = dest.PutBlobWithOptions(ctx, &errorAnnotationReader{destStream}, inputInfo, options)
diff --git a/vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go b/vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go
index 3e81e06c0..3bda6af29 100644
--- a/vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go
+++ b/vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go
@@ -9,7 +9,7 @@ package platform
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
-// http://www.apache.org/licenses/LICENSE-2.0
+// https://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/vendor/github.com/containers/image/v5/internal/types/types.go b/vendor/github.com/containers/image/v5/internal/types/types.go
index bf89a69b8..4a863ba34 100644
--- a/vendor/github.com/containers/image/v5/internal/types/types.go
+++ b/vendor/github.com/containers/image/v5/internal/types/types.go
@@ -39,6 +39,8 @@ type PutBlobOptions struct {
Cache publicTypes.BlobInfoCache
// Denotes whether the blob is a config or not.
IsConfig bool
+ // Indicates an empty layer.
+ EmptyLayer bool
// The corresponding index in the layer slice.
LayerIndex *int
}
@@ -49,6 +51,8 @@ type TryReusingBlobOptions struct {
Cache publicTypes.BlobInfoCache
// Use an equivalent of the desired blob.
CanSubstitute bool
+ // Indicates an empty layer.
+ EmptyLayer bool
// The corresponding index in the layer slice.
LayerIndex *int
// The reference of the image that contains the target blob.
diff --git a/vendor/github.com/containers/image/v5/pkg/docker/config/config.go b/vendor/github.com/containers/image/v5/pkg/docker/config/config.go
index b84aac6e4..ec7c2fcc3 100644
--- a/vendor/github.com/containers/image/v5/pkg/docker/config/config.go
+++ b/vendor/github.com/containers/image/v5/pkg/docker/config/config.go
@@ -51,21 +51,26 @@ var (
ErrNotSupported = errors.New("not supported")
)
-// SetAuthentication stores the username and password in the credential helper or file
-func SetAuthentication(sys *types.SystemContext, registry, username, password string) error {
+// SetCredentials stores the username and password in the credential helper or file
+// and returns path to file or helper name in format (helper:%s).
+// Returns a human-redable description of the location that was updated.
+// NOTE: The return value is only intended to be read by humans; its form is not an API,
+// it may change (or new forms can be added) any time.
+func SetCredentials(sys *types.SystemContext, registry, username, password string) (string, error) {
helpers, err := sysregistriesv2.CredentialHelpers(sys)
if err != nil {
- return err
+ return "", err
}
// Make sure to collect all errors.
var multiErr error
for _, helper := range helpers {
+ var desc string
var err error
switch helper {
// Special-case the built-in helpers for auth files.
case sysregistriesv2.AuthenticationFileHelper:
- err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
+ desc, err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
if ch, exists := auths.CredHelpers[registry]; exists {
return false, setAuthToCredHelper(ch, registry, username, password)
}
@@ -76,6 +81,7 @@ func SetAuthentication(sys *types.SystemContext, registry, username, password st
})
// External helpers.
default:
+ desc = fmt.Sprintf("credential helper: %s", helper)
err = setAuthToCredHelper(helper, registry, username, password)
}
if err != nil {
@@ -84,9 +90,15 @@ func SetAuthentication(sys *types.SystemContext, registry, username, password st
continue
}
logrus.Debugf("Stored credentials for %s in credential helper %s", registry, helper)
- return nil
+ return desc, nil
}
- return multiErr
+ return "", multiErr
+}
+
+// SetAuthentication stores the username and password in the credential helper or file
+func SetAuthentication(sys *types.SystemContext, registry, username, password string) error {
+ _, err := SetCredentials(sys, registry, username, password)
+ return err
}
// GetAllCredentials returns the registry credentials for all registries stored
@@ -322,7 +334,7 @@ func RemoveAuthentication(sys *types.SystemContext, registry string) error {
switch helper {
// Special-case the built-in helper for auth files.
case sysregistriesv2.AuthenticationFileHelper:
- err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
+ _, err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
if innerHelper, exists := auths.CredHelpers[registry]; exists {
removeFromCredHelper(innerHelper)
}
@@ -368,7 +380,7 @@ func RemoveAllAuthentication(sys *types.SystemContext) error {
switch helper {
// Special-case the built-in helper for auth files.
case sysregistriesv2.AuthenticationFileHelper:
- err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
+ _, err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
for registry, helper := range auths.CredHelpers {
// Helpers in auth files are expected
// to exist, so no special treatment
@@ -493,42 +505,44 @@ func readJSONFile(path string, legacyFormat bool) (dockerConfigFile, error) {
return auths, nil
}
-// modifyJSON writes to auth.json if the dockerConfigFile has been updated
-func modifyJSON(sys *types.SystemContext, editor func(auths *dockerConfigFile) (bool, error)) error {
+// modifyJSON finds an auth.json file, calls editor on the contents, and
+// writes it back if editor returns true.
+// Returns a human-redable description of the file, to be returned by SetCredentials.
+func modifyJSON(sys *types.SystemContext, editor func(auths *dockerConfigFile) (bool, error)) (string, error) {
path, legacyFormat, err := getPathToAuth(sys)
if err != nil {
- return err
+ return "", err
}
if legacyFormat {
- return fmt.Errorf("writes to %s using legacy format are not supported", path)
+ return "", fmt.Errorf("writes to %s using legacy format are not supported", path)
}
dir := filepath.Dir(path)
if err = os.MkdirAll(dir, 0700); err != nil {
- return err
+ return "", err
}
auths, err := readJSONFile(path, false)
if err != nil {
- return errors.Wrapf(err, "error reading JSON file %q", path)
+ return "", errors.Wrapf(err, "error reading JSON file %q", path)
}
updated, err := editor(&auths)
if err != nil {
- return errors.Wrapf(err, "error updating %q", path)
+ return "", errors.Wrapf(err, "error updating %q", path)
}
if updated {
newData, err := json.MarshalIndent(auths, "", "\t")
if err != nil {
- return errors.Wrapf(err, "error marshaling JSON %q", path)
+ return "", errors.Wrapf(err, "error marshaling JSON %q", path)
}
if err = ioutil.WriteFile(path, newData, 0600); err != nil {
- return errors.Wrapf(err, "error writing to file %q", path)
+ return "", errors.Wrapf(err, "error writing to file %q", path)
}
}
- return nil
+ return path, nil
}
func getAuthFromCredHelper(credHelper, registry string) (types.DockerAuthConfig, error) {
diff --git a/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go b/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go
index 5bbfb450f..93c75b944 100644
--- a/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go
+++ b/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go
@@ -13,9 +13,9 @@ import (
// reenable keyring support, we should introduce a similar built-in credential
// helpers as for `sysregistriesv2.AuthenticationFileHelper`.
-const keyDescribePrefix = "container-registry-login:" // nolint
+const keyDescribePrefix = "container-registry-login:" //nolint:deadcode,unused
-func getAuthFromKernelKeyring(registry string) (string, string, error) { // nolint
+func getAuthFromKernelKeyring(registry string) (string, string, error) { //nolint:deadcode,unused
userkeyring, err := keyctl.UserKeyring()
if err != nil {
return "", "", err
@@ -35,7 +35,7 @@ func getAuthFromKernelKeyring(registry string) (string, string, error) { // noli
return parts[0], parts[1], nil
}
-func deleteAuthFromKernelKeyring(registry string) error { // nolint
+func deleteAuthFromKernelKeyring(registry string) error { //nolint:deadcode,unused
userkeyring, err := keyctl.UserKeyring()
if err != nil {
@@ -48,7 +48,7 @@ func deleteAuthFromKernelKeyring(registry string) error { // nolint
return key.Unlink()
}
-func removeAllAuthFromKernelKeyring() error { // nolint
+func removeAllAuthFromKernelKeyring() error { //nolint:deadcode,unused
keys, err := keyctl.ReadUserKeyring()
if err != nil {
return err
@@ -81,7 +81,7 @@ func removeAllAuthFromKernelKeyring() error { // nolint
return nil
}
-func setAuthToKernelKeyring(registry, username, password string) error { // nolint
+func setAuthToKernelKeyring(registry, username, password string) error { //nolint:deadcode,unused
keyring, err := keyctl.SessionKeyring()
if err != nil {
return err
@@ -114,6 +114,6 @@ func setAuthToKernelKeyring(registry, username, password string) error { // noli
return nil
}
-func genDescription(registry string) string { // nolint
+func genDescription(registry string) string { //nolint:deadcode,unused
return fmt.Sprintf("%s%s", keyDescribePrefix, registry)
}
diff --git a/vendor/github.com/containers/image/v5/pkg/docker/config/config_unsupported.go b/vendor/github.com/containers/image/v5/pkg/docker/config/config_unsupported.go
index 9b0e8bee2..65e580410 100644
--- a/vendor/github.com/containers/image/v5/pkg/docker/config/config_unsupported.go
+++ b/vendor/github.com/containers/image/v5/pkg/docker/config/config_unsupported.go
@@ -3,18 +3,18 @@
package config
-func getAuthFromKernelKeyring(registry string) (string, string, error) {
+func getAuthFromKernelKeyring(registry string) (string, string, error) { //nolint:deadcode,unused
return "", "", ErrNotSupported
}
-func deleteAuthFromKernelKeyring(registry string) error {
+func deleteAuthFromKernelKeyring(registry string) error { //nolint:deadcode,unused
return ErrNotSupported
}
-func setAuthToKernelKeyring(registry, username, password string) error {
+func setAuthToKernelKeyring(registry, username, password string) error { //nolint:deadcode,unused
return ErrNotSupported
}
-func removeAllAuthFromKernelKeyring() error {
+func removeAllAuthFromKernelKeyring() error { //nolint:deadcode,unused
return ErrNotSupported
}
diff --git a/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go b/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go
index b64f44674..ab1eee8f3 100644
--- a/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go
+++ b/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go
@@ -11,7 +11,7 @@ import (
"github.com/manifoldco/promptui"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
// IsShortName returns true if the specified input is a "short name". A "short
@@ -343,7 +343,7 @@ func Resolve(ctx *types.SystemContext, name string) (*Resolved, error) {
}
// If we don't have a TTY, act according to the mode.
- if !terminal.IsTerminal(int(os.Stdout.Fd())) || !terminal.IsTerminal(int(os.Stdin.Fd())) {
+ if !term.IsTerminal(int(os.Stdout.Fd())) || !term.IsTerminal(int(os.Stdin.Fd())) {
switch mode {
case types.ShortNameModePermissive:
// Permissive falls back to using all candidates.
diff --git a/vendor/github.com/containers/image/v5/storage/storage_image.go b/vendor/github.com/containers/image/v5/storage/storage_image.go
index f4747357c..7072d6860 100644
--- a/vendor/github.com/containers/image/v5/storage/storage_image.go
+++ b/vendor/github.com/containers/image/v5/storage/storage_image.go
@@ -76,12 +76,12 @@ type storageImageDestination struct {
indexToStorageID map[int]*string
// All accesses to below data are protected by `lock` which is made
// *explicit* in the code.
- blobDiffIDs map[digest.Digest]digest.Digest // Mapping from layer blobsums to their corresponding DiffIDs
- fileSizes map[digest.Digest]int64 // Mapping from layer blobsums to their sizes
- filenames map[digest.Digest]string // Mapping from layer blobsums to names of files we used to hold them
- currentIndex int // The index of the layer to be committed (i.e., lower indices have already been committed)
- indexToPulledBlob map[int]*types.BlobInfo // Mapping from layer (by index) to pulled down blob
- blobAdditionalLayer map[digest.Digest]storage.AdditionalLayer // Mapping from layer blobsums to their corresponding additional layer
+ blobDiffIDs map[digest.Digest]digest.Digest // Mapping from layer blobsums to their corresponding DiffIDs
+ fileSizes map[digest.Digest]int64 // Mapping from layer blobsums to their sizes
+ filenames map[digest.Digest]string // Mapping from layer blobsums to names of files we used to hold them
+ currentIndex int // The index of the layer to be committed (i.e., lower indices have already been committed)
+ indexToPulledLayerInfo map[int]*manifest.LayerInfo // Mapping from layer (by index) to pulled down blob
+ blobAdditionalLayer map[digest.Digest]storage.AdditionalLayer // Mapping from layer blobsums to their corresponding additional layer
}
type storageImageCloser struct {
@@ -392,17 +392,17 @@ func newImageDestination(sys *types.SystemContext, imageRef storageReference) (*
return nil, errors.Wrapf(err, "error creating a temporary directory")
}
image := &storageImageDestination{
- imageRef: imageRef,
- directory: directory,
- signatureses: make(map[digest.Digest][]byte),
- blobDiffIDs: make(map[digest.Digest]digest.Digest),
- blobAdditionalLayer: make(map[digest.Digest]storage.AdditionalLayer),
- fileSizes: make(map[digest.Digest]int64),
- filenames: make(map[digest.Digest]string),
- SignatureSizes: []int{},
- SignaturesSizes: make(map[digest.Digest][]int),
- indexToStorageID: make(map[int]*string),
- indexToPulledBlob: make(map[int]*types.BlobInfo),
+ imageRef: imageRef,
+ directory: directory,
+ signatureses: make(map[digest.Digest][]byte),
+ blobDiffIDs: make(map[digest.Digest]digest.Digest),
+ blobAdditionalLayer: make(map[digest.Digest]storage.AdditionalLayer),
+ fileSizes: make(map[digest.Digest]int64),
+ filenames: make(map[digest.Digest]string),
+ SignatureSizes: []int{},
+ SignaturesSizes: make(map[digest.Digest][]int),
+ indexToStorageID: make(map[int]*string),
+ indexToPulledLayerInfo: make(map[int]*manifest.LayerInfo),
}
return image, nil
}
@@ -449,7 +449,7 @@ func (s *storageImageDestination) PutBlobWithOptions(ctx context.Context, stream
return info, nil
}
- return info, s.queueOrCommit(ctx, info, *options.LayerIndex)
+ return info, s.queueOrCommit(ctx, info, *options.LayerIndex, options.EmptyLayer)
}
// HasThreadSafePutBlob indicates whether PutBlob can be executed concurrently.
@@ -542,7 +542,7 @@ func (s *storageImageDestination) TryReusingBlobWithOptions(ctx context.Context,
return reused, info, err
}
- return reused, info, s.queueOrCommit(ctx, info, *options.LayerIndex)
+ return reused, info, s.queueOrCommit(ctx, info, *options.LayerIndex, options.EmptyLayer)
}
// tryReusingBlobWithSrcRef is a wrapper around TryReusingBlob.
@@ -731,7 +731,7 @@ func (s *storageImageDestination) getConfigBlob(info types.BlobInfo) ([]byte, er
// queueOrCommit queues in the specified blob to be committed to the storage.
// If no other goroutine is already committing layers, the layer and all
// subsequent layers (if already queued) will be committed to the storage.
-func (s *storageImageDestination) queueOrCommit(ctx context.Context, blob types.BlobInfo, index int) error {
+func (s *storageImageDestination) queueOrCommit(ctx context.Context, blob types.BlobInfo, index int, emptyLayer bool) error {
// NOTE: whenever the code below is touched, make sure that all code
// paths unlock the lock and to unlock it exactly once.
//
@@ -751,7 +751,10 @@ func (s *storageImageDestination) queueOrCommit(ctx context.Context, blob types.
// caller is the "worker" routine comitting layers. All other routines
// can continue pulling and queuing in layers.
s.lock.Lock()
- s.indexToPulledBlob[index] = &blob
+ s.indexToPulledLayerInfo[index] = &manifest.LayerInfo{
+ BlobInfo: blob,
+ EmptyLayer: emptyLayer,
+ }
// We're still waiting for at least one previous/parent layer to be
// committed, so there's nothing to do.
@@ -760,14 +763,10 @@ func (s *storageImageDestination) queueOrCommit(ctx context.Context, blob types.
return nil
}
- for info := s.indexToPulledBlob[index]; info != nil; info = s.indexToPulledBlob[index] {
+ for info := s.indexToPulledLayerInfo[index]; info != nil; info = s.indexToPulledLayerInfo[index] {
s.lock.Unlock()
- layerInfo := manifest.LayerInfo{
- BlobInfo: *info,
- EmptyLayer: info.Digest == image.GzippedEmptyLayerDigest,
- }
// Note: commitLayer locks on-demand.
- if err := s.commitLayer(ctx, layerInfo, index); err != nil {
+ if err := s.commitLayer(ctx, *info, index); err != nil {
return err
}
s.lock.Lock()
@@ -1034,25 +1033,6 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
return errors.Wrapf(err, "error saving big data %q for image %q", blob.String(), img.ID)
}
}
- // Set the reference's name on the image. We don't need to worry about avoiding duplicate
- // values because SetNames() will deduplicate the list that we pass to it.
- if name := s.imageRef.DockerReference(); len(oldNames) > 0 || name != nil {
- names := []string{}
- if name != nil {
- names = append(names, name.String())
- }
- if len(oldNames) > 0 {
- names = append(names, oldNames...)
- }
- if err := s.imageRef.transport.store.SetNames(img.ID, names); err != nil {
- if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil {
- logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2)
- }
- logrus.Debugf("error setting names %v on image %q: %v", names, img.ID, err)
- return errors.Wrapf(err, "error setting names %v on image %q", names, img.ID)
- }
- logrus.Debugf("set names of image %q to %v", img.ID, names)
- }
// Save the unparsedToplevel's manifest.
if len(toplevelManifest) != 0 {
manifestDigest, err := manifest.Digest(toplevelManifest)
@@ -1130,6 +1110,25 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
}
logrus.Debugf("saved image metadata %q", string(metadata))
}
+ // Set the reference's name on the image. We don't need to worry about avoiding duplicate
+ // values because SetNames() will deduplicate the list that we pass to it.
+ if name := s.imageRef.DockerReference(); len(oldNames) > 0 || name != nil {
+ names := []string{}
+ if name != nil {
+ names = append(names, name.String())
+ }
+ if len(oldNames) > 0 {
+ names = append(names, oldNames...)
+ }
+ if err := s.imageRef.transport.store.SetNames(img.ID, names); err != nil {
+ if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil {
+ logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2)
+ }
+ logrus.Debugf("error setting names %v on image %q: %v", names, img.ID, err)
+ return errors.Wrapf(err, "error setting names %v on image %q", names, img.ID)
+ }
+ logrus.Debugf("set names of image %q to %v", img.ID, names)
+ }
return nil
}
diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go
index 4afb3b90b..edf4681de 100644
--- a/vendor/github.com/containers/image/v5/version/version.go
+++ b/vendor/github.com/containers/image/v5/version/version.go
@@ -6,9 +6,9 @@ const (
// VersionMajor is for an API incompatible changes
VersionMajor = 5
// VersionMinor is for functionality in a backwards-compatible manner
- VersionMinor = 12
+ VersionMinor = 13
// VersionPatch is for backwards-compatible bug fixes
- VersionPatch = 0
+ VersionPatch = 2
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = ""
diff --git a/vendor/github.com/containers/storage/.cirrus.yml b/vendor/github.com/containers/storage/.cirrus.yml
index 96714c2fc..12f6f10c6 100644
--- a/vendor/github.com/containers/storage/.cirrus.yml
+++ b/vendor/github.com/containers/storage/.cirrus.yml
@@ -143,7 +143,7 @@ lint_task:
meta_task:
container:
- image: "quay.io/libpod/imgts:master"
+ image: "quay.io/libpod/imgts:${_BUILT_IMAGE_SUFFIX}"
cpu: 1
memory: 1
diff --git a/vendor/github.com/containers/storage/CODE-OF-CONDUCT.md b/vendor/github.com/containers/storage/CODE-OF-CONDUCT.md
index be0791620..f4f7df4b8 100644
--- a/vendor/github.com/containers/storage/CODE-OF-CONDUCT.md
+++ b/vendor/github.com/containers/storage/CODE-OF-CONDUCT.md
@@ -1,3 +1,3 @@
## The Containers Storage Project Community Code of Conduct
-The Containers Storage project follows the [Containers Community Code of Conduct](https://github.com/containers/common/blob/master/CODE-OF-CONDUCT.md).
+The Containers Storage project follows the [Containers Community Code of Conduct](https://github.com/containers/common/blob/main/CODE-OF-CONDUCT.md).
diff --git a/vendor/github.com/containers/storage/SECURITY.md b/vendor/github.com/containers/storage/SECURITY.md
index 1496a4c00..ab2c14182 100644
--- a/vendor/github.com/containers/storage/SECURITY.md
+++ b/vendor/github.com/containers/storage/SECURITY.md
@@ -1,3 +1,3 @@
## Security and Disclosure Information Policy for the Containers Storage Project
-The Containers Storage Project follows the [Security and Disclosure Information Policy](https://github.com/containers/common/blob/master/SECURITY.md) for the Containers Projects.
+The Containers Storage Project follows the [Security and Disclosure Information Policy](https://github.com/containers/common/blob/main/SECURITY.md) for the Containers Projects.
diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION
index c78d39b8e..00b225209 100644
--- a/vendor/github.com/containers/storage/VERSION
+++ b/vendor/github.com/containers/storage/VERSION
@@ -1 +1 @@
-1.32.2
+1.32.3
diff --git a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
index 19fb3fda9..c5168bfdd 100644
--- a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
+++ b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
@@ -2229,7 +2229,7 @@ func (devices *DeviceSet) cancelDeferredRemovalIfNeeded(info *devInfo) error {
// Cancel deferred remove
if err := devices.cancelDeferredRemoval(info); err != nil {
// If Error is ErrEnxio. Device is probably already gone. Continue.
- if errors.Cause(err) != devicemapper.ErrBusy {
+ if errors.Cause(err) != devicemapper.ErrEnxio {
return err
}
}
diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod
index 2217ea739..40eeaf837 100644
--- a/vendor/github.com/containers/storage/go.mod
+++ b/vendor/github.com/containers/storage/go.mod
@@ -10,7 +10,7 @@ require (
github.com/google/go-intervals v0.0.2
github.com/hashicorp/go-multierror v1.1.1
github.com/json-iterator/go v1.1.11
- github.com/klauspost/compress v1.13.0
+ github.com/klauspost/compress v1.13.1
github.com/klauspost/pgzip v1.2.5
github.com/mattn/go-shellwords v1.0.12
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum
index 6cd6df17c..16da895f5 100644
--- a/vendor/github.com/containers/storage/go.sum
+++ b/vendor/github.com/containers/storage/go.sum
@@ -385,8 +385,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.13.0 h1:2T7tUoQrQT+fQWdaY5rjWztFGAFwbGD04iPJg90ZiOs=
-github.com/klauspost/compress v1.13.0/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
+github.com/klauspost/compress v1.13.1 h1:wXr2uRxZTJXHLly6qhJabee5JqIhTRoLBhDOA74hDEQ=
+github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go
index 9b05474bb..fa0dce033 100644
--- a/vendor/github.com/containers/storage/layers.go
+++ b/vendor/github.com/containers/storage/layers.go
@@ -271,21 +271,22 @@ type LayerStore interface {
}
type layerStore struct {
- lockfile Locker
- mountsLockfile Locker
- rundir string
- driver drivers.Driver
- layerdir string
- layers []*Layer
- idindex *truncindex.TruncIndex
- byid map[string]*Layer
- byname map[string]*Layer
- bymount map[string]*Layer
- bycompressedsum map[digest.Digest][]string
- byuncompressedsum map[digest.Digest][]string
- uidMap []idtools.IDMap
- gidMap []idtools.IDMap
- loadMut sync.Mutex
+ lockfile Locker
+ mountsLockfile Locker
+ rundir string
+ driver drivers.Driver
+ layerdir string
+ layers []*Layer
+ idindex *truncindex.TruncIndex
+ byid map[string]*Layer
+ byname map[string]*Layer
+ bymount map[string]*Layer
+ bycompressedsum map[digest.Digest][]string
+ byuncompressedsum map[digest.Digest][]string
+ uidMap []idtools.IDMap
+ gidMap []idtools.IDMap
+ loadMut sync.Mutex
+ layerspathModified time.Time
}
func copyLayer(l *Layer) *Layer {
@@ -1744,7 +1745,7 @@ func (r *layerStore) Touch() error {
}
func (r *layerStore) Modified() (bool, error) {
- var mmodified bool
+ var mmodified, tmodified bool
lmodified, err := r.lockfile.Modified()
if err != nil {
return lmodified, err
@@ -1757,7 +1758,23 @@ func (r *layerStore) Modified() (bool, error) {
return lmodified, err
}
}
- return lmodified || mmodified, nil
+
+ if lmodified || mmodified {
+ return true, nil
+ }
+
+ // If the layers.json file has been modified manually, then we have to
+ // reload the storage in any case.
+ info, err := os.Stat(r.layerspath())
+ if err != nil && !os.IsNotExist(err) {
+ return false, errors.Wrap(err, "stat layers file")
+ }
+ if info != nil {
+ tmodified = info.ModTime() != r.layerspathModified
+ r.layerspathModified = info.ModTime()
+ }
+
+ return tmodified, nil
}
func (r *layerStore) IsReadWrite() bool {
diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go
index b38340126..90d5b6c50 100644
--- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go
+++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go
@@ -195,16 +195,21 @@ func (plugin *cniNetworkPlugin) monitorConfDir(start *sync.WaitGroup) {
// If defaultNetName is empty, CNI config files should be reloaded real-time and
// defaultNetName should be changeable and determined by file sorting.
func InitCNI(defaultNetName string, confDir string, binDirs ...string) (CNIPlugin, error) {
- return initCNI(nil, "", defaultNetName, confDir, binDirs...)
+ return initCNI(nil, "", defaultNetName, confDir, true, binDirs...)
}
// InitCNIWithCache works like InitCNI except that it takes the cni cache directory as third param.
func InitCNIWithCache(defaultNetName, confDir, cacheDir string, binDirs ...string) (CNIPlugin, error) {
- return initCNI(nil, cacheDir, defaultNetName, confDir, binDirs...)
+ return initCNI(nil, cacheDir, defaultNetName, confDir, true, binDirs...)
+}
+
+// InitCNINoInotify works like InitCNI except that it does not use inotify to watch for changes in the CNI config dir.
+func InitCNINoInotify(defaultNetName, confDir, cacheDir string, binDirs ...string) (CNIPlugin, error) {
+ return initCNI(nil, cacheDir, defaultNetName, confDir, false, binDirs...)
}
// Internal function to allow faking out exec functions for testing
-func initCNI(exec cniinvoke.Exec, cacheDir, defaultNetName string, confDir string, binDirs ...string) (CNIPlugin, error) {
+func initCNI(exec cniinvoke.Exec, cacheDir, defaultNetName string, confDir string, useInotify bool, binDirs ...string) (CNIPlugin, error) {
if confDir == "" {
confDir = DefaultConfDir
}
@@ -245,22 +250,26 @@ func initCNI(exec cniinvoke.Exec, cacheDir, defaultNetName string, confDir strin
plugin.syncNetworkConfig()
- plugin.watcher, err = newWatcher(plugin.confDir)
- if err != nil {
- return nil, err
- }
+ if useInotify {
+ plugin.watcher, err = newWatcher(plugin.confDir)
+ if err != nil {
+ return nil, err
+ }
- startWg := sync.WaitGroup{}
- startWg.Add(1)
- go plugin.monitorConfDir(&startWg)
- startWg.Wait()
+ startWg := sync.WaitGroup{}
+ startWg.Add(1)
+ go plugin.monitorConfDir(&startWg)
+ startWg.Wait()
+ }
return plugin, nil
}
func (plugin *cniNetworkPlugin) Shutdown() error {
close(plugin.shutdownChan)
- plugin.watcher.Close()
+ if plugin.watcher != nil {
+ plugin.watcher.Close()
+ }
plugin.done.Wait()
return nil
}
@@ -539,10 +548,11 @@ func (plugin *cniNetworkPlugin) SetUpPodWithContext(ctx context.Context, podNetw
results := make([]NetResult, 0)
if err := plugin.forEachNetwork(&podNetwork, false, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error {
+ fullPodName := buildFullPodName(*podNetwork)
+ logrus.Infof("Adding pod %s to CNI network %q (type=%v)", fullPodName, network.name, network.config.Plugins[0].Network.Type)
result, err := network.addToNetwork(ctx, rt, plugin.cniConfig)
if err != nil {
- logrus.Errorf("Error while adding pod to CNI network %q: %s", network.name, err)
- return err
+ return fmt.Errorf("error adding pod %s to CNI network %q: %v", fullPodName, network.name, err)
}
results = append(results, NetResult{
Result: result,
@@ -654,8 +664,10 @@ func (plugin *cniNetworkPlugin) TearDownPodWithContext(ctx context.Context, podN
}
return plugin.forEachNetwork(&podNetwork, true, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error {
+ fullPodName := buildFullPodName(*podNetwork)
+ logrus.Infof("Deleting pod %s from CNI network %q (type=%v)", fullPodName, network.name, network.config.Plugins[0].Network.Type)
if err := network.deleteFromNetwork(ctx, rt, plugin.cniConfig); err != nil {
- return fmt.Errorf("Error while removing pod from CNI network %q: %s", network.name, err)
+ return fmt.Errorf("error removing pod %s from CNI network %q: %v", fullPodName, network.name, err)
}
return nil
})
@@ -680,10 +692,11 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatusWithContext(ctx context.Conte
results := make([]NetResult, 0)
if err := plugin.forEachNetwork(&podNetwork, true, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error {
+ fullPodName := buildFullPodName(*podNetwork)
+ logrus.Infof("Checking pod %s for CNI network %s (type=%v)", fullPodName, network.name, network.config.Plugins[0].Network.Type)
result, err := network.checkNetwork(ctx, rt, plugin.cniConfig, plugin.nsManager, podNetwork.NetNS)
if err != nil {
- logrus.Errorf("Error while checking pod to CNI network %q: %s", network.name, err)
- return err
+ return fmt.Errorf("error checking pod %s for CNI network %q: %v", fullPodName, network.name, err)
}
if result != nil {
results = append(results, NetResult{
@@ -703,19 +716,10 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatusWithContext(ctx context.Conte
}
func (network *cniNetwork) addToNetwork(ctx context.Context, rt *libcni.RuntimeConf, cni *libcni.CNIConfig) (cnitypes.Result, error) {
- logrus.Infof("About to add CNI network %s (type=%v)", network.name, network.config.Plugins[0].Network.Type)
- res, err := cni.AddNetworkList(ctx, network.config, rt)
- if err != nil {
- logrus.Errorf("Error adding network: %v", err)
- return nil, err
- }
-
- return res, nil
+ return cni.AddNetworkList(ctx, network.config, rt)
}
func (network *cniNetwork) checkNetwork(ctx context.Context, rt *libcni.RuntimeConf, cni *libcni.CNIConfig, nsManager *nsManager, netns string) (cnitypes.Result, error) {
- logrus.Infof("About to check CNI network %s (type=%v)", network.name, network.config.Plugins[0].Network.Type)
-
gtet, err := cniversion.GreaterThanOrEqualTo(network.config.CNIVersion, "0.4.0")
if err != nil {
return nil, err
@@ -786,11 +790,7 @@ func (network *cniNetwork) checkNetwork(ctx context.Context, rt *libcni.RuntimeC
}
func (network *cniNetwork) deleteFromNetwork(ctx context.Context, rt *libcni.RuntimeConf, cni *libcni.CNIConfig) error {
- logrus.Infof("About to del CNI network %s (type=%v)", network.name, network.config.Plugins[0].Network.Type)
- if err := cni.DelNetworkList(ctx, network.config, rt); err != nil {
- return err
- }
- return nil
+ return cni.DelNetworkList(ctx, network.config, rt)
}
func buildCNIRuntimeConf(podNetwork *PodNetwork, ifName string, runtimeConfig RuntimeConfig) (*libcni.RuntimeConf, error) {
@@ -809,6 +809,13 @@ func buildCNIRuntimeConf(podNetwork *PodNetwork, ifName string, runtimeConfig Ru
CapabilityArgs: map[string]interface{}{},
}
+ // Propagate existing CNI_ARGS to non-k8s consumers
+ for _, kvpairs := range strings.Split(os.Getenv("CNI_ARGS"), ";") {
+ if keyval := strings.SplitN(kvpairs, "=", 2); len(keyval) == 2 {
+ rt.Args = append(rt.Args, [2]string{keyval[0], keyval[1]})
+ }
+ }
+
// Add requested static IP to CNI_ARGS
ip := runtimeConfig.IP
if ip != "" {
diff --git a/vendor/github.com/docker/docker-credential-helpers/client/command.go b/vendor/github.com/docker/docker-credential-helpers/client/command.go
index 8da334306..0183c0639 100644
--- a/vendor/github.com/docker/docker-credential-helpers/client/command.go
+++ b/vendor/github.com/docker/docker-credential-helpers/client/command.go
@@ -4,7 +4,8 @@ import (
"fmt"
"io"
"os"
- "os/exec"
+
+ exec "golang.org/x/sys/execabs"
)
// Program is an interface to execute external programs.
diff --git a/vendor/github.com/docker/docker-credential-helpers/credentials/version.go b/vendor/github.com/docker/docker-credential-helpers/credentials/version.go
index c2cc3e2e0..185e36796 100644
--- a/vendor/github.com/docker/docker-credential-helpers/credentials/version.go
+++ b/vendor/github.com/docker/docker-credential-helpers/credentials/version.go
@@ -1,4 +1,4 @@
package credentials
// Version holds a string describing the current version
-const Version = "0.6.3"
+const Version = "0.6.4"
diff --git a/vendor/github.com/imdario/mergo/.travis.yml b/vendor/github.com/imdario/mergo/.travis.yml
index dad29725f..d324c43ba 100644
--- a/vendor/github.com/imdario/mergo/.travis.yml
+++ b/vendor/github.com/imdario/mergo/.travis.yml
@@ -1,4 +1,7 @@
language: go
+arch:
+ - amd64
+ - ppc64le
install:
- go get -t
- go get golang.org/x/tools/cmd/cover
diff --git a/vendor/github.com/imdario/mergo/README.md b/vendor/github.com/imdario/mergo/README.md
index 876abb500..aa8cbd7ce 100644
--- a/vendor/github.com/imdario/mergo/README.md
+++ b/vendor/github.com/imdario/mergo/README.md
@@ -97,7 +97,7 @@ If Mergo is useful to you, consider buying me a coffee, a beer, or making a mont
- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server)
- [jnuthong/item_search](https://github.com/jnuthong/item_search)
- [bukalapak/snowboard](https://github.com/bukalapak/snowboard)
-- [janoszen/containerssh](https://github.com/janoszen/containerssh)
+- [containerssh/containerssh](https://github.com/containerssh/containerssh)
## Install
diff --git a/vendor/github.com/imdario/mergo/merge.go b/vendor/github.com/imdario/mergo/merge.go
index afa84a1e2..8c2a8fcd9 100644
--- a/vendor/github.com/imdario/mergo/merge.go
+++ b/vendor/github.com/imdario/mergo/merge.go
@@ -95,13 +95,18 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
}
}
} else {
- if (isReflectNil(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) {
+ if dst.CanSet() && (isReflectNil(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) {
dst.Set(src)
}
}
case reflect.Map:
if dst.IsNil() && !src.IsNil() {
- dst.Set(reflect.MakeMap(dst.Type()))
+ if dst.CanSet() {
+ dst.Set(reflect.MakeMap(dst.Type()))
+ } else {
+ dst = src
+ return
+ }
}
if src.Kind() != reflect.Map {
diff --git a/vendor/github.com/jinzhu/copier/README.md b/vendor/github.com/jinzhu/copier/README.md
index cff72405c..ec04b4be0 100644
--- a/vendor/github.com/jinzhu/copier/README.md
+++ b/vendor/github.com/jinzhu/copier/README.md
@@ -27,9 +27,10 @@ import (
)
type User struct {
- Name string
- Role string
- Age int32
+ Name string
+ Role string
+ Age int32
+ EmployeCode int64 `copier:"EmployeNum"` // specify field name
// Explicitly ignored in the destination struct.
Salary int
@@ -52,7 +53,7 @@ type Employee struct {
Salary int `copier:"-"`
DoubleAge int32
- EmployeId int64
+ EmployeId int64 `copier:"EmployeNum"` // specify field name
SuperRole string
}
diff --git a/vendor/github.com/jinzhu/copier/copier.go b/vendor/github.com/jinzhu/copier/copier.go
index 72bf65c78..412ff5497 100644
--- a/vendor/github.com/jinzhu/copier/copier.go
+++ b/vendor/github.com/jinzhu/copier/copier.go
@@ -3,9 +3,11 @@ package copier
import (
"database/sql"
"database/sql/driver"
+ "errors"
"fmt"
"reflect"
"strings"
+ "unicode"
)
// These flags define options for tag handling
@@ -32,6 +34,19 @@ type Option struct {
DeepCopy bool
}
+// Tag Flags
+type flags struct {
+ BitFlags map[string]uint8
+ SrcNames tagNameMapping
+ DestNames tagNameMapping
+}
+
+// Field Tag name mapping
+type tagNameMapping struct {
+ FieldNameToTag map[string]string
+ TagToFieldName map[string]string
+}
+
// Copy copy things
func Copy(toValue interface{}, fromValue interface{}) (err error) {
return copier(toValue, fromValue, Option{})
@@ -134,7 +149,8 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
}
if !set(to.Index(i), from.Index(i), opt.DeepCopy) {
- err = CopyWithOption(to.Index(i).Addr().Interface(), from.Index(i).Interface(), opt)
+ // ignore error while copy slice element
+ err = copier(to.Index(i).Addr().Interface(), from.Index(i).Interface(), opt)
if err != nil {
continue
}
@@ -148,7 +164,7 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
return
}
- if to.Kind() == reflect.Slice {
+ if from.Kind() == reflect.Slice || to.Kind() == reflect.Slice {
isSlice = true
if from.Kind() == reflect.Slice {
amount = from.Len()
@@ -180,9 +196,9 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
}
// Get tag options
- tagBitFlags := map[string]uint8{}
- if dest.IsValid() {
- tagBitFlags = getBitFlags(toType)
+ flgs, err := getFlags(dest, source, toType, fromType)
+ if err != nil {
+ return err
}
// check source
@@ -193,17 +209,18 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
name := field.Name
// Get bit flags for field
- fieldFlags, _ := tagBitFlags[name]
+ fieldFlags, _ := flgs.BitFlags[name]
// Check if we should ignore copying
if (fieldFlags & tagIgnore) != 0 {
continue
}
- if fromField := source.FieldByName(name); fromField.IsValid() && !shouldIgnore(fromField, opt.IgnoreEmpty) {
+ srcFieldName, destFieldName := getFieldName(name, flgs)
+ if fromField := source.FieldByName(srcFieldName); fromField.IsValid() && !shouldIgnore(fromField, opt.IgnoreEmpty) {
// process for nested anonymous field
destFieldNotSet := false
- if f, ok := dest.Type().FieldByName(name); ok {
+ if f, ok := dest.Type().FieldByName(destFieldName); ok {
for idx := range f.Index {
destField := dest.FieldByIndex(f.Index[:idx+1])
@@ -229,7 +246,7 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
break
}
- toField := dest.FieldByName(name)
+ toField := dest.FieldByName(destFieldName)
if toField.IsValid() {
if toField.CanSet() {
if !set(toField, fromField, opt.DeepCopy) {
@@ -239,16 +256,16 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
}
if fieldFlags != 0 {
// Note that a copy was made
- tagBitFlags[name] = fieldFlags | hasCopied
+ flgs.BitFlags[name] = fieldFlags | hasCopied
}
}
} else {
// try to set to method
var toMethod reflect.Value
if dest.CanAddr() {
- toMethod = dest.Addr().MethodByName(name)
+ toMethod = dest.Addr().MethodByName(destFieldName)
} else {
- toMethod = dest.MethodByName(name)
+ toMethod = dest.MethodByName(destFieldName)
}
if toMethod.IsValid() && toMethod.Type().NumIn() == 1 && fromField.Type().AssignableTo(toMethod.Type().In(0)) {
@@ -261,16 +278,17 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
// Copy from from method to dest field
for _, field := range deepFields(toType) {
name := field.Name
+ srcFieldName, destFieldName := getFieldName(name, flgs)
var fromMethod reflect.Value
if source.CanAddr() {
- fromMethod = source.Addr().MethodByName(name)
+ fromMethod = source.Addr().MethodByName(srcFieldName)
} else {
- fromMethod = source.MethodByName(name)
+ fromMethod = source.MethodByName(srcFieldName)
}
if fromMethod.IsValid() && fromMethod.Type().NumIn() == 0 && fromMethod.Type().NumOut() == 1 && !shouldIgnore(fromMethod, opt.IgnoreEmpty) {
- if toField := dest.FieldByName(name); toField.IsValid() && toField.CanSet() {
+ if toField := dest.FieldByName(destFieldName); toField.IsValid() && toField.CanSet() {
values := fromMethod.Call([]reflect.Value{})
if len(values) >= 1 {
set(toField, values[0], opt.DeepCopy)
@@ -280,25 +298,37 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
}
}
- if isSlice {
+ if isSlice && to.Kind() == reflect.Slice {
if dest.Addr().Type().AssignableTo(to.Type().Elem()) {
if to.Len() < i+1 {
to.Set(reflect.Append(to, dest.Addr()))
} else {
- set(to.Index(i), dest.Addr(), opt.DeepCopy)
+ if !set(to.Index(i), dest.Addr(), opt.DeepCopy) {
+ // ignore error while copy slice element
+ err = copier(to.Index(i).Addr().Interface(), dest.Addr().Interface(), opt)
+ if err != nil {
+ continue
+ }
+ }
}
} else if dest.Type().AssignableTo(to.Type().Elem()) {
if to.Len() < i+1 {
to.Set(reflect.Append(to, dest))
} else {
- set(to.Index(i), dest, opt.DeepCopy)
+ if !set(to.Index(i), dest, opt.DeepCopy) {
+ // ignore error while copy slice element
+ err = copier(to.Index(i).Addr().Interface(), dest.Interface(), opt)
+ if err != nil {
+ continue
+ }
+ }
}
}
} else if initDest {
to.Set(dest)
}
- err = checkBitFlags(tagBitFlags)
+ err = checkBitFlags(flgs.BitFlags)
}
return
@@ -432,46 +462,90 @@ func set(to, from reflect.Value, deepCopy bool) bool {
}
// parseTags Parses struct tags and returns uint8 bit flags.
-func parseTags(tag string) (flags uint8) {
+func parseTags(tag string) (flg uint8, name string, err error) {
for _, t := range strings.Split(tag, ",") {
switch t {
case "-":
- flags = tagIgnore
+ flg = tagIgnore
return
case "must":
- flags = flags | tagMust
+ flg = flg | tagMust
case "nopanic":
- flags = flags | tagNoPanic
+ flg = flg | tagNoPanic
+ default:
+ if unicode.IsUpper([]rune(t)[0]) {
+ name = strings.TrimSpace(t)
+ } else {
+ err = errors.New("copier field name tag must be start upper case")
+ }
}
}
return
}
-// getBitFlags Parses struct tags for bit flags.
-func getBitFlags(toType reflect.Type) map[string]uint8 {
- flags := map[string]uint8{}
- toTypeFields := deepFields(toType)
+// getTagFlags Parses struct tags for bit flags, field name.
+func getFlags(dest, src reflect.Value, toType, fromType reflect.Type) (flags, error) {
+ flgs := flags{
+ BitFlags: map[string]uint8{},
+ SrcNames: tagNameMapping{
+ FieldNameToTag: map[string]string{},
+ TagToFieldName: map[string]string{},
+ },
+ DestNames: tagNameMapping{
+ FieldNameToTag: map[string]string{},
+ TagToFieldName: map[string]string{},
+ },
+ }
+ var toTypeFields, fromTypeFields []reflect.StructField
+ if dest.IsValid() {
+ toTypeFields = deepFields(toType)
+ }
+ if src.IsValid() {
+ fromTypeFields = deepFields(fromType)
+ }
// Get a list dest of tags
for _, field := range toTypeFields {
tags := field.Tag.Get("copier")
if tags != "" {
- flags[field.Name] = parseTags(tags)
+ var name string
+ var err error
+ if flgs.BitFlags[field.Name], name, err = parseTags(tags); err != nil {
+ return flags{}, err
+ } else if name != "" {
+ flgs.DestNames.FieldNameToTag[field.Name] = name
+ flgs.DestNames.TagToFieldName[name] = field.Name
+ }
+ }
+ }
+
+ // Get a list source of tags
+ for _, field := range fromTypeFields {
+ tags := field.Tag.Get("copier")
+ if tags != "" {
+ var name string
+ var err error
+ if _, name, err = parseTags(tags); err != nil {
+ return flags{}, err
+ } else if name != "" {
+ flgs.SrcNames.FieldNameToTag[field.Name] = name
+ flgs.SrcNames.TagToFieldName[name] = field.Name
+ }
}
}
- return flags
+ return flgs, nil
}
// checkBitFlags Checks flags for error or panic conditions.
func checkBitFlags(flagsList map[string]uint8) (err error) {
// Check flag conditions were met
- for name, flags := range flagsList {
- if flags&hasCopied == 0 {
+ for name, flgs := range flagsList {
+ if flgs&hasCopied == 0 {
switch {
- case flags&tagMust != 0 && flags&tagNoPanic != 0:
+ case flgs&tagMust != 0 && flgs&tagNoPanic != 0:
err = fmt.Errorf("field %s has must tag but was not copied", name)
return
- case flags&(tagMust) != 0:
+ case flgs&(tagMust) != 0:
panic(fmt.Sprintf("Field %s has must tag but was not copied", name))
}
}
@@ -479,6 +553,40 @@ func checkBitFlags(flagsList map[string]uint8) (err error) {
return
}
+func getFieldName(fieldName string, flgs flags) (srcFieldName string, destFieldName string) {
+ // get dest field name
+ if srcTagName, ok := flgs.SrcNames.FieldNameToTag[fieldName]; ok {
+ destFieldName = srcTagName
+ if destTagName, ok := flgs.DestNames.TagToFieldName[srcTagName]; ok {
+ destFieldName = destTagName
+ }
+ } else {
+ if destTagName, ok := flgs.DestNames.TagToFieldName[fieldName]; ok {
+ destFieldName = destTagName
+ }
+ }
+ if destFieldName == "" {
+ destFieldName = fieldName
+ }
+
+ // get source field name
+ if destTagName, ok := flgs.DestNames.FieldNameToTag[fieldName]; ok {
+ srcFieldName = destTagName
+ if srcField, ok := flgs.SrcNames.TagToFieldName[destTagName]; ok {
+ srcFieldName = srcField
+ }
+ } else {
+ if srcField, ok := flgs.SrcNames.TagToFieldName[fieldName]; ok {
+ srcFieldName = srcField
+ }
+ }
+
+ if srcFieldName == "" {
+ srcFieldName = fieldName
+ }
+ return
+}
+
func driverValuer(v reflect.Value) (i driver.Valuer, ok bool) {
if !v.CanAddr() {
diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go
index e30af505c..8a98c4562 100644
--- a/vendor/github.com/klauspost/compress/zstd/blockdec.go
+++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go
@@ -168,10 +168,10 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error {
// Read block data.
if cap(b.dataStorage) < cSize {
- if b.lowMem {
+ if b.lowMem || cSize > maxCompressedBlockSize {
b.dataStorage = make([]byte, 0, cSize)
} else {
- b.dataStorage = make([]byte, 0, maxBlockSize)
+ b.dataStorage = make([]byte, 0, maxCompressedBlockSize)
}
}
if cap(b.dst) <= maxSize {
diff --git a/vendor/github.com/klauspost/compress/zstd/decoder_options.go b/vendor/github.com/klauspost/compress/zstd/decoder_options.go
index c0fd058c2..95cc9b8b8 100644
--- a/vendor/github.com/klauspost/compress/zstd/decoder_options.go
+++ b/vendor/github.com/klauspost/compress/zstd/decoder_options.go
@@ -17,14 +17,16 @@ type decoderOptions struct {
lowMem bool
concurrent int
maxDecodedSize uint64
+ maxWindowSize uint64
dicts []dict
}
func (o *decoderOptions) setDefault() {
*o = decoderOptions{
// use less ram: true for now, but may change.
- lowMem: true,
- concurrent: runtime.GOMAXPROCS(0),
+ lowMem: true,
+ concurrent: runtime.GOMAXPROCS(0),
+ maxWindowSize: MaxWindowSize,
}
o.maxDecodedSize = 1 << 63
}
@@ -52,7 +54,6 @@ func WithDecoderConcurrency(n int) DOption {
// WithDecoderMaxMemory allows to set a maximum decoded size for in-memory
// non-streaming operations or maximum window size for streaming operations.
// This can be used to control memory usage of potentially hostile content.
-// For streaming operations, the maximum window size is capped at 1<<30 bytes.
// Maximum and default is 1 << 63 bytes.
func WithDecoderMaxMemory(n uint64) DOption {
return func(o *decoderOptions) error {
@@ -81,3 +82,21 @@ func WithDecoderDicts(dicts ...[]byte) DOption {
return nil
}
}
+
+// WithDecoderMaxWindow allows to set a maximum window size for decodes.
+// This allows rejecting packets that will cause big memory usage.
+// The Decoder will likely allocate more memory based on the WithDecoderLowmem setting.
+// If WithDecoderMaxMemory is set to a lower value, that will be used.
+// Default is 512MB, Maximum is ~3.75 TB as per zstandard spec.
+func WithDecoderMaxWindow(size uint64) DOption {
+ return func(o *decoderOptions) error {
+ if size < MinWindowSize {
+ return errors.New("WithMaxWindowSize must be at least 1KB, 1024 bytes")
+ }
+ if size > (1<<41)+7*(1<<38) {
+ return errors.New("WithMaxWindowSize must be less than (1<<41) + 7*(1<<38) ~ 3.75TB")
+ }
+ o.maxWindowSize = size
+ return nil
+ }
+}
diff --git a/vendor/github.com/klauspost/compress/zstd/framedec.go b/vendor/github.com/klauspost/compress/zstd/framedec.go
index e8cc9a2c2..989c79f8c 100644
--- a/vendor/github.com/klauspost/compress/zstd/framedec.go
+++ b/vendor/github.com/klauspost/compress/zstd/framedec.go
@@ -22,10 +22,6 @@ type frameDec struct {
WindowSize uint64
- // maxWindowSize is the maximum windows size to support.
- // should never be bigger than max-int.
- maxWindowSize uint64
-
// In order queue of blocks being decoded.
decoding chan *blockDec
@@ -50,8 +46,11 @@ type frameDec struct {
}
const (
- // The minimum Window_Size is 1 KB.
+ // MinWindowSize is the minimum Window Size, which is 1 KB.
MinWindowSize = 1 << 10
+
+ // MaxWindowSize is the maximum encoder window size
+ // and the default decoder maximum window size.
MaxWindowSize = 1 << 29
)
@@ -61,12 +60,11 @@ var (
)
func newFrameDec(o decoderOptions) *frameDec {
- d := frameDec{
- o: o,
- maxWindowSize: MaxWindowSize,
+ if o.maxWindowSize > o.maxDecodedSize {
+ o.maxWindowSize = o.maxDecodedSize
}
- if d.maxWindowSize > o.maxDecodedSize {
- d.maxWindowSize = o.maxDecodedSize
+ d := frameDec{
+ o: o,
}
return &d
}
@@ -251,13 +249,17 @@ func (d *frameDec) reset(br byteBuffer) error {
}
}
- if d.WindowSize > d.maxWindowSize {
- printf("window size %d > max %d\n", d.WindowSize, d.maxWindowSize)
+ if d.WindowSize > uint64(d.o.maxWindowSize) {
+ if debugDecoder {
+ printf("window size %d > max %d\n", d.WindowSize, d.o.maxWindowSize)
+ }
return ErrWindowSizeExceeded
}
// The minimum Window_Size is 1 KB.
if d.WindowSize < MinWindowSize {
- println("got window size: ", d.WindowSize)
+ if debugDecoder {
+ println("got window size: ", d.WindowSize)
+ }
return ErrWindowSizeTooSmall
}
d.history.windowSize = int(d.WindowSize)
@@ -352,8 +354,8 @@ func (d *frameDec) checkCRC() error {
func (d *frameDec) initAsync() {
if !d.o.lowMem && !d.SingleSegment {
- // set max extra size history to 10MB.
- d.history.maxSize = d.history.windowSize + maxBlockSize*5
+ // set max extra size history to 2MB.
+ d.history.maxSize = d.history.windowSize + maxBlockSize
}
// re-alloc if more than one extra block size.
if d.o.lowMem && cap(d.history.b) > d.history.maxSize+maxBlockSize {
diff --git a/vendor/github.com/mattn/go-runewidth/go.mod b/vendor/github.com/mattn/go-runewidth/go.mod
index 8a9d524ec..62dba1bfc 100644
--- a/vendor/github.com/mattn/go-runewidth/go.mod
+++ b/vendor/github.com/mattn/go-runewidth/go.mod
@@ -2,4 +2,4 @@ module github.com/mattn/go-runewidth
go 1.9
-require github.com/rivo/uniseg v0.1.0
+require github.com/rivo/uniseg v0.2.0
diff --git a/vendor/github.com/mattn/go-runewidth/go.sum b/vendor/github.com/mattn/go-runewidth/go.sum
index 02135660b..03f902d56 100644
--- a/vendor/github.com/mattn/go-runewidth/go.sum
+++ b/vendor/github.com/mattn/go-runewidth/go.sum
@@ -1,2 +1,2 @@
-github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
-github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
diff --git a/vendor/github.com/vbauerster/mpb/v7/.gitignore b/vendor/github.com/vbauerster/mpb/v7/.gitignore
new file mode 100644
index 000000000..63bd91672
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/.gitignore
@@ -0,0 +1,5 @@
+# Test binary, build with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
diff --git a/vendor/github.com/vbauerster/mpb/v7/.travis.yml b/vendor/github.com/vbauerster/mpb/v7/.travis.yml
new file mode 100644
index 000000000..9a203a67d
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/.travis.yml
@@ -0,0 +1,11 @@
+language: go
+arch:
+ - amd64
+ - ppc64le
+
+go:
+ - 1.14.x
+
+script:
+ - go test -race ./...
+ - for i in _examples/*/; do go build $i/*.go || exit 1; done
diff --git a/vendor/github.com/vbauerster/mpb/v7/README.md b/vendor/github.com/vbauerster/mpb/v7/README.md
new file mode 100644
index 000000000..d0560d799
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/README.md
@@ -0,0 +1,121 @@
+# Multi Progress Bar
+
+[![GoDoc](https://pkg.go.dev/badge/github.com/vbauerster/mpb)](https://pkg.go.dev/github.com/vbauerster/mpb/v7)
+[![Build Status](https://travis-ci.org/vbauerster/mpb.svg?branch=master)](https://travis-ci.org/vbauerster/mpb)
+[![Go Report Card](https://goreportcard.com/badge/github.com/vbauerster/mpb)](https://goreportcard.com/report/github.com/vbauerster/mpb)
+[![Donate with PayPal](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/vbauerster)
+
+**mpb** is a Go lib for rendering progress bars in terminal applications.
+
+## Features
+
+- **Multiple Bars**: Multiple progress bars are supported
+- **Dynamic Total**: Set total while bar is running
+- **Dynamic Add/Remove**: Dynamically add or remove bars
+- **Cancellation**: Cancel whole rendering process
+- **Predefined Decorators**: Elapsed time, [ewma](https://github.com/VividCortex/ewma) based ETA, Percentage, Bytes counter
+- **Decorator's width sync**: Synchronized decorator's width among multiple bars
+
+## Usage
+
+#### [Rendering single bar](_examples/singleBar/main.go)
+
+```go
+package main
+
+import (
+ "math/rand"
+ "time"
+
+ "github.com/vbauerster/mpb/v7"
+ "github.com/vbauerster/mpb/v7/decor"
+)
+
+func main() {
+ // initialize progress container, with custom width
+ p := mpb.New(mpb.WithWidth(64))
+
+ total := 100
+ name := "Single Bar:"
+ // adding a single bar, which will inherit container's width
+ bar := p.Add(int64(total),
+ // progress bar filler with customized style
+ mpb.NewBarFiller(mpb.BarStyle().Lbound("╢").Filler("▌").Tip("▌").Padding("░").Rbound("╟")),
+ mpb.PrependDecorators(
+ // display our name with one space on the right
+ decor.Name(name, decor.WC{W: len(name) + 1, C: decor.DidentRight}),
+ // replace ETA decorator with "done" message, OnComplete event
+ decor.OnComplete(
+ decor.AverageETA(decor.ET_STYLE_GO, decor.WC{W: 4}), "done",
+ ),
+ ),
+ mpb.AppendDecorators(decor.Percentage()),
+ )
+ // simulating some work
+ max := 100 * time.Millisecond
+ for i := 0; i < total; i++ {
+ time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10)
+ bar.Increment()
+ }
+ // wait for our bar to complete and flush
+ p.Wait()
+}
+```
+
+#### [Rendering multiple bars](_examples/multiBars/main.go)
+
+```go
+ var wg sync.WaitGroup
+ // passed &wg will be accounted at p.Wait() call
+ p := mpb.New(mpb.WithWaitGroup(&wg))
+ total, numBars := 100, 3
+ wg.Add(numBars)
+
+ for i := 0; i < numBars; i++ {
+ name := fmt.Sprintf("Bar#%d:", i)
+ bar := p.AddBar(int64(total),
+ mpb.PrependDecorators(
+ // simple name decorator
+ decor.Name(name),
+ // decor.DSyncWidth bit enables column width synchronization
+ decor.Percentage(decor.WCSyncSpace),
+ ),
+ mpb.AppendDecorators(
+ // replace ETA decorator with "done" message, OnComplete event
+ decor.OnComplete(
+ // ETA decorator with ewma age of 60
+ decor.EwmaETA(decor.ET_STYLE_GO, 60), "done",
+ ),
+ ),
+ )
+ // simulating some work
+ go func() {
+ defer wg.Done()
+ rng := rand.New(rand.NewSource(time.Now().UnixNano()))
+ max := 100 * time.Millisecond
+ for i := 0; i < total; i++ {
+ // start variable is solely for EWMA calculation
+ // EWMA's unit of measure is an iteration's duration
+ start := time.Now()
+ time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10)
+ bar.Increment()
+ // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract
+ bar.DecoratorEwmaUpdate(time.Since(start))
+ }
+ }()
+ }
+ // Waiting for passed &wg and for all bars to complete and flush
+ p.Wait()
+```
+
+#### [Dynamic total](_examples/dynTotal/main.go)
+
+![dynamic total](_svg/godEMrCZmJkHYH1X9dN4Nm0U7.svg)
+
+#### [Complex example](_examples/complex/main.go)
+
+![complex](_svg/wHzf1M7sd7B3zVa2scBMnjqRf.svg)
+
+#### [Bytes counters](_examples/io/main.go)
+
+![byte counters](_svg/hIpTa3A5rQz65ssiVuRJu87X6.svg)
diff --git a/vendor/github.com/vbauerster/mpb/v7/UNLICENSE b/vendor/github.com/vbauerster/mpb/v7/UNLICENSE
new file mode 100644
index 000000000..68a49daad
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/UNLICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/>
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar.go b/vendor/github.com/vbauerster/mpb/v7/bar.go
new file mode 100644
index 000000000..ed6c73eda
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/bar.go
@@ -0,0 +1,492 @@
+package mpb
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "io"
+ "log"
+ "runtime/debug"
+ "strings"
+ "time"
+
+ "github.com/acarl005/stripansi"
+ "github.com/mattn/go-runewidth"
+ "github.com/vbauerster/mpb/v7/decor"
+)
+
+// Bar represents a progress bar.
+type Bar struct {
+ priority int // used by heap
+ index int // used by heap
+
+ extendedLines int
+ toShutdown bool
+ toDrop bool
+ noPop bool
+ hasEwmaDecorators bool
+ operateState chan func(*bState)
+ frameCh chan io.Reader
+ syncTableCh chan [][]chan int
+ completed chan bool
+
+ // cancel is called either by user or on complete event
+ cancel func()
+ // done is closed after cacheState is assigned
+ done chan struct{}
+ // cacheState is populated, right after close(shutdown)
+ cacheState *bState
+
+ container *Progress
+ dlogger *log.Logger
+ recoveredPanic interface{}
+}
+
+type extenderFunc func(in io.Reader, reqWidth int, st decor.Statistics) (out io.Reader, lines int)
+
+// bState is actual bar state. It gets passed to *Bar.serve(...) monitor
+// goroutine.
+type bState struct {
+ id int
+ priority int
+ reqWidth int
+ total int64
+ current int64
+ refill int64
+ lastN int64
+ iterated bool
+ trimSpace bool
+ completed bool
+ completeFlushed bool
+ triggerComplete bool
+ dropOnComplete bool
+ noPop bool
+ aDecorators []decor.Decorator
+ pDecorators []decor.Decorator
+ averageDecorators []decor.AverageDecorator
+ ewmaDecorators []decor.EwmaDecorator
+ shutdownListeners []decor.ShutdownListener
+ bufP, bufB, bufA *bytes.Buffer
+ filler BarFiller
+ middleware func(BarFiller) BarFiller
+ extender extenderFunc
+
+ // runningBar is a key for *pState.parkedBars
+ runningBar *Bar
+
+ debugOut io.Writer
+}
+
+func newBar(container *Progress, bs *bState) *Bar {
+ logPrefix := fmt.Sprintf("%sbar#%02d ", container.dlogger.Prefix(), bs.id)
+ ctx, cancel := context.WithCancel(container.ctx)
+
+ bar := &Bar{
+ container: container,
+ priority: bs.priority,
+ toDrop: bs.dropOnComplete,
+ noPop: bs.noPop,
+ operateState: make(chan func(*bState)),
+ frameCh: make(chan io.Reader, 1),
+ syncTableCh: make(chan [][]chan int, 1),
+ completed: make(chan bool, 1),
+ done: make(chan struct{}),
+ cancel: cancel,
+ dlogger: log.New(bs.debugOut, logPrefix, log.Lshortfile),
+ }
+
+ go bar.serve(ctx, bs)
+ return bar
+}
+
+// ProxyReader wraps r with metrics required for progress tracking.
+// Panics if r is nil.
+func (b *Bar) ProxyReader(r io.Reader) io.ReadCloser {
+ if r == nil {
+ panic("expected non nil io.Reader")
+ }
+ return newProxyReader(r, b)
+}
+
+// ID returs id of the bar.
+func (b *Bar) ID() int {
+ result := make(chan int)
+ select {
+ case b.operateState <- func(s *bState) { result <- s.id }:
+ return <-result
+ case <-b.done:
+ return b.cacheState.id
+ }
+}
+
+// Current returns bar's current number, in other words sum of all increments.
+func (b *Bar) Current() int64 {
+ result := make(chan int64)
+ select {
+ case b.operateState <- func(s *bState) { result <- s.current }:
+ return <-result
+ case <-b.done:
+ return b.cacheState.current
+ }
+}
+
+// SetRefill sets refill flag with specified amount.
+// The underlying BarFiller will change its visual representation, to
+// indicate refill event. Refill event may be referred to some retry
+// operation for example.
+func (b *Bar) SetRefill(amount int64) {
+ select {
+ case b.operateState <- func(s *bState) {
+ s.refill = amount
+ }:
+ case <-b.done:
+ }
+}
+
+// TraverseDecorators traverses all available decorators and calls cb func on each.
+func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) {
+ select {
+ case b.operateState <- func(s *bState) {
+ for _, decorators := range [...][]decor.Decorator{
+ s.pDecorators,
+ s.aDecorators,
+ } {
+ for _, d := range decorators {
+ cb(extractBaseDecorator(d))
+ }
+ }
+ }:
+ case <-b.done:
+ }
+}
+
+// SetTotal sets total dynamically.
+// If total is less than or equal to zero it takes progress' current value.
+func (b *Bar) SetTotal(total int64, triggerComplete bool) {
+ select {
+ case b.operateState <- func(s *bState) {
+ s.triggerComplete = triggerComplete
+ if total <= 0 {
+ s.total = s.current
+ } else {
+ s.total = total
+ }
+ if s.triggerComplete && !s.completed {
+ s.current = s.total
+ s.completed = true
+ go b.refreshTillShutdown()
+ }
+ }:
+ case <-b.done:
+ }
+}
+
+// SetCurrent sets progress' current to an arbitrary value.
+// Setting a negative value will cause a panic.
+func (b *Bar) SetCurrent(current int64) {
+ select {
+ case b.operateState <- func(s *bState) {
+ s.iterated = true
+ s.lastN = current - s.current
+ s.current = current
+ if s.triggerComplete && s.current >= s.total {
+ s.current = s.total
+ s.completed = true
+ go b.refreshTillShutdown()
+ }
+ }:
+ case <-b.done:
+ }
+}
+
+// Increment is a shorthand for b.IncrInt64(1).
+func (b *Bar) Increment() {
+ b.IncrInt64(1)
+}
+
+// IncrBy is a shorthand for b.IncrInt64(int64(n)).
+func (b *Bar) IncrBy(n int) {
+ b.IncrInt64(int64(n))
+}
+
+// IncrInt64 increments progress by amount of n.
+func (b *Bar) IncrInt64(n int64) {
+ select {
+ case b.operateState <- func(s *bState) {
+ s.iterated = true
+ s.lastN = n
+ s.current += n
+ if s.triggerComplete && s.current >= s.total {
+ s.current = s.total
+ s.completed = true
+ go b.refreshTillShutdown()
+ }
+ }:
+ case <-b.done:
+ }
+}
+
+// DecoratorEwmaUpdate updates all EWMA based decorators. Should be
+// called on each iteration, because EWMA's unit of measure is an
+// iteration's duration. Panics if called before *Bar.Incr... family
+// methods.
+func (b *Bar) DecoratorEwmaUpdate(dur time.Duration) {
+ select {
+ case b.operateState <- func(s *bState) {
+ ewmaIterationUpdate(false, s, dur)
+ }:
+ case <-b.done:
+ ewmaIterationUpdate(true, b.cacheState, dur)
+ }
+}
+
+// DecoratorAverageAdjust adjusts all average based decorators. Call
+// if you need to adjust start time of all average based decorators
+// or after progress resume.
+func (b *Bar) DecoratorAverageAdjust(start time.Time) {
+ select {
+ case b.operateState <- func(s *bState) {
+ for _, d := range s.averageDecorators {
+ d.AverageAdjust(start)
+ }
+ }:
+ case <-b.done:
+ }
+}
+
+// SetPriority changes bar's order among multiple bars. Zero is highest
+// priority, i.e. bar will be on top. If you don't need to set priority
+// dynamically, better use BarPriority option.
+func (b *Bar) SetPriority(priority int) {
+ select {
+ case <-b.done:
+ default:
+ b.container.setBarPriority(b, priority)
+ }
+}
+
+// Abort interrupts bar's running goroutine. Call this, if you'd like
+// to stop/remove bar before completion event. It has no effect after
+// completion event. If drop is true bar will be removed as well.
+func (b *Bar) Abort(drop bool) {
+ select {
+ case <-b.done:
+ default:
+ if drop {
+ b.container.dropBar(b)
+ }
+ b.cancel()
+ }
+}
+
+// Completed reports whether the bar is in completed state.
+func (b *Bar) Completed() bool {
+ select {
+ case b.operateState <- func(s *bState) { b.completed <- s.completed }:
+ return <-b.completed
+ case <-b.done:
+ return true
+ }
+}
+
+func (b *Bar) serve(ctx context.Context, s *bState) {
+ defer b.container.bwg.Done()
+ for {
+ select {
+ case op := <-b.operateState:
+ op(s)
+ case <-ctx.Done():
+ b.cacheState = s
+ close(b.done)
+ // Notifying decorators about shutdown event
+ for _, sl := range s.shutdownListeners {
+ sl.Shutdown()
+ }
+ return
+ }
+ }
+}
+
+func (b *Bar) render(tw int) {
+ select {
+ case b.operateState <- func(s *bState) {
+ stat := newStatistics(tw, s)
+ defer func() {
+ // recovering if user defined decorator panics for example
+ if p := recover(); p != nil {
+ if b.recoveredPanic == nil {
+ s.extender = makePanicExtender(p)
+ b.toShutdown = !b.toShutdown
+ b.recoveredPanic = p
+ }
+ frame, lines := s.extender(nil, s.reqWidth, stat)
+ b.extendedLines = lines
+ b.frameCh <- frame
+ b.dlogger.Println(p)
+ }
+ s.completeFlushed = s.completed
+ }()
+ frame, lines := s.extender(s.draw(stat), s.reqWidth, stat)
+ b.extendedLines = lines
+ b.toShutdown = s.completed && !s.completeFlushed
+ b.frameCh <- frame
+ }:
+ case <-b.done:
+ s := b.cacheState
+ stat := newStatistics(tw, s)
+ var r io.Reader
+ if b.recoveredPanic == nil {
+ r = s.draw(stat)
+ }
+ frame, lines := s.extender(r, s.reqWidth, stat)
+ b.extendedLines = lines
+ b.frameCh <- frame
+ }
+}
+
+func (b *Bar) subscribeDecorators() {
+ var averageDecorators []decor.AverageDecorator
+ var ewmaDecorators []decor.EwmaDecorator
+ var shutdownListeners []decor.ShutdownListener
+ b.TraverseDecorators(func(d decor.Decorator) {
+ if d, ok := d.(decor.AverageDecorator); ok {
+ averageDecorators = append(averageDecorators, d)
+ }
+ if d, ok := d.(decor.EwmaDecorator); ok {
+ ewmaDecorators = append(ewmaDecorators, d)
+ }
+ if d, ok := d.(decor.ShutdownListener); ok {
+ shutdownListeners = append(shutdownListeners, d)
+ }
+ })
+ select {
+ case b.operateState <- func(s *bState) {
+ s.averageDecorators = averageDecorators
+ s.ewmaDecorators = ewmaDecorators
+ s.shutdownListeners = shutdownListeners
+ }:
+ b.hasEwmaDecorators = len(ewmaDecorators) != 0
+ case <-b.done:
+ }
+}
+
+func (b *Bar) refreshTillShutdown() {
+ for {
+ select {
+ case b.container.refreshCh <- time.Now():
+ case <-b.done:
+ return
+ }
+ }
+}
+
+func (b *Bar) wSyncTable() [][]chan int {
+ select {
+ case b.operateState <- func(s *bState) { b.syncTableCh <- s.wSyncTable() }:
+ return <-b.syncTableCh
+ case <-b.done:
+ return b.cacheState.wSyncTable()
+ }
+}
+
+func (s *bState) draw(stat decor.Statistics) io.Reader {
+ nlr := strings.NewReader("\n")
+ tw := stat.AvailableWidth
+ for _, d := range s.pDecorators {
+ str := d.Decor(stat)
+ stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str))
+ s.bufP.WriteString(str)
+ }
+ if stat.AvailableWidth < 1 {
+ trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(s.bufP.String()), tw, "…"))
+ s.bufP.Reset()
+ return io.MultiReader(trunc, nlr)
+ }
+
+ if !s.trimSpace && stat.AvailableWidth > 1 {
+ stat.AvailableWidth -= 2
+ s.bufB.WriteByte(' ')
+ defer s.bufB.WriteByte(' ')
+ }
+
+ tw = stat.AvailableWidth
+ for _, d := range s.aDecorators {
+ str := d.Decor(stat)
+ stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str))
+ s.bufA.WriteString(str)
+ }
+ if stat.AvailableWidth < 1 {
+ trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(s.bufA.String()), tw, "…"))
+ s.bufA.Reset()
+ return io.MultiReader(s.bufP, s.bufB, trunc, nlr)
+ }
+
+ s.filler.Fill(s.bufB, s.reqWidth, stat)
+
+ return io.MultiReader(s.bufP, s.bufB, s.bufA, nlr)
+}
+
+func (s *bState) wSyncTable() [][]chan int {
+ columns := make([]chan int, 0, len(s.pDecorators)+len(s.aDecorators))
+ var pCount int
+ for _, d := range s.pDecorators {
+ if ch, ok := d.Sync(); ok {
+ columns = append(columns, ch)
+ pCount++
+ }
+ }
+ var aCount int
+ for _, d := range s.aDecorators {
+ if ch, ok := d.Sync(); ok {
+ columns = append(columns, ch)
+ aCount++
+ }
+ }
+ table := make([][]chan int, 2)
+ table[0] = columns[0:pCount]
+ table[1] = columns[pCount : pCount+aCount : pCount+aCount]
+ return table
+}
+
+func newStatistics(tw int, s *bState) decor.Statistics {
+ return decor.Statistics{
+ ID: s.id,
+ AvailableWidth: tw,
+ Total: s.total,
+ Current: s.current,
+ Refill: s.refill,
+ Completed: s.completeFlushed,
+ }
+}
+
+func extractBaseDecorator(d decor.Decorator) decor.Decorator {
+ if d, ok := d.(decor.Wrapper); ok {
+ return extractBaseDecorator(d.Base())
+ }
+ return d
+}
+
+func ewmaIterationUpdate(done bool, s *bState, dur time.Duration) {
+ if !done && !s.iterated {
+ panic("increment required before ewma iteration update")
+ } else {
+ s.iterated = false
+ }
+ for _, d := range s.ewmaDecorators {
+ d.EwmaUpdate(s.lastN, dur)
+ }
+}
+
+func makePanicExtender(p interface{}) extenderFunc {
+ pstr := fmt.Sprint(p)
+ stack := debug.Stack()
+ stackLines := bytes.Count(stack, []byte("\n"))
+ return func(_ io.Reader, _ int, st decor.Statistics) (io.Reader, int) {
+ mr := io.MultiReader(
+ strings.NewReader(runewidth.Truncate(pstr, st.AvailableWidth, "…")),
+ strings.NewReader(fmt.Sprintf("\n%#v\n", st)),
+ bytes.NewReader(stack),
+ )
+ return mr, stackLines + 1
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_filler.go b/vendor/github.com/vbauerster/mpb/v7/bar_filler.go
new file mode 100644
index 000000000..a69087c47
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/bar_filler.go
@@ -0,0 +1,39 @@
+package mpb
+
+import (
+ "io"
+
+ "github.com/vbauerster/mpb/v7/decor"
+)
+
+// BarFiller interface.
+// Bar (without decorators) renders itself by calling BarFiller's Fill method.
+//
+// reqWidth is requested width, set by `func WithWidth(int) ContainerOption`.
+// If not set, it defaults to terminal width.
+//
+// Default implementations can be obtained via:
+//
+// func NewBarFiller(BarStyle()) BarFiller
+// func NewBarFiller(SpinnerStyle()) BarFiller
+//
+type BarFiller interface {
+ Fill(w io.Writer, reqWidth int, stat decor.Statistics)
+}
+
+// BarFillerBuilder interface.
+type BarFillerBuilder interface {
+ Build() BarFiller
+}
+
+// BarFillerFunc is function type adapter to convert function into BarFiller.
+type BarFillerFunc func(w io.Writer, reqWidth int, stat decor.Statistics)
+
+func (f BarFillerFunc) Fill(w io.Writer, reqWidth int, stat decor.Statistics) {
+ f(w, reqWidth, stat)
+}
+
+// NewBarFiller constructs a BarFiller from provided BarFillerBuilder.
+func NewBarFiller(b BarFillerBuilder) BarFiller {
+ return b.Build()
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_filler_bar.go b/vendor/github.com/vbauerster/mpb/v7/bar_filler_bar.go
new file mode 100644
index 000000000..e30d4921c
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/bar_filler_bar.go
@@ -0,0 +1,219 @@
+package mpb
+
+import (
+ "io"
+
+ "github.com/acarl005/stripansi"
+ "github.com/mattn/go-runewidth"
+ "github.com/vbauerster/mpb/v7/decor"
+ "github.com/vbauerster/mpb/v7/internal"
+)
+
+const (
+ iLbound = iota
+ iRbound
+ iFiller
+ iRefiller
+ iPadding
+ components
+)
+
+// BarStyleComposer interface.
+type BarStyleComposer interface {
+ BarFillerBuilder
+ Lbound(string) BarStyleComposer
+ Rbound(string) BarStyleComposer
+ Filler(string) BarStyleComposer
+ Refiller(string) BarStyleComposer
+ Padding(string) BarStyleComposer
+ Tip(...string) BarStyleComposer
+ Reverse() BarStyleComposer
+}
+
+type bFiller struct {
+ components [components]*component
+ tip struct {
+ count uint
+ frames []*component
+ }
+ flush func(dst io.Writer, filling, padding [][]byte)
+}
+
+type component struct {
+ width int
+ bytes []byte
+}
+
+type barStyle struct {
+ lbound string
+ rbound string
+ filler string
+ refiller string
+ padding string
+ tip []string
+ rev bool
+}
+
+// BarStyle constructs default bar style which can be altered via
+// BarStyleComposer interface.
+func BarStyle() BarStyleComposer {
+ return &barStyle{
+ lbound: "[",
+ rbound: "]",
+ filler: "=",
+ refiller: "+",
+ padding: "-",
+ tip: []string{">"},
+ }
+}
+
+func (s *barStyle) Lbound(bound string) BarStyleComposer {
+ s.lbound = bound
+ return s
+}
+
+func (s *barStyle) Rbound(bound string) BarStyleComposer {
+ s.rbound = bound
+ return s
+}
+
+func (s *barStyle) Filler(filler string) BarStyleComposer {
+ s.filler = filler
+ return s
+}
+
+func (s *barStyle) Refiller(refiller string) BarStyleComposer {
+ s.refiller = refiller
+ return s
+}
+
+func (s *barStyle) Padding(padding string) BarStyleComposer {
+ s.padding = padding
+ return s
+}
+
+func (s *barStyle) Tip(tip ...string) BarStyleComposer {
+ if len(tip) != 0 {
+ s.tip = append(s.tip[:0], tip...)
+ }
+ return s
+}
+
+func (s *barStyle) Reverse() BarStyleComposer {
+ s.rev = true
+ return s
+}
+
+func (s *barStyle) Build() BarFiller {
+ bf := new(bFiller)
+ if s.rev {
+ bf.flush = func(dst io.Writer, filling, padding [][]byte) {
+ flush(dst, padding, filling)
+ }
+ } else {
+ bf.flush = flush
+ }
+ bf.components[iLbound] = &component{
+ width: runewidth.StringWidth(stripansi.Strip(s.lbound)),
+ bytes: []byte(s.lbound),
+ }
+ bf.components[iRbound] = &component{
+ width: runewidth.StringWidth(stripansi.Strip(s.rbound)),
+ bytes: []byte(s.rbound),
+ }
+ bf.components[iFiller] = &component{
+ width: runewidth.StringWidth(stripansi.Strip(s.filler)),
+ bytes: []byte(s.filler),
+ }
+ bf.components[iRefiller] = &component{
+ width: runewidth.StringWidth(stripansi.Strip(s.refiller)),
+ bytes: []byte(s.refiller),
+ }
+ bf.components[iPadding] = &component{
+ width: runewidth.StringWidth(stripansi.Strip(s.padding)),
+ bytes: []byte(s.padding),
+ }
+ bf.tip.frames = make([]*component, len(s.tip))
+ for i, t := range s.tip {
+ bf.tip.frames[i] = &component{
+ width: runewidth.StringWidth(stripansi.Strip(t)),
+ bytes: []byte(t),
+ }
+ }
+ return bf
+}
+
+func (s *bFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
+ width = internal.CheckRequestedWidth(width, stat.AvailableWidth)
+ brackets := s.components[iLbound].width + s.components[iRbound].width
+ if width < brackets {
+ return
+ }
+ // don't count brackets as progress
+ width -= brackets
+
+ w.Write(s.components[iLbound].bytes)
+ defer w.Write(s.components[iRbound].bytes)
+
+ curWidth := int(internal.PercentageRound(stat.Total, stat.Current, width))
+ refWidth, filled := 0, curWidth
+ filling := make([][]byte, 0, curWidth)
+
+ if curWidth > 0 && curWidth != width {
+ tipFrame := s.tip.frames[s.tip.count%uint(len(s.tip.frames))]
+ filling = append(filling, tipFrame.bytes)
+ curWidth -= tipFrame.width
+ s.tip.count++
+ }
+
+ if stat.Refill > 0 && curWidth > 0 {
+ refWidth = int(internal.PercentageRound(stat.Total, int64(stat.Refill), width))
+ if refWidth > curWidth {
+ refWidth = curWidth
+ }
+ curWidth -= refWidth
+ }
+
+ for curWidth > 0 && curWidth >= s.components[iFiller].width {
+ filling = append(filling, s.components[iFiller].bytes)
+ curWidth -= s.components[iFiller].width
+ if s.components[iFiller].width == 0 {
+ break
+ }
+ }
+
+ for refWidth > 0 && refWidth >= s.components[iRefiller].width {
+ filling = append(filling, s.components[iRefiller].bytes)
+ refWidth -= s.components[iRefiller].width
+ if s.components[iRefiller].width == 0 {
+ break
+ }
+ }
+
+ filled -= curWidth + refWidth
+ padWidth := width - filled
+ padding := make([][]byte, 0, padWidth)
+ for padWidth > 0 && padWidth >= s.components[iPadding].width {
+ padding = append(padding, s.components[iPadding].bytes)
+ padWidth -= s.components[iPadding].width
+ if s.components[iPadding].width == 0 {
+ break
+ }
+ }
+
+ for padWidth > 0 {
+ padding = append(padding, []byte("…"))
+ padWidth--
+ }
+
+ s.flush(w, filling, padding)
+}
+
+func flush(dst io.Writer, filling, padding [][]byte) {
+ for i := len(filling) - 1; i >= 0; i-- {
+ dst.Write(filling[i])
+ }
+ for i := 0; i < len(padding); i++ {
+ dst.Write(padding[i])
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_filler_spinner.go b/vendor/github.com/vbauerster/mpb/v7/bar_filler_spinner.go
new file mode 100644
index 000000000..58ae1c532
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/bar_filler_spinner.go
@@ -0,0 +1,87 @@
+package mpb
+
+import (
+ "io"
+ "strings"
+
+ "github.com/acarl005/stripansi"
+ "github.com/mattn/go-runewidth"
+ "github.com/vbauerster/mpb/v7/decor"
+ "github.com/vbauerster/mpb/v7/internal"
+)
+
+const (
+ positionLeft = 1 + iota
+ positionRight
+)
+
+// SpinnerStyleComposer interface.
+type SpinnerStyleComposer interface {
+ BarFillerBuilder
+ PositionLeft() SpinnerStyleComposer
+ PositionRight() SpinnerStyleComposer
+}
+
+type sFiller struct {
+ count uint
+ position uint
+ frames []string
+}
+
+type spinnerStyle struct {
+ position uint
+ frames []string
+}
+
+// SpinnerStyle constructs default spinner style which can be altered via
+// SpinnerStyleComposer interface.
+func SpinnerStyle(frames ...string) SpinnerStyleComposer {
+ ss := new(spinnerStyle)
+ if len(frames) != 0 {
+ ss.frames = append(ss.frames, frames...)
+ } else {
+ ss.frames = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
+ }
+ return ss
+}
+
+func (s *spinnerStyle) PositionLeft() SpinnerStyleComposer {
+ s.position = positionLeft
+ return s
+}
+
+func (s *spinnerStyle) PositionRight() SpinnerStyleComposer {
+ s.position = positionRight
+ return s
+}
+
+func (s *spinnerStyle) Build() BarFiller {
+ sf := &sFiller{
+ position: s.position,
+ frames: s.frames,
+ }
+ return sf
+}
+
+func (s *sFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
+ width = internal.CheckRequestedWidth(width, stat.AvailableWidth)
+
+ frame := s.frames[s.count%uint(len(s.frames))]
+ frameWidth := runewidth.StringWidth(stripansi.Strip(frame))
+
+ if width < frameWidth {
+ return
+ }
+
+ rest := width - frameWidth
+ switch s.position {
+ case positionLeft:
+ io.WriteString(w, frame+strings.Repeat(" ", rest))
+ case positionRight:
+ io.WriteString(w, strings.Repeat(" ", rest)+frame)
+ default:
+ str := strings.Repeat(" ", rest/2) + frame + strings.Repeat(" ", rest/2+rest%2)
+ io.WriteString(w, str)
+ }
+ s.count++
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_option.go b/vendor/github.com/vbauerster/mpb/v7/bar_option.go
new file mode 100644
index 000000000..46b7de0bf
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/bar_option.go
@@ -0,0 +1,153 @@
+package mpb
+
+import (
+ "bytes"
+ "io"
+
+ "github.com/vbauerster/mpb/v7/decor"
+ "github.com/vbauerster/mpb/v7/internal"
+)
+
+// BarOption is a func option to alter default behavior of a bar.
+type BarOption func(*bState)
+
+func (s *bState) addDecorators(dest *[]decor.Decorator, decorators ...decor.Decorator) {
+ type mergeWrapper interface {
+ MergeUnwrap() []decor.Decorator
+ }
+ for _, decorator := range decorators {
+ if mw, ok := decorator.(mergeWrapper); ok {
+ *dest = append(*dest, mw.MergeUnwrap()...)
+ }
+ *dest = append(*dest, decorator)
+ }
+}
+
+// AppendDecorators let you inject decorators to the bar's right side.
+func AppendDecorators(decorators ...decor.Decorator) BarOption {
+ return func(s *bState) {
+ s.addDecorators(&s.aDecorators, decorators...)
+ }
+}
+
+// PrependDecorators let you inject decorators to the bar's left side.
+func PrependDecorators(decorators ...decor.Decorator) BarOption {
+ return func(s *bState) {
+ s.addDecorators(&s.pDecorators, decorators...)
+ }
+}
+
+// BarID sets bar id.
+func BarID(id int) BarOption {
+ return func(s *bState) {
+ s.id = id
+ }
+}
+
+// BarWidth sets bar width independent of the container.
+func BarWidth(width int) BarOption {
+ return func(s *bState) {
+ s.reqWidth = width
+ }
+}
+
+// BarQueueAfter queues this (being constructed) bar to relplace
+// runningBar after it has been completed.
+func BarQueueAfter(runningBar *Bar) BarOption {
+ if runningBar == nil {
+ return nil
+ }
+ return func(s *bState) {
+ s.runningBar = runningBar
+ }
+}
+
+// BarRemoveOnComplete removes both bar's filler and its decorators
+// on complete event.
+func BarRemoveOnComplete() BarOption {
+ return func(s *bState) {
+ s.dropOnComplete = true
+ }
+}
+
+// BarFillerClearOnComplete clears bar's filler on complete event.
+// It's shortcut for BarFillerOnComplete("").
+func BarFillerClearOnComplete() BarOption {
+ return BarFillerOnComplete("")
+}
+
+// BarFillerOnComplete replaces bar's filler with message, on complete event.
+func BarFillerOnComplete(message string) BarOption {
+ return BarFillerMiddleware(func(base BarFiller) BarFiller {
+ return BarFillerFunc(func(w io.Writer, reqWidth int, st decor.Statistics) {
+ if st.Completed {
+ io.WriteString(w, message)
+ } else {
+ base.Fill(w, reqWidth, st)
+ }
+ })
+ })
+}
+
+// BarFillerMiddleware provides a way to augment the underlying BarFiller.
+func BarFillerMiddleware(middle func(BarFiller) BarFiller) BarOption {
+ return func(s *bState) {
+ s.middleware = middle
+ }
+}
+
+// BarPriority sets bar's priority. Zero is highest priority, i.e. bar
+// will be on top. If `BarReplaceOnComplete` option is supplied, this
+// option is ignored.
+func BarPriority(priority int) BarOption {
+ return func(s *bState) {
+ s.priority = priority
+ }
+}
+
+// BarExtender provides a way to extend bar to the next new line.
+func BarExtender(filler BarFiller) BarOption {
+ if filler == nil {
+ return nil
+ }
+ return func(s *bState) {
+ s.extender = makeExtenderFunc(filler)
+ }
+}
+
+func makeExtenderFunc(filler BarFiller) extenderFunc {
+ buf := new(bytes.Buffer)
+ return func(r io.Reader, reqWidth int, st decor.Statistics) (io.Reader, int) {
+ filler.Fill(buf, reqWidth, st)
+ return io.MultiReader(r, buf), bytes.Count(buf.Bytes(), []byte("\n"))
+ }
+}
+
+// BarFillerTrim removes leading and trailing space around the underlying BarFiller.
+func BarFillerTrim() BarOption {
+ return func(s *bState) {
+ s.trimSpace = true
+ }
+}
+
+// BarNoPop disables bar pop out of container. Effective when
+// PopCompletedMode of container is enabled.
+func BarNoPop() BarOption {
+ return func(s *bState) {
+ s.noPop = true
+ }
+}
+
+// BarOptional will invoke provided option only when pick is true.
+func BarOptional(option BarOption, pick bool) BarOption {
+ return BarOptOn(option, internal.Predicate(pick))
+}
+
+// BarOptOn will invoke provided option only when higher order predicate
+// evaluates to true.
+func BarOptOn(option BarOption, predicate func() bool) BarOption {
+ if predicate() {
+ return option
+ }
+ return nil
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/container_option.go b/vendor/github.com/vbauerster/mpb/v7/container_option.go
new file mode 100644
index 000000000..e4254f662
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/container_option.go
@@ -0,0 +1,112 @@
+package mpb
+
+import (
+ "io"
+ "io/ioutil"
+ "sync"
+ "time"
+
+ "github.com/vbauerster/mpb/v7/internal"
+)
+
+// ContainerOption is a func option to alter default behavior of a bar
+// container. Container term refers to a Progress struct which can
+// hold one or more Bars.
+type ContainerOption func(*pState)
+
+// WithWaitGroup provides means to have a single joint point. If
+// *sync.WaitGroup is provided, you can safely call just p.Wait()
+// without calling Wait() on provided *sync.WaitGroup. Makes sense
+// when there are more than one bar to render.
+func WithWaitGroup(wg *sync.WaitGroup) ContainerOption {
+ return func(s *pState) {
+ s.uwg = wg
+ }
+}
+
+// WithWidth sets container width. If not set it defaults to terminal
+// width. A bar added to the container will inherit its width, unless
+// overridden by `func BarWidth(int) BarOption`.
+func WithWidth(width int) ContainerOption {
+ return func(s *pState) {
+ s.reqWidth = width
+ }
+}
+
+// WithRefreshRate overrides default 120ms refresh rate.
+func WithRefreshRate(d time.Duration) ContainerOption {
+ return func(s *pState) {
+ s.rr = d
+ }
+}
+
+// WithManualRefresh disables internal auto refresh time.Ticker.
+// Refresh will occur upon receive value from provided ch.
+func WithManualRefresh(ch <-chan interface{}) ContainerOption {
+ return func(s *pState) {
+ s.externalRefresh = ch
+ }
+}
+
+// WithRenderDelay delays rendering. By default rendering starts as
+// soon as bar is added, with this option it's possible to delay
+// rendering process by keeping provided chan unclosed. In other words
+// rendering will start as soon as provided chan is closed.
+func WithRenderDelay(ch <-chan struct{}) ContainerOption {
+ return func(s *pState) {
+ s.renderDelay = ch
+ }
+}
+
+// WithShutdownNotifier provided chanel will be closed, after all bars
+// have been rendered.
+func WithShutdownNotifier(ch chan struct{}) ContainerOption {
+ return func(s *pState) {
+ s.shutdownNotifier = ch
+ }
+}
+
+// WithOutput overrides default os.Stdout output. Setting it to nil
+// will effectively disable auto refresh rate and discard any output,
+// useful if you want to disable progress bars with little overhead.
+func WithOutput(w io.Writer) ContainerOption {
+ return func(s *pState) {
+ if w == nil {
+ s.output = ioutil.Discard
+ s.outputDiscarded = true
+ return
+ }
+ s.output = w
+ }
+}
+
+// WithDebugOutput sets debug output.
+func WithDebugOutput(w io.Writer) ContainerOption {
+ if w == nil {
+ return nil
+ }
+ return func(s *pState) {
+ s.debugOut = w
+ }
+}
+
+// PopCompletedMode will pop and stop rendering completed bars.
+func PopCompletedMode() ContainerOption {
+ return func(s *pState) {
+ s.popCompleted = true
+ }
+}
+
+// ContainerOptional will invoke provided option only when pick is true.
+func ContainerOptional(option ContainerOption, pick bool) ContainerOption {
+ return ContainerOptOn(option, internal.Predicate(pick))
+}
+
+// ContainerOptOn will invoke provided option only when higher order
+// predicate evaluates to true.
+func ContainerOptOn(option ContainerOption, predicate func() bool) ContainerOption {
+ if predicate() {
+ return option
+ }
+ return nil
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/doc.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/doc.go
new file mode 100644
index 000000000..93c8f8268
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/doc.go
@@ -0,0 +1,2 @@
+// Package cwriter is a console writer abstraction for the underlying OS.
+package cwriter
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_bsd.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_bsd.go
new file mode 100644
index 000000000..4e3564ece
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_bsd.go
@@ -0,0 +1,7 @@
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package cwriter
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TIOCGETA
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_linux.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_linux.go
new file mode 100644
index 000000000..253f12dd2
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_linux.go
@@ -0,0 +1,7 @@
+// +build aix linux
+
+package cwriter
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TCGETS
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_solaris.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_solaris.go
new file mode 100644
index 000000000..4b29ff5c0
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_solaris.go
@@ -0,0 +1,7 @@
+// +build solaris
+
+package cwriter
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TCGETA
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go
new file mode 100644
index 000000000..1ade54761
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go
@@ -0,0 +1,84 @@
+package cwriter
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "os"
+ "strconv"
+)
+
+// ErrNotTTY not a TeleTYpewriter error.
+var ErrNotTTY = errors.New("not a terminal")
+
+// http://ascii-table.com/ansi-escape-sequences.php
+const (
+ escOpen = "\x1b["
+ cuuAndEd = "A\x1b[J"
+)
+
+// Writer is a buffered the writer that updates the terminal. The
+// contents of writer will be flushed when Flush is called.
+type Writer struct {
+ out io.Writer
+ buf bytes.Buffer
+ lineCount int
+ fd int
+ isTerminal bool
+}
+
+// New returns a new Writer with defaults.
+func New(out io.Writer) *Writer {
+ w := &Writer{out: out}
+ if f, ok := out.(*os.File); ok {
+ w.fd = int(f.Fd())
+ w.isTerminal = IsTerminal(w.fd)
+ }
+ return w
+}
+
+// Flush flushes the underlying buffer.
+func (w *Writer) Flush(lineCount int) (err error) {
+ // some terminals interpret 'cursor up 0' as 'cursor up 1'
+ if w.lineCount > 0 {
+ err = w.clearLines()
+ if err != nil {
+ return
+ }
+ }
+ w.lineCount = lineCount
+ _, err = w.buf.WriteTo(w.out)
+ return
+}
+
+// Write appends the contents of p to the underlying buffer.
+func (w *Writer) Write(p []byte) (n int, err error) {
+ return w.buf.Write(p)
+}
+
+// WriteString writes string to the underlying buffer.
+func (w *Writer) WriteString(s string) (n int, err error) {
+ return w.buf.WriteString(s)
+}
+
+// ReadFrom reads from the provided io.Reader and writes to the
+// underlying buffer.
+func (w *Writer) ReadFrom(r io.Reader) (n int64, err error) {
+ return w.buf.ReadFrom(r)
+}
+
+// GetWidth returns width of underlying terminal.
+func (w *Writer) GetWidth() (int, error) {
+ if !w.isTerminal {
+ return -1, ErrNotTTY
+ }
+ tw, _, err := GetSize(w.fd)
+ return tw, err
+}
+
+func (w *Writer) ansiCuuAndEd() (err error) {
+ buf := make([]byte, 8)
+ buf = strconv.AppendInt(buf[:copy(buf, escOpen)], int64(w.lineCount), 10)
+ _, err = w.out.Write(append(buf, cuuAndEd...))
+ return
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go
new file mode 100644
index 000000000..f54a5d06b
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go
@@ -0,0 +1,26 @@
+// +build !windows
+
+package cwriter
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+func (w *Writer) clearLines() error {
+ return w.ansiCuuAndEd()
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+ ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
+ if err != nil {
+ return -1, -1, err
+ }
+ return int(ws.Col), int(ws.Row), nil
+}
+
+// IsTerminal returns whether the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+ _, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+ return err == nil
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_windows.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_windows.go
new file mode 100644
index 000000000..1a69c81ac
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_windows.go
@@ -0,0 +1,73 @@
+// +build windows
+
+package cwriter
+
+import (
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var kernel32 = windows.NewLazySystemDLL("kernel32.dll")
+
+var (
+ procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
+ procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
+)
+
+func (w *Writer) clearLines() error {
+ if !w.isTerminal {
+ // hope it's cygwin or similar
+ return w.ansiCuuAndEd()
+ }
+
+ var info windows.ConsoleScreenBufferInfo
+ if err := windows.GetConsoleScreenBufferInfo(windows.Handle(w.fd), &info); err != nil {
+ return err
+ }
+
+ info.CursorPosition.Y -= int16(w.lineCount)
+ if info.CursorPosition.Y < 0 {
+ info.CursorPosition.Y = 0
+ }
+ _, _, _ = procSetConsoleCursorPosition.Call(
+ uintptr(w.fd),
+ uintptr(uint32(uint16(info.CursorPosition.Y))<<16|uint32(uint16(info.CursorPosition.X))),
+ )
+
+ // clear the lines
+ cursor := &windows.Coord{
+ X: info.Window.Left,
+ Y: info.CursorPosition.Y,
+ }
+ count := uint32(info.Size.X) * uint32(w.lineCount)
+ _, _, _ = procFillConsoleOutputCharacter.Call(
+ uintptr(w.fd),
+ uintptr(' '),
+ uintptr(count),
+ *(*uintptr)(unsafe.Pointer(cursor)),
+ uintptr(unsafe.Pointer(new(uint32))),
+ )
+ return nil
+}
+
+// GetSize returns the visible dimensions of the given terminal.
+//
+// These dimensions don't include any scrollback buffer height.
+func GetSize(fd int) (width, height int, err error) {
+ var info windows.ConsoleScreenBufferInfo
+ if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
+ return 0, 0, err
+ }
+ // terminal.GetSize from crypto/ssh adds "+ 1" to both width and height:
+ // https://go.googlesource.com/crypto/+/refs/heads/release-branch.go1.14/ssh/terminal/util_windows.go#75
+ // but looks like this is a root cause of issue #66, so removing both "+ 1" have fixed it.
+ return int(info.Window.Right - info.Window.Left), int(info.Window.Bottom - info.Window.Top), nil
+}
+
+// IsTerminal returns whether the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+ var st uint32
+ err := windows.GetConsoleMode(windows.Handle(fd), &st)
+ return err == nil
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/any.go b/vendor/github.com/vbauerster/mpb/v7/decor/any.go
new file mode 100644
index 000000000..39518f594
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/any.go
@@ -0,0 +1,21 @@
+package decor
+
+// Any decorator displays text, that can be changed during decorator's
+// lifetime via provided DecorFunc.
+//
+// `fn` DecorFunc callback
+//
+// `wcc` optional WC config
+//
+func Any(fn DecorFunc, wcc ...WC) Decorator {
+ return &any{initWC(wcc...), fn}
+}
+
+type any struct {
+ WC
+ fn DecorFunc
+}
+
+func (d *any) Decor(s Statistics) string {
+ return d.FormatMsg(d.fn(s))
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/counters.go b/vendor/github.com/vbauerster/mpb/v7/decor/counters.go
new file mode 100644
index 000000000..4a5343d41
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/counters.go
@@ -0,0 +1,243 @@
+package decor
+
+import (
+ "fmt"
+ "strings"
+)
+
+const (
+ _ = iota
+ UnitKiB
+ UnitKB
+)
+
+// CountersNoUnit is a wrapper around Counters with no unit param.
+func CountersNoUnit(pairFmt string, wcc ...WC) Decorator {
+ return Counters(0, pairFmt, wcc...)
+}
+
+// CountersKibiByte is a wrapper around Counters with predefined unit
+// UnitKiB (bytes/1024).
+func CountersKibiByte(pairFmt string, wcc ...WC) Decorator {
+ return Counters(UnitKiB, pairFmt, wcc...)
+}
+
+// CountersKiloByte is a wrapper around Counters with predefined unit
+// UnitKB (bytes/1000).
+func CountersKiloByte(pairFmt string, wcc ...WC) Decorator {
+ return Counters(UnitKB, pairFmt, wcc...)
+}
+
+// Counters decorator with dynamic unit measure adjustment.
+//
+// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
+//
+// `pairFmt` printf compatible verbs for current and total pair
+//
+// `wcc` optional WC config
+//
+// pairFmt example if unit=UnitKB:
+//
+// pairFmt="%.1f / %.1f" output: "1.0MB / 12.0MB"
+// pairFmt="% .1f / % .1f" output: "1.0 MB / 12.0 MB"
+// pairFmt="%d / %d" output: "1MB / 12MB"
+// pairFmt="% d / % d" output: "1 MB / 12 MB"
+//
+func Counters(unit int, pairFmt string, wcc ...WC) Decorator {
+ producer := func(unit int, pairFmt string) DecorFunc {
+ if pairFmt == "" {
+ pairFmt = "%d / %d"
+ } else if strings.Count(pairFmt, "%") != 2 {
+ panic("expected pairFmt with exactly 2 verbs")
+ }
+ switch unit {
+ case UnitKiB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(pairFmt, SizeB1024(s.Current), SizeB1024(s.Total))
+ }
+ case UnitKB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(pairFmt, SizeB1000(s.Current), SizeB1000(s.Total))
+ }
+ default:
+ return func(s Statistics) string {
+ return fmt.Sprintf(pairFmt, s.Current, s.Total)
+ }
+ }
+ }
+ return Any(producer(unit, pairFmt), wcc...)
+}
+
+// TotalNoUnit is a wrapper around Total with no unit param.
+func TotalNoUnit(format string, wcc ...WC) Decorator {
+ return Total(0, format, wcc...)
+}
+
+// TotalKibiByte is a wrapper around Total with predefined unit
+// UnitKiB (bytes/1024).
+func TotalKibiByte(format string, wcc ...WC) Decorator {
+ return Total(UnitKiB, format, wcc...)
+}
+
+// TotalKiloByte is a wrapper around Total with predefined unit
+// UnitKB (bytes/1000).
+func TotalKiloByte(format string, wcc ...WC) Decorator {
+ return Total(UnitKB, format, wcc...)
+}
+
+// Total decorator with dynamic unit measure adjustment.
+//
+// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
+//
+// `format` printf compatible verb for Total
+//
+// `wcc` optional WC config
+//
+// format example if unit=UnitKiB:
+//
+// format="%.1f" output: "12.0MiB"
+// format="% .1f" output: "12.0 MiB"
+// format="%d" output: "12MiB"
+// format="% d" output: "12 MiB"
+//
+func Total(unit int, format string, wcc ...WC) Decorator {
+ producer := func(unit int, format string) DecorFunc {
+ if format == "" {
+ format = "%d"
+ } else if strings.Count(format, "%") != 1 {
+ panic("expected format with exactly 1 verb")
+ }
+
+ switch unit {
+ case UnitKiB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, SizeB1024(s.Total))
+ }
+ case UnitKB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, SizeB1000(s.Total))
+ }
+ default:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, s.Total)
+ }
+ }
+ }
+ return Any(producer(unit, format), wcc...)
+}
+
+// CurrentNoUnit is a wrapper around Current with no unit param.
+func CurrentNoUnit(format string, wcc ...WC) Decorator {
+ return Current(0, format, wcc...)
+}
+
+// CurrentKibiByte is a wrapper around Current with predefined unit
+// UnitKiB (bytes/1024).
+func CurrentKibiByte(format string, wcc ...WC) Decorator {
+ return Current(UnitKiB, format, wcc...)
+}
+
+// CurrentKiloByte is a wrapper around Current with predefined unit
+// UnitKB (bytes/1000).
+func CurrentKiloByte(format string, wcc ...WC) Decorator {
+ return Current(UnitKB, format, wcc...)
+}
+
+// Current decorator with dynamic unit measure adjustment.
+//
+// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
+//
+// `format` printf compatible verb for Current
+//
+// `wcc` optional WC config
+//
+// format example if unit=UnitKiB:
+//
+// format="%.1f" output: "12.0MiB"
+// format="% .1f" output: "12.0 MiB"
+// format="%d" output: "12MiB"
+// format="% d" output: "12 MiB"
+//
+func Current(unit int, format string, wcc ...WC) Decorator {
+ producer := func(unit int, format string) DecorFunc {
+ if format == "" {
+ format = "%d"
+ } else if strings.Count(format, "%") != 1 {
+ panic("expected format with exactly 1 verb")
+ }
+
+ switch unit {
+ case UnitKiB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, SizeB1024(s.Current))
+ }
+ case UnitKB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, SizeB1000(s.Current))
+ }
+ default:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, s.Current)
+ }
+ }
+ }
+ return Any(producer(unit, format), wcc...)
+}
+
+// InvertedCurrentNoUnit is a wrapper around InvertedCurrent with no unit param.
+func InvertedCurrentNoUnit(format string, wcc ...WC) Decorator {
+ return InvertedCurrent(0, format, wcc...)
+}
+
+// InvertedCurrentKibiByte is a wrapper around InvertedCurrent with predefined unit
+// UnitKiB (bytes/1024).
+func InvertedCurrentKibiByte(format string, wcc ...WC) Decorator {
+ return InvertedCurrent(UnitKiB, format, wcc...)
+}
+
+// InvertedCurrentKiloByte is a wrapper around InvertedCurrent with predefined unit
+// UnitKB (bytes/1000).
+func InvertedCurrentKiloByte(format string, wcc ...WC) Decorator {
+ return InvertedCurrent(UnitKB, format, wcc...)
+}
+
+// InvertedCurrent decorator with dynamic unit measure adjustment.
+//
+// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
+//
+// `format` printf compatible verb for InvertedCurrent
+//
+// `wcc` optional WC config
+//
+// format example if unit=UnitKiB:
+//
+// format="%.1f" output: "12.0MiB"
+// format="% .1f" output: "12.0 MiB"
+// format="%d" output: "12MiB"
+// format="% d" output: "12 MiB"
+//
+func InvertedCurrent(unit int, format string, wcc ...WC) Decorator {
+ producer := func(unit int, format string) DecorFunc {
+ if format == "" {
+ format = "%d"
+ } else if strings.Count(format, "%") != 1 {
+ panic("expected format with exactly 1 verb")
+ }
+
+ switch unit {
+ case UnitKiB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, SizeB1024(s.Total-s.Current))
+ }
+ case UnitKB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, SizeB1000(s.Total-s.Current))
+ }
+ default:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, s.Total-s.Current)
+ }
+ }
+ }
+ return Any(producer(unit, format), wcc...)
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/decorator.go b/vendor/github.com/vbauerster/mpb/v7/decor/decorator.go
new file mode 100644
index 000000000..e81fae367
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/decorator.go
@@ -0,0 +1,191 @@
+package decor
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/acarl005/stripansi"
+ "github.com/mattn/go-runewidth"
+)
+
+const (
+ // DidentRight bit specifies identation direction.
+ // |foo |b | With DidentRight
+ // | foo| b| Without DidentRight
+ DidentRight = 1 << iota
+
+ // DextraSpace bit adds extra space, makes sense with DSyncWidth only.
+ // When DidentRight bit set, the space will be added to the right,
+ // otherwise to the left.
+ DextraSpace
+
+ // DSyncWidth bit enables same column width synchronization.
+ // Effective with multiple bars only.
+ DSyncWidth
+
+ // DSyncWidthR is shortcut for DSyncWidth|DidentRight
+ DSyncWidthR = DSyncWidth | DidentRight
+
+ // DSyncSpace is shortcut for DSyncWidth|DextraSpace
+ DSyncSpace = DSyncWidth | DextraSpace
+
+ // DSyncSpaceR is shortcut for DSyncWidth|DextraSpace|DidentRight
+ DSyncSpaceR = DSyncWidth | DextraSpace | DidentRight
+)
+
+// TimeStyle enum.
+type TimeStyle int
+
+// TimeStyle kinds.
+const (
+ ET_STYLE_GO TimeStyle = iota
+ ET_STYLE_HHMMSS
+ ET_STYLE_HHMM
+ ET_STYLE_MMSS
+)
+
+// Statistics consists of progress related statistics, that Decorator
+// may need.
+type Statistics struct {
+ ID int
+ AvailableWidth int
+ Total int64
+ Current int64
+ Refill int64
+ Completed bool
+}
+
+// Decorator interface.
+// Most of the time there is no need to implement this interface
+// manually, as decor package already provides a wide range of decorators
+// which implement this interface. If however built-in decorators don't
+// meet your needs, you're free to implement your own one by implementing
+// this particular interface. The easy way to go is to convert a
+// `DecorFunc` into a `Decorator` interface by using provided
+// `func Any(DecorFunc, ...WC) Decorator`.
+type Decorator interface {
+ Configurator
+ Synchronizer
+ Decor(Statistics) string
+}
+
+// DecorFunc func type.
+// To be used with `func Any`(DecorFunc, ...WC) Decorator`.
+type DecorFunc func(Statistics) string
+
+// Synchronizer interface.
+// All decorators implement this interface implicitly. Its Sync
+// method exposes width sync channel, if DSyncWidth bit is set.
+type Synchronizer interface {
+ Sync() (chan int, bool)
+}
+
+// Configurator interface.
+type Configurator interface {
+ GetConf() WC
+ SetConf(WC)
+}
+
+// Wrapper interface.
+// If you're implementing custom Decorator by wrapping a built-in one,
+// it is necessary to implement this interface to retain functionality
+// of built-in Decorator.
+type Wrapper interface {
+ Base() Decorator
+}
+
+// EwmaDecorator interface.
+// EWMA based decorators should implement this one.
+type EwmaDecorator interface {
+ EwmaUpdate(int64, time.Duration)
+}
+
+// AverageDecorator interface.
+// Average decorators should implement this interface to provide start
+// time adjustment facility, for resume-able tasks.
+type AverageDecorator interface {
+ AverageAdjust(time.Time)
+}
+
+// ShutdownListener interface.
+// If decorator needs to be notified once upon bar shutdown event, so
+// this is the right interface to implement.
+type ShutdownListener interface {
+ Shutdown()
+}
+
+// Global convenience instances of WC with sync width bit set.
+// To be used with multiple bars only, i.e. not effective for single bar usage.
+var (
+ WCSyncWidth = WC{C: DSyncWidth}
+ WCSyncWidthR = WC{C: DSyncWidthR}
+ WCSyncSpace = WC{C: DSyncSpace}
+ WCSyncSpaceR = WC{C: DSyncSpaceR}
+)
+
+// WC is a struct with two public fields W and C, both of int type.
+// W represents width and C represents bit set of width related config.
+// A decorator should embed WC, to enable width synchronization.
+type WC struct {
+ W int
+ C int
+ fill func(s string, w int) string
+ wsync chan int
+}
+
+// FormatMsg formats final message according to WC.W and WC.C.
+// Should be called by any Decorator implementation.
+func (wc *WC) FormatMsg(msg string) string {
+ pureWidth := runewidth.StringWidth(msg)
+ stripWidth := runewidth.StringWidth(stripansi.Strip(msg))
+ maxCell := wc.W
+ if (wc.C & DSyncWidth) != 0 {
+ cellCount := stripWidth
+ if (wc.C & DextraSpace) != 0 {
+ cellCount++
+ }
+ wc.wsync <- cellCount
+ maxCell = <-wc.wsync
+ }
+ return wc.fill(msg, maxCell+(pureWidth-stripWidth))
+}
+
+// Init initializes width related config.
+func (wc *WC) Init() WC {
+ wc.fill = runewidth.FillLeft
+ if (wc.C & DidentRight) != 0 {
+ wc.fill = runewidth.FillRight
+ }
+ if (wc.C & DSyncWidth) != 0 {
+ // it's deliberate choice to override wsync on each Init() call,
+ // this way globals like WCSyncSpace can be reused
+ wc.wsync = make(chan int)
+ }
+ return *wc
+}
+
+// Sync is implementation of Synchronizer interface.
+func (wc *WC) Sync() (chan int, bool) {
+ if (wc.C&DSyncWidth) != 0 && wc.wsync == nil {
+ panic(fmt.Sprintf("%T is not initialized", wc))
+ }
+ return wc.wsync, (wc.C & DSyncWidth) != 0
+}
+
+// GetConf is implementation of Configurator interface.
+func (wc *WC) GetConf() WC {
+ return *wc
+}
+
+// SetConf is implementation of Configurator interface.
+func (wc *WC) SetConf(conf WC) {
+ *wc = conf.Init()
+}
+
+func initWC(wcc ...WC) WC {
+ var wc WC
+ for _, nwc := range wcc {
+ wc = nwc
+ }
+ return wc.Init()
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/doc.go b/vendor/github.com/vbauerster/mpb/v7/decor/doc.go
new file mode 100644
index 000000000..4e4299307
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/doc.go
@@ -0,0 +1,19 @@
+// Package decor provides common decorators for "github.com/vbauerster/mpb/v7" module.
+//
+// Some decorators returned by this package might have a closure state. It is ok to use
+// decorators concurrently, unless you share the same decorator among multiple
+// *mpb.Bar instances. To avoid data races, create new decorator per *mpb.Bar instance.
+//
+// Don't:
+//
+// p := mpb.New()
+// name := decor.Name("bar")
+// p.AddBar(100, mpb.AppendDecorators(name))
+// p.AddBar(100, mpb.AppendDecorators(name))
+//
+// Do:
+//
+// p := mpb.New()
+// p.AddBar(100, mpb.AppendDecorators(decor.Name("bar1")))
+// p.AddBar(100, mpb.AppendDecorators(decor.Name("bar2")))
+package decor
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/elapsed.go b/vendor/github.com/vbauerster/mpb/v7/decor/elapsed.go
new file mode 100644
index 000000000..e389f1581
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/elapsed.go
@@ -0,0 +1,35 @@
+package decor
+
+import (
+ "time"
+)
+
+// Elapsed decorator. It's wrapper of NewElapsed.
+//
+// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
+//
+// `wcc` optional WC config
+//
+func Elapsed(style TimeStyle, wcc ...WC) Decorator {
+ return NewElapsed(style, time.Now(), wcc...)
+}
+
+// NewElapsed returns elapsed time decorator.
+//
+// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
+//
+// `startTime` start time
+//
+// `wcc` optional WC config
+//
+func NewElapsed(style TimeStyle, startTime time.Time, wcc ...WC) Decorator {
+ var msg string
+ producer := chooseTimeProducer(style)
+ fn := func(s Statistics) string {
+ if !s.Completed {
+ msg = producer(time.Since(startTime))
+ }
+ return msg
+ }
+ return Any(fn, wcc...)
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/eta.go b/vendor/github.com/vbauerster/mpb/v7/decor/eta.go
new file mode 100644
index 000000000..d03caa735
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/eta.go
@@ -0,0 +1,203 @@
+package decor
+
+import (
+ "fmt"
+ "math"
+ "time"
+
+ "github.com/VividCortex/ewma"
+)
+
+// TimeNormalizer interface. Implementors could be passed into
+// MovingAverageETA, in order to affect i.e. normalize its output.
+type TimeNormalizer interface {
+ Normalize(time.Duration) time.Duration
+}
+
+// TimeNormalizerFunc is function type adapter to convert function
+// into TimeNormalizer.
+type TimeNormalizerFunc func(time.Duration) time.Duration
+
+func (f TimeNormalizerFunc) Normalize(src time.Duration) time.Duration {
+ return f(src)
+}
+
+// EwmaETA exponential-weighted-moving-average based ETA decorator.
+// For this decorator to work correctly you have to measure each
+// iteration's duration and pass it to the
+// *Bar.DecoratorEwmaUpdate(time.Duration) method after each increment.
+func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator {
+ var average ewma.MovingAverage
+ if age == 0 {
+ average = ewma.NewMovingAverage()
+ } else {
+ average = ewma.NewMovingAverage(age)
+ }
+ return MovingAverageETA(style, NewThreadSafeMovingAverage(average), nil, wcc...)
+}
+
+// MovingAverageETA decorator relies on MovingAverage implementation to calculate its average.
+//
+// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
+//
+// `average` implementation of MovingAverage interface
+//
+// `normalizer` available implementations are [FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer]
+//
+// `wcc` optional WC config
+//
+func MovingAverageETA(style TimeStyle, average ewma.MovingAverage, normalizer TimeNormalizer, wcc ...WC) Decorator {
+ d := &movingAverageETA{
+ WC: initWC(wcc...),
+ average: average,
+ normalizer: normalizer,
+ producer: chooseTimeProducer(style),
+ }
+ return d
+}
+
+type movingAverageETA struct {
+ WC
+ average ewma.MovingAverage
+ normalizer TimeNormalizer
+ producer func(time.Duration) string
+}
+
+func (d *movingAverageETA) Decor(s Statistics) string {
+ v := math.Round(d.average.Value())
+ remaining := time.Duration((s.Total - s.Current) * int64(v))
+ if d.normalizer != nil {
+ remaining = d.normalizer.Normalize(remaining)
+ }
+ return d.FormatMsg(d.producer(remaining))
+}
+
+func (d *movingAverageETA) EwmaUpdate(n int64, dur time.Duration) {
+ durPerItem := float64(dur) / float64(n)
+ if math.IsInf(durPerItem, 0) || math.IsNaN(durPerItem) {
+ return
+ }
+ d.average.Add(durPerItem)
+}
+
+// AverageETA decorator. It's wrapper of NewAverageETA.
+//
+// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
+//
+// `wcc` optional WC config
+//
+func AverageETA(style TimeStyle, wcc ...WC) Decorator {
+ return NewAverageETA(style, time.Now(), nil, wcc...)
+}
+
+// NewAverageETA decorator with user provided start time.
+//
+// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
+//
+// `startTime` start time
+//
+// `normalizer` available implementations are [FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer]
+//
+// `wcc` optional WC config
+//
+func NewAverageETA(style TimeStyle, startTime time.Time, normalizer TimeNormalizer, wcc ...WC) Decorator {
+ d := &averageETA{
+ WC: initWC(wcc...),
+ startTime: startTime,
+ normalizer: normalizer,
+ producer: chooseTimeProducer(style),
+ }
+ return d
+}
+
+type averageETA struct {
+ WC
+ startTime time.Time
+ normalizer TimeNormalizer
+ producer func(time.Duration) string
+}
+
+func (d *averageETA) Decor(s Statistics) string {
+ var remaining time.Duration
+ if s.Current != 0 {
+ durPerItem := float64(time.Since(d.startTime)) / float64(s.Current)
+ durPerItem = math.Round(durPerItem)
+ remaining = time.Duration((s.Total - s.Current) * int64(durPerItem))
+ if d.normalizer != nil {
+ remaining = d.normalizer.Normalize(remaining)
+ }
+ }
+ return d.FormatMsg(d.producer(remaining))
+}
+
+func (d *averageETA) AverageAdjust(startTime time.Time) {
+ d.startTime = startTime
+}
+
+// MaxTolerateTimeNormalizer returns implementation of TimeNormalizer.
+func MaxTolerateTimeNormalizer(maxTolerate time.Duration) TimeNormalizer {
+ var normalized time.Duration
+ var lastCall time.Time
+ return TimeNormalizerFunc(func(remaining time.Duration) time.Duration {
+ if diff := normalized - remaining; diff <= 0 || diff > maxTolerate || remaining < time.Minute {
+ normalized = remaining
+ lastCall = time.Now()
+ return remaining
+ }
+ normalized -= time.Since(lastCall)
+ lastCall = time.Now()
+ return normalized
+ })
+}
+
+// FixedIntervalTimeNormalizer returns implementation of TimeNormalizer.
+func FixedIntervalTimeNormalizer(updInterval int) TimeNormalizer {
+ var normalized time.Duration
+ var lastCall time.Time
+ var count int
+ return TimeNormalizerFunc(func(remaining time.Duration) time.Duration {
+ if count == 0 || remaining < time.Minute {
+ count = updInterval
+ normalized = remaining
+ lastCall = time.Now()
+ return remaining
+ }
+ count--
+ normalized -= time.Since(lastCall)
+ lastCall = time.Now()
+ return normalized
+ })
+}
+
+func chooseTimeProducer(style TimeStyle) func(time.Duration) string {
+ switch style {
+ case ET_STYLE_HHMMSS:
+ return func(remaining time.Duration) string {
+ hours := int64(remaining/time.Hour) % 60
+ minutes := int64(remaining/time.Minute) % 60
+ seconds := int64(remaining/time.Second) % 60
+ return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds)
+ }
+ case ET_STYLE_HHMM:
+ return func(remaining time.Duration) string {
+ hours := int64(remaining/time.Hour) % 60
+ minutes := int64(remaining/time.Minute) % 60
+ return fmt.Sprintf("%02d:%02d", hours, minutes)
+ }
+ case ET_STYLE_MMSS:
+ return func(remaining time.Duration) string {
+ hours := int64(remaining/time.Hour) % 60
+ minutes := int64(remaining/time.Minute) % 60
+ seconds := int64(remaining/time.Second) % 60
+ if hours > 0 {
+ return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds)
+ }
+ return fmt.Sprintf("%02d:%02d", minutes, seconds)
+ }
+ default:
+ return func(remaining time.Duration) string {
+ // strip off nanoseconds
+ return ((remaining / time.Second) * time.Second).String()
+ }
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/merge.go b/vendor/github.com/vbauerster/mpb/v7/decor/merge.go
new file mode 100644
index 000000000..e41406a64
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/merge.go
@@ -0,0 +1,107 @@
+package decor
+
+import (
+ "strings"
+
+ "github.com/acarl005/stripansi"
+ "github.com/mattn/go-runewidth"
+)
+
+// Merge wraps its decorator argument with intention to sync width
+// with several decorators of another bar. Visual example:
+//
+// +----+--------+---------+--------+
+// | B1 | MERGE(D, P1, Pn) |
+// +----+--------+---------+--------+
+// | B2 | D0 | D1 | Dn |
+// +----+--------+---------+--------+
+//
+func Merge(decorator Decorator, placeholders ...WC) Decorator {
+ if _, ok := decorator.Sync(); !ok || len(placeholders) == 0 {
+ return decorator
+ }
+ md := &mergeDecorator{
+ Decorator: decorator,
+ wc: decorator.GetConf(),
+ placeHolders: make([]*placeHolderDecorator, len(placeholders)),
+ }
+ decorator.SetConf(WC{})
+ for i, wc := range placeholders {
+ if (wc.C & DSyncWidth) == 0 {
+ return decorator
+ }
+ md.placeHolders[i] = &placeHolderDecorator{wc.Init()}
+ }
+ return md
+}
+
+type mergeDecorator struct {
+ Decorator
+ wc WC
+ placeHolders []*placeHolderDecorator
+}
+
+func (d *mergeDecorator) GetConf() WC {
+ return d.wc
+}
+
+func (d *mergeDecorator) SetConf(conf WC) {
+ d.wc = conf.Init()
+}
+
+func (d *mergeDecorator) MergeUnwrap() []Decorator {
+ decorators := make([]Decorator, len(d.placeHolders))
+ for i, ph := range d.placeHolders {
+ decorators[i] = ph
+ }
+ return decorators
+}
+
+func (d *mergeDecorator) Sync() (chan int, bool) {
+ return d.wc.Sync()
+}
+
+func (d *mergeDecorator) Base() Decorator {
+ return d.Decorator
+}
+
+func (d *mergeDecorator) Decor(s Statistics) string {
+ msg := d.Decorator.Decor(s)
+ pureWidth := runewidth.StringWidth(msg)
+ stripWidth := runewidth.StringWidth(stripansi.Strip(msg))
+ cellCount := stripWidth
+ if (d.wc.C & DextraSpace) != 0 {
+ cellCount++
+ }
+
+ total := runewidth.StringWidth(d.placeHolders[0].FormatMsg(""))
+ pw := (cellCount - total) / len(d.placeHolders)
+ rem := (cellCount - total) % len(d.placeHolders)
+
+ var diff int
+ for i := 1; i < len(d.placeHolders); i++ {
+ ph := d.placeHolders[i]
+ width := pw - diff
+ if (ph.WC.C & DextraSpace) != 0 {
+ width--
+ if width < 0 {
+ width = 0
+ }
+ }
+ max := runewidth.StringWidth(ph.FormatMsg(strings.Repeat(" ", width)))
+ total += max
+ diff = max - pw
+ }
+
+ d.wc.wsync <- pw + rem
+ max := <-d.wc.wsync
+ return d.wc.fill(msg, max+total+(pureWidth-stripWidth))
+}
+
+type placeHolderDecorator struct {
+ WC
+}
+
+func (d *placeHolderDecorator) Decor(Statistics) string {
+ return ""
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/moving_average.go b/vendor/github.com/vbauerster/mpb/v7/decor/moving_average.go
new file mode 100644
index 000000000..50ac9c393
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/moving_average.go
@@ -0,0 +1,68 @@
+package decor
+
+import (
+ "sort"
+ "sync"
+
+ "github.com/VividCortex/ewma"
+)
+
+type threadSafeMovingAverage struct {
+ ewma.MovingAverage
+ mu sync.Mutex
+}
+
+func (s *threadSafeMovingAverage) Add(value float64) {
+ s.mu.Lock()
+ s.MovingAverage.Add(value)
+ s.mu.Unlock()
+}
+
+func (s *threadSafeMovingAverage) Value() float64 {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ return s.MovingAverage.Value()
+}
+
+func (s *threadSafeMovingAverage) Set(value float64) {
+ s.mu.Lock()
+ s.MovingAverage.Set(value)
+ s.mu.Unlock()
+}
+
+// NewThreadSafeMovingAverage converts provided ewma.MovingAverage
+// into thread safe ewma.MovingAverage.
+func NewThreadSafeMovingAverage(average ewma.MovingAverage) ewma.MovingAverage {
+ if tsma, ok := average.(*threadSafeMovingAverage); ok {
+ return tsma
+ }
+ return &threadSafeMovingAverage{MovingAverage: average}
+}
+
+type medianWindow [3]float64
+
+func (s *medianWindow) Len() int { return len(s) }
+func (s *medianWindow) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+func (s *medianWindow) Less(i, j int) bool { return s[i] < s[j] }
+
+func (s *medianWindow) Add(value float64) {
+ s[0], s[1] = s[1], s[2]
+ s[2] = value
+}
+
+func (s *medianWindow) Value() float64 {
+ tmp := *s
+ sort.Sort(&tmp)
+ return tmp[1]
+}
+
+func (s *medianWindow) Set(value float64) {
+ for i := 0; i < len(s); i++ {
+ s[i] = value
+ }
+}
+
+// NewMedian is fixed last 3 samples median MovingAverage.
+func NewMedian() ewma.MovingAverage {
+ return NewThreadSafeMovingAverage(new(medianWindow))
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/name.go b/vendor/github.com/vbauerster/mpb/v7/decor/name.go
new file mode 100644
index 000000000..3af311254
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/name.go
@@ -0,0 +1,12 @@
+package decor
+
+// Name decorator displays text that is set once and can't be changed
+// during decorator's lifetime.
+//
+// `str` string to display
+//
+// `wcc` optional WC config
+//
+func Name(str string, wcc ...WC) Decorator {
+ return Any(func(Statistics) string { return str }, wcc...)
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go b/vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go
new file mode 100644
index 000000000..f46b19aba
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go
@@ -0,0 +1,37 @@
+package decor
+
+// OnComplete returns decorator, which wraps provided decorator, with
+// sole purpose to display provided message on complete event.
+//
+// `decorator` Decorator to wrap
+//
+// `message` message to display on complete event
+//
+func OnComplete(decorator Decorator, message string) Decorator {
+ d := &onCompleteWrapper{
+ Decorator: decorator,
+ msg: message,
+ }
+ if md, ok := decorator.(*mergeDecorator); ok {
+ d.Decorator, md.Decorator = md.Decorator, d
+ return md
+ }
+ return d
+}
+
+type onCompleteWrapper struct {
+ Decorator
+ msg string
+}
+
+func (d *onCompleteWrapper) Decor(s Statistics) string {
+ if s.Completed {
+ wc := d.GetConf()
+ return wc.FormatMsg(d.msg)
+ }
+ return d.Decorator.Decor(s)
+}
+
+func (d *onCompleteWrapper) Base() Decorator {
+ return d.Decorator
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/percentage.go b/vendor/github.com/vbauerster/mpb/v7/decor/percentage.go
new file mode 100644
index 000000000..2b0a7a956
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/percentage.go
@@ -0,0 +1,58 @@
+package decor
+
+import (
+ "fmt"
+ "io"
+ "strconv"
+
+ "github.com/vbauerster/mpb/v7/internal"
+)
+
+type percentageType float64
+
+func (s percentageType) Format(st fmt.State, verb rune) {
+ var prec int
+ switch verb {
+ case 'd':
+ case 's':
+ prec = -1
+ default:
+ if p, ok := st.Precision(); ok {
+ prec = p
+ } else {
+ prec = 6
+ }
+ }
+
+ io.WriteString(st, strconv.FormatFloat(float64(s), 'f', prec, 64))
+
+ if st.Flag(' ') {
+ io.WriteString(st, " ")
+ }
+ io.WriteString(st, "%")
+}
+
+// Percentage returns percentage decorator. It's a wrapper of NewPercentage.
+func Percentage(wcc ...WC) Decorator {
+ return NewPercentage("% d", wcc...)
+}
+
+// NewPercentage percentage decorator with custom format string.
+//
+// format examples:
+//
+// format="%.1f" output: "1.0%"
+// format="% .1f" output: "1.0 %"
+// format="%d" output: "1%"
+// format="% d" output: "1 %"
+//
+func NewPercentage(format string, wcc ...WC) Decorator {
+ if format == "" {
+ format = "% d"
+ }
+ f := func(s Statistics) string {
+ p := internal.Percentage(s.Total, s.Current, 100)
+ return fmt.Sprintf(format, percentageType(p))
+ }
+ return Any(f, wcc...)
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/size_type.go b/vendor/github.com/vbauerster/mpb/v7/decor/size_type.go
new file mode 100644
index 000000000..e4b974058
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/size_type.go
@@ -0,0 +1,109 @@
+package decor
+
+import (
+ "fmt"
+ "io"
+ "math"
+ "strconv"
+)
+
+//go:generate stringer -type=SizeB1024 -trimprefix=_i
+//go:generate stringer -type=SizeB1000 -trimprefix=_
+
+const (
+ _ib SizeB1024 = iota + 1
+ _iKiB SizeB1024 = 1 << (iota * 10)
+ _iMiB
+ _iGiB
+ _iTiB
+)
+
+// SizeB1024 named type, which implements fmt.Formatter interface. It
+// adjusts its value according to byte size multiple by 1024 and appends
+// appropriate size marker (KiB, MiB, GiB, TiB).
+type SizeB1024 int64
+
+func (self SizeB1024) Format(st fmt.State, verb rune) {
+ var prec int
+ switch verb {
+ case 'd':
+ case 's':
+ prec = -1
+ default:
+ if p, ok := st.Precision(); ok {
+ prec = p
+ } else {
+ prec = 6
+ }
+ }
+
+ var unit SizeB1024
+ switch {
+ case self < _iKiB:
+ unit = _ib
+ case self < _iMiB:
+ unit = _iKiB
+ case self < _iGiB:
+ unit = _iMiB
+ case self < _iTiB:
+ unit = _iGiB
+ case self <= math.MaxInt64:
+ unit = _iTiB
+ }
+
+ io.WriteString(st, strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64))
+
+ if st.Flag(' ') {
+ io.WriteString(st, " ")
+ }
+ io.WriteString(st, unit.String())
+}
+
+const (
+ _b SizeB1000 = 1
+ _KB SizeB1000 = _b * 1000
+ _MB SizeB1000 = _KB * 1000
+ _GB SizeB1000 = _MB * 1000
+ _TB SizeB1000 = _GB * 1000
+)
+
+// SizeB1000 named type, which implements fmt.Formatter interface. It
+// adjusts its value according to byte size multiple by 1000 and appends
+// appropriate size marker (KB, MB, GB, TB).
+type SizeB1000 int64
+
+func (self SizeB1000) Format(st fmt.State, verb rune) {
+ var prec int
+ switch verb {
+ case 'd':
+ case 's':
+ prec = -1
+ default:
+ if p, ok := st.Precision(); ok {
+ prec = p
+ } else {
+ prec = 6
+ }
+ }
+
+ var unit SizeB1000
+ switch {
+ case self < _KB:
+ unit = _b
+ case self < _MB:
+ unit = _KB
+ case self < _GB:
+ unit = _MB
+ case self < _TB:
+ unit = _GB
+ case self <= math.MaxInt64:
+ unit = _TB
+ }
+
+ io.WriteString(st, strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64))
+
+ if st.Flag(' ') {
+ io.WriteString(st, " ")
+ }
+ io.WriteString(st, unit.String())
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1000_string.go b/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1000_string.go
new file mode 100644
index 000000000..3f32ef715
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1000_string.go
@@ -0,0 +1,41 @@
+// Code generated by "stringer -type=SizeB1000 -trimprefix=_"; DO NOT EDIT.
+
+package decor
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[_b-1]
+ _ = x[_KB-1000]
+ _ = x[_MB-1000000]
+ _ = x[_GB-1000000000]
+ _ = x[_TB-1000000000000]
+}
+
+const (
+ _SizeB1000_name_0 = "b"
+ _SizeB1000_name_1 = "KB"
+ _SizeB1000_name_2 = "MB"
+ _SizeB1000_name_3 = "GB"
+ _SizeB1000_name_4 = "TB"
+)
+
+func (i SizeB1000) String() string {
+ switch {
+ case i == 1:
+ return _SizeB1000_name_0
+ case i == 1000:
+ return _SizeB1000_name_1
+ case i == 1000000:
+ return _SizeB1000_name_2
+ case i == 1000000000:
+ return _SizeB1000_name_3
+ case i == 1000000000000:
+ return _SizeB1000_name_4
+ default:
+ return "SizeB1000(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1024_string.go b/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1024_string.go
new file mode 100644
index 000000000..9fca66cc7
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1024_string.go
@@ -0,0 +1,41 @@
+// Code generated by "stringer -type=SizeB1024 -trimprefix=_i"; DO NOT EDIT.
+
+package decor
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[_ib-1]
+ _ = x[_iKiB-1024]
+ _ = x[_iMiB-1048576]
+ _ = x[_iGiB-1073741824]
+ _ = x[_iTiB-1099511627776]
+}
+
+const (
+ _SizeB1024_name_0 = "b"
+ _SizeB1024_name_1 = "KiB"
+ _SizeB1024_name_2 = "MiB"
+ _SizeB1024_name_3 = "GiB"
+ _SizeB1024_name_4 = "TiB"
+)
+
+func (i SizeB1024) String() string {
+ switch {
+ case i == 1:
+ return _SizeB1024_name_0
+ case i == 1024:
+ return _SizeB1024_name_1
+ case i == 1048576:
+ return _SizeB1024_name_2
+ case i == 1073741824:
+ return _SizeB1024_name_3
+ case i == 1099511627776:
+ return _SizeB1024_name_4
+ default:
+ return "SizeB1024(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/speed.go b/vendor/github.com/vbauerster/mpb/v7/decor/speed.go
new file mode 100644
index 000000000..634edabfd
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/speed.go
@@ -0,0 +1,171 @@
+package decor
+
+import (
+ "fmt"
+ "io"
+ "math"
+ "time"
+
+ "github.com/VividCortex/ewma"
+)
+
+// FmtAsSpeed adds "/s" to the end of the input formatter. To be
+// used with SizeB1000 or SizeB1024 types, for example:
+//
+// fmt.Printf("%.1f", FmtAsSpeed(SizeB1024(2048)))
+//
+func FmtAsSpeed(input fmt.Formatter) fmt.Formatter {
+ return &speedFormatter{input}
+}
+
+type speedFormatter struct {
+ fmt.Formatter
+}
+
+func (self *speedFormatter) Format(st fmt.State, verb rune) {
+ self.Formatter.Format(st, verb)
+ io.WriteString(st, "/s")
+}
+
+// EwmaSpeed exponential-weighted-moving-average based speed decorator.
+// For this decorator to work correctly you have to measure each
+// iteration's duration and pass it to the
+// *Bar.DecoratorEwmaUpdate(time.Duration) method after each increment.
+func EwmaSpeed(unit int, format string, age float64, wcc ...WC) Decorator {
+ var average ewma.MovingAverage
+ if age == 0 {
+ average = ewma.NewMovingAverage()
+ } else {
+ average = ewma.NewMovingAverage(age)
+ }
+ return MovingAverageSpeed(unit, format, NewThreadSafeMovingAverage(average), wcc...)
+}
+
+// MovingAverageSpeed decorator relies on MovingAverage implementation
+// to calculate its average.
+//
+// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
+//
+// `format` printf compatible verb for value, like "%f" or "%d"
+//
+// `average` MovingAverage implementation
+//
+// `wcc` optional WC config
+//
+// format examples:
+//
+// unit=UnitKiB, format="%.1f" output: "1.0MiB/s"
+// unit=UnitKiB, format="% .1f" output: "1.0 MiB/s"
+// unit=UnitKB, format="%.1f" output: "1.0MB/s"
+// unit=UnitKB, format="% .1f" output: "1.0 MB/s"
+//
+func MovingAverageSpeed(unit int, format string, average ewma.MovingAverage, wcc ...WC) Decorator {
+ if format == "" {
+ format = "%.0f"
+ }
+ d := &movingAverageSpeed{
+ WC: initWC(wcc...),
+ average: average,
+ producer: chooseSpeedProducer(unit, format),
+ }
+ return d
+}
+
+type movingAverageSpeed struct {
+ WC
+ producer func(float64) string
+ average ewma.MovingAverage
+ msg string
+}
+
+func (d *movingAverageSpeed) Decor(s Statistics) string {
+ if !s.Completed {
+ var speed float64
+ if v := d.average.Value(); v > 0 {
+ speed = 1 / v
+ }
+ d.msg = d.producer(speed * 1e9)
+ }
+ return d.FormatMsg(d.msg)
+}
+
+func (d *movingAverageSpeed) EwmaUpdate(n int64, dur time.Duration) {
+ durPerByte := float64(dur) / float64(n)
+ if math.IsInf(durPerByte, 0) || math.IsNaN(durPerByte) {
+ return
+ }
+ d.average.Add(durPerByte)
+}
+
+// AverageSpeed decorator with dynamic unit measure adjustment. It's
+// a wrapper of NewAverageSpeed.
+func AverageSpeed(unit int, format string, wcc ...WC) Decorator {
+ return NewAverageSpeed(unit, format, time.Now(), wcc...)
+}
+
+// NewAverageSpeed decorator with dynamic unit measure adjustment and
+// user provided start time.
+//
+// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
+//
+// `format` printf compatible verb for value, like "%f" or "%d"
+//
+// `startTime` start time
+//
+// `wcc` optional WC config
+//
+// format examples:
+//
+// unit=UnitKiB, format="%.1f" output: "1.0MiB/s"
+// unit=UnitKiB, format="% .1f" output: "1.0 MiB/s"
+// unit=UnitKB, format="%.1f" output: "1.0MB/s"
+// unit=UnitKB, format="% .1f" output: "1.0 MB/s"
+//
+func NewAverageSpeed(unit int, format string, startTime time.Time, wcc ...WC) Decorator {
+ if format == "" {
+ format = "%.0f"
+ }
+ d := &averageSpeed{
+ WC: initWC(wcc...),
+ startTime: startTime,
+ producer: chooseSpeedProducer(unit, format),
+ }
+ return d
+}
+
+type averageSpeed struct {
+ WC
+ startTime time.Time
+ producer func(float64) string
+ msg string
+}
+
+func (d *averageSpeed) Decor(s Statistics) string {
+ if !s.Completed {
+ speed := float64(s.Current) / float64(time.Since(d.startTime))
+ d.msg = d.producer(speed * 1e9)
+ }
+
+ return d.FormatMsg(d.msg)
+}
+
+func (d *averageSpeed) AverageAdjust(startTime time.Time) {
+ d.startTime = startTime
+}
+
+func chooseSpeedProducer(unit int, format string) func(float64) string {
+ switch unit {
+ case UnitKiB:
+ return func(speed float64) string {
+ return fmt.Sprintf(format, FmtAsSpeed(SizeB1024(math.Round(speed))))
+ }
+ case UnitKB:
+ return func(speed float64) string {
+ return fmt.Sprintf(format, FmtAsSpeed(SizeB1000(math.Round(speed))))
+ }
+ default:
+ return func(speed float64) string {
+ return fmt.Sprintf(format, speed)
+ }
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/spinner.go b/vendor/github.com/vbauerster/mpb/v7/decor/spinner.go
new file mode 100644
index 000000000..6871639db
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/spinner.go
@@ -0,0 +1,21 @@
+package decor
+
+var defaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
+
+// Spinner returns spinner decorator.
+//
+// `frames` spinner frames, if nil or len==0, default is used
+//
+// `wcc` optional WC config
+func Spinner(frames []string, wcc ...WC) Decorator {
+ if len(frames) == 0 {
+ frames = defaultSpinnerStyle
+ }
+ var count uint
+ f := func(s Statistics) string {
+ frame := frames[count%uint(len(frames))]
+ count++
+ return frame
+ }
+ return Any(f, wcc...)
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/doc.go b/vendor/github.com/vbauerster/mpb/v7/doc.go
new file mode 100644
index 000000000..5ada71774
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/doc.go
@@ -0,0 +1,2 @@
+// Package mpb is a library for rendering progress bars in terminal applications.
+package mpb
diff --git a/vendor/github.com/vbauerster/mpb/v7/go.mod b/vendor/github.com/vbauerster/mpb/v7/go.mod
new file mode 100644
index 000000000..ea22e1eda
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/go.mod
@@ -0,0 +1,10 @@
+module github.com/vbauerster/mpb/v7
+
+require (
+ github.com/VividCortex/ewma v1.2.0
+ github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
+ github.com/mattn/go-runewidth v0.0.13
+ golang.org/x/sys v0.0.0-20210603125802-9665404d3644
+)
+
+go 1.14
diff --git a/vendor/github.com/vbauerster/mpb/v7/go.sum b/vendor/github.com/vbauerster/mpb/v7/go.sum
new file mode 100644
index 000000000..0b609b223
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/go.sum
@@ -0,0 +1,10 @@
+github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
+github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
+github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
+github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
+github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
+github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I=
+golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
diff --git a/vendor/github.com/vbauerster/mpb/v7/internal/percentage.go b/vendor/github.com/vbauerster/mpb/v7/internal/percentage.go
new file mode 100644
index 000000000..a8ef8be12
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/internal/percentage.go
@@ -0,0 +1,19 @@
+package internal
+
+import "math"
+
+// Percentage is a helper function, to calculate percentage.
+func Percentage(total, current int64, width int) float64 {
+ if total <= 0 {
+ return 0
+ }
+ if current >= total {
+ return float64(width)
+ }
+ return float64(int64(width)*current) / float64(total)
+}
+
+// PercentageRound same as Percentage but with math.Round.
+func PercentageRound(total, current int64, width int) float64 {
+ return math.Round(Percentage(total, current, width))
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/internal/predicate.go b/vendor/github.com/vbauerster/mpb/v7/internal/predicate.go
new file mode 100644
index 000000000..1e4dd24d9
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/internal/predicate.go
@@ -0,0 +1,6 @@
+package internal
+
+// Predicate helper for internal use.
+func Predicate(pick bool) func() bool {
+ return func() bool { return pick }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/internal/width.go b/vendor/github.com/vbauerster/mpb/v7/internal/width.go
new file mode 100644
index 000000000..7677e404a
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/internal/width.go
@@ -0,0 +1,10 @@
+package internal
+
+// CheckRequestedWidth checks that requested width doesn't overflow
+// available width
+func CheckRequestedWidth(requested, available int) int {
+ if requested < 1 || requested >= available {
+ return available
+ }
+ return requested
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/priority_queue.go b/vendor/github.com/vbauerster/mpb/v7/priority_queue.go
new file mode 100644
index 000000000..29d9bd5a8
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/priority_queue.go
@@ -0,0 +1,32 @@
+package mpb
+
+// A priorityQueue implements heap.Interface
+type priorityQueue []*Bar
+
+func (pq priorityQueue) Len() int { return len(pq) }
+
+func (pq priorityQueue) Less(i, j int) bool {
+ return pq[i].priority < pq[j].priority
+}
+
+func (pq priorityQueue) Swap(i, j int) {
+ pq[i], pq[j] = pq[j], pq[i]
+ pq[i].index = i
+ pq[j].index = j
+}
+
+func (pq *priorityQueue) Push(x interface{}) {
+ s := *pq
+ bar := x.(*Bar)
+ bar.index = len(s)
+ s = append(s, bar)
+ *pq = s
+}
+
+func (pq *priorityQueue) Pop() interface{} {
+ s := *pq
+ *pq = s[0 : len(s)-1]
+ bar := s[len(s)-1]
+ bar.index = -1 // for safety
+ return bar
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/progress.go b/vendor/github.com/vbauerster/mpb/v7/progress.go
new file mode 100644
index 000000000..b2017f3f0
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/progress.go
@@ -0,0 +1,412 @@
+package mpb
+
+import (
+ "bytes"
+ "container/heap"
+ "context"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "log"
+ "math"
+ "os"
+ "sync"
+ "time"
+
+ "github.com/vbauerster/mpb/v7/cwriter"
+ "github.com/vbauerster/mpb/v7/decor"
+)
+
+const (
+ // default RefreshRate
+ prr = 120 * time.Millisecond
+)
+
+// Progress represents a container that renders one or more progress
+// bars.
+type Progress struct {
+ ctx context.Context
+ uwg *sync.WaitGroup
+ cwg *sync.WaitGroup
+ bwg *sync.WaitGroup
+ operateState chan func(*pState)
+ done chan struct{}
+ refreshCh chan time.Time
+ once sync.Once
+ dlogger *log.Logger
+}
+
+// pState holds bars in its priorityQueue. It gets passed to
+// *Progress.serve(...) monitor goroutine.
+type pState struct {
+ bHeap priorityQueue
+ heapUpdated bool
+ pMatrix map[int][]chan int
+ aMatrix map[int][]chan int
+ barShutdownQueue []*Bar
+
+ // following are provided/overrided by user
+ idCount int
+ reqWidth int
+ popCompleted bool
+ outputDiscarded bool
+ rr time.Duration
+ uwg *sync.WaitGroup
+ externalRefresh <-chan interface{}
+ renderDelay <-chan struct{}
+ shutdownNotifier chan struct{}
+ parkedBars map[*Bar]*Bar
+ output io.Writer
+ debugOut io.Writer
+}
+
+// New creates new Progress container instance. It's not possible to
+// reuse instance after *Progress.Wait() method has been called.
+func New(options ...ContainerOption) *Progress {
+ return NewWithContext(context.Background(), options...)
+}
+
+// NewWithContext creates new Progress container instance with provided
+// context. It's not possible to reuse instance after *Progress.Wait()
+// method has been called.
+func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress {
+ s := &pState{
+ bHeap: priorityQueue{},
+ rr: prr,
+ parkedBars: make(map[*Bar]*Bar),
+ output: os.Stdout,
+ debugOut: ioutil.Discard,
+ }
+
+ for _, opt := range options {
+ if opt != nil {
+ opt(s)
+ }
+ }
+
+ p := &Progress{
+ ctx: ctx,
+ uwg: s.uwg,
+ cwg: new(sync.WaitGroup),
+ bwg: new(sync.WaitGroup),
+ operateState: make(chan func(*pState)),
+ done: make(chan struct{}),
+ dlogger: log.New(s.debugOut, "[mpb] ", log.Lshortfile),
+ }
+
+ p.cwg.Add(1)
+ go p.serve(s, cwriter.New(s.output))
+ return p
+}
+
+// AddBar creates a bar with default bar filler. Different filler can
+// be chosen and applied via `*Progress.Add(...) *Bar` method.
+func (p *Progress) AddBar(total int64, options ...BarOption) *Bar {
+ return p.Add(total, NewBarFiller(BarStyle()), options...)
+}
+
+// AddSpinner creates a bar with default spinner filler. Different
+// filler can be chosen and applied via `*Progress.Add(...) *Bar`
+// method.
+func (p *Progress) AddSpinner(total int64, options ...BarOption) *Bar {
+ return p.Add(total, NewBarFiller(SpinnerStyle()), options...)
+}
+
+// Add creates a bar which renders itself by provided filler.
+// If `total <= 0` trigger complete event is disabled until reset with *bar.SetTotal(int64, bool).
+// Panics if *Progress instance is done, i.e. called after *Progress.Wait().
+func (p *Progress) Add(total int64, filler BarFiller, options ...BarOption) *Bar {
+ if filler == nil {
+ filler = BarFillerFunc(func(io.Writer, int, decor.Statistics) {})
+ }
+ p.bwg.Add(1)
+ result := make(chan *Bar)
+ select {
+ case p.operateState <- func(ps *pState) {
+ bs := ps.makeBarState(total, filler, options...)
+ bar := newBar(p, bs)
+ if bs.runningBar != nil {
+ bs.runningBar.noPop = true
+ ps.parkedBars[bs.runningBar] = bar
+ } else {
+ heap.Push(&ps.bHeap, bar)
+ ps.heapUpdated = true
+ }
+ ps.idCount++
+ result <- bar
+ }:
+ bar := <-result
+ bar.subscribeDecorators()
+ return bar
+ case <-p.done:
+ p.bwg.Done()
+ panic(fmt.Sprintf("%T instance can't be reused after it's done!", p))
+ }
+}
+
+func (p *Progress) dropBar(b *Bar) {
+ select {
+ case p.operateState <- func(s *pState) {
+ if b.index < 0 {
+ return
+ }
+ heap.Remove(&s.bHeap, b.index)
+ s.heapUpdated = true
+ }:
+ case <-p.done:
+ }
+}
+
+func (p *Progress) setBarPriority(b *Bar, priority int) {
+ select {
+ case p.operateState <- func(s *pState) {
+ if b.index < 0 {
+ return
+ }
+ b.priority = priority
+ heap.Fix(&s.bHeap, b.index)
+ }:
+ case <-p.done:
+ }
+}
+
+// UpdateBarPriority same as *Bar.SetPriority(int).
+func (p *Progress) UpdateBarPriority(b *Bar, priority int) {
+ p.setBarPriority(b, priority)
+}
+
+// BarCount returns bars count.
+func (p *Progress) BarCount() int {
+ result := make(chan int, 1)
+ select {
+ case p.operateState <- func(s *pState) { result <- s.bHeap.Len() }:
+ return <-result
+ case <-p.done:
+ return 0
+ }
+}
+
+// Wait waits for all bars to complete and finally shutdowns container.
+// After this method has been called, there is no way to reuse *Progress
+// instance.
+func (p *Progress) Wait() {
+ if p.uwg != nil {
+ // wait for user wg
+ p.uwg.Wait()
+ }
+
+ // wait for bars to quit, if any
+ p.bwg.Wait()
+
+ p.once.Do(p.shutdown)
+
+ // wait for container to quit
+ p.cwg.Wait()
+}
+
+func (p *Progress) shutdown() {
+ close(p.done)
+}
+
+func (p *Progress) serve(s *pState, cw *cwriter.Writer) {
+ defer p.cwg.Done()
+
+ p.refreshCh = s.newTicker(p.done)
+
+ for {
+ select {
+ case op := <-p.operateState:
+ op(s)
+ case <-p.refreshCh:
+ if err := s.render(cw); err != nil {
+ p.dlogger.Println(err)
+ }
+ case <-s.shutdownNotifier:
+ if s.heapUpdated {
+ if err := s.render(cw); err != nil {
+ p.dlogger.Println(err)
+ }
+ }
+ return
+ }
+ }
+}
+
+func (s *pState) newTicker(done <-chan struct{}) chan time.Time {
+ ch := make(chan time.Time)
+ if s.shutdownNotifier == nil {
+ s.shutdownNotifier = make(chan struct{})
+ }
+ go func() {
+ if s.renderDelay != nil {
+ <-s.renderDelay
+ }
+ var internalRefresh <-chan time.Time
+ if !s.outputDiscarded {
+ if s.externalRefresh == nil {
+ ticker := time.NewTicker(s.rr)
+ defer ticker.Stop()
+ internalRefresh = ticker.C
+ }
+ } else {
+ s.externalRefresh = nil
+ }
+ for {
+ select {
+ case t := <-internalRefresh:
+ ch <- t
+ case x := <-s.externalRefresh:
+ if t, ok := x.(time.Time); ok {
+ ch <- t
+ } else {
+ ch <- time.Now()
+ }
+ case <-done:
+ close(s.shutdownNotifier)
+ return
+ }
+ }
+ }()
+ return ch
+}
+
+func (s *pState) render(cw *cwriter.Writer) error {
+ if s.heapUpdated {
+ s.updateSyncMatrix()
+ s.heapUpdated = false
+ }
+ syncWidth(s.pMatrix)
+ syncWidth(s.aMatrix)
+
+ tw, err := cw.GetWidth()
+ if err != nil {
+ tw = s.reqWidth
+ }
+ for i := 0; i < s.bHeap.Len(); i++ {
+ bar := s.bHeap[i]
+ go bar.render(tw)
+ }
+
+ return s.flush(cw)
+}
+
+func (s *pState) flush(cw *cwriter.Writer) error {
+ var lineCount int
+ bm := make(map[*Bar]struct{}, s.bHeap.Len())
+ for s.bHeap.Len() > 0 {
+ b := heap.Pop(&s.bHeap).(*Bar)
+ cw.ReadFrom(<-b.frameCh)
+ if b.toShutdown {
+ if b.recoveredPanic != nil {
+ s.barShutdownQueue = append(s.barShutdownQueue, b)
+ b.toShutdown = false
+ } else {
+ // shutdown at next flush
+ // this ensures no bar ends up with less than 100% rendered
+ defer func() {
+ s.barShutdownQueue = append(s.barShutdownQueue, b)
+ }()
+ }
+ }
+ lineCount += b.extendedLines + 1
+ bm[b] = struct{}{}
+ }
+
+ for _, b := range s.barShutdownQueue {
+ if parkedBar := s.parkedBars[b]; parkedBar != nil {
+ parkedBar.priority = b.priority
+ heap.Push(&s.bHeap, parkedBar)
+ delete(s.parkedBars, b)
+ b.toDrop = true
+ }
+ if s.popCompleted && !b.noPop {
+ lineCount -= b.extendedLines + 1
+ b.toDrop = true
+ }
+ if b.toDrop {
+ delete(bm, b)
+ s.heapUpdated = true
+ }
+ b.cancel()
+ }
+ s.barShutdownQueue = s.barShutdownQueue[0:0]
+
+ for b := range bm {
+ heap.Push(&s.bHeap, b)
+ }
+
+ return cw.Flush(lineCount)
+}
+
+func (s *pState) updateSyncMatrix() {
+ s.pMatrix = make(map[int][]chan int)
+ s.aMatrix = make(map[int][]chan int)
+ for i := 0; i < s.bHeap.Len(); i++ {
+ bar := s.bHeap[i]
+ table := bar.wSyncTable()
+ pRow, aRow := table[0], table[1]
+
+ for i, ch := range pRow {
+ s.pMatrix[i] = append(s.pMatrix[i], ch)
+ }
+
+ for i, ch := range aRow {
+ s.aMatrix[i] = append(s.aMatrix[i], ch)
+ }
+ }
+}
+
+func (s *pState) makeBarState(total int64, filler BarFiller, options ...BarOption) *bState {
+ bs := &bState{
+ id: s.idCount,
+ priority: s.idCount,
+ reqWidth: s.reqWidth,
+ total: total,
+ filler: filler,
+ extender: func(r io.Reader, _ int, _ decor.Statistics) (io.Reader, int) { return r, 0 },
+ debugOut: s.debugOut,
+ }
+
+ if total > 0 {
+ bs.triggerComplete = true
+ }
+
+ for _, opt := range options {
+ if opt != nil {
+ opt(bs)
+ }
+ }
+
+ if bs.middleware != nil {
+ bs.filler = bs.middleware(filler)
+ bs.middleware = nil
+ }
+
+ if s.popCompleted && !bs.noPop {
+ bs.priority = -(math.MaxInt32 - s.idCount)
+ }
+
+ bs.bufP = bytes.NewBuffer(make([]byte, 0, 128))
+ bs.bufB = bytes.NewBuffer(make([]byte, 0, 256))
+ bs.bufA = bytes.NewBuffer(make([]byte, 0, 128))
+
+ return bs
+}
+
+func syncWidth(matrix map[int][]chan int) {
+ for _, column := range matrix {
+ go maxWidthDistributor(column)
+ }
+}
+
+var maxWidthDistributor = func(column []chan int) {
+ var maxWidth int
+ for _, ch := range column {
+ if w := <-ch; w > maxWidth {
+ maxWidth = w
+ }
+ }
+ for _, ch := range column {
+ ch <- maxWidth
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/proxyreader.go b/vendor/github.com/vbauerster/mpb/v7/proxyreader.go
new file mode 100644
index 000000000..316f438d7
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/proxyreader.go
@@ -0,0 +1,90 @@
+package mpb
+
+import (
+ "io"
+ "io/ioutil"
+ "time"
+)
+
+type proxyReader struct {
+ io.ReadCloser
+ bar *Bar
+}
+
+func (x *proxyReader) Read(p []byte) (int, error) {
+ n, err := x.ReadCloser.Read(p)
+ x.bar.IncrBy(n)
+ if err == io.EOF {
+ go x.bar.SetTotal(0, true)
+ }
+ return n, err
+}
+
+type proxyWriterTo struct {
+ io.ReadCloser // *proxyReader
+ wt io.WriterTo
+ bar *Bar
+}
+
+func (x *proxyWriterTo) WriteTo(w io.Writer) (int64, error) {
+ n, err := x.wt.WriteTo(w)
+ x.bar.IncrInt64(n)
+ if err == io.EOF {
+ go x.bar.SetTotal(0, true)
+ }
+ return n, err
+}
+
+type ewmaProxyReader struct {
+ io.ReadCloser // *proxyReader
+ bar *Bar
+ iT time.Time
+}
+
+func (x *ewmaProxyReader) Read(p []byte) (int, error) {
+ n, err := x.ReadCloser.Read(p)
+ if n > 0 {
+ x.bar.DecoratorEwmaUpdate(time.Since(x.iT))
+ x.iT = time.Now()
+ }
+ return n, err
+}
+
+type ewmaProxyWriterTo struct {
+ io.ReadCloser // *ewmaProxyReader
+ wt io.WriterTo // *proxyWriterTo
+ bar *Bar
+ iT time.Time
+}
+
+func (x *ewmaProxyWriterTo) WriteTo(w io.Writer) (int64, error) {
+ n, err := x.wt.WriteTo(w)
+ if n > 0 {
+ x.bar.DecoratorEwmaUpdate(time.Since(x.iT))
+ x.iT = time.Now()
+ }
+ return n, err
+}
+
+func newProxyReader(r io.Reader, bar *Bar) io.ReadCloser {
+ rc := toReadCloser(r)
+ rc = &proxyReader{rc, bar}
+
+ if wt, isWriterTo := r.(io.WriterTo); bar.hasEwmaDecorators {
+ now := time.Now()
+ rc = &ewmaProxyReader{rc, bar, now}
+ if isWriterTo {
+ rc = &ewmaProxyWriterTo{rc, wt, bar, now}
+ }
+ } else if isWriterTo {
+ rc = &proxyWriterTo{rc, wt, bar}
+ }
+ return rc
+}
+
+func toReadCloser(r io.Reader) io.ReadCloser {
+ if rc, ok := r.(io.ReadCloser); ok {
+ return rc
+ }
+ return ioutil.NopCloser(r)
+}
diff --git a/vendor/golang.org/x/sys/unix/README.md b/vendor/golang.org/x/sys/unix/README.md
index 579d2d735..474efad0e 100644
--- a/vendor/golang.org/x/sys/unix/README.md
+++ b/vendor/golang.org/x/sys/unix/README.md
@@ -76,7 +76,7 @@ arguments can be passed to the kernel. The third is for low-level use by the
ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
let it know that a system call is running.
-When porting Go to an new architecture/OS, this file must be implemented for
+When porting Go to a new architecture/OS, this file must be implemented for
each GOOS/GOARCH pair.
### mksysnum
@@ -107,7 +107,7 @@ prototype can be exported (capitalized) or not.
Adding a new syscall often just requires adding a new `//sys` function prototype
with the desired arguments and a capitalized name so it is exported. However, if
you want the interface to the syscall to be different, often one will make an
-unexported `//sys` prototype, an then write a custom wrapper in
+unexported `//sys` prototype, and then write a custom wrapper in
`syscall_${GOOS}.go`.
### types files
@@ -137,7 +137,7 @@ some `#if/#elif` macros in your include statements.
This script is used to generate the system's various constants. This doesn't
just include the error numbers and error strings, but also the signal numbers
-an a wide variety of miscellaneous constants. The constants come from the list
+and a wide variety of miscellaneous constants. The constants come from the list
of include files in the `includes_${uname}` variable. A regex then picks out
the desired `#define` statements, and generates the corresponding Go constants.
The error numbers and strings are generated from `#include <errno.h>`, and the
diff --git a/vendor/golang.org/x/sys/unix/asm_bsd_386.s b/vendor/golang.org/x/sys/unix/asm_bsd_386.s
index 7f29275fa..e0fcd9b3d 100644
--- a/vendor/golang.org/x/sys/unix/asm_bsd_386.s
+++ b/vendor/golang.org/x/sys/unix/asm_bsd_386.s
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build (darwin || freebsd || netbsd || openbsd) && gc
-// +build darwin freebsd netbsd openbsd
+//go:build (freebsd || netbsd || openbsd) && gc
+// +build freebsd netbsd openbsd
// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_bsd_arm.s b/vendor/golang.org/x/sys/unix/asm_bsd_arm.s
index 98ebfad9d..d702d4adc 100644
--- a/vendor/golang.org/x/sys/unix/asm_bsd_arm.s
+++ b/vendor/golang.org/x/sys/unix/asm_bsd_arm.s
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build (darwin || freebsd || netbsd || openbsd) && gc
-// +build darwin freebsd netbsd openbsd
+//go:build (freebsd || netbsd || openbsd) && gc
+// +build freebsd netbsd openbsd
// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh
index 007358af8..3f670faba 100644
--- a/vendor/golang.org/x/sys/unix/mkerrors.sh
+++ b/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -239,6 +239,7 @@ struct ltchars {
#include <linux/netfilter/nfnetlink.h>
#include <linux/netlink.h>
#include <linux/net_namespace.h>
+#include <linux/nfc.h>
#include <linux/nsfs.h>
#include <linux/perf_event.h>
#include <linux/pps.h>
@@ -258,6 +259,7 @@ struct ltchars {
#include <linux/watchdog.h>
#include <mtd/ubi-user.h>
+#include <mtd/mtd-user.h>
#include <net/route.h>
#if defined(__sparc__)
@@ -501,6 +503,9 @@ ccflags="$@"
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL)_/ ||
+ $2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
+ $2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
+ $2 ~ /^RAW_PAYLOAD_/ ||
$2 ~ /^TP_STATUS_/ ||
$2 ~ /^FALLOC_/ ||
$2 ~ /^ICMPV?6?_(FILTER|SEC)/ ||
@@ -593,6 +598,9 @@ ccflags="$@"
$2 == "HID_MAX_DESCRIPTOR_SIZE" ||
$2 ~ /^_?HIDIOC/ ||
$2 ~ /^BUS_(USB|HIL|BLUETOOTH|VIRTUAL)$/ ||
+ $2 ~ /^MTD/ ||
+ $2 ~ /^OTP/ ||
+ $2 ~ /^MEM/ ||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
$2 ~ /^__WCOREFLAG$/ {next}
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index 2dd7c8e34..41b91fdfb 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -904,6 +904,46 @@ func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil
}
+type SockaddrNFC struct {
+ DeviceIdx uint32
+ TargetIdx uint32
+ NFCProtocol uint32
+ raw RawSockaddrNFC
+}
+
+func (sa *SockaddrNFC) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ sa.raw.Sa_family = AF_NFC
+ sa.raw.Dev_idx = sa.DeviceIdx
+ sa.raw.Target_idx = sa.TargetIdx
+ sa.raw.Nfc_protocol = sa.NFCProtocol
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrNFC, nil
+}
+
+type SockaddrNFCLLCP struct {
+ DeviceIdx uint32
+ TargetIdx uint32
+ NFCProtocol uint32
+ DestinationSAP uint8
+ SourceSAP uint8
+ ServiceName string
+ raw RawSockaddrNFCLLCP
+}
+
+func (sa *SockaddrNFCLLCP) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ sa.raw.Sa_family = AF_NFC
+ sa.raw.Dev_idx = sa.DeviceIdx
+ sa.raw.Target_idx = sa.TargetIdx
+ sa.raw.Nfc_protocol = sa.NFCProtocol
+ sa.raw.Dsap = sa.DestinationSAP
+ sa.raw.Ssap = sa.SourceSAP
+ if len(sa.ServiceName) > len(sa.raw.Service_name) {
+ return nil, 0, EINVAL
+ }
+ copy(sa.raw.Service_name[:], sa.ServiceName)
+ sa.raw.SetServiceNameLen(len(sa.ServiceName))
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrNFCLLCP, nil
+}
+
var socketProtocol = func(fd int) (int, error) {
return GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
}
@@ -1144,6 +1184,37 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
}
return sa, nil
}
+ case AF_NFC:
+ proto, err := socketProtocol(fd)
+ if err != nil {
+ return nil, err
+ }
+ switch proto {
+ case NFC_SOCKPROTO_RAW:
+ pp := (*RawSockaddrNFC)(unsafe.Pointer(rsa))
+ sa := &SockaddrNFC{
+ DeviceIdx: pp.Dev_idx,
+ TargetIdx: pp.Target_idx,
+ NFCProtocol: pp.Nfc_protocol,
+ }
+ return sa, nil
+ case NFC_SOCKPROTO_LLCP:
+ pp := (*RawSockaddrNFCLLCP)(unsafe.Pointer(rsa))
+ if uint64(pp.Service_name_len) > uint64(len(pp.Service_name)) {
+ return nil, EINVAL
+ }
+ sa := &SockaddrNFCLLCP{
+ DeviceIdx: pp.Dev_idx,
+ TargetIdx: pp.Target_idx,
+ NFCProtocol: pp.Nfc_protocol,
+ DestinationSAP: pp.Dsap,
+ SourceSAP: pp.Ssap,
+ ServiceName: string(pp.Service_name[:pp.Service_name_len]),
+ }
+ return sa, nil
+ default:
+ return nil, EINVAL
+ }
}
return nil, EAFNOSUPPORT
}
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_386.go b/vendor/golang.org/x/sys/unix/syscall_linux_386.go
index 7b52e5d8a..b430536c8 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_386.go
@@ -378,6 +378,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
+func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
+ rsa.Service_name_len = uint32(length)
+}
+
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
index 28b764115..85cd97da0 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
@@ -172,6 +172,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
+func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
+ rsa.Service_name_len = uint64(length)
+}
+
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
index 68877728e..39a864d4e 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
@@ -256,6 +256,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
+func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
+ rsa.Service_name_len = uint32(length)
+}
+
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
index 7ed703476..7f27ebf2f 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
@@ -207,6 +207,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
+func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
+ rsa.Service_name_len = uint64(length)
+}
+
func InotifyInit() (fd int, err error) {
return InotifyInit1(0)
}
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
index 06dec06fa..27aee81d9 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
@@ -217,6 +217,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
+func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
+ rsa.Service_name_len = uint64(length)
+}
+
func InotifyInit() (fd int, err error) {
return InotifyInit1(0)
}
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
index 8f0d0a5b5..3a5621e37 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
@@ -229,6 +229,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
+func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
+ rsa.Service_name_len = uint32(length)
+}
+
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go b/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
index 7e65e088d..cf0d36f76 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
@@ -215,6 +215,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
+func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
+ rsa.Service_name_len = uint32(length)
+}
+
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
index 0b1f0d6da..5259a5fea 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
@@ -100,6 +100,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
+func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
+ rsa.Service_name_len = uint64(length)
+}
+
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
index ce9bcd317..8ef821e5d 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
@@ -188,6 +188,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
+func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
+ rsa.Service_name_len = uint64(length)
+}
+
func InotifyInit() (fd int, err error) {
return InotifyInit1(0)
}
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
index a1e45694b..a1c0574b5 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
@@ -129,6 +129,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
+func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
+ rsa.Service_name_len = uint64(length)
+}
+
// Linux on s390x uses the old mmap interface, which requires arguments to be passed in a struct.
// mmap2 also requires arguments to be passed in a struct; it is currently not exposed in <asm/unistd.h>.
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
index 49055a3cf..de14b8898 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
@@ -116,6 +116,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
+func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
+ rsa.Service_name_len = uint64(length)
+}
+
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go
index 47572aaa6..c3fa22486 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go
@@ -1406,6 +1406,10 @@ const (
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
+ MEMGETREGIONINFO = 0xc0104d08
+ MEMREADOOB64 = 0xc0184d16
+ MEMWRITE = 0xc0304d18
+ MEMWRITEOOB64 = 0xc0184d15
MFD_ALLOW_SEALING = 0x2
MFD_CLOEXEC = 0x1
MFD_HUGETLB = 0x4
@@ -1494,7 +1498,35 @@ const (
MS_SYNCHRONOUS = 0x10
MS_UNBINDABLE = 0x20000
MS_VERBOSE = 0x8000
+ MTD_ABSENT = 0x0
+ MTD_BIT_WRITEABLE = 0x800
+ MTD_CAP_NANDFLASH = 0x400
+ MTD_CAP_NORFLASH = 0xc00
+ MTD_CAP_NVRAM = 0x1c00
+ MTD_CAP_RAM = 0x1c00
+ MTD_CAP_ROM = 0x0
+ MTD_DATAFLASH = 0x6
MTD_INODE_FS_MAGIC = 0x11307854
+ MTD_MAX_ECCPOS_ENTRIES = 0x40
+ MTD_MAX_OOBFREE_ENTRIES = 0x8
+ MTD_MLCNANDFLASH = 0x8
+ MTD_NANDECC_AUTOPLACE = 0x2
+ MTD_NANDECC_AUTOPL_USR = 0x4
+ MTD_NANDECC_OFF = 0x0
+ MTD_NANDECC_PLACE = 0x1
+ MTD_NANDECC_PLACEONLY = 0x3
+ MTD_NANDFLASH = 0x4
+ MTD_NORFLASH = 0x3
+ MTD_NO_ERASE = 0x1000
+ MTD_OTP_FACTORY = 0x1
+ MTD_OTP_OFF = 0x0
+ MTD_OTP_USER = 0x2
+ MTD_POWERUP_LOCK = 0x2000
+ MTD_RAM = 0x1
+ MTD_ROM = 0x2
+ MTD_SLC_ON_MLC_EMULATION = 0x4000
+ MTD_UBIVOLUME = 0x7
+ MTD_WRITEABLE = 0x400
NAME_MAX = 0xff
NCP_SUPER_MAGIC = 0x564c
NETLINK_ADD_MEMBERSHIP = 0x1
@@ -1534,6 +1566,59 @@ const (
NETLINK_XFRM = 0x6
NETNSA_MAX = 0x5
NETNSA_NSID_NOT_ASSIGNED = -0x1
+ NFC_ATR_REQ_GB_MAXSIZE = 0x30
+ NFC_ATR_REQ_MAXSIZE = 0x40
+ NFC_ATR_RES_GB_MAXSIZE = 0x2f
+ NFC_ATR_RES_MAXSIZE = 0x40
+ NFC_COMM_ACTIVE = 0x0
+ NFC_COMM_PASSIVE = 0x1
+ NFC_DEVICE_NAME_MAXSIZE = 0x8
+ NFC_DIRECTION_RX = 0x0
+ NFC_DIRECTION_TX = 0x1
+ NFC_FIRMWARE_NAME_MAXSIZE = 0x20
+ NFC_GB_MAXSIZE = 0x30
+ NFC_GENL_MCAST_EVENT_NAME = "events"
+ NFC_GENL_NAME = "nfc"
+ NFC_GENL_VERSION = 0x1
+ NFC_HEADER_SIZE = 0x1
+ NFC_ISO15693_UID_MAXSIZE = 0x8
+ NFC_LLCP_MAX_SERVICE_NAME = 0x3f
+ NFC_LLCP_MIUX = 0x1
+ NFC_LLCP_REMOTE_LTO = 0x3
+ NFC_LLCP_REMOTE_MIU = 0x2
+ NFC_LLCP_REMOTE_RW = 0x4
+ NFC_LLCP_RW = 0x0
+ NFC_NFCID1_MAXSIZE = 0xa
+ NFC_NFCID2_MAXSIZE = 0x8
+ NFC_NFCID3_MAXSIZE = 0xa
+ NFC_PROTO_FELICA = 0x3
+ NFC_PROTO_FELICA_MASK = 0x8
+ NFC_PROTO_ISO14443 = 0x4
+ NFC_PROTO_ISO14443_B = 0x6
+ NFC_PROTO_ISO14443_B_MASK = 0x40
+ NFC_PROTO_ISO14443_MASK = 0x10
+ NFC_PROTO_ISO15693 = 0x7
+ NFC_PROTO_ISO15693_MASK = 0x80
+ NFC_PROTO_JEWEL = 0x1
+ NFC_PROTO_JEWEL_MASK = 0x2
+ NFC_PROTO_MAX = 0x8
+ NFC_PROTO_MIFARE = 0x2
+ NFC_PROTO_MIFARE_MASK = 0x4
+ NFC_PROTO_NFC_DEP = 0x5
+ NFC_PROTO_NFC_DEP_MASK = 0x20
+ NFC_RAW_HEADER_SIZE = 0x2
+ NFC_RF_INITIATOR = 0x0
+ NFC_RF_NONE = 0x2
+ NFC_RF_TARGET = 0x1
+ NFC_SENSB_RES_MAXSIZE = 0xc
+ NFC_SENSF_RES_MAXSIZE = 0x12
+ NFC_SE_DISABLED = 0x0
+ NFC_SE_EMBEDDED = 0x2
+ NFC_SE_ENABLED = 0x1
+ NFC_SE_UICC = 0x1
+ NFC_SOCKPROTO_LLCP = 0x1
+ NFC_SOCKPROTO_MAX = 0x2
+ NFC_SOCKPROTO_RAW = 0x0
NFNETLINK_V0 = 0x0
NFNLGRP_ACCT_QUOTA = 0x8
NFNLGRP_CONNTRACK_DESTROY = 0x3
@@ -1959,6 +2044,11 @@ const (
QNX4_SUPER_MAGIC = 0x2f
QNX6_SUPER_MAGIC = 0x68191122
RAMFS_MAGIC = 0x858458f6
+ RAW_PAYLOAD_DIGITAL = 0x3
+ RAW_PAYLOAD_HCI = 0x2
+ RAW_PAYLOAD_LLCP = 0x0
+ RAW_PAYLOAD_NCI = 0x1
+ RAW_PAYLOAD_PROPRIETARY = 0x4
RDTGROUP_SUPER_MAGIC = 0x7655821
REISERFS_SUPER_MAGIC = 0x52654973
RENAME_EXCHANGE = 0x2
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
index e91a1a957..09fc559ed 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x30
CSIZE = 0x30
CSTOPB = 0x40
+ ECCGETLAYOUT = 0x81484d11
+ ECCGETSTATS = 0x80104d12
ECHOCTL = 0x200
ECHOE = 0x10
ECHOK = 0x20
@@ -123,6 +125,19 @@ const (
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
+ MEMERASE = 0x40084d02
+ MEMERASE64 = 0x40104d14
+ MEMGETBADBLOCK = 0x40084d0b
+ MEMGETINFO = 0x80204d01
+ MEMGETOOBSEL = 0x80c84d0a
+ MEMGETREGIONCOUNT = 0x80044d07
+ MEMISLOCKED = 0x80084d17
+ MEMLOCK = 0x40084d05
+ MEMREADOOB = 0xc00c4d04
+ MEMSETBADBLOCK = 0x40084d0c
+ MEMUNLOCK = 0x40084d06
+ MEMWRITEOOB = 0xc00c4d03
+ MTDFILEMODE = 0x4d13
NFDBITS = 0x20
NLDLY = 0x100
NOFLSH = 0x80
@@ -132,6 +147,10 @@ const (
NS_GET_USERNS = 0xb701
OLCUC = 0x2
ONLCR = 0x4
+ OTPGETREGIONCOUNT = 0x40044d0e
+ OTPGETREGIONINFO = 0x400c4d0f
+ OTPLOCK = 0x800c4d10
+ OTPSELECT = 0x80044d0d
O_APPEND = 0x400
O_ASYNC = 0x2000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
index a9cbac644..75730cc22 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x30
CSIZE = 0x30
CSTOPB = 0x40
+ ECCGETLAYOUT = 0x81484d11
+ ECCGETSTATS = 0x80104d12
ECHOCTL = 0x200
ECHOE = 0x10
ECHOK = 0x20
@@ -123,6 +125,19 @@ const (
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
+ MEMERASE = 0x40084d02
+ MEMERASE64 = 0x40104d14
+ MEMGETBADBLOCK = 0x40084d0b
+ MEMGETINFO = 0x80204d01
+ MEMGETOOBSEL = 0x80c84d0a
+ MEMGETREGIONCOUNT = 0x80044d07
+ MEMISLOCKED = 0x80084d17
+ MEMLOCK = 0x40084d05
+ MEMREADOOB = 0xc0104d04
+ MEMSETBADBLOCK = 0x40084d0c
+ MEMUNLOCK = 0x40084d06
+ MEMWRITEOOB = 0xc0104d03
+ MTDFILEMODE = 0x4d13
NFDBITS = 0x40
NLDLY = 0x100
NOFLSH = 0x80
@@ -132,6 +147,10 @@ const (
NS_GET_USERNS = 0xb701
OLCUC = 0x2
ONLCR = 0x4
+ OTPGETREGIONCOUNT = 0x40044d0e
+ OTPGETREGIONINFO = 0x400c4d0f
+ OTPLOCK = 0x800c4d10
+ OTPSELECT = 0x80044d0d
O_APPEND = 0x400
O_ASYNC = 0x2000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
index d74f3c15a..127cf17ad 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x30
CSIZE = 0x30
CSTOPB = 0x40
+ ECCGETLAYOUT = 0x81484d11
+ ECCGETSTATS = 0x80104d12
ECHOCTL = 0x200
ECHOE = 0x10
ECHOK = 0x20
@@ -121,6 +123,19 @@ const (
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
+ MEMERASE = 0x40084d02
+ MEMERASE64 = 0x40104d14
+ MEMGETBADBLOCK = 0x40084d0b
+ MEMGETINFO = 0x80204d01
+ MEMGETOOBSEL = 0x80c84d0a
+ MEMGETREGIONCOUNT = 0x80044d07
+ MEMISLOCKED = 0x80084d17
+ MEMLOCK = 0x40084d05
+ MEMREADOOB = 0xc00c4d04
+ MEMSETBADBLOCK = 0x40084d0c
+ MEMUNLOCK = 0x40084d06
+ MEMWRITEOOB = 0xc00c4d03
+ MTDFILEMODE = 0x4d13
NFDBITS = 0x20
NLDLY = 0x100
NOFLSH = 0x80
@@ -130,6 +145,10 @@ const (
NS_GET_USERNS = 0xb701
OLCUC = 0x2
ONLCR = 0x4
+ OTPGETREGIONCOUNT = 0x40044d0e
+ OTPGETREGIONINFO = 0x400c4d0f
+ OTPLOCK = 0x800c4d10
+ OTPSELECT = 0x80044d0d
O_APPEND = 0x400
O_ASYNC = 0x2000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
index e1538995b..957ca1ff1 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x30
CSIZE = 0x30
CSTOPB = 0x40
+ ECCGETLAYOUT = 0x81484d11
+ ECCGETSTATS = 0x80104d12
ECHOCTL = 0x200
ECHOE = 0x10
ECHOK = 0x20
@@ -124,6 +126,19 @@ const (
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
+ MEMERASE = 0x40084d02
+ MEMERASE64 = 0x40104d14
+ MEMGETBADBLOCK = 0x40084d0b
+ MEMGETINFO = 0x80204d01
+ MEMGETOOBSEL = 0x80c84d0a
+ MEMGETREGIONCOUNT = 0x80044d07
+ MEMISLOCKED = 0x80084d17
+ MEMLOCK = 0x40084d05
+ MEMREADOOB = 0xc0104d04
+ MEMSETBADBLOCK = 0x40084d0c
+ MEMUNLOCK = 0x40084d06
+ MEMWRITEOOB = 0xc0104d03
+ MTDFILEMODE = 0x4d13
NFDBITS = 0x40
NLDLY = 0x100
NOFLSH = 0x80
@@ -133,6 +148,10 @@ const (
NS_GET_USERNS = 0xb701
OLCUC = 0x2
ONLCR = 0x4
+ OTPGETREGIONCOUNT = 0x40044d0e
+ OTPGETREGIONINFO = 0x400c4d0f
+ OTPLOCK = 0x800c4d10
+ OTPSELECT = 0x80044d0d
O_APPEND = 0x400
O_ASYNC = 0x2000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
index 5e8e71ff8..314a2054f 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x30
CSIZE = 0x30
CSTOPB = 0x40
+ ECCGETLAYOUT = 0x41484d11
+ ECCGETSTATS = 0x40104d12
ECHOCTL = 0x200
ECHOE = 0x10
ECHOK = 0x20
@@ -121,6 +123,19 @@ const (
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
+ MEMERASE = 0x80084d02
+ MEMERASE64 = 0x80104d14
+ MEMGETBADBLOCK = 0x80084d0b
+ MEMGETINFO = 0x40204d01
+ MEMGETOOBSEL = 0x40c84d0a
+ MEMGETREGIONCOUNT = 0x40044d07
+ MEMISLOCKED = 0x40084d17
+ MEMLOCK = 0x80084d05
+ MEMREADOOB = 0xc00c4d04
+ MEMSETBADBLOCK = 0x80084d0c
+ MEMUNLOCK = 0x80084d06
+ MEMWRITEOOB = 0xc00c4d03
+ MTDFILEMODE = 0x20004d13
NFDBITS = 0x20
NLDLY = 0x100
NOFLSH = 0x80
@@ -130,6 +145,10 @@ const (
NS_GET_USERNS = 0x2000b701
OLCUC = 0x2
ONLCR = 0x4
+ OTPGETREGIONCOUNT = 0x80044d0e
+ OTPGETREGIONINFO = 0x800c4d0f
+ OTPLOCK = 0x400c4d10
+ OTPSELECT = 0x40044d0d
O_APPEND = 0x8
O_ASYNC = 0x1000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
index e670ee148..457e8de97 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x30
CSIZE = 0x30
CSTOPB = 0x40
+ ECCGETLAYOUT = 0x41484d11
+ ECCGETSTATS = 0x40104d12
ECHOCTL = 0x200
ECHOE = 0x10
ECHOK = 0x20
@@ -121,6 +123,19 @@ const (
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
+ MEMERASE = 0x80084d02
+ MEMERASE64 = 0x80104d14
+ MEMGETBADBLOCK = 0x80084d0b
+ MEMGETINFO = 0x40204d01
+ MEMGETOOBSEL = 0x40c84d0a
+ MEMGETREGIONCOUNT = 0x40044d07
+ MEMISLOCKED = 0x40084d17
+ MEMLOCK = 0x80084d05
+ MEMREADOOB = 0xc0104d04
+ MEMSETBADBLOCK = 0x80084d0c
+ MEMUNLOCK = 0x80084d06
+ MEMWRITEOOB = 0xc0104d03
+ MTDFILEMODE = 0x20004d13
NFDBITS = 0x40
NLDLY = 0x100
NOFLSH = 0x80
@@ -130,6 +145,10 @@ const (
NS_GET_USERNS = 0x2000b701
OLCUC = 0x2
ONLCR = 0x4
+ OTPGETREGIONCOUNT = 0x80044d0e
+ OTPGETREGIONINFO = 0x800c4d0f
+ OTPLOCK = 0x400c4d10
+ OTPSELECT = 0x40044d0d
O_APPEND = 0x8
O_ASYNC = 0x1000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
index dd11eacb8..33cd28f6b 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x30
CSIZE = 0x30
CSTOPB = 0x40
+ ECCGETLAYOUT = 0x41484d11
+ ECCGETSTATS = 0x40104d12
ECHOCTL = 0x200
ECHOE = 0x10
ECHOK = 0x20
@@ -121,6 +123,19 @@ const (
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
+ MEMERASE = 0x80084d02
+ MEMERASE64 = 0x80104d14
+ MEMGETBADBLOCK = 0x80084d0b
+ MEMGETINFO = 0x40204d01
+ MEMGETOOBSEL = 0x40c84d0a
+ MEMGETREGIONCOUNT = 0x40044d07
+ MEMISLOCKED = 0x40084d17
+ MEMLOCK = 0x80084d05
+ MEMREADOOB = 0xc0104d04
+ MEMSETBADBLOCK = 0x80084d0c
+ MEMUNLOCK = 0x80084d06
+ MEMWRITEOOB = 0xc0104d03
+ MTDFILEMODE = 0x20004d13
NFDBITS = 0x40
NLDLY = 0x100
NOFLSH = 0x80
@@ -130,6 +145,10 @@ const (
NS_GET_USERNS = 0x2000b701
OLCUC = 0x2
ONLCR = 0x4
+ OTPGETREGIONCOUNT = 0x80044d0e
+ OTPGETREGIONINFO = 0x800c4d0f
+ OTPLOCK = 0x400c4d10
+ OTPSELECT = 0x40044d0d
O_APPEND = 0x8
O_ASYNC = 0x1000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
index a0a5b22ae..0e085ba14 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x30
CSIZE = 0x30
CSTOPB = 0x40
+ ECCGETLAYOUT = 0x41484d11
+ ECCGETSTATS = 0x40104d12
ECHOCTL = 0x200
ECHOE = 0x10
ECHOK = 0x20
@@ -121,6 +123,19 @@ const (
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
+ MEMERASE = 0x80084d02
+ MEMERASE64 = 0x80104d14
+ MEMGETBADBLOCK = 0x80084d0b
+ MEMGETINFO = 0x40204d01
+ MEMGETOOBSEL = 0x40c84d0a
+ MEMGETREGIONCOUNT = 0x40044d07
+ MEMISLOCKED = 0x40084d17
+ MEMLOCK = 0x80084d05
+ MEMREADOOB = 0xc00c4d04
+ MEMSETBADBLOCK = 0x80084d0c
+ MEMUNLOCK = 0x80084d06
+ MEMWRITEOOB = 0xc00c4d03
+ MTDFILEMODE = 0x20004d13
NFDBITS = 0x20
NLDLY = 0x100
NOFLSH = 0x80
@@ -130,6 +145,10 @@ const (
NS_GET_USERNS = 0x2000b701
OLCUC = 0x2
ONLCR = 0x4
+ OTPGETREGIONCOUNT = 0x80044d0e
+ OTPGETREGIONINFO = 0x800c4d0f
+ OTPLOCK = 0x400c4d10
+ OTPSELECT = 0x40044d0d
O_APPEND = 0x8
O_ASYNC = 0x1000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go
index d9530e5fb..1b5928cff 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x300
CSIZE = 0x300
CSTOPB = 0x400
+ ECCGETLAYOUT = 0x41484d11
+ ECCGETSTATS = 0x40104d12
ECHOCTL = 0x40
ECHOE = 0x2
ECHOK = 0x4
@@ -121,6 +123,19 @@ const (
MCL_CURRENT = 0x2000
MCL_FUTURE = 0x4000
MCL_ONFAULT = 0x8000
+ MEMERASE = 0x80084d02
+ MEMERASE64 = 0x80104d14
+ MEMGETBADBLOCK = 0x80084d0b
+ MEMGETINFO = 0x40204d01
+ MEMGETOOBSEL = 0x40c84d0a
+ MEMGETREGIONCOUNT = 0x40044d07
+ MEMISLOCKED = 0x40084d17
+ MEMLOCK = 0x80084d05
+ MEMREADOOB = 0xc00c4d04
+ MEMSETBADBLOCK = 0x80084d0c
+ MEMUNLOCK = 0x80084d06
+ MEMWRITEOOB = 0xc00c4d03
+ MTDFILEMODE = 0x20004d13
NFDBITS = 0x20
NL2 = 0x200
NL3 = 0x300
@@ -132,6 +147,10 @@ const (
NS_GET_USERNS = 0x2000b701
OLCUC = 0x4
ONLCR = 0x2
+ OTPGETREGIONCOUNT = 0x80044d0e
+ OTPGETREGIONINFO = 0x800c4d0f
+ OTPLOCK = 0x400c4d10
+ OTPSELECT = 0x40044d0d
O_APPEND = 0x400
O_ASYNC = 0x2000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
index e60102f6a..f3a41d6ec 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x300
CSIZE = 0x300
CSTOPB = 0x400
+ ECCGETLAYOUT = 0x41484d11
+ ECCGETSTATS = 0x40104d12
ECHOCTL = 0x40
ECHOE = 0x2
ECHOK = 0x4
@@ -121,6 +123,19 @@ const (
MCL_CURRENT = 0x2000
MCL_FUTURE = 0x4000
MCL_ONFAULT = 0x8000
+ MEMERASE = 0x80084d02
+ MEMERASE64 = 0x80104d14
+ MEMGETBADBLOCK = 0x80084d0b
+ MEMGETINFO = 0x40204d01
+ MEMGETOOBSEL = 0x40c84d0a
+ MEMGETREGIONCOUNT = 0x40044d07
+ MEMISLOCKED = 0x40084d17
+ MEMLOCK = 0x80084d05
+ MEMREADOOB = 0xc0104d04
+ MEMSETBADBLOCK = 0x80084d0c
+ MEMUNLOCK = 0x80084d06
+ MEMWRITEOOB = 0xc0104d03
+ MTDFILEMODE = 0x20004d13
NFDBITS = 0x40
NL2 = 0x200
NL3 = 0x300
@@ -132,6 +147,10 @@ const (
NS_GET_USERNS = 0x2000b701
OLCUC = 0x4
ONLCR = 0x2
+ OTPGETREGIONCOUNT = 0x80044d0e
+ OTPGETREGIONINFO = 0x800c4d0f
+ OTPLOCK = 0x400c4d10
+ OTPSELECT = 0x40044d0d
O_APPEND = 0x400
O_ASYNC = 0x2000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
index 838ff4ea6..6a5a555d5 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x300
CSIZE = 0x300
CSTOPB = 0x400
+ ECCGETLAYOUT = 0x41484d11
+ ECCGETSTATS = 0x40104d12
ECHOCTL = 0x40
ECHOE = 0x2
ECHOK = 0x4
@@ -121,6 +123,19 @@ const (
MCL_CURRENT = 0x2000
MCL_FUTURE = 0x4000
MCL_ONFAULT = 0x8000
+ MEMERASE = 0x80084d02
+ MEMERASE64 = 0x80104d14
+ MEMGETBADBLOCK = 0x80084d0b
+ MEMGETINFO = 0x40204d01
+ MEMGETOOBSEL = 0x40c84d0a
+ MEMGETREGIONCOUNT = 0x40044d07
+ MEMISLOCKED = 0x40084d17
+ MEMLOCK = 0x80084d05
+ MEMREADOOB = 0xc0104d04
+ MEMSETBADBLOCK = 0x80084d0c
+ MEMUNLOCK = 0x80084d06
+ MEMWRITEOOB = 0xc0104d03
+ MTDFILEMODE = 0x20004d13
NFDBITS = 0x40
NL2 = 0x200
NL3 = 0x300
@@ -132,6 +147,10 @@ const (
NS_GET_USERNS = 0x2000b701
OLCUC = 0x4
ONLCR = 0x2
+ OTPGETREGIONCOUNT = 0x80044d0e
+ OTPGETREGIONINFO = 0x800c4d0f
+ OTPLOCK = 0x400c4d10
+ OTPSELECT = 0x40044d0d
O_APPEND = 0x400
O_ASYNC = 0x2000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
index 7cc98f09c..a4da67edb 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x30
CSIZE = 0x30
CSTOPB = 0x40
+ ECCGETLAYOUT = 0x81484d11
+ ECCGETSTATS = 0x80104d12
ECHOCTL = 0x200
ECHOE = 0x10
ECHOK = 0x20
@@ -121,6 +123,19 @@ const (
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
+ MEMERASE = 0x40084d02
+ MEMERASE64 = 0x40104d14
+ MEMGETBADBLOCK = 0x40084d0b
+ MEMGETINFO = 0x80204d01
+ MEMGETOOBSEL = 0x80c84d0a
+ MEMGETREGIONCOUNT = 0x80044d07
+ MEMISLOCKED = 0x80084d17
+ MEMLOCK = 0x40084d05
+ MEMREADOOB = 0xc0104d04
+ MEMSETBADBLOCK = 0x40084d0c
+ MEMUNLOCK = 0x40084d06
+ MEMWRITEOOB = 0xc0104d03
+ MTDFILEMODE = 0x4d13
NFDBITS = 0x40
NLDLY = 0x100
NOFLSH = 0x80
@@ -130,6 +145,10 @@ const (
NS_GET_USERNS = 0xb701
OLCUC = 0x2
ONLCR = 0x4
+ OTPGETREGIONCOUNT = 0x40044d0e
+ OTPGETREGIONINFO = 0x400c4d0f
+ OTPLOCK = 0x800c4d10
+ OTPSELECT = 0x80044d0d
O_APPEND = 0x400
O_ASYNC = 0x2000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
index 6d30e6fd8..a7028e0ef 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
@@ -60,6 +60,8 @@ const (
CS8 = 0x30
CSIZE = 0x30
CSTOPB = 0x40
+ ECCGETLAYOUT = 0x81484d11
+ ECCGETSTATS = 0x80104d12
ECHOCTL = 0x200
ECHOE = 0x10
ECHOK = 0x20
@@ -121,6 +123,19 @@ const (
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
+ MEMERASE = 0x40084d02
+ MEMERASE64 = 0x40104d14
+ MEMGETBADBLOCK = 0x40084d0b
+ MEMGETINFO = 0x80204d01
+ MEMGETOOBSEL = 0x80c84d0a
+ MEMGETREGIONCOUNT = 0x80044d07
+ MEMISLOCKED = 0x80084d17
+ MEMLOCK = 0x40084d05
+ MEMREADOOB = 0xc0104d04
+ MEMSETBADBLOCK = 0x40084d0c
+ MEMUNLOCK = 0x40084d06
+ MEMWRITEOOB = 0xc0104d03
+ MTDFILEMODE = 0x4d13
NFDBITS = 0x40
NLDLY = 0x100
NOFLSH = 0x80
@@ -130,6 +145,10 @@ const (
NS_GET_USERNS = 0xb701
OLCUC = 0x2
ONLCR = 0x4
+ OTPGETREGIONCOUNT = 0x40044d0e
+ OTPGETREGIONINFO = 0x400c4d0f
+ OTPLOCK = 0x800c4d10
+ OTPSELECT = 0x80044d0d
O_APPEND = 0x400
O_ASYNC = 0x2000
O_CLOEXEC = 0x80000
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
index d5e2dc94f..ed3b3286c 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
@@ -63,6 +63,8 @@ const (
CS8 = 0x30
CSIZE = 0x30
CSTOPB = 0x40
+ ECCGETLAYOUT = 0x41484d11
+ ECCGETSTATS = 0x40104d12
ECHOCTL = 0x200
ECHOE = 0x10
ECHOK = 0x20
@@ -126,6 +128,19 @@ const (
MCL_CURRENT = 0x2000
MCL_FUTURE = 0x4000
MCL_ONFAULT = 0x8000
+ MEMERASE = 0x80084d02
+ MEMERASE64 = 0x80104d14
+ MEMGETBADBLOCK = 0x80084d0b
+ MEMGETINFO = 0x40204d01
+ MEMGETOOBSEL = 0x40c84d0a
+ MEMGETREGIONCOUNT = 0x40044d07
+ MEMISLOCKED = 0x40084d17
+ MEMLOCK = 0x80084d05
+ MEMREADOOB = 0xc0104d04
+ MEMSETBADBLOCK = 0x80084d0c
+ MEMUNLOCK = 0x80084d06
+ MEMWRITEOOB = 0xc0104d03
+ MTDFILEMODE = 0x20004d13
NFDBITS = 0x40
NLDLY = 0x100
NOFLSH = 0x80
@@ -135,6 +150,10 @@ const (
NS_GET_USERNS = 0x2000b701
OLCUC = 0x2
ONLCR = 0x4
+ OTPGETREGIONCOUNT = 0x80044d0e
+ OTPGETREGIONINFO = 0x800c4d0f
+ OTPLOCK = 0x400c4d10
+ OTPSELECT = 0x40044d0d
O_APPEND = 0x8
O_ASYNC = 0x40
O_CLOEXEC = 0x400000
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go
index 087323591..72887abe5 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go
@@ -351,6 +351,13 @@ type RawSockaddrIUCV struct {
Name [8]int8
}
+type RawSockaddrNFC struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+}
+
type _Socklen uint32
type Linger struct {
@@ -464,6 +471,7 @@ const (
SizeofSockaddrL2TPIP = 0x10
SizeofSockaddrL2TPIP6 = 0x20
SizeofSockaddrIUCV = 0x20
+ SizeofSockaddrNFC = 0x10
SizeofLinger = 0x8
SizeofIPMreq = 0x8
SizeofIPMreqn = 0xc
@@ -3742,3 +3750,158 @@ const (
NLMSGERR_ATTR_OFFS = 0x2
NLMSGERR_ATTR_COOKIE = 0x3
)
+
+type (
+ EraseInfo struct {
+ Start uint32
+ Length uint32
+ }
+ EraseInfo64 struct {
+ Start uint64
+ Length uint64
+ }
+ MtdOobBuf struct {
+ Start uint32
+ Length uint32
+ Ptr *uint8
+ }
+ MtdOobBuf64 struct {
+ Start uint64
+ Pad uint32
+ Length uint32
+ Ptr uint64
+ }
+ MtdWriteReq struct {
+ Start uint64
+ Len uint64
+ Ooblen uint64
+ Data uint64
+ Oob uint64
+ Mode uint8
+ _ [7]uint8
+ }
+ MtdInfo struct {
+ Type uint8
+ Flags uint32
+ Size uint32
+ Erasesize uint32
+ Writesize uint32
+ Oobsize uint32
+ _ uint64
+ }
+ RegionInfo struct {
+ Offset uint32
+ Erasesize uint32
+ Numblocks uint32
+ Regionindex uint32
+ }
+ OtpInfo struct {
+ Start uint32
+ Length uint32
+ Locked uint32
+ }
+ NandOobinfo struct {
+ Useecc uint32
+ Eccbytes uint32
+ Oobfree [8][2]uint32
+ Eccpos [32]uint32
+ }
+ NandOobfree struct {
+ Offset uint32
+ Length uint32
+ }
+ NandEcclayout struct {
+ Eccbytes uint32
+ Eccpos [64]uint32
+ Oobavail uint32
+ Oobfree [8]NandOobfree
+ }
+ MtdEccStats struct {
+ Corrected uint32
+ Failed uint32
+ Badblocks uint32
+ Bbtblocks uint32
+ }
+)
+
+const (
+ MTD_OPS_PLACE_OOB = 0x0
+ MTD_OPS_AUTO_OOB = 0x1
+ MTD_OPS_RAW = 0x2
+)
+
+const (
+ MTD_FILE_MODE_NORMAL = 0x0
+ MTD_FILE_MODE_OTP_FACTORY = 0x1
+ MTD_FILE_MODE_OTP_USER = 0x2
+ MTD_FILE_MODE_RAW = 0x3
+)
+
+const (
+ NFC_CMD_UNSPEC = 0x0
+ NFC_CMD_GET_DEVICE = 0x1
+ NFC_CMD_DEV_UP = 0x2
+ NFC_CMD_DEV_DOWN = 0x3
+ NFC_CMD_DEP_LINK_UP = 0x4
+ NFC_CMD_DEP_LINK_DOWN = 0x5
+ NFC_CMD_START_POLL = 0x6
+ NFC_CMD_STOP_POLL = 0x7
+ NFC_CMD_GET_TARGET = 0x8
+ NFC_EVENT_TARGETS_FOUND = 0x9
+ NFC_EVENT_DEVICE_ADDED = 0xa
+ NFC_EVENT_DEVICE_REMOVED = 0xb
+ NFC_EVENT_TARGET_LOST = 0xc
+ NFC_EVENT_TM_ACTIVATED = 0xd
+ NFC_EVENT_TM_DEACTIVATED = 0xe
+ NFC_CMD_LLC_GET_PARAMS = 0xf
+ NFC_CMD_LLC_SET_PARAMS = 0x10
+ NFC_CMD_ENABLE_SE = 0x11
+ NFC_CMD_DISABLE_SE = 0x12
+ NFC_CMD_LLC_SDREQ = 0x13
+ NFC_EVENT_LLC_SDRES = 0x14
+ NFC_CMD_FW_DOWNLOAD = 0x15
+ NFC_EVENT_SE_ADDED = 0x16
+ NFC_EVENT_SE_REMOVED = 0x17
+ NFC_EVENT_SE_CONNECTIVITY = 0x18
+ NFC_EVENT_SE_TRANSACTION = 0x19
+ NFC_CMD_GET_SE = 0x1a
+ NFC_CMD_SE_IO = 0x1b
+ NFC_CMD_ACTIVATE_TARGET = 0x1c
+ NFC_CMD_VENDOR = 0x1d
+ NFC_CMD_DEACTIVATE_TARGET = 0x1e
+ NFC_ATTR_UNSPEC = 0x0
+ NFC_ATTR_DEVICE_INDEX = 0x1
+ NFC_ATTR_DEVICE_NAME = 0x2
+ NFC_ATTR_PROTOCOLS = 0x3
+ NFC_ATTR_TARGET_INDEX = 0x4
+ NFC_ATTR_TARGET_SENS_RES = 0x5
+ NFC_ATTR_TARGET_SEL_RES = 0x6
+ NFC_ATTR_TARGET_NFCID1 = 0x7
+ NFC_ATTR_TARGET_SENSB_RES = 0x8
+ NFC_ATTR_TARGET_SENSF_RES = 0x9
+ NFC_ATTR_COMM_MODE = 0xa
+ NFC_ATTR_RF_MODE = 0xb
+ NFC_ATTR_DEVICE_POWERED = 0xc
+ NFC_ATTR_IM_PROTOCOLS = 0xd
+ NFC_ATTR_TM_PROTOCOLS = 0xe
+ NFC_ATTR_LLC_PARAM_LTO = 0xf
+ NFC_ATTR_LLC_PARAM_RW = 0x10
+ NFC_ATTR_LLC_PARAM_MIUX = 0x11
+ NFC_ATTR_SE = 0x12
+ NFC_ATTR_LLC_SDP = 0x13
+ NFC_ATTR_FIRMWARE_NAME = 0x14
+ NFC_ATTR_SE_INDEX = 0x15
+ NFC_ATTR_SE_TYPE = 0x16
+ NFC_ATTR_SE_AID = 0x17
+ NFC_ATTR_FIRMWARE_DOWNLOAD_STATUS = 0x18
+ NFC_ATTR_SE_APDU = 0x19
+ NFC_ATTR_TARGET_ISO15693_DSFID = 0x1a
+ NFC_ATTR_TARGET_ISO15693_UID = 0x1b
+ NFC_ATTR_SE_PARAMS = 0x1c
+ NFC_ATTR_VENDOR_ID = 0x1d
+ NFC_ATTR_VENDOR_SUBCMD = 0x1e
+ NFC_ATTR_VENDOR_DATA = 0x1f
+ NFC_SDP_ATTR_UNSPEC = 0x0
+ NFC_SDP_ATTR_URI = 0x1
+ NFC_SDP_ATTR_SAP = 0x2
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
index 4d4d283de..235c62e46 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
@@ -128,6 +128,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint32
+}
+
type RawSockaddr struct {
Family uint16
Data [14]int8
@@ -160,9 +171,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x8
- SizeofMsghdr = 0x1c
- SizeofCmsghdr = 0xc
+ SizeofSockaddrNFCLLCP = 0x58
+ SizeofIovec = 0x8
+ SizeofMsghdr = 0x1c
+ SizeofCmsghdr = 0xc
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
index 8a2eed5ec..99b1e5b6a 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
@@ -130,6 +130,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint64
+}
+
type RawSockaddr struct {
Family uint16
Data [14]int8
@@ -163,9 +174,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x10
- SizeofMsghdr = 0x38
- SizeofCmsghdr = 0x10
+ SizeofSockaddrNFCLLCP = 0x60
+ SizeofIovec = 0x10
+ SizeofMsghdr = 0x38
+ SizeofCmsghdr = 0x10
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
index 94b34add6..cc8bba791 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
@@ -134,6 +134,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint32
+}
+
type RawSockaddr struct {
Family uint16
Data [14]uint8
@@ -166,9 +177,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x8
- SizeofMsghdr = 0x1c
- SizeofCmsghdr = 0xc
+ SizeofSockaddrNFCLLCP = 0x58
+ SizeofIovec = 0x8
+ SizeofMsghdr = 0x1c
+ SizeofCmsghdr = 0xc
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
index 2143de4d5..fa8fe3a75 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
@@ -131,6 +131,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint64
+}
+
type RawSockaddr struct {
Family uint16
Data [14]int8
@@ -164,9 +175,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x10
- SizeofMsghdr = 0x38
- SizeofCmsghdr = 0x10
+ SizeofSockaddrNFCLLCP = 0x60
+ SizeofIovec = 0x10
+ SizeofMsghdr = 0x38
+ SizeofCmsghdr = 0x10
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
index a40216eee..e7fb8d9b7 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
@@ -133,6 +133,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint32
+}
+
type RawSockaddr struct {
Family uint16
Data [14]int8
@@ -165,9 +176,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x8
- SizeofMsghdr = 0x1c
- SizeofCmsghdr = 0xc
+ SizeofSockaddrNFCLLCP = 0x58
+ SizeofIovec = 0x8
+ SizeofMsghdr = 0x1c
+ SizeofCmsghdr = 0xc
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
index e834b069f..2fa61d593 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
@@ -131,6 +131,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint64
+}
+
type RawSockaddr struct {
Family uint16
Data [14]int8
@@ -164,9 +175,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x10
- SizeofMsghdr = 0x38
- SizeofCmsghdr = 0x10
+ SizeofSockaddrNFCLLCP = 0x60
+ SizeofIovec = 0x10
+ SizeofMsghdr = 0x38
+ SizeofCmsghdr = 0x10
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
index e31083b04..7f3639933 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
@@ -131,6 +131,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint64
+}
+
type RawSockaddr struct {
Family uint16
Data [14]int8
@@ -164,9 +175,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x10
- SizeofMsghdr = 0x38
- SizeofCmsghdr = 0x10
+ SizeofSockaddrNFCLLCP = 0x60
+ SizeofIovec = 0x10
+ SizeofMsghdr = 0x38
+ SizeofCmsghdr = 0x10
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
index 42811f7fb..f3c20cb86 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
@@ -133,6 +133,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint32
+}
+
type RawSockaddr struct {
Family uint16
Data [14]int8
@@ -165,9 +176,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x8
- SizeofMsghdr = 0x1c
- SizeofCmsghdr = 0xc
+ SizeofSockaddrNFCLLCP = 0x58
+ SizeofIovec = 0x8
+ SizeofMsghdr = 0x1c
+ SizeofCmsghdr = 0xc
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go
index af7a72017..885d27950 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go
@@ -134,6 +134,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint32
+}
+
type RawSockaddr struct {
Family uint16
Data [14]uint8
@@ -166,9 +177,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x8
- SizeofMsghdr = 0x1c
- SizeofCmsghdr = 0xc
+ SizeofSockaddrNFCLLCP = 0x58
+ SizeofIovec = 0x8
+ SizeofMsghdr = 0x1c
+ SizeofCmsghdr = 0xc
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
index 2a3afbaef..a94eb8e18 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
@@ -132,6 +132,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint64
+}
+
type RawSockaddr struct {
Family uint16
Data [14]uint8
@@ -165,9 +176,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x10
- SizeofMsghdr = 0x38
- SizeofCmsghdr = 0x10
+ SizeofSockaddrNFCLLCP = 0x60
+ SizeofIovec = 0x10
+ SizeofMsghdr = 0x38
+ SizeofCmsghdr = 0x10
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
index c0de30a65..659e32ebd 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
@@ -132,6 +132,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint64
+}
+
type RawSockaddr struct {
Family uint16
Data [14]uint8
@@ -165,9 +176,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x10
- SizeofMsghdr = 0x38
- SizeofCmsghdr = 0x10
+ SizeofSockaddrNFCLLCP = 0x60
+ SizeofIovec = 0x10
+ SizeofMsghdr = 0x38
+ SizeofCmsghdr = 0x10
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
index 74faf2e91..ab8ec604f 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
@@ -131,6 +131,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint64
+}
+
type RawSockaddr struct {
Family uint16
Data [14]uint8
@@ -164,9 +175,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x10
- SizeofMsghdr = 0x38
- SizeofCmsghdr = 0x10
+ SizeofSockaddrNFCLLCP = 0x60
+ SizeofIovec = 0x10
+ SizeofMsghdr = 0x38
+ SizeofCmsghdr = 0x10
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
index 9a8f0c2c6..3ec08237f 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
@@ -130,6 +130,17 @@ const (
FADV_NOREUSE = 0x7
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint64
+}
+
type RawSockaddr struct {
Family uint16
Data [14]int8
@@ -163,9 +174,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x10
- SizeofMsghdr = 0x38
- SizeofCmsghdr = 0x10
+ SizeofSockaddrNFCLLCP = 0x60
+ SizeofIovec = 0x10
+ SizeofMsghdr = 0x38
+ SizeofCmsghdr = 0x10
)
const (
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go
index 72cdda75b..23d474470 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go
@@ -134,6 +134,17 @@ const (
FADV_NOREUSE = 0x5
)
+type RawSockaddrNFCLLCP struct {
+ Sa_family uint16
+ Dev_idx uint32
+ Target_idx uint32
+ Nfc_protocol uint32
+ Dsap uint8
+ Ssap uint8
+ Service_name [63]uint8
+ Service_name_len uint64
+}
+
type RawSockaddr struct {
Family uint16
Data [14]int8
@@ -167,9 +178,10 @@ type Cmsghdr struct {
}
const (
- SizeofIovec = 0x10
- SizeofMsghdr = 0x38
- SizeofCmsghdr = 0x10
+ SizeofSockaddrNFCLLCP = 0x60
+ SizeofIovec = 0x10
+ SizeofMsghdr = 0x38
+ SizeofCmsghdr = 0x10
)
const (
diff --git a/vendor/golang.org/x/sys/windows/exec_windows.go b/vendor/golang.org/x/sys/windows/exec_windows.go
index a020caeef..7a11e83b7 100644
--- a/vendor/golang.org/x/sys/windows/exec_windows.go
+++ b/vendor/golang.org/x/sys/windows/exec_windows.go
@@ -9,6 +9,8 @@ package windows
import (
errorspkg "errors"
"unsafe"
+
+ "golang.org/x/sys/internal/unsafeheader"
)
// EscapeArg rewrites command line argument s as prescribed
@@ -135,8 +137,8 @@ func FullPath(name string) (path string, err error) {
}
}
-// NewProcThreadAttributeList allocates a new ProcThreadAttributeList, with the requested maximum number of attributes.
-func NewProcThreadAttributeList(maxAttrCount uint32) (*ProcThreadAttributeList, error) {
+// NewProcThreadAttributeList allocates a new ProcThreadAttributeListContainer, with the requested maximum number of attributes.
+func NewProcThreadAttributeList(maxAttrCount uint32) (*ProcThreadAttributeListContainer, error) {
var size uintptr
err := initializeProcThreadAttributeList(nil, maxAttrCount, 0, &size)
if err != ERROR_INSUFFICIENT_BUFFER {
@@ -145,10 +147,9 @@ func NewProcThreadAttributeList(maxAttrCount uint32) (*ProcThreadAttributeList,
}
return nil, err
}
- const psize = unsafe.Sizeof(uintptr(0))
// size is guaranteed to be ≥1 by InitializeProcThreadAttributeList.
- al := (*ProcThreadAttributeList)(unsafe.Pointer(&make([]unsafe.Pointer, (size+psize-1)/psize)[0]))
- err = initializeProcThreadAttributeList(al, maxAttrCount, 0, &size)
+ al := &ProcThreadAttributeListContainer{data: (*ProcThreadAttributeList)(unsafe.Pointer(&make([]byte, size)[0]))}
+ err = initializeProcThreadAttributeList(al.data, maxAttrCount, 0, &size)
if err != nil {
return nil, err
}
@@ -156,11 +157,39 @@ func NewProcThreadAttributeList(maxAttrCount uint32) (*ProcThreadAttributeList,
}
// Update modifies the ProcThreadAttributeList using UpdateProcThreadAttribute.
-func (al *ProcThreadAttributeList) Update(attribute uintptr, flags uint32, value unsafe.Pointer, size uintptr, prevValue unsafe.Pointer, returnedSize *uintptr) error {
- return updateProcThreadAttribute(al, flags, attribute, value, size, prevValue, returnedSize)
+// Note that the value passed to this function will be copied into memory
+// allocated by LocalAlloc, the contents of which should not contain any
+// Go-managed pointers, even if the passed value itself is a Go-managed
+// pointer.
+func (al *ProcThreadAttributeListContainer) Update(attribute uintptr, value unsafe.Pointer, size uintptr) error {
+ alloc, err := LocalAlloc(LMEM_FIXED, uint32(size))
+ if err != nil {
+ return err
+ }
+ var src, dst []byte
+ hdr := (*unsafeheader.Slice)(unsafe.Pointer(&src))
+ hdr.Data = value
+ hdr.Cap = int(size)
+ hdr.Len = int(size)
+ hdr = (*unsafeheader.Slice)(unsafe.Pointer(&dst))
+ hdr.Data = unsafe.Pointer(alloc)
+ hdr.Cap = int(size)
+ hdr.Len = int(size)
+ copy(dst, src)
+ al.heapAllocations = append(al.heapAllocations, alloc)
+ return updateProcThreadAttribute(al.data, 0, attribute, unsafe.Pointer(alloc), size, nil, nil)
}
// Delete frees ProcThreadAttributeList's resources.
-func (al *ProcThreadAttributeList) Delete() {
- deleteProcThreadAttributeList(al)
+func (al *ProcThreadAttributeListContainer) Delete() {
+ deleteProcThreadAttributeList(al.data)
+ for i := range al.heapAllocations {
+ LocalFree(Handle(al.heapAllocations[i]))
+ }
+ al.heapAllocations = nil
+}
+
+// List returns the actual ProcThreadAttributeList to be passed to StartupInfoEx.
+func (al *ProcThreadAttributeListContainer) List() *ProcThreadAttributeList {
+ return al.data
}
diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go
index bb6aaf89e..1215b2ae2 100644
--- a/vendor/golang.org/x/sys/windows/syscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/syscall_windows.go
@@ -220,6 +220,7 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys CancelIo(s Handle) (err error)
//sys CancelIoEx(s Handle, o *Overlapped) (err error)
//sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW
+//sys CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = advapi32.CreateProcessAsUserW
//sys initializeProcThreadAttributeList(attrlist *ProcThreadAttributeList, attrcount uint32, flags uint32, size *uintptr) (err error) = InitializeProcThreadAttributeList
//sys deleteProcThreadAttributeList(attrlist *ProcThreadAttributeList) = DeleteProcThreadAttributeList
//sys updateProcThreadAttribute(attrlist *ProcThreadAttributeList, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) = UpdateProcThreadAttribute
diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go
index 23fe18ece..1f733398e 100644
--- a/vendor/golang.org/x/sys/windows/types_windows.go
+++ b/vendor/golang.org/x/sys/windows/types_windows.go
@@ -909,14 +909,15 @@ type StartupInfoEx struct {
// ProcThreadAttributeList is a placeholder type to represent a PROC_THREAD_ATTRIBUTE_LIST.
//
-// To create a *ProcThreadAttributeList, use NewProcThreadAttributeList, and
-// free its memory using ProcThreadAttributeList.Delete.
-type ProcThreadAttributeList struct {
- // This is of type unsafe.Pointer, not of type byte or uintptr, because
- // the contents of it is mostly a list of pointers, and in most cases,
- // that's a list of pointers to Go-allocated objects. In order to keep
- // the GC from collecting these objects, we declare this as unsafe.Pointer.
- _ [1]unsafe.Pointer
+// To create a *ProcThreadAttributeList, use NewProcThreadAttributeList, update
+// it with ProcThreadAttributeListContainer.Update, free its memory using
+// ProcThreadAttributeListContainer.Delete, and access the list itself using
+// ProcThreadAttributeListContainer.List.
+type ProcThreadAttributeList struct{}
+
+type ProcThreadAttributeListContainer struct {
+ data *ProcThreadAttributeList
+ heapAllocations []uintptr
}
type ProcessInformation struct {
diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
index 559bc845c..148de0ffb 100644
--- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
@@ -69,6 +69,7 @@ var (
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW")
procCopySid = modadvapi32.NewProc("CopySid")
+ procCreateProcessAsUserW = modadvapi32.NewProc("CreateProcessAsUserW")
procCreateServiceW = modadvapi32.NewProc("CreateServiceW")
procCreateWellKnownSid = modadvapi32.NewProc("CreateWellKnownSid")
procCryptAcquireContextW = modadvapi32.NewProc("CryptAcquireContextW")
@@ -553,6 +554,18 @@ func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) {
return
}
+func CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) {
+ var _p0 uint32
+ if inheritHandles {
+ _p0 = 1
+ }
+ r1, _, e1 := syscall.Syscall12(procCreateProcessAsUserW.Addr(), 11, uintptr(token), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) {
r0, _, e1 := syscall.Syscall15(procCreateServiceW.Addr(), 13, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), 0, 0)
handle = Handle(r0)
diff --git a/vendor/modules.txt b/vendor/modules.txt
index f2a38caca..c4cfc0d83 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -93,7 +93,7 @@ github.com/containers/buildah/pkg/overlay
github.com/containers/buildah/pkg/parse
github.com/containers/buildah/pkg/rusage
github.com/containers/buildah/util
-# github.com/containers/common v0.39.1-0.20210527140106-e5800a20386a
+# github.com/containers/common v0.40.2-0.20210623133759-d13a31743aec
github.com/containers/common/libimage
github.com/containers/common/libimage/manifests
github.com/containers/common/pkg/apparmor
@@ -114,6 +114,7 @@ github.com/containers/common/pkg/retry
github.com/containers/common/pkg/seccomp
github.com/containers/common/pkg/secrets
github.com/containers/common/pkg/secrets/filedriver
+github.com/containers/common/pkg/secrets/passdriver
github.com/containers/common/pkg/signal
github.com/containers/common/pkg/subscriptions
github.com/containers/common/pkg/supplemented
@@ -123,7 +124,7 @@ github.com/containers/common/pkg/umask
github.com/containers/common/version
# github.com/containers/conmon v2.0.20+incompatible
github.com/containers/conmon/runner/config
-# github.com/containers/image/v5 v5.12.0
+# github.com/containers/image/v5 v5.13.2
github.com/containers/image/v5/copy
github.com/containers/image/v5/directory
github.com/containers/image/v5/directory/explicitfilepath
@@ -195,7 +196,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.32.2
+# github.com/containers/storage v1.32.3
github.com/containers/storage
github.com/containers/storage/drivers
github.com/containers/storage/drivers/aufs
@@ -253,7 +254,7 @@ github.com/coreos/stream-metadata-go/fedoracoreos
github.com/coreos/stream-metadata-go/fedoracoreos/internals
github.com/coreos/stream-metadata-go/stream
github.com/coreos/stream-metadata-go/stream/rhcos
-# github.com/cri-o/ocicni v0.2.1-0.20210301205850-541cf7c703cf
+# github.com/cri-o/ocicni v0.2.1-0.20210621164014-d0acc7862283
github.com/cri-o/ocicni/pkg/ocicni
# github.com/cyphar/filepath-securejoin v0.2.2
github.com/cyphar/filepath-securejoin
@@ -311,7 +312,7 @@ github.com/docker/docker/pkg/parsers
github.com/docker/docker/pkg/pools
github.com/docker/docker/pkg/stdcopy
github.com/docker/docker/pkg/system
-# github.com/docker/docker-credential-helpers v0.6.3
+# github.com/docker/docker-credential-helpers v0.6.4
github.com/docker/docker-credential-helpers/client
github.com/docker/docker-credential-helpers/credentials
# github.com/docker/go-connections v0.4.0
@@ -384,20 +385,20 @@ github.com/hpcloud/tail/ratelimiter
github.com/hpcloud/tail/util
github.com/hpcloud/tail/watch
github.com/hpcloud/tail/winfile
-# github.com/imdario/mergo v0.3.11
+# github.com/imdario/mergo v0.3.12
github.com/imdario/mergo
# github.com/inconshreveable/mousetrap v1.0.0
github.com/inconshreveable/mousetrap
# github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee
github.com/ishidawataru/sctp
-# github.com/jinzhu/copier v0.3.0
+# github.com/jinzhu/copier v0.3.2
github.com/jinzhu/copier
# github.com/json-iterator/go v1.1.11
github.com/json-iterator/go
# github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a
github.com/juju/ansiterm
github.com/juju/ansiterm/tabwriter
-# github.com/klauspost/compress v1.13.0
+# github.com/klauspost/compress v1.13.1
github.com/klauspost/compress/flate
github.com/klauspost/compress/fse
github.com/klauspost/compress/huff0
@@ -415,7 +416,7 @@ github.com/manifoldco/promptui/screenbuf
github.com/mattn/go-colorable
# github.com/mattn/go-isatty v0.0.12
github.com/mattn/go-isatty
-# github.com/mattn/go-runewidth v0.0.12
+# github.com/mattn/go-runewidth v0.0.13
github.com/mattn/go-runewidth
# github.com/mattn/go-shellwords v1.0.12
github.com/mattn/go-shellwords
@@ -605,6 +606,11 @@ github.com/vbauerster/mpb/v6
github.com/vbauerster/mpb/v6/cwriter
github.com/vbauerster/mpb/v6/decor
github.com/vbauerster/mpb/v6/internal
+# github.com/vbauerster/mpb/v7 v7.0.2
+github.com/vbauerster/mpb/v7
+github.com/vbauerster/mpb/v7/cwriter
+github.com/vbauerster/mpb/v7/decor
+github.com/vbauerster/mpb/v7/internal
# github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852
github.com/vishvananda/netlink
github.com/vishvananda/netlink/nl
@@ -662,7 +668,7 @@ golang.org/x/net/proxy
golang.org/x/net/trace
# golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
golang.org/x/sync/semaphore
-# golang.org/x/sys v0.0.0-20210514084401-e8d321eab015
+# golang.org/x/sys v0.0.0-20210603125802-9665404d3644
golang.org/x/sys/cpu
golang.org/x/sys/execabs
golang.org/x/sys/internal/unsafeheader
@@ -782,10 +788,10 @@ gopkg.in/tomb.v1
gopkg.in/yaml.v2
# gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
gopkg.in/yaml.v3
-# k8s.io/api v0.21.1
+# k8s.io/api v0.21.2
k8s.io/api/apps/v1
k8s.io/api/core/v1
-# k8s.io/apimachinery v0.21.1
+# k8s.io/apimachinery v0.21.2
k8s.io/apimachinery/pkg/api/resource
k8s.io/apimachinery/pkg/apis/meta/v1
k8s.io/apimachinery/pkg/conversion