diff options
79 files changed, 2057 insertions, 1924 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 958c6b0c7..324fd32f6 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -29,7 +29,7 @@ env: UBUNTU_NAME: "ubuntu-2110" # Google-cloud VM Images - IMAGE_SUFFIX: "c4955393725038592" + IMAGE_SUFFIX: "c6211193021923328" FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}" PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}" UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX}" @@ -51,6 +51,11 @@ env: VM_IMAGE_NAME: # One of the "Google-cloud VM Images" (above) CTR_FQIN: # One of the "Container FQIN's" (above) + # Curl-command prefix for downloading task artifacts, simply add the + # the url-encoded task name, artifact name, and path as a suffix. + ARTCURL: >- + curl --fail --location -O + --url https://api.cirrus-ci.com/v1/artifact/build/${CIRRUS_BUILD_ID} # Default timeout for each task timeout_in: 60m @@ -96,7 +101,6 @@ ext_svc_check_task: _gc='git config --file /root/.gitconfig' $_gc user.email "TMcTestFace@example.com" $_gc user.name "Testy McTestface" - make install.tools setup_script: &setup '$GOSRC/$SCRIPT_BASE/setup_environment.sh' main_script: &main '/usr/bin/time --verbose --output="$STATS_LOGFILE" $GOSRC/$SCRIPT_BASE/runner.sh' @@ -123,14 +127,12 @@ automation_task: always: *runner_stats -# N/B: This task is critical. It builds all binaries and release archives -# for the project, using all primary OS platforms and versions. Assuming -# the builds are successful, a cache is stored of the entire `$GOPATH` -# contents. For all subsequent tasks, the _BUILD_CACHE_HANDLE value -# is used as a key to reuse this cache, saving both time and money. -# The only exceptions are tasks which only run inside a container, they -# will not have access the cache and therefore must rely on cloning the -# repository. +# N/B: This task is critical. It builds all binaries for all supported +# OS platforms and versions. On success, the contents of the repository +# are preserved as an artifact. This saves most subsequent tasks about +# 3 minutes of otherwise duplicative effort. It also ensures that the +# exact same binaries used throughout CI testing, are available for +# future consumption|inspection by the final 'artifacts' task. build_task: alias: 'build' name: 'Build for $DISTRO_NV' @@ -151,37 +153,27 @@ build_task: VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME} CTR_FQIN: ${FEDORA_CONTAINER_FQIN} # ID for re-use of build output - _BUILD_CACHE_HANDLE: ${FEDORA_NAME}-build-${CIRRUS_BUILD_ID} - env: &priorfedora_envvars DISTRO_NV: ${PRIOR_FEDORA_NAME} VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME} CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN} - _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID} - env: &ubuntu_envvars DISTRO_NV: ${UBUNTU_NAME} VM_IMAGE_NAME: ${UBUNTU_CACHE_IMAGE_NAME} CTR_FQIN: ${UBUNTU_CONTAINER_FQIN} - _BUILD_CACHE_HANDLE: ${UBUNTU_NAME}-build-${CIRRUS_BUILD_ID} env: TEST_FLAVOR: build - # Ref: https://cirrus-ci.org/guide/writing-tasks/#cache-instruction - gopath_cache: &gopath_cache - folder: *gopath # Required hard-coded path, no variables. - fingerprint_script: echo "$_BUILD_CACHE_HANDLE" - # Cheat: Clone here when cache is empty, guaranteeing consistency. - populate_script: *full_clone - # A normal clone would invalidate useful cache - clone_script: &noop mkdir -p $CIRRUS_WORKING_DIR + clone_script: *full_clone setup_script: *setup main_script: *main - always: &binary_artifacts - <<: *runner_stats - gosrc_artifacts: - path: ./* # Grab everything in top-level $GOSRC - type: application/octet-stream - binary_artifacts: - path: ./bin/* - type: application/octet-stream + # Cirrus-CI is very slow uploading one file at time, and the repo contains + # thousands of files. Speed this up by archiving into tarball first. + repo_prep_script: &repo_prep >- + tar cjf /tmp/repo.tbz -C $GOSRC . && mv /tmp/repo.tbz $GOSRC/ + repo_artifacts: &repo_artifacts + path: ./repo.tbz + type: application/octet-stream + always: *runner_stats # Confirm the result of building on at least one platform appears sane. @@ -208,10 +200,12 @@ validate_task: env: <<: *stdenvars TEST_FLAVOR: validate - gopath_cache: &ro_gopath_cache - <<: *gopath_cache - reupload_on_changes: false - clone_script: *noop + # N/B: This script depends on ${DISTRO_NV} being defined for the task. + clone_script: &get_gosrc | + cd /tmp + echo "$ARTCURL/Build%20for%20${DISTRO_NV}/repo/repo.tbz" + time $ARTCURL/Build%20for%20${DISTRO_NV}/repo/repo.tbz + time tar xjf /tmp/repo.tbz -C $GOSRC setup_script: *setup main_script: *main always: *runner_stats @@ -231,8 +225,7 @@ bindings_task: env: <<: *stdenvars TEST_FLAVOR: bindings - gopath_cache: *ro_gopath_cache - clone_script: *noop # Comes from cache + clone_script: *get_gosrc setup_script: *setup main_script: *main always: &logs_artifacts @@ -260,19 +253,18 @@ swagger_task: env: <<: *stdenvars TEST_FLAVOR: swagger - # TODO: Due to podman 3.0 activity (including new images), avoid - # disturbing the status-quo just to incorporate this one new - # container image. Uncomment line below when CI activities normalize. - #CTR_FQIN: 'quay.io/libpod/gcsupld:${IMAGE_SUFFIX}' - CTR_FQIN: 'quay.io/libpod/gcsupld:c4813063494828032' + CTR_FQIN: 'quay.io/libpod/gcsupld:${IMAGE_SUFFIX}' GCPJSON: ENCRYPTED[927dc01e755eaddb4242b0845cf86c9098d1e3dffac38c70aefb1487fd8b4fe6dd6ae627b3bffafaba70e2c63172664e] GCPNAME: ENCRYPTED[c145e9c16b6fb88d476944a454bf4c1ccc84bb4ecaca73bdd28bdacef0dfa7959ebc8171a27b2e4064d66093b2cdba49] GCPPROJECT: 'libpod-218412' - gopath_cache: *ro_gopath_cache - clone_script: *noop # Comes from cache + clone_script: *get_gosrc setup_script: *setup main_script: *main - always: *binary_artifacts + always: + <<: *runner_stats + swagger_artifacts: + path: ./swagger.yaml + type: text/plain # Check that all included go modules from other sources match @@ -291,7 +283,7 @@ consistency_task: TEST_FLAVOR: consistency TEST_ENVIRON: container CTR_FQIN: ${FEDORA_CONTAINER_FQIN} - clone_script: *full_clone # build-cache not available to container tasks + clone_script: *get_gosrc setup_script: *setup main_script: *main always: *runner_stats @@ -322,11 +314,14 @@ alt_build_task: ALT_NAME: 'Test build RPM' - env: ALT_NAME: 'Alt Arch. Cross' - gopath_cache: *ro_gopath_cache - clone_script: *noop # Comes from cache + # This task cannot make use of the shared repo.tbz artifact. + clone_script: *full_clone setup_script: *setup main_script: *main - always: *binary_artifacts + # Produce a new repo.tbz artifact for consumption by 'artifacts' task. + repo_prep_script: *repo_prep + repo_artifacts: *repo_artifacts + always: *runner_stats # Confirm building the remote client, natively on a Mac OS-X VM. @@ -348,10 +343,14 @@ osx_alt_build_task: - brew install go-md2man - go version build_amd64_script: - - make podman-remote-release-darwin_amd64.zip + - make podman-remote-release-darwin_amd64.zip GOARCH=amd64 build_arm64_script: - make podman-remote-release-darwin_arm64.zip GOARCH=arm64 - always: *binary_artifacts + # This task cannot make use of the shared repo.tbz artifact and must + # produce a new repo.tbz artifact for consumption by 'artifacts' task. + repo_prep_script: *repo_prep + repo_artifacts: *repo_artifacts + always: *runner_stats # Verify podman is compatible with the docker python-module. @@ -367,8 +366,7 @@ docker-py_test_task: <<: *stdenvars TEST_FLAVOR: docker-py TEST_ENVIRON: container - gopath_cache: *ro_gopath_cache - clone_script: *noop # Comes from cache + clone_script: *get_gosrc setup_script: *setup main_script: *main always: *runner_stats @@ -395,8 +393,7 @@ unit_test_task: gce_instance: *standardvm env: TEST_FLAVOR: unit - clone_script: *noop # Comes from cache - gopath_cache: *ro_gopath_cache + clone_script: *get_gosrc setup_script: *setup main_script: *main always: *logs_artifacts @@ -416,8 +413,7 @@ apiv2_test_task: env: <<: *stdenvars TEST_FLAVOR: apiv2 - clone_script: *noop # Comes from cache - gopath_cache: *ro_gopath_cache + clone_script: *get_gosrc setup_script: *setup main_script: *main always: *logs_artifacts @@ -431,8 +427,6 @@ compose_test_task: depends_on: - validate gce_instance: *standardvm - env: - <<: *stdenvars matrix: - env: TEST_FLAVOR: compose @@ -446,8 +440,9 @@ compose_test_task: - env: TEST_FLAVOR: compose_v2 PRIV_NAME: rootless - clone_script: *noop # Comes from cache - gopath_cache: *ro_gopath_cache + env: + <<: *stdenvars + clone_script: *get_gosrc setup_script: *setup main_script: *main always: *logs_artifacts @@ -469,8 +464,7 @@ local_integration_test_task: &local_integration_test_task timeout_in: 90m env: TEST_FLAVOR: int - clone_script: *noop # Comes from cache - gopath_cache: *ro_gopath_cache + clone_script: *get_gosrc setup_script: *setup main_script: *main always: &int_logs_artifacts @@ -516,8 +510,7 @@ container_integration_test_task: env: TEST_FLAVOR: int TEST_ENVIRON: container - clone_script: *noop # Comes from cache - gopath_cache: *ro_gopath_cache + clone_script: *get_gosrc setup_script: *setup main_script: *main always: *int_logs_artifacts @@ -537,8 +530,7 @@ rootless_integration_test_task: env: TEST_FLAVOR: int PRIV_NAME: rootless - clone_script: *noop # Comes from cache - gopath_cache: *ro_gopath_cache + clone_script: *get_gosrc setup_script: *setup main_script: *main always: *int_logs_artifacts @@ -559,8 +551,7 @@ local_system_test_task: &local_system_test_task gce_instance: *standardvm env: TEST_FLAVOR: sys - clone_script: *noop # Comes from cache - gopath_cache: *ro_gopath_cache + clone_script: *get_gosrc setup_script: *setup main_script: *main always: *logs_artifacts @@ -619,8 +610,7 @@ buildah_bud_test_task: PODBIN_NAME: remote gce_instance: *standardvm timeout_in: 45m - clone_script: *noop - gopath_cache: *ro_gopath_cache + clone_script: *get_gosrc setup_script: *setup main_script: *main always: *int_logs_artifacts @@ -638,8 +628,7 @@ rootless_system_test_task: env: TEST_FLAVOR: sys PRIV_NAME: rootless - clone_script: *noop # Comes from cache - gopath_cache: *ro_gopath_cache + clone_script: *get_gosrc setup_script: *setup main_script: *main always: *logs_artifacts @@ -661,8 +650,7 @@ rootless_gitlab_test_task: <<: *ubuntu_envvars TEST_FLAVOR: 'gitlab' PRIV_NAME: rootless - clone_script: *noop # Comes from cache - gopath_cache: *ro_gopath_cache + clone_script: *get_gosrc setup_script: *setup main_script: *main always: @@ -694,8 +682,7 @@ upgrade_test_task: VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME} # ID for re-use of build output _BUILD_CACHE_HANDLE: ${FEDORA_NAME}-build-${CIRRUS_BUILD_ID} - clone_script: *noop - gopath_cache: *ro_gopath_cache + clone_script: *get_gosrc setup_script: *setup main_script: *main always: *logs_artifacts @@ -715,11 +702,6 @@ image_build_task: &image-build image_name: build-push-${IMAGE_SUFFIX} # More muscle required for parallel multi-arch build type: "n2-standard-4" - env: - PODMAN_USERNAME: ENCRYPTED[b9f0f2550029dd2196e086d9dd6c2d1fec7e328630b15990d9bb610f9fcccb5baab8b64a8c3e72b0c1d0f5917cf65aa1] - PODMAN_PASSWORD: ENCRYPTED[e3444f6072853f0c8db7f964ead5e2204116af485469fa0de367f26b9316b460fd842a9882f552b9e9a83bbaf650d8b4] - CONTAINERS_USERNAME: ENCRYPTED[54a372d5f22f424173c114c6fb25c3214956cad323d5b285c7393a71041884ce96471d0ff733774e5dab9fa5a3c8795c] - CONTAINERS_PASSWORD: ENCRYPTED[4ecc3fb534935095a99fb1f2e320ac6bc87f3e7e186746e41cbcc4b5f5379a014b9fc8cc90e1f3d5abdbaf31580a4ab9] matrix: - env: CTXDIR: contrib/podmanimage/upstream @@ -729,6 +711,12 @@ image_build_task: &image-build CTXDIR: contrib/podmanimage/stable - env: CTXDIR: contrib/hello + env: + PODMAN_USERNAME: ENCRYPTED[b9f0f2550029dd2196e086d9dd6c2d1fec7e328630b15990d9bb610f9fcccb5baab8b64a8c3e72b0c1d0f5917cf65aa1] + PODMAN_PASSWORD: ENCRYPTED[e3444f6072853f0c8db7f964ead5e2204116af485469fa0de367f26b9316b460fd842a9882f552b9e9a83bbaf650d8b4] + CONTAINERS_USERNAME: ENCRYPTED[54a372d5f22f424173c114c6fb25c3214956cad323d5b285c7393a71041884ce96471d0ff733774e5dab9fa5a3c8795c] + CONTAINERS_PASSWORD: ENCRYPTED[4ecc3fb534935095a99fb1f2e320ac6bc87f3e7e186746e41cbcc4b5f5379a014b9fc8cc90e1f3d5abdbaf31580a4ab9] + clone_script: &noop mkdir -p $CIRRUS_WORKING_DIR script: - set -a; source /etc/automation_environment; set +a - main.sh $CIRRUS_REPO_CLONE_URL $CTXDIR @@ -828,42 +816,41 @@ artifacts_task: env: CTR_FQIN: ${FEDORA_CONTAINER_FQIN} TEST_ENVIRON: container - CURL: "curl --fail --location -O https://api.cirrus-ci.com/v1/artifact/build/${CIRRUS_BUILD_ID}" # In order to keep the download URL and Cirrus-CI artifact.zip contents # simple, nothing should exist in $CIRRUS_WORKING_DIR except for artifacts. clone_script: *noop - script: - # Assume the latest Fedora release build is most useful - - $CURL/Build%20for%20$FEDORA_NAME/binary/bin/podman - - $CURL/Build%20for%20$FEDORA_NAME/binary/bin/podman-remote - - $CURL/Build%20for%20$FEDORA_NAME/binary/bin/rootlessport - - chmod +x podman* rootlessport - # Architecture in filename & can't use wildcards in a URL + fedora_binaries_script: + - mkdir -p /tmp/fed + - cd /tmp/fed + - $ARTCURL/Build%20for%20${FEDORA_NAME}/repo/repo.tbz + - tar xjf repo.tbz + - cp ./bin/* $CIRRUS_WORKING_DIR/ + alt_binaries_script: - mkdir -p /tmp/alt - cd /tmp/alt - - $CURL/Alt%20Arch.%20Cross/gosrc.zip - - unzip gosrc.zip - - cd $CIRRUS_WORKING_DIR - - mv /tmp/alt/*.tar.gz ./ - # Windows MSI filename has version number + - $ARTCURL/Alt%20Arch.%20Cross/repo/repo.tbz + - tar xjf repo.tbz + - mv ./*.tar.gz $CIRRUS_WORKING_DIR/ + win_binaries_script: - mkdir -p /tmp/win - cd /tmp/win - - $CURL/Windows%20Cross/gosrc.zip - - unzip gosrc.zip - - cd $CIRRUS_WORKING_DIR - - mv /tmp/win/podman-remote*.zip /tmp/win/*.msi ./ - # OSX - - $CURL/OSX%20Cross/gosrc/podman-remote-release-darwin_amd64.zip - - $CURL/OSX%20Cross/gosrc/podman-remote-release-darwin_arm64.zip - # Always show contents to assist in debugging + - $ARTCURL/Windows%20Cross/repo/repo.tbz + - tar xjf repo.tbz + - mv ./podman-remote*.zip ./*.msi $CIRRUS_WORKING_DIR/ + osx_binaries_script: + - mkdir -p /tmp/osx + - cd /tmp/osx + - $ARTCURL/OSX%20Cross/repo/repo.tbz + - tar xjf repo.tbz + - mv ./podman-remote-release-darwin_*.zip $CIRRUS_WORKING_DIR/ always: - contents_script: ls -1 $CIRRUS_WORKING_DIR - # Produce downloadable files and an automatic zip-file accessible - # by a consistent URL, based on contents of $CIRRUS_WORKING_DIR - # Ref: https://cirrus-ci.org/guide/writing-tasks/#latest-build-artifacts - binary_artifacts: - path: ./* - type: application/octet-stream + contents_script: ls -la $CIRRUS_WORKING_DIR + # Produce downloadable files and an automatic zip-file accessible + # by a consistent URL, based on contents of $CIRRUS_WORKING_DIR + # Ref: https://cirrus-ci.org/guide/writing-tasks/#latest-build-artifacts + binary_artifacts: + path: ./* + type: application/octet-stream # When a new tag is pushed, confirm that the code and commits @@ -878,11 +865,9 @@ release_task: env: <<: *stdenvars TEST_FLAVOR: release - gopath_cache: *ro_gopath_cache - clone_script: *noop # Comes from cache + clone_script: *get_gosrc setup_script: *setup main_script: *main - always: *binary_artifacts # When preparing to release a new version, this task may be manually @@ -905,8 +890,6 @@ release_test_task: env: <<: *stdenvars TEST_FLAVOR: release - gopath_cache: *ro_gopath_cache - clone_script: *noop # Comes from cache + clone_script: *get_gosrc setup_script: *setup main_script: *main - always: *binary_artifacts diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3416a93ee..ca023d18a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,3 +17,4 @@ repos: - id: check-byte-order-marker - id: check-executables-have-shebangs - id: check-merge-conflict + - id: check-yaml @@ -134,7 +134,8 @@ ifeq ($(GOBIN),) GOBIN := $(FIRST_GOPATH)/bin endif -export PATH := $(PATH):$(GOBIN):$(CURDIR)/hack +# This must never include the 'hack' directory +export PATH := $(PATH):$(GOBIN) GOMD2MAN ?= $(shell command -v go-md2man || echo './test/tools/build/go-md2man') @@ -568,7 +569,7 @@ remoteintegration: test-binaries ginkgo-remote .PHONY: localbenchmarks localbenchmarks: test-binaries - ACK_GINKGO_RC=true $(GOBIN)/ginkgo \ + PATH=$(PATH):$(shell PWD)/hack ACK_GINKGO_RC=true $(GOBIN)/ginkgo \ -focus "Podman Benchmark Suite" \ -tags "$(BUILDTAGS) benchmarks" -noColor \ -noisySkippings=false -noisyPendings=false \ diff --git a/cmd/podman/machine/list.go b/cmd/podman/machine/list.go index ef26b7886..5254d50cf 100644 --- a/cmd/podman/machine/list.go +++ b/cmd/podman/machine/list.go @@ -43,7 +43,7 @@ type listFlagType struct { quiet bool } -type machineReporter struct { +type ListReporter struct { Name string Default bool Created string @@ -68,7 +68,7 @@ func init() { flags := lsCmd.Flags() formatFlagName := "format" flags.StringVar(&listFlag.format, formatFlagName, "{{.Name}}\t{{.VMType}}\t{{.Created}}\t{{.LastUp}}\t{{.CPUs}}\t{{.Memory}}\t{{.DiskSize}}\n", "Format volume output using JSON or a Go template") - _ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&machineReporter{})) + _ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&ListReporter{})) flags.BoolVar(&listFlag.noHeading, "noheading", false, "Do not print headers") flags.BoolVarP(&listFlag.quiet, "quiet", "q", false, "Show only machine names") } @@ -121,8 +121,8 @@ func list(cmd *cobra.Command, args []string) error { return outputTemplate(cmd, machineReporter) } -func outputTemplate(cmd *cobra.Command, responses []*machineReporter) error { - headers := report.Headers(machineReporter{}, map[string]string{ +func outputTemplate(cmd *cobra.Command, responses []*ListReporter) error { + headers := report.Headers(ListReporter{}, map[string]string{ "LastUp": "LAST UP", "VmType": "VM TYPE", "CPUs": "CPUS", @@ -181,15 +181,15 @@ func streamName(imageStream string) string { return imageStream } -func toMachineFormat(vms []*machine.ListResponse) ([]*machineReporter, error) { +func toMachineFormat(vms []*machine.ListResponse) ([]*ListReporter, error) { cfg, err := config.ReadCustomConfig() if err != nil { return nil, err } - machineResponses := make([]*machineReporter, 0, len(vms)) + machineResponses := make([]*ListReporter, 0, len(vms)) for _, vm := range vms { - response := new(machineReporter) + response := new(ListReporter) response.Default = vm.Name == cfg.Engine.ActiveService response.Name = vm.Name response.Running = vm.Running @@ -209,15 +209,15 @@ func toMachineFormat(vms []*machine.ListResponse) ([]*machineReporter, error) { return machineResponses, nil } -func toHumanFormat(vms []*machine.ListResponse) ([]*machineReporter, error) { +func toHumanFormat(vms []*machine.ListResponse) ([]*ListReporter, error) { cfg, err := config.ReadCustomConfig() if err != nil { return nil, err } - humanResponses := make([]*machineReporter, 0, len(vms)) + humanResponses := make([]*ListReporter, 0, len(vms)) for _, vm := range vms { - response := new(machineReporter) + response := new(ListReporter) if vm.Name == cfg.Engine.ActiveService { response.Name = vm.Name + "*" response.Default = true diff --git a/cmd/podman/play/kube.go b/cmd/podman/play/kube.go index 3be7396ce..5fe059139 100644 --- a/cmd/podman/play/kube.go +++ b/cmd/podman/play/kube.go @@ -98,6 +98,12 @@ func init() { ) _ = kubeCmd.RegisterFlagCompletionFunc(logOptFlagName, common.AutocompleteLogOpt) + usernsFlagName := "userns" + flags.StringVar(&kubeOptions.Userns, usernsFlagName, os.Getenv("PODMAN_USERNS"), + "User namespace to use", + ) + _ = kubeCmd.RegisterFlagCompletionFunc(usernsFlagName, common.AutocompleteUserNamespace) + flags.BoolVar(&kubeOptions.NoHosts, "no-hosts", false, "Do not create /etc/hosts within the pod's containers, instead use the version from the image") flags.BoolVarP(&kubeOptions.Quiet, "quiet", "q", false, "Suppress output information when pulling images") flags.BoolVar(&kubeOptions.TLSVerifyCLI, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index 46b245a45..5d3e43c50 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -36,11 +36,6 @@ fi # Managed by setup_environment.sh; holds task-specific definitions. if [[ -r "/etc/ci_environment" ]]; then source /etc/ci_environment; fi -OS_RELEASE_ID="$(source /etc/os-release; echo $ID)" -# GCE image-name compatible string representation of distribution _major_ version -OS_RELEASE_VER="$(source /etc/os-release; echo $VERSION_ID | tr -d '.')" -# Combined to ease some usage -OS_REL_VER="${OS_RELEASE_ID}-${OS_RELEASE_VER}" # This is normally set from .cirrus.yml but default is necessary when # running under hack/get_ci_vm.sh since it cannot infer the value. DISTRO_NV="${DISTRO_NV:-$OS_REL_VER}" @@ -96,7 +91,7 @@ EPOCH_TEST_COMMIT="$CIRRUS_BASE_SHA" # testing operations on all platforms and versions. This is necessary # to avoid needlessly passing through global/system values across # contexts, such as host->container or root->rootless user -PASSTHROUGH_ENV_RE='(^CI.*)|(^CIRRUS)|(^DISTRO_NV)|(^GOPATH)|(^GOCACHE)|(^GOSRC)|(^SCRIPT_BASE)|(CGROUP_MANAGER)|(OCI_RUNTIME)|(^TEST.*)|(^PODBIN_NAME)|(^PRIV_NAME)|(^ALT_NAME)|(^ROOTLESS_USER)|(SKIP_USERNS)|(.*_NAME)|(.*_FQIN)|(NETWORK_BACKEND)' +PASSTHROUGH_ENV_RE='(^CI.*)|(^CIRRUS)|(^DISTRO_NV)|(^GOPATH)|(^GOCACHE)|(^GOSRC)|(^SCRIPT_BASE)|(CGROUP_MANAGER)|(OCI_RUNTIME)|(^TEST.*)|(^PODBIN_NAME)|(^PRIV_NAME)|(^ALT_NAME)|(^ROOTLESS_USER)|(SKIP_USERNS)|(.*_NAME)|(.*_FQIN)|(NETWORK_BACKEND)|(DEST_BRANCH)' # Unsafe env. vars for display SECRET_ENV_RE='(ACCOUNT)|(GC[EP]..+)|(SSH)|(PASSWORD)|(TOKEN)' @@ -182,30 +177,21 @@ setup_rootless() { cat $HOME/.ssh/*.pub /home/$ROOTLESS_USER/.ssh/*.pub >> $HOME/.ssh/authorized_keys cat $HOME/.ssh/*.pub /home/$ROOTLESS_USER/.ssh/*.pub >> /home/$ROOTLESS_USER/.ssh/authorized_keys - msg "Ensure the ssh daemon is up and running within 5 minutes" - systemctl start sshd - lilto systemctl is-active sshd - msg "Configure ssh file permissions" chmod -R 700 "$HOME/.ssh" chmod -R 700 "/home/$ROOTLESS_USER/.ssh" chown -R $ROOTLESS_USER:$ROOTLESS_USER "/home/$ROOTLESS_USER/.ssh" + # N/B: We're clobbering the known_hosts here on purpose. There should + # never be any non-localhost connections made from tests (using strict-mode). + # If there are, it's either a security problem or a broken test, both of which + # we want to lead to test failures. msg " setup known_hosts for $USER" - ssh -q root@localhost \ - -o UserKnownHostsFile=/root/.ssh/known_hosts \ - -o UpdateHostKeys=yes \ - -o StrictHostKeyChecking=no \ - -o CheckHostIP=no \ - true - + ssh-keyscan localhost > /root/.ssh/known_hosts msg " setup known_hosts for $ROOTLESS_USER" - su $ROOTLESS_USER -c "ssh -q $ROOTLESS_USER@localhost \ - -o UserKnownHostsFile=/home/$ROOTLESS_USER/.ssh/known_hosts \ - -o UpdateHostKeys=yes \ - -o StrictHostKeyChecking=no \ - -o CheckHostIP=no \ - true" + # Maintain access-permission consistency with all other .ssh files. + install -Z -m 700 -o $ROOTLESS_USER -g $ROOTLESS_USER \ + /root/.ssh/known_hosts /home/$ROOTLESS_USER/.ssh/known_hosts } install_test_configs() { @@ -270,6 +256,8 @@ remove_packaged_podman_files() { done done + # OS_RELEASE_ID is defined by automation-library + # shellcheck disable=SC2154 if [[ "$OS_RELEASE_ID" =~ "ubuntu" ]] then LISTING_CMD="dpkg-query -L podman" diff --git a/contrib/cirrus/pr-should-include-tests b/contrib/cirrus/pr-should-include-tests index 0d39047a6..57ca39d9b 100755 --- a/contrib/cirrus/pr-should-include-tests +++ b/contrib/cirrus/pr-should-include-tests @@ -30,19 +30,20 @@ fi # Nothing changed under test subdirectory. # # This is OK if the only files being touched are "safe" ones. -filtered_changes=$(git diff --name-only $base $head | - fgrep -vx .cirrus.yml | - fgrep -vx .gitignore | - fgrep -vx Makefile | - fgrep -vx go.mod | - fgrep -vx go.sum | - egrep -v '^[^/]+\.md$' | - egrep -v '^.github' | - egrep -v '^contrib/' | - egrep -v '^docs/' | - egrep -v '^hack/' | - egrep -v '^nix/' | - egrep -v '^vendor/' | +filtered_changes=$(git diff --name-only $base $head | + fgrep -vx .cirrus.yml | + fgrep -vx .pre-commit-config.yaml | + fgrep -vx .gitignore | + fgrep -vx Makefile | + fgrep -vx go.mod | + fgrep -vx go.sum | + egrep -v '^[^/]+\.md$' | + egrep -v '^.github' | + egrep -v '^contrib/' | + egrep -v '^docs/' | + egrep -v '^hack/' | + egrep -v '^nix/' | + egrep -v '^vendor/' | egrep -v '^version/') if [[ -z "$filtered_changes" ]]; then exit 0 diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh index c4a714691..83a81bd0a 100755 --- a/contrib/cirrus/runner.sh +++ b/contrib/cirrus/runner.sh @@ -246,20 +246,28 @@ function _run_altbuild() { # shellcheck disable=SC2154 msg "Performing alternate build: $ALT_NAME" msg "************************************************************" + set -x cd $GOSRC case "$ALT_NAME" in *Each*) git fetch origin - # The check-size script, introduced 2022-03-22 in #13518, + # The make-and-check-size script, introduced 2022-03-22 in #13518, # runs 'make' (the original purpose of this check) against # each commit, then checks image sizes to make sure that # none have grown beyond a given limit. That of course - # requires a baseline, which is why we use '^' to start - # with the *parent* commit of this PR, not the first commit. + # requires a baseline, so our first step is to build the + # branch point of the PR. + local context_dir savedhead pr_base context_dir=$(mktemp -d --tmpdir make-size-check.XXXXXXX) - make build-all-new-commits \ - GIT_BASE_BRANCH=origin/"${DEST_BRANCH}^" \ - MAKE="hack/make-and-check-size $context_dir" + savedhead=$(git rev-parse HEAD) + # Push to PR base. First run of the script will write size files + pr_base=$(git merge-base origin/$DEST_BRANCH HEAD) + git checkout $pr_base + hack/make-and-check-size $context_dir + # pop back to PR, and run incremental makes. Subsequent script + # invocations will compare against original size. + git checkout $savedhead + git rebase $pr_base -x "hack/make-and-check-size $context_dir" rm -rf $context_dir ;; *Windows*) diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index e3eb46783..f31cd6eeb 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -25,7 +25,7 @@ msg "************************************************************" show_env_vars req_env_vars USER HOME GOSRC SCRIPT_BASE TEST_FLAVOR TEST_ENVIRON \ - PODBIN_NAME PRIV_NAME DISTRO_NV + PODBIN_NAME PRIV_NAME DISTRO_NV DEST_BRANCH # Verify basic dependencies for depbin in go rsync unzip sha256sum curl make python3 git @@ -121,6 +121,9 @@ case "$OS_RELEASE_ID" in # CNI networking available. Upgrading from one to the other is # not supported at this time. Support execution of the upgrade # tests in F36 and later, by disabling Netavark and enabling CNI. + # + # OS_RELEASE_VER is defined by automation-library + # shellcheck disable=SC2154 if [[ "$OS_RELEASE_VER" -ge 36 ]] && \ [[ "$TEST_FLAVOR" != "upgrade_test" ]]; then @@ -217,6 +220,7 @@ case "$TEST_FLAVOR" in validate) dnf install -y $PACKAGE_DOWNLOAD_DIR/python3*.rpm # For some reason, this is also needed for validation + make install.tools make .install.pre-commit ;; automation) ;; @@ -226,10 +230,12 @@ case "$TEST_FLAVOR" in if [[ "$ALT_NAME" =~ RPM ]]; then bigto dnf install -y glibc-minimal-langpack go-rpm-macros rpkg rpm-build shadow-utils-subid-devel fi + make install.tools ;; docker-py) remove_packaged_podman_files - make && make install PREFIX=/usr ETCDIR=/etc + make install.tools + make install PREFIX=/usr ETCDIR=/etc msg "Installing previously downloaded/cached packages" dnf install -y $PACKAGE_DOWNLOAD_DIR/python3*.rpm @@ -239,13 +245,17 @@ case "$TEST_FLAVOR" in pip install --requirement $GOSRC/test/python/requirements.txt ;; build) make clean ;; - unit) ;; + unit) + make install.tools + ;; compose_v2) + make install.tools dnf -y remove docker-compose curl -SL https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose ;& # Continue with next item apiv2) + make install.tools msg "Installing previously downloaded/cached packages" dnf install -y $PACKAGE_DOWNLOAD_DIR/python3*.rpm virtualenv .venv/requests @@ -254,6 +264,7 @@ case "$TEST_FLAVOR" in pip install --requirement $GOSRC/test/apiv2/python/requirements.txt ;& # continue with next item compose) + make install.tools rpm -ivh $PACKAGE_DOWNLOAD_DIR/podman-docker* ;& # continue with next item int) ;& @@ -262,6 +273,7 @@ case "$TEST_FLAVOR" in bud) ;& bindings) ;& endpoint) + make install.tools # Use existing host bits when testing is to happen inside a container # since this script will run again in that environment. # shellcheck disable=SC2154 @@ -270,11 +282,11 @@ case "$TEST_FLAVOR" in die "Refusing to config. host-test in container"; fi remove_packaged_podman_files - make && make install PREFIX=/usr ETCDIR=/etc + make install PREFIX=/usr ETCDIR=/etc elif [[ "$TEST_ENVIRON" == "container" ]]; then if ((CONTAINER)); then remove_packaged_podman_files - make && make install PREFIX=/usr ETCDIR=/etc + make install PREFIX=/usr ETCDIR=/etc fi else die "Invalid value for \$TEST_ENVIRON=$TEST_ENVIRON" @@ -291,7 +303,7 @@ case "$TEST_FLAVOR" in # Ref: https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27270#note_499585550 remove_packaged_podman_files - make && make install PREFIX=/usr ETCDIR=/etc + make install PREFIX=/usr ETCDIR=/etc msg "Installing docker and containerd" # N/B: Tests check/expect `docker info` output, and this `!= podman info` @@ -324,7 +336,10 @@ case "$TEST_FLAVOR" in docker.io/gitlab/gitlab-runner-helper:x86_64-latest-pwsh ;; swagger) ;& # use next item - consistency) make clean ;; + consistency) + make clean + make install.tools + ;; release) ;; *) die_unknown TEST_FLAVOR esac diff --git a/docs/source/markdown/podman-auto-update.1.md b/docs/source/markdown/podman-auto-update.1.md index 755f46d70..992c87432 100644 --- a/docs/source/markdown/podman-auto-update.1.md +++ b/docs/source/markdown/podman-auto-update.1.md @@ -51,15 +51,6 @@ The `UPDATED` field indicates the availability of a new image with "pending". Change the default output format. This can be of a supported type like 'json' or a Go template. Valid placeholders for the Go template are listed below: -#### **--rollback** - -If restarting a systemd unit after updating the image has failed, rollback to using the previous image and restart the unit another time. Default is true. - -Please note that detecting if a systemd unit has failed is best done by the container sending the READY message via SDNOTIFY. This way, restarting the unit will wait until having received the message or a timeout kicked in. Without that, restarting the systemd unit may succeed even if the container has failed shortly after. - -For a container to send the READY message via SDNOTIFY it must be created with the `--sdnotify=container` option (see podman-run(1)). The application running inside the container can then execute `systemd-notify --ready` when ready or use the sdnotify bindings of the specific programming language (e.g., sd_notify(3)). - - | **Placeholder** | **Description** | | --------------- | -------------------------------------- | | .Unit | Name of the systemd unit | @@ -70,6 +61,14 @@ For a container to send the READY message via SDNOTIFY it must be created with t | .Policy | Auto-update policy of the container | | .Updated | Update status: true,false,failed | +#### **--rollback** + +If restarting a systemd unit after updating the image has failed, rollback to using the previous image and restart the unit another time. Default is true. + +Please note that detecting if a systemd unit has failed is best done by the container sending the READY message via SDNOTIFY. This way, restarting the unit will wait until having received the message or a timeout kicked in. Without that, restarting the systemd unit may succeed even if the container has failed shortly after. + +For a container to send the READY message via SDNOTIFY it must be created with the `--sdnotify=container` option (see podman-run(1)). The application running inside the container can then execute `systemd-notify --ready` when ready or use the sdnotify bindings of the specific programming language (e.g., sd_notify(3)). + ## EXAMPLES Autoupdate with registry policy diff --git a/docs/source/markdown/podman-history.1.md b/docs/source/markdown/podman-history.1.md index 16f1e48e6..d114e0523 100644 --- a/docs/source/markdown/podman-history.1.md +++ b/docs/source/markdown/podman-history.1.md @@ -17,6 +17,12 @@ set, the time of creation and size are printed out in a human readable format. The **--quiet** flag displays the ID of the image only when set and the **--format** flag is used to print the information using the Go template provided by the user. +## OPTIONS + +#### **--format**=*format* + +Alter the output for a format like 'json' or a Go template. + Valid placeholders for the Go template are listed below: | **Placeholder** | **Description** | @@ -28,12 +34,7 @@ Valid placeholders for the Go template are listed below: | .CreatedSince | Elapsed time since the image layer was created | | .Size | Size of layer on disk | | .Comment | Comment for the layer | -## OPTIONS - -Print the numeric IDs only (default *false*). -#### **--format**=*format* - -Alter the output for a format like 'json' or a Go template. +| .Tags | Image tags | #### **--help**, **-h** @@ -49,6 +50,8 @@ Do not truncate the output (default *false*). #### **--quiet**, **-q** +Print the numeric IDs only (default *false*). + ## EXAMPLES ``` diff --git a/docs/source/markdown/podman-play-kube.1.md b/docs/source/markdown/podman-play-kube.1.md index 8ed71b734..5c4bdc8c4 100644 --- a/docs/source/markdown/podman-play-kube.1.md +++ b/docs/source/markdown/podman-play-kube.1.md @@ -243,6 +243,45 @@ 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. +#### **--userns**=*mode* + +Set the user namespace mode for the container. It defaults to the **PODMAN_USERNS** environment variable. An empty value ("") means user namespaces are disabled unless an explicit mapping is set with the **--uidmap** and **--gidmap** options. + +Rootless user --userns=Key mappings: + +Key | Host User | Container User +----------|---------------|--------------------- +"" |$UID |0 (Default User account mapped to root user in container.) +keep-id |$UID |$UID (Map user account to same UID within container.) +auto |$UID | nil (Host User UID is not mapped into container.) +nomap |$UID | nil (Host User UID is not mapped into container.) + +Valid _mode_ values are: + +**auto**[:_OPTIONS,..._]: automatically create a unique user namespace. + +The `--userns=auto` flag, requires that the user name `containers` and a range of subordinate user ids that the Podman container is allowed to use be specified in the /etc/subuid and /etc/subgid files. + +Example: `containers:2147483647:2147483648`. + +Podman allocates unique ranges of UIDs and GIDs from the `containers` subordinate user ids. The size of the ranges is based on the number of UIDs required in the image. The number of UIDs and GIDs can be overridden with the `size` option. The `auto` options currently does not work in rootless mode + + Valid `auto` options: + + - *gidmapping*=_CONTAINER_GID:HOST_GID:SIZE_: to force a GID mapping to be present in the user namespace. + - *size*=_SIZE_: to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will estimate a size for the user namespace. + - *uidmapping*=_CONTAINER_UID:HOST_UID:SIZE_: to force a UID mapping to be present in the user namespace. + +**container:**_id_: join the user namespace of the specified container. + +**host**: create a new namespace for the container. + +**keep-id**: creates a user namespace where the current rootless user's UID:GID are mapped to the same values in the container. This option is ignored for containers created by the root user. + +**nomap**: creates a user namespace where the current rootless user's UID:GID are not mapped into the container. This option is ignored for containers created by the root user. + +**ns:**_namespace_: run the pod in the given existing user namespace. + ## EXAMPLES Recreate the pod and containers as described in a file called `demo.yml` diff --git a/docs/source/markdown/podman-system-connection-list.1.md b/docs/source/markdown/podman-system-connection-list.1.md index cc457860a..23784a319 100644 --- a/docs/source/markdown/podman-system-connection-list.1.md +++ b/docs/source/markdown/podman-system-connection-list.1.md @@ -20,10 +20,10 @@ 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*] | -| *.Default* | Indicates whether connection is the default | +| .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*] | +| .Default | Indicates whether connection is the default | ## EXAMPLE ``` diff --git a/docs/tutorials/podman-for-windows.md b/docs/tutorials/podman-for-windows.md new file mode 100644 index 000000000..bb9674774 --- /dev/null +++ b/docs/tutorials/podman-for-windows.md @@ -0,0 +1,417 @@ + + +Podman for Windows +================== + +While "containers are Linux," Podman also runs on Mac and Windows, where it +provides a native CLI and embeds a guest Linux system to launch your +containers. This guest is referred to as a Podman machine and is managed with +the `podman machine` command. On Windows, each Podman machine is backed by a +virtualized Windows System for Linux (WSLv2) distribution. The podman command +can be run directly from your Windows PowerShell (or CMD) prompt, where it +remotely communicates with the podman service running in the WSL environment. +Alternatively, you can access Podman directly from the WSL instance if you +prefer a Linux prompt and Linux tooling. In addition to command-line access, +Podman also listens for Docker API clients, supporting direct usage of +Docker-based tools and programmatic access from your language of choice. + +Prerequisites +------------- + +Since Podman uses WSL, you need a recent release of Windows 10 or Windows 11. +On x64, WSL requires build 18362 or later, and 19041 or later is required for +arm64 systems. Internally, WSL uses virtualization, so your system must +support and have hardware virtualization enabled. If you are running Windows +on a VM, you must have a VM that supports nested virtualization. + +It is also recommended to install the modern "Windows Terminal," which +provides a superior user experience to the standard PowerShell and CMD +prompts, as well as a WSL prompt, should you want it. + +You can install it by searching the Windows Store or by running the following +`winget` command: + +`winget install Microsoft.WindowsTerminal` + + +Installing Podman +----------------- + +Installing the Windows Podman client begins by downloading the Podman Windows +installer. The Windows installer is built with each Podman release and can be +downloaded from the official + [Github release page](https://github.com/containers/podman/releases). The +Windows installer file is named podman-v.#.#.#.msi, where the # symbols +represent the version number of Podman. Be sure to download a 4.1 or later +release for the capabilities discussed in this guide. + + + +Once downloaded, simply run the MSI file, and relaunch a new terminal. After +this point, podman.exe will be present on your PATH, and you will be able to run +the `podman machine init` command to create your first machine. + +`PS C:\Users\User> podman machine init` + +Automatic WSL Installation +-------------------------- + +If WSL has not been installed on your system, the first machine init command +will prompt a dialog to begin an automated install. If accepted, this process +will install the necessary Windows components, restart the system, and after +login, relaunch the machine creation process in a terminal window. Be sure to +wait a minute or two for the relaunch to occur, as Windows has a delay before +executing startup items. Alternatively, you can decline automatic installation +and install WSL manually. However, this will require additional download and +setup time. + +Machine Init Process +-------------------- + +After WSL is installed, the init command will install a minimal installation +of Fedora, customizing it to run podman. + +``` +PS C:\Users\User> podman machine init +Extracting compressed file +Importing operating system into WSL (this may take 5+ minutes on a new WSL install)... +Installing packages (this will take a while)... +Complete! +Configuring system... +Generating public/private ed25519 key pair. +Your identification has been saved in podman-machine-default +Your public key has been saved in podman-machine-default.pub +The key fingerprint is: +SHA256:RGTGg2Q/LX7ijN+mzu8+BzcS3cEWP6Hir6pYllJtceA root@WINPC +Machine init complete +To start your machine run: + + podman machine start +``` + + +Starting Machine +---------------- + +After the machine init process completes, it can then be started and stopped +as desired: + +``` +PS C:\Users\User> podman machine start + +Starting machine "podman-machine-default" + +This machine is currently configured in rootless mode. If your containers +require root permissions (e.g. ports < 1024), or if you run into compatibility +issues with non-podman clients, you can switch using the following command: + + podman machine set --rootful + +API forwarding listening on: npipe:////./pipe/docker_engine + +Docker API clients default to this address. You do not need to set DOCKER_HOST. +Machine "podman-machine-default" started successfully +``` + +First Podman Command +-------------------- + +From this point on, podman commands operate similarly to how they would on +Linux. + +For a quick working example with a small image, you can run the Linux date +command on PowerShell. + +``` +PS C:\Users\User> podman run ubi8-micro date +Thu May 5 21:56:42 UTC 2022 +``` + +Port Forwarding +--------------- + +Port forwarding also works as expected; ports will be bound against localhost +(127.0.0.1). Note: When running as rootless (the default), you must use a port +greater than 1023. See the Rooftull and Rootless section for more details. + +To launch httpd, you can run: + +``` +PS C:\Users\User> podman run --rm -d -p 8080:80 --name httpd docker.io/library/httpd +f708641300564a6caf90c145e64cd852e76f77f6a41699478bb83a162dceada9 +``` + +A curl command against localhost on the PowerShell prompt will return a +successful HTTP response: + +``` +PS C:\Users\User> curl http://localhost:8080/ -UseBasicParsing + +StatusCode : 200 +StatusDescription : OK +Content : <html><body><h1>It works!</h1></body></html> +``` + +As with Linux, to stop, run: + +`podman stop httpd` + + +Using API Forwarding +-------------------- + +API forwarding allows Docker API tools and clients to use podman as if it was +Docker. Provided there is no other service listening on the Docker API pipe; +no special settings will be required. + +``` +PS C:\Users\User> .\docker.exe run -it fedora echo "Hello Podman!" +Hello Podman! +``` + +Otherwise, after starting the machine, you will be notified of an environment +variable you can set for tools to point to podman. Alternatively, you can shut +down both the conflicting service and podman, then finally run `podman machine +start` to restart, which should grab the Docker API address. + + +``` +Another process was listening on the default Docker API pipe address. +You can still connect Docker API clients by setting DOCKER HOST using the +following PowerShell command in your terminal session: + + $Env:DOCKER_HOST = 'npipe:////./pipe/podman-machine-default' + +Or in a classic CMD prompt: + + set DOCKER_HOST = 'npipe:////./pipe/podman-machine-default' + +Alternatively, terminate the other process and restart podman machine. +Machine "podman-machine-default" started successfully + +PS C:\Users\User> $Env:DOCKER_HOST = 'npipe:////./pipe/podman-machine-default' +PS C:\Users\User>.\docker.exe version --format '{{(index .Server.Components 0).Name}}' +Podman Engine +``` + +Rootfull & Rootless +------------------- + +On the embedded WSL Linux distro, podman can either be run under the root user +(rootful) or a non-privileged user (rootless). For behavioral consistency with +Podman on Linux, rootless is the default. Note: Rootfull and Rootless +containers are distinct and isolated from one another. Podman commands against +one (e.g., podman ps) will not represent results/state for the other. + +While most containers run fine in a rootless setting, you may find a case +where the container only functions with root privileges. If this is the case, +you can switch the machine to rootful by stopping it and using the set +command: + +``` +podman machine stop +podman machine set --rootful +``` + +To restore rootless execution, set rootful to false: + +``` +Podman machine stop +Podman machine set --rootful=false +``` + +Another case in which you may wish to use rootful execution is binding a port +less than 1024. However, future versions of podman will likely drop this to a +lower number to improve compatibility with defaults on system port services (such +as MySQL) + +Volume Mounting +--------------- + +New in Podman v4.1 is the ability to perform volume mounts from Windows paths into a +Linux container. This supports several notation schemes, including: + +Windows Style Paths: + +`podman run -it c:\Users\User\myfolder:/myfolder ubi8-micro ls /myfolder` + +Unixy Windows Paths: + +`podman run -it /c/Users/User/myfolder:/myfolder ubi8-micro ls /myfolder` + +Linux paths local to the WSL filesystem: + +`podman run -it /var/myfolder:/myfolder ubi-micro ls /myfolder` + +All of the above conventions work, whether running on a Windows prompt or the +WSL Linux shell. Although when using Windows paths on Linux, appropriately quote +or escape the Windows path portion of the argument. + + +Listing Podman Machine(s) +------------------------- + +To list the available podman machine instances and their current resource +usage, use the `podman machine ls` command: + +``` +PS C:\Users\User> podman machine ls + + +NAME VM TYPE CREATED LAST UP CPUS MEMORY DISK SIZE +podman-machine-default wsl 2 hours ago Currently running 4 331.1MB 768MB +``` + +Since WSL shares the same virtual machine and Linux kernel across multiple +distributions, the CPU and Memory values represent the total resources shared +across running systems. The opposite applies to the Disk value. It is +independent and represents the amount of storage for each individual +distribution. + + +Accessing the Podman Linux Environment +-------------------------------------- + +While using the podman.exe client on the Windows environment provides a +seamless native experience supporting the usage of local desktop tools and +APIs, there are a few scenarios in which you may wish to access the Linux +environment: + ++ Updating to the latest stable packages on the embedded Fedora instance ++ Using Linux development tools directly ++ Using a workflow that relies on EXT4 filesystem performance or behavior + semantics + +There are three mechanisms to access the embedded WSL distribution: +1. SSH using `podman machine ssh` +2. WSL command on the Windows PowerShell prompt +3. Windows Terminal Integration + +### Using SSH + +SSH access provides a similar experience as Podman on Mac. It immediately +drops you into the appropriate user based on your machine's rootful/rootless +configuration (root in the former, 'user' in the latter). The --username +option can be used to override with a specific user. + +An example task using SSH is updating your Linux environment to pull down the +latest OS bugfixes: + +`podman machine ssh sudo dnf upgrade -y` + +### Using the WSL Command + +The `wsl` command provides direct access to the Linux system but enters the +shell as root first. This is due to design limitations of WSL, where running +systemd (Linux's system services) requires the usage of a privileged process +namespace. + +Unless you have no other distributions of WSL installed, it's recommended to +use the `-d` option with the name of your podman machine (podman-machine-default +is the default) + +``` +PS C:\Users\User> wsl -d podman-machine-default +``` + +You will be automatically entered into a nested process namespace where +systemd is running. If you need to access the parent namespace, hit `ctrl-d` +or type exit. This also means to log out, you need to exit twice. + +``` +[root@WINPC /]# podman --version +podman version 4.1.0 +``` + + +To access commands as the non-privileged user (rootless podman), you must +first type `su user`. Alternatively, you can prefix the `wsl` command to use the +special `enterns`: + +``` +wsl -d podman-machine-default enterns su user +[user@WINPC /]$ id +uid=1000(user) gid=1000(user) groups=1000(user),10(wheel) +``` + +Likewise, running commands as root without entering a prompt should also be +prefixed with `enterns`. + +`wsl -d podman-machine-default enterns systemctl status` + +Accessing the WSL instance as a specific user using `wsl -u` or using inline +commands without `enterns` is not recommended since commands will execute +against the incorrect namespace. + +### Using Windows Terminal Integration + +Entering WSL as root is a 2-click operation. Simply click the drop-down tag, +and pick 'podman-machine-default,' where you will be entered directly as root. + + + +As before, to switch to a non-privileged user for rootless podman commands, +type `su user`. + +``` +[root@WINPC /]# su user +[user@WINPC /]$ podman info --format '{{.Store.RunRoot}}' +/run/user/1000/containers +``` + +Stopping a Podman Machine +------------------------- + +To stop a running podman machine, use the `podman machine stop` command: + +``` +PS C:\Users\User> podman machine stop +Machine "podman-machine-default" stopped successfully +``` + +Removing a Podman Machine +------------------------- + +To remove a machine, use the `podman machine rm` command: + +``` +PS C:\Users\User> podman machine rm + +The following files will be deleted: + +C:\Users\User\.ssh\podman-machine-default +C:\Users\User\.ssh\podman-machine-default.pub +C:\Users\User\.local\share\containers\podman\machine\wsl\podman-machine-default_fedora-35-x86_64.tar +C:\Users\User\.config\containers\podman\machine\wsl\podman-machine-default.json +C:\Users\User\.local\share\containers\podman\machine\wsl\wsldist\podman-machine-default + + +Are you sure you want to continue? [y/N] y +``` + + + +Troubleshooting +--------------- + +Recovering from a failed auto-installation of WSL + +If auto-install fails and retrying is unsuccessful, you can attempt to reset +your WSL system state and perform a manual WSL installation using the `wsl +--install command`. To do so, perform the following steps: + +1. Launch PowerShell as administrator + ``` + Start-Process powershell -Verb RunAs + ``` +2. Disable WSL Features + ``` + dism.exe /online /disable-feature /featurename:Microsoft-Windows-Subsystem-Linux /norestart + dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /norestart + ``` +3. Reboot +4. Run manual WSL install + ``` + wsl --install + ``` +5. Continue with podman machine init diff --git a/docs/tutorials/podman-win-install.jpg b/docs/tutorials/podman-win-install.jpg Binary files differnew file mode 100644 index 000000000..cf1b3ca86 --- /dev/null +++ b/docs/tutorials/podman-win-install.jpg diff --git a/docs/tutorials/podman-wsl-term.jpg b/docs/tutorials/podman-wsl-term.jpg Binary files differnew file mode 100644 index 000000000..a01bea84e --- /dev/null +++ b/docs/tutorials/podman-wsl-term.jpg @@ -14,10 +14,10 @@ require ( github.com/containers/buildah v1.26.1 github.com/containers/common v0.48.0 github.com/containers/conmon v2.0.20+incompatible - github.com/containers/image/v5 v5.21.1 + github.com/containers/image/v5 v5.21.2-0.20220511203756-fe4fd4ed8be4 github.com/containers/ocicrypt v1.1.4-0.20220428134531-566b808bdf6f github.com/containers/psgo v1.7.2 - github.com/containers/storage v1.40.2 + github.com/containers/storage v1.41.1-0.20220511210719-cacc3325a9c8 github.com/coreos/go-systemd/v22 v22.3.2 github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3 github.com/cyphar/filepath-securejoin v0.2.3 @@ -343,8 +343,9 @@ github.com/containers/common v0.48.0 h1:997nnXBZ+eNpfSM7L4SxhhZubQrfEyw3jRyNMTSs github.com/containers/common v0.48.0/go.mod h1:zPLZCfLXfnd1jI0QRsD4By54fP4k1+ifQs+tulIe3o0= 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.21.1 h1:Cr3zw2f0FZs4SCkdGlc8SN/mpcmg2AKG4OUuDbeGS/Q= github.com/containers/image/v5 v5.21.1/go.mod h1:zl35egpcDQa79IEXIuoUe1bW+D1pdxRxYjNlyb3YiXw= +github.com/containers/image/v5 v5.21.2-0.20220511203756-fe4fd4ed8be4 h1:9yDGjKniCxCIVJwdiUHGTjguGJUcntDtWLUIz+LhyzY= +github.com/containers/image/v5 v5.21.2-0.20220511203756-fe4fd4ed8be4/go.mod h1:OsX9sFexyGF0FCNAjfcVFv3IwMqDyLyV/WQY/roLPcE= github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a h1:spAGlqziZjCJL25C6F1zsQY05tfCKE9F5YwtEWWe6hU= github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= @@ -359,8 +360,9 @@ github.com/containers/psgo v1.7.2/go.mod h1:SLpqxsPOHtTqRygjutCPXmeU2PoEFzV3gzJp github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4= github.com/containers/storage v1.38.0/go.mod h1:lBzt28gAk5ADZuRtwdndRJyqX22vnRaXmlF+7ktfMYc= github.com/containers/storage v1.40.0/go.mod h1:zUyPC3CFIGR1OhY1CKkffxgw9+LuH76PGvVcFj38dgs= -github.com/containers/storage v1.40.2 h1:GUlHaGnrs1JOEwv6YEvkQdgYXOXZdU1Angy4wgWNgF8= github.com/containers/storage v1.40.2/go.mod h1:zUyPC3CFIGR1OhY1CKkffxgw9+LuH76PGvVcFj38dgs= +github.com/containers/storage v1.41.1-0.20220511210719-cacc3325a9c8 h1:4XdTbn3iVIr1+kN5srZND2G3/Q3hJiZSZZtKdL6r9jg= +github.com/containers/storage v1.41.1-0.20220511210719-cacc3325a9c8/go.mod h1:Pb0l5Sm/89kolX3o2KolKQ5cCHk5vPNpJrhNaLcdS5s= 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= @@ -831,8 +833,9 @@ github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.2 h1:3WH+AG7s2+T8o3nrM/8u2rdqUEcQhmga7smjrT41nAw= github.com/klauspost/compress v1.15.2/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.15.4 h1:1kn4/7MepF/CHmYub99/nNX8az0IJjfSOU/jbnTVfqQ= +github.com/klauspost/compress v1.15.4/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= 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/hack/get_ci_vm.sh b/hack/get_ci_vm.sh index ef7069a81..6632a0178 100755 --- a/hack/get_ci_vm.sh +++ b/hack/get_ci_vm.sh @@ -61,7 +61,7 @@ else -e NAME="$USER" \ -e SRCDIR=/src \ -e GCLOUD_ZONE="$GCLOUD_ZONE" \ - -e DEBUG="${DEBUG:-0}" \ + -e A_DEBUG="${A_DEBUG:-0}" \ -v $REPO_DIRPATH:/src:O \ -v $HOME/.config/gcloud:/root/.config/gcloud:z \ -v $HOME/.config/gcloud/ssh:/root/.ssh:z \ diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index c232702e9..6aa7ce6dc 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -36,7 +36,6 @@ import ( "github.com/containers/podman/v4/utils" "github.com/containers/storage/pkg/homedir" pmount "github.com/containers/storage/pkg/mount" - "github.com/coreos/go-systemd/v22/daemon" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/selinux/go-selinux/label" "github.com/pkg/errors" @@ -1279,19 +1278,6 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co // conmon not having a pid file is a valid state, so don't set it if we don't have it logrus.Infof("Got Conmon PID as %d", conmonPID) ctr.state.ConmonPID = conmonPID - - // Send the MAINPID via sdnotify if needed. - switch ctr.config.SdNotifyMode { - case define.SdNotifyModeContainer, define.SdNotifyModeIgnore: - // Nothing to do or conmon takes care of it already. - - default: - if sent, err := daemon.SdNotify(false, fmt.Sprintf("MAINPID=%d", conmonPID)); err != nil { - logrus.Errorf("Notifying systemd of Conmon PID: %v", err) - } else if sent { - logrus.Debugf("Notify MAINPID sent successfully") - } - } } runtimeRestoreDuration := func() int64 { diff --git a/pkg/bindings/play/types.go b/pkg/bindings/play/types.go index dbff4304b..5aaa87b8c 100644 --- a/pkg/bindings/play/types.go +++ b/pkg/bindings/play/types.go @@ -43,4 +43,6 @@ type KubeOptions struct { LogOptions *[]string // Start - don't start the pod if false Start *bool + // Userns - define the user namespace to use. + Userns *string } diff --git a/pkg/bindings/play/types_kube_options.go b/pkg/bindings/play/types_kube_options.go index d7a452ea2..54c9a8e74 100644 --- a/pkg/bindings/play/types_kube_options.go +++ b/pkg/bindings/play/types_kube_options.go @@ -272,3 +272,18 @@ func (o *KubeOptions) GetStart() bool { } return *o.Start } + +// WithUserns set field Userns to given value +func (o *KubeOptions) WithUserns(value string) *KubeOptions { + o.Userns = &value + return o +} + +// GetUserns returns value of field Userns +func (o *KubeOptions) GetUserns() string { + if o.Userns == nil { + var z string + return z + } + return *o.Userns +} diff --git a/pkg/domain/entities/play.go b/pkg/domain/entities/play.go index c9dc3f08c..bf7c33f2b 100644 --- a/pkg/domain/entities/play.go +++ b/pkg/domain/entities/play.go @@ -54,6 +54,8 @@ type PlayKubeOptions struct { LogOptions []string // Start - don't start the pod if false Start types.OptionalBool + // Userns - define the user namespace to use. + Userns string } // PlayKubePod represents a single pod and associated containers created by play kube diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index b3ded7db6..019361694 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -222,6 +222,16 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY podOpt.Net.NetworkOptions = netOpts } + if options.Userns == "" { + options.Userns = "host" + } + + // Validate the userns modes supported. + podOpt.Userns, err = specgen.ParseUserNamespace(options.Userns) + if err != nil { + return nil, err + } + // FIXME This is very hard to support properly with a good ux if len(options.StaticIPs) > *ipIndex { if !podOpt.Net.Network.IsBridge() { @@ -352,6 +362,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY infraImage := util.DefaultContainerConfig().Engine.InfraImage infraOptions := entities.NewInfraContainerCreateOptions() infraOptions.Hostname = podSpec.PodSpecGen.PodBasicConfig.Hostname + infraOptions.UserNS = options.Userns podSpec.PodSpecGen.InfraImage = infraImage podSpec.PodSpecGen.NoInfra = false podSpec.PodSpecGen.InfraContainerSpec = specgen.NewSpecGenerator(infraImage, false) @@ -412,22 +423,24 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY } specgenOpts := kube.CtrSpecGenOptions{ - Annotations: annotations, - Container: initCtr, - Image: pulledImage, - Volumes: volumes, - PodID: pod.ID(), - PodName: podName, - PodInfraID: podInfraID, - ConfigMaps: configMaps, - SeccompPaths: seccompPaths, - RestartPolicy: ctrRestartPolicy, - NetNSIsHost: p.NetNS.IsHost(), - SecretsManager: secretsManager, - LogDriver: options.LogDriver, - LogOptions: options.LogOptions, - Labels: labels, - InitContainerType: define.AlwaysInitContainer, + Annotations: annotations, + ConfigMaps: configMaps, + Container: initCtr, + Image: pulledImage, + InitContainerType: define.AlwaysInitContainer, + Labels: labels, + LogDriver: options.LogDriver, + LogOptions: options.LogOptions, + NetNSIsHost: p.NetNS.IsHost(), + PodID: pod.ID(), + PodInfraID: podInfraID, + PodName: podName, + PodSecurityContext: podYAML.Spec.SecurityContext, + RestartPolicy: ctrRestartPolicy, + SeccompPaths: seccompPaths, + SecretsManager: secretsManager, + UserNSIsHost: p.Userns.IsHost(), + Volumes: volumes, } specGen, err := kube.ToSpecGen(ctx, &specgenOpts) if err != nil { @@ -460,21 +473,23 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY } specgenOpts := kube.CtrSpecGenOptions{ - Annotations: annotations, - Container: container, - Image: pulledImage, - Volumes: volumes, - PodID: pod.ID(), - PodName: podName, - PodInfraID: podInfraID, - ConfigMaps: configMaps, - SeccompPaths: seccompPaths, - RestartPolicy: ctrRestartPolicy, - NetNSIsHost: p.NetNS.IsHost(), - SecretsManager: secretsManager, - LogDriver: options.LogDriver, - LogOptions: options.LogOptions, - Labels: labels, + Annotations: annotations, + ConfigMaps: configMaps, + Container: container, + Image: pulledImage, + Labels: labels, + LogDriver: options.LogDriver, + LogOptions: options.LogOptions, + NetNSIsHost: p.NetNS.IsHost(), + PodID: pod.ID(), + PodInfraID: podInfraID, + PodName: podName, + PodSecurityContext: podYAML.Spec.SecurityContext, + RestartPolicy: ctrRestartPolicy, + SeccompPaths: seccompPaths, + SecretsManager: secretsManager, + UserNSIsHost: p.Userns.IsHost(), + Volumes: volumes, } specGen, err := kube.ToSpecGen(ctx, &specgenOpts) if err != nil { diff --git a/pkg/domain/infra/tunnel/play.go b/pkg/domain/infra/tunnel/play.go index d9637254a..d731a1d6c 100644 --- a/pkg/domain/infra/tunnel/play.go +++ b/pkg/domain/infra/tunnel/play.go @@ -20,7 +20,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, opts en if opts.Annotations != nil { options.WithAnnotations(opts.Annotations) } - options.WithNoHosts(opts.NoHosts) + options.WithNoHosts(opts.NoHosts).WithUserns(opts.Userns) if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined { options.WithSkipTLSVerify(s == types.OptionalBoolTrue) } diff --git a/pkg/machine/e2e/config_init.go b/pkg/machine/e2e/config_init.go index 2340a1133..7f18cce7d 100644 --- a/pkg/machine/e2e/config_init.go +++ b/pkg/machine/e2e/config_init.go @@ -25,6 +25,7 @@ type initMachine struct { memory *uint now bool timezone string + rootful bool volumes []string cmd []string diff --git a/pkg/machine/e2e/init_test.go b/pkg/machine/e2e/init_test.go index 304122738..6949eb0af 100644 --- a/pkg/machine/e2e/init_test.go +++ b/pkg/machine/e2e/init_test.go @@ -1,6 +1,8 @@ package e2e import ( + "io/ioutil" + "os" "time" "github.com/containers/podman/v4/pkg/machine" @@ -74,4 +76,67 @@ var _ = Describe("podman machine init", func() { Expect(inspectAfter[0].State).To(Equal(machine.Running)) }) + It("machine init with cpus, disk size, memory, timezone", func() { + name := randomString(12) + i := new(initMachine) + session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath).withCPUs(2).withDiskSize(102).withMemory(4000).withTimezone("Pacific/Honolulu")).run() + Expect(err).To(BeNil()) + Expect(session).To(Exit(0)) + + s := new(startMachine) + startSession, err := mb.setCmd(s).run() + Expect(err).To(BeNil()) + Expect(startSession).To(Exit(0)) + + sshCPU := sshMachine{} + CPUsession, err := mb.setName(name).setCmd(sshCPU.withSSHComand([]string{"lscpu", "|", "grep", "\"CPU(s):\"", "|", "head", "-1"})).run() + Expect(err).To(BeNil()) + Expect(CPUsession).To(Exit(0)) + Expect(CPUsession.outputToString()).To(ContainSubstring("2")) + + sshDisk := sshMachine{} + diskSession, err := mb.setName(name).setCmd(sshDisk.withSSHComand([]string{"sudo", "fdisk", "-l", "|", "grep", "Disk"})).run() + Expect(err).To(BeNil()) + Expect(diskSession).To(Exit(0)) + Expect(diskSession.outputToString()).To(ContainSubstring("102 GiB")) + + sshMemory := sshMachine{} + memorySession, err := mb.setName(name).setCmd(sshMemory.withSSHComand([]string{"cat", "/proc/meminfo", "|", "numfmt", "--field", "2", "--from-unit=Ki", "--to-unit=Mi", "|", "sed", "'s/ kB/M/g'", "|", "grep", "MemTotal"})).run() + Expect(err).To(BeNil()) + Expect(memorySession).To(Exit(0)) + Expect(memorySession.outputToString()).To(ContainSubstring("3824")) + + sshTimezone := sshMachine{} + timezoneSession, err := mb.setName(name).setCmd(sshTimezone.withSSHComand([]string{"date"})).run() + Expect(err).To(BeNil()) + Expect(timezoneSession).To(Exit(0)) + Expect(timezoneSession.outputToString()).To(ContainSubstring("HST")) + }) + + It("machine init with volume", func() { + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + _, err = ioutil.TempFile(tmpDir, "example") + Expect(err).To(BeNil()) + mount := tmpDir + ":/testmountdir" + defer os.RemoveAll(tmpDir) + + name := randomString(12) + i := new(initMachine) + session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath).withVolume(mount)).run() + Expect(err).To(BeNil()) + Expect(session).To(Exit(0)) + + s := new(startMachine) + startSession, err := mb.setCmd(s).run() + Expect(err).To(BeNil()) + Expect(startSession).To(Exit(0)) + + ssh2 := sshMachine{} + sshSession2, err := mb.setName(name).setCmd(ssh2.withSSHComand([]string{"ls /testmountdir"})).run() + Expect(err).To(BeNil()) + Expect(sshSession2).To(Exit(0)) + Expect(sshSession2.outputToString()).To(ContainSubstring("example")) + }) + }) diff --git a/pkg/machine/e2e/inspect_test.go b/pkg/machine/e2e/inspect_test.go index b34285dd8..2c9de5664 100644 --- a/pkg/machine/e2e/inspect_test.go +++ b/pkg/machine/e2e/inspect_test.go @@ -3,7 +3,9 @@ package e2e import ( "encoding/json" + "github.com/containers/podman/v4/pkg/machine" "github.com/containers/podman/v4/pkg/machine/qemu" + jsoniter "github.com/json-iterator/go" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -67,4 +69,29 @@ var _ = Describe("podman machine stop", func() { // mb.names = []string{} }) + + It("inspect with go format", func() { + name := randomString(12) + i := new(initMachine) + session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run() + Expect(err).To(BeNil()) + Expect(session).To(Exit(0)) + + // regular inspect should + inspectJson := new(inspectMachine) + inspectSession, err := mb.setName(name).setCmd(inspectJson).run() + Expect(err).To(BeNil()) + Expect(inspectSession).To(Exit(0)) + + var inspectInfo []machine.InspectInfo + err = jsoniter.Unmarshal(inspectSession.Bytes(), &inspectInfo) + Expect(err).To(BeNil()) + + inspect := new(inspectMachine) + inspect = inspect.withFormat("{{.Name}}") + inspectSession, err = mb.setName(name).setCmd(inspect).run() + Expect(err).To(BeNil()) + Expect(inspectSession).To(Exit(0)) + Expect(inspectSession.Bytes()).To(ContainSubstring(name)) + }) }) diff --git a/pkg/machine/e2e/list_test.go b/pkg/machine/e2e/list_test.go index 0ce9063f9..0bc867047 100644 --- a/pkg/machine/e2e/list_test.go +++ b/pkg/machine/e2e/list_test.go @@ -4,6 +4,8 @@ import ( "strings" "github.com/containers/buildah/util" + "github.com/containers/podman/v4/cmd/podman/machine" + jsoniter "github.com/json-iterator/go" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gexec" @@ -40,7 +42,7 @@ var _ = Describe("podman machine list", func() { Expect(len(secondList.outputToStringSlice())).To(Equal(2)) // one machine and the header }) - It("list machines with quiet", func() { + It("list machines with quiet or noheading", func() { // Random names for machines to test list name1 := randomString(12) name2 := randomString(12) @@ -51,6 +53,11 @@ var _ = Describe("podman machine list", func() { Expect(firstList).Should(Exit(0)) Expect(len(firstList.outputToStringSlice())).To(Equal(0)) // No header with quiet + noheaderSession, err := mb.setCmd(list.withNoHeading()).run() // noheader + Expect(err).NotTo(HaveOccurred()) + Expect(noheaderSession).Should(Exit(0)) + Expect(len(noheaderSession.outputToStringSlice())).To(Equal(0)) + i := new(initMachine) session, err := mb.setName(name1).setCmd(i.withImagePath(mb.imagePath)).run() Expect(err).To(BeNil()) @@ -97,6 +104,38 @@ var _ = Describe("podman machine list", func() { Expect(listSession.outputToString()).To(ContainSubstring("Currently running")) Expect(listSession.outputToString()).NotTo(ContainSubstring("Less than a second ago")) // check to make sure time created is accurate }) + + It("list with --format", func() { + // Random names for machines to test list + name1 := randomString(12) + + i := new(initMachine) + session, err := mb.setName(name1).setCmd(i.withImagePath(mb.imagePath)).run() + Expect(err).To(BeNil()) + Expect(session).To(Exit(0)) + + // go format + list := new(listMachine) + listSession, err := mb.setCmd(list.withFormat("{{.Name}}").withNoHeading()).run() + Expect(err).NotTo(HaveOccurred()) + Expect(listSession).To(Exit(0)) + Expect(len(listSession.outputToStringSlice())).To(Equal(1)) + + listNames := listSession.outputToStringSlice() + stripAsterisk(listNames) + Expect(util.StringInSlice(name1, listNames)).To(BeTrue()) + + // --format json + list2 := new(listMachine) + list2 = list2.withFormat("json") + listSession2, err := mb.setName("foo1").setCmd(list2).run() + Expect(err).To(BeNil()) + Expect(listSession2).To(Exit(0)) + + var listResponse []*machine.ListReporter + err = jsoniter.Unmarshal(listSession.Bytes(), &listResponse) + Expect(err).To(BeNil()) + }) }) func stripAsterisk(sl []string) { diff --git a/pkg/machine/e2e/set_test.go b/pkg/machine/e2e/set_test.go index 9af29c560..15215a44d 100644 --- a/pkg/machine/e2e/set_test.go +++ b/pkg/machine/e2e/set_test.go @@ -19,7 +19,7 @@ var _ = Describe("podman machine set", func() { teardown(originalHomeDir, testDir, mb) }) - It("set machine cpus", func() { + It("set machine cpus, disk, memory", func() { name := randomString(12) i := new(initMachine) session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run() @@ -27,40 +27,11 @@ var _ = Describe("podman machine set", func() { Expect(session).To(Exit(0)) set := setMachine{} - setSession, err := mb.setName(name).setCmd(set.withCPUs(2)).run() + setSession, err := mb.setName(name).setCmd(set.withCPUs(2).withDiskSize(102).withMemory(4000)).run() Expect(err).To(BeNil()) Expect(setSession).To(Exit(0)) - s := new(startMachine) - startSession, err := mb.setCmd(s).run() - Expect(err).To(BeNil()) - Expect(startSession).To(Exit(0)) - - ssh2 := sshMachine{} - sshSession2, err := mb.setName(name).setCmd(ssh2.withSSHComand([]string{"lscpu", "|", "grep", "\"CPU(s):\"", "|", "head", "-1"})).run() - Expect(err).To(BeNil()) - Expect(sshSession2).To(Exit(0)) - Expect(sshSession2.outputToString()).To(ContainSubstring("2")) - - // Setting a running machine results in 125 - runner, err := mb.setName(name).setCmd(set.withCPUs(4)).run() - Expect(err).To(BeNil()) - Expect(runner).To(Exit(125)) - }) - - It("increase machine disk size", func() { - name := randomString(12) - i := new(initMachine) - session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run() - Expect(err).To(BeNil()) - Expect(session).To(Exit(0)) - - set := setMachine{} - setSession, err := mb.setName(name).setCmd(set.withDiskSize(102)).run() - Expect(err).To(BeNil()) - Expect(setSession).To(Exit(0)) - - // shrinking disk size iss verboten + // shrinking disk size is verboten shrink, err := mb.setName(name).setCmd(set.withDiskSize(5)).run() Expect(err).To(BeNil()) Expect(shrink).To(Exit(125)) @@ -70,35 +41,28 @@ var _ = Describe("podman machine set", func() { Expect(err).To(BeNil()) Expect(startSession).To(Exit(0)) - ssh2 := sshMachine{} - sshSession2, err := mb.setName(name).setCmd(ssh2.withSSHComand([]string{"sudo", "fdisk", "-l", "|", "grep", "Disk"})).run() - Expect(err).To(BeNil()) - Expect(sshSession2).To(Exit(0)) - Expect(sshSession2.outputToString()).To(ContainSubstring("102 GiB")) - }) - - It("set machine ram", func() { - name := randomString(12) - i := new(initMachine) - session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run() + sshCPU := sshMachine{} + CPUsession, err := mb.setName(name).setCmd(sshCPU.withSSHComand([]string{"lscpu", "|", "grep", "\"CPU(s):\"", "|", "head", "-1"})).run() Expect(err).To(BeNil()) - Expect(session).To(Exit(0)) + Expect(CPUsession).To(Exit(0)) + Expect(CPUsession.outputToString()).To(ContainSubstring("2")) - set := setMachine{} - setSession, err := mb.setName(name).setCmd(set.withMemory(4000)).run() + sshDisk := sshMachine{} + diskSession, err := mb.setName(name).setCmd(sshDisk.withSSHComand([]string{"sudo", "fdisk", "-l", "|", "grep", "Disk"})).run() Expect(err).To(BeNil()) - Expect(setSession).To(Exit(0)) + Expect(diskSession).To(Exit(0)) + Expect(diskSession.outputToString()).To(ContainSubstring("102 GiB")) - s := new(startMachine) - startSession, err := mb.setCmd(s).run() + sshMemory := sshMachine{} + memorySession, err := mb.setName(name).setCmd(sshMemory.withSSHComand([]string{"cat", "/proc/meminfo", "|", "numfmt", "--field", "2", "--from-unit=Ki", "--to-unit=Mi", "|", "sed", "'s/ kB/M/g'", "|", "grep", "MemTotal"})).run() Expect(err).To(BeNil()) - Expect(startSession).To(Exit(0)) + Expect(memorySession).To(Exit(0)) + Expect(memorySession.outputToString()).To(ContainSubstring("3824")) - ssh2 := sshMachine{} - sshSession2, err := mb.setName(name).setCmd(ssh2.withSSHComand([]string{"cat", "/proc/meminfo", "|", "numfmt", "--field", "2", "--from-unit=Ki", "--to-unit=Mi", "|", "sed", "'s/ kB/M/g'", "|", "grep", "MemTotal"})).run() + // Setting a running machine results in 125 + runner, err := mb.setName(name).setCmd(set.withCPUs(4)).run() Expect(err).To(BeNil()) - Expect(sshSession2).To(Exit(0)) - Expect(sshSession2.outputToString()).To(ContainSubstring("3824")) + Expect(runner).To(Exit(125)) }) It("no settings should change if no flags", func() { diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index d56b50fd5..e4c149abf 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -120,6 +120,8 @@ type CtrSpecGenOptions struct { RestartPolicy string // NetNSIsHost tells the container to use the host netns NetNSIsHost bool + // UserNSIsHost tells the container to use the host userns + UserNSIsHost bool // SecretManager to access the secrets SecretsManager *secrets.SecretsManager // LogDriver which should be used for the container @@ -133,6 +135,8 @@ type CtrSpecGenOptions struct { // InitContainerType sets what type the init container is // Note: When playing a kube yaml, the inti container type will be set to "always" only InitContainerType string + // PodSecurityContext is the security context specified for the pod + PodSecurityContext *v1.PodSecurityContext } func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGenerator, error) { @@ -188,7 +192,7 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener s.InitContainerType = opts.InitContainerType - setupSecurityContext(s, opts.Container) + setupSecurityContext(s, opts.Container.SecurityContext, opts.PodSecurityContext) err := setupLivenessProbe(s, opts.Container, opts.RestartPolicy) if err != nil { return nil, errors.Wrap(err, "Failed to configure livenessProbe") @@ -387,8 +391,9 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener if opts.NetNSIsHost { s.NetNS.NSMode = specgen.Host } - // Always set the userns to host since k8s doesn't have support for userns yet - s.UserNS.NSMode = specgen.Host + if opts.UserNSIsHost { + s.UserNS.NSMode = specgen.Host + } // Add labels that come from kube if len(s.Labels) == 0 { @@ -531,22 +536,30 @@ func makeHealthCheck(inCmd string, interval int32, retries int32, timeout int32, return &hc, nil } -func setupSecurityContext(s *specgen.SpecGenerator, containerYAML v1.Container) { - if containerYAML.SecurityContext == nil { - return +func setupSecurityContext(s *specgen.SpecGenerator, securityContext *v1.SecurityContext, podSecurityContext *v1.PodSecurityContext) { + if securityContext == nil { + securityContext = &v1.SecurityContext{} + } + if podSecurityContext == nil { + podSecurityContext = &v1.PodSecurityContext{} } - if containerYAML.SecurityContext.ReadOnlyRootFilesystem != nil { - s.ReadOnlyFilesystem = *containerYAML.SecurityContext.ReadOnlyRootFilesystem + + if securityContext.ReadOnlyRootFilesystem != nil { + s.ReadOnlyFilesystem = *securityContext.ReadOnlyRootFilesystem } - if containerYAML.SecurityContext.Privileged != nil { - s.Privileged = *containerYAML.SecurityContext.Privileged + if securityContext.Privileged != nil { + s.Privileged = *securityContext.Privileged } - if containerYAML.SecurityContext.AllowPrivilegeEscalation != nil { - s.NoNewPrivileges = !*containerYAML.SecurityContext.AllowPrivilegeEscalation + if securityContext.AllowPrivilegeEscalation != nil { + s.NoNewPrivileges = !*securityContext.AllowPrivilegeEscalation } - if seopt := containerYAML.SecurityContext.SELinuxOptions; seopt != nil { + seopt := securityContext.SELinuxOptions + if seopt == nil { + seopt = podSecurityContext.SELinuxOptions + } + if seopt != nil { if seopt.User != "" { s.SelinuxOpts = append(s.SelinuxOpts, fmt.Sprintf("user:%s", seopt.User)) } @@ -560,7 +573,7 @@ func setupSecurityContext(s *specgen.SpecGenerator, containerYAML v1.Container) s.SelinuxOpts = append(s.SelinuxOpts, fmt.Sprintf("level:%s", seopt.Level)) } } - if caps := containerYAML.SecurityContext.Capabilities; caps != nil { + if caps := securityContext.Capabilities; caps != nil { for _, capability := range caps.Add { s.CapAdd = append(s.CapAdd, string(capability)) } @@ -568,14 +581,26 @@ func setupSecurityContext(s *specgen.SpecGenerator, containerYAML v1.Container) s.CapDrop = append(s.CapDrop, string(capability)) } } - if containerYAML.SecurityContext.RunAsUser != nil { - s.User = fmt.Sprintf("%d", *containerYAML.SecurityContext.RunAsUser) + runAsUser := securityContext.RunAsUser + if runAsUser == nil { + runAsUser = podSecurityContext.RunAsUser } - if containerYAML.SecurityContext.RunAsGroup != nil { + if runAsUser != nil { + s.User = fmt.Sprintf("%d", *runAsUser) + } + + runAsGroup := securityContext.RunAsGroup + if runAsGroup == nil { + runAsGroup = podSecurityContext.RunAsGroup + } + if runAsGroup != nil { if s.User == "" { s.User = "0" } - s.User = fmt.Sprintf("%s:%d", s.User, *containerYAML.SecurityContext.RunAsGroup) + s.User = fmt.Sprintf("%s:%d", s.User, *runAsGroup) + } + for _, group := range podSecurityContext.SupplementalGroups { + s.Groups = append(s.Groups, fmt.Sprintf("%d", group)) } } diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 28991af7f..db194b777 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -516,17 +516,13 @@ func (p *PodmanTestIntegration) PodmanPID(args []string) (*PodmanSessionIntegrat // Cleanup cleans up the temporary store func (p *PodmanTestIntegration) Cleanup() { - // Remove all containers - stopall := p.Podman([]string{"stop", "-a", "--time", "0"}) - stopall.WaitWithDefaultTimeout() - - podstop := p.Podman([]string{"pod", "stop", "-a", "-t", "0"}) - podstop.WaitWithDefaultTimeout() - podrm := p.Podman([]string{"pod", "rm", "-fa"}) + // Remove all pods... + podrm := p.Podman([]string{"pod", "rm", "-fa", "-t", "0"}) podrm.WaitWithDefaultTimeout() - session := p.Podman([]string{"rm", "-fa"}) - session.WaitWithDefaultTimeout() + // ...and containers + rmall := p.Podman([]string{"rm", "-fa", "-t", "0"}) + rmall.WaitWithDefaultTimeout() p.StopRemoteService() // Nuke tempdir diff --git a/test/e2e/config.go b/test/e2e/config.go index 9c810575b..2ca8e2a15 100644 --- a/test/e2e/config.go +++ b/test/e2e/config.go @@ -14,7 +14,7 @@ var ( BB = "quay.io/libpod/busybox:latest" healthcheck = "quay.io/libpod/alpine_healthcheck:latest" ImageCacheDir = "/tmp/podman/imagecachedir" - fedoraToolbox = "registry.fedoraproject.org/f32/fedora-toolbox:latest" + fedoraToolbox = "registry.fedoraproject.org/fedora-toolbox:36" volumeTest = "quay.io/libpod/volume-plugin-test-img:latest" // This image has seccomp profiles that blocks all syscalls. diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index fb01dc1e9..216c3357c 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -8,6 +8,7 @@ import ( "net" "net/url" "os" + "os/user" "path/filepath" "strconv" "strings" @@ -327,6 +328,11 @@ spec: name: {{ .Name }} {{ end }} {{ end }} +{{ if .SecurityContext }} + securityContext: + {{ if .RunAsUser }}runAsUser: {{ .RunAsUser }}{{- end }} + {{ if .RunAsGroup }}runAsGroup: {{ .RunAsGroup }}{{- end }} +{{ end }} containers: {{ with .Ctrs }} {{ range . }} @@ -393,6 +399,8 @@ spec: {{- end }} {{ if .SecurityContext }} securityContext: + {{ if .RunAsUser }}runAsUser: {{ .RunAsUser }}{{- end }} + {{ if .RunAsGroup }}runAsGroup: {{ .RunAsGroup }}{{- end }} allowPrivilegeEscalation: true {{ if .Caps }} capabilities: @@ -758,16 +766,19 @@ func withPVCAnnotations(k, v string) pvcOption { // Pod describes the options a kube yaml can be configured at pod level type Pod struct { - Name string - RestartPolicy string - Hostname string - HostNetwork bool - HostAliases []HostAlias - Ctrs []*Ctr - InitCtrs []*Ctr - Volumes []*Volume - Labels map[string]string - Annotations map[string]string + Name string + RestartPolicy string + Hostname string + HostNetwork bool + HostAliases []HostAlias + Ctrs []*Ctr + InitCtrs []*Ctr + Volumes []*Volume + Labels map[string]string + Annotations map[string]string + SecurityContext bool + RunAsUser string + RunAsGroup string } type HostAlias struct { @@ -802,6 +813,24 @@ func getPod(options ...podOption) *Pod { type podOption func(*Pod) +func withPodSecurityContext(sc bool) podOption { + return func(p *Pod) { + p.SecurityContext = sc + } +} + +func withPodRunAsUser(runAsUser string) podOption { + return func(p *Pod) { + p.RunAsUser = runAsUser + } +} + +func withPodRunAsGroup(runAsGroup string) podOption { + return func(p *Pod) { + p.RunAsGroup = runAsGroup + } +} + func withPodName(name string) podOption { return func(pod *Pod) { pod.Name = name @@ -949,6 +978,8 @@ type Ctr struct { Env []Env EnvFrom []EnvFrom InitCtrType string + RunAsUser string + RunAsGroup string } // getCtr takes a list of ctrOptions and returns a Ctr with sane defaults @@ -1042,6 +1073,18 @@ func withSecurityContext(sc bool) ctrOption { } } +func withRunAsUser(runAsUser string) ctrOption { + return func(c *Ctr) { + c.RunAsUser = runAsUser + } +} + +func withRunAsGroup(runAsGroup string) ctrOption { + return func(c *Ctr) { + c.RunAsGroup = runAsGroup + } +} + func withCapAdd(caps []string) ctrOption { return func(c *Ctr) { c.CapAdd = caps @@ -1105,8 +1148,12 @@ func withEnvFrom(name, from string, optional bool) ctrOption { } } +func makeCtrNameInPod(pod *Pod, containerName string) string { + return fmt.Sprintf("%s-%s", pod.Name, containerName) +} + func getCtrNameInPod(pod *Pod) string { - return fmt.Sprintf("%s-%s", pod.Name, defaultCtrName) + return makeCtrNameInPod(pod, defaultCtrName) } type HostPath struct { @@ -3222,6 +3269,38 @@ invalid kube kind Expect(ls.OutputToStringArray()).To(HaveLen(1)) }) + It("podman play kube RunAsUser", func() { + ctr1Name := "ctr1" + ctr2Name := "ctr2" + ctr1 := getCtr(withName(ctr1Name), withSecurityContext(true), withRunAsUser("101"), withRunAsGroup("102")) + ctr2 := getCtr(withName(ctr2Name), withSecurityContext(true)) + + pod := getPod( + withCtr(ctr1), + withCtr(ctr2), + withPodSecurityContext(true), + withPodRunAsUser("103"), + withPodRunAsGroup("104"), + ) + + err := generateKubeYaml("pod", pod, kubeYaml) + Expect(err).To(BeNil()) + + cmd := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + cmd.WaitWithDefaultTimeout() + Expect(cmd).Should(Exit(0)) + + // we expect the user:group as configured for the container + inspect := podmanTest.Podman([]string{"container", "inspect", "--format", "'{{.Config.User}}'", makeCtrNameInPod(pod, ctr1Name)}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.OutputToString()).To(Equal("'101:102'")) + + // we expect the user:group as configured for the pod + inspect = podmanTest.Podman([]string{"container", "inspect", "--format", "'{{.Config.User}}'", makeCtrNameInPod(pod, ctr2Name)}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.OutputToString()).To(Equal("'103:104'")) + }) + Describe("verify environment variables", func() { var maxLength int BeforeEach(func() { @@ -3555,6 +3634,55 @@ ENV OPENJ9_JAVA_OPTIONS=%q inspect.WaitWithDefaultTimeout() Expect(start).Should(Exit(0)) Expect((inspect.InspectContainerToJSON()[0]).HostConfig.LogConfig.Tag).To(Equal("{{.ImageName}}")) + }) + + // Check that --userns=auto creates a user namespace + It("podman play kube --userns=auto", func() { + u, err := user.Current() + Expect(err).To(BeNil()) + name := u.Name + if name == "root" { + name = "containers" + } + content, err := ioutil.ReadFile("/etc/subuid") + if err != nil { + Skip("cannot read /etc/subuid") + } + if !strings.Contains(string(content), name) { + Skip("cannot find mappings for the current user") + } + + initialUsernsConfig, err := ioutil.ReadFile("/proc/self/uid_map") + Expect(err).To(BeNil()) + if os.Geteuid() != 0 { + unshare := podmanTest.Podman([]string{"unshare", "cat", "/proc/self/uid_map"}) + unshare.WaitWithDefaultTimeout() + Expect(unshare).Should(Exit(0)) + initialUsernsConfig = unshare.Out.Contents() + } + + pod := getPod() + err = generateKubeYaml("pod", pod, kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube).Should(Exit(0)) + + usernsInCtr := podmanTest.Podman([]string{"exec", getCtrNameInPod(pod), "cat", "/proc/self/uid_map"}) + usernsInCtr.WaitWithDefaultTimeout() + Expect(usernsInCtr).Should(Exit(0)) + // the conversion to string is needed for better error messages + Expect(string(usernsInCtr.Out.Contents())).To(Equal(string(initialUsernsConfig))) + + // PodmanNoCache is a workaround for https://github.com/containers/storage/issues/1232 + kube = podmanTest.PodmanNoCache([]string{"play", "kube", "--replace", "--userns=auto", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube).Should(Exit(0)) + usernsInCtr = podmanTest.Podman([]string{"exec", getCtrNameInPod(pod), "cat", "/proc/self/uid_map"}) + usernsInCtr.WaitWithDefaultTimeout() + Expect(usernsInCtr).Should(Exit(0)) + Expect(string(usernsInCtr.Out.Contents())).To(Not(Equal(string(initialUsernsConfig)))) }) }) diff --git a/test/system/260-sdnotify.bats b/test/system/260-sdnotify.bats index 395e6f94f..88d84c86f 100644 --- a/test/system/260-sdnotify.bats +++ b/test/system/260-sdnotify.bats @@ -106,6 +106,9 @@ function _assert_mainpid_is_conmon() { cid="$output" wait_for_ready $cid + run_podman container inspect sdnotify_conmon_c --format "{{.State.ConmonPid}}" + mainPID="$output" + run_podman logs sdnotify_conmon_c is "$output" "READY" "\$NOTIFY_SOCKET in container" @@ -114,12 +117,8 @@ function _assert_mainpid_is_conmon() { echo "socat log:" echo "$output" - # ARGH! 'READY=1' should always be the last output line. But sometimes, - # for reasons unknown, we get an extra MAINPID=xxx after READY=1 (#8718). - # Who knows if this is a systemd bug, or conmon, or what. I don't - # even know where to begin asking. So, to eliminate the test flakes, - # we look for READY=1 _anywhere_ in the output, not just the last line. - is "$output" ".*READY=1.*" "sdnotify sent READY=1" + is "$output" "MAINPID=$mainPID +READY=1" "sdnotify sent MAINPID and READY" _assert_mainpid_is_conmon "$output" diff --git a/vendor/github.com/containers/image/v5/docker/docker_client.go b/vendor/github.com/containers/image/v5/docker/docker_client.go index f537de72d..daac45f87 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_client.go +++ b/vendor/github.com/containers/image/v5/docker/docker_client.go @@ -61,8 +61,8 @@ type certPath struct { var ( homeCertDir = filepath.FromSlash(".config/containers/certs.d") perHostCertDirs = []certPath{ - {path: "/etc/containers/certs.d", absolute: true}, - {path: "/etc/docker/certs.d", absolute: true}, + {path: etcDir + "/containers/certs.d", absolute: true}, + {path: etcDir + "/docker/certs.d", absolute: true}, } defaultUserAgent = "containers/" + version.Version + " (github.com/containers/image)" diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_src.go b/vendor/github.com/containers/image/v5/docker/docker_image_src.go index 085a3afcc..27fb838f5 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image_src.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image_src.go @@ -9,6 +9,7 @@ import ( "net/http" "net/url" "os" + "regexp" "strconv" "strings" "sync" @@ -343,12 +344,16 @@ func handle206Response(streams chan io.ReadCloser, errs chan error, body io.Read buffered := makeBufferedNetworkReader(body, 64, 16384) defer buffered.Close() mr := multipart.NewReader(buffered, boundary) + parts := 0 for { p, err := mr.NextPart() if err != nil { if err != io.EOF { errs <- err } + if parts != len(chunks) { + errs <- errors.Errorf("invalid number of chunks returned by the server") + } return } s := signalCloseReader{ @@ -359,7 +364,32 @@ func handle206Response(streams chan io.ReadCloser, errs chan error, body io.Read // NextPart() cannot be called while the current part // is being read, so wait until it is closed <-s.closed + parts++ + } +} + +var multipartByteRangesRe = regexp.MustCompile("multipart/byteranges; boundary=([A-Za-z-0-9:]+)") + +func parseMediaType(contentType string) (string, map[string]string, error) { + mediaType, params, err := mime.ParseMediaType(contentType) + if err != nil { + if err == mime.ErrInvalidMediaParameter { + // CloudFront returns an invalid MIME type, that contains an unquoted ":" in the boundary + // param, let's handle it here. + matches := multipartByteRangesRe.FindStringSubmatch(contentType) + if len(matches) == 2 { + mediaType = "multipart/byteranges" + params = map[string]string{ + "boundary": matches[1], + } + err = nil + } + } + if err != nil { + return "", nil, err + } } + return mediaType, params, err } // GetBlobAt returns a sequential channel of readers that contain data for the requested @@ -397,7 +427,7 @@ func (s *dockerImageSource) GetBlobAt(ctx context.Context, info types.BlobInfo, go splitHTTP200ResponseToPartial(streams, errs, res.Body, chunks) return streams, errs, nil case http.StatusPartialContent: - mediaType, params, err := mime.ParseMediaType(res.Header.Get("Content-Type")) + mediaType, params, err := parseMediaType(res.Header.Get("Content-Type")) if err != nil { return nil, nil, err } diff --git a/vendor/github.com/containers/image/v5/docker/lookaside.go b/vendor/github.com/containers/image/v5/docker/lookaside.go index d0a3f1be0..3294d7def 100644 --- a/vendor/github.com/containers/image/v5/docker/lookaside.go +++ b/vendor/github.com/containers/image/v5/docker/lookaside.go @@ -25,7 +25,7 @@ var systemRegistriesDirPath = builtinRegistriesDirPath // builtinRegistriesDirPath is the path to registries.d. // DO NOT change this, instead see systemRegistriesDirPath above. -const builtinRegistriesDirPath = "/etc/containers/registries.d" +const builtinRegistriesDirPath = etcDir + "/containers/registries.d" // userRegistriesDirPath is the path to the per user registries.d. var userRegistriesDir = filepath.FromSlash(".config/containers/registries.d") diff --git a/vendor/github.com/containers/image/v5/docker/paths_common.go b/vendor/github.com/containers/image/v5/docker/paths_common.go new file mode 100644 index 000000000..862e88039 --- /dev/null +++ b/vendor/github.com/containers/image/v5/docker/paths_common.go @@ -0,0 +1,6 @@ +//go:build !freebsd +// +build !freebsd + +package docker + +const etcDir = "/etc" diff --git a/vendor/github.com/containers/image/v5/docker/paths_freebsd.go b/vendor/github.com/containers/image/v5/docker/paths_freebsd.go new file mode 100644 index 000000000..2bf27ac06 --- /dev/null +++ b/vendor/github.com/containers/image/v5/docker/paths_freebsd.go @@ -0,0 +1,6 @@ +//go:build freebsd +// +build freebsd + +package docker + +const etcDir = "/usr/local/etc" diff --git a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/paths_common.go b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/paths_common.go new file mode 100644 index 000000000..07fe50294 --- /dev/null +++ b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/paths_common.go @@ -0,0 +1,12 @@ +//go:build !freebsd +// +build !freebsd + +package sysregistriesv2 + +// builtinRegistriesConfPath is the path to the registry configuration file. +// DO NOT change this, instead see systemRegistriesConfPath above. +const builtinRegistriesConfPath = "/etc/containers/registries.conf" + +// builtinRegistriesConfDirPath is the path to the registry configuration directory. +// DO NOT change this, instead see systemRegistriesConfDirectoryPath above. +const builtinRegistriesConfDirPath = "/etc/containers/registries.conf.d" diff --git a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/paths_freebsd.go b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/paths_freebsd.go new file mode 100644 index 000000000..741b99f8f --- /dev/null +++ b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/paths_freebsd.go @@ -0,0 +1,12 @@ +//go:build freebsd +// +build freebsd + +package sysregistriesv2 + +// builtinRegistriesConfPath is the path to the registry configuration file. +// DO NOT change this, instead see systemRegistriesConfPath above. +const builtinRegistriesConfPath = "/usr/local/etc/containers/registries.conf" + +// builtinRegistriesConfDirPath is the path to the registry configuration directory. +// DO NOT change this, instead see systemRegistriesConfDirectoryPath above. +const builtinRegistriesConfDirPath = "/usr/local/etc/containers/registries.conf.d" diff --git a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go index c1753c845..002b28d75 100644 --- a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go +++ b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go @@ -25,20 +25,12 @@ import ( // -ldflags '-X github.com/containers/image/v5/sysregistries.systemRegistriesConfPath=$your_path' var systemRegistriesConfPath = builtinRegistriesConfPath -// builtinRegistriesConfPath is the path to the registry configuration file. -// DO NOT change this, instead see systemRegistriesConfPath above. -const builtinRegistriesConfPath = "/etc/containers/registries.conf" - // systemRegistriesConfDirPath is the path to the system-wide registry // configuration directory and is used to add/subtract potential registries for // obtaining images. You can override this at build time with // -ldflags '-X github.com/containers/image/v5/sysregistries.systemRegistriesConfDirectoryPath=$your_path' var systemRegistriesConfDirPath = builtinRegistriesConfDirPath -// builtinRegistriesConfDirPath is the path to the registry configuration directory. -// DO NOT change this, instead see systemRegistriesConfDirectoryPath above. -const builtinRegistriesConfDirPath = "/etc/containers/registries.conf.d" - // AuthenticationFileHelper is a special key for credential helpers indicating // the usage of consulting containers-auth.json files instead of a credential // helper. diff --git a/vendor/github.com/containers/image/v5/signature/policy_config.go b/vendor/github.com/containers/image/v5/signature/policy_config.go index bb91cae8c..2ed0f882b 100644 --- a/vendor/github.com/containers/image/v5/signature/policy_config.go +++ b/vendor/github.com/containers/image/v5/signature/policy_config.go @@ -32,10 +32,6 @@ import ( // -ldflags '-X github.com/containers/image/v5/signature.systemDefaultPolicyPath=$your_path' var systemDefaultPolicyPath = builtinDefaultPolicyPath -// builtinDefaultPolicyPath is the policy path used for DefaultPolicy(). -// DO NOT change this, instead see systemDefaultPolicyPath above. -const builtinDefaultPolicyPath = "/etc/containers/policy.json" - // userPolicyFile is the path to the per user policy path. var userPolicyFile = filepath.FromSlash(".config/containers/policy.json") diff --git a/vendor/github.com/containers/image/v5/signature/policy_paths_common.go b/vendor/github.com/containers/image/v5/signature/policy_paths_common.go new file mode 100644 index 000000000..290fc2459 --- /dev/null +++ b/vendor/github.com/containers/image/v5/signature/policy_paths_common.go @@ -0,0 +1,8 @@ +//go:build !freebsd +// +build !freebsd + +package signature + +// builtinDefaultPolicyPath is the policy path used for DefaultPolicy(). +// DO NOT change this, instead see systemDefaultPolicyPath above. +const builtinDefaultPolicyPath = "/etc/containers/policy.json" diff --git a/vendor/github.com/containers/image/v5/signature/policy_paths_freebsd.go b/vendor/github.com/containers/image/v5/signature/policy_paths_freebsd.go new file mode 100644 index 000000000..702b7171f --- /dev/null +++ b/vendor/github.com/containers/image/v5/signature/policy_paths_freebsd.go @@ -0,0 +1,8 @@ +//go:build freebsd +// +build freebsd + +package signature + +// builtinDefaultPolicyPath is the policy path used for DefaultPolicy(). +// DO NOT change this, instead see systemDefaultPolicyPath above. +const builtinDefaultPolicyPath = "/usr/local/etc/containers/policy.json" diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go index 6295b5493..f15c5ac20 100644 --- a/vendor/github.com/containers/image/v5/version/version.go +++ b/vendor/github.com/containers/image/v5/version/version.go @@ -8,10 +8,10 @@ const ( // VersionMinor is for functionality in a backwards-compatible manner VersionMinor = 21 // VersionPatch is for backwards-compatible bug fixes - VersionPatch = 1 + VersionPatch = 2 // VersionDev indicates development branch. Releases will be empty string. - VersionDev = "" + VersionDev = "-dev" ) // Version is the specification version that the package types support. diff --git a/vendor/github.com/containers/storage/Makefile b/vendor/github.com/containers/storage/Makefile index 2c1e4a185..244576d54 100644 --- a/vendor/github.com/containers/storage/Makefile +++ b/vendor/github.com/containers/storage/Makefile @@ -59,8 +59,8 @@ binary local-binary: containers-storage local-gccgo: ## build using gccgo on the host GCCGO=$(PWD)/hack/gccgo-wrapper.sh $(GO) build $(MOD_VENDOR) -compiler gccgo $(BUILDFLAGS) -o containers-storage.gccgo ./cmd/containers-storage -local-cross: ## cross build the binaries for arm, darwin, and\nfreebsd - @for target in linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64 linux/ppc64le darwin/amd64 windows/amd64 ; do \ +local-cross: ## cross build the binaries for arm, darwin, and freebsd + @for target in linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64 linux/ppc64le darwin/amd64 windows/amd64 freebsd/amd64 freebsd/arm64 ; do \ os=`echo $${target} | cut -f1 -d/` ; \ arch=`echo $${target} | cut -f2 -d/` ; \ suffix=$${os}.$${arch} ; \ diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION index 148dabb45..ce045fe2d 100644 --- a/vendor/github.com/containers/storage/VERSION +++ b/vendor/github.com/containers/storage/VERSION @@ -1 +1 @@ -1.40.2 +1.41.1-dev diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go index 09d24ae8b..8600ee685 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go +++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go @@ -207,14 +207,18 @@ func checkSupportVolatile(home, runhome string) (bool, error) { // checkAndRecordIDMappedSupport checks and stores if the kernel supports mounting overlay on top of a // idmapped lower layer. func checkAndRecordIDMappedSupport(home, runhome string) (bool, error) { + if os.Geteuid() != 0 { + return false, nil + } + feature := "idmapped-lower-dir" overlayCacheResult, overlayCacheText, err := cachedFeatureCheck(runhome, feature) if err == nil { if overlayCacheResult { - logrus.Debugf("Cached value indicated that overlay is supported") + logrus.Debugf("Cached value indicated that idmapped mounts for overlay are supported") return true, nil } - logrus.Debugf("Cached value indicated that overlay is not supported") + logrus.Debugf("Cached value indicated that idmapped mounts for overlay are not supported") return false, errors.New(overlayCacheText) } supportsIDMappedMounts, err := supportsIdmappedLowerLayers(home) diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod index 5d8c59960..1b9f25bcb 100644 --- a/vendor/github.com/containers/storage/go.mod +++ b/vendor/github.com/containers/storage/go.mod @@ -12,7 +12,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.12 - github.com/klauspost/compress v1.15.2 + github.com/klauspost/compress v1.15.4 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 97a0d167d..6587fddb3 100644 --- a/vendor/github.com/containers/storage/go.sum +++ b/vendor/github.com/containers/storage/go.sum @@ -425,8 +425,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o 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.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.2 h1:3WH+AG7s2+T8o3nrM/8u2rdqUEcQhmga7smjrT41nAw= -github.com/klauspost/compress v1.15.2/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.15.4 h1:1kn4/7MepF/CHmYub99/nNX8az0IJjfSOU/jbnTVfqQ= +github.com/klauspost/compress v1.15.4/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= 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/pkg/chrootarchive/archive.go b/vendor/github.com/containers/storage/pkg/chrootarchive/archive.go index e874eb74e..482e03663 100644 --- a/vendor/github.com/containers/storage/pkg/chrootarchive/archive.go +++ b/vendor/github.com/containers/storage/pkg/chrootarchive/archive.go @@ -5,9 +5,7 @@ import ( "fmt" "io" "io/ioutil" - "net" "os" - "os/user" "path/filepath" "sync" @@ -17,13 +15,6 @@ import ( "github.com/pkg/errors" ) -func init() { - // initialize nss libraries in Glibc so that the dynamic libraries are loaded in the host - // environment not in the chroot from untrusted files. - _, _ = user.Lookup("storage") - _, _ = net.LookupHost("localhost") -} - // NewArchiver returns a new Archiver which uses chrootarchive.Untar func NewArchiver(idMappings *idtools.IDMappings) *archive.Archiver { archiver := archive.NewArchiver(idMappings) diff --git a/vendor/github.com/containers/storage/pkg/chrootarchive/chroot_linux.go b/vendor/github.com/containers/storage/pkg/chrootarchive/chroot_linux.go index 76c94c6c1..58729ec8c 100644 --- a/vendor/github.com/containers/storage/pkg/chrootarchive/chroot_linux.go +++ b/vendor/github.com/containers/storage/pkg/chrootarchive/chroot_linux.go @@ -3,7 +3,9 @@ package chrootarchive import ( "fmt" "io/ioutil" + "net" "os" + "os/user" "path/filepath" "github.com/containers/storage/pkg/mount" @@ -23,6 +25,11 @@ func chroot(path string) (err error) { return err } + // initialize nss libraries in Glibc so that the dynamic libraries are loaded in the host + // environment not in the chroot from untrusted files. + _, _ = user.Lookup("storage") + _, _ = net.LookupHost("localhost") + // if the process doesn't have CAP_SYS_ADMIN, but does have CAP_SYS_CHROOT, we need to use the actual chroot if !caps.Get(capability.EFFECTIVE, capability.CAP_SYS_ADMIN) && caps.Get(capability.EFFECTIVE, capability.CAP_SYS_CHROOT) { return realChroot(path) diff --git a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go index 7de20feaa..9434499d2 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go +++ b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go @@ -918,6 +918,9 @@ func (c *chunkedDiffer) storeMissingFiles(streams chan io.ReadCloser, errs chan case p := <-streams: part = p case err := <-errs: + if err == nil { + return errors.New("not enough data returned from the server") + } return err } if part == nil { @@ -1081,12 +1084,18 @@ func mergeMissingChunks(missingParts []missingPart, target int) []missingPart { func (c *chunkedDiffer) retrieveMissingFiles(dest string, dirfd int, missingParts []missingPart, options *archive.TarOptions) error { var chunksToRequest []ImageSourceChunk - for _, c := range missingParts { - if c.OriginFile == nil && !c.Hole { - chunksToRequest = append(chunksToRequest, *c.SourceChunk) + + calculateChunksToRequest := func() { + chunksToRequest = []ImageSourceChunk{} + for _, c := range missingParts { + if c.OriginFile == nil && !c.Hole { + chunksToRequest = append(chunksToRequest, *c.SourceChunk) + } } } + calculateChunksToRequest() + // There are some missing files. Prepare a multirange request for the missing chunks. var streams chan io.ReadCloser var err error @@ -1106,6 +1115,7 @@ func (c *chunkedDiffer) retrieveMissingFiles(dest string, dirfd int, missingPart // Merge more chunks to request missingParts = mergeMissingChunks(missingParts, requested/2) + calculateChunksToRequest() continue } return err @@ -1575,6 +1585,8 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra wg.Wait() for _, res := range copyResults[:filesToWaitFor] { + r := &mergedEntries[res.index] + if res.err != nil { return output, res.err } @@ -1584,8 +1596,6 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra continue } - r := &mergedEntries[res.index] - missingPartsSize += r.Size remainingSize := r.Size diff --git a/vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go b/vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go index 72ceec3dd..2404e331d 100644 --- a/vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go +++ b/vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go @@ -1,3 +1,6 @@ +//go:build freebsd && cgo +// +build freebsd,cgo + package mount /* diff --git a/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go b/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go index 9d20cfbf8..74fe66609 100644 --- a/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go +++ b/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go @@ -1,4 +1,6 @@ -// +build !linux,!freebsd +//go:build !linux && !(freebsd && cgo) +// +build !linux +// +build !freebsd !cgo package mount diff --git a/vendor/github.com/containers/storage/storage.conf-freebsd b/vendor/github.com/containers/storage/storage.conf-freebsd index cc655c62e..34d80152c 100644 --- a/vendor/github.com/containers/storage/storage.conf-freebsd +++ b/vendor/github.com/containers/storage/storage.conf-freebsd @@ -5,8 +5,8 @@ # files. # # Note: The storage.conf file overrides other storage.conf files based on this precedence: -# /usr/containers/storage.conf -# /etc/containers/storage.conf +# /usr/local/share/containers/storage.conf +# /usr/local/etc/containers/storage.conf # $HOME/.config/containers/storage.conf # $XDG_CONFIG_HOME/containers/storage.conf (If XDG_CONFIG_HOME is set) # See man 5 containers-storage.conf for more information diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go index 30d3e8715..45912d0ca 100644 --- a/vendor/github.com/containers/storage/store.go +++ b/vendor/github.com/containers/storage/store.go @@ -1195,6 +1195,11 @@ func (s *store) imageTopLayerForMapping(image *Image, ristore ROImageStore, crea if layer == nil { layer = cLayer parentLayer = cParentLayer + if store != rlstore { + // The layer is in another store, so we cannot + // create a mapped version of it to the image. + createMappedLayer = false + } } } } diff --git a/vendor/github.com/containers/storage/types/options.go b/vendor/github.com/containers/storage/types/options.go index a71c6d2ef..d318421a4 100644 --- a/vendor/github.com/containers/storage/types/options.go +++ b/vendor/github.com/containers/storage/types/options.go @@ -26,22 +26,6 @@ type TomlConfig struct { } const ( - // these are default path for run and graph root for rootful users - // for rootless path is constructed via getRootlessStorageOpts - defaultRunRoot string = "/run/containers/storage" - defaultGraphRoot string = "/var/lib/containers/storage" -) - -// defaultConfigFile path to the system wide storage.conf file -var ( - defaultConfigFile = "/usr/share/containers/storage.conf" - defaultOverrideConfigFile = "/etc/containers/storage.conf" - defaultConfigFileSet = false - // DefaultStoreOptions is a reasonable default set of options. - defaultStoreOptions StoreOptions -) - -const ( overlayDriver = "overlay" overlay2 = "overlay2" ) diff --git a/vendor/github.com/containers/storage/types/options_darwin.go b/vendor/github.com/containers/storage/types/options_darwin.go new file mode 100644 index 000000000..d5ad50bc0 --- /dev/null +++ b/vendor/github.com/containers/storage/types/options_darwin.go @@ -0,0 +1,17 @@ +package types + +const ( + // these are default path for run and graph root for rootful users + // for rootless path is constructed via getRootlessStorageOpts + defaultRunRoot string = "/run/containers/storage" + defaultGraphRoot string = "/var/lib/containers/storage" +) + +// defaultConfigFile path to the system wide storage.conf file +var ( + defaultConfigFile = "/usr/share/containers/storage.conf" + defaultOverrideConfigFile = "/etc/containers/storage.conf" + defaultConfigFileSet = false + // DefaultStoreOptions is a reasonable default set of options. + defaultStoreOptions StoreOptions +) diff --git a/vendor/github.com/containers/storage/types/options_freebsd.go b/vendor/github.com/containers/storage/types/options_freebsd.go new file mode 100644 index 000000000..d5976b6d5 --- /dev/null +++ b/vendor/github.com/containers/storage/types/options_freebsd.go @@ -0,0 +1,17 @@ +package types + +const ( + // these are default path for run and graph root for rootful users + // for rootless path is constructed via getRootlessStorageOpts + defaultRunRoot string = "/var/run/containers/storage" + defaultGraphRoot string = "/var/db/containers/storage" +) + +// defaultConfigFile path to the system wide storage.conf file +var ( + defaultConfigFile = "/usr/local/share/containers/storage.conf" + defaultOverrideConfigFile = "/usr/local/etc/containers/storage.conf" + defaultConfigFileSet = false + // DefaultStoreOptions is a reasonable default set of options. + defaultStoreOptions StoreOptions +) diff --git a/vendor/github.com/containers/storage/types/options_linux.go b/vendor/github.com/containers/storage/types/options_linux.go new file mode 100644 index 000000000..d5ad50bc0 --- /dev/null +++ b/vendor/github.com/containers/storage/types/options_linux.go @@ -0,0 +1,17 @@ +package types + +const ( + // these are default path for run and graph root for rootful users + // for rootless path is constructed via getRootlessStorageOpts + defaultRunRoot string = "/run/containers/storage" + defaultGraphRoot string = "/var/lib/containers/storage" +) + +// defaultConfigFile path to the system wide storage.conf file +var ( + defaultConfigFile = "/usr/share/containers/storage.conf" + defaultOverrideConfigFile = "/etc/containers/storage.conf" + defaultConfigFileSet = false + // DefaultStoreOptions is a reasonable default set of options. + defaultStoreOptions StoreOptions +) diff --git a/vendor/github.com/containers/storage/types/options_windows.go b/vendor/github.com/containers/storage/types/options_windows.go new file mode 100644 index 000000000..d5ad50bc0 --- /dev/null +++ b/vendor/github.com/containers/storage/types/options_windows.go @@ -0,0 +1,17 @@ +package types + +const ( + // these are default path for run and graph root for rootful users + // for rootless path is constructed via getRootlessStorageOpts + defaultRunRoot string = "/run/containers/storage" + defaultGraphRoot string = "/var/lib/containers/storage" +) + +// defaultConfigFile path to the system wide storage.conf file +var ( + defaultConfigFile = "/usr/share/containers/storage.conf" + defaultOverrideConfigFile = "/etc/containers/storage.conf" + defaultConfigFileSet = false + // DefaultStoreOptions is a reasonable default set of options. + defaultStoreOptions StoreOptions +) diff --git a/vendor/github.com/klauspost/compress/README.md b/vendor/github.com/klauspost/compress/README.md index 5b7cf781a..c3ec9d8a7 100644 --- a/vendor/github.com/klauspost/compress/README.md +++ b/vendor/github.com/klauspost/compress/README.md @@ -17,6 +17,16 @@ This package provides various compression algorithms. # changelog
+* May 5, 2022 (v1.15.3)
+ * zstd: Allow to ignore checksum checking by @WojciechMula [#572](https://github.com/klauspost/compress/pull/572)
+ * s2: Fix incorrect seek for io.SeekEnd in [#575](https://github.com/klauspost/compress/pull/575)
+
+* Apr 26, 2022 (v1.15.2)
+ * zstd: Add x86-64 assembly for decompression on streams and blocks. Contributed by [@WojciechMula](https://github.com/WojciechMula). Typically 2x faster. [#528](https://github.com/klauspost/compress/pull/528) [#531](https://github.com/klauspost/compress/pull/531) [#545](https://github.com/klauspost/compress/pull/545) [#537](https://github.com/klauspost/compress/pull/537)
+ * zstd: Add options to ZipDecompressor and fixes [#539](https://github.com/klauspost/compress/pull/539)
+ * s2: Use sorted search for index [#555](https://github.com/klauspost/compress/pull/555)
+ * Minimum version is Go 1.16, added CI test on 1.18.
+
* Mar 11, 2022 (v1.15.1)
* huff0: Add x86 assembly of Decode4X by @WojciechMula in [#512](https://github.com/klauspost/compress/pull/512)
* zstd: Reuse zip decoders in [#514](https://github.com/klauspost/compress/pull/514)
diff --git a/vendor/github.com/klauspost/compress/flate/inflate_gen.go b/vendor/github.com/klauspost/compress/flate/inflate_gen.go index 8d632cea0..61342b6b8 100644 --- a/vendor/github.com/klauspost/compress/flate/inflate_gen.go +++ b/vendor/github.com/klauspost/compress/flate/inflate_gen.go @@ -24,7 +24,7 @@ func (f *decompressor) huffmanBytesBuffer() { // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, // but is smart enough to keep local variables in registers, so use nb and b, // inline call to moreBits and reassign b,nb back to f on return. - fnb, fb := f.nb, f.b + fnb, fb, dict := f.nb, f.b, &f.dict switch f.stepState { case stateInit: @@ -82,9 +82,9 @@ readLiteral: var length int switch { case v < 256: - f.dict.writeByte(byte(v)) - if f.dict.availWrite() == 0 { - f.toRead = f.dict.readFlush() + dict.writeByte(byte(v)) + if dict.availWrite() == 0 { + f.toRead = dict.readFlush() f.step = (*decompressor).huffmanBytesBuffer f.stepState = stateInit f.b, f.nb = fb, fnb @@ -227,10 +227,10 @@ readLiteral: } // No check on length; encoding can be prescient. - if dist > uint32(f.dict.histSize()) { + if dist > uint32(dict.histSize()) { f.b, f.nb = fb, fnb if debugDecode { - fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize()) + fmt.Println("dist > dict.histSize():", dist, dict.histSize()) } f.err = CorruptInputError(f.roffset) return @@ -243,14 +243,14 @@ readLiteral: copyHistory: // Perform a backwards copy according to RFC section 3.2.3. { - cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen) + cnt := dict.tryWriteCopy(f.copyDist, f.copyLen) if cnt == 0 { - cnt = f.dict.writeCopy(f.copyDist, f.copyLen) + cnt = dict.writeCopy(f.copyDist, f.copyLen) } f.copyLen -= cnt - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() + if dict.availWrite() == 0 || f.copyLen > 0 { + f.toRead = dict.readFlush() f.step = (*decompressor).huffmanBytesBuffer // We need to continue this work f.stepState = stateDict f.b, f.nb = fb, fnb @@ -275,7 +275,7 @@ func (f *decompressor) huffmanBytesReader() { // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, // but is smart enough to keep local variables in registers, so use nb and b, // inline call to moreBits and reassign b,nb back to f on return. - fnb, fb := f.nb, f.b + fnb, fb, dict := f.nb, f.b, &f.dict switch f.stepState { case stateInit: @@ -333,9 +333,9 @@ readLiteral: var length int switch { case v < 256: - f.dict.writeByte(byte(v)) - if f.dict.availWrite() == 0 { - f.toRead = f.dict.readFlush() + dict.writeByte(byte(v)) + if dict.availWrite() == 0 { + f.toRead = dict.readFlush() f.step = (*decompressor).huffmanBytesReader f.stepState = stateInit f.b, f.nb = fb, fnb @@ -478,10 +478,10 @@ readLiteral: } // No check on length; encoding can be prescient. - if dist > uint32(f.dict.histSize()) { + if dist > uint32(dict.histSize()) { f.b, f.nb = fb, fnb if debugDecode { - fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize()) + fmt.Println("dist > dict.histSize():", dist, dict.histSize()) } f.err = CorruptInputError(f.roffset) return @@ -494,14 +494,14 @@ readLiteral: copyHistory: // Perform a backwards copy according to RFC section 3.2.3. { - cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen) + cnt := dict.tryWriteCopy(f.copyDist, f.copyLen) if cnt == 0 { - cnt = f.dict.writeCopy(f.copyDist, f.copyLen) + cnt = dict.writeCopy(f.copyDist, f.copyLen) } f.copyLen -= cnt - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() + if dict.availWrite() == 0 || f.copyLen > 0 { + f.toRead = dict.readFlush() f.step = (*decompressor).huffmanBytesReader // We need to continue this work f.stepState = stateDict f.b, f.nb = fb, fnb @@ -526,7 +526,7 @@ func (f *decompressor) huffmanBufioReader() { // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, // but is smart enough to keep local variables in registers, so use nb and b, // inline call to moreBits and reassign b,nb back to f on return. - fnb, fb := f.nb, f.b + fnb, fb, dict := f.nb, f.b, &f.dict switch f.stepState { case stateInit: @@ -584,9 +584,9 @@ readLiteral: var length int switch { case v < 256: - f.dict.writeByte(byte(v)) - if f.dict.availWrite() == 0 { - f.toRead = f.dict.readFlush() + dict.writeByte(byte(v)) + if dict.availWrite() == 0 { + f.toRead = dict.readFlush() f.step = (*decompressor).huffmanBufioReader f.stepState = stateInit f.b, f.nb = fb, fnb @@ -729,10 +729,10 @@ readLiteral: } // No check on length; encoding can be prescient. - if dist > uint32(f.dict.histSize()) { + if dist > uint32(dict.histSize()) { f.b, f.nb = fb, fnb if debugDecode { - fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize()) + fmt.Println("dist > dict.histSize():", dist, dict.histSize()) } f.err = CorruptInputError(f.roffset) return @@ -745,14 +745,14 @@ readLiteral: copyHistory: // Perform a backwards copy according to RFC section 3.2.3. { - cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen) + cnt := dict.tryWriteCopy(f.copyDist, f.copyLen) if cnt == 0 { - cnt = f.dict.writeCopy(f.copyDist, f.copyLen) + cnt = dict.writeCopy(f.copyDist, f.copyLen) } f.copyLen -= cnt - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() + if dict.availWrite() == 0 || f.copyLen > 0 { + f.toRead = dict.readFlush() f.step = (*decompressor).huffmanBufioReader // We need to continue this work f.stepState = stateDict f.b, f.nb = fb, fnb @@ -777,7 +777,7 @@ func (f *decompressor) huffmanStringsReader() { // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, // but is smart enough to keep local variables in registers, so use nb and b, // inline call to moreBits and reassign b,nb back to f on return. - fnb, fb := f.nb, f.b + fnb, fb, dict := f.nb, f.b, &f.dict switch f.stepState { case stateInit: @@ -835,9 +835,9 @@ readLiteral: var length int switch { case v < 256: - f.dict.writeByte(byte(v)) - if f.dict.availWrite() == 0 { - f.toRead = f.dict.readFlush() + dict.writeByte(byte(v)) + if dict.availWrite() == 0 { + f.toRead = dict.readFlush() f.step = (*decompressor).huffmanStringsReader f.stepState = stateInit f.b, f.nb = fb, fnb @@ -980,10 +980,10 @@ readLiteral: } // No check on length; encoding can be prescient. - if dist > uint32(f.dict.histSize()) { + if dist > uint32(dict.histSize()) { f.b, f.nb = fb, fnb if debugDecode { - fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize()) + fmt.Println("dist > dict.histSize():", dist, dict.histSize()) } f.err = CorruptInputError(f.roffset) return @@ -996,14 +996,14 @@ readLiteral: copyHistory: // Perform a backwards copy according to RFC section 3.2.3. { - cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen) + cnt := dict.tryWriteCopy(f.copyDist, f.copyLen) if cnt == 0 { - cnt = f.dict.writeCopy(f.copyDist, f.copyLen) + cnt = dict.writeCopy(f.copyDist, f.copyLen) } f.copyLen -= cnt - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() + if dict.availWrite() == 0 || f.copyLen > 0 { + f.toRead = dict.readFlush() f.step = (*decompressor).huffmanStringsReader // We need to continue this work f.stepState = stateDict f.b, f.nb = fb, fnb @@ -1028,7 +1028,7 @@ func (f *decompressor) huffmanGenericReader() { // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, // but is smart enough to keep local variables in registers, so use nb and b, // inline call to moreBits and reassign b,nb back to f on return. - fnb, fb := f.nb, f.b + fnb, fb, dict := f.nb, f.b, &f.dict switch f.stepState { case stateInit: @@ -1086,9 +1086,9 @@ readLiteral: var length int switch { case v < 256: - f.dict.writeByte(byte(v)) - if f.dict.availWrite() == 0 { - f.toRead = f.dict.readFlush() + dict.writeByte(byte(v)) + if dict.availWrite() == 0 { + f.toRead = dict.readFlush() f.step = (*decompressor).huffmanGenericReader f.stepState = stateInit f.b, f.nb = fb, fnb @@ -1231,10 +1231,10 @@ readLiteral: } // No check on length; encoding can be prescient. - if dist > uint32(f.dict.histSize()) { + if dist > uint32(dict.histSize()) { f.b, f.nb = fb, fnb if debugDecode { - fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize()) + fmt.Println("dist > dict.histSize():", dist, dict.histSize()) } f.err = CorruptInputError(f.roffset) return @@ -1247,14 +1247,14 @@ readLiteral: copyHistory: // Perform a backwards copy according to RFC section 3.2.3. { - cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen) + cnt := dict.tryWriteCopy(f.copyDist, f.copyLen) if cnt == 0 { - cnt = f.dict.writeCopy(f.copyDist, f.copyLen) + cnt = dict.writeCopy(f.copyDist, f.copyLen) } f.copyLen -= cnt - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() + if dict.availWrite() == 0 || f.copyLen > 0 { + f.toRead = dict.readFlush() f.step = (*decompressor).huffmanGenericReader // We need to continue this work f.stepState = stateDict f.b, f.nb = fb, fnb diff --git a/vendor/github.com/klauspost/compress/huff0/autogen.go b/vendor/github.com/klauspost/compress/huff0/autogen.go deleted file mode 100644 index ff2c69d60..000000000 --- a/vendor/github.com/klauspost/compress/huff0/autogen.go +++ /dev/null @@ -1,5 +0,0 @@ -package huff0 - -//go:generate go run generate.go -//go:generate asmfmt -w decompress_amd64.s -//go:generate asmfmt -w decompress_8b_amd64.s diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s b/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s deleted file mode 100644 index 0d6cb1a96..000000000 --- a/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s +++ /dev/null @@ -1,488 +0,0 @@ -// +build !appengine -// +build gc -// +build !noasm - -#include "textflag.h" -#include "funcdata.h" -#include "go_asm.h" - -#define bufoff 256 // see decompress.go, we're using [4][256]byte table - -// func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, -// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool) -TEXT ·decompress4x_8b_loop_x86(SB), NOSPLIT, $8 -#define off R8 -#define buffer DI -#define table SI - -#define br_bits_read R9 -#define br_value R10 -#define br_offset R11 -#define peek_bits R12 -#define exhausted DX - -#define br0 R13 -#define br1 R14 -#define br2 R15 -#define br3 BP - - MOVQ BP, 0(SP) - - XORQ exhausted, exhausted // exhausted = false - XORQ off, off // off = 0 - - MOVBQZX peekBits+32(FP), peek_bits - MOVQ buf+40(FP), buffer - MOVQ tbl+48(FP), table - - MOVQ pbr0+0(FP), br0 - MOVQ pbr1+8(FP), br1 - MOVQ pbr2+16(FP), br2 - MOVQ pbr3+24(FP), br3 - -main_loop: - - // const stream = 0 - // br0.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br0), br_bits_read - MOVQ bitReaderShifted_value(br0), br_value - MOVQ bitReaderShifted_off(br0), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill0 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br0), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br0.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } -skip_fill0: - - // val0 := br0.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br0.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br0.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br0.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 0(buffer)(off*1) - - // SECOND PART: - // val2 := br0.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br0.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br0.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br0.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, 0+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br0) - MOVQ br_value, bitReaderShifted_value(br0) - MOVQ br_offset, bitReaderShifted_off(br0) - - // const stream = 1 - // br1.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br1), br_bits_read - MOVQ bitReaderShifted_value(br1), br_value - MOVQ bitReaderShifted_off(br1), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill1 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br1), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br1.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } -skip_fill1: - - // val0 := br1.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br1.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br1.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br1.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 256(buffer)(off*1) - - // SECOND PART: - // val2 := br1.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br1.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br1.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br1.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, 256+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br1) - MOVQ br_value, bitReaderShifted_value(br1) - MOVQ br_offset, bitReaderShifted_off(br1) - - // const stream = 2 - // br2.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br2), br_bits_read - MOVQ bitReaderShifted_value(br2), br_value - MOVQ bitReaderShifted_off(br2), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill2 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br2), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br2.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } -skip_fill2: - - // val0 := br2.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br2.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br2.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br2.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 512(buffer)(off*1) - - // SECOND PART: - // val2 := br2.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br2.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br2.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br2.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, 512+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br2) - MOVQ br_value, bitReaderShifted_value(br2) - MOVQ br_offset, bitReaderShifted_off(br2) - - // const stream = 3 - // br3.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br3), br_bits_read - MOVQ bitReaderShifted_value(br3), br_value - MOVQ bitReaderShifted_off(br3), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill3 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br3), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br3.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } -skip_fill3: - - // val0 := br3.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br3.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br3.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br3.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 768(buffer)(off*1) - - // SECOND PART: - // val2 := br3.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br3.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br3.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br3.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, 768+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br3) - MOVQ br_value, bitReaderShifted_value(br3) - MOVQ br_offset, bitReaderShifted_off(br3) - - ADDQ $4, off // off += 2 - - TESTB DH, DH // any br[i].ofs < 4? - JNZ end - - CMPQ off, $bufoff - JL main_loop - -end: - MOVQ 0(SP), BP - - MOVB off, ret+56(FP) - RET - -#undef off -#undef buffer -#undef table - -#undef br_bits_read -#undef br_value -#undef br_offset -#undef peek_bits -#undef exhausted - -#undef br0 -#undef br1 -#undef br2 -#undef br3 diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s.in b/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s.in deleted file mode 100644 index 6d477a2c1..000000000 --- a/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s.in +++ /dev/null @@ -1,197 +0,0 @@ -// +build !appengine -// +build gc -// +build !noasm - -#include "textflag.h" -#include "funcdata.h" -#include "go_asm.h" - - -#define bufoff 256 // see decompress.go, we're using [4][256]byte table - -//func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, -// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool) -TEXT ·decompress4x_8b_loop_x86(SB), NOSPLIT, $8 -#define off R8 -#define buffer DI -#define table SI - -#define br_bits_read R9 -#define br_value R10 -#define br_offset R11 -#define peek_bits R12 -#define exhausted DX - -#define br0 R13 -#define br1 R14 -#define br2 R15 -#define br3 BP - - MOVQ BP, 0(SP) - - XORQ exhausted, exhausted // exhausted = false - XORQ off, off // off = 0 - - MOVBQZX peekBits+32(FP), peek_bits - MOVQ buf+40(FP), buffer - MOVQ tbl+48(FP), table - - MOVQ pbr0+0(FP), br0 - MOVQ pbr1+8(FP), br1 - MOVQ pbr2+16(FP), br2 - MOVQ pbr3+24(FP), br3 - -main_loop: -{{ define "decode_2_values_x86" }} - // const stream = {{ var "id" }} - // br{{ var "id"}}.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br{{ var "id" }}), br_bits_read - MOVQ bitReaderShifted_value(br{{ var "id" }}), br_value - MOVQ bitReaderShifted_off(br{{ var "id" }}), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill{{ var "id" }} - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br{{ var "id" }}), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br{{ var "id"}}.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - // } -skip_fill{{ var "id" }}: - - // val0 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br{{ var "id"}}.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br{{ var "id"}}.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, {{ var "bufofs" }}(buffer)(off*1) - - // SECOND PART: - // val2 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br{{ var "id"}}.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br{{ var "id"}}.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, {{ var "bufofs" }}+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br{{ var "id" }}) - MOVQ br_value, bitReaderShifted_value(br{{ var "id" }}) - MOVQ br_offset, bitReaderShifted_off(br{{ var "id" }}) -{{ end }} - - {{ set "id" "0" }} - {{ set "ofs" "0" }} - {{ set "bufofs" "0" }} {{/* id * bufoff */}} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "1" }} - {{ set "ofs" "8" }} - {{ set "bufofs" "256" }} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "2" }} - {{ set "ofs" "16" }} - {{ set "bufofs" "512" }} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "3" }} - {{ set "ofs" "24" }} - {{ set "bufofs" "768" }} - {{ template "decode_2_values_x86" . }} - - ADDQ $4, off // off += 2 - - TESTB DH, DH // any br[i].ofs < 4? - JNZ end - - CMPQ off, $bufoff - JL main_loop -end: - MOVQ 0(SP), BP - - MOVB off, ret+56(FP) - RET -#undef off -#undef buffer -#undef table - -#undef br_bits_read -#undef br_value -#undef br_offset -#undef peek_bits -#undef exhausted - -#undef br0 -#undef br1 -#undef br2 -#undef br3 diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go index ce8e93bcd..3415e5da2 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go @@ -13,19 +13,30 @@ import ( // decompress4x_main_loop_x86 is an x86 assembler implementation // of Decompress4X when tablelog > 8. //go:noescape -func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, - peekBits uint8, buf *byte, tbl *dEntrySingle) uint8 +func decompress4x_main_loop_amd64(ctx *decompress4xContext) // decompress4x_8b_loop_x86 is an x86 assembler implementation // of Decompress4X when tablelog <= 8 which decodes 4 entries // per loop. //go:noescape -func decompress4x_8b_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, - peekBits uint8, buf *byte, tbl *dEntrySingle) uint8 +func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) // fallback8BitSize is the size where using Go version is faster. const fallback8BitSize = 800 +type decompress4xContext struct { + pbr0 *bitReaderShifted + pbr1 *bitReaderShifted + pbr2 *bitReaderShifted + pbr3 *bitReaderShifted + peekBits uint8 + out *byte + dstEvery int + tbl *dEntrySingle + decoded int + limit *byte +} + // Decompress4X will decompress a 4X encoded stream. // The length of the supplied input must match the end of a block exactly. // The *capacity* of the dst slice must match the destination size of @@ -42,6 +53,7 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { if cap(dst) < fallback8BitSize && use8BitTables { return d.decompress4X8bit(dst, src) } + var br [4]bitReaderShifted // Decode "jump table" start := 6 @@ -71,70 +83,28 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { const tlMask = tlSize - 1 single := d.dt.single[:tlSize] - // Use temp table to avoid bound checks/append penalty. - buf := d.buffer() - var off uint8 var decoded int - const debug = false - - // see: bitReaderShifted.peekBitsFast() - peekBits := uint8((64 - d.actualTableLog) & 63) - - // Decode 2 values from each decoder/loop. - const bufoff = 256 - for { - if br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4 { - break + if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) { + ctx := decompress4xContext{ + pbr0: &br[0], + pbr1: &br[1], + pbr2: &br[2], + pbr3: &br[3], + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + out: &out[0], + dstEvery: dstEvery, + tbl: &single[0], + limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last. } - if use8BitTables { - off = decompress4x_8b_loop_x86(&br[0], &br[1], &br[2], &br[3], peekBits, &buf[0][0], &single[0]) + decompress4x_8b_main_loop_amd64(&ctx) } else { - off = decompress4x_main_loop_x86(&br[0], &br[1], &br[2], &br[3], peekBits, &buf[0][0], &single[0]) - } - if debug { - fmt.Print("DEBUG: ") - fmt.Printf("off=%d,", off) - for i := 0; i < 4; i++ { - fmt.Printf(" br[%d]={bitsRead=%d, value=%x, off=%d}", - i, br[i].bitsRead, br[i].value, br[i].off) - } - fmt.Println("") - } - - if off != 0 { - break + decompress4x_main_loop_amd64(&ctx) } - if bufoff > dstEvery { - d.bufs.Put(buf) - return nil, errors.New("corruption detected: stream overrun 1") - } - copy(out, buf[0][:]) - copy(out[dstEvery:], buf[1][:]) - copy(out[dstEvery*2:], buf[2][:]) - copy(out[dstEvery*3:], buf[3][:]) - out = out[bufoff:] - decoded += bufoff * 4 - // There must at least be 3 buffers left. - if len(out) < dstEvery*3 { - d.bufs.Put(buf) - return nil, errors.New("corruption detected: stream overrun 2") - } - } - if off > 0 { - ioff := int(off) - if len(out) < dstEvery*3+ioff { - d.bufs.Put(buf) - return nil, errors.New("corruption detected: stream overrun 3") - } - copy(out, buf[0][:off]) - copy(out[dstEvery:], buf[1][:off]) - copy(out[dstEvery*2:], buf[2][:off]) - copy(out[dstEvery*3:], buf[3][:off]) - decoded += int(off) * 4 - out = out[off:] + decoded = ctx.decoded + out = out[decoded/4:] } // Decode remaining. @@ -150,7 +120,6 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { for bitsLeft > 0 { br.fill() if offset >= endsAt { - d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 4") } @@ -164,7 +133,6 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { offset++ } if offset != endsAt { - d.bufs.Put(buf) return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt) } decoded += offset - dstEvery*i @@ -173,7 +141,6 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { return nil, err } } - d.bufs.Put(buf) if dstSize != decoded { return nil, errors.New("corruption detected: short output block") } diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s index 2edad3ea5..06287f568 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s @@ -1,506 +1,662 @@ -// +build !appengine -// +build gc -// +build !noasm - -#include "textflag.h" -#include "funcdata.h" -#include "go_asm.h" - -#ifdef GOAMD64_v4 -#ifndef GOAMD64_v3 -#define GOAMD64_v3 -#endif -#endif - -#define bufoff 256 // see decompress.go, we're using [4][256]byte table - -// func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, -// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool) -TEXT ·decompress4x_main_loop_x86(SB), NOSPLIT, $8 -#define off R8 -#define buffer DI -#define table SI - -#define br_bits_read R9 -#define br_value R10 -#define br_offset R11 -#define peek_bits R12 -#define exhausted DX - -#define br0 R13 -#define br1 R14 -#define br2 R15 -#define br3 BP - - MOVQ BP, 0(SP) - - XORQ exhausted, exhausted // exhausted = false - XORQ off, off // off = 0 - - MOVBQZX peekBits+32(FP), peek_bits - MOVQ buf+40(FP), buffer - MOVQ tbl+48(FP), table - - MOVQ pbr0+0(FP), br0 - MOVQ pbr1+8(FP), br1 - MOVQ pbr2+16(FP), br2 - MOVQ pbr3+24(FP), br3 - +// Code generated by command: go run gen.go -out ../decompress_amd64.s -pkg=huff0. DO NOT EDIT. + +//go:build amd64 && !appengine && !noasm && gc +// +build amd64,!appengine,!noasm,gc + +// func decompress4x_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_main_loop_amd64(SB), $8-8 + XORQ DX, DX + + // Preload values + MOVQ ctx+0(FP), AX + MOVBQZX 32(AX), SI + MOVQ 40(AX), DI + MOVQ DI, BX + MOVQ 72(AX), CX + MOVQ CX, (SP) + MOVQ 48(AX), R8 + MOVQ 56(AX), R9 + MOVQ (AX), R10 + MOVQ 8(AX), R11 + MOVQ 16(AX), R12 + MOVQ 24(AX), R13 + + // Main loop main_loop: - - // const stream = 0 - // br0.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br0), br_bits_read - MOVQ bitReaderShifted_value(br0), br_value - MOVQ bitReaderShifted_off(br0), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill0 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br0), AX + MOVQ BX, DI + CMPQ DI, (SP) + SETGE DL + + // br0.fillFast32() + MOVQ 32(R10), R14 + MOVBQZX 40(R10), R15 + CMPQ R15, $0x20 + JBE skip_fill0 + MOVQ 24(R10), AX + SUBQ $0x20, R15 + SUBQ $0x04, AX + MOVQ (R10), BP // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) - -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX - -#endif - - ORQ AX, br_value + MOVL (AX)(BP*1), BP + MOVQ R15, CX + SHLQ CL, BP + MOVQ AX, 24(R10) + ORQ BP, R14 // exhausted = exhausted || (br0.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH + CMPQ AX, $0x04 + SETLT AL + ORB AL, DL - // } skip_fill0: - // val0 := br0.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ R14, BP + MOVQ SI, CX + SHRQ CL, BP // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br0.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n + MOVW (R9)(BP*2), CX -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n + // br0.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R14 + ADDB CL, R15 -#endif - - ADDQ CX, br_bits_read // bits_read += n - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else // val1 := br0.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ SI, CX + MOVQ R14, BP + SHRQ CL, BP // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 + MOVW (R9)(BP*2), CX // br0.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n + MOVB CH, AH + SHLQ CL, R14 + ADDB CL, R15 // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 0(buffer)(off*1) + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVW AX, (DI) // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br0) - MOVQ br_value, bitReaderShifted_value(br0) - MOVQ br_offset, bitReaderShifted_off(br0) - - // const stream = 1 - // br1.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br1), br_bits_read - MOVQ bitReaderShifted_value(br1), br_value - MOVQ bitReaderShifted_off(br1), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill1 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br1), AX + MOVQ R14, 32(R10) + MOVB R15, 40(R10) + ADDQ R8, DI + + // br1.fillFast32() + MOVQ 32(R11), R14 + MOVBQZX 40(R11), R15 + CMPQ R15, $0x20 + JBE skip_fill1 + MOVQ 24(R11), AX + SUBQ $0x20, R15 + SUBQ $0x04, AX + MOVQ (R11), BP // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) - -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX - -#endif - - ORQ AX, br_value + MOVL (AX)(BP*1), BP + MOVQ R15, CX + SHLQ CL, BP + MOVQ AX, 24(R11) + ORQ BP, R14 // exhausted = exhausted || (br1.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH + CMPQ AX, $0x04 + SETLT AL + ORB AL, DL - // } skip_fill1: - // val0 := br1.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ R14, BP + MOVQ SI, CX + SHRQ CL, BP // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br1.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n + MOVW (R9)(BP*2), CX -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n + // br1.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R14 + ADDB CL, R15 -#endif - - ADDQ CX, br_bits_read // bits_read += n - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else // val1 := br1.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ SI, CX + MOVQ R14, BP + SHRQ CL, BP // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 + MOVW (R9)(BP*2), CX // br1.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n + MOVB CH, AH + SHLQ CL, R14 + ADDB CL, R15 // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 256(buffer)(off*1) + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVW AX, (DI) // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br1) - MOVQ br_value, bitReaderShifted_value(br1) - MOVQ br_offset, bitReaderShifted_off(br1) - - // const stream = 2 - // br2.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br2), br_bits_read - MOVQ bitReaderShifted_value(br2), br_value - MOVQ bitReaderShifted_off(br2), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill2 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br2), AX + MOVQ R14, 32(R11) + MOVB R15, 40(R11) + ADDQ R8, DI + + // br2.fillFast32() + MOVQ 32(R12), R14 + MOVBQZX 40(R12), R15 + CMPQ R15, $0x20 + JBE skip_fill2 + MOVQ 24(R12), AX + SUBQ $0x20, R15 + SUBQ $0x04, AX + MOVQ (R12), BP // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) - -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX - -#endif - - ORQ AX, br_value + MOVL (AX)(BP*1), BP + MOVQ R15, CX + SHLQ CL, BP + MOVQ AX, 24(R12) + ORQ BP, R14 // exhausted = exhausted || (br2.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH + CMPQ AX, $0x04 + SETLT AL + ORB AL, DL - // } skip_fill2: - // val0 := br2.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ R14, BP + MOVQ SI, CX + SHRQ CL, BP // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 + MOVW (R9)(BP*2), CX - // br2.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) + // br2.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R14 + ADDB CL, R15 -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else // val1 := br2.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ SI, CX + MOVQ R14, BP + SHRQ CL, BP // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 + MOVW (R9)(BP*2), CX // br2.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n + MOVB CH, AH + SHLQ CL, R14 + ADDB CL, R15 // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 512(buffer)(off*1) + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVW AX, (DI) // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br2) - MOVQ br_value, bitReaderShifted_value(br2) - MOVQ br_offset, bitReaderShifted_off(br2) - - // const stream = 3 - // br3.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br3), br_bits_read - MOVQ bitReaderShifted_value(br3), br_value - MOVQ bitReaderShifted_off(br3), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill3 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br3), AX + MOVQ R14, 32(R12) + MOVB R15, 40(R12) + ADDQ R8, DI + + // br3.fillFast32() + MOVQ 32(R13), R14 + MOVBQZX 40(R13), R15 + CMPQ R15, $0x20 + JBE skip_fill3 + MOVQ 24(R13), AX + SUBQ $0x20, R15 + SUBQ $0x04, AX + MOVQ (R13), BP // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) - -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX - -#endif - - ORQ AX, br_value + MOVL (AX)(BP*1), BP + MOVQ R15, CX + SHLQ CL, BP + MOVQ AX, 24(R13) + ORQ BP, R14 // exhausted = exhausted || (br3.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH + CMPQ AX, $0x04 + SETLT AL + ORB AL, DL - // } skip_fill3: - // val0 := br3.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ R14, BP + MOVQ SI, CX + SHRQ CL, BP // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 + MOVW (R9)(BP*2), CX - // br3.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) + // br3.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R14 + ADDB CL, R15 -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n + // val1 := br3.peekTopBits(peekBits) + MOVQ SI, CX + MOVQ R14, BP + SHRQ CL, BP -#endif + // v1 := table[val1&mask] + MOVW (R9)(BP*2), CX - ADDQ CX, br_bits_read // bits_read += n + // br3.advance(uint8(v1.entry)) + MOVB CH, AH + SHLQ CL, R14 + ADDB CL, R15 -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVW AX, (DI) -#else - // val1 := br3.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask + // update the bitrader reader structure + MOVQ R14, 32(R13) + MOVB R15, 40(R13) + ADDQ $0x02, BX + TESTB DL, DL + JZ main_loop + MOVQ ctx+0(FP), AX + MOVQ 40(AX), CX + MOVQ BX, DX + SUBQ CX, DX + SHLQ $0x02, DX + MOVQ DX, 64(AX) + RET -#endif +// func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_8b_main_loop_amd64(SB), $16-8 + XORQ DX, DX + + // Preload values + MOVQ ctx+0(FP), CX + MOVBQZX 32(CX), BX + MOVQ 40(CX), SI + MOVQ SI, (SP) + MOVQ 72(CX), DX + MOVQ DX, 8(SP) + MOVQ 48(CX), DI + MOVQ 56(CX), R8 + MOVQ (CX), R9 + MOVQ 8(CX), R10 + MOVQ 16(CX), R11 + MOVQ 24(CX), R12 + + // Main loop +main_loop: + MOVQ (SP), SI + CMPQ SI, 8(SP) + SETGE DL + + // br1000.fillFast32() + MOVQ 32(R9), R13 + MOVBQZX 40(R9), R14 + CMPQ R14, $0x20 + JBE skip_fill1000 + MOVQ 24(R9), R15 + SUBQ $0x20, R14 + SUBQ $0x04, R15 + MOVQ (R9), BP - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVL (R15)(BP*1), BP + MOVQ R14, CX + SHLQ CL, BP + MOVQ R15, 24(R9) + ORQ BP, R13 + + // exhausted = exhausted || (br1000.off < 4) + CMPQ R15, $0x04 + SETLT AL + ORB AL, DL + +skip_fill1000: + // val0 := br0.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 - // br3.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) + // v0 := table[val0&mask] + MOVW (R8)(R15*2), CX -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n + // br0.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R13 + ADDB CL, R14 -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n + // val1 := br0.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 + + // v1 := table[val0&mask] + MOVW (R8)(R15*2), CX + + // br0.advance(uint8(v1.entry) + MOVB CH, AH + SHLQ CL, R13 + ADDB CL, R14 + BSWAPL AX + + // val2 := br0.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 + + // v2 := table[val0&mask] + MOVW (R8)(R15*2), CX + + // br0.advance(uint8(v2.entry) + MOVB CH, AH + SHLQ CL, R13 + ADDB CL, R14 + + // val3 := br0.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 + + // v3 := table[val0&mask] + MOVW (R8)(R15*2), CX + + // br0.advance(uint8(v3.entry) + MOVB CH, AL + SHLQ CL, R13 + ADDB CL, R14 + BSWAPL AX + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVL AX, (SI) + + // update the bitreader reader structure + MOVQ R13, 32(R9) + MOVB R14, 40(R9) + ADDQ DI, SI + + // br1001.fillFast32() + MOVQ 32(R10), R13 + MOVBQZX 40(R10), R14 + CMPQ R14, $0x20 + JBE skip_fill1001 + MOVQ 24(R10), R15 + SUBQ $0x20, R14 + SUBQ $0x04, R15 + MOVQ (R10), BP -#endif + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVL (R15)(BP*1), BP + MOVQ R14, CX + SHLQ CL, BP + MOVQ R15, 24(R10) + ORQ BP, R13 + + // exhausted = exhausted || (br1001.off < 4) + CMPQ R15, $0x04 + SETLT AL + ORB AL, DL + +skip_fill1001: + // val0 := br1.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 - ADDQ CX, br_bits_read // bits_read += n + // v0 := table[val0&mask] + MOVW (R8)(R15*2), CX - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 768(buffer)(off*1) + // br1.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R13 + ADDB CL, R14 - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br3) - MOVQ br_value, bitReaderShifted_value(br3) - MOVQ br_offset, bitReaderShifted_off(br3) + // val1 := br1.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 + + // v1 := table[val0&mask] + MOVW (R8)(R15*2), CX + + // br1.advance(uint8(v1.entry) + MOVB CH, AH + SHLQ CL, R13 + ADDB CL, R14 + BSWAPL AX + + // val2 := br1.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 + + // v2 := table[val0&mask] + MOVW (R8)(R15*2), CX + + // br1.advance(uint8(v2.entry) + MOVB CH, AH + SHLQ CL, R13 + ADDB CL, R14 + + // val3 := br1.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 + + // v3 := table[val0&mask] + MOVW (R8)(R15*2), CX + + // br1.advance(uint8(v3.entry) + MOVB CH, AL + SHLQ CL, R13 + ADDB CL, R14 + BSWAPL AX + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVL AX, (SI) + + // update the bitreader reader structure + MOVQ R13, 32(R10) + MOVB R14, 40(R10) + ADDQ DI, SI + + // br1002.fillFast32() + MOVQ 32(R11), R13 + MOVBQZX 40(R11), R14 + CMPQ R14, $0x20 + JBE skip_fill1002 + MOVQ 24(R11), R15 + SUBQ $0x20, R14 + SUBQ $0x04, R15 + MOVQ (R11), BP - ADDQ $2, off // off += 2 + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVL (R15)(BP*1), BP + MOVQ R14, CX + SHLQ CL, BP + MOVQ R15, 24(R11) + ORQ BP, R13 + + // exhausted = exhausted || (br1002.off < 4) + CMPQ R15, $0x04 + SETLT AL + ORB AL, DL + +skip_fill1002: + // val0 := br2.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 - TESTB DH, DH // any br[i].ofs < 4? - JNZ end + // v0 := table[val0&mask] + MOVW (R8)(R15*2), CX - CMPQ off, $bufoff - JL main_loop + // br2.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R13 + ADDB CL, R14 -end: - MOVQ 0(SP), BP + // val1 := br2.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 + + // v1 := table[val0&mask] + MOVW (R8)(R15*2), CX + + // br2.advance(uint8(v1.entry) + MOVB CH, AH + SHLQ CL, R13 + ADDB CL, R14 + BSWAPL AX + + // val2 := br2.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 + + // v2 := table[val0&mask] + MOVW (R8)(R15*2), CX + + // br2.advance(uint8(v2.entry) + MOVB CH, AH + SHLQ CL, R13 + ADDB CL, R14 + + // val3 := br2.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 + + // v3 := table[val0&mask] + MOVW (R8)(R15*2), CX + + // br2.advance(uint8(v3.entry) + MOVB CH, AL + SHLQ CL, R13 + ADDB CL, R14 + BSWAPL AX + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVL AX, (SI) + + // update the bitreader reader structure + MOVQ R13, 32(R11) + MOVB R14, 40(R11) + ADDQ DI, SI + + // br1003.fillFast32() + MOVQ 32(R12), R13 + MOVBQZX 40(R12), R14 + CMPQ R14, $0x20 + JBE skip_fill1003 + MOVQ 24(R12), R15 + SUBQ $0x20, R14 + SUBQ $0x04, R15 + MOVQ (R12), BP - MOVB off, ret+56(FP) - RET + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVL (R15)(BP*1), BP + MOVQ R14, CX + SHLQ CL, BP + MOVQ R15, 24(R12) + ORQ BP, R13 + + // exhausted = exhausted || (br1003.off < 4) + CMPQ R15, $0x04 + SETLT AL + ORB AL, DL + +skip_fill1003: + // val0 := br3.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 -#undef off -#undef buffer -#undef table + // v0 := table[val0&mask] + MOVW (R8)(R15*2), CX -#undef br_bits_read -#undef br_value -#undef br_offset -#undef peek_bits -#undef exhausted + // br3.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R13 + ADDB CL, R14 -#undef br0 -#undef br1 -#undef br2 -#undef br3 + // val1 := br3.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 + + // v1 := table[val0&mask] + MOVW (R8)(R15*2), CX + + // br3.advance(uint8(v1.entry) + MOVB CH, AH + SHLQ CL, R13 + ADDB CL, R14 + BSWAPL AX + + // val2 := br3.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 + + // v2 := table[val0&mask] + MOVW (R8)(R15*2), CX + + // br3.advance(uint8(v2.entry) + MOVB CH, AH + SHLQ CL, R13 + ADDB CL, R14 + + // val3 := br3.peekTopBits(peekBits) + MOVQ R13, R15 + MOVQ BX, CX + SHRQ CL, R15 + + // v3 := table[val0&mask] + MOVW (R8)(R15*2), CX + + // br3.advance(uint8(v3.entry) + MOVB CH, AL + SHLQ CL, R13 + ADDB CL, R14 + BSWAPL AX + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVL AX, (SI) + + // update the bitreader reader structure + MOVQ R13, 32(R12) + MOVB R14, 40(R12) + ADDQ $0x04, (SP) + TESTB DL, DL + JZ main_loop + MOVQ ctx+0(FP), AX + MOVQ 40(AX), CX + MOVQ (SP), DX + SUBQ CX, DX + SHLQ $0x02, DX + MOVQ DX, 64(AX) + RET diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s.in b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s.in deleted file mode 100644 index 330d86ae1..000000000 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s.in +++ /dev/null @@ -1,195 +0,0 @@ -// +build !appengine -// +build gc -// +build !noasm - -#include "textflag.h" -#include "funcdata.h" -#include "go_asm.h" - -#ifdef GOAMD64_v4 -#ifndef GOAMD64_v3 -#define GOAMD64_v3 -#endif -#endif - -#define bufoff 256 // see decompress.go, we're using [4][256]byte table - -//func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, -// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool) -TEXT ·decompress4x_main_loop_x86(SB), NOSPLIT, $8 -#define off R8 -#define buffer DI -#define table SI - -#define br_bits_read R9 -#define br_value R10 -#define br_offset R11 -#define peek_bits R12 -#define exhausted DX - -#define br0 R13 -#define br1 R14 -#define br2 R15 -#define br3 BP - - MOVQ BP, 0(SP) - - XORQ exhausted, exhausted // exhausted = false - XORQ off, off // off = 0 - - MOVBQZX peekBits+32(FP), peek_bits - MOVQ buf+40(FP), buffer - MOVQ tbl+48(FP), table - - MOVQ pbr0+0(FP), br0 - MOVQ pbr1+8(FP), br1 - MOVQ pbr2+16(FP), br2 - MOVQ pbr3+24(FP), br3 - -main_loop: -{{ define "decode_2_values_x86" }} - // const stream = {{ var "id" }} - // br{{ var "id"}}.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br{{ var "id" }}), br_bits_read - MOVQ bitReaderShifted_value(br{{ var "id" }}), br_value - MOVQ bitReaderShifted_off(br{{ var "id" }}), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill{{ var "id" }} - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br{{ var "id" }}), AX - - // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX -#endif - - ORQ AX, br_value - - // exhausted = exhausted || (br{{ var "id"}}.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - // } -skip_fill{{ var "id" }}: - - // val0 := br{{ var "id"}}.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask -#endif - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br{{ var "id"}}.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n -#endif - - ADDQ CX, br_bits_read // bits_read += n - - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask -#else - // val1 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask -#endif - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br{{ var "id"}}.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n -#endif - - ADDQ CX, br_bits_read // bits_read += n - - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, {{ var "bufofs" }}(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br{{ var "id" }}) - MOVQ br_value, bitReaderShifted_value(br{{ var "id" }}) - MOVQ br_offset, bitReaderShifted_off(br{{ var "id" }}) -{{ end }} - - {{ set "id" "0" }} - {{ set "ofs" "0" }} - {{ set "bufofs" "0" }} {{/* id * bufoff */}} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "1" }} - {{ set "ofs" "8" }} - {{ set "bufofs" "256" }} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "2" }} - {{ set "ofs" "16" }} - {{ set "bufofs" "512" }} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "3" }} - {{ set "ofs" "24" }} - {{ set "bufofs" "768" }} - {{ template "decode_2_values_x86" . }} - - ADDQ $2, off // off += 2 - - TESTB DH, DH // any br[i].ofs < 4? - JNZ end - - CMPQ off, $bufoff - JL main_loop -end: - MOVQ 0(SP), BP - - MOVB off, ret+56(FP) - RET -#undef off -#undef buffer -#undef table - -#undef br_bits_read -#undef br_value -#undef br_offset -#undef peek_bits -#undef exhausted - -#undef br0 -#undef br1 -#undef br2 -#undef br3 diff --git a/vendor/github.com/klauspost/compress/zstd/decoder.go b/vendor/github.com/klauspost/compress/zstd/decoder.go index c65ea9795..36119f385 100644 --- a/vendor/github.com/klauspost/compress/zstd/decoder.go +++ b/vendor/github.com/klauspost/compress/zstd/decoder.go @@ -439,7 +439,7 @@ func (d *Decoder) nextBlock(blocking bool) (ok bool) { println("got", len(d.current.b), "bytes, error:", d.current.err, "data crc:", tmp) } - if len(next.b) > 0 { + if !d.o.ignoreChecksum && len(next.b) > 0 { n, err := d.current.crc.Write(next.b) if err == nil { if n != len(next.b) { @@ -451,7 +451,7 @@ func (d *Decoder) nextBlock(blocking bool) (ok bool) { got := d.current.crc.Sum64() var tmp [4]byte binary.LittleEndian.PutUint32(tmp[:], uint32(got)) - if !bytes.Equal(tmp[:], next.d.checkCRC) && !ignoreCRC { + if !d.o.ignoreChecksum && !bytes.Equal(tmp[:], next.d.checkCRC) { if debugDecoder { println("CRC Check Failed:", tmp[:], " (got) !=", next.d.checkCRC, "(on stream)") } @@ -535,9 +535,15 @@ func (d *Decoder) nextBlockSync() (ok bool) { // Update/Check CRC if d.frame.HasCheckSum { - d.frame.crc.Write(d.current.b) + if !d.o.ignoreChecksum { + d.frame.crc.Write(d.current.b) + } if d.current.d.Last { - d.current.err = d.frame.checkCRC() + if !d.o.ignoreChecksum { + d.current.err = d.frame.checkCRC() + } else { + d.current.err = d.frame.consumeCRC() + } if d.current.err != nil { println("CRC error:", d.current.err) return false diff --git a/vendor/github.com/klauspost/compress/zstd/decoder_options.go b/vendor/github.com/klauspost/compress/zstd/decoder_options.go index fc52ebc40..c70e6fa0f 100644 --- a/vendor/github.com/klauspost/compress/zstd/decoder_options.go +++ b/vendor/github.com/klauspost/compress/zstd/decoder_options.go @@ -19,6 +19,7 @@ type decoderOptions struct { maxDecodedSize uint64 maxWindowSize uint64 dicts []dict + ignoreChecksum bool } func (o *decoderOptions) setDefault() { @@ -112,3 +113,11 @@ func WithDecoderMaxWindow(size uint64) DOption { return nil } } + +// IgnoreChecksum allows to forcibly ignore checksum checking. +func IgnoreChecksum(b bool) DOption { + return func(o *decoderOptions) error { + o.ignoreChecksum = b + return nil + } +} diff --git a/vendor/github.com/klauspost/compress/zstd/framedec.go b/vendor/github.com/klauspost/compress/zstd/framedec.go index 509d5cece..3ff109cce 100644 --- a/vendor/github.com/klauspost/compress/zstd/framedec.go +++ b/vendor/github.com/klauspost/compress/zstd/framedec.go @@ -290,13 +290,6 @@ func (d *frameDec) checkCRC() error { if !d.HasCheckSum { return nil } - var tmp [4]byte - got := d.crc.Sum64() - // Flip to match file order. - tmp[0] = byte(got >> 0) - tmp[1] = byte(got >> 8) - tmp[2] = byte(got >> 16) - tmp[3] = byte(got >> 24) // We can overwrite upper tmp now want, err := d.rawInput.readSmall(4) @@ -305,7 +298,19 @@ func (d *frameDec) checkCRC() error { return err } - if !bytes.Equal(tmp[:], want) && !ignoreCRC { + if d.o.ignoreChecksum { + return nil + } + + var tmp [4]byte + got := d.crc.Sum64() + // Flip to match file order. + tmp[0] = byte(got >> 0) + tmp[1] = byte(got >> 8) + tmp[2] = byte(got >> 16) + tmp[3] = byte(got >> 24) + + if !bytes.Equal(tmp[:], want) { if debugDecoder { println("CRC Check Failed:", tmp[:], "!=", want) } @@ -317,6 +322,19 @@ func (d *frameDec) checkCRC() error { return nil } +// consumeCRC reads the checksum data if the frame has one. +func (d *frameDec) consumeCRC() error { + if d.HasCheckSum { + _, err := d.rawInput.readSmall(4) + if err != nil { + println("CRC missing?", err) + return err + } + } + + return nil +} + // runDecoder will create a sync decoder that will decode a block of data. func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { saved := d.history.b @@ -373,13 +391,17 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { if d.FrameContentSize != fcsUnknown && uint64(len(d.history.b)-crcStart) != d.FrameContentSize { err = ErrFrameSizeMismatch } else if d.HasCheckSum { - var n int - n, err = d.crc.Write(dst[crcStart:]) - if err == nil { - if n != len(dst)-crcStart { - err = io.ErrShortWrite - } else { - err = d.checkCRC() + if d.o.ignoreChecksum { + err = d.consumeCRC() + } else { + var n int + n, err = d.crc.Write(dst[crcStart:]) + if err == nil { + if n != len(dst)-crcStart { + err = io.ErrShortWrite + } else { + err = d.checkCRC() + } } } } diff --git a/vendor/github.com/klauspost/compress/zstd/fuzz.go b/vendor/github.com/klauspost/compress/zstd/fuzz.go deleted file mode 100644 index 7f2210e05..000000000 --- a/vendor/github.com/klauspost/compress/zstd/fuzz.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build ignorecrc -// +build ignorecrc - -// Copyright 2019+ Klaus Post. All rights reserved. -// License information can be found in the LICENSE file. -// Based on work by Yann Collet, released under BSD License. - -package zstd - -// ignoreCRC can be used for fuzz testing to ignore CRC values... -const ignoreCRC = true diff --git a/vendor/github.com/klauspost/compress/zstd/fuzz_none.go b/vendor/github.com/klauspost/compress/zstd/fuzz_none.go deleted file mode 100644 index 6811c68a8..000000000 --- a/vendor/github.com/klauspost/compress/zstd/fuzz_none.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build !ignorecrc -// +build !ignorecrc - -// Copyright 2019+ Klaus Post. All rights reserved. -// License information can be found in the LICENSE file. -// Based on work by Yann Collet, released under BSD License. - -package zstd - -// ignoreCRC can be used for fuzz testing to ignore CRC values... -const ignoreCRC = false diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s index 01cc23fa8..2585b2e98 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s @@ -1326,30 +1326,30 @@ copy_match: JA copy_overlapping_match // Copy non-overlapping match - XORQ R12, R12 + ADDQ R13, DI + MOVQ BX, R12 + ADDQ R13, BX copy_2: - MOVUPS (R11)(R12*1), X0 - MOVUPS X0, (BX)(R12*1) + MOVUPS (R11), X0 + MOVUPS X0, (R12) + ADDQ $0x10, R11 ADDQ $0x10, R12 - CMPQ R12, R13 - JB copy_2 - ADDQ R13, BX - ADDQ R13, DI + SUBQ $0x10, R13 + JHI copy_2 JMP handle_loop // Copy overlapping match copy_overlapping_match: - XORQ R12, R12 + ADDQ R13, DI copy_slow_3: - MOVB (R11)(R12*1), R14 - MOVB R14, (BX)(R12*1) - INCQ R12 - CMPQ R12, R13 - JB copy_slow_3 - ADDQ R13, BX - ADDQ R13, DI + MOVB (R11), R12 + MOVB R12, (BX) + INCQ R11 + INCQ BX + DECQ R13 + JNZ copy_slow_3 handle_loop: ADDQ $0x18, AX @@ -1826,30 +1826,30 @@ copy_match: JA copy_overlapping_match // Copy non-overlapping match - XORQ CX, CX + ADDQ R13, R12 + MOVQ R10, CX + ADDQ R13, R10 copy_2: - MOVUPS (AX)(CX*1), X0 - MOVUPS X0, (R10)(CX*1) + MOVUPS (AX), X0 + MOVUPS X0, (CX) + ADDQ $0x10, AX ADDQ $0x10, CX - CMPQ CX, R13 - JB copy_2 - ADDQ R13, R10 - ADDQ R13, R12 + SUBQ $0x10, R13 + JHI copy_2 JMP handle_loop // Copy overlapping match copy_overlapping_match: - XORQ CX, CX + ADDQ R13, R12 copy_slow_3: - MOVB (AX)(CX*1), R14 - MOVB R14, (R10)(CX*1) - INCQ CX - CMPQ CX, R13 - JB copy_slow_3 - ADDQ R13, R10 - ADDQ R13, R12 + MOVB (AX), CL + MOVB CL, (R10) + INCQ AX + INCQ R10 + DECQ R13 + JNZ copy_slow_3 handle_loop: MOVQ ctx+16(FP), AX @@ -2333,30 +2333,30 @@ copy_match: JA copy_overlapping_match // Copy non-overlapping match - XORQ R12, R12 + ADDQ R13, R11 + MOVQ R9, R12 + ADDQ R13, R9 copy_2: - MOVUPS (CX)(R12*1), X0 - MOVUPS X0, (R9)(R12*1) + MOVUPS (CX), X0 + MOVUPS X0, (R12) + ADDQ $0x10, CX ADDQ $0x10, R12 - CMPQ R12, R13 - JB copy_2 - ADDQ R13, R9 - ADDQ R13, R11 + SUBQ $0x10, R13 + JHI copy_2 JMP handle_loop // Copy overlapping match copy_overlapping_match: - XORQ R12, R12 + ADDQ R13, R11 copy_slow_3: - MOVB (CX)(R12*1), R14 - MOVB R14, (R9)(R12*1) - INCQ R12 - CMPQ R12, R13 - JB copy_slow_3 - ADDQ R13, R9 - ADDQ R13, R11 + MOVB (CX), R12 + MOVB R12, (R9) + INCQ CX + INCQ R9 + DECQ R13 + JNZ copy_slow_3 handle_loop: MOVQ ctx+16(FP), CX @@ -2862,6 +2862,7 @@ copy_match: JA copy_overlapping_match // Copy non-overlapping match + ADDQ R13, R12 XORQ CX, CX TESTQ $0x00000001, R13 JZ copy_2_word @@ -2900,21 +2901,19 @@ copy_2_test: CMPQ CX, R13 JB copy_2 ADDQ R13, R10 - ADDQ R13, R12 JMP handle_loop // Copy overlapping match copy_overlapping_match: - XORQ CX, CX + ADDQ R13, R12 copy_slow_3: - MOVB (AX)(CX*1), R14 - MOVB R14, (R10)(CX*1) - INCQ CX - CMPQ CX, R13 - JB copy_slow_3 - ADDQ R13, R10 - ADDQ R13, R12 + MOVB (AX), CL + MOVB CL, (R10) + INCQ AX + INCQ R10 + DECQ R13 + JNZ copy_slow_3 handle_loop: MOVQ ctx+16(FP), AX @@ -3398,6 +3397,7 @@ copy_match: JA copy_overlapping_match // Copy non-overlapping match + ADDQ R13, R11 XORQ R12, R12 TESTQ $0x00000001, R13 JZ copy_2_word @@ -3436,21 +3436,19 @@ copy_2_test: CMPQ R12, R13 JB copy_2 ADDQ R13, R9 - ADDQ R13, R11 JMP handle_loop // Copy overlapping match copy_overlapping_match: - XORQ R12, R12 + ADDQ R13, R11 copy_slow_3: - MOVB (CX)(R12*1), R14 - MOVB R14, (R9)(R12*1) - INCQ R12 - CMPQ R12, R13 - JB copy_slow_3 - ADDQ R13, R9 - ADDQ R13, R11 + MOVB (CX), R12 + MOVB R12, (R9) + INCQ CX + INCQ R9 + DECQ R13 + JNZ copy_slow_3 handle_loop: MOVQ ctx+16(FP), CX diff --git a/vendor/modules.txt b/vendor/modules.txt index 51e0d5f4a..d2d7a6df9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -155,7 +155,7 @@ github.com/containers/common/version # github.com/containers/conmon v2.0.20+incompatible ## explicit github.com/containers/conmon/runner/config -# github.com/containers/image/v5 v5.21.1 +# github.com/containers/image/v5 v5.21.2-0.20220511203756-fe4fd4ed8be4 ## explicit github.com/containers/image/v5/copy github.com/containers/image/v5/directory @@ -235,7 +235,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.40.2 +# github.com/containers/storage v1.41.1-0.20220511210719-cacc3325a9c8 ## explicit github.com/containers/storage github.com/containers/storage/drivers @@ -450,7 +450,7 @@ github.com/jinzhu/copier # github.com/json-iterator/go v1.1.12 ## explicit github.com/json-iterator/go -# github.com/klauspost/compress v1.15.2 +# github.com/klauspost/compress v1.15.4 github.com/klauspost/compress github.com/klauspost/compress/flate github.com/klauspost/compress/fse |