diff options
559 files changed, 6837 insertions, 4025 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index c14e38771..2badd7b5a 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -77,79 +77,11 @@ gcp_credentials: ENCRYPTED[a28959877b2c9c36f151781b0a05407218cda646c7d047fc556e4 aws_credentials: ENCRYPTED[4ca070bffe28eb9b27d63c568b52970dd46f119c3a83b8e443241e895dbf1737580b4d84eed27a311a2b74287ef9f79f] -# Attempt to prevent flakes by confirming all required external/3rd-party -# services are available and functional. -ext_svc_check_task: - alias: 'ext_svc_check' # int. ref. name - required for depends_on reference - name: "Ext. services" # Displayed Title - has no other significance - # Don't create this task for new tags so release process is more reliable - # Docs: ./contrib/cirrus/CIModes.md - only_if: $CIRRUS_TAG == '' - # Default/small container image to execute tasks with - container: &smallcontainer - image: ${CTR_FQIN} - # Resources are limited across ALL currently executing tasks - # ref: https://cirrus-ci.org/guide/linux/#linux-containers - cpu: 2 - memory: 2 - env: - TEST_FLAVOR: ext_svc - CTR_FQIN: ${FEDORA_CONTAINER_FQIN} - # NOTE: The default way Cirrus-CI clones is *NOT* compatible with - # environment expectations in contrib/cirrus/lib.sh. Specifically - # the 'origin' remote must be defined, and all remote branches/tags - # must be available for reference from CI scripts. - clone_script: &full_clone | - cd / - rm -rf $CIRRUS_WORKING_DIR - mkdir -p $CIRRUS_WORKING_DIR - git clone --recursive --branch=$DEST_BRANCH https://x-access-token:${CIRRUS_REPO_CLONE_TOKEN}@github.com/${CIRRUS_REPO_FULL_NAME}.git $CIRRUS_WORKING_DIR - cd $CIRRUS_WORKING_DIR - git remote update origin - if [[ -n "$CIRRUS_PR" ]]; then # running for a PR - git fetch origin pull/$CIRRUS_PR/head:pull/$CIRRUS_PR - git checkout pull/$CIRRUS_PR - else - git reset --hard $CIRRUS_CHANGE_IN_REPO - fi - # Some test operations & checks require a git "identity" - _gc='git config --file /root/.gitconfig' - $_gc user.email "TMcTestFace@example.com" - $_gc user.name "Testy McTestface" - - setup_script: &setup '$GOSRC/$SCRIPT_BASE/setup_environment.sh' - main_script: &main '/usr/bin/time --verbose --output="$STATS_LOGFILE" $GOSRC/$SCRIPT_BASE/runner.sh' - always: &runner_stats - runner_stats_artifacts: - path: ./*-${STATS_LOGFILE_SFX} - type: text/plain - - -# Execute some quick checks to confirm this YAML file and all -# automation-related shell scripts are sane. -automation_task: - alias: 'automation' - name: "Check Automation" - # This task is not needed for branches, tags, or cron runs. - # Docs: ./contrib/cirrus/CIModes.md - only_if: &is_pr "$CIRRUS_PR != ''" - container: *smallcontainer - env: - TEST_FLAVOR: automation - CTR_FQIN: ${FEDORA_CONTAINER_FQIN} - TEST_ENVIRON: container - clone_script: *full_clone - setup_script: *setup - main_script: *main - always: *runner_stats - - -# N/B: The two following tasks are critical. They build all binaries for all supported -# OS platforms and versions on x86_64 and aarch64. 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. +# N/B: This matrix of build tasks are critical to CI, along with the following +# aarch64 task. They build binaries for all CI platforms, and versions. On +# success, the contents of the repository are preserved as an artifact for +# consumption by most subsequent CI tasks. This saves about 3-5 minutes of +# otherwise duplicative effort in most tasks. build_task: alias: 'build' name: 'Build for $DISTRO_NV' @@ -175,10 +107,10 @@ build_task: # ID for re-use of build output CI_DESIRED_RUNTIME: crun #- env: &priorfedora_envvars - #DISTRO_NV: ${PRIOR_FEDORA_NAME} - #VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME} - #CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN} - #CI_DESIRED_RUNTIME: crun + # DISTRO_NV: ${PRIOR_FEDORA_NAME} + # VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME} + # CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN} + # CI_DESIRED_RUNTIME: crun - env: &ubuntu_envvars DISTRO_NV: ${UBUNTU_NAME} VM_IMAGE_NAME: ${UBUNTU_CACHE_IMAGE_NAME} @@ -186,9 +118,38 @@ build_task: CI_DESIRED_RUNTIME: runc env: TEST_FLAVOR: build - clone_script: *full_clone - setup_script: *setup - main_script: *main + # NOTE: The default way Cirrus-CI clones is *NOT* compatible with + # environment expectations in contrib/cirrus/lib.sh. Specifically + # the 'origin' remote must be defined, and all remote branches/tags + # must be available for reference from CI scripts. + clone_script: &full_clone | + cd / + rm -rf $CIRRUS_WORKING_DIR + mkdir -p $CIRRUS_WORKING_DIR + git clone --recursive --branch=$DEST_BRANCH https://x-access-token:${CIRRUS_REPO_CLONE_TOKEN}@github.com/${CIRRUS_REPO_FULL_NAME}.git $CIRRUS_WORKING_DIR + cd $CIRRUS_WORKING_DIR + git remote update origin + if [[ -n "$CIRRUS_PR" ]]; then # running for a PR + git fetch origin pull/$CIRRUS_PR/head:pull/$CIRRUS_PR + git checkout pull/$CIRRUS_PR + else + git reset --hard $CIRRUS_CHANGE_IN_REPO + fi + # Some test operations & checks require a git "identity" + _gc='git config --file /root/.gitconfig' + $_gc user.email "TMcTestFace@example.com" + $_gc user.name "Testy McTestface" + # Attempt to prevent flakes by confirming basic environment expectations, + # network service connectivity and essential container image availability. + prebuild_script: &prebuild $SCRIPT_BASE/prebuild.sh + # Standard setup stage call, used by nearly every task in CI. + setup_script: &setup '$GOSRC/$SCRIPT_BASE/setup_environment.sh' + # Attempt to prevent flakes by confirming automation environment and + # all required external/3rd-party services are available and functional. + # Standard main execution stage call, used by nearly every task in CI. + main_script: &main '/usr/bin/time --verbose --output="$STATS_LOGFILE" $GOSRC/$SCRIPT_BASE/runner.sh' + # Attempt to catch code-quality and vendoring problems early. + postbuild_script: &postbuild $SCRIPT_BASE/postbuild.sh # 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 >- @@ -196,8 +157,10 @@ build_task: repo_artifacts: &repo_artifacts path: ./repo.tbz type: application/octet-stream - always: *runner_stats - + always: &runner_stats + runner_stats_artifacts: + path: ./*-${STATS_LOGFILE_SFX} + type: text/plain build_aarch64_task: alias: 'build_aarch64' @@ -218,7 +181,9 @@ build_aarch64_task: CI_DESIRED_RUNTIME: crun TEST_FLAVOR: build clone_script: *full_clone + prebuild_script: *prebuild setup_script: *setup + postbuild_script: *postbuild main_script: *main # 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. @@ -242,10 +207,8 @@ validate_task: # to nonsequential PR merging practices, will be caught on a future PR, # build or test task failures. # Docs: ./contrib/cirrus/CIModes.md - only_if: *is_pr + only_if: &is_pr "$CIRRUS_PR != ''" depends_on: - - ext_svc_check - - automation - build # golangci-lint is a very, very hungry beast. gce_instance: &bigvm @@ -281,8 +244,6 @@ validate_aarch64_task: # Docs: ./contrib/cirrus/CIModes.md only_if: *is_pr depends_on: - - ext_svc_check - - automation - build_aarch64 # golangci-lint is a very, very hungry beast. ec2_instance: *standard_build_ec2_aarch64 @@ -366,51 +327,6 @@ swagger_task: type: text/plain -# Check that all included go modules from other sources match -# what is expected in `vendor/modules.txt` vs `go.mod`. Also -# make sure that the generated bindings in pkg/bindings/... -# are in sync with the code. -consistency_task: - name: "Test Code Consistency" - alias: consistency - # Docs: ./contrib/cirrus/CIModes.md - only_if: *is_pr - depends_on: - - build - container: *smallcontainer - env: - <<: *stdenvars - TEST_FLAVOR: consistency - TEST_ENVIRON: container - CTR_FQIN: ${FEDORA_CONTAINER_FQIN} - clone_script: *get_gosrc - setup_script: *setup - main_script: *main - always: *runner_stats - - -# Check that all included go modules from other sources match -# what is expected in `vendor/modules.txt` vs `go.mod`. Also -# make sure that the generated bindings in pkg/bindings/... -# are in sync with the code. -consistency_aarch64_task: - name: "Test Code Consistency (aarch64)" - alias: consistency_aarch64 - # Docs: ./contrib/cirrus/CIModes.md - only_if: *is_pr - depends_on: - - build_aarch64 - ec2_instance: *standard_build_ec2_aarch64 - env: - <<: *stdenvars_aarch64 - TEST_FLAVOR: consistency - TEST_ENVIRON: container - clone_script: *get_gosrc_aarch64 - setup_script: *setup - main_script: *main - always: *runner_stats - - # There are several other important variations of podman which # must always build successfully. Most of them are handled in # this task, though a few need dedicated tasks which follow. @@ -470,6 +386,10 @@ osx_alt_build_task: - make podman-remote-release-darwin_amd64.zip GOARCH=amd64 build_arm64_script: - make podman-remote-release-darwin_arm64.zip GOARCH=arm64 + build_pkginstaller_script: + - cd contrib/pkginstaller + - make ARCH=amd64 NO_CODESIGN=1 pkginstaller + - make ARCH=aarch64 NO_CODESIGN=1 pkginstaller # 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 @@ -639,9 +559,9 @@ container_integration_test_task: CTR_FQIN: ${FEDORA_CONTAINER_FQIN} CI_DESIRED_RUNTIME: crun #- env: - #DISTRO_NV: ${PRIOR_FEDORA_NAME} - #VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME} - #CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN} + # DISTRO_NV: ${PRIOR_FEDORA_NAME} + # VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME} + # CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN} gce_instance: *standardvm timeout_in: 90m env: @@ -925,8 +845,6 @@ image_build_task: &image-build # this task to a specific Cirrus-Cron entry with this name. # Docs: ./contrib/cirrus/CIModes.md only_if: $CIRRUS_CRON == 'multiarch' - depends_on: - - ext_svc_check timeout_in: 120m # emulation is sssllllooooowwww gce_instance: <<: *standardvm @@ -1006,16 +924,12 @@ success_task: alias: success # N/B: ALL tasks must be listed here, minus their '_task' suffix. depends_on: - - ext_svc_check - - automation - build - build_aarch64 - validate - validate_aarch64 - bindings - swagger - - consistency - - consistency_aarch64 - alt_build - osx_alt_build - win_installer @@ -1040,7 +954,12 @@ success_task: - upgrade_test - image_build - meta - container: *smallcontainer + container: &smallcontainer + image: ${CTR_FQIN} + # Resources are limited across ALL currently executing tasks + # ref: https://cirrus-ci.org/guide/linux/#linux-containers + cpu: 2 + memory: 2 env: CTR_FQIN: ${FEDORA_CONTAINER_FQIN} TEST_ENVIRON: container @@ -1093,6 +1012,7 @@ artifacts_task: - $ARTCURL/OSX%20Cross/repo/repo.tbz - tar xjf repo.tbz - mv ./podman-remote-release-darwin_*.zip $CIRRUS_WORKING_DIR/ + - mv ./contrib/pkginstaller/out/podman-installer-macos-*.pkg $CIRRUS_WORKING_DIR/ always: contents_script: ls -la $CIRRUS_WORKING_DIR # Produce downloadable files and an automatic zip-file accessible diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 5946fa6a1..5c8cd9a37 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -61,7 +61,7 @@ Briefly describe the problem you are having in a few paragraphs. (paste your output here) ``` -**Package info (e.g. output of `rpm -q podman` or `apt list podman`):** +**Package info (e.g. output of `rpm -q podman` or `apt list podman` or `brew info podman`):** ``` (paste your output here) @@ -850,12 +850,20 @@ endif .PHONY: install.tools install.tools: .install.ginkgo .install.golangci-lint ## Install needed tools - make -C test/tools + $(MAKE) -C test/tools + +.PHONY: .install.goimports +.install.goimports: + $(MAKE) -C test/tools build/goimports .PHONY: .install.ginkgo .install.ginkgo: $(GO) install $(BUILDFLAGS) ./vendor/github.com/onsi/ginkgo/ginkgo +.PHONY: .install.gitvalidation +.install.gitvalidation: + $(MAKE) -C test/tools build/git-validation + .PHONY: .install.golangci-lint .install.golangci-lint: VERSION=1.46.2 ./hack/install_golangci.sh @@ -863,7 +871,7 @@ install.tools: .install.ginkgo .install.golangci-lint ## Install needed tools .PHONY: .install.md2man .install.md2man: if [ ! -x "$(GOMD2MAN)" ]; then \ - make -C test/tools build/go-md2man ; \ + $(MAKE) -C test/tools build/go-md2man ; \ fi .PHONY: .install.pre-commit diff --git a/cmd/podman-mac-helper/main.go b/cmd/podman-mac-helper/main.go index 937cb8433..ef57341bc 100644 --- a/cmd/podman-mac-helper/main.go +++ b/cmd/podman-mac-helper/main.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "regexp" @@ -131,7 +130,7 @@ func readCapped(reader io.Reader) string { // Cap output buffer := make([]byte, 2048) n, _ := io.ReadFull(reader, buffer) - _, _ = io.Copy(ioutil.Discard, reader) + _, _ = io.Copy(io.Discard, reader) if n > 0 { return string(buffer[:n]) } diff --git a/cmd/podman/containers/commit.go b/cmd/podman/containers/commit.go index fb6dccad4..77f74395e 100644 --- a/cmd/podman/containers/commit.go +++ b/cmd/podman/containers/commit.go @@ -3,7 +3,6 @@ package containers import ( "context" "fmt" - "io/ioutil" "os" "strings" @@ -107,7 +106,7 @@ func commit(cmd *cobra.Command, args []string) error { return err } if len(iidFile) > 0 { - if err = ioutil.WriteFile(iidFile, []byte(response.Id), 0644); err != nil { + if err = os.WriteFile(iidFile, []byte(response.Id), 0644); err != nil { return fmt.Errorf("failed to write image ID: %w", err) } } diff --git a/cmd/podman/containers/cp.go b/cmd/podman/containers/cp.go index 93477feb8..9e63169a0 100644 --- a/cmd/podman/containers/cp.go +++ b/cmd/podman/containers/cp.go @@ -3,7 +3,6 @@ package containers import ( "fmt" "io" - "io/ioutil" "os" "os/user" "path/filepath" @@ -379,7 +378,7 @@ func copyToContainer(container string, containerPath string, hostPath string) er // Copy from stdin to a temporary file *before* throwing it // over the wire. This allows for proper client-side error // reporting. - tmpFile, err := ioutil.TempFile("", "") + tmpFile, err := os.CreateTemp("", "") if err != nil { return err } diff --git a/cmd/podman/containers/kill.go b/cmd/podman/containers/kill.go index 86a7e3ff2..3c9bf6b71 100644 --- a/cmd/podman/containers/kill.go +++ b/cmd/podman/containers/kill.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -96,7 +96,7 @@ func kill(_ *cobra.Command, args []string) error { return errors.New("valid signals are 1 through 64") } for _, cidFile := range killCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/pause.go b/cmd/podman/containers/pause.go index 591523cf9..ea5dd3a0c 100644 --- a/cmd/podman/containers/pause.go +++ b/cmd/podman/containers/pause.go @@ -3,7 +3,7 @@ package containers import ( "context" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -92,7 +92,7 @@ func pause(cmd *cobra.Command, args []string) error { ) for _, cidFile := range pauseCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/restart.go b/cmd/podman/containers/restart.go index 0cc7901f9..db2759f0b 100644 --- a/cmd/podman/containers/restart.go +++ b/cmd/podman/containers/restart.go @@ -3,7 +3,7 @@ package containers import ( "context" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -105,7 +105,7 @@ func restart(cmd *cobra.Command, args []string) error { } for _, cidFile := range restartCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/restore.go b/cmd/podman/containers/restore.go index ee01e19b8..144925a54 100644 --- a/cmd/podman/containers/restore.go +++ b/cmd/podman/containers/restore.go @@ -10,7 +10,6 @@ import ( "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/cmd/podman/utils" "github.com/containers/podman/v4/cmd/podman/validate" - "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/rootless" "github.com/spf13/cobra" @@ -94,7 +93,7 @@ func init() { func restore(cmd *cobra.Command, args []string) error { var ( - e error + err error errs utils.OutputErrors ) podmanStart := time.Now() @@ -105,9 +104,9 @@ func restore(cmd *cobra.Command, args []string) error { // Check if the container exists (#15055) exists := &entities.BoolReport{Value: false} for _, ctr := range args { - exists, e = registry.ContainerEngine().ContainerExists(registry.GetContext(), ctr, entities.ContainerExistsOptions{}) - if e != nil { - return e + exists, err = registry.ContainerEngine().ContainerExists(registry.GetContext(), ctr, entities.ContainerExistsOptions{}) + if err != nil { + return err } if exists.Value { break @@ -116,27 +115,10 @@ func restore(cmd *cobra.Command, args []string) error { if !exists.Value { // Find out if this is an image - inspectOpts := entities.InspectOptions{} - imgData, _, err := registry.ImageEngine().Inspect(context.Background(), args, inspectOpts) - if err != nil { - return err - } - - hostInfo, err := registry.ContainerEngine().Info(context.Background()) + restoreOptions.CheckpointImage, err = utils.IsCheckpointImage(context.Background(), args) if err != nil { return err } - - for i := range imgData { - restoreOptions.CheckpointImage = true - checkpointRuntimeName, found := imgData[i].Annotations[define.CheckpointAnnotationRuntimeName] - if !found { - return fmt.Errorf("image is not a checkpoint: %s", imgData[i].ID) - } - if hostInfo.Host.OCIRuntime.Name != checkpointRuntimeName { - return fmt.Errorf("container image \"%s\" requires runtime: \"%s\"", imgData[i].ID, checkpointRuntimeName) - } - } } notImport := (!restoreOptions.CheckpointImage && restoreOptions.Import == "") diff --git a/cmd/podman/containers/rm.go b/cmd/podman/containers/rm.go index 44d03e9de..da5c24ab8 100644 --- a/cmd/podman/containers/rm.go +++ b/cmd/podman/containers/rm.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -108,7 +108,7 @@ func rm(cmd *cobra.Command, args []string) error { rmOptions.Timeout = &stopTimeout } for _, cidFile := range rmCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go index f66d4d4d3..d8d020c63 100644 --- a/cmd/podman/containers/run.go +++ b/cmd/podman/containers/run.go @@ -148,6 +148,35 @@ func run(cmd *cobra.Command, args []string) error { imageName = name } + // If this is a checkpoint image, invoke container restore. + // We do not return `err` when checkpointImage is false, because the value + // of `err` could be "image is not a checkpoint". In this case, the run + // command should continue as usual, preserving backwards compatibility. + checkpointImage, err := utils.IsCheckpointImage(registry.GetContext(), []string{imageName}) + if checkpointImage { + if err != nil { + return err + } + var restoreOptions entities.RestoreOptions + responses, err := registry.ContainerEngine().ContainerRestore(registry.GetContext(), []string{imageName}, restoreOptions) + if err != nil { + return err + } + + var errs utils.OutputErrors + for _, r := range responses { + switch { + case r.Err != nil: + errs = append(errs, r.Err) + case r.RawInput != "": + fmt.Println(r.RawInput) + default: + fmt.Println(r.Id) + } + } + return errs.PrintErrors() + } + if cliVals.Replace { if err := replaceContainer(cliVals.Name); err != nil { return err diff --git a/cmd/podman/containers/stop.go b/cmd/podman/containers/stop.go index 412c513e1..a1e3a0c46 100644 --- a/cmd/podman/containers/stop.go +++ b/cmd/podman/containers/stop.go @@ -3,7 +3,7 @@ package containers import ( "context" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -105,7 +105,7 @@ func stop(cmd *cobra.Command, args []string) error { stopOptions.Timeout = &stopTimeout } for _, cidFile := range stopCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/unpause.go b/cmd/podman/containers/unpause.go index 988964266..fea05ee22 100644 --- a/cmd/podman/containers/unpause.go +++ b/cmd/podman/containers/unpause.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/cgroups" @@ -99,7 +99,7 @@ func unpause(cmd *cobra.Command, args []string) error { } for _, cidFile := range unpauseCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/generate/spec.go b/cmd/podman/generate/spec.go index bf451ebc5..0c3d7884c 100644 --- a/cmd/podman/generate/spec.go +++ b/cmd/podman/generate/spec.go @@ -2,7 +2,7 @@ package generate import ( "fmt" - "io/ioutil" + "os" "github.com/containers/common/pkg/completion" "github.com/containers/podman/v4/cmd/podman/common" @@ -59,7 +59,7 @@ func spec(cmd *cobra.Command, args []string) error { // if we are looking to print the output, do not mess it up by printing the path // if we are using -v the user probably expects to pipe the output somewhere else if len(opts.FileName) > 0 { - err = ioutil.WriteFile(opts.FileName, report.Data, 0644) + err = os.WriteFile(opts.FileName, report.Data, 0644) if err != nil { return err } diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go index 2b24c1cff..473048834 100644 --- a/cmd/podman/images/build.go +++ b/cmd/podman/images/build.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -19,6 +18,7 @@ import ( "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/config" "github.com/containers/image/v5/docker/reference" + "github.com/containers/image/v5/types" encconfig "github.com/containers/ocicrypt/config" enchelpers "github.com/containers/ocicrypt/helpers" "github.com/containers/podman/v4/cmd/podman/common" @@ -206,6 +206,24 @@ func build(cmd *cobra.Command, args []string) error { return errors.New("'--output' option is not supported in remote mode") } + if buildOpts.Network == "none" { + if cmd.Flag("dns").Changed { + return errors.New("the --dns option cannot be used with --network=none") + } + if cmd.Flag("dns-option").Changed { + return errors.New("the --dns-option option cannot be used with --network=none") + } + if cmd.Flag("dns-search").Changed { + return errors.New("the --dns-search option cannot be used with --network=none") + } + } + + if cmd.Flag("network").Changed { + if buildOpts.Network != "host" && buildOpts.Isolation == buildahDefine.IsolationChroot.String() { + return fmt.Errorf("cannot set --network other than host with --isolation %s", buildOpts.Isolation) + } + } + // Extract container files from the CLI (i.e., --file/-f) first. var containerFiles []string for _, f := range buildOpts.File { @@ -614,6 +632,9 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil timestamp := time.Unix(flags.Timestamp, 0).UTC() opts.Timestamp = ×tamp } + if c.Flag("skip-unused-stages").Changed { + opts.SkipUnusedStages = types.NewOptionalBool(flags.SkipUnusedStages) + } return &entities.BuildOptions{BuildOptions: opts}, nil } @@ -635,7 +656,7 @@ func getDecryptConfig(decryptionKeys []string) (*encconfig.DecryptConfig, error) func parseDockerignore(ignoreFile string) ([]string, error) { excludes := []string{} - ignore, err := ioutil.ReadFile(ignoreFile) + ignore, err := os.ReadFile(ignoreFile) if err != nil { return excludes, err } diff --git a/cmd/podman/images/import.go b/cmd/podman/images/import.go index 8343a0bda..7532bf7a9 100644 --- a/cmd/podman/images/import.go +++ b/cmd/podman/images/import.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "strings" @@ -116,7 +115,7 @@ func importCon(cmd *cobra.Command, args []string) error { } if source == "-" { - outFile, err := ioutil.TempFile("", "podman") + outFile, err := os.CreateTemp("", "podman") if err != nil { return fmt.Errorf("creating file %v", err) } diff --git a/cmd/podman/images/load.go b/cmd/podman/images/load.go index 367b628c7..4aae5217d 100644 --- a/cmd/podman/images/load.go +++ b/cmd/podman/images/load.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "strings" @@ -93,7 +92,7 @@ func load(cmd *cobra.Command, args []string) error { if term.IsTerminal(int(os.Stdin.Fd())) { return errors.New("cannot read from terminal, use command-line redirection or the --input flag") } - outFile, err := ioutil.TempFile(util.Tmpdir(), "podman") + outFile, err := os.CreateTemp(util.Tmpdir(), "podman") if err != nil { return fmt.Errorf("creating file %v", err) } diff --git a/cmd/podman/images/save.go b/cmd/podman/images/save.go index ecff0f841..426684d49 100644 --- a/cmd/podman/images/save.go +++ b/cmd/podman/images/save.go @@ -96,6 +96,11 @@ func saveFlags(cmd *cobra.Command) { flags.BoolVarP(&saveOpts.Quiet, "quiet", "q", false, "Suppress the output") flags.BoolVarP(&saveOpts.MultiImageArchive, "multi-image-archive", "m", containerConfig.Engine.MultiImageArchive, "Interpret additional arguments as images not tags and create a multi-image-archive (only for docker-archive)") + + if !registry.IsRemote() { + flags.StringVar(&saveOpts.SignaturePolicy, "signature-policy", "", "Path to a signature-policy file") + _ = flags.MarkHidden("signature-policy") + } } func save(cmd *cobra.Command, args []string) (finalErr error) { diff --git a/cmd/podman/images/utils_linux.go b/cmd/podman/images/utils_linux.go index 935a45667..a2f471a48 100644 --- a/cmd/podman/images/utils_linux.go +++ b/cmd/podman/images/utils_linux.go @@ -3,7 +3,6 @@ package images import ( "fmt" "io" - "io/ioutil" "os" "path/filepath" @@ -16,7 +15,7 @@ import ( // the caller should use the returned function to clean up the pipeDir func setupPipe() (string, func() <-chan error, error) { errc := make(chan error) - pipeDir, err := ioutil.TempDir(os.TempDir(), "pipeDir") + pipeDir, err := os.MkdirTemp(os.TempDir(), "pipeDir") if err != nil { return "", nil, err } diff --git a/cmd/podman/kube/generate.go b/cmd/podman/kube/generate.go index ee2ea51ae..30b06b0c5 100644 --- a/cmd/podman/kube/generate.go +++ b/cmd/podman/kube/generate.go @@ -3,7 +3,6 @@ package kube import ( "fmt" "io" - "io/ioutil" "os" "github.com/containers/common/pkg/completion" @@ -77,7 +76,7 @@ func generateKube(cmd *cobra.Command, args []string) error { if err != nil { return err } - content, err := ioutil.ReadAll(report.Reader) + content, err := io.ReadAll(report.Reader) if err != nil { return err } @@ -89,7 +88,7 @@ func generateKube(cmd *cobra.Command, args []string) error { if _, err := os.Stat(generateFile); err == nil { return fmt.Errorf("cannot write to %q; file exists", generateFile) } - if err := ioutil.WriteFile(generateFile, content, 0644); err != nil { + if err := os.WriteFile(generateFile, content, 0644); err != nil { return fmt.Errorf("cannot write to %q: %w", generateFile, err) } return nil diff --git a/cmd/podman/kube/play.go b/cmd/podman/kube/play.go index c846ec32c..1163a6ff6 100644 --- a/cmd/podman/kube/play.go +++ b/cmd/podman/kube/play.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "os" @@ -284,7 +283,7 @@ func readerFromArg(fileName string) (*bytes.Reader, error) { } defer response.Body.Close() - data, err := ioutil.ReadAll(response.Body) + data, err := io.ReadAll(response.Body) if err != nil { return nil, err } diff --git a/cmd/podman/machine/list.go b/cmd/podman/machine/list.go index ddc9ce246..26db5e1a4 100644 --- a/cmd/podman/machine/list.go +++ b/cmd/podman/machine/list.go @@ -177,6 +177,7 @@ func toMachineFormat(vms []*machine.ListResponse) ([]*entities.ListReporter, err response.Port = vm.Port response.RemoteUsername = vm.RemoteUsername response.IdentityPath = vm.IdentityPath + response.Starting = vm.Starting machineResponses = append(machineResponses, response) } diff --git a/cmd/podman/machine/ssh.go b/cmd/podman/machine/ssh.go index 8534b8efa..1cadce916 100644 --- a/cmd/podman/machine/ssh.go +++ b/cmd/podman/machine/ssh.go @@ -101,7 +101,7 @@ func remoteConnectionUsername() (string, error) { if err != nil { return "", err } - dest, _, err := cfg.ActiveDestination() + dest, _, _, err := cfg.ActiveDestination() if err != nil { return "", err } diff --git a/cmd/podman/manifest/push.go b/cmd/podman/manifest/push.go index c8893ff2e..2b4c570a5 100644 --- a/cmd/podman/manifest/push.go +++ b/cmd/podman/manifest/push.go @@ -3,7 +3,6 @@ package manifest import ( "errors" "fmt" - "io/ioutil" "os" "github.com/containers/common/pkg/auth" @@ -149,7 +148,7 @@ func push(cmd *cobra.Command, args []string) error { return err } if manifestPushOpts.DigestFile != "" { - if err := ioutil.WriteFile(manifestPushOpts.DigestFile, []byte(digest), 0644); err != nil { + if err := os.WriteFile(manifestPushOpts.DigestFile, []byte(digest), 0644); err != nil { return err } } diff --git a/cmd/podman/parse/net_test.go b/cmd/podman/parse/net_test.go index a11edc2ca..88bfaa894 100644 --- a/cmd/podman/parse/net_test.go +++ b/cmd/podman/parse/net_test.go @@ -3,7 +3,6 @@ package parse import ( - "io/ioutil" "os" "testing" @@ -15,7 +14,7 @@ var ( ) func createTmpFile(content []byte) (string, error) { - tmpfile, err := ioutil.TempFile(os.TempDir(), "unittest") + tmpfile, err := os.CreateTemp(os.TempDir(), "unittest") if err != nil { return "", err } diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go index 1f8152f32..fc2e07894 100644 --- a/cmd/podman/pods/create.go +++ b/cmd/podman/pods/create.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" "runtime" "sort" @@ -300,7 +299,7 @@ func create(cmd *cobra.Command, args []string) error { } if len(podIDFile) > 0 { - if err = ioutil.WriteFile(podIDFile, []byte(response.Id), 0644); err != nil { + if err = os.WriteFile(podIDFile, []byte(response.Id), 0644); err != nil { return fmt.Errorf("failed to write pod ID to file: %w", err) } } diff --git a/cmd/podman/registry/remote.go b/cmd/podman/registry/remote.go index afe32e0b9..02aa31c58 100644 --- a/cmd/podman/registry/remote.go +++ b/cmd/podman/registry/remote.go @@ -32,6 +32,8 @@ func IsRemote() bool { fs.BoolVarP(&remoteFromCLI.Value, "remote", "r", remote, "") connectionFlagName := "connection" fs.StringP(connectionFlagName, "c", "", "") + contextFlagName := "context" + fs.String(contextFlagName, "", "") hostFlagName := "host" fs.StringP(hostFlagName, "H", "", "") urlFlagName := "url" @@ -46,7 +48,7 @@ func IsRemote() bool { } _ = fs.Parse(os.Args[start:]) // --connection or --url implies --remote - remoteFromCLI.Value = remoteFromCLI.Value || fs.Changed(connectionFlagName) || fs.Changed(urlFlagName) || fs.Changed(hostFlagName) + remoteFromCLI.Value = remoteFromCLI.Value || fs.Changed(connectionFlagName) || fs.Changed(urlFlagName) || fs.Changed(hostFlagName) || fs.Changed(contextFlagName) }) return podmanOptions.EngineMode == entities.TunnelMode || remoteFromCLI.Value } diff --git a/cmd/podman/root.go b/cmd/podman/root.go index 2e00777a4..5c65be96d 100644 --- a/cmd/podman/root.go +++ b/cmd/podman/root.go @@ -174,13 +174,9 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { } } - // --connection is not as "special" as --remote so we can wait and process it here - conn := cmd.Root().LocalFlags().Lookup("connection") - if conn != nil && conn.Changed { - cfg.Engine.ActiveService = conn.Value.String() - + setupConnection := func() error { var err error - cfg.URI, cfg.Identity, err = cfg.ActiveDestination() + cfg.URI, cfg.Identity, cfg.MachineMode, err = cfg.ActiveDestination() if err != nil { return fmt.Errorf("failed to resolve active destination: %w", err) } @@ -192,6 +188,29 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { if err := cmd.Root().LocalFlags().Set("identity", cfg.Identity); err != nil { return fmt.Errorf("failed to override --identity flag: %w", err) } + return nil + } + + // --connection is not as "special" as --remote so we can wait and process it here + contextConn := cmd.Root().LocalFlags().Lookup("context") + conn := cmd.Root().LocalFlags().Lookup("connection") + if conn != nil && conn.Changed { + if contextConn != nil && contextConn.Changed { + return fmt.Errorf("use of --connection and --context at the same time is not allowed") + } + cfg.Engine.ActiveService = conn.Value.String() + if err := setupConnection(); err != nil { + return err + } + } + if contextConn != nil && contextConn.Changed { + service := contextConn.Value.String() + if service != "default" { + cfg.Engine.ActiveService = service + if err := setupConnection(); err != nil { + return err + } + } } // Special case if command is hidden completion command ("__complete","__completeNoDesc") @@ -232,10 +251,6 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { } } - context := cmd.Root().LocalFlags().Lookup("context") - if context.Value.String() != "default" { - return errors.New("podman does not support swarm, the only --context value allowed is \"default\"") - } if !registry.IsRemote() { if cmd.Flag("cpu-profile").Changed { f, err := os.Create(cfg.CPUProfile) @@ -353,16 +368,19 @@ func loggingHook() { func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) { cfg := opts.Config - srv, uri, ident := resolveDestination() + srv, uri, ident, machine := resolveDestination() lFlags := cmd.Flags() + // non configurable option to help ssh dialing + opts.MachineMode = machine + sshFlagName := "ssh" lFlags.StringVar(&opts.SSHMode, sshFlagName, string(ssh.GolangMode), "define the ssh mode") _ = cmd.RegisterFlagCompletionFunc(sshFlagName, common.AutocompleteSSH) connectionFlagName := "connection" - lFlags.StringVarP(&opts.Engine.ActiveService, connectionFlagName, "c", srv, "Connection to use for remote Podman service") + lFlags.StringP(connectionFlagName, "c", srv, "Connection to use for remote Podman service") _ = cmd.RegisterFlagCompletionFunc(connectionFlagName, common.AutocompleteSystemConnections) urlFlagName := "url" @@ -498,26 +516,26 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) { } } -func resolveDestination() (string, string, string) { +func resolveDestination() (string, string, string, bool) { if uri, found := os.LookupEnv("CONTAINER_HOST"); found { var ident string if v, found := os.LookupEnv("CONTAINER_SSHKEY"); found { ident = v } - return "", uri, ident + return "", uri, ident, false } cfg, err := config.ReadCustomConfig() if err != nil { logrus.Warning(fmt.Errorf("unable to read local containers.conf: %w", err)) - return "", registry.DefaultAPIAddress(), "" + return "", registry.DefaultAPIAddress(), "", false } - uri, ident, err := cfg.ActiveDestination() + uri, ident, machine, err := cfg.ActiveDestination() if err != nil { - return "", registry.DefaultAPIAddress(), "" + return "", registry.DefaultAPIAddress(), "", false } - return cfg.Engine.ActiveService, uri, ident + return cfg.Engine.ActiveService, uri, ident, machine } func formatError(err error) string { diff --git a/cmd/podman/secrets/create.go b/cmd/podman/secrets/create.go index 01775f563..293da2103 100644 --- a/cmd/podman/secrets/create.go +++ b/cmd/podman/secrets/create.go @@ -10,6 +10,7 @@ import ( "github.com/containers/common/pkg/completion" "github.com/containers/podman/v4/cmd/podman/common" + "github.com/containers/podman/v4/cmd/podman/parse" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/spf13/cobra" @@ -31,6 +32,7 @@ var ( var ( createOpts = entities.SecretCreateOptions{} env = false + labels []string ) func init() { @@ -38,21 +40,24 @@ func init() { Command: createCmd, Parent: secretCmd, }) + cfg := registry.PodmanConfig() flags := createCmd.Flags() driverFlagName := "driver" - optsFlagName := "driver-opts" - - cfg := registry.PodmanConfig() - flags.StringVarP(&createOpts.Driver, driverFlagName, "d", cfg.Secrets.Driver, "Specify secret driver") - flags.StringToStringVar(&createOpts.DriverOpts, optsFlagName, cfg.Secrets.Opts, "Specify driver specific options") _ = createCmd.RegisterFlagCompletionFunc(driverFlagName, completion.AutocompleteNone) + + optsFlagName := "driver-opts" + flags.StringToStringVar(&createOpts.DriverOpts, optsFlagName, cfg.Secrets.Opts, "Specify driver specific options") _ = createCmd.RegisterFlagCompletionFunc(optsFlagName, completion.AutocompleteNone) envFlagName := "env" flags.BoolVar(&env, envFlagName, false, "Read secret data from environment variable") + + labelFlagName := "label" + flags.StringArrayVarP(&labels, labelFlagName, "l", nil, "Specify labels on the secret") + _ = createCmd.RegisterFlagCompletionFunc(labelFlagName, completion.AutocompleteNone) } func create(cmd *cobra.Command, args []string) error { @@ -87,6 +92,11 @@ func create(cmd *cobra.Command, args []string) error { reader = file } + createOpts.Labels, err = parse.GetAllLabels([]string{}, labels) + if err != nil { + return fmt.Errorf("unable to process labels: %w", err) + } + report, err := registry.ContainerEngine().SecretCreate(context.Background(), name, reader, createOpts) if err != nil { return err diff --git a/cmd/podman/secrets/inspect.go b/cmd/podman/secrets/inspect.go index f4c395b0f..9054fc3b0 100644 --- a/cmd/podman/secrets/inspect.go +++ b/cmd/podman/secrets/inspect.go @@ -25,7 +25,23 @@ var ( } ) -var format string +var ( + format string + pretty bool +) + +const ( + prettyTemplate = `ID: {{.ID}} +Name: {{.Spec.Name}} +{{- if .Spec.Labels }} +Labels: +{{- range $k, $v := .Spec.Labels }} + - {{ $k }}{{if $v }}={{ $v }}{{ end }} +{{- end }}{{ end }} +Driver: {{.Spec.Driver.Name}} +Created at: {{.CreatedAt}} +Updated at: {{.UpdatedAt}}` +) func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ @@ -34,8 +50,11 @@ func init() { }) flags := inspectCmd.Flags() formatFlagName := "format" - flags.StringVarP(&format, formatFlagName, "f", "", "Format volume output using Go template") + flags.StringVarP(&format, formatFlagName, "f", "", "Format inspect output using Go template") _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.SecretInfoReport{})) + + prettyFlagName := "pretty" + flags.BoolVar(&pretty, prettyFlagName, false, "Print inspect output in human-readable format") } func inspect(cmd *cobra.Command, args []string) error { @@ -46,7 +65,21 @@ func inspect(cmd *cobra.Command, args []string) error { inspected = []*entities.SecretInfoReport{} } - if cmd.Flags().Changed("format") { + switch { + case cmd.Flags().Changed("pretty"): + rpt := report.New(os.Stdout, cmd.Name()) + defer rpt.Flush() + + rpt, err := rpt.Parse(report.OriginUser, prettyTemplate) + if err != nil { + return err + } + + if err := rpt.Execute(inspected); err != nil { + return err + } + + case cmd.Flags().Changed("format"): rpt := report.New(os.Stdout, cmd.Name()) defer rpt.Flush() @@ -58,7 +91,8 @@ func inspect(cmd *cobra.Command, args []string) error { if err := rpt.Execute(inspected); err != nil { return err } - } else { + + default: buf, err := json.MarshalIndent(inspected, "", " ") if err != nil { return err diff --git a/cmd/podman/system/connection/add.go b/cmd/podman/system/connection/add.go index f3b61b254..2730ebfb7 100644 --- a/cmd/podman/system/connection/add.go +++ b/cmd/podman/system/connection/add.go @@ -6,6 +6,7 @@ import ( "net/url" "os" "regexp" + "strings" "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/config" @@ -37,6 +38,17 @@ var ( `, } + createCmd = &cobra.Command{ + Use: "create [options] NAME DESTINATION", + Args: cobra.ExactArgs(1), + Short: addCmd.Short, + Long: addCmd.Long, + RunE: create, + ValidArgsFunction: completion.AutocompleteNone, + } + + dockerPath string + cOpts = struct { Identity string Port int @@ -50,7 +62,6 @@ func init() { Command: addCmd, Parent: system.ConnectionCmd, }) - flags := addCmd.Flags() portFlagName := "port" @@ -66,6 +77,21 @@ func init() { _ = addCmd.RegisterFlagCompletionFunc(socketPathFlagName, completion.AutocompleteDefault) flags.BoolVarP(&cOpts.Default, "default", "d", false, "Set connection to be default") + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: createCmd, + Parent: system.ContextCmd, + }) + + flags = createCmd.Flags() + dockerFlagName := "docker" + flags.StringVar(&dockerPath, dockerFlagName, "", "Description of the context") + + _ = createCmd.RegisterFlagCompletionFunc(dockerFlagName, completion.AutocompleteNone) + flags.String("description", "", "Ignored. Just for script compatibility") + flags.String("from", "", "Ignored. Just for script compatibility") + flags.String("kubernetes", "", "Ignored. Just for script compatibility") + flags.String("default-stack-orchestrator", "", "Ignored. Just for script compatibility") } func add(cmd *cobra.Command, args []string) error { @@ -171,3 +197,59 @@ func add(cmd *cobra.Command, args []string) error { } return cfg.Write() } + +func create(cmd *cobra.Command, args []string) error { + dest, err := translateDest(dockerPath) + if err != nil { + return err + } + if match, err := regexp.Match("^[A-Za-z][A-Za-z0-9+.-]*://", []byte(dest)); err != nil { + return fmt.Errorf("invalid destination: %w", err) + } else if !match { + dest = "ssh://" + dest + } + + uri, err := url.Parse(dest) + if err != nil { + return err + } + + cfg, err := config.ReadCustomConfig() + if err != nil { + return err + } + + dst := config.Destination{ + URI: uri.String(), + } + + if cfg.Engine.ServiceDestinations == nil { + cfg.Engine.ServiceDestinations = map[string]config.Destination{ + args[0]: dst, + } + cfg.Engine.ActiveService = args[0] + } else { + cfg.Engine.ServiceDestinations[args[0]] = dst + } + return cfg.Write() +} + +func translateDest(path string) (string, error) { + if path == "" { + return "", nil + } + split := strings.SplitN(path, "=", 2) + if len(split) == 1 { + return split[0], nil + } + if split[0] != "host" { + return "", fmt.Errorf("\"host\" is requited for --docker option") + } + // "host=tcp://myserver:2376,ca=~/ca-file,cert=~/cert-file,key=~/key-file" + vals := strings.Split(split[1], ",") + if len(vals) > 1 { + return "", fmt.Errorf("--docker additional options %q not supported", strings.Join(vals[1:], ",")) + } + // for now we ignore other fields specified on command line + return vals[0], nil +} diff --git a/cmd/podman/system/connection/default.go b/cmd/podman/system/connection/default.go index 81866df55..8d1709e9f 100644 --- a/cmd/podman/system/connection/default.go +++ b/cmd/podman/system/connection/default.go @@ -21,10 +21,24 @@ var ( RunE: defaultRunE, Example: `podman system connection default testing`, } + + useCmd = &cobra.Command{ + Use: "use NAME", + Args: cobra.ExactArgs(1), + Short: dfltCmd.Short, + Long: dfltCmd.Long, + ValidArgsFunction: dfltCmd.ValidArgsFunction, + RunE: dfltCmd.RunE, + Example: `podman context use testing`, + } ) func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: useCmd, + Parent: system.ContextCmd, + }) + registry.Commands = append(registry.Commands, registry.CliCommand{ Command: dfltCmd, Parent: system.ConnectionCmd, }) diff --git a/cmd/podman/system/connection/list.go b/cmd/podman/system/connection/list.go index 2c5f6a310..3c1a42453 100644 --- a/cmd/podman/system/connection/list.go +++ b/cmd/podman/system/connection/list.go @@ -8,6 +8,7 @@ import ( "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/report" + "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/cmd/podman/system" @@ -29,16 +30,36 @@ var ( RunE: list, TraverseChildren: false, } + inspectCmd = &cobra.Command{ + Use: "inspect [options] [CONTEXT] [CONTEXT...]", + Short: "Inspect destination for a Podman service(s)", + ValidArgsFunction: completion.AutocompleteNone, + RunE: inspect, + } ) func init() { + initFlags := func(cmd *cobra.Command) { + cmd.Flags().StringP("format", "f", "", "Custom Go template for printing connections") + _ = cmd.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(&namedDestination{})) + cmd.Flags().BoolP("quiet", "q", false, "Custom Go template for printing connections") + } + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: listCmd, + Parent: system.ContextCmd, + }) registry.Commands = append(registry.Commands, registry.CliCommand{ Command: listCmd, Parent: system.ConnectionCmd, }) + initFlags(listCmd) - listCmd.Flags().String("format", "", "Custom Go template for printing connections") - _ = listCmd.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(&namedDestination{})) + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: inspectCmd, + Parent: system.ContextCmd, + }) + initFlags(inspectCmd) } type namedDestination struct { @@ -48,13 +69,34 @@ type namedDestination struct { } func list(cmd *cobra.Command, _ []string) error { + return inspect(cmd, nil) +} + +func inspect(cmd *cobra.Command, args []string) error { cfg, err := config.ReadCustomConfig() if err != nil { return err } + format := cmd.Flag("format").Value.String() + if format == "" && args != nil { + format = "json" + } + + quiet, err := cmd.Flags().GetBool("quiet") + if err != nil { + return err + } rows := make([]namedDestination, 0) for k, v := range cfg.Engine.ServiceDestinations { + if args != nil && !util.StringInSlice(k, args) { + continue + } + + if quiet { + fmt.Println(k) + continue + } def := false if k == cfg.Engine.ActiveService { def = true @@ -63,14 +105,19 @@ func list(cmd *cobra.Command, _ []string) error { r := namedDestination{ Name: k, Destination: config.Destination{ - Identity: v.Identity, - URI: v.URI, + Identity: v.Identity, + URI: v.URI, + IsMachine: v.IsMachine, }, Default: def, } rows = append(rows, r) } + if quiet { + return nil + } + sort.Slice(rows, func(i, j int) bool { return rows[i].Name < rows[j].Name }) @@ -78,7 +125,7 @@ func list(cmd *cobra.Command, _ []string) error { rpt := report.New(os.Stdout, cmd.Name()) defer rpt.Flush() - if report.IsJSON(cmd.Flag("format").Value.String()) { + if report.IsJSON(format) { buf, err := registry.JSONLibrary().MarshalIndent(rows, "", " ") if err == nil { fmt.Println(string(buf)) @@ -86,8 +133,8 @@ func list(cmd *cobra.Command, _ []string) error { return err } - if cmd.Flag("format").Changed { - rpt, err = rpt.Parse(report.OriginUser, cmd.Flag("format").Value.String()) + if format != "" { + rpt, err = rpt.Parse(report.OriginUser, format) } else { rpt, err = rpt.Parse(report.OriginPodman, "{{range .}}{{.Name}}\t{{.URI}}\t{{.Identity}}\t{{.Default}}\n{{end -}}") diff --git a/cmd/podman/system/connection/remove.go b/cmd/podman/system/connection/remove.go index 29bf98c43..5ff0000d6 100644 --- a/cmd/podman/system/connection/remove.go +++ b/cmd/podman/system/connection/remove.go @@ -31,11 +31,19 @@ var ( func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Command: rmCmd, + Parent: system.ContextCmd, + }) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: rmCmd, Parent: system.ConnectionCmd, }) flags := rmCmd.Flags() flags.BoolVarP(&rmOpts.All, "all", "a", false, "Remove all connections") + + flags.BoolP("force", "f", false, "Ignored: for Docker compatibility") + _ = flags.MarkHidden("force") } func rm(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/system/context.go b/cmd/podman/system/context.go new file mode 100644 index 000000000..926e4a443 --- /dev/null +++ b/cmd/podman/system/context.go @@ -0,0 +1,28 @@ +package system + +import ( + "github.com/containers/podman/v4/cmd/podman/registry" + "github.com/containers/podman/v4/cmd/podman/validate" + "github.com/spf13/cobra" +) + +var ( + // ContextCmd skips creating engines (PersistentPreRunE/PersistentPostRunE are No-Op's) since + // sub-commands will obtain connection information to said engines + ContextCmd = &cobra.Command{ + Use: "context", + Short: "Manage remote API service destinations", + Long: `Manage remote API service destination information in podman configuration`, + PersistentPreRunE: validate.NoOp, + RunE: validate.SubCommandExists, + PersistentPostRunE: validate.NoOp, + Hidden: true, + TraverseChildren: false, + } +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: ContextCmd, + }) +} diff --git a/cmd/podman/utils/utils.go b/cmd/podman/utils/utils.go index a265faf51..8063f4309 100644 --- a/cmd/podman/utils/utils.go +++ b/cmd/podman/utils/utils.go @@ -1,9 +1,12 @@ package utils import ( + "context" "fmt" "os" + "github.com/containers/podman/v4/cmd/podman/registry" + "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/domain/entities/reports" ) @@ -99,3 +102,40 @@ func PrintNetworkPruneResults(networkPruneReport []*entities.NetworkPruneReport, } return errs.PrintErrors() } + +// IsCheckpointImage returns true with no error only if all values in +// namesOrIDs correspond to checkpoint images AND these images are +// compatible with the container runtime that is currently in use, +// e.g., crun or runc. +// +// IsCheckpointImage returns false with no error when none of the values +// in namesOrIDs corresponds to an ID or name of an image. +// +// Otherwise, IsCheckpointImage returns false with appropriate error. +func IsCheckpointImage(ctx context.Context, namesOrIDs []string) (bool, error) { + inspectOpts := entities.InspectOptions{} + imgData, _, err := registry.ImageEngine().Inspect(ctx, namesOrIDs, inspectOpts) + if err != nil { + return false, err + } + if len(imgData) == 0 { + return false, nil + } + imgID := imgData[0].ID + + hostInfo, err := registry.ContainerEngine().Info(ctx) + if err != nil { + return false, err + } + + for i := range imgData { + checkpointRuntimeName, found := imgData[i].Annotations[define.CheckpointAnnotationRuntimeName] + if !found { + return false, fmt.Errorf("image is not a checkpoint: %s", imgID) + } + if hostInfo.Host.OCIRuntime.Name != checkpointRuntimeName { + return false, fmt.Errorf("container image \"%s\" requires runtime: \"%s\"", imgID, checkpointRuntimeName) + } + } + return true, nil +} diff --git a/cmd/rootlessport/main.go b/cmd/rootlessport/main.go index d8d6ffcee..2508eb1c2 100644 --- a/cmd/rootlessport/main.go +++ b/cmd/rootlessport/main.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "os" "os/exec" @@ -50,7 +49,7 @@ func main() { } func loadConfig(r io.Reader) (*rootlessport.Config, io.ReadCloser, io.WriteCloser, error) { - stdin, err := ioutil.ReadAll(r) + stdin, err := io.ReadAll(r) if err != nil { return nil, nil, nil, err } @@ -92,7 +91,7 @@ func parent() error { } // create the parent driver - stateDir, err := ioutil.TempDir(cfg.TmpDir, "rootlessport") + stateDir, err := os.MkdirTemp(cfg.TmpDir, "rootlessport") if err != nil { return err } @@ -240,7 +239,7 @@ outer: // wait for ExitFD to be closed logrus.Info("Waiting for exitfd to be closed") - if _, err := ioutil.ReadAll(exitR); err != nil { + if _, err := io.ReadAll(exitR); err != nil { return err } return nil @@ -357,7 +356,7 @@ func child() error { }() // wait for stdin to be closed - if _, err := ioutil.ReadAll(os.Stdin); err != nil { + if _, err := io.ReadAll(os.Stdin); err != nil { return err } return nil diff --git a/contrib/cirrus/CIModes.md b/contrib/cirrus/CIModes.md index 0b5a189a6..7d6a36cf3 100644 --- a/contrib/cirrus/CIModes.md +++ b/contrib/cirrus/CIModes.md @@ -43,13 +43,10 @@ of this document, it's not possible to override the behavior of `$CIRRUS_PR`. ## Cirrus Task contexts and runtime modes ### Intended general PR Tasks (*italic*: matrix) -+ ext_svc_check -+ automation + *build* + validate + bindings + swagger -+ consistency + *alt_build* + osx_alt_build + docker-py_test @@ -76,31 +73,22 @@ of this document, it's not possible to override the behavior of `$CIRRUS_PR`. + release_test ### Intended `[CI:DOCS]` PR Tasks: -+ ext_svc_check -+ automation + *build* + validate + swagger -+ consistency + meta + success ### Intended `[CI:COPR]` PR Tasks: -+ ext_svc_check -+ automation + *build* + validate + swagger -+ consistency + meta + success ### Intend `[CI:BUILD]` PR Tasks: -+ ext_svc_check -+ automation + *build* + validate -+ consistency + *alt_build* + osx_alt_build + test_image_build @@ -109,7 +97,6 @@ of this document, it's not possible to override the behavior of `$CIRRUS_PR`. + artifacts ### Intended Branch tasks (and Cirrus-cron jobs, except "multiarch"): -+ ext_svc_check + *build* + swagger + *alt_build* @@ -123,7 +110,6 @@ of this document, it's not possible to override the behavior of `$CIRRUS_PR`. + artifacts ### Intended for "multiarch" Cirrus-Cron (always a branch): -+ ext_svc_check + image_build + meta + success diff --git a/contrib/cirrus/check_go_changes.sh b/contrib/cirrus/check_go_changes.sh new file mode 100755 index 000000000..a92ab03af --- /dev/null +++ b/contrib/cirrus/check_go_changes.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +set -eo pipefail + +# This script is intended to confirm new go code conforms to certain +# conventions and/or does not introduce use of old/deprecated packages +# or functions. It needs to run in the Cirrus CI environment, on behalf +# of PRs, via runner.sh. This ensures a consistent and predictable +# environment not easily reproduced by a `Makefile`. + +# shellcheck source=contrib/cirrus/lib.sh +source $(dirname $0)/lib.sh + +check_msg() { + msg "#####" # Cirrus-CI logs automatically squash empty lines + msg "##### $1" # Complains if $1 is empty +} + +# First arg is check description, second is regex to search $diffs for. +check_diffs() { + local check regex + check="$1" + regex="$2" + check_msg "Confirming changes have no $check" + req_env_vars check regex diffs + if egrep -q "$regex"<<<"$diffs"; then + # Show 5 context lines before/after as compromise for script simplicity + die "Found $check: +$(egrep -B 5 -A 5 "$regex"<<<"$diffs")" + fi +} + +if [[ -n "$CIRRUS_TAG" ]] || ! req_env_vars CIRRUS_CHANGE_IN_REPO CIRRUS_PR DEST_BRANCH +then + warn "Skipping: Golang code checks cannot run in this context" + exit 0 +fi + +# Defined by/in Cirrus-CI config. +# shellcheck disable=SC2154 +base=$(git merge-base $DEST_BRANCH $CIRRUS_CHANGE_IN_REPO) +diffs=$(git diff $base $CIRRUS_CHANGE_IN_REPO -- '*.go' ':^vendor/') + +if [[ -z "$diffs" ]]; then + check_msg "There are no golang diffs to check between $base...$CIRRUS_CHANGE_IN_REPO" + exit 0 +fi + +check_diffs \ + "use of deprecated ioutil vs recommended io or os packages." \ + "^(\\+[^#]+io/ioutil)|(\\+.+ioutil\\..+)" + +check_diffs \ + "use of os.IsNotExists(err) vs recommended errors.Is(err, os.ErrNotExist)" \ + "^\\+[^#]*os\\.IsNotExists\\(" diff --git a/contrib/cirrus/ext_svc_check.sh b/contrib/cirrus/ext_svc_check.sh deleted file mode 100755 index 146919c39..000000000 --- a/contrib/cirrus/ext_svc_check.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -set -eo pipefail - -# This script attempts basic confirmation of functional networking -# by connecting to a set of essential external servers and failing -# if any cannot be reached. It's intended for use early on in the -# podman CI system, to help prevent wasting time on tests that can't -# succeed due to some outage or another. - -# shellcheck source=./contrib/cirrus/lib.sh -source $(dirname $0)/lib.sh - -cat ${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/required_host_ports.txt | \ - while read host port - do - if [[ "$port" -eq "443" ]] - then - echo "SSL/TLS to $host:$port" - echo -n '' | \ - err_retry 9 1000 "" openssl s_client -quiet -no_ign_eof -connect $host:$port - else - echo "Connect to $host:$port" - err_retry 9 1000 1 nc -zv -w 13 $host $port - fi - done - -# Verify we can pull metadata from a few key testing images on quay.io -# in the 'libpod' namespace. This is mostly aimed at validating the -# quay.io service is up and responsive. Images were hand-picked with -# egrep -ro 'quay.io/libpod/.+:latest' test | sort -u -TEST_IMGS=(\ - alpine:latest - busybox:latest - alpine_labels:latest - alpine_nginx:latest - alpine_healthcheck:latest - badhealthcheck:latest - cirros:latest -) - -echo "Checking quay.io test image accessibility" -for testimg in "${TEST_IMGS[@]}"; do - fqin="quay.io/libpod/$testimg" - echo " $fqin" - skopeo inspect --retry-times 5 "docker://$fqin" | jq . > /dev/null -done diff --git a/contrib/cirrus/postbuild.sh b/contrib/cirrus/postbuild.sh new file mode 100755 index 000000000..47cb558e3 --- /dev/null +++ b/contrib/cirrus/postbuild.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +set -eo pipefail + +# This script attempts to confirm all included go modules from +# other sources match what is expected in `vendor/modules.txt` +# vs `go.mod`. Also make sure that the generated bindings in +# `pkg/bindings/...` are in sync with the code. It's intended +# for use after successfully building podman, to prevent wasting +# time on tests that might otherwise succeed with bad/ugly/invalid +# code. + +source /etc/automation_environment +source $AUTOMATION_LIB_PATH/common_lib.sh + +# Defined by the CI system +# shellcheck disable=SC2154 +cd $CIRRUS_WORKING_DIR + +showrun make .install.goimports +showrun make vendor +SUGGESTION="run 'make vendor' and commit all changes" ./hack/tree_status.sh +showrun make generate-bindings +SUGGESTION="run 'make generate-bindings' and commit all changes" ./hack/tree_status.sh +showrun make completions +SUGGESTION="run 'make completions' and commit all changes" ./hack/tree_status.sh + +# Defined in Cirrus-CI config. +# shellcheck disable=SC2154 +$SCRIPT_BASE/check_go_changes.sh diff --git a/contrib/cirrus/prebuild.sh b/contrib/cirrus/prebuild.sh new file mode 100755 index 000000000..ea05d90dc --- /dev/null +++ b/contrib/cirrus/prebuild.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +set -eo pipefail + +# This script attempts to confirm functional networking and +# connectivity to essential external servers. It also verifies +# some basic environmental expectations and shell-script sanity. +# It's intended for use early on in the podman CI system, to help +# prevent wasting time on tests that can't succeed due to some +# outage, failure, or missed expectation. + +source /etc/automation_environment +source $AUTOMATION_LIB_PATH/common_lib.sh + +req_env_vars CI DEST_BRANCH IMAGE_SUFFIX TEST_FLAVOR TEST_ENVIRON \ + PODBIN_NAME PRIV_NAME DISTRO_NV AUTOMATION_LIB_PATH \ + SCRIPT_BASE CIRRUS_WORKING_DIR FEDORA_NAME UBUNTU_NAME \ + VM_IMAGE_NAME + +# Defined by the CI system +# shellcheck disable=SC2154 +cd $CIRRUS_WORKING_DIR + +# Defined by CI config. +# shellcheck disable=SC2154 +showrun $SCRIPT_BASE/cirrus_yaml_test.py + +# Defined by CI config. +# shellcheck disable=SC2154 +if [[ "${DISTRO_NV}" =~ fedora ]]; then + showrun ooe.sh dnf install -y ShellCheck # small/quick addition + showrun shellcheck --color=always --format=tty \ + --shell=bash --external-sources \ + --enable add-default-case,avoid-nullary-conditions,check-unassigned-uppercase \ + --exclude SC2046,SC2034,SC2090,SC2064 \ + --wiki-link-count=0 --severity=warning \ + $SCRIPT_BASE/*.sh hack/get_ci_vm.sh +fi + +msg "Checking 3rd party network service connectivity" +# shellcheck disable=SC2154 +cat ${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/required_host_ports.txt | \ + while read host port + do + if [[ "$port" -eq "443" ]] + then + echo "SSL/TLS to $host:$port" + echo -n '' | \ + err_retry 9 1000 "" openssl s_client -quiet -no_ign_eof -connect $host:$port + else + echo "Connect to $host:$port" + err_retry 9 1000 1 nc -zv -w 13 $host $port + fi + done + +# Verify we can pull metadata from a few key testing images on quay.io +# in the 'libpod' namespace. This is mostly aimed at validating the +# quay.io service is up and responsive. Images were hand-picked with +# egrep -ro 'quay.io/libpod/.+:latest' test | sort -u +TEST_IMGS=(\ + alpine:latest + busybox:latest + alpine_labels:latest + alpine_nginx:latest + alpine_healthcheck:latest + badhealthcheck:latest + cirros:latest +) + +msg "Checking quay.io test image accessibility" +for testimg in "${TEST_IMGS[@]}"; do + fqin="quay.io/libpod/$testimg" + echo " $fqin" + # Belt-and-suspenders: Catch skopeo (somehow) returning False or null + # in addition to "bad" (invalid) JSON. + skopeo inspect --retry-times 5 "docker://$fqin" | jq -e . > /dev/null +done diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh index 6b2d123f2..d360f6a04 100755 --- a/contrib/cirrus/runner.sh +++ b/contrib/cirrus/runner.sh @@ -19,21 +19,6 @@ set -eo pipefail # shellcheck source=contrib/cirrus/lib.sh source $(dirname $0)/lib.sh -function _run_ext_svc() { - $SCRIPT_BASE/ext_svc_check.sh -} - -function _run_automation() { - $SCRIPT_BASE/cirrus_yaml_test.py - - req_env_vars CI DEST_BRANCH IMAGE_SUFFIX TEST_FLAVOR TEST_ENVIRON \ - PODBIN_NAME PRIV_NAME DISTRO_NV CONTAINER USER HOME \ - UID AUTOMATION_LIB_PATH SCRIPT_BASE OS_RELEASE_ID \ - CG_FS_TYPE - bigto ooe.sh dnf install -y ShellCheck # small/quick addition - $SCRIPT_BASE/shellcheck.sh -} - function _run_validate() { # TODO: aarch64 images need python3-devel installed # https://github.com/containers/automation_images/issues/159 @@ -226,15 +211,6 @@ eof rm -f $envvarsfile } -function _run_consistency() { - make vendor - SUGGESTION="run 'make vendor' and commit all changes" ./hack/tree_status.sh - make generate-bindings - SUGGESTION="run 'make generate-bindings' and commit all changes" ./hack/tree_status.sh - make completions - SUGGESTION="run 'make completions' and commit all changes" ./hack/tree_status.sh -} - function _run_build() { # Ensure always start from clean-slate with all vendor modules downloaded make clean @@ -422,6 +398,8 @@ function _bail_if_test_can_be_skipped() { return 0 fi + # Defined by Cirrus-CI for all tasks + # shellcheck disable=SC2154 head=$CIRRUS_CHANGE_IN_REPO base=$(git merge-base $DEST_BRANCH $head) diffs=$(git diff --name-only $base $head) diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index f84f78ee9..ca1e16544 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -228,25 +228,20 @@ esac # Required to be defined by caller: The primary type of testing that will be performed # shellcheck disable=SC2154 case "$TEST_FLAVOR" in - ext_svc) ;; 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 + make .install.pre-commit .install.gitvalidation ;; - automation) ;; altbuild) # Defined in .cirrus.yml # shellcheck disable=SC2154 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 install.tools make install PREFIX=/usr ETCDIR=/etc msg "Installing previously downloaded/cached packages" @@ -258,16 +253,14 @@ case "$TEST_FLAVOR" in ;; build) make clean ;; unit) - make install.tools + make .install.ginkgo ;; 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 @@ -276,16 +269,16 @@ case "$TEST_FLAVOR" in pip install --requirement $GOSRC/test/apiv2/python/requirements.txt ;& # continue with next item compose) - make install.tools dnf install -y $PACKAGE_DOWNLOAD_DIR/podman-docker* ;& # continue with next item - int) ;& + int) + make .install.ginkgo + ;& sys) ;& upgrade_test) ;& 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 @@ -309,7 +302,6 @@ case "$TEST_FLAVOR" in machine) dnf install -y $PACKAGE_DOWNLOAD_DIR/podman-gvproxy* remove_packaged_podman_files - make install.tools make install PREFIX=/usr ETCDIR=/etc install_test_configs ;; @@ -372,10 +364,6 @@ case "$TEST_FLAVOR" in docker.io/gitlab/gitlab-runner-helper:x86_64-latest-pwsh ;; swagger) ;& # use next item - consistency) - make clean - make install.tools - ;; release) ;; *) die_unknown TEST_FLAVOR esac diff --git a/contrib/cirrus/shellcheck.sh b/contrib/cirrus/shellcheck.sh deleted file mode 100755 index 667d30c91..000000000 --- a/contrib/cirrus/shellcheck.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -set -eo pipefail - -# shellcheck source=./contrib/cirrus/lib.sh -source $(dirname $0)/lib.sh - -cd $CIRRUS_WORKING_DIR -shellcheck --color=always --format=tty \ - --shell=bash --external-sources \ - --enable add-default-case,avoid-nullary-conditions,check-unassigned-uppercase \ - --exclude SC2046,SC2034,SC2090,SC2064 \ - --wiki-link-count=0 --severity=warning \ - $SCRIPT_BASE/*.sh hack/get_ci_vm.sh - -echo "Shellcheck: PASS" diff --git a/contrib/pkginstaller/scripts/postinstall b/contrib/pkginstaller/scripts/postinstall index db17eede8..c62971a14 100755 --- a/contrib/pkginstaller/scripts/postinstall +++ b/contrib/pkginstaller/scripts/postinstall @@ -2,26 +2,7 @@ set -e -BZSH_PODMAN_PATH_EXP='PATH="/opt/podman/bin:$PATH"' -FISH_PODMAN_PATH_EXP='set PATH "/opt/podman/bin $PATH"' -BASHRC_PATH="$HOME/.bash_profile" -ZSHENV_PATH="$HOME/.zshenv" -ZSHRC_PATH="$HOME/.zshrc" -FSHCFG_PATH="$HOME/.config/fish/config.fish" - -# append /Applications/podman/bin to $PATH -if [ -f "$BASHRC_PATH" ]; then - grep -Fxq "$BZSH_PODMAN_PATH_EXP" "$BASHRC_PATH" || echo "$BZSH_PODMAN_PATH_EXP" >> "$BASHRC_PATH" -fi -if [ -f "$ZSHENV_PATH" ]; then - grep -Fxq "$BZSH_PODMAN_PATH_EXP" "$ZSHENV_PATH" || echo "$BZSH_PODMAN_PATH_EXP" >> "$ZSHENV_PATH" -fi -if [ -f "$ZSHRC_PATH" ]; then - grep -Fxq "$BZSH_PODMAN_PATH_EXP" "$ZSHRC_PATH" || echo "$BZSH_PODMAN_PATH_EXP" >> "$ZSHRC_PATH" -fi -if [ -f "$FSHCFG_PATH" ]; then - grep -Fxq "$FISH_PODMAN_PATH_EXP" "$FSHCFG_PATH" || echo "$FISH_PODMAN_PATH_EXP" >> "$FSHCFG_PATH" -fi +echo "/opt/podman/bin" > /etc/paths.d/podman-pkg ln -s /opt/podman/bin/podman-mac-helper /opt/podman/qemu/bin/podman-mac-helper ln -s /opt/podman/bin/gvproxy /opt/podman/qemu/bin/gvproxy diff --git a/contrib/pkginstaller/scripts/preinstall b/contrib/pkginstaller/scripts/preinstall index a381868fc..22336222f 100755 --- a/contrib/pkginstaller/scripts/preinstall +++ b/contrib/pkginstaller/scripts/preinstall @@ -3,3 +3,7 @@ set -e rm -rf /opt/podman + +if [ ! -d "/etc/paths.d" ]; then + mkdir -p /etc/paths.d +fi diff --git a/contrib/podmanimage/README.md b/contrib/podmanimage/README.md index ab406a56a..8720b41c7 100644 --- a/contrib/podmanimage/README.md +++ b/contrib/podmanimage/README.md @@ -1,3 +1,16 @@ +[comment]: <> (***ATTENTION*** ***WARNING*** ***ALERT*** ***CAUTION*** ***DANGER***) +[comment]: <> () +[comment]: <> (ANY changes made to this file, once commited/merged must) +[comment]: <> (be manually copy/pasted -in markdown- into the description) +[comment]: <> (field on Quay at the following locations:) +[comment]: <> () +[comment]: <> (https://quay.io/repository/containers/podman) +[comment]: <> (https://quay.io/repository/podman/stable) +[comment]: <> (https://quay.io/repository/podman/testing) +[comment]: <> (https://quay.io/repository/podman/upstream) +[comment]: <> () +[comment]: <> (***ATTENTION*** ***WARNING*** ***ALERT*** ***CAUTION*** ***DANGER***) + ![PODMAN logo](https://raw.githubusercontent.com/containers/common/main/logos/podman-logo-full-vert.png) # podmanimage diff --git a/contrib/podmanremoteimage/Containerfile b/contrib/podmanremoteimage/Containerfile new file mode 100644 index 000000000..aa24b3956 --- /dev/null +++ b/contrib/podmanremoteimage/Containerfile @@ -0,0 +1,10 @@ +FROM registry.access.redhat.com/ubi8/go-toolset:latest AS builder +WORKDIR /opt/app-root/src +COPY . . +RUN make podman-remote-static +RUN GOOS=windows make podman-remote +RUN GOOS=darwin make podman-remote + +FROM scratch +COPY --from=builder /opt/app-root/src/bin . +ENTRYPOINT ["/podman-remote-static"] diff --git a/contrib/podmanremoteimage/README.md b/contrib/podmanremoteimage/README.md new file mode 100644 index 000000000..e43df9c64 --- /dev/null +++ b/contrib/podmanremoteimage/README.md @@ -0,0 +1,25 @@ +podman-remote-images +==================== + +Overview +-------- + +This directory contains the containerfile for creating a container image which consist podman-remote binary +for each platform (win/linux/mac). + +Users can copy those binaries onto the specific platforms using following instructions + +- For Windows binary +```bash +$ podman cp $(podman create --name remote-temp quay.io/containers/podman-remote-artifacts:latest):/windows/podman.exe . && podman rm remote-temp +``` + +- For Linux binary +```bash +$ podman cp $(podman create --name remote-temp quay.io/containers/podman-remote-artifacts:latest):/podman-remote-static . && podman rm remote-temp +``` + +- For Mac binary +```bash +$ podman cp $(podman create --name remote-temp quay.io/containers/podman-remote-artifacts:latest):/darwin/podman . && podman rm remote-temp +``` diff --git a/docs/source/markdown/.gitignore b/docs/source/markdown/.gitignore index af4c5360b..57a64e1c1 100644 --- a/docs/source/markdown/.gitignore +++ b/docs/source/markdown/.gitignore @@ -1,3 +1,4 @@ +podman-attach.1.md podman-auto-update.1.md podman-build.1.md podman-container-clone.1.md diff --git a/docs/source/markdown/options/device.md b/docs/source/markdown/options/device.md index 619c70a9b..bd6d7f9d9 100644 --- a/docs/source/markdown/options/device.md +++ b/docs/source/markdown/options/device.md @@ -12,3 +12,11 @@ The <<container|pod>> will only store the major and minor numbers of the host de Podman may load kernel modules required for using the specified device. The devices that Podman will load modules for when necessary are: /dev/fuse. + +In rootless mode, the new device is bind mounted in the container from the host +rather than Podman creating it within the container space. Because the bind +mount retains its SELinux label on SELinux systems, the container can get +permission denied when accessing the mounted device. Modify SELinux settings to +allow containers to use all device labels via the following command: + +$ sudo setsebool -P container_use_devices=true diff --git a/docs/source/markdown/options/env-file.md b/docs/source/markdown/options/env-file.md new file mode 100644 index 000000000..f08dc09f0 --- /dev/null +++ b/docs/source/markdown/options/env-file.md @@ -0,0 +1,3 @@ +#### **--env-file**=*file* + +Read in a line-delimited file of environment variables. diff --git a/docs/source/markdown/options/env.md b/docs/source/markdown/options/env.md new file mode 100644 index 000000000..ace25138e --- /dev/null +++ b/docs/source/markdown/options/env.md @@ -0,0 +1,5 @@ +#### **--env**, **-e**=*env* + +Set environment variables. + +This option allows arbitrary environment variables that are available for the process to be launched inside of the container. If an environment variable is specified without a value, Podman will check the host environment for a value and set the variable only if it is set on the host. As a special case, if an environment variable ending in __*__ is specified without a value, Podman will search the host environment for variables starting with the prefix and will add those variables to the container. diff --git a/docs/source/markdown/options/log-opt.md b/docs/source/markdown/options/log-opt.md new file mode 100644 index 000000000..4eafc1fb0 --- /dev/null +++ b/docs/source/markdown/options/log-opt.md @@ -0,0 +1,16 @@ +#### **--log-opt**=*name=value* + +Logging driver specific options. + +Set custom logging configuration. The following *name*s are supported: + +**path**: specify a path to the log file + (e.g. **--log-opt path=/var/log/container/mycontainer.json**); + +**max-size**: specify a max size of the log file + (e.g. **--log-opt max-size=10mb**); + +**tag**: specify a custom log tag for the container + (e.g. **--log-opt tag="{{.ImageName}}"**. +It supports the same keys as **podman inspect --format**. +This option is currently supported only by the **journald** log driver. diff --git a/docs/source/markdown/options/network.md b/docs/source/markdown/options/network.md new file mode 100644 index 000000000..e2a2dc36a --- /dev/null +++ b/docs/source/markdown/options/network.md @@ -0,0 +1,32 @@ +#### **--network**=*mode*, **--net** + +Set the network mode for the <<container|pod>>. + +Valid _mode_ values are: + +- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootful containers. It is possible to specify these additional options: + - **alias=name**: Add network-scoped alias for the container. + - **ip=IPv4**: Specify a static ipv4 address for this container. + - **ip=IPv6**: Specify a static ipv6 address for this container. + - **mac=MAC**: Specify a static mac address for this container. + - **interface_name**: Specify a name for the created network interface inside the container. + + For example to set a static ipv4 address and a static mac address, use `--network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99`. +- \<network name or ID\>[:OPTIONS,...]: Connect to a user-defined network; this is the network name or ID from a network created by **[podman network create](podman-network-create.1.md)**. Using the network name implies the bridge network mode. It is possible to specify the same options described under the bridge mode above. You can use the **--network** option multiple times to specify additional networks. +- **none**: Create a network namespace for the container but do not configure network interfaces for it, thus the container has no network connectivity. +- **container:**_id_: Reuse another container's network stack. +- **host**: Do not create a network namespace, the container will use the host's network. Note: The host mode gives the container full access to local system services such as D-bus and is therefore considered insecure. +- **ns:**_path_: Path to a network namespace to join. +- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootful containers and **slirp4netns** for rootless ones. +- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf: + - **allow_host_loopback=true|false**: Allow slirp4netns to reach the host loopback IP (default is 10.0.2.2 or the second IP from slirp4netns cidr subnet when changed, see the cidr option below). The default is false. + - **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`). + - **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`). + - **enable_ipv6=true|false**: Enable IPv6. Default is true. (Required for `outbound_addr6`). + - **outbound_addr=INTERFACE**: Specify the outbound interface slirp should bind to (ipv4 traffic only). + - **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp should bind to. + - **outbound_addr6=INTERFACE**: Specify the outbound interface slirp should bind to (ipv6 traffic only). + - **outbound_addr6=IPv6**: Specify the outbound ipv6 address slirp should bind to. + - **port_handler=rootlesskit**: Use rootlesskit for port forwarding. Default. + Note: Rootlesskit changes the source IP address of incoming packets to an IP address in the container network namespace, usually `10.0.2.100`. If your application requires the real source IP address, e.g. web server logs, use the slirp4netns port handler. The rootlesskit port handler is also used for rootless containers when connected to user-defined networks. + - **port_handler=slirp4netns**: Use the slirp4netns port forwarding, it is slower than rootlesskit but preserves the correct source IP address. This port handler cannot be used for user-defined networks. diff --git a/docs/source/markdown/options/sig-proxy.md b/docs/source/markdown/options/sig-proxy.md new file mode 100644 index 000000000..bb940aed3 --- /dev/null +++ b/docs/source/markdown/options/sig-proxy.md @@ -0,0 +1,3 @@ +#### **--sig-proxy** + +Proxy received signals to the container process (non-TTY mode only). SIGCHLD, SIGSTOP, and SIGKILL are not proxied. diff --git a/docs/source/markdown/options/sign-passphrase-file.md b/docs/source/markdown/options/sign-passphrase-file.md new file mode 100644 index 000000000..46e724db1 --- /dev/null +++ b/docs/source/markdown/options/sign-passphrase-file.md @@ -0,0 +1,3 @@ +#### **--sign-passphrase-file**=*path* + +If signing the image (using either **--sign-by** or **--sign-by-sigstore-private-key**), read the passphrase to use from the specified path. diff --git a/docs/source/markdown/podman-attach.1.md b/docs/source/markdown/podman-attach.1.md.in index c073fccf8..427f764dc 100644 --- a/docs/source/markdown/podman-attach.1.md +++ b/docs/source/markdown/podman-attach.1.md.in @@ -28,9 +28,8 @@ The default is **false**.\ Do not attach STDIN. The default is **false**. -#### **--sig-proxy** +@@option sig-proxy -Proxy received signals to the process (non-TTY mode only). SIGCHLD, SIGSTOP, and SIGKILL are not proxied.\ The default is **true**. ## EXAMPLES diff --git a/docs/source/markdown/podman-build.1.md.in b/docs/source/markdown/podman-build.1.md.in index e201806e5..e1ef13a0d 100644 --- a/docs/source/markdown/podman-build.1.md.in +++ b/docs/source/markdown/podman-build.1.md.in @@ -145,6 +145,10 @@ Limit the use of cached images to only consider images with created timestamps l For example if `--cache-ttl=1h` is specified, Buildah will only consider intermediate cache images which are created under the duration of one hour, and intermediate cache images outside this duration will be ignored. +Note: Setting `--cache-ttl=0` manually is equivalent to using `--no-cache` in the +implementation since this would effectively mean that user is not willing to use +cache at all. + #### **--cap-add**=*CAP\_xxx* When executing RUN instructions, run the command specified in the instruction @@ -564,6 +568,10 @@ as a seccomp filter Sign the image using a GPG key with the specified FINGERPRINT. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines,) +#### **--skip-unused-stages** + +Skip stages in multi-stage builds which don't affect the target stage. (Default: **true**). + #### **--squash** Squash all of the image's new layers into a single new layer; any preexisting diff --git a/docs/source/markdown/podman-create.1.md.in b/docs/source/markdown/podman-create.1.md.in index 742a32b5a..503e6fac7 100644 --- a/docs/source/markdown/podman-create.1.md.in +++ b/docs/source/markdown/podman-create.1.md.in @@ -151,17 +151,13 @@ This option cannot be combined with **--network** that is set to **none** or **c @@option entrypoint -#### **--env**, **-e**=*env* - -Set environment variables - -This option allows arbitrary environment variables that are available for the process to be launched inside of the container. If an environment variable is specified without a value, Podman will check the host environment for a value and set the variable only if it is set on the host. As a special case, if an environment variable ending in __*__ is specified without a value, Podman will search the host environment for variables starting with the prefix and will add those variables to the container. +@@option env See [**Environment**](#environment) note below for precedence and examples. -#### **--env-file**=*file* +@@option env-file -Read in a line delimited file of environment variables. See **Environment** note below for precedence. +See [**Environment**](#environment) note below for precedence and examples. @@option env-host @@ -232,22 +228,7 @@ pod when that pod is not running. @@option log-driver -#### **--log-opt**=*name=value* - -Set custom logging configuration. The following *name*s are supported: - -- **path**: specify a path to the log file -(e.g. **--log-opt path=/var/log/container/mycontainer.json**); - -- **max-size**: specify a max size of the log file -(e.g. **--log-opt max-size=10mb**); - -- **tag**: specify a custom log tag for the container -(e.g. **--log-opt tag="{{.ImageName}}"**. - -It supports the same keys as **podman inspect --format**. - -This option is currently supported only by the **journald** log driver. +@@option log-opt @@option mac-address @@ -263,38 +244,11 @@ This option is currently supported only by the **journald** log driver. @@option name.container -#### **--network**=*mode*, **--net** - -Set the network mode for the container. Invalid if using **--dns**, **--dns-option**, or **--dns-search** with **--network** set to **none** or **container:**_id_. If used together with **--pod**, the container will not join the pod's network namespace. - -Valid _mode_ values are: - -- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootful containers. It is possible to specify these additional options: - - **alias=name**: Add network-scoped alias for the container. - - **ip=IPv4**: Specify a static ipv4 address for this container. - - **ip=IPv6**: Specify a static ipv6 address for this container. - - **mac=MAC**: Specify a static mac address for this container. - - **interface_name**: Specify a name for the created network interface inside the container. - - For example to set a static ipv4 address and a static mac address, use `--network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99`. -- \<network name or ID\>[:OPTIONS,...]: Connect to a user-defined network; this is the network name or ID from a network created by **[podman network create](podman-network-create.1.md)**. Using the network name implies the bridge network mode. It is possible to specify the same options described under the bridge mode above. You can use the **--network** option multiple times to specify additional networks. -- **none**: Create a network namespace for the container but do not configure network interfaces for it, thus the container has no network connectivity. -- **container:**_id_: Reuse another container's network stack. -- **host**: Do not create a network namespace, the container will use the host's network. Note: The host mode gives the container full access to local system services such as D-bus and is therefore considered insecure. -- **ns:**_path_: Path to a network namespace to join. -- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootful containers and **slirp4netns** for rootless ones. -- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf: - - **allow_host_loopback=true|false**: Allow slirp4netns to reach the host loopback IP (default is 10.0.2.2 or the second IP from slirp4netns cidr subnet when changed, see the cidr option below). The default is false. - - **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`). - - **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`). - - **enable_ipv6=true|false**: Enable IPv6. Default is true. (Required for `outbound_addr6`). - - **outbound_addr=INTERFACE**: Specify the outbound interface slirp should bind to (ipv4 traffic only). - - **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp should bind to. - - **outbound_addr6=INTERFACE**: Specify the outbound interface slirp should bind to (ipv6 traffic only). - - **outbound_addr6=IPv6**: Specify the outbound ipv6 address slirp should bind to. - - **port_handler=rootlesskit**: Use rootlesskit for port forwarding. Default. - Note: Rootlesskit changes the source IP address of incoming packets to an IP address in the container network namespace, usually `10.0.2.100`. If your application requires the real source IP address, e.g. web server logs, use the slirp4netns port handler. The rootlesskit port handler is also used for rootless containers when connected to user-defined networks. - - **port_handler=slirp4netns**: Use the slirp4netns port forwarding, it is slower than rootlesskit but preserves the correct source IP address. This port handler cannot be used for user-defined networks. +@@option network + +Invalid if using **--dns**, **--dns-option**, or **--dns-search** with **--network** set to **none** or **container:**_id_. + +If used together with **--pod**, the container will not join the pod's network namespace. @@option network-alias diff --git a/docs/source/markdown/podman-events.1.md b/docs/source/markdown/podman-events.1.md index d0c95fe06..dd62ef5a2 100644 --- a/docs/source/markdown/podman-events.1.md +++ b/docs/source/markdown/podman-events.1.md @@ -95,6 +95,20 @@ In the case where an ID is used, the ID may be in its full or shortened form. Format the output to JSON Lines or using the given Go template. +| **Placeholder** | **Description** | +|--------------------|-----------------------------------------------| +| .Attributes | created_at, _by, labels, and more (map[]) | +| .ContainerExitCode | Exit code (int) | +| .Details ... | Internal structure, not actually useful | +| .HealthStatus | Health Status (string) | +| .ID | Container ID (full 64-bit SHA) | +| .Image | Name of image being run (string) | +| .Name | Container name (string) | +| .Network | Name of network being used (string) | +| .Status | Event status (e.g., create, start, died, ...) | +| .Time | Event timestamp (string) | +| .Type | Event type (e.g., image, container, pod, ...) | + #### **--help** Print usage statement. diff --git a/docs/source/markdown/podman-exec.1.md.in b/docs/source/markdown/podman-exec.1.md.in index 8198c319e..0479f2ee4 100644 --- a/docs/source/markdown/podman-exec.1.md.in +++ b/docs/source/markdown/podman-exec.1.md.in @@ -21,15 +21,9 @@ Start the exec session, but do not attach to it. The command will run in the bac Specify the key sequence for detaching a container. Format is a single character `[a-Z]` or one or more `ctrl-<value>` characters where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`. Specifying "" will disable this feature. The default is *ctrl-p,ctrl-q*. -#### **--env**, **-e**=*env* +@@option env -Set environment variables. - -This option allows arbitrary environment variables that are available for the process to be launched inside of the container. If an environment variable is specified without a value, Podman will check the host environment for a value and set the variable only if it is set on the host. As a special case, if an environment variable ending in __*__ is specified without a value, Podman will search the host environment for variables starting with the prefix and will add those variables to the container. - -#### **--env-file**=*file* - -Read in a line delimited file of environment variables. +@@option env-file @@option interactive diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md index b733cff8d..190b21b71 100644 --- a/docs/source/markdown/podman-generate-systemd.1.md +++ b/docs/source/markdown/podman-generate-systemd.1.md @@ -141,7 +141,8 @@ RequiresMountsFor=/var/run/container/storage [Service] Restart=always ExecStart=/usr/bin/podman start de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6 -ExecStop=/usr/bin/podman stop -t 1 de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6 +ExecStop=/usr/bin/podman stop \ + -t 1 de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6 KillMode=none Type=forking PIDFile=/run/user/1000/overlay-containers/de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6/userdata/conmon.pid @@ -171,14 +172,19 @@ RequiresMountsFor=/var/run/container/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure ExecStartPre=/bin/rm -f %t/%n-pid %t/%n-cid -ExecStart=/usr/local/bin/podman run - --conmon-pidfile %t/%n-pid - --cidfile %t/%n-cid - --cgroups=no-conmon - -d +ExecStart=/usr/local/bin/podman run \ + --conmon-pidfile %t/%n-pid \ + --cidfile %t/%n-cid \ + --cgroups=no-conmon \ + -d \ -dit alpine -ExecStop=/usr/local/bin/podman stop --ignore --cidfile %t/%n-cid -t 10 -ExecStopPost=/usr/local/bin/podman rm --ignore -f --cidfile %t/%n-cid +ExecStop=/usr/local/bin/podman stop \ + --ignore \ + --cidfile %t/%n-cid -t 10 +ExecStopPost=/usr/local/bin/podman rm \ + --ignore \ + -f \ + --cidfile %t/%n-cid PIDFile=%t/%n-pid KillMode=none Type=forking @@ -217,7 +223,8 @@ RequiresMountsFor=/var/run/container/storage [Service] Restart=on-failure ExecStart=/usr/bin/podman start 77a818221650-infra -ExecStop=/usr/bin/podman stop -t 10 77a818221650-infra +ExecStop=/usr/bin/podman stop \ + -t 10 77a818221650-infra KillMode=none Type=forking PIDFile=/run/user/1000/overlay-containers/ccfd5c71a088768774ca7bd05888d55cc287698dde06f475c8b02f696a25adcd/userdata/conmon.pid diff --git a/docs/source/markdown/podman-kube-play.1.md.in b/docs/source/markdown/podman-kube-play.1.md.in index 3bbe8113a..d3a6eaa03 100644 --- a/docs/source/markdown/podman-kube-play.1.md.in +++ b/docs/source/markdown/podman-kube-play.1.md.in @@ -146,58 +146,16 @@ Note: When joining multiple networks you should use the **--network name:ip=\<ip Set logging driver for all created containers. -#### **--log-opt**=*name=value* - -Set custom logging configuration. The following *name*s are supported: - -- **path**: specify a path to the log file -(e.g. **--log-opt path=/var/log/container/mycontainer.json**); - -- **max-size**: specify a max size of the log file -(e.g. **--log-opt max-size=10mb**); - -- **tag**: specify a custom log tag for the container -(e.g. **--log-opt tag="{{.ImageName}}"**. - -It supports the same keys as **podman inspect --format**. - -This option is currently supported only by the **journald** log driver. +@@option log-opt #### **--mac-address**=*MAC address* Assign a static mac address to the pod. This option can be specified several times when kube play creates more than one pod. Note: When joining multiple networks you should use the **--network name:mac=\<mac\>** syntax. -#### **--network**=*mode*, **--net** - -Change the network mode of the pod. The host network mode should be configured in the YAML file. -Valid _mode_ values are: - -- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootful containers. It is possible to specify these additional options: - - **alias=name**: Add network-scoped alias for the container. - - **ip=IPv4**: Specify a static ipv4 address for this container. - - **ip=IPv6**: Specify a static ipv6 address for this container. - - **mac=MAC**: Specify a static mac address for this container. - - **interface_name**: Specify a name for the created network interface inside the container. - - For example to set a static ipv4 address and a static mac address, use `--network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99`. -- \<network name or ID\>[:OPTIONS,...]: Connect to a user-defined network; this is the network name or ID from a network created by **[podman network create](podman-network-create.1.md)**. Using the network name implies the bridge network mode. It is possible to specify the same options described under the bridge mode above. You can use the **--network** option multiple times to specify additional networks. -- **none**: Create a network namespace for the container but do not configure network interfaces for it, thus the container has no network connectivity. -- **container:**_id_: Reuse another container's network stack. -- **ns:**_path_: Path to a network namespace to join. -- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootful containers and **slirp4netns** for rootless ones. -- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf: - - **allow_host_loopback=true|false**: Allow slirp4netns to reach the host loopback IP (default is 10.0.2.2 or the second IP from slirp4netns cidr subnet when changed, see the cidr option below). The default is false. - - **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`). - - **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`). - - **enable_ipv6=true|false**: Enable IPv6. Default is true. (Required for `outbound_addr6`). - - **outbound_addr=INTERFACE**: Specify the outbound interface slirp should bind to (ipv4 traffic only). - - **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp should bind to. - - **outbound_addr6=INTERFACE**: Specify the outbound interface slirp should bind to (ipv6 traffic only). - - **outbound_addr6=IPv6**: Specify the outbound ipv6 address slirp should bind to. - - **port_handler=rootlesskit**: Use rootlesskit for port forwarding. Default. - Note: Rootlesskit changes the source IP address of incoming packets to an IP address in the container network namespace, usually `10.0.2.100`. If your application requires the real source IP address, e.g. web server logs, use the slirp4netns port handler. The rootlesskit port handler is also used for rootless containers when connected to user-defined networks. - - **port_handler=slirp4netns**: Use the slirp4netns port forwarding, it is slower than rootlesskit but preserves the correct source IP address. This port handler cannot be used for user-defined networks. +@@option network + +The *host* network mode should be configured in the YAML file. @@option no-hosts diff --git a/docs/source/markdown/podman-machine-list.1.md b/docs/source/markdown/podman-machine-list.1.md index 351e8cf1b..0c929dcdc 100644 --- a/docs/source/markdown/podman-machine-list.1.md +++ b/docs/source/markdown/podman-machine-list.1.md @@ -1,4 +1,4 @@ -% podman-machine-ls 1 +% podman-machine-list 1 ## NAME podman\-machine\-list - List virtual machines diff --git a/docs/source/markdown/podman-manifest-push.1.md.in b/docs/source/markdown/podman-manifest-push.1.md.in index fe0a534c9..8b91f504c 100644 --- a/docs/source/markdown/podman-manifest-push.1.md.in +++ b/docs/source/markdown/podman-manifest-push.1.md.in @@ -55,9 +55,7 @@ Sign the pushed images with a “simple signing” signature using the specified Sign the pushed images with a sigstore signature using a private key at the specified path. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines) -#### **--sign-passphrase-file**=*path* - -If signing the image (using either **--sign-by** or **--sign-by-sigstore-private-key**), read the passphrase to use from the specified path. +@@option sign-passphrase-file @@option tls-verify diff --git a/docs/source/markdown/podman-pod-create.1.md.in b/docs/source/markdown/podman-pod-create.1.md.in index fdae1d249..14c798772 100644 --- a/docs/source/markdown/podman-pod-create.1.md.in +++ b/docs/source/markdown/podman-pod-create.1.md.in @@ -117,38 +117,9 @@ The custom image that will be used for the infra container. Unless specified, P Assign a name to the pod. -#### **--network**=*mode*, **--net** - -Set the network mode for the pod. Invalid if using **--dns**, **--dns-option**, or **--dns-search** with **--network** that is set to **none** or **container:**_id_. - -Valid _mode_ values are: - -- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootful containers. It is possible to specify these additional options: - - **alias=name**: Add network-scoped alias for the container. - - **ip=IPv4**: Specify a static ipv4 address for this container. - - **ip=IPv6**: Specify a static ipv6 address for this container. - - **mac=MAC**: Specify a static mac address for this container. - - **interface_name**: Specify a name for the created network interface inside the container. - - For example to set a static ipv4 address and a static mac address, use `--network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99`. -- \<network name or ID\>[:OPTIONS,...]: Connect to a user-defined network; this is the network name or ID from a network created by **[podman network create](podman-network-create.1.md)**. Using the network name implies the bridge network mode. It is possible to specify the same options described under the bridge mode above. You can use the **--network** option multiple times to specify additional networks. -- **none**: Create a network namespace for the container but do not configure network interfaces for it, thus the container has no network connectivity. -- **container:**_id_: Reuse another container's network stack. -- **host**: Do not create a network namespace, the container will use the host's network. Note: The host mode gives the container full access to local system services such as D-bus and is therefore considered insecure. -- **ns:**_path_: Path to a network namespace to join. -- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootful containers and **slirp4netns** for rootless ones. -- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf: - - **allow_host_loopback=true|false**: Allow slirp4netns to reach the host loopback IP (default is 10.0.2.2 or the second IP from slirp4netns cidr subnet when changed, see the cidr option below). The default is false. - - **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`). - - **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`). - - **enable_ipv6=true|false**: Enable IPv6. Default is true. (Required for `outbound_addr6`). - - **outbound_addr=INTERFACE**: Specify the outbound interface slirp should bind to (ipv4 traffic only). - - **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp should bind to. - - **outbound_addr6=INTERFACE**: Specify the outbound interface slirp should bind to (ipv6 traffic only). - - **outbound_addr6=IPv6**: Specify the outbound ipv6 address slirp should bind to. - - **port_handler=rootlesskit**: Use rootlesskit for port forwarding. Default. - Note: Rootlesskit changes the source IP address of incoming packets to an IP address in the container network namespace, usually `10.0.2.100`. If your application requires the real source IP address, e.g. web server logs, use the slirp4netns port handler. The rootlesskit port handler is also used for rootless containers when connected to user-defined networks. - - **port_handler=slirp4netns**: Use the slirp4netns port forwarding, it is slower than rootlesskit but preserves the correct source IP address. This port handler cannot be used for user-defined networks. +@@option network + +Invalid if using **--dns**, **--dns-option**, or **--dns-search** with **--network** set to **none** or **container:**_id_. @@option network-alias diff --git a/docs/source/markdown/podman-push.1.md.in b/docs/source/markdown/podman-push.1.md.in index c679950f7..dd2a9feae 100644 --- a/docs/source/markdown/podman-push.1.md.in +++ b/docs/source/markdown/podman-push.1.md.in @@ -86,9 +86,7 @@ Add a “simple signing” signature at the destination using the specified key. Add a sigstore signature at the destination using a private key at the specified path. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines) -#### **--sign-passphrase-file**=*path* - -If signing the image (using either **--sign-by** or **--sign-by-sigstore-private-key**), read the passphrase to use from the specified path. +@@option sign-passphrase-file @@option tls-verify diff --git a/docs/source/markdown/podman-run.1.md.in b/docs/source/markdown/podman-run.1.md.in index 2109a0e33..88547e126 100644 --- a/docs/source/markdown/podman-run.1.md.in +++ b/docs/source/markdown/podman-run.1.md.in @@ -187,17 +187,13 @@ This option cannot be combined with **--network** that is set to **none** or **c @@option entrypoint -#### **--env**, **-e**=*env* - -Set environment variables. - -This option allows arbitrary environment variables that are available for the process to be launched inside of the container. If an environment variable is specified without a value, Podman will check the host environment for a value and set the variable only if it is set on the host. As a special case, if an environment variable ending in __*__ is specified without a value, Podman will search the host environment for variables starting with the prefix and will add those variables to the container. +@@option env See [**Environment**](#environment) note below for precedence and examples. -#### **--env-file**=*file* +@@option env-file -Read in a line delimited file of environment variables. See **Environment** note below for precedence. +See [**Environment**](#environment) note below for precedence and examples. @@option env-host @@ -253,22 +249,7 @@ Print usage statement @@option log-driver -#### **--log-opt**=*name=value* - -Logging driver specific options. - -Set custom logging configuration. The following *name*s are supported: - -**path**: specify a path to the log file - (e.g. **--log-opt path=/var/log/container/mycontainer.json**); - -**max-size**: specify a max size of the log file - (e.g. **--log-opt max-size=10mb**); - -**tag**: specify a custom log tag for the container - (e.g. **--log-opt tag="{{.ImageName}}"**. - -This option is currently supported only by the **journald** log driver. +@@option log-opt @@option mac-address @@ -284,38 +265,11 @@ This option is currently supported only by the **journald** log driver. @@option name.container -#### **--network**=*mode*, **--net** - -Set the network mode for the container. Invalid if using **--dns**, **--dns-option**, or **--dns-search** with **--network** set to **none** or **container:**_id_. If used together with **--pod**, the container will not join the pod's network namespace. - -Valid _mode_ values are: - -- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootful containers. It is possible to specify these additional options: - - **alias=name**: Add network-scoped alias for the container. - - **ip=IPv4**: Specify a static ipv4 address for this container. - - **ip=IPv6**: Specify a static ipv6 address for this container. - - **mac=MAC**: Specify a static mac address for this container. - - **interface_name**: Specify a name for the created network interface inside the container. - - For example to set a static ipv4 address and a static mac address, use `--network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99`. -- \<network name or ID\>[:OPTIONS,...]: Connect to a user-defined network; this is the network name or ID from a network created by **[podman network create](podman-network-create.1.md)**. Using the network name implies the bridge network mode. It is possible to specify the same options described under the bridge mode above. You can use the **--network** option multiple times to specify additional networks. -- **none**: Create a network namespace for the container but do not configure network interfaces for it, thus the container has no network connectivity. -- **container:**_id_: Reuse another container's network stack. -- **host**: Do not create a network namespace, the container will use the host's network. Note: The host mode gives the container full access to local system services such as D-bus and is therefore considered insecure. -- **ns:**_path_: Path to a network namespace to join. -- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootful containers and **slirp4netns** for rootless ones. -- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf: - - **allow_host_loopback=true|false**: Allow slirp4netns to reach the host loopback IP (default is 10.0.2.2 or the second IP from slirp4netns cidr subnet when changed, see the cidr option below). The default is false. - - **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`). - - **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`). - - **enable_ipv6=true|false**: Enable IPv6. Default is true. (Required for `outbound_addr6`). - - **outbound_addr=INTERFACE**: Specify the outbound interface slirp should bind to (ipv4 traffic only). - - **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp should bind to. - - **outbound_addr6=INTERFACE**: Specify the outbound interface slirp should bind to (ipv6 traffic only). - - **outbound_addr6=IPv6**: Specify the outbound ipv6 address slirp should bind to. - - **port_handler=rootlesskit**: Use rootlesskit for port forwarding. Default. - Note: Rootlesskit changes the source IP address of incoming packets to an IP address in the container network namespace, usually `10.0.2.100`. If your application requires the real source IP address, e.g. web server logs, use the slirp4netns port handler. The rootlesskit port handler is also used for rootless containers when connected to user-defined networks. - - **port_handler=slirp4netns**: Use the slirp4netns port forwarding, it is slower than rootlesskit but preserves the correct source IP address. This port handler cannot be used for user-defined networks. +@@option network + +Invalid if using **--dns**, **--dns-option**, or **--dns-search** with **--network** set to **none** or **container:**_id_. + +If used together with **--pod**, the container will not join the pod's network namespace. @@option network-alias @@ -439,9 +393,9 @@ Note: Labeling can be disabled for all containers by setting **label=false** in @@option shm-size -#### **--sig-proxy** +@@option sig-proxy -Sets whether the signals sent to the **podman run** command are proxied to the container process. SIGCHLD, SIGSTOP, and SIGKILL are not proxied. The default is **true**. +The default is **true**. @@option stop-signal diff --git a/docs/source/markdown/podman-secret-create.1.md b/docs/source/markdown/podman-secret-create.1.md index 1aafc6c11..fc6d72efb 100644 --- a/docs/source/markdown/podman-secret-create.1.md +++ b/docs/source/markdown/podman-secret-create.1.md @@ -26,16 +26,20 @@ Specify the secret driver (default **file**, which is unencrypted). #### **--driver-opts**=*key1=val1,key2=val2* -Specify driver specific options +Specify driver specific options. #### **--env**=*false* -Read secret data from environment variable +Read secret data from environment variable. #### **--help** Print usage statement. +#### **--label**, **-l**=*key=val1,key2=val2* + +Add label to secret. These labels can be viewed in podman secrete inspect or ls. + ## EXAMPLES ``` diff --git a/docs/source/markdown/podman-secret-inspect.1.md b/docs/source/markdown/podman-secret-inspect.1.md index 77d9276bd..b5bcd2b92 100644 --- a/docs/source/markdown/podman-secret-inspect.1.md +++ b/docs/source/markdown/podman-secret-inspect.1.md @@ -34,6 +34,10 @@ Format secret output using Go template. Print usage statement. +#### **--pretty** + +Print inspect output in human-readable format + ## EXAMPLES diff --git a/docs/source/markdown/podman-start.1.md.in b/docs/source/markdown/podman-start.1.md.in index 6fa41018b..a1ccc4120 100644 --- a/docs/source/markdown/podman-start.1.md.in +++ b/docs/source/markdown/podman-start.1.md.in @@ -60,9 +60,9 @@ Valid filters are listed below: Instead of providing the container name or ID, use the last created container. If you use methods other than Podman to run containers such as CRI-O, the last started container could be from either of those methods. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines) -#### **--sig-proxy** +@@option sig-proxy -Proxy received signals to the process (non-TTY mode only). SIGCHLD, SIGSTOP, and SIGKILL are not proxied. The default is *true* when attaching, *false* otherwise. +The default is **true** when attaching, **false** otherwise. ## EXAMPLE diff --git a/docs/source/markdown/podman-system-connection-list.1.md b/docs/source/markdown/podman-system-connection-list.1.md index 325c78a5c..99804f77f 100644 --- a/docs/source/markdown/podman-system-connection-list.1.md +++ b/docs/source/markdown/podman-system-connection-list.1.md @@ -13,7 +13,7 @@ List ssh destination(s) for podman service(s). ## OPTIONS -#### **--format**=*format* +#### **--format**, **-f**=*format* Change the default output format. This can be of a supported type like 'json' or a Go template. Valid placeholders for the Go template listed below: @@ -25,6 +25,10 @@ Valid placeholders for the Go template listed below: | .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 | +#### **--quiet**, **-q** + +Only show connection names + ## EXAMPLE ``` $ podman system connection list diff --git a/docs/source/markdown/podman-system-service.1.md b/docs/source/markdown/podman-system-service.1.md index 2ec48aeb4..2293dea0a 100644 --- a/docs/source/markdown/podman-system-service.1.md +++ b/docs/source/markdown/podman-system-service.1.md @@ -1,4 +1,4 @@ -% podman-service 1 +% podman-system-service 1 ## NAME podman\-system\-service - Run an API service diff --git a/docs/source/markdown/podman-volume-create.1.md b/docs/source/markdown/podman-volume-create.1.md index 934488111..1e99df55a 100644 --- a/docs/source/markdown/podman-volume-create.1.md +++ b/docs/source/markdown/podman-volume-create.1.md @@ -17,7 +17,13 @@ driver options can be set using the **--opt** flag. #### **--driver**=*driver* -Specify the volume driver name (default **local**). Setting this to a value other than **local** Podman attempts to create the volume using a volume plugin with the given name. Such plugins must be defined in the **volume_plugins** section of the **[containers.conf(5)](https://github.com/containers/common/blob/main/docs/containers.conf.5.md)** configuration file. +Specify the volume driver name (default **local**). +There are two drivers supported by Podman itself: **local** and **image**. +The **local** driver uses a directory on disk as the backend by default, but can also use the **mount(8)** command to mount a filesystem as the volume if **--opt** is specified. +The **image** driver uses an image as the backing store of for the volume. +An overlay filesystem will be created, which allows changes to the volume to be committed as a new layer on top of the image. +Using a value other than **local or **image**, Podman will attempt to create the volume using a volume plugin with the given name. +Such plugins must be defined in the **volume_plugins** section of the **[containers.conf(5)](https://github.com/containers/common/blob/main/docs/containers.conf.5.md)** configuration file. #### **--help** @@ -43,7 +49,10 @@ The `o` option sets options for the mount, and is equivalent to the `-o` flag to - The `o` option supports using volume options other than the UID/GID options with the **local** driver and requires root privileges. - The `o` options supports the `timeout` option which allows users to set a driver specific timeout in seconds before volume creation fails. For example, **--opts=o=timeout=10** sets a driver timeout of 10 seconds. -When not using the **local** driver, the given options are passed directly to the volume plugin. In this case, supported options are dictated by the plugin in question, not Podman. +For the **image** driver, the only supported option is `image`, which specifies the image the volume is based on. +This option is mandatory when using the **image** driver. + +When not using the **local** and **image** drivers, the given options are passed directly to the volume plugin. In this case, supported options are dictated by the plugin in question, not Podman. ## EXAMPLES @@ -57,6 +66,8 @@ $ podman volume create --label foo=bar myvol # podman volume create --opt device=tmpfs --opt type=tmpfs --opt o=nodev,noexec myvol # podman volume create --opt device=tmpfs --opt type=tmpfs --opt o=uid=1000,gid=1000 testvol + +# podman volume create --driver image --opt image=fedora:latest fedoraVol ``` ## QUOTAS @@ -8,16 +8,16 @@ require ( github.com/buger/goterm v1.0.4 github.com/checkpoint-restore/checkpointctl v0.0.0-20220321135231-33f4a66335f0 github.com/checkpoint-restore/go-criu/v5 v5.3.0 - github.com/container-orchestrated-devices/container-device-interface v0.5.1 + github.com/container-orchestrated-devices/container-device-interface v0.5.2 github.com/containernetworking/cni v1.1.2 github.com/containernetworking/plugins v1.1.1 - github.com/containers/buildah v1.27.1-0.20220907121344-97a52b13bb27 - github.com/containers/common v0.49.2-0.20220909190843-e5685792b5d7 + github.com/containers/buildah v1.27.1-0.20220921131114-d3064796af36 + github.com/containers/common v0.50.1 github.com/containers/conmon v2.0.20+incompatible - github.com/containers/image/v5 v5.22.1-0.20220907162003-651744379993 + github.com/containers/image/v5 v5.23.0 github.com/containers/ocicrypt v1.1.5 github.com/containers/psgo v1.7.3 - github.com/containers/storage v1.42.1-0.20220911223137-e11b246de159 + github.com/containers/storage v1.43.0 github.com/coreos/go-systemd/v22 v22.4.0 github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3 github.com/cyphar/filepath-securejoin v0.2.3 @@ -44,11 +44,11 @@ require ( github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.20.2 github.com/opencontainers/go-digest v1.0.0 - github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 + github.com/opencontainers/image-spec v1.1.0-rc1 github.com/opencontainers/runc v1.1.4 github.com/opencontainers/runtime-spec v1.0.3-0.20211214071223-8958f93039ab github.com/opencontainers/runtime-tools v0.9.1-0.20220714195903-17b3287fafb7 - github.com/opencontainers/selinux v1.10.1 + github.com/opencontainers/selinux v1.10.2 github.com/openshift/imagebuilder v1.2.4-0.20220711175835-4151e43600df github.com/rootless-containers/rootlesskit v1.0.1 github.com/sirupsen/logrus v1.9.0 @@ -62,7 +62,7 @@ require ( github.com/vishvananda/netlink v1.1.1-0.20220115184804-dd687eb2f2d4 go.etcd.io/bbolt v1.3.6 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 - golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 + golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 golang.org/x/text v0.3.7 google.golang.org/protobuf v1.28.1 @@ -86,30 +86,29 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/digitalocean/go-libvirt v0.0.0-20201209184759-e2a69bcd5bd1 // indirect github.com/disiqueira/gotree/v3 v3.0.2 // indirect - github.com/docker/docker-credential-helpers v0.6.4 // indirect + github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsouza/go-dockerclient v1.8.3 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-containerregistry v0.11.0 // indirect github.com/google/go-intervals v0.0.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/honeycombio/libhoney-go v1.15.8 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jinzhu/copier v0.3.5 // indirect - github.com/klauspost/compress v1.15.9 // indirect - github.com/klauspost/pgzip v1.2.5 // indirect + github.com/klauspost/compress v1.15.11 // indirect + github.com/klauspost/pgzip v1.2.6-0.20220930104621-17e8dac29df8 // indirect github.com/kr/fs v0.1.0 // indirect github.com/letsencrypt/boulder v0.0.0-20220723181115-27de4befb95e // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect - github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible // indirect + github.com/mistifyio/go-zfs/v3 v3.0.0 // indirect github.com/moby/sys/mount v0.3.3 // indirect github.com/moby/sys/mountinfo v0.6.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -123,21 +122,22 @@ require ( github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/seccomp/libseccomp-golang v0.10.0 // indirect - github.com/sigstore/sigstore v1.4.0 // indirect + github.com/sigstore/sigstore v1.4.2 // indirect github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 // indirect - github.com/sylabs/sif/v2 v2.7.2 // indirect + github.com/sylabs/sif/v2 v2.8.0 // indirect github.com/tchap/go-patricia v2.3.0+incompatible // indirect - github.com/theupdateframework/go-tuf v0.4.0 // indirect + github.com/theupdateframework/go-tuf v0.5.1 // indirect github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect github.com/vbatts/tar-split v0.11.2 // indirect github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect + github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect go.opencensus.io v0.23.0 // indirect - golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect - golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect + golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 // indirect + golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect golang.org/x/tools v0.1.12 // indirect google.golang.org/genproto v0.0.0-20220720214146-176da50484ac // indirect google.golang.org/grpc v1.48.0 // indirect @@ -86,7 +86,6 @@ github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSW github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= -github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= @@ -155,13 +154,11 @@ github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb0 github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= -github.com/ProtonMail/go-crypto v0.0.0-20220517143526-88bb52951d5b/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/ReneKroon/ttlcache/v2 v2.11.0/go.mod h1:mBxvsNY+BT8qLLd6CuAJubbKo6r0jh3nb5et22bbfGY= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= @@ -185,7 +182,6 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -196,32 +192,50 @@ github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZo github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.44.44/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.76/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go-v2 v1.16.5/go.mod h1:Wh7MEsmEApyL5hrWzpDkba4gwAPc5/piwLVLFnCxp48= +github.com/aws/aws-sdk-go v1.44.96/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.102/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go-v2 v1.16.11/go.mod h1:WTACcleLz6VZTp7fak4EO5b9Q4foxbn+8PIz3PmyKlo= -github.com/aws/aws-sdk-go-v2/config v1.15.11/go.mod h1:mD5tNFciV7YHNjPpFYqJ6KGpoSfY107oZULvTHIxtbI= +github.com/aws/aws-sdk-go-v2 v1.16.14/go.mod h1:s/G+UV29dECbF5rf+RNj1xhlmvoNurGSr+McVSRj59w= +github.com/aws/aws-sdk-go-v2 v1.16.15/go.mod h1:SwiyXi/1zTUZ6KIAmLK5V5ll8SiURNUYOqTerZPaF9k= +github.com/aws/aws-sdk-go-v2 v1.16.16/go.mod h1:SwiyXi/1zTUZ6KIAmLK5V5ll8SiURNUYOqTerZPaF9k= github.com/aws/aws-sdk-go-v2/config v1.17.0/go.mod h1:4SKzBMiB8lV0fw2w7eDBo/LjQyHFITN4vUUuqpurFmI= -github.com/aws/aws-sdk-go-v2/credentials v1.12.6/go.mod h1:mQgnRmBPF2S/M01W4T4Obp3ZaZB6o1s/R8cOUda9vtI= +github.com/aws/aws-sdk-go-v2/config v1.17.5/go.mod h1:H0cvPNDO3uExWts/9PDhD/0ne2esu1uaIulwn1vkwxM= +github.com/aws/aws-sdk-go-v2/config v1.17.7/go.mod h1:dN2gja/QXxFF15hQreyrqYhLBaQo1d9ZKe/v/uplQoI= github.com/aws/aws-sdk-go-v2/credentials v1.12.13/go.mod h1:9fDEemXizwXrxPU1MTzv69LP/9D8HVl5qHAQO9A9ikY= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.6/go.mod h1:ClLMcuQA/wcHPmOIfNzNI4Y1Q0oDbmEkbYhMFOzHDh8= +github.com/aws/aws-sdk-go-v2/credentials v1.12.18/go.mod h1:O7n/CPagQ33rfG6h7vR/W02ammuc5CrsSM22cNZp9so= +github.com/aws/aws-sdk-go-v2/credentials v1.12.20/go.mod h1:UKY5HyIux08bbNA7Blv4PcXQ8cTkGh7ghHMFklaviR4= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.12/go.mod h1:aZ4vZnyUuxedC7eD4JyEHpGnCz+O2sHQEx3VvAwklSE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.12/go.mod h1:Afj/U8svX6sJ77Q+FPWMzabJ9QjbwP32YlopgKALUpg= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.15/go.mod h1:Oz2/qWINxIgSmoZT9adpxJy2UhpcOAI3TIyWgYMVSz0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17/go.mod h1:yIkQcCDYNsZfXpd5UX2Cy+sWA1jPgIhGTw9cOBzfVnQ= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.18/go.mod h1:348MLhzV1GSlZSMusdwQpXKbhD7X2gbI/TxwAPKkYZQ= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.6/go.mod h1:FwpAKI+FBPIELJIdmQzlLtRe8LQSOreMcM2wBsPMvvc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.21/go.mod h1:XsmHMV9c512xgsW01q7H0ut+UQQQpWX8QsFbdLHDwaU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.22/go.mod h1:/vNv5Al0bpiF8YdX2Ov6Xy05VTiXsql94yUqJMYaj0w= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23/go.mod h1:2DFxAQ9pfIRy0imBCJv+vZ2X6RKxves6fbnEuSry6b4= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.12/go.mod h1:ckaCVTEdGAxO6KwTGzgskxR1xM+iJW4lxMyDFVda2Fc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.13/go.mod h1:hiM/y1XPp3DoEPhoVEYc/CZcS58dP6RKJRDFp99wdX0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.15/go.mod h1:kjJ4CyD9M3Wq88GYg3IPfj67Rs0Uvz8aXK7MJ8BvE4I= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.16/go.mod h1:62dsXI0BqTIGomDl8Hpm33dv0OntGaVblri3ZRParVQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17/go.mod h1:pRwaTYCJemADaqCbUAxltMoHKata7hmB5PjEXeu0kfg= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.19/go.mod h1:cVHo8KTuHjShb9V8/VjH3S/8+xPu16qx8fdGwmotJhE= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.6/go.mod h1:DxAPjquoEHf3rUHh1b9+47RAaXB8/7cB6jkzCt/GOEI= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.22/go.mod h1:tltHVGy977LrSOgRR5aV9+miyno/Gul/uJNPKS7FzP4= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24/go.mod h1:jULHjqqjDlbyTa7pfM7WICATnOv+iOhjletM3N0Xbu8= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.12/go.mod h1:1TODGhheLWjpQWSuhYuAUWYTCKwEjx2iblIFKDHjeTc= -github.com/aws/aws-sdk-go-v2/service/kms v1.17.3/go.mod h1:EKkrWWXwWYf8x3Nrm6Oix3zZP9NRBHqxw5buFGVBHA0= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.15/go.mod h1:ZVJ7ejRl4+tkWMuCwjXoy0jd8fF5u3RCyWjSVjUIvQE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17/go.mod h1:4nYOrY41Lrbk2170/BGkcJKBhws9Pfn8MG3aGqjjeFI= github.com/aws/aws-sdk-go-v2/service/kms v1.18.4/go.mod h1:WG8HUJKtDqXJM3+CNZeN+2wvdcJb5vprKo01fr1KQW4= -github.com/aws/aws-sdk-go-v2/service/sso v1.11.9/go.mod h1:UqRD9bBt15P0ofRyDZX6CfsIqPpzeHOhZKWzgSuAzpo= +github.com/aws/aws-sdk-go-v2/service/kms v1.18.9/go.mod h1:8sR6O18d56mlJf0VkYD7mOtrBoM//8eym7FcfG1t9Sc= +github.com/aws/aws-sdk-go-v2/service/kms v1.18.10/go.mod h1:45pB2oUV71tilooilIi3dC1KVWWJHHhc7JnyqByuheo= github.com/aws/aws-sdk-go-v2/service/sso v1.11.16/go.mod h1:mS5xqLZc/6kc06IpXn5vRxdLaED+jEuaSRv5BxtnsiY= -github.com/aws/aws-sdk-go-v2/service/sts v1.16.7/go.mod h1:lVxTdiiSHY3jb1aeg+BBFtDzZGSUCv6qaNOyEGCJ1AY= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.21/go.mod h1:q8nYq51W3gpZempYsAD83fPRlrOTMCwN+Ahg4BKFTXQ= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.23/go.mod h1:/w0eg9IhFGjGyyncHIQrXtU8wvNsTJOP0R6PPj0wf80= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.3/go.mod h1:+IF75RMJh0+zqTGXGshyEGRsU2ImqWv6UuHGkHl6kEo= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.5/go.mod h1:csZuQY65DAdFBt1oIjO5hhBR49kQqop4+lcuCjf2arA= github.com/aws/aws-sdk-go-v2/service/sts v1.16.13/go.mod h1:Ru3QVMLygVs/07UQ3YDur1AQZZp2tUNje8wfloFttC0= -github.com/aws/smithy-go v1.11.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.17/go.mod h1:bQujK1n0V1D1Gz5uII1jaB1WDvhj4/T3tElsJnVXCR0= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.19/go.mod h1:h4J3oPZQbxLhzGnk+j9dfYHi5qIOVJ5kczZd658/ydM= github.com/aws/smithy-go v1.12.1/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.13.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.13.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beeker1121/goque v1.0.3-0.20191103205551-d618510128af/go.mod h1:84CWnaDz4g1tEVnFLnuBigmGK15oPohy0RfvSN8d4eg= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= @@ -309,8 +323,8 @@ github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= -github.com/container-orchestrated-devices/container-device-interface v0.5.1 h1:nXIUTrlEgGcA/n2geY3J7yyaGGhkocSlMkKPS4Qp4c0= -github.com/container-orchestrated-devices/container-device-interface v0.5.1/go.mod h1:ZToWfSyUH5l9Rk7/bjkUUkNLz4b1mE+CVUVafuikDPY= +github.com/container-orchestrated-devices/container-device-interface v0.5.2 h1:Bf/Zq8UBhbSBtB+pFBVIQ2Rh7sNK/x2ZEr6uW5YjNv8= +github.com/container-orchestrated-devices/container-device-interface v0.5.2/go.mod h1:ZToWfSyUH5l9Rk7/bjkUUkNLz4b1mE+CVUVafuikDPY= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= @@ -391,7 +405,6 @@ github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oM github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM= github.com/containerd/stargz-snapshotter/estargz v0.9.0/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0= -github.com/containerd/stargz-snapshotter/estargz v0.11.4/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0= github.com/containerd/stargz-snapshotter/estargz v0.12.0 h1:idtwRTLjk2erqiYhPWy2L844By8NRFYEwYHcXhoIWPM= github.com/containerd/stargz-snapshotter/estargz v0.12.0/go.mod h1:AIQ59TewBFJ4GOPEQXujcrJ/EKxh5xXZegW1rkR1P/M= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= @@ -421,16 +434,17 @@ github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRD github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE= github.com/containernetworking/plugins v1.1.1 h1:+AGfFigZ5TiQH00vhR8qPeSatj53eNGz0C1d3wVYlHE= github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8= -github.com/containers/buildah v1.27.1-0.20220907121344-97a52b13bb27 h1:LRgKJ/JUd6iTocPg/q7oMZ9ilnbew50JXClXgiEoR9Q= -github.com/containers/buildah v1.27.1-0.20220907121344-97a52b13bb27/go.mod h1:0iWhIkE70dkoVuwpmZy5/DXpBdI3C23iYmBQccTDWMU= -github.com/containers/common v0.49.1/go.mod h1:ueM5hT0itKqCQvVJDs+EtjornAQtrHYxQJzP2gxeGIg= -github.com/containers/common v0.49.2-0.20220909190843-e5685792b5d7 h1:iSrqOya92AllZSA7y64Aamfcr4iOxgf4iatc9uFeL0U= -github.com/containers/common v0.49.2-0.20220909190843-e5685792b5d7/go.mod h1:HaPvle8BvLTyjtY9B4HJoNCl60DpHwCDLA2FsZTWaak= +github.com/containers/buildah v1.27.1-0.20220921131114-d3064796af36 h1:LTSEbPUbs0slJSJ+IH6atAjYDe0IDzA0sPgBLjT1yAo= +github.com/containers/buildah v1.27.1-0.20220921131114-d3064796af36/go.mod h1:cY3pGPyMmrNp/sEDK8ESoBOf4hoNovptZSI0oyo8eQM= +github.com/containers/common v0.49.2-0.20220920205255-8062f81c5497/go.mod h1:ZnhOPR/07UOkfIg5bezUpBilGjxEUdaeoUpu7gRBGc0= +github.com/containers/common v0.50.1 h1:AYRAf1xyahNVRez49KIkREInNf36SQx1lyLY9M95wQI= +github.com/containers/common v0.50.1/go.mod h1:XnWlXPyE9Ky+8v8MfYWJZFnejkprAkUeo0DTWmSiwcY= 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.22.0/go.mod h1:D8Ksv2RNB8qLJ7xe1P3rgJJOSQpahA6amv2Ax++/YO4= -github.com/containers/image/v5 v5.22.1-0.20220907162003-651744379993 h1:Dsga+pCSq+2JwIaHaxilCWrLpzSQIbBdovTCHb8zPag= github.com/containers/image/v5 v5.22.1-0.20220907162003-651744379993/go.mod h1:/Ruurd87C6Ap45t1PWNOD8+SGwiZbk79XCgs1iUTvYA= +github.com/containers/image/v5 v5.22.1-0.20220919112403-fe51f7ffca50/go.mod h1:yA5N2XShBHbvlhp51kNABiFPmnRLpDRHV++zmMQn3eE= +github.com/containers/image/v5 v5.23.0 h1:Uv/n8zsHVUBBJK2rfBUHbN4CutHHmsQeyi4f80lAOf8= +github.com/containers/image/v5 v5.23.0/go.mod h1:EXFFGEsL99S6aqLqK2mQJ3yrNh6Q05UCHt4mhF9JNoM= 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= @@ -445,8 +459,9 @@ github.com/containers/psgo v1.7.3/go.mod h1:PfaNzzHmMb8M9/blPgyD4BB3ZEj/0ApZIxN6 github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4= github.com/containers/storage v1.42.0/go.mod h1:JiUJwOgOo1dr2DdOUc1MRe2GCAXABYoYmOdPF8yvH78= github.com/containers/storage v1.42.1-0.20220907083030-5aff7f62e8d0/go.mod h1:nj2fW3rgwkr6toBVFzv5OqUYs1kowX+AMiPjgv2UXN0= -github.com/containers/storage v1.42.1-0.20220911223137-e11b246de159 h1:euFlaTBhuBLuUUQK4wGXjruNUh24ZbdQLREvLz15r9o= -github.com/containers/storage v1.42.1-0.20220911223137-e11b246de159/go.mod h1:nj2fW3rgwkr6toBVFzv5OqUYs1kowX+AMiPjgv2UXN0= +github.com/containers/storage v1.42.1-0.20220919112236-8a581aac3bdf/go.mod h1:uZ147thiIFGdVTjMmIw19knttQnUCl3y9zjreHrg11s= +github.com/containers/storage v1.43.0 h1:P+zulGXA3mqe2GnYmZU0xu87Wy1M0PVHM2ucrgmvTdU= +github.com/containers/storage v1.43.0/go.mod h1:uZ147thiIFGdVTjMmIw19knttQnUCl3y9zjreHrg11s= 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= @@ -456,6 +471,7 @@ github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmeka github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-oidc/v3 v3.2.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= +github.com/coreos/go-oidc/v3 v3.4.0/go.mod h1:eHUXhZtXPQLgEaDrOVTgwbgmz1xGOkJNye6h3zkD2Pw= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -490,6 +506,7 @@ github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/ github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/daixiang0/gci v0.2.9/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg= +github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -509,7 +526,6 @@ github.com/disiqueira/gotree/v3 v3.0.2 h1:ik5iuLQQoufZBNPY518dXhiO5056hyNBIK9lWh github.com/disiqueira/gotree/v3 v3.0.2/go.mod h1:ZuyjE4+mUQZlbpkI24AmruZKhg3VHEgPLDY8Qk+uUu8= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.16+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= @@ -518,13 +534,13 @@ github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6 github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.16+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.18+incompatible h1:SN84VYXTBNGn92T/QwIRPlum9zfemfitN7pbsp26WSc= github.com/docker/docker v20.10.18+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= -github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o= github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= +github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= +github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 h1:IPrmumsT9t5BS7XcPhgsCTlkWbYg80SEXUzDpReaU6Y= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11/go.mod h1:a6bNUGTbQBsY6VRHTr4h/rkOXjl244DyRD0tx3fgq4Q= @@ -544,7 +560,6 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eggsampler/acme/v3 v3.2.1/go.mod h1:/qh0rKC/Dh7Jj+p4So7DbWmFNzC4dpcpK53r226Fhuo= github.com/eggsampler/acme/v3 v3.3.0/go.mod h1:/qh0rKC/Dh7Jj+p4So7DbWmFNzC4dpcpK53r226Fhuo= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -656,10 +671,9 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTM github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= -github.com/go-rod/rod v0.107.3/go.mod h1:4SqYRUrcc4dSr9iT36YRZ4hdUAPg3A0O8RhxAMh0eCQ= github.com/go-rod/rod v0.109.1/go.mod h1:GZDtmEs6RpF6kBRYpGCZXxXlKNneKVPiKOjaMbmVVjE= +github.com/go-rod/rod v0.109.3/go.mod h1:GZDtmEs6RpF6kBRYpGCZXxXlKNneKVPiKOjaMbmVVjE= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -818,10 +832,10 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= -github.com/google/go-containerregistry v0.10.0/go.mod h1:C7uwbB1QUAtvnknyd3ethxJRd4gtEjU/9WLXzckfI1Y= github.com/google/go-containerregistry v0.11.0 h1:Xt8x1adcREjFcmDoDK8OdOsjxu90PHkGuwNP8GiHMLM= github.com/google/go-containerregistry v0.11.0/go.mod h1:BBaYtsHPHA42uEgAvd/NejvAfPSlz281sJWqupjSxfk= github.com/google/go-intervals v0.0.2 h1:FGrVEiUnTRKR8yE04qzXYaJMtnIYqobR5QbblK3ixcM= @@ -931,11 +945,11 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.1.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g= +github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.0/go.mod h1:xvb32K2keAc+R8DSFG2IwDcydK9DBQE+fGA5fsw6hSk= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= @@ -946,7 +960,6 @@ github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ3 github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= @@ -968,7 +981,6 @@ github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -983,10 +995,11 @@ github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hashicorp/vault/api v1.7.2/go.mod h1:xbfA+1AvxFseDzxxdWaL0uO99n1+tndus4GCrtouy0M= +github.com/hashicorp/vault/api v1.8.0/go.mod h1:uJrw6D3y9Rv7hhmS17JQC50jbPDAZdjZoTtrCCxxs7E= github.com/hashicorp/vault/sdk v0.5.1/go.mod h1:DoGraE9kKGNcVgPmTuX357Fm6WAx1Okvde8Vp3dPDoU= github.com/hashicorp/vault/sdk v0.5.3/go.mod h1:DoGraE9kKGNcVgPmTuX357Fm6WAx1Okvde8Vp3dPDoU= +github.com/hashicorp/vault/sdk v0.6.0/go.mod h1:+DRpzoXIdMvKc88R4qxr+edwy/RvH5QK8itmxLiDHLc= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.1.0/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/honeycombio/beeline-go v1.1.1/go.mod h1:kN0cfUGBMfA87DyCYbiiLoSzWsnw3bluZvNEWtatHxk= github.com/honeycombio/beeline-go v1.9.0 h1:MM/20HBFE2AKno0N9bOgEicSHHiTkTklGdtjdtAEWbk= @@ -1131,14 +1144,15 @@ github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdY github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.4/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.7/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.8/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= +github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= +github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/klauspost/pgzip v1.2.6-0.20220930104621-17e8dac29df8 h1:BcxbplxjtczA1a6d3wYoa7a0WL3rq9DKBMGHeKyjEF0= +github.com/klauspost/pgzip v1.2.6-0.20220930104621-17e8dac29df8/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -1167,7 +1181,6 @@ github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3 github.com/ldez/gomoddirectives v0.2.2/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= github.com/ldez/tagliatelle v0.2.0/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/letsencrypt/boulder v0.0.0-20220331220046-b23ab962616e/go.mod h1:Bl3mfF2LHYepsU2XfzMceIglyByfPe1IFAXtO+p37Qk= github.com/letsencrypt/boulder v0.0.0-20220723181115-27de4befb95e h1:2ba+yBBeT8ZFyZjRLPDKvkqVrWX4CCYAuR6nuJGojD0= github.com/letsencrypt/boulder v0.0.0-20220723181115-27de4befb95e/go.mod h1:54WQpg5QI0mpRhxoj9bxysLqA5WJylVsLtXOrb3zAiU= github.com/letsencrypt/challtestsrv v1.2.1/go.mod h1:Ur4e4FvELUXLGhkMztHOsPIsvGxD/kzSJninOrkM+zc= @@ -1260,7 +1273,6 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.45/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= @@ -1268,6 +1280,8 @@ github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= +github.com/mistifyio/go-zfs/v3 v3.0.0 h1:J5QK618xRcXnQYZ2GE5FdmpS1ufIrWue+lR/mpe6/14= +github.com/mistifyio/go-zfs/v3 v3.0.0/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= @@ -1368,8 +1382,9 @@ github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042 github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU= github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI= +github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -1384,7 +1399,6 @@ github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAl github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY= github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= @@ -1400,8 +1414,9 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 h1:+czc/J8SlhPKLOtVLMQc+xDCFBT73ZStMsRhSsUhsSg= github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198/go.mod h1:j4h1pJW6ZcJTgMZWP3+7RlG3zTaP02aDZ/Qw0sppK7Q= +github.com/opencontainers/image-spec v1.1.0-rc1 h1:lfG+OTa7V8PD3PKvkocSG9KAcA9MANqJn53m31Fvwkc= +github.com/opencontainers/image-spec v1.1.0-rc1/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc h1:qjkUzmFsOFbQyjObybk40mRida83j5IHRaKzLGdBbEU= github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc/go.mod h1:wUOQGsiKae6VzA/UvlCK3cO+pHk8F2VQHlIoITEfMM8= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -1423,8 +1438,9 @@ github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xA github.com/opencontainers/selinux v1.8.5/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo= github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= -github.com/opencontainers/selinux v1.10.1 h1:09LIPVRP3uuZGQvgR+SgMSNBd1Eb3vlRbGqQpoHsF8w= github.com/opencontainers/selinux v1.10.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/opencontainers/selinux v1.10.2 h1:NFy2xCsjn7+WspbfZkUd5zyVeisV7VFbPSP96+8/ha4= +github.com/opencontainers/selinux v1.10.2/go.mod h1:cARutUbaUrlRClyvxOICCgKixCs6L05aUsohzA3EkHQ= github.com/openshift/imagebuilder v1.2.4-0.20220711175835-4151e43600df h1:vf6pdI10F2Tim5a9JKiVVl4/dpNz1OEhz4EnfLdLtiA= github.com/openshift/imagebuilder v1.2.4-0.20220711175835-4151e43600df/go.mod h1:TRYHe4CH9U6nkDjxjBNM5klrLbJBrRbpJE5SaRwUBsQ= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -1558,7 +1574,6 @@ github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624 github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= github.com/seccomp/libseccomp-golang v0.10.0 h1:aA4bp+/Zzi0BnWZ2F1wgNBs5gTpm+na2rWM6M9YjLpY= github.com/seccomp/libseccomp-golang v0.10.0/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= -github.com/secure-systems-lab/go-securesystemslib v0.3.1/go.mod h1:o8hhjkbNl2gOamKUA/eNW3xUrntHT9L4W89W1nfj43U= github.com/secure-systems-lab/go-securesystemslib v0.4.0/go.mod h1:FGBZgq2tXWICsxWQW1msNf49F0Pf2Op5Htayx335Qbs= github.com/securego/gosec/v2 v2.9.1/go.mod h1:oDcDLcatOJxkCGaCaq8lua1jTnYf6Sou4wdiJ1n4iHc= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= @@ -1573,9 +1588,10 @@ github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sigstore/sigstore v1.3.1-0.20220629021053-b95fc0d626c1/go.mod h1:y83NePRM98MJpbGgBgi54UZduhG0aD7lYngAVCx+i/E= -github.com/sigstore/sigstore v1.4.0 h1:5A3eUhbSQkhiqJNUPi/2UMKdTyb3NKfWcVjaTBkkaJk= github.com/sigstore/sigstore v1.4.0/go.mod h1:z3kt1jm2A39M+g7emkQ8jdErL/haCMEjkNxvqTf41/k= +github.com/sigstore/sigstore v1.4.1/go.mod h1:4+s4d6oTDdoQkf5lwpZBoOlWWV+hXhur1my9WdN5PjU= +github.com/sigstore/sigstore v1.4.2 h1:fTppzuZBAmQ/skgl7FWJRLyby70pxCqJGKyWfkSuMR8= +github.com/sigstore/sigstore v1.4.2/go.mod h1:wCv58Fia7u1snVJyPcxdgIh/3uw1XdOLhxPExTwwyt4= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -1650,13 +1666,12 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/sylabs/sif/v2 v2.7.1/go.mod h1:bBse2nEFd3yHkmq6KmAOFEWQg5LdFYiQUdVcgamxlc8= -github.com/sylabs/sif/v2 v2.7.2 h1:eCxtl2ub9fPfrO7g2JPagn6HKDhv+Kl92Jz6+ww2Y1Q= github.com/sylabs/sif/v2 v2.7.2/go.mod h1:LQOdYXC9a8i7BleTKRw9lohi0rTbXkJOeS9u0ebvgyM= +github.com/sylabs/sif/v2 v2.8.0 h1:FIfWA1fYSFynKD1LJwGbWJ2ib8ylT8XwZl9naLlciPE= +github.com/sylabs/sif/v2 v2.8.0/go.mod h1:LQOdYXC9a8i7BleTKRw9lohi0rTbXkJOeS9u0ebvgyM= github.com/sylvia7788/contextcheck v1.0.4/go.mod h1:vuPKJMQ7MQ91ZTqfdyreNKwZjyUg6KO+IebVyQDedZQ= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -1672,10 +1687,12 @@ github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0 github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= -github.com/theupdateframework/go-tuf v0.3.0/go.mod h1:E5XP0wXitrFUHe4b8cUcAAdxBW4LbfnqF4WXXGLgWNo= github.com/theupdateframework/go-tuf v0.3.1/go.mod h1:lhHZ3Vt2pdAh15h0Cc6gWdlI+Okn2ZznD3q/cNjd5jw= -github.com/theupdateframework/go-tuf v0.4.0 h1:KTFzOsIdtmMe4KTEOEcDdD68uXYf2hDYq+Bh+hU7yWU= github.com/theupdateframework/go-tuf v0.4.0/go.mod h1:kfQTX2LhNeK/cp03OBiZHoua0Pp2l9w4ShRwFtc0oKg= +github.com/theupdateframework/go-tuf v0.5.0/go.mod h1:vAqWV3zEs89byeFsAYoh/Q14vJTgJkHwnnRCWBBBINY= +github.com/theupdateframework/go-tuf v0.5.1-0.20220920170306-f237d7ca5b42/go.mod h1:vAqWV3zEs89byeFsAYoh/Q14vJTgJkHwnnRCWBBBINY= +github.com/theupdateframework/go-tuf v0.5.1 h1:kd8in4+boNxtYf8AYPbm9//Ps75RG5yURkN9Fng4Qs4= +github.com/theupdateframework/go-tuf v0.5.1/go.mod h1:vAqWV3zEs89byeFsAYoh/Q14vJTgJkHwnnRCWBBBINY= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= @@ -1718,7 +1735,6 @@ github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/V github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= -github.com/vbauerster/mpb/v7 v7.4.2/go.mod h1:UmOiIUI8aPqWXIps0ciik3RKMdzx7+ooQpq+fBcXwBA= github.com/vbauerster/mpb/v7 v7.5.2/go.mod h1:UmOiIUI8aPqWXIps0ciik3RKMdzx7+ooQpq+fBcXwBA= github.com/vbauerster/mpb/v7 v7.5.3 h1:BkGfmb6nMrrBQDFECR/Q7RkKCw7ylMetCb4079CGs4w= github.com/vbauerster/mpb/v7 v7.5.3/go.mod h1:i+h4QY6lmLvBNK2ah1fSreiw3ajskRlBp9AhY/PnuOE= @@ -1742,7 +1758,6 @@ github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/weppos/publicsuffix-go v0.15.1-0.20210807195340-dc689ff0bb59/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= -github.com/weppos/publicsuffix-go v0.15.1-0.20220329081811-9a40b608a236/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= github.com/weppos/publicsuffix-go v0.15.1-0.20220413065649-906f534b73a4/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= @@ -1759,12 +1774,10 @@ github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1z github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yeya24/promlinter v0.1.0/go.mod h1:rs5vtZzeBHqqMwXqFScncpCF6u06lezhZepno9AB1Oc= github.com/ysmood/goob v0.4.0/go.mod h1:u6yx7ZhS4Exf2MwciFr6nIM8knHQIE22lFpWHnfql18= -github.com/ysmood/got v0.31.2/go.mod h1:pE1l4LOwOBhQg6A/8IAatkGp7uZjnalzrZolnlhhMgY= github.com/ysmood/got v0.31.3/go.mod h1:pE1l4LOwOBhQg6A/8IAatkGp7uZjnalzrZolnlhhMgY= github.com/ysmood/gotrace v0.6.0/go.mod h1:TzhIG7nHDry5//eYZDYcTzuJLYQIkykJzCRIo4/dzQM= github.com/ysmood/gson v0.7.1/go.mod h1:3Kzs5zDl21g5F/BlLTNcuAGAYLKt2lV5G8D1zF3RNmg= github.com/ysmood/gson v0.7.2/go.mod h1:3Kzs5zDl21g5F/BlLTNcuAGAYLKt2lV5G8D1zF3RNmg= -github.com/ysmood/leakless v0.7.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ= github.com/ysmood/leakless v0.8.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= @@ -1890,11 +1903,11 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 h1:a5Yg6ylndHHYJqIPrdq0AhvR6KTvDTAvgBtaidhEevY= +golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -2003,7 +2016,6 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -2013,13 +2025,14 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220524220425-1d687d428aca/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2040,10 +2053,10 @@ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220718184931-c8730f7fcb92/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2056,7 +2069,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2176,6 +2188,7 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2211,10 +2224,14 @@ golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 h1:wM1k/lXfpc5HdkJJyW9GELpd8ERGdnh8sMGL6Gzq3Ho= +golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 h1:h+EGohizhe9XlX18rfpa8k8RAc5XyaeamM+0VHRd4lc= +golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2241,7 +2258,6 @@ golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ= golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2417,6 +2433,8 @@ google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3p google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= google.golang.org/api v0.86.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= google.golang.org/api v0.92.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2606,7 +2624,6 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= diff --git a/hack/install_golangci.sh b/hack/install_golangci.sh index 896d59901..29d925666 100755 --- a/hack/install_golangci.sh +++ b/hack/install_golangci.sh @@ -6,7 +6,7 @@ die() { echo "${1:-No error message given} (from $(basename $0))"; exit 1; } function install() { echo "Installing golangci-lint v$VERSION into $BIN" - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v$VERSION + curl -sSL --retry 5 https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v$VERSION } # Undocumented behavior: golangci-lint installer requires $BINDIR in env, diff --git a/hack/libsubid_tag.sh b/hack/libsubid_tag.sh index 31412b3e6..137826484 100755 --- a/hack/libsubid_tag.sh +++ b/hack/libsubid_tag.sh @@ -5,7 +5,7 @@ fi tmpdir="$PWD/tmp.$RANDOM" mkdir -p "$tmpdir" trap 'rm -fr "$tmpdir"' EXIT -cc -o "$tmpdir"/libsubid_tag -l subid -x c - > /dev/null 2> /dev/null << EOF +cc -o "$tmpdir"/libsubid_tag -x c - -l subid > /dev/null 2> /dev/null << EOF #include <shadow/subid.h> #include <stdio.h> #include <stdlib.h> diff --git a/hack/xref-helpmsgs-manpages b/hack/xref-helpmsgs-manpages index de9ef8630..fbf2deb22 100755 --- a/hack/xref-helpmsgs-manpages +++ b/hack/xref-helpmsgs-manpages @@ -292,6 +292,15 @@ sub podman_man { chomp $line; next unless $line; # skip empty lines + # First line (page title) must match the command name. + if ($line =~ /^%\s+/) { + my $expect = "% $command 1"; + if ($line ne $expect) { + warn "$ME: $subpath:$.: wrong title line '$line'; should be '$expect'\n"; + ++$Errs; + } + } + # .md files designate sections with leading double hash if ($line =~ /^##\s*(GLOBAL\s+)?OPTIONS/) { $section = 'flags'; diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go index 4fd95a3cf..77c234892 100644 --- a/libpod/boltdb_state.go +++ b/libpod/boltdb_state.go @@ -109,6 +109,7 @@ func NewBoltState(path string, runtime *Runtime) (State, error) { runtimeConfigBkt, exitCodeBkt, exitCodeTimeStampBkt, + volCtrsBkt, } // Does the DB need an update? @@ -2551,6 +2552,11 @@ func (s *BoltState) AddVolume(volume *Volume) error { return err } + volCtrsBkt, err := getVolumeContainersBucket(tx) + if err != nil { + return err + } + // Check if we already have a volume with the given name volExists := allVolsBkt.Get(volName) if volExists != nil { @@ -2580,6 +2586,12 @@ func (s *BoltState) AddVolume(volume *Volume) error { } } + if volume.config.StorageID != "" { + if err := volCtrsBkt.Put([]byte(volume.config.StorageID), volName); err != nil { + return fmt.Errorf("storing volume %s container ID in DB: %w", volume.Name(), err) + } + } + if err := allVolsBkt.Put(volName, volName); err != nil { return fmt.Errorf("storing volume %s in all volumes bucket in DB: %w", volume.Name(), err) } @@ -2619,6 +2631,11 @@ func (s *BoltState) RemoveVolume(volume *Volume) error { return err } + volCtrIDBkt, err := getVolumeContainersBucket(tx) + if err != nil { + return err + } + // Check if the volume exists volDB := volBkt.Bucket(volName) if volDB == nil { @@ -2665,6 +2682,11 @@ func (s *BoltState) RemoveVolume(volume *Volume) error { if err := volBkt.DeleteBucket(volName); err != nil { return fmt.Errorf("removing volume %s from DB: %w", volume.Name(), err) } + if volume.config.StorageID != "" { + if err := volCtrIDBkt.Delete([]byte(volume.config.StorageID)); err != nil { + return fmt.Errorf("removing volume %s container ID from DB: %w", volume.Name(), err) + } + } return nil }) @@ -3618,3 +3640,34 @@ func (s *BoltState) AllPods() ([]*Pod, error) { return pods, nil } + +// ContainerIDIsVolume checks if the given c/storage container ID is used as +// backing storage for a volume. +func (s *BoltState) ContainerIDIsVolume(id string) (bool, error) { + if !s.valid { + return false, define.ErrDBClosed + } + + isVol := false + + db, err := s.getDBCon() + if err != nil { + return false, err + } + defer s.deferredCloseDBCon(db) + + err = db.View(func(tx *bolt.Tx) error { + volCtrsBkt, err := getVolumeContainersBucket(tx) + if err != nil { + return err + } + + volName := volCtrsBkt.Get([]byte(id)) + if volName != nil { + isVol = true + } + + return nil + }) + return isVol, err +} diff --git a/libpod/boltdb_state_internal.go b/libpod/boltdb_state_internal.go index 87f1fa4eb..7f2d49b31 100644 --- a/libpod/boltdb_state_internal.go +++ b/libpod/boltdb_state_internal.go @@ -28,6 +28,7 @@ const ( execName = "exec" aliasesName = "aliases" runtimeConfigName = "runtime-config" + volumeCtrsName = "volume-ctrs" exitCodeName = "exit-code" exitCodeTimeStampName = "exit-code-time-stamp" @@ -67,6 +68,7 @@ var ( dependenciesBkt = []byte(dependenciesName) volDependenciesBkt = []byte(volCtrDependencies) networksBkt = []byte(networksName) + volCtrsBkt = []byte(volumeCtrsName) exitCodeBkt = []byte(exitCodeName) exitCodeTimeStampBkt = []byte(exitCodeTimeStampName) @@ -384,6 +386,14 @@ func getExitCodeTimeStampBucket(tx *bolt.Tx) (*bolt.Bucket, error) { return bkt, nil } +func getVolumeContainersBucket(tx *bolt.Tx) (*bolt.Bucket, error) { + bkt := tx.Bucket(volCtrsBkt) + if bkt == nil { + return nil, fmt.Errorf("volume containers bucket not found in DB: %w", define.ErrDBBadConfig) + } + return bkt, nil +} + func (s *BoltState) getContainerConfigFromDB(id []byte, config *ContainerConfig, ctrsBkt *bolt.Bucket) error { ctrBkt := ctrsBkt.Bucket(id) if ctrBkt == nil { @@ -528,6 +538,9 @@ func (s *BoltState) getVolumeFromDB(name []byte, volume *Volume, volBkt *bolt.Bu } } + // Need this for UsesVolumeDriver() so set it now. + volume.runtime = s.runtime + // Retrieve volume driver if volume.UsesVolumeDriver() { plugin, err := s.runtime.getVolumePlugin(volume.config) @@ -550,7 +563,6 @@ func (s *BoltState) getVolumeFromDB(name []byte, volume *Volume, volBkt *bolt.Bu } volume.lock = lock - volume.runtime = s.runtime volume.valid = true return nil diff --git a/libpod/container.go b/libpod/container.go index cfffd8ea1..a4eb33c49 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -3,7 +3,7 @@ package libpod import ( "bytes" "fmt" - "io/ioutil" + "io" "net" "os" "strings" @@ -351,7 +351,7 @@ func (c *Container) specFromState() (*spec.Spec, error) { if f, err := os.Open(c.state.ConfigPath); err == nil { returnSpec = new(spec.Spec) - content, err := ioutil.ReadAll(f) + content, err := io.ReadAll(f) if err != nil { return nil, fmt.Errorf("reading container config: %w", err) } @@ -990,7 +990,7 @@ func (c *Container) cGroupPath() (string, error) { // the lookup. // See #10602 for more details. procPath := fmt.Sprintf("/proc/%d/cgroup", c.state.PID) - lines, err := ioutil.ReadFile(procPath) + lines, err := os.ReadFile(procPath) if err != nil { // If the file doesn't exist, it means the container could have been terminated // so report it. diff --git a/libpod/container_api.go b/libpod/container_api.go index dd47b4d12..be0ca0128 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "os" "sync" @@ -479,7 +478,7 @@ func (c *Container) AddArtifact(name string, data []byte) error { return define.ErrCtrRemoved } - return ioutil.WriteFile(c.getArtifactPath(name), data, 0o740) + return os.WriteFile(c.getArtifactPath(name), data, 0o740) } // GetArtifact reads the specified artifact file from the container @@ -488,7 +487,7 @@ func (c *Container) GetArtifact(name string) ([]byte, error) { return nil, define.ErrCtrRemoved } - return ioutil.ReadFile(c.getArtifactPath(name)) + return os.ReadFile(c.getArtifactPath(name)) } // RemoveArtifact deletes the specified artifacts file diff --git a/libpod/container_copy_common.go b/libpod/container_copy_common.go new file mode 100644 index 000000000..d07b4c692 --- /dev/null +++ b/libpod/container_copy_common.go @@ -0,0 +1,213 @@ +//go:build linux || freebsd +// +build linux freebsd + +package libpod + +import ( + "errors" + "io" + "path/filepath" + "strings" + + buildahCopiah "github.com/containers/buildah/copier" + "github.com/containers/buildah/pkg/chrootuser" + "github.com/containers/buildah/util" + "github.com/containers/podman/v4/libpod/define" + "github.com/containers/podman/v4/pkg/rootless" + "github.com/containers/storage/pkg/archive" + "github.com/containers/storage/pkg/idtools" + "github.com/opencontainers/runtime-spec/specs-go" + "github.com/sirupsen/logrus" +) + +func (c *Container) copyFromArchive(path string, chown, noOverwriteDirNonDir bool, rename map[string]string, reader io.Reader) (func() error, error) { + var ( + mountPoint string + resolvedRoot string + resolvedPath string + unmount func() + err error + ) + + // Make sure that "/" copies the *contents* of the mount point and not + // the directory. + if path == "/" { + path = "/." + } + + // Optimization: only mount if the container is not already. + if c.state.Mounted { + mountPoint = c.state.Mountpoint + unmount = func() {} + } else { + // NOTE: make sure to unmount in error paths. + mountPoint, err = c.mount() + if err != nil { + return nil, err + } + unmount = func() { + if err := c.unmount(false); err != nil { + logrus.Errorf("Failed to unmount container: %v", err) + } + } + } + + resolvedRoot, resolvedPath, err = c.resolveCopyTarget(mountPoint, path) + if err != nil { + unmount() + return nil, err + } + + var idPair *idtools.IDPair + if chown { + // Make sure we chown the files to the container's main user and group ID. + user, err := getContainerUser(c, mountPoint) + if err != nil { + unmount() + return nil, err + } + idPair = &idtools.IDPair{UID: int(user.UID), GID: int(user.GID)} + } + + decompressed, err := archive.DecompressStream(reader) + if err != nil { + unmount() + return nil, err + } + + logrus.Debugf("Container copy *to* %q (resolved: %q) on container %q (ID: %s)", path, resolvedPath, c.Name(), c.ID()) + + return func() error { + defer unmount() + defer decompressed.Close() + putOptions := buildahCopiah.PutOptions{ + UIDMap: c.config.IDMappings.UIDMap, + GIDMap: c.config.IDMappings.GIDMap, + ChownDirs: idPair, + ChownFiles: idPair, + NoOverwriteDirNonDir: noOverwriteDirNonDir, + NoOverwriteNonDirDir: noOverwriteDirNonDir, + Rename: rename, + } + + return c.joinMountAndExec( + func() error { + return buildahCopiah.Put(resolvedRoot, resolvedPath, putOptions, decompressed) + }, + ) + }, nil +} + +func (c *Container) copyToArchive(path string, writer io.Writer) (func() error, error) { + var ( + mountPoint string + unmount func() + err error + ) + + // Optimization: only mount if the container is not already. + if c.state.Mounted { + mountPoint = c.state.Mountpoint + unmount = func() {} + } else { + // NOTE: make sure to unmount in error paths. + mountPoint, err = c.mount() + if err != nil { + return nil, err + } + unmount = func() { + if err := c.unmount(false); err != nil { + logrus.Errorf("Failed to unmount container: %v", err) + } + } + } + + statInfo, resolvedRoot, resolvedPath, err := c.stat(mountPoint, path) + if err != nil { + unmount() + return nil, err + } + + // We optimistically chown to the host user. In case of a hypothetical + // container-to-container copy, the reading side will chown back to the + // container user. + user, err := getContainerUser(c, mountPoint) + if err != nil { + unmount() + return nil, err + } + hostUID, hostGID, err := util.GetHostIDs( + idtoolsToRuntimeSpec(c.config.IDMappings.UIDMap), + idtoolsToRuntimeSpec(c.config.IDMappings.GIDMap), + user.UID, + user.GID, + ) + if err != nil { + unmount() + return nil, err + } + idPair := idtools.IDPair{UID: int(hostUID), GID: int(hostGID)} + + logrus.Debugf("Container copy *from* %q (resolved: %q) on container %q (ID: %s)", path, resolvedPath, c.Name(), c.ID()) + + return func() error { + defer unmount() + getOptions := buildahCopiah.GetOptions{ + // Unless the specified points to ".", we want to copy the base directory. + KeepDirectoryNames: statInfo.IsDir && filepath.Base(path) != ".", + UIDMap: c.config.IDMappings.UIDMap, + GIDMap: c.config.IDMappings.GIDMap, + ChownDirs: &idPair, + ChownFiles: &idPair, + Excludes: []string{"dev", "proc", "sys"}, + // Ignore EPERMs when copying from rootless containers + // since we cannot read TTY devices. Those are owned + // by the host's root and hence "nobody" inside the + // container's user namespace. + IgnoreUnreadable: rootless.IsRootless() && c.state.State == define.ContainerStateRunning, + } + return c.joinMountAndExec( + func() error { + return buildahCopiah.Get(resolvedRoot, "", getOptions, []string{resolvedPath}, writer) + }, + ) + }, nil +} + +// getContainerUser returns the specs.User and ID mappings of the container. +func getContainerUser(container *Container, mountPoint string) (specs.User, error) { + userspec := container.config.User + + uid, gid, _, err := chrootuser.GetUser(mountPoint, userspec) + u := specs.User{ + UID: uid, + GID: gid, + Username: userspec, + } + + if !strings.Contains(userspec, ":") { + groups, err2 := chrootuser.GetAdditionalGroupsForUser(mountPoint, uint64(u.UID)) + if err2 != nil { + if !errors.Is(err2, chrootuser.ErrNoSuchUser) && err == nil { + err = err2 + } + } else { + u.AdditionalGids = groups + } + } + + return u, err +} + +// idtoolsToRuntimeSpec converts idtools ID mapping to the one of the runtime spec. +func idtoolsToRuntimeSpec(idMaps []idtools.IDMap) (convertedIDMap []specs.LinuxIDMapping) { + for _, idmap := range idMaps { + tempIDMap := specs.LinuxIDMapping{ + ContainerID: uint32(idmap.ContainerID), + HostID: uint32(idmap.HostID), + Size: uint32(idmap.Size), + } + convertedIDMap = append(convertedIDMap, tempIDMap) + } + return convertedIDMap +} diff --git a/libpod/container_copy_freebsd.go b/libpod/container_copy_freebsd.go new file mode 100644 index 000000000..218f3917f --- /dev/null +++ b/libpod/container_copy_freebsd.go @@ -0,0 +1,13 @@ +package libpod + +// On FreeBSD, the container's mounts are in the global mount +// namespace so we can just execute the function directly. +func (c *Container) joinMountAndExec(f func() error) error { + return f() +} + +// Similarly, we can just use resolvePath for both running and stopped +// containers. +func (c *Container) resolveCopyTarget(mountPoint string, containerPath string) (string, string, error) { + return c.resolvePath(mountPoint, containerPath) +} diff --git a/libpod/container_copy_linux.go b/libpod/container_copy_linux.go index 557fead1e..3b029f08f 100644 --- a/libpod/container_copy_linux.go +++ b/libpod/container_copy_linux.go @@ -1,226 +1,14 @@ -//go:build linux -// +build linux - package libpod import ( - "errors" "fmt" - "io" "os" - "path/filepath" "runtime" - "strings" - buildahCopiah "github.com/containers/buildah/copier" - "github.com/containers/buildah/pkg/chrootuser" - "github.com/containers/buildah/util" "github.com/containers/podman/v4/libpod/define" - "github.com/containers/podman/v4/pkg/rootless" - "github.com/containers/storage/pkg/archive" - "github.com/containers/storage/pkg/idtools" - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) -func (c *Container) copyFromArchive(path string, chown, noOverwriteDirNonDir bool, rename map[string]string, reader io.Reader) (func() error, error) { - var ( - mountPoint string - resolvedRoot string - resolvedPath string - unmount func() - err error - ) - - // Make sure that "/" copies the *contents* of the mount point and not - // the directory. - if path == "/" { - path = "/." - } - - // Optimization: only mount if the container is not already. - if c.state.Mounted { - mountPoint = c.state.Mountpoint - unmount = func() {} - } else { - // NOTE: make sure to unmount in error paths. - mountPoint, err = c.mount() - if err != nil { - return nil, err - } - unmount = func() { - if err := c.unmount(false); err != nil { - logrus.Errorf("Failed to unmount container: %v", err) - } - } - } - - if c.state.State == define.ContainerStateRunning { - resolvedRoot = "/" - resolvedPath = c.pathAbs(path) - } else { - resolvedRoot, resolvedPath, err = c.resolvePath(mountPoint, path) - if err != nil { - unmount() - return nil, err - } - } - - var idPair *idtools.IDPair - if chown { - // Make sure we chown the files to the container's main user and group ID. - user, err := getContainerUser(c, mountPoint) - if err != nil { - unmount() - return nil, err - } - idPair = &idtools.IDPair{UID: int(user.UID), GID: int(user.GID)} - } - - decompressed, err := archive.DecompressStream(reader) - if err != nil { - unmount() - return nil, err - } - - logrus.Debugf("Container copy *to* %q (resolved: %q) on container %q (ID: %s)", path, resolvedPath, c.Name(), c.ID()) - - return func() error { - defer unmount() - defer decompressed.Close() - putOptions := buildahCopiah.PutOptions{ - UIDMap: c.config.IDMappings.UIDMap, - GIDMap: c.config.IDMappings.GIDMap, - ChownDirs: idPair, - ChownFiles: idPair, - NoOverwriteDirNonDir: noOverwriteDirNonDir, - NoOverwriteNonDirDir: noOverwriteDirNonDir, - Rename: rename, - } - - return c.joinMountAndExec( - func() error { - return buildahCopiah.Put(resolvedRoot, resolvedPath, putOptions, decompressed) - }, - ) - }, nil -} - -func (c *Container) copyToArchive(path string, writer io.Writer) (func() error, error) { - var ( - mountPoint string - unmount func() - err error - ) - - // Optimization: only mount if the container is not already. - if c.state.Mounted { - mountPoint = c.state.Mountpoint - unmount = func() {} - } else { - // NOTE: make sure to unmount in error paths. - mountPoint, err = c.mount() - if err != nil { - return nil, err - } - unmount = func() { - if err := c.unmount(false); err != nil { - logrus.Errorf("Failed to unmount container: %v", err) - } - } - } - - statInfo, resolvedRoot, resolvedPath, err := c.stat(mountPoint, path) - if err != nil { - unmount() - return nil, err - } - - // We optimistically chown to the host user. In case of a hypothetical - // container-to-container copy, the reading side will chown back to the - // container user. - user, err := getContainerUser(c, mountPoint) - if err != nil { - unmount() - return nil, err - } - hostUID, hostGID, err := util.GetHostIDs( - idtoolsToRuntimeSpec(c.config.IDMappings.UIDMap), - idtoolsToRuntimeSpec(c.config.IDMappings.GIDMap), - user.UID, - user.GID, - ) - if err != nil { - unmount() - return nil, err - } - idPair := idtools.IDPair{UID: int(hostUID), GID: int(hostGID)} - - logrus.Debugf("Container copy *from* %q (resolved: %q) on container %q (ID: %s)", path, resolvedPath, c.Name(), c.ID()) - - return func() error { - defer unmount() - getOptions := buildahCopiah.GetOptions{ - // Unless the specified points to ".", we want to copy the base directory. - KeepDirectoryNames: statInfo.IsDir && filepath.Base(path) != ".", - UIDMap: c.config.IDMappings.UIDMap, - GIDMap: c.config.IDMappings.GIDMap, - ChownDirs: &idPair, - ChownFiles: &idPair, - Excludes: []string{"dev", "proc", "sys"}, - // Ignore EPERMs when copying from rootless containers - // since we cannot read TTY devices. Those are owned - // by the host's root and hence "nobody" inside the - // container's user namespace. - IgnoreUnreadable: rootless.IsRootless() && c.state.State == define.ContainerStateRunning, - } - return c.joinMountAndExec( - func() error { - return buildahCopiah.Get(resolvedRoot, "", getOptions, []string{resolvedPath}, writer) - }, - ) - }, nil -} - -// getContainerUser returns the specs.User and ID mappings of the container. -func getContainerUser(container *Container, mountPoint string) (specs.User, error) { - userspec := container.config.User - - uid, gid, _, err := chrootuser.GetUser(mountPoint, userspec) - u := specs.User{ - UID: uid, - GID: gid, - Username: userspec, - } - - if !strings.Contains(userspec, ":") { - groups, err2 := chrootuser.GetAdditionalGroupsForUser(mountPoint, uint64(u.UID)) - if err2 != nil { - if !errors.Is(err2, chrootuser.ErrNoSuchUser) && err == nil { - err = err2 - } - } else { - u.AdditionalGids = groups - } - } - - return u, err -} - -// idtoolsToRuntimeSpec converts idtools ID mapping to the one of the runtime spec. -func idtoolsToRuntimeSpec(idMaps []idtools.IDMap) (convertedIDMap []specs.LinuxIDMapping) { - for _, idmap := range idMaps { - tempIDMap := specs.LinuxIDMapping{ - ContainerID: uint32(idmap.ContainerID), - HostID: uint32(idmap.HostID), - Size: uint32(idmap.Size), - } - convertedIDMap = append(convertedIDMap, tempIDMap) - } - return convertedIDMap -} - // joinMountAndExec executes the specified function `f` inside the container's // mount and PID namespace. That allows for having the exact view on the // container's file system. @@ -288,3 +76,13 @@ func (c *Container) joinMountAndExec(f func() error) error { }() return <-errChan } + +func (c *Container) resolveCopyTarget(mountPoint string, containerPath string) (string, string, error) { + // If the container is running, we will execute the copy + // inside the container's mount namespace so we return a path + // relative to the container's root. + if c.state.State == define.ContainerStateRunning { + return "/", c.pathAbs(containerPath), nil + } + return c.resolvePath(mountPoint, containerPath) +} diff --git a/libpod/container_copy_unsupported.go b/libpod/container_copy_unsupported.go index 62937279a..703b0a74e 100644 --- a/libpod/container_copy_unsupported.go +++ b/libpod/container_copy_unsupported.go @@ -1,5 +1,5 @@ -//go:build !linux -// +build !linux +//go:build !linux && !freebsd +// +build !linux,!freebsd package libpod diff --git a/libpod/container_exec.go b/libpod/container_exec.go index 3a2cba52f..7896d1932 100644 --- a/libpod/container_exec.go +++ b/libpod/container_exec.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "net/http" "os" "path/filepath" @@ -928,7 +927,7 @@ func (c *Container) readExecExitCode(sessionID string) (int, error) { if err != nil { return -1, err } - ec, err := ioutil.ReadFile(exitFile) + ec, err := os.ReadFile(exitFile) if err != nil { return -1, err } diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index e4089efa6..4dc1ca3a5 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -166,6 +166,15 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver IsInfra: c.IsInfra(), IsService: c.IsService(), } + + if config.RootfsImageID != "" { // May not be set if the container was created with --rootfs + image, _, err := c.runtime.libimageRuntime.LookupImage(config.RootfsImageID, nil) + if err != nil { + return nil, err + } + data.ImageDigest = image.Digest().String() + } + if ctrSpec.Process.Capabilities != nil { data.EffectiveCaps = ctrSpec.Process.Capabilities.Effective data.BoundingCaps = ctrSpec.Process.Capabilities.Bounding diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 994243805..9bf93412d 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strconv" @@ -201,7 +200,7 @@ func (c *Container) waitForExitFileAndSync() error { // This assumes the exit file already exists. func (c *Container) handleExitFile(exitFile string, fi os.FileInfo) error { c.state.FinishedTime = ctime.Created(fi) - statusCodeStr, err := ioutil.ReadFile(exitFile) + statusCodeStr, err := os.ReadFile(exitFile) if err != nil { return fmt.Errorf("failed to read exit file for container %s: %w", c.ID(), err) } @@ -2089,7 +2088,7 @@ func (c *Container) saveSpec(spec *spec.Spec) error { if err != nil { return fmt.Errorf("exporting runtime spec for container %s to JSON: %w", c.ID(), err) } - if err := ioutil.WriteFile(jsonPath, fileJSON, 0644); err != nil { + if err := os.WriteFile(jsonPath, fileJSON, 0644); err != nil { return fmt.Errorf("writing runtime spec JSON for container %s to disk: %w", c.ID(), err) } @@ -2343,7 +2342,7 @@ func (c *Container) extractSecretToCtrStorage(secr *ContainerSecret) error { if err != nil { return fmt.Errorf("unable to extract secret: %w", err) } - err = ioutil.WriteFile(secretFile, data, 0644) + err = os.WriteFile(secretFile, data, 0644) if err != nil { return fmt.Errorf("unable to create %s: %w", secretFile, err) } diff --git a/libpod/container_internal_common.go b/libpod/container_internal_common.go index 9c4a3bb67..29107d4b6 100644 --- a/libpod/container_internal_common.go +++ b/libpod/container_internal_common.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "math" "os" "os/user" @@ -110,7 +109,11 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { // If the flag to mount all devices is set for a privileged container, add // all the devices from the host's machine into the container if c.config.MountAllDevices { - if err := util.AddPrivilegedDevices(&g); err != nil { + systemdMode := false + if c.config.Systemd != nil { + systemdMode = *c.config.Systemd + } + if err := util.AddPrivilegedDevices(&g, systemdMode); err != nil { return nil, err } } @@ -788,7 +791,7 @@ func (c *Container) createCheckpointImage(ctx context.Context, options Container } // Export checkpoint into temporary tar file - tmpDir, err := ioutil.TempDir("", "checkpoint_image_") + tmpDir, err := os.MkdirTemp("", "checkpoint_image_") if err != nil { return err } @@ -2442,7 +2445,7 @@ func (c *Container) generatePasswdAndGroup() (string, string, error) { if err != nil { return "", "", fmt.Errorf("creating path to container %s /etc/passwd: %w", c.ID(), err) } - orig, err := ioutil.ReadFile(originPasswdFile) + orig, err := os.ReadFile(originPasswdFile) if err != nil && !os.IsNotExist(err) { return "", "", err } @@ -2488,7 +2491,7 @@ func (c *Container) generatePasswdAndGroup() (string, string, error) { if err != nil { return "", "", fmt.Errorf("creating path to container %s /etc/group: %w", c.ID(), err) } - orig, err := ioutil.ReadFile(originGroupFile) + orig, err := os.ReadFile(originGroupFile) if err != nil && !os.IsNotExist(err) { return "", "", err } @@ -2659,7 +2662,7 @@ func (c *Container) fixVolumePermissions(v *ContainerNamedVolume) error { return nil } -func (c *Container) relabel(src, mountLabel string, recurse bool) error { +func (c *Container) relabel(src, mountLabel string, shared bool) error { if !selinux.GetEnabled() || mountLabel == "" { return nil } @@ -2674,7 +2677,7 @@ func (c *Container) relabel(src, mountLabel string, recurse bool) error { return nil } } - return label.Relabel(src, mountLabel, recurse) + return label.Relabel(src, mountLabel, shared) } func (c *Container) ChangeHostPathOwnership(src string, recurse bool, uid, gid int) error { diff --git a/libpod/container_internal_test.go b/libpod/container_internal_test.go index 1b4e62e91..46a2da544 100644 --- a/libpod/container_internal_test.go +++ b/libpod/container_internal_test.go @@ -3,7 +3,7 @@ package libpod import ( "context" "fmt" - "io/ioutil" + "os" "path/filepath" "runtime" "testing" @@ -60,7 +60,7 @@ func TestPostDeleteHooks(t *testing.T) { for _, p := range []string{statePath, copyPath} { path := p t.Run(path, func(t *testing.T) { - content, err := ioutil.ReadFile(path) + content, err := os.ReadFile(path) if err != nil { t.Fatal(err) } diff --git a/libpod/container_stat_common.go b/libpod/container_stat_common.go new file mode 100644 index 000000000..e59a52ede --- /dev/null +++ b/libpod/container_stat_common.go @@ -0,0 +1,155 @@ +//go:build linux || freebsd +// +build linux freebsd + +package libpod + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/containers/buildah/copier" + "github.com/containers/podman/v4/libpod/define" + "github.com/containers/podman/v4/pkg/copy" +) + +// statOnHost stats the specified path *on the host*. It returns the file info +// along with the resolved root and the resolved path. Both paths are absolute +// to the host's root. Note that the paths may resolved outside the +// container's mount point (e.g., to a volume or bind mount). +func (c *Container) statOnHost(mountPoint string, containerPath string) (*copier.StatForItem, string, string, error) { + // Now resolve the container's path. It may hit a volume, it may hit a + // bind mount, it may be relative. + resolvedRoot, resolvedPath, err := c.resolvePath(mountPoint, containerPath) + if err != nil { + return nil, "", "", err + } + + statInfo, err := secureStat(resolvedRoot, resolvedPath) + return statInfo, resolvedRoot, resolvedPath, err +} + +func (c *Container) stat(containerMountPoint string, containerPath string) (*define.FileInfo, string, string, error) { + var ( + resolvedRoot string + resolvedPath string + absContainerPath string + statInfo *copier.StatForItem + statErr error + ) + + // Make sure that "/" copies the *contents* of the mount point and not + // the directory. + if containerPath == "/" { + containerPath = "/." + } + + // Wildcards are not allowed. + // TODO: it's now technically possible wildcards. + // We may consider enabling support in the future. + if strings.Contains(containerPath, "*") { + return nil, "", "", copy.ErrENOENT + } + + statInfo, resolvedRoot, resolvedPath, statErr = c.statInContainer(containerMountPoint, containerPath) + if statErr != nil { + if statInfo == nil { + return nil, "", "", statErr + } + // Not all errors from secureStat map to ErrNotExist, so we + // have to look into the error string. Turning it into an + // ENOENT let's the API handlers return the correct status code + // which is crucial for the remote client. + if os.IsNotExist(statErr) || strings.Contains(statErr.Error(), "o such file or directory") { + statErr = copy.ErrENOENT + } + } + + switch { + case statInfo.IsSymlink: + // Symlinks are already evaluated and always relative to the + // container's mount point. + absContainerPath = statInfo.ImmediateTarget + case strings.HasPrefix(resolvedPath, containerMountPoint): + // If the path is on the container's mount point, strip it off. + absContainerPath = strings.TrimPrefix(resolvedPath, containerMountPoint) + absContainerPath = filepath.Join("/", absContainerPath) + default: + // No symlink and not on the container's mount point, so let's + // move it back to the original input. It must have evaluated + // to a volume or bind mount but we cannot return host paths. + absContainerPath = containerPath + } + + // Preserve the base path as specified by the user. The `filepath` + // packages likes to remove trailing slashes and dots that are crucial + // to the copy logic. + absContainerPath = copy.PreserveBasePath(containerPath, absContainerPath) + resolvedPath = copy.PreserveBasePath(containerPath, resolvedPath) + + info := &define.FileInfo{ + IsDir: statInfo.IsDir, + Name: filepath.Base(absContainerPath), + Size: statInfo.Size, + Mode: statInfo.Mode, + ModTime: statInfo.ModTime, + LinkTarget: absContainerPath, + } + + return info, resolvedRoot, resolvedPath, statErr +} + +// secureStat extracts file info for path in a chroot'ed environment in root. +func secureStat(root string, path string) (*copier.StatForItem, error) { + var glob string + var err error + + // If root and path are equal, then dir must be empty and the glob must + // be ".". + if filepath.Clean(root) == filepath.Clean(path) { + glob = "." + } else { + glob, err = filepath.Rel(root, path) + if err != nil { + return nil, err + } + } + + globStats, err := copier.Stat(root, "", copier.StatOptions{}, []string{glob}) + if err != nil { + return nil, err + } + + if len(globStats) != 1 { + return nil, fmt.Errorf("internal error: secureStat: expected 1 item but got %d", len(globStats)) + } + if len(globStats) != 1 { + return nil, fmt.Errorf("internal error: secureStat: expected 1 result but got %d", len(globStats[0].Results)) + } + + // NOTE: the key in the map differ from `glob` when hitting symlink. + // Hence, we just take the first (and only) key/value pair. + for _, stat := range globStats[0].Results { + var statErr error + if stat.Error != "" { + statErr = errors.New(stat.Error) + } + // If necessary evaluate the symlink + if stat.IsSymlink { + target, err := copier.Eval(root, path, copier.EvalOptions{}) + if err != nil { + return nil, fmt.Errorf("evaluating symlink in container: %w", err) + } + // Need to make sure the symlink is relative to the root! + target = strings.TrimPrefix(target, root) + target = filepath.Join("/", target) + stat.ImmediateTarget = target + } + return stat, statErr + } + + // Nothing found! + return nil, copy.ErrENOENT +} diff --git a/libpod/container_stat_freebsd.go b/libpod/container_stat_freebsd.go new file mode 100644 index 000000000..d1e0db348 --- /dev/null +++ b/libpod/container_stat_freebsd.go @@ -0,0 +1,13 @@ +package libpod + +import ( + "github.com/containers/buildah/copier" +) + +// On FreeBSD, jails use the global mount namespace, filtered to only +// the mounts the jail should see. This means that we can use +// statOnHost whether the container is running or not. +// container is running +func (c *Container) statInContainer(mountPoint string, containerPath string) (*copier.StatForItem, string, string, error) { + return c.statOnHost(mountPoint, containerPath) +} diff --git a/libpod/container_stat_linux.go b/libpod/container_stat_linux.go index dc3a524f5..5e5ef3c1a 100644 --- a/libpod/container_stat_linux.go +++ b/libpod/container_stat_linux.go @@ -1,18 +1,8 @@ -//go:build linux -// +build linux - package libpod import ( - "errors" - "fmt" - "os" - "path/filepath" - "strings" - "github.com/containers/buildah/copier" "github.com/containers/podman/v4/libpod/define" - "github.com/containers/podman/v4/pkg/copy" ) // statInsideMount stats the specified path *inside* the container's mount and PID @@ -34,150 +24,15 @@ func (c *Container) statInsideMount(containerPath string) (*copier.StatForItem, return statInfo, resolvedRoot, resolvedPath, err } -// statOnHost stats the specified path *on the host*. It returns the file info -// along with the resolved root and the resolved path. Both paths are absolute -// to the host's root. Note that the paths may resolved outside the -// container's mount point (e.g., to a volume or bind mount). -func (c *Container) statOnHost(mountPoint string, containerPath string) (*copier.StatForItem, string, string, error) { - // Now resolve the container's path. It may hit a volume, it may hit a - // bind mount, it may be relative. - resolvedRoot, resolvedPath, err := c.resolvePath(mountPoint, containerPath) - if err != nil { - return nil, "", "", err - } - - statInfo, err := secureStat(resolvedRoot, resolvedPath) - return statInfo, resolvedRoot, resolvedPath, err -} - -func (c *Container) stat(containerMountPoint string, containerPath string) (*define.FileInfo, string, string, error) { - var ( - resolvedRoot string - resolvedPath string - absContainerPath string - statInfo *copier.StatForItem - statErr error - ) - - // Make sure that "/" copies the *contents* of the mount point and not - // the directory. - if containerPath == "/" { - containerPath = "/." - } - - // Wildcards are not allowed. - // TODO: it's now technically possible wildcards. - // We may consider enabling support in the future. - if strings.Contains(containerPath, "*") { - return nil, "", "", copy.ErrENOENT - } - +// Calls either statOnHost or statInsideMount depending on whether the +// container is running +func (c *Container) statInContainer(mountPoint string, containerPath string) (*copier.StatForItem, string, string, error) { if c.state.State == define.ContainerStateRunning { // If the container is running, we need to join it's mount namespace // and stat there. - statInfo, resolvedRoot, resolvedPath, statErr = c.statInsideMount(containerPath) - } else { - // If the container is NOT running, we need to resolve the path - // on the host. - statInfo, resolvedRoot, resolvedPath, statErr = c.statOnHost(containerMountPoint, containerPath) - } - - if statErr != nil { - if statInfo == nil { - return nil, "", "", statErr - } - // Not all errors from secureStat map to ErrNotExist, so we - // have to look into the error string. Turning it into an - // ENOENT let's the API handlers return the correct status code - // which is crucial for the remote client. - if os.IsNotExist(statErr) || strings.Contains(statErr.Error(), "o such file or directory") { - statErr = copy.ErrENOENT - } - } - - switch { - case statInfo.IsSymlink: - // Symlinks are already evaluated and always relative to the - // container's mount point. - absContainerPath = statInfo.ImmediateTarget - case strings.HasPrefix(resolvedPath, containerMountPoint): - // If the path is on the container's mount point, strip it off. - absContainerPath = strings.TrimPrefix(resolvedPath, containerMountPoint) - absContainerPath = filepath.Join("/", absContainerPath) - default: - // No symlink and not on the container's mount point, so let's - // move it back to the original input. It must have evaluated - // to a volume or bind mount but we cannot return host paths. - absContainerPath = containerPath + return c.statInsideMount(containerPath) } - - // Preserve the base path as specified by the user. The `filepath` - // packages likes to remove trailing slashes and dots that are crucial - // to the copy logic. - absContainerPath = copy.PreserveBasePath(containerPath, absContainerPath) - resolvedPath = copy.PreserveBasePath(containerPath, resolvedPath) - - info := &define.FileInfo{ - IsDir: statInfo.IsDir, - Name: filepath.Base(absContainerPath), - Size: statInfo.Size, - Mode: statInfo.Mode, - ModTime: statInfo.ModTime, - LinkTarget: absContainerPath, - } - - return info, resolvedRoot, resolvedPath, statErr -} - -// secureStat extracts file info for path in a chroot'ed environment in root. -func secureStat(root string, path string) (*copier.StatForItem, error) { - var glob string - var err error - - // If root and path are equal, then dir must be empty and the glob must - // be ".". - if filepath.Clean(root) == filepath.Clean(path) { - glob = "." - } else { - glob, err = filepath.Rel(root, path) - if err != nil { - return nil, err - } - } - - globStats, err := copier.Stat(root, "", copier.StatOptions{}, []string{glob}) - if err != nil { - return nil, err - } - - if len(globStats) != 1 { - return nil, fmt.Errorf("internal error: secureStat: expected 1 item but got %d", len(globStats)) - } - if len(globStats) != 1 { - return nil, fmt.Errorf("internal error: secureStat: expected 1 result but got %d", len(globStats[0].Results)) - } - - // NOTE: the key in the map differ from `glob` when hitting symlink. - // Hence, we just take the first (and only) key/value pair. - for _, stat := range globStats[0].Results { - var statErr error - if stat.Error != "" { - statErr = errors.New(stat.Error) - } - // If necessary evaluate the symlink - if stat.IsSymlink { - target, err := copier.Eval(root, path, copier.EvalOptions{}) - if err != nil { - return nil, fmt.Errorf("evaluating symlink in container: %w", err) - } - // Need to make sure the symlink is relative to the root! - target = strings.TrimPrefix(target, root) - target = filepath.Join("/", target) - stat.ImmediateTarget = target - } - return stat, statErr - } - - // Nothing found! - return nil, copy.ErrENOENT + // If the container is NOT running, we need to resolve the path + // on the host. + return c.statOnHost(mountPoint, containerPath) } diff --git a/libpod/container_stat_unsupported.go b/libpod/container_stat_unsupported.go index 2f1acd44d..e88b88bb1 100644 --- a/libpod/container_stat_unsupported.go +++ b/libpod/container_stat_unsupported.go @@ -1,5 +1,5 @@ -//go:build !linux -// +build !linux +//go:build !linux && !freebsd +// +build !linux,!freebsd package libpod diff --git a/libpod/container_validate.go b/libpod/container_validate.go index f4611ecce..7224ec7db 100644 --- a/libpod/container_validate.go +++ b/libpod/container_validate.go @@ -3,6 +3,9 @@ package libpod import ( "fmt" + "github.com/containers/image/v5/docker" + "github.com/containers/image/v5/pkg/shortnames" + "github.com/containers/image/v5/transports/alltransports" "github.com/containers/podman/v4/libpod/define" spec "github.com/opencontainers/runtime-spec/specs-go" ) @@ -141,5 +144,35 @@ func (c *Container) validate() error { if c.config.HealthCheckOnFailureAction != define.HealthCheckOnFailureActionNone && c.config.HealthCheckConfig == nil { return fmt.Errorf("cannot set on-failure action to %s without a health check", c.config.HealthCheckOnFailureAction.String()) } + + if value, exists := c.config.Labels[define.AutoUpdateLabel]; exists { + // TODO: we cannot reference pkg/autoupdate here due to + // circular dependencies. It's worth considering moving the + // auto-update logic into the libpod package. + if value == "registry" || value == "image" { + if err := validateAutoUpdateImageReference(c.config.RawImageName); err != nil { + return err + } + } + } + + return nil +} + +// validateAutoUpdateImageReference checks if the specified imageName is a +// fully-qualified image reference to the docker transport. Such a reference +// includes a domain, name and tag (e.g., quay.io/podman/stable:latest). The +// reference may also be prefixed with "docker://" explicitly indicating that +// it's a reference to the docker transport. +func validateAutoUpdateImageReference(imageName string) error { + // Make sure the input image is a docker. + imageRef, err := alltransports.ParseImageName(imageName) + if err == nil && imageRef.Transport().Name() != docker.Transport.Name() { + return fmt.Errorf("auto updates require the docker image transport but image is of transport %q", imageRef.Transport().Name()) + } else if err != nil { + if shortnames.IsShortName(imageName) { + return fmt.Errorf("short name: auto updates require fully-qualified image reference: %q", imageName) + } + } return nil } diff --git a/libpod/define/autoupdate.go b/libpod/define/autoupdate.go new file mode 100644 index 000000000..7c278c3c5 --- /dev/null +++ b/libpod/define/autoupdate.go @@ -0,0 +1,9 @@ +package define + +// AutoUpdateLabel denotes the container/pod label key to specify auto-update +// policies in container labels. +const AutoUpdateLabel = "io.containers.autoupdate" + +// AutoUpdateAuthfileLabel denotes the container label key to specify authfile +// in container labels. +const AutoUpdateAuthfileLabel = "io.containers.autoupdate.authfile" diff --git a/libpod/define/config.go b/libpod/define/config.go index 1fad5cc9a..0427206ed 100644 --- a/libpod/define/config.go +++ b/libpod/define/config.go @@ -40,6 +40,10 @@ type InfoData struct { // itself. const VolumeDriverLocal = "local" +// VolumeDriverImage is the "image" volume driver. It is managed by Libpod and +// uses volumes backed by an image. +const VolumeDriverImage = "image" + const ( OCIManifestDir = "oci-dir" OCIArchive = "oci-archive" diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go index da5c58f27..7a00d708c 100644 --- a/libpod/define/container_inspect.go +++ b/libpod/define/container_inspect.go @@ -659,6 +659,7 @@ type InspectContainerData struct { Args []string `json:"Args"` State *InspectContainerState `json:"State"` Image string `json:"Image"` + ImageDigest string `json:"ImageDigest"` ImageName string `json:"ImageName"` Rootfs string `json:"Rootfs"` Pod string `json:"Pod"` diff --git a/libpod/define/volume_inspect.go b/libpod/define/volume_inspect.go index 76120647c..4d6f12080 100644 --- a/libpod/define/volume_inspect.go +++ b/libpod/define/volume_inspect.go @@ -58,6 +58,9 @@ type InspectVolumeData struct { NeedsChown bool `json:"NeedsChown,omitempty"` // Timeout is the specified driver timeout if given Timeout uint `json:"Timeout,omitempty"` + // StorageID is the ID of the container backing the volume in c/storage. + // Only used with Image Volumes. + StorageID string `json:"StorageID,omitempty"` } type VolumeReload struct { diff --git a/libpod/events.go b/libpod/events.go index 2f9799114..31a857a7d 100644 --- a/libpod/events.go +++ b/libpod/events.go @@ -34,6 +34,7 @@ func (c *Container) newContainerEvent(status events.Status) { e.Details = events.Details{ ID: e.ID, + PodID: c.PodID(), Attributes: c.Labels(), } @@ -59,6 +60,7 @@ func (c *Container) newContainerExitedEvent(exitCode int32) { e.Name = c.Name() e.Image = c.config.RootfsImageName e.Type = events.Container + e.PodID = c.PodID() e.ContainerExitCode = int(exitCode) e.Details = events.Details{ diff --git a/libpod/events/config.go b/libpod/events/config.go index 4ea45a00e..28bc87a34 100644 --- a/libpod/events/config.go +++ b/libpod/events/config.go @@ -50,6 +50,8 @@ type Event struct { type Details struct { // ID is the event ID ID string + // PodID is the ID of the pod associated with the container. + PodID string `json:",omitempty"` // Attributes can be used to describe specifics about the event // in the case of a container event, labels for example Attributes map[string]string diff --git a/libpod/events/events.go b/libpod/events/events.go index 764481e51..2105a3b89 100644 --- a/libpod/events/events.go +++ b/libpod/events/events.go @@ -76,7 +76,13 @@ func (e *Event) ToHumanReadable(truncate bool) string { } switch e.Type { case Container, Pod: - humanFormat = fmt.Sprintf("%s %s %s %s (image=%s, name=%s, health_status=%s", e.Time, e.Type, e.Status, id, e.Image, e.Name, e.HealthStatus) + humanFormat = fmt.Sprintf("%s %s %s %s (image=%s, name=%s", e.Time, e.Type, e.Status, id, e.Image, e.Name) + if e.PodID != "" { + humanFormat += fmt.Sprintf(", pod_id=%s", e.PodID) + } + if e.HealthStatus != "" { + humanFormat += fmt.Sprintf(", health_status=%s", e.HealthStatus) + } // check if the container has labels and add it to the output if len(e.Attributes) > 0 { for k, v := range e.Attributes { diff --git a/libpod/events/journal_linux.go b/libpod/events/journal_linux.go index 4986502a2..e303a205d 100644 --- a/libpod/events/journal_linux.go +++ b/libpod/events/journal_linux.go @@ -50,6 +50,9 @@ func (e EventJournalD) Write(ee Event) error { if ee.ContainerExitCode != 0 { m["PODMAN_EXIT_CODE"] = strconv.Itoa(ee.ContainerExitCode) } + if ee.PodID != "" { + m["PODMAN_POD_ID"] = ee.PodID + } // If we have container labels, we need to convert them to a string so they // can be recorded with the event if len(ee.Details.Attributes) > 0 { @@ -161,6 +164,7 @@ func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) { case Container, Pod: newEvent.ID = entry.Fields["PODMAN_ID"] newEvent.Image = entry.Fields["PODMAN_IMAGE"] + newEvent.PodID = entry.Fields["PODMAN_POD_ID"] if code, ok := entry.Fields["PODMAN_EXIT_CODE"]; ok { intCode, err := strconv.Atoi(code) if err != nil { @@ -179,7 +183,7 @@ func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) { // if we have labels, add them to the event if len(labels) > 0 { - newEvent.Details = Details{Attributes: labels} + newEvent.Attributes = labels } } newEvent.HealthStatus = entry.Fields["PODMAN_HEALTH_STATUS"] diff --git a/libpod/events/logfile.go b/libpod/events/logfile.go index d749a0d4d..bb0f461e3 100644 --- a/libpod/events/logfile.go +++ b/libpod/events/logfile.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path" "path/filepath" @@ -204,11 +203,11 @@ func truncate(filePath string) error { size := origFinfo.Size() threshold := size / 2 - tmp, err := ioutil.TempFile(path.Dir(filePath), "") + tmp, err := os.CreateTemp(path.Dir(filePath), "") if err != nil { // Retry in /tmp in case creating a tmp file in the same // directory has failed. - tmp, err = ioutil.TempFile("", "") + tmp, err = os.CreateTemp("", "") if err != nil { return err } diff --git a/libpod/events/logfile_test.go b/libpod/events/logfile_test.go index 302533c12..50141168e 100644 --- a/libpod/events/logfile_test.go +++ b/libpod/events/logfile_test.go @@ -1,7 +1,6 @@ package events import ( - "io/ioutil" "os" "testing" @@ -29,7 +28,7 @@ func TestRotateLog(t *testing.T) { } for _, test := range tests { - tmp, err := ioutil.TempFile("", "log-rotation-") + tmp, err := os.CreateTemp("", "log-rotation-") require.NoError(t, err) defer os.Remove(tmp.Name()) defer tmp.Close() @@ -84,7 +83,7 @@ func TestTruncationOutput(t *testing.T) { 10 ` // Create dummy file - tmp, err := ioutil.TempFile("", "log-rotation") + tmp, err := os.CreateTemp("", "log-rotation") require.NoError(t, err) defer os.Remove(tmp.Name()) defer tmp.Close() @@ -94,11 +93,11 @@ func TestTruncationOutput(t *testing.T) { require.NoError(t, err) // Truncate the file - beforeTruncation, err := ioutil.ReadFile(tmp.Name()) + beforeTruncation, err := os.ReadFile(tmp.Name()) require.NoError(t, err) err = truncate(tmp.Name()) require.NoError(t, err) - afterTruncation, err := ioutil.ReadFile(tmp.Name()) + afterTruncation, err := os.ReadFile(tmp.Name()) require.NoError(t, err) // Test if rotation was successful @@ -116,9 +115,9 @@ func TestRenameLog(t *testing.T) { 5 ` // Create two dummy files - source, err := ioutil.TempFile("", "removing") + source, err := os.CreateTemp("", "removing") require.NoError(t, err) - target, err := ioutil.TempFile("", "renaming") + target, err := os.CreateTemp("", "renaming") require.NoError(t, err) // Write to source dummy file @@ -126,11 +125,11 @@ func TestRenameLog(t *testing.T) { require.NoError(t, err) // Rename the files - beforeRename, err := ioutil.ReadFile(source.Name()) + beforeRename, err := os.ReadFile(source.Name()) require.NoError(t, err) err = renameLog(source.Name(), target.Name()) require.NoError(t, err) - afterRename, err := ioutil.ReadFile(target.Name()) + afterRename, err := os.ReadFile(target.Name()) require.NoError(t, err) // Test if renaming was successful diff --git a/libpod/healthcheck.go b/libpod/healthcheck.go index e835af9f0..a589f2787 100644 --- a/libpod/healthcheck.go +++ b/libpod/healthcheck.go @@ -5,7 +5,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -208,7 +207,7 @@ func (c *Container) updateHealthStatus(status string) error { if err != nil { return fmt.Errorf("unable to marshall healthchecks for writing status: %w", err) } - return ioutil.WriteFile(c.healthCheckLogPath(), newResults, 0700) + return os.WriteFile(c.healthCheckLogPath(), newResults, 0700) } // UpdateHealthCheckLog parses the health check results and writes the log @@ -242,7 +241,7 @@ func (c *Container) updateHealthCheckLog(hcl define.HealthCheckLog, inStartPerio if err != nil { return fmt.Errorf("unable to marshall healthchecks for writing: %w", err) } - return ioutil.WriteFile(c.healthCheckLogPath(), newResults, 0700) + return os.WriteFile(c.healthCheckLogPath(), newResults, 0700) } // HealthCheckLogPath returns the path for where the health check log is @@ -259,7 +258,7 @@ func (c *Container) getHealthCheckLog() (define.HealthCheckResults, error) { if _, err := os.Stat(c.healthCheckLogPath()); os.IsNotExist(err) { return healthCheck, nil } - b, err := ioutil.ReadFile(c.healthCheckLogPath()) + b, err := os.ReadFile(c.healthCheckLogPath()) if err != nil { return healthCheck, fmt.Errorf("failed to read health check log file: %w", err) } diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index e27ec8e9d..5376ff8ad 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -8,7 +8,6 @@ import ( "crypto/sha256" "errors" "fmt" - "io/ioutil" "net" "os" "os/exec" @@ -303,7 +302,7 @@ func (r *RootlessNetNS) Cleanup(runtime *Runtime) error { if err != nil { logrus.Error(err) } - b, err := ioutil.ReadFile(r.getPath(rootlessNetNsSilrp4netnsPidFile)) + b, err := os.ReadFile(r.getPath(rootlessNetNsSilrp4netnsPidFile)) if err == nil { var i int i, err = strconv.Atoi(string(b)) @@ -445,7 +444,7 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) { // create pid file for the slirp4netns process // this is need to kill the process in the cleanup pid := strconv.Itoa(cmd.Process.Pid) - err = ioutil.WriteFile(filepath.Join(rootlessNetNsDir, rootlessNetNsSilrp4netnsPidFile), []byte(pid), 0700) + err = os.WriteFile(filepath.Join(rootlessNetNsDir, rootlessNetNsSilrp4netnsPidFile), []byte(pid), 0700) if err != nil { return nil, fmt.Errorf("unable to write rootless-netns slirp4netns pid file: %w", err) } @@ -696,23 +695,31 @@ func (r *Runtime) teardownNetNS(ctr *Container) error { // do not return an error otherwise we would prevent network cleanup logrus.Errorf("failed to free gvproxy machine ports: %v", err) } - if err := r.teardownCNI(ctr); err != nil { - return err - } + + // Do not check the error here, we want to always umount the netns + // This will ensure that the container interface will be deleted + // even when there is a CNI or netavark bug. + prevErr := r.teardownCNI(ctr) // First unmount the namespace if err := netns.UnmountNS(ctr.state.NetNS); err != nil { + if prevErr != nil { + logrus.Error(prevErr) + } return fmt.Errorf("unmounting network namespace for container %s: %w", ctr.ID(), err) } // Now close the open file descriptor if err := ctr.state.NetNS.Close(); err != nil { + if prevErr != nil { + logrus.Error(prevErr) + } return fmt.Errorf("closing network namespace for container %s: %w", ctr.ID(), err) } ctr.state.NetNS = nil - return nil + return prevErr } func getContainerNetNS(ctr *Container) (string, *Container, error) { diff --git a/libpod/networking_machine.go b/libpod/networking_machine.go index 7b8eb94df..dce335c0a 100644 --- a/libpod/networking_machine.go +++ b/libpod/networking_machine.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "strconv" @@ -109,7 +108,7 @@ func makeMachineRequest(ctx context.Context, client *http.Client, url string, bu } func annotateGvproxyResponseError(r io.Reader) error { - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err == nil && len(b) > 0 { return fmt.Errorf("something went wrong with the request: %q", string(b)) } diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go index d4ec9082b..4026b6b48 100644 --- a/libpod/networking_slirp4netns.go +++ b/libpod/networking_slirp4netns.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "os" "os/exec" @@ -324,7 +323,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error { // correct value assigned so DAD is disabled for it // Also make sure to change this value back to the original after slirp4netns // is ready in case users rely on this sysctl. - orgValue, err := ioutil.ReadFile(ipv6ConfDefaultAcceptDadSysctl) + orgValue, err := os.ReadFile(ipv6ConfDefaultAcceptDadSysctl) if err != nil { netnsReadyWg.Done() // on ipv6 disabled systems the sysctl does not exists @@ -334,7 +333,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error { } return err } - err = ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, []byte("0"), 0644) + err = os.WriteFile(ipv6ConfDefaultAcceptDadSysctl, []byte("0"), 0644) netnsReadyWg.Done() if err != nil { return err @@ -342,7 +341,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error { // wait until slirp4nets is ready before resetting this value slirpReadyWg.Wait() - return ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, orgValue, 0644) + return os.WriteFile(ipv6ConfDefaultAcceptDadSysctl, orgValue, 0644) }) if err != nil { logrus.Warnf("failed to set net.ipv6.conf.default.accept_dad sysctl: %v", err) @@ -486,7 +485,7 @@ func waitForSync(syncR *os.File, cmd *exec.Cmd, logFile io.ReadSeeker, timeout t if _, err := logFile.Seek(0, 0); err != nil { logrus.Errorf("Could not seek log file: %q", err) } - logContent, err := ioutil.ReadAll(logFile) + logContent, err := io.ReadAll(logFile) if err != nil { return fmt.Errorf("%s failed: %w", prog, err) } @@ -730,7 +729,7 @@ func (c *Container) reloadRootlessRLKPortMapping() error { if err != nil { return fmt.Errorf("port reloading failed: %w", err) } - b, err := ioutil.ReadAll(conn) + b, err := io.ReadAll(conn) if err != nil { return fmt.Errorf("port reloading failed: %w", err) } diff --git a/libpod/oci_conmon_common.go b/libpod/oci_conmon_common.go index 53dddd064..cbdbad02d 100644 --- a/libpod/oci_conmon_common.go +++ b/libpod/oci_conmon_common.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "os" @@ -232,7 +231,7 @@ func (r *ConmonOCIRuntime) UpdateContainerStatus(ctr *Container) error { } if err := cmd.Start(); err != nil { - out, err2 := ioutil.ReadAll(errPipe) + out, err2 := io.ReadAll(errPipe) if err2 != nil { return fmt.Errorf("getting container %s state: %w", ctr.ID(), err) } @@ -254,7 +253,7 @@ func (r *ConmonOCIRuntime) UpdateContainerStatus(ctr *Container) error { if err := errPipe.Close(); err != nil { return err } - out, err := ioutil.ReadAll(outPipe) + out, err := io.ReadAll(outPipe) if err != nil { return fmt.Errorf("reading stdout: %s: %w", ctr.ID(), err) } @@ -335,7 +334,7 @@ func generateResourceFile(res *spec.LinuxResources) (string, []string, error) { return "", flags, nil } - f, err := ioutil.TempFile("", "podman") + f, err := os.CreateTemp("", "podman") if err != nil { return "", nil, err } @@ -1398,7 +1397,7 @@ func newPipe() (*os.File, *os.File, error) { func readConmonPidFile(pidFile string) (int, error) { // Let's try reading the Conmon pid at the same time. if pidFile != "" { - contents, err := ioutil.ReadFile(pidFile) + contents, err := os.ReadFile(pidFile) if err != nil { return -1, err } @@ -1447,7 +1446,7 @@ func readConmonPipeData(runtimeName string, pipe *os.File, ociLog string) (int, case ss := <-ch: if ss.err != nil { if ociLog != "" { - ociLogData, err := ioutil.ReadFile(ociLog) + ociLogData, err := os.ReadFile(ociLog) if err == nil { var ociErr ociError if err := json.Unmarshal(ociLogData, &ociErr); err == nil { @@ -1460,7 +1459,7 @@ func readConmonPipeData(runtimeName string, pipe *os.File, ociLog string) (int, logrus.Debugf("Received: %d", ss.si.Data) if ss.si.Data < 0 { if ociLog != "" { - ociLogData, err := ioutil.ReadFile(ociLog) + ociLogData, err := os.ReadFile(ociLog) if err == nil { var ociErr ociError if err := json.Unmarshal(ociLogData, &ociErr); err == nil { diff --git a/libpod/oci_conmon_exec_common.go b/libpod/oci_conmon_exec_common.go index e5080942b..24113bd8d 100644 --- a/libpod/oci_conmon_exec_common.go +++ b/libpod/oci_conmon_exec_common.go @@ -3,7 +3,6 @@ package libpod import ( "errors" "fmt" - "io/ioutil" "net/http" "os" "os/exec" @@ -665,7 +664,7 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp // prepareProcessExec returns the path of the process.json used in runc exec -p // caller is responsible to close the returned *os.File if needed. func (c *Container) prepareProcessExec(options *ExecOptions, env []string, sessionID string) (*os.File, error) { - f, err := ioutil.TempFile(c.execBundlePath(sessionID), "exec-process-") + f, err := os.CreateTemp(c.execBundlePath(sessionID), "exec-process-") if err != nil { return nil, err } @@ -764,7 +763,7 @@ func (c *Container) prepareProcessExec(options *ExecOptions, env []string, sessi return nil, err } - if err := ioutil.WriteFile(f.Name(), processJSON, 0644); err != nil { + if err := os.WriteFile(f.Name(), processJSON, 0644); err != nil { return nil, err } return f, nil diff --git a/libpod/plugin/volume_api.go b/libpod/plugin/volume_api.go index 522895798..c595937ae 100644 --- a/libpod/plugin/volume_api.go +++ b/libpod/plugin/volume_api.go @@ -5,7 +5,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "io" "net" "net/http" "os" @@ -95,7 +95,7 @@ func validatePlugin(newPlugin *VolumePlugin) error { } // Read and decode the body so we can tell if this is a volume plugin. - respBytes, err := ioutil.ReadAll(resp.Body) + respBytes, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("reading activation response body from plugin %s: %w", newPlugin.Name, err) } @@ -252,7 +252,7 @@ func (p *VolumePlugin) handleErrorResponse(resp *http.Response, endpoint, volNam // Let's interpret anything other than 200 as an error. // If there isn't an error, don't even bother decoding the response. if resp.StatusCode != 200 { - errResp, err := ioutil.ReadAll(resp.Body) + errResp, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("reading response body from volume plugin %s: %w", p.Name, err) } @@ -307,7 +307,7 @@ func (p *VolumePlugin) ListVolumes() ([]*volume.Volume, error) { return nil, err } - volumeRespBytes, err := ioutil.ReadAll(resp.Body) + volumeRespBytes, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("reading response body from volume plugin %s: %w", p.Name, err) } @@ -342,7 +342,7 @@ func (p *VolumePlugin) GetVolume(req *volume.GetRequest) (*volume.Volume, error) return nil, err } - getRespBytes, err := ioutil.ReadAll(resp.Body) + getRespBytes, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("reading response body from volume plugin %s: %w", p.Name, err) } @@ -398,7 +398,7 @@ func (p *VolumePlugin) GetVolumePath(req *volume.PathRequest) (string, error) { return "", err } - pathRespBytes, err := ioutil.ReadAll(resp.Body) + pathRespBytes, err := io.ReadAll(resp.Body) if err != nil { return "", fmt.Errorf("reading response body from volume plugin %s: %w", p.Name, err) } @@ -435,7 +435,7 @@ func (p *VolumePlugin) MountVolume(req *volume.MountRequest) (string, error) { return "", err } - mountRespBytes, err := ioutil.ReadAll(resp.Body) + mountRespBytes, err := io.ReadAll(resp.Body) if err != nil { return "", fmt.Errorf("reading response body from volume plugin %s: %w", p.Name, err) } diff --git a/libpod/runtime.go b/libpod/runtime.go index 83c9f53e2..f250d759c 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -1091,6 +1091,9 @@ func (r *Runtime) getVolumePlugin(volConfig *VolumeConfig) (*plugin.VolumePlugin pluginPath, ok := r.config.Engine.VolumePlugins[name] if !ok { + if name == define.VolumeDriverImage { + return nil, nil + } return nil, fmt.Errorf("no volume plugin with name %s available: %w", name, define.ErrMissingPlugin) } diff --git a/libpod/runtime_cstorage.go b/libpod/runtime_cstorage.go index 372434b49..5917b7931 100644 --- a/libpod/runtime_cstorage.go +++ b/libpod/runtime_cstorage.go @@ -86,6 +86,17 @@ func (r *Runtime) RemoveStorageContainer(idOrName string, force bool) error { return fmt.Errorf("refusing to remove %q as it exists in libpod as container %s: %w", idOrName, ctr.ID, define.ErrCtrExists) } + // Error out if this is an image-backed volume + allVols, err := r.state.AllVolumes() + if err != nil { + return err + } + for _, vol := range allVols { + if vol.config.Driver == define.VolumeDriverImage && vol.config.StorageID == ctr.ID { + return fmt.Errorf("refusing to remove %q as it exists in libpod as an image-backed volume %s: %w", idOrName, vol.Name(), define.ErrCtrExists) + } + } + if !force { timesMounted, err := r.store.Mounted(ctr.ID) if err != nil { diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 7b3cbadfa..bb30078cb 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -512,7 +512,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai volOptions = append(volOptions, parsedOptions...) } } - newVol, err := r.newVolume(false, volOptions...) + newVol, err := r.newVolume(ctx, false, volOptions...) if err != nil { return nil, fmt.Errorf("creating named volume %q: %w", vol.Name, err) } diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index dacbd752f..d8e88ca50 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" buildahDefine "github.com/containers/buildah/define" @@ -52,6 +51,23 @@ func (r *Runtime) RemoveContainersForImageCallback(ctx context.Context) libimage } } } + + // Need to handle volumes with the image driver + vols, err := r.state.AllVolumes() + if err != nil { + return err + } + for _, vol := range vols { + if vol.config.Driver != define.VolumeDriverImage || vol.config.StorageImageID != imageID { + continue + } + // Do a force removal of the volume, and all containers + // using it. + if err := r.RemoveVolume(ctx, vol, true, nil); err != nil { + return fmt.Errorf("removing image %s: volume %s backed by image could not be removed: %w", imageID, vol.Name(), err) + } + } + // Note that `libimage` will take care of removing any leftover // containers from the storage. return nil @@ -75,6 +91,10 @@ func (r *Runtime) IsExternalContainerCallback(_ context.Context) libimage.IsExte if errors.Is(err, define.ErrNoSuchCtr) { return true, nil } + isVol, err := r.state.ContainerIDIsVolume(idOrName) + if err == nil && !isVol { + return true, nil + } return false, nil } } @@ -105,7 +125,7 @@ func (r *Runtime) Build(ctx context.Context, options buildahDefine.BuildOptions, // DownloadFromFile reads all of the content from the reader and temporarily // saves in it $TMPDIR/importxyz, which is deleted after the image is imported func DownloadFromFile(reader *os.File) (string, error) { - outFile, err := ioutil.TempFile(util.Tmpdir(), "import") + outFile, err := os.CreateTemp(util.Tmpdir(), "import") if err != nil { return "", fmt.Errorf("creating file: %w", err) } diff --git a/libpod/runtime_migrate.go b/libpod/runtime_migrate.go index 36901d4d0..df1a1f1cb 100644 --- a/libpod/runtime_migrate.go +++ b/libpod/runtime_migrate.go @@ -5,7 +5,6 @@ package libpod import ( "fmt" - "io/ioutil" "os" "path/filepath" "strconv" @@ -23,7 +22,7 @@ func (r *Runtime) stopPauseProcess() error { if err != nil { return fmt.Errorf("could not get pause process pid file path: %w", err) } - data, err := ioutil.ReadFile(pausePidPath) + data, err := os.ReadFile(pausePidPath) if err != nil { if os.IsNotExist(err) { return nil diff --git a/libpod/runtime_volume_linux.go b/libpod/runtime_volume_common.go index 08fdbf977..b1de2be86 100644 --- a/libpod/runtime_volume_linux.go +++ b/libpod/runtime_volume_common.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package libpod @@ -15,6 +15,7 @@ import ( "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/events" volplugin "github.com/containers/podman/v4/libpod/plugin" + "github.com/containers/storage" "github.com/containers/storage/drivers/quota" "github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/stringid" @@ -22,18 +23,20 @@ import ( "github.com/sirupsen/logrus" ) +const volumeSuffix = "+volume" + // NewVolume creates a new empty volume func (r *Runtime) NewVolume(ctx context.Context, options ...VolumeCreateOption) (*Volume, error) { if !r.valid { return nil, define.ErrRuntimeStopped } - return r.newVolume(false, options...) + return r.newVolume(ctx, false, options...) } // newVolume creates a new empty volume with the given options. // The createPluginVolume can be set to true to make it not create the volume in the volume plugin, // this is required for the UpdateVolumePlugins() function. If you are not sure, set this to false. -func (r *Runtime) newVolume(noCreatePluginVolume bool, options ...VolumeCreateOption) (_ *Volume, deferredErr error) { +func (r *Runtime) newVolume(ctx context.Context, noCreatePluginVolume bool, options ...VolumeCreateOption) (_ *Volume, deferredErr error) { volume := newVolume(r) for _, option := range options { if err := option(volume); err != nil { @@ -83,6 +86,50 @@ func (r *Runtime) newVolume(noCreatePluginVolume bool, options ...VolumeCreateOp return nil, fmt.Errorf("invalid mount option %s for driver 'local': %w", key, define.ErrInvalidArg) } } + } else if volume.config.Driver == define.VolumeDriverImage && !volume.UsesVolumeDriver() { + logrus.Debugf("Creating image-based volume") + var imgString string + // Validate options + for key, val := range volume.config.Options { + switch strings.ToLower(key) { + case "image": + imgString = val + default: + return nil, fmt.Errorf("invalid mount option %s for driver 'image': %w", key, define.ErrInvalidArg) + } + } + + if imgString == "" { + return nil, fmt.Errorf("must provide an image name when creating a volume with the image driver: %w", define.ErrInvalidArg) + } + + // Look up the image + image, _, err := r.libimageRuntime.LookupImage(imgString, nil) + if err != nil { + return nil, fmt.Errorf("looking up image %s to create volume failed: %w", imgString, err) + } + + // Generate a c/storage name and ID for the volume. + // Use characters Podman does not allow for the name, to ensure + // no collision with containers. + volume.config.StorageID = stringid.GenerateRandomID() + volume.config.StorageName = volume.config.Name + volumeSuffix + volume.config.StorageImageID = image.ID() + + // Create a backing container in c/storage. + storageConfig := storage.ContainerOptions{ + LabelOpts: []string{"filetype:container_file_t:s0"}, + } + if _, err := r.storageService.CreateContainerStorage(ctx, r.imageContext, imgString, image.ID(), volume.config.StorageName, volume.config.StorageID, storageConfig); err != nil { + return nil, fmt.Errorf("creating backing storage for image driver: %w", err) + } + defer func() { + if deferredErr != nil { + if err := r.storageService.DeleteContainer(volume.config.StorageID); err != nil { + logrus.Errorf("Error removing volume %s backing storage: %v", volume.config.Name, err) + } + } + }() } // Now we get conditional: we either need to make the volume in the @@ -196,7 +243,7 @@ func (r *Runtime) UpdateVolumePlugins(ctx context.Context) *define.VolumeReload } for _, vol := range vols { allPluginVolumes[vol.Name] = struct{}{} - if _, err := r.newVolume(true, WithVolumeName(vol.Name), WithVolumeDriver(driverName)); err != nil { + if _, err := r.newVolume(ctx, true, WithVolumeName(vol.Name), WithVolumeDriver(driverName)); err != nil { // If the volume exists this is not an error, just ignore it and log. It is very likely // that the volume from the plugin was already in our db. if !errors.Is(err, define.ErrVolumeExists) { @@ -375,6 +422,14 @@ func (r *Runtime) removeVolume(ctx context.Context, v *Volume, force bool, timeo return fmt.Errorf("volume %s could not be removed from plugin %s: %w", v.Name(), v.Driver(), err) } } + } else if v.config.Driver == define.VolumeDriverImage { + if err := v.runtime.storageService.DeleteContainer(v.config.StorageID); err != nil { + // Storage container is already gone, no problem. + if !(errors.Is(err, storage.ErrNotAContainer) || errors.Is(err, storage.ErrContainerUnknown)) { + return fmt.Errorf("removing volume %s storage: %w", v.Name(), err) + } + logrus.Infof("Storage for volume %s already removed", v.Name()) + } } // Remove the volume from the state diff --git a/libpod/runtime_volume_unsupported.go b/libpod/runtime_volume_unsupported.go index c2816b817..7b7758894 100644 --- a/libpod/runtime_volume_unsupported.go +++ b/libpod/runtime_volume_unsupported.go @@ -1,5 +1,5 @@ -//go:build !linux -// +build !linux +//go:build !linux && !freebsd +// +build !linux,!freebsd package libpod diff --git a/libpod/state.go b/libpod/state.go index 4fbd3c302..9d9604563 100644 --- a/libpod/state.go +++ b/libpod/state.go @@ -144,6 +144,14 @@ type State interface { // As with RemoveExecSession, container state will not be modified. RemoveContainerExecSessions(ctr *Container) error + // ContainerIDIsVolume checks if the given container ID is in use by a + // volume. + // Some volumes are backed by a c/storage container. These do not have a + // corresponding Container struct in Libpod, but rather a Volume. + // This determines if a given ID from c/storage is used as a backend by + // a Podman volume. + ContainerIDIsVolume(id string) (bool, error) + // PLEASE READ FULL DESCRIPTION BEFORE USING. // Rewrite a container's configuration. // This function breaks libpod's normal prohibition on a read-only diff --git a/libpod/state_test.go b/libpod/state_test.go index 3c1fe8f63..7664f7c00 100644 --- a/libpod/state_test.go +++ b/libpod/state_test.go @@ -1,7 +1,6 @@ package libpod import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -35,7 +34,7 @@ var ( // Get an empty BoltDB state for use in tests func getEmptyBoltState() (_ State, _ string, _ lock.Manager, retErr error) { - tmpDir, err := ioutil.TempDir("", tmpDirPrefix) + tmpDir, err := os.MkdirTemp("", tmpDirPrefix) if err != nil { return nil, "", nil, err } diff --git a/libpod/util_freebsd.go b/libpod/util_freebsd.go new file mode 100644 index 000000000..72019743c --- /dev/null +++ b/libpod/util_freebsd.go @@ -0,0 +1,36 @@ +//go:build freebsd +// +build freebsd + +package libpod + +import ( + "errors" + "syscall" + + spec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" +) + +// systemdSliceFromPath makes a new systemd slice under the given parent with +// the given name. +// The parent must be a slice. The name must NOT include ".slice" +func systemdSliceFromPath(parent, name string, resources *spec.LinuxResources) (string, error) { + return "", errors.New("not implemented systemdSliceFromPath") +} + +// No equivalent on FreeBSD? +func LabelVolumePath(path string) error { + return nil +} + +// Unmount umounts a target directory +func Unmount(mount string) { + if err := unix.Unmount(mount, unix.MNT_FORCE); err != nil { + if err != syscall.EINVAL { + logrus.Warnf("Failed to unmount %s : %v", mount, err) + } else { + logrus.Debugf("failed to unmount %s : %v", mount, err) + } + } +} diff --git a/libpod/util_unsupported.go b/libpod/util_unsupported.go index d2ec3ae7b..fc3d00274 100644 --- a/libpod/util_unsupported.go +++ b/libpod/util_unsupported.go @@ -1,5 +1,5 @@ -//go:build !linux -// +build !linux +//go:build !linux && !freebsd +// +build !linux,!freebsd package libpod diff --git a/libpod/volume.go b/libpod/volume.go index a054e4032..2d4ea4280 100644 --- a/libpod/volume.go +++ b/libpod/volume.go @@ -57,6 +57,15 @@ type VolumeConfig struct { DisableQuota bool `json:"disableQuota,omitempty"` // Timeout allows users to override the default driver timeout of 5 seconds Timeout *uint `json:"timeout,omitempty"` + // StorageName is the name of the volume in c/storage. Only used for + // image volumes. + StorageName string `json:"storageName,omitempty"` + // StorageID is the ID of the volume in c/storage. Only used for image + // volumes. + StorageID string `json:"storageID,omitempty"` + // StorageImageID is the ID of the image the volume was based off of. + // Only used for image volumes. + StorageImageID string `json:"storageImageID,omitempty"` } // VolumeState holds the volume's mutable state. @@ -149,7 +158,7 @@ func (v *Volume) MountCount() (uint, error) { // Internal-only helper for volume mountpoint func (v *Volume) mountPoint() string { - if v.UsesVolumeDriver() { + if v.UsesVolumeDriver() || v.config.Driver == define.VolumeDriverImage { return v.state.MountPoint } @@ -250,6 +259,12 @@ func (v *Volume) IsDangling() (bool, error) { // drivers are pluggable backends for volumes that will manage the storage and // mounting. func (v *Volume) UsesVolumeDriver() bool { + if v.config.Driver == define.VolumeDriverImage { + if _, ok := v.runtime.config.Engine.VolumePlugins[v.config.Driver]; ok { + return true + } + return false + } return !(v.config.Driver == define.VolumeDriverLocal || v.config.Driver == "") } diff --git a/libpod/volume_inspect.go b/libpod/volume_inspect.go index 73441576b..31fbd5eff 100644 --- a/libpod/volume_inspect.go +++ b/libpod/volume_inspect.go @@ -64,6 +64,7 @@ func (v *Volume) Inspect() (*define.InspectVolumeData, error) { data.MountCount = v.state.MountCount data.NeedsCopyUp = v.state.NeedsCopyUp data.NeedsChown = v.state.NeedsChown + data.StorageID = v.config.StorageID if v.config.Timeout != nil { data.Timeout = *v.config.Timeout diff --git a/libpod/volume_internal.go b/libpod/volume_internal.go index 43c3f9b0b..14b852f8e 100644 --- a/libpod/volume_internal.go +++ b/libpod/volume_internal.go @@ -39,6 +39,11 @@ func (v *Volume) needsMount() bool { return true } + // Image driver always needs mount + if v.config.Driver == define.VolumeDriverImage { + return true + } + // Commit 28138dafcc added the UID and GID options to this map // However we should only mount when options other than uid and gid are set. // see https://github.com/containers/podman/issues/10620 diff --git a/libpod/volume_internal_common.go b/libpod/volume_internal_common.go new file mode 100644 index 000000000..4ff7ac790 --- /dev/null +++ b/libpod/volume_internal_common.go @@ -0,0 +1,194 @@ +//go:build linux || freebsd +// +build linux freebsd + +package libpod + +import ( + "errors" + "fmt" + "os/exec" + "strings" + + "github.com/containers/podman/v4/libpod/define" + pluginapi "github.com/docker/go-plugins-helpers/volume" + "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" +) + +// This is a pseudo-container ID to use when requesting a mount or unmount from +// the volume plugins. +// This is the shas256 of the string "placeholder\n". +const pseudoCtrID = "2f73349cfc4630255319c6c8dfc1b46a8996ace9d14d8e07563b165915918ec2" + +// mount mounts the volume if necessary. +// A mount is necessary if a volume has any options set. +// If a mount is necessary, v.state.MountCount will be incremented. +// If it was 0 when the increment occurred, the volume will be mounted on the +// host. Otherwise, we assume it is already mounted. +// Must be done while the volume is locked. +// Is a no-op on volumes that do not require a mount (as defined by +// volumeNeedsMount()). +func (v *Volume) mount() error { + if !v.needsMount() { + return nil + } + + // Update the volume from the DB to get an accurate mount counter. + if err := v.update(); err != nil { + return err + } + + // If the count is non-zero, the volume is already mounted. + // Nothing to do. + if v.state.MountCount > 0 { + v.state.MountCount++ + logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount) + return v.save() + } + + // Volume plugins implement their own mount counter, based on the ID of + // the mounting container. But we already have one, and honestly I trust + // ours more. So hardcode container ID to something reasonable, and use + // the same one for everything. + if v.UsesVolumeDriver() { + if v.plugin == nil { + return fmt.Errorf("volume plugin %s (needed by volume %s) missing: %w", v.Driver(), v.Name(), define.ErrMissingPlugin) + } + + req := new(pluginapi.MountRequest) + req.Name = v.Name() + req.ID = pseudoCtrID + mountPoint, err := v.plugin.MountVolume(req) + if err != nil { + return err + } + + v.state.MountCount++ + v.state.MountPoint = mountPoint + return v.save() + } else if v.config.Driver == define.VolumeDriverImage { + mountPoint, err := v.runtime.storageService.MountContainerImage(v.config.StorageID) + if err != nil { + return fmt.Errorf("mounting volume %s image failed: %w", v.Name(), err) + } + + v.state.MountCount++ + v.state.MountPoint = mountPoint + return v.save() + } + + volDevice := v.config.Options["device"] + volType := v.config.Options["type"] + volOptions := v.config.Options["o"] + + // Some filesystems (tmpfs) don't have a device, but we still need to + // give the kernel something. + if volDevice == "" && volType != "" { + volDevice = volType + } + + // We need to use the actual mount command. + // Convincing unix.Mount to use the same semantics as the mount command + // itself seems prohibitively difficult. + // TODO: might want to cache this path in the runtime? + mountPath, err := exec.LookPath("mount") + if err != nil { + return fmt.Errorf("locating 'mount' binary: %w", err) + } + mountArgs := []string{} + if volOptions != "" { + mountArgs = append(mountArgs, "-o", volOptions) + } + switch volType { + case "": + case "bind": + mountArgs = append(mountArgs, "-o", volType) + default: + mountArgs = append(mountArgs, "-t", volType) + } + + mountArgs = append(mountArgs, volDevice, v.config.MountPoint) + mountCmd := exec.Command(mountPath, mountArgs...) + + logrus.Debugf("Running mount command: %s %s", mountPath, strings.Join(mountArgs, " ")) + if output, err := mountCmd.CombinedOutput(); err != nil { + logrus.Debugf("Mount %v failed with %v", mountCmd, err) + return errors.New(string(output)) + } + + logrus.Debugf("Mounted volume %s", v.Name()) + + // Increment the mount counter + v.state.MountCount++ + logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount) + return v.save() +} + +// unmount unmounts the volume if necessary. +// Unmounting a volume that is not mounted is a no-op. +// Unmounting a volume that does not require a mount is a no-op. +// The volume must be locked for this to occur. +// The mount counter will be decremented if non-zero. If the counter reaches 0, +// the volume will really be unmounted, as no further containers are using the +// volume. +// If force is set, the volume will be unmounted regardless of mount counter. +func (v *Volume) unmount(force bool) error { + if !v.needsMount() { + return nil + } + + // Update the volume from the DB to get an accurate mount counter. + if err := v.update(); err != nil { + return err + } + + if v.state.MountCount == 0 { + logrus.Debugf("Volume %s already unmounted", v.Name()) + return nil + } + + if !force { + v.state.MountCount-- + } else { + v.state.MountCount = 0 + } + + logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount) + + if v.state.MountCount == 0 { + if v.UsesVolumeDriver() { + if v.plugin == nil { + return fmt.Errorf("volume plugin %s (needed by volume %s) missing: %w", v.Driver(), v.Name(), define.ErrMissingPlugin) + } + + req := new(pluginapi.UnmountRequest) + req.Name = v.Name() + req.ID = pseudoCtrID + if err := v.plugin.UnmountVolume(req); err != nil { + return err + } + + v.state.MountPoint = "" + return v.save() + } else if v.config.Driver == define.VolumeDriverImage { + if _, err := v.runtime.storageService.UnmountContainerImage(v.config.StorageID, force); err != nil { + return fmt.Errorf("unmounting volume %s image: %w", v.Name(), err) + } + + v.state.MountPoint = "" + return v.save() + } + + // Unmount the volume + if err := detachUnmount(v.config.MountPoint); err != nil { + if err == unix.EINVAL { + // Ignore EINVAL - the mount no longer exists. + return nil + } + return fmt.Errorf("unmounting volume %s: %w", v.Name(), err) + } + logrus.Debugf("Unmounted volume %s", v.Name()) + } + + return v.save() +} diff --git a/libpod/volume_internal_freebsd.go b/libpod/volume_internal_freebsd.go new file mode 100644 index 000000000..cf71f1e32 --- /dev/null +++ b/libpod/volume_internal_freebsd.go @@ -0,0 +1,9 @@ +package libpod + +import ( + "golang.org/x/sys/unix" +) + +func detachUnmount(mountPoint string) error { + return unix.Unmount(mountPoint, unix.MNT_FORCE) +} diff --git a/libpod/volume_internal_linux.go b/libpod/volume_internal_linux.go index cfd60554d..eb4309dc3 100644 --- a/libpod/volume_internal_linux.go +++ b/libpod/volume_internal_linux.go @@ -1,178 +1,9 @@ -//go:build linux -// +build linux - package libpod import ( - "errors" - "fmt" - "os/exec" - "strings" - - "github.com/containers/podman/v4/libpod/define" - pluginapi "github.com/docker/go-plugins-helpers/volume" - "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) -// This is a pseudo-container ID to use when requesting a mount or unmount from -// the volume plugins. -// This is the shas256 of the string "placeholder\n". -const pseudoCtrID = "2f73349cfc4630255319c6c8dfc1b46a8996ace9d14d8e07563b165915918ec2" - -// mount mounts the volume if necessary. -// A mount is necessary if a volume has any options set. -// If a mount is necessary, v.state.MountCount will be incremented. -// If it was 0 when the increment occurred, the volume will be mounted on the -// host. Otherwise, we assume it is already mounted. -// Must be done while the volume is locked. -// Is a no-op on volumes that do not require a mount (as defined by -// volumeNeedsMount()). -func (v *Volume) mount() error { - if !v.needsMount() { - return nil - } - - // Update the volume from the DB to get an accurate mount counter. - if err := v.update(); err != nil { - return err - } - - // If the count is non-zero, the volume is already mounted. - // Nothing to do. - if v.state.MountCount > 0 { - v.state.MountCount++ - logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount) - return v.save() - } - - // Volume plugins implement their own mount counter, based on the ID of - // the mounting container. But we already have one, and honestly I trust - // ours more. So hardcode container ID to something reasonable, and use - // the same one for everything. - if v.UsesVolumeDriver() { - if v.plugin == nil { - return fmt.Errorf("volume plugin %s (needed by volume %s) missing: %w", v.Driver(), v.Name(), define.ErrMissingPlugin) - } - - req := new(pluginapi.MountRequest) - req.Name = v.Name() - req.ID = pseudoCtrID - mountPoint, err := v.plugin.MountVolume(req) - if err != nil { - return err - } - - v.state.MountCount++ - v.state.MountPoint = mountPoint - return v.save() - } - - volDevice := v.config.Options["device"] - volType := v.config.Options["type"] - volOptions := v.config.Options["o"] - - // Some filesystems (tmpfs) don't have a device, but we still need to - // give the kernel something. - if volDevice == "" && volType != "" { - volDevice = volType - } - - // We need to use the actual mount command. - // Convincing unix.Mount to use the same semantics as the mount command - // itself seems prohibitively difficult. - // TODO: might want to cache this path in the runtime? - mountPath, err := exec.LookPath("mount") - if err != nil { - return fmt.Errorf("locating 'mount' binary: %w", err) - } - mountArgs := []string{} - if volOptions != "" { - mountArgs = append(mountArgs, "-o", volOptions) - } - switch volType { - case "": - case "bind": - mountArgs = append(mountArgs, "-o", volType) - default: - mountArgs = append(mountArgs, "-t", volType) - } - - mountArgs = append(mountArgs, volDevice, v.config.MountPoint) - mountCmd := exec.Command(mountPath, mountArgs...) - - logrus.Debugf("Running mount command: %s %s", mountPath, strings.Join(mountArgs, " ")) - if output, err := mountCmd.CombinedOutput(); err != nil { - logrus.Debugf("Mount %v failed with %v", mountCmd, err) - return errors.New(string(output)) - } - - logrus.Debugf("Mounted volume %s", v.Name()) - - // Increment the mount counter - v.state.MountCount++ - logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount) - return v.save() -} - -// unmount unmounts the volume if necessary. -// Unmounting a volume that is not mounted is a no-op. -// Unmounting a volume that does not require a mount is a no-op. -// The volume must be locked for this to occur. -// The mount counter will be decremented if non-zero. If the counter reaches 0, -// the volume will really be unmounted, as no further containers are using the -// volume. -// If force is set, the volume will be unmounted regardless of mount counter. -func (v *Volume) unmount(force bool) error { - if !v.needsMount() { - return nil - } - - // Update the volume from the DB to get an accurate mount counter. - if err := v.update(); err != nil { - return err - } - - if v.state.MountCount == 0 { - logrus.Debugf("Volume %s already unmounted", v.Name()) - return nil - } - - if !force { - v.state.MountCount-- - } else { - v.state.MountCount = 0 - } - - logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount) - - if v.state.MountCount == 0 { - if v.UsesVolumeDriver() { - if v.plugin == nil { - return fmt.Errorf("volume plugin %s (needed by volume %s) missing: %w", v.Driver(), v.Name(), define.ErrMissingPlugin) - } - - req := new(pluginapi.UnmountRequest) - req.Name = v.Name() - req.ID = pseudoCtrID - if err := v.plugin.UnmountVolume(req); err != nil { - return err - } - - v.state.MountPoint = "" - return v.save() - } - - // Unmount the volume - if err := unix.Unmount(v.config.MountPoint, unix.MNT_DETACH); err != nil { - if err == unix.EINVAL { - // Ignore EINVAL - the mount no longer exists. - return nil - } - return fmt.Errorf("unmounting volume %s: %w", v.Name(), err) - } - logrus.Debugf("Unmounted volume %s", v.Name()) - } - - return v.save() +func detachUnmount(mountPoint string) error { + return unix.Unmount(mountPoint, unix.MNT_DETACH) } diff --git a/libpod/volume_internal_unsupported.go b/libpod/volume_internal_unsupported.go index 50515e692..d138c15fb 100644 --- a/libpod/volume_internal_unsupported.go +++ b/libpod/volume_internal_unsupported.go @@ -1,5 +1,5 @@ -//go:build !linux -// +build !linux +//go:build !linux && !freebsd +// +build !linux,!freebsd package libpod diff --git a/pkg/api/handlers/compat/containers_export.go b/pkg/api/handlers/compat/containers_export.go index 66e1dcca5..03e547411 100644 --- a/pkg/api/handlers/compat/containers_export.go +++ b/pkg/api/handlers/compat/containers_export.go @@ -2,7 +2,6 @@ package compat import ( "fmt" - "io/ioutil" "net/http" "os" @@ -19,7 +18,7 @@ func ExportContainer(w http.ResponseWriter, r *http.Request) { utils.ContainerNotFound(w, name, err) return } - tmpfile, err := ioutil.TempFile("", "api.tar") + tmpfile, err := os.CreateTemp("", "api.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index 0493c6ffb..cce482441 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -4,7 +4,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "net/http" "os" "strings" @@ -49,7 +48,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) { // 500 server runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) - tmpfile, err := ioutil.TempFile("", "api.tar") + tmpfile, err := os.CreateTemp("", "api.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return @@ -193,7 +192,7 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) { // fromSrc – Source to import. The value may be a URL from which the image can be retrieved or - to read the image from the request body. This parameter may only be used when importing an image. source := query.FromSrc if source == "-" { - f, err := ioutil.TempFile("", "api_load.tar") + f, err := os.CreateTemp("", "api_load.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("failed to create tempfile: %w", err)) return @@ -480,7 +479,7 @@ func LoadImages(w http.ResponseWriter, r *http.Request) { // First write the body to a temporary file that we can later attempt // to load. - f, err := ioutil.TempFile("", "api_load.tar") + f, err := os.CreateTemp("", "api_load.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("failed to create tempfile: %w", err)) return @@ -547,7 +546,7 @@ func ExportImages(w http.ResponseWriter, r *http.Request) { images[i] = possiblyNormalizedName } - tmpfile, err := ioutil.TempFile("", "api.tar") + tmpfile, err := os.CreateTemp("", "api.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index 4035b4315..d4c8c0743 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "os" "path/filepath" @@ -131,6 +130,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { Secrets string `schema:"secrets"` SecurityOpt string `schema:"securityopt"` ShmSize int `schema:"shmsize"` + SkipUnusedStages bool `schema:"skipunusedstages"` Squash bool `schema:"squash"` TLSVerify bool `schema:"tlsVerify"` Tags []string `schema:"t"` @@ -139,12 +139,13 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { Ulimits string `schema:"ulimits"` UnsetEnvs []string `schema:"unsetenv"` }{ - Dockerfile: "Dockerfile", - IdentityLabel: true, - Registry: "docker.io", - Rm: true, - ShmSize: 64 * 1024 * 1024, - TLSVerify: true, + Dockerfile: "Dockerfile", + IdentityLabel: true, + Registry: "docker.io", + Rm: true, + ShmSize: 64 * 1024 * 1024, + TLSVerify: true, + SkipUnusedStages: true, } decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) @@ -182,7 +183,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { dockerFileSet := false if utils.IsLibpodRequest(r) && query.Remote != "" { // The context directory could be a URL. Try to handle that. - anchorDir, err := ioutil.TempDir(parse.GetTempDir(), "libpod_builder") + anchorDir, err := os.MkdirTemp(parse.GetTempDir(), "libpod_builder") if err != nil { utils.InternalServerError(w, err) } @@ -676,6 +677,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { RemoveIntermediateCtrs: query.Rm, ReportWriter: reporter, RusageLogFile: query.RusageLogFile, + SkipUnusedStages: types.NewOptionalBool(query.SkipUnusedStages), Squash: query.Squash, SystemContext: systemContext, Target: query.Target, @@ -730,7 +732,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { if logrus.IsLevelEnabled(logrus.DebugLevel) { if v, found := os.LookupEnv("PODMAN_RETAIN_BUILD_ARTIFACT"); found { if keep, _ := strconv.ParseBool(v); keep { - t, _ := ioutil.TempFile("", "build_*_server") + t, _ := os.CreateTemp("", "build_*_server") defer t.Close() body = io.MultiWriter(t, w) } @@ -852,7 +854,7 @@ func parseLibPodIsolation(isolation string) (buildah.Isolation, error) { func extractTarFile(r *http.Request) (string, error) { // build a home for the request body - anchorDir, err := ioutil.TempDir("", "libpod_builder") + anchorDir, err := os.MkdirTemp("", "libpod_builder") if err != nil { return "", err } diff --git a/pkg/api/handlers/compat/images_push.go b/pkg/api/handlers/compat/images_push.go index a1173de0b..e1655a3bc 100644 --- a/pkg/api/handlers/compat/images_push.go +++ b/pkg/api/handlers/compat/images_push.go @@ -4,8 +4,9 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "net/http" + "os" "strings" "github.com/containers/image/v5/types" @@ -26,7 +27,7 @@ func PushImage(w http.ResponseWriter, r *http.Request) { decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) - digestFile, err := ioutil.TempFile("", "digest.txt") + digestFile, err := os.CreateTemp("", "digest.txt") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return @@ -186,7 +187,7 @@ loop: // break out of for/select infinite loop break loop } - digestBytes, err := ioutil.ReadAll(digestFile) + digestBytes, err := io.ReadAll(digestFile) if err != nil { report.Error = &jsonmessage.JSONError{ Message: err.Error(), diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go index 29d1398cf..078e75ed3 100644 --- a/pkg/api/handlers/compat/networks.go +++ b/pkg/api/handlers/compat/networks.go @@ -118,6 +118,11 @@ func convertLibpodNetworktoDockerNetwork(runtime *libpod.Runtime, network *netty if changeDefaultName && name == runtime.Network().DefaultNetworkName() { name = nettypes.BridgeNetworkDriver } + options := network.Options + // bridge always has isolate set in the compat API but we should not return it to not confuse callers + // https://github.com/containers/podman/issues/15580 + delete(options, nettypes.IsolateOption) + report := types.NetworkResource{ Name: name, ID: network.ID, @@ -126,7 +131,7 @@ func convertLibpodNetworktoDockerNetwork(runtime *libpod.Runtime, network *netty Internal: network.Internal, EnableIPv6: network.IPv6Enabled, Labels: network.Labels, - Options: network.Options, + Options: options, IPAM: ipam, Scope: "local", Attachable: false, diff --git a/pkg/api/handlers/compat/secrets.go b/pkg/api/handlers/compat/secrets.go index 13b3c4e24..847f05f27 100644 --- a/pkg/api/handlers/compat/secrets.go +++ b/pkg/api/handlers/compat/secrets.go @@ -111,14 +111,11 @@ func CreateSecret(w http.ResponseWriter, r *http.Request) { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("Decode(): %w", err)) return } - if len(createParams.Labels) > 0 { - utils.Error(w, http.StatusBadRequest, fmt.Errorf("labels not supported: %w", errors.New("bad parameter"))) - return - } decoded, _ := base64.StdEncoding.DecodeString(createParams.Data) reader := bytes.NewReader(decoded) opts.Driver = createParams.Driver.Name + opts.Labels = createParams.Labels ic := abi.ContainerEngine{Libpod: runtime} report, err := ic.SecretCreate(r.Context(), createParams.Name, reader, opts) diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go index a76e3d988..9d18c9420 100644 --- a/pkg/api/handlers/libpod/containers.go +++ b/pkg/api/handlers/libpod/containers.go @@ -4,7 +4,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "net/http" "os" "strings" @@ -248,7 +247,7 @@ func Checkpoint(w http.ResponseWriter, r *http.Request) { } if query.Export { - f, err := ioutil.TempFile("", "checkpoint") + f, err := os.CreateTemp("", "checkpoint") if err != nil { utils.InternalServerError(w, err) return @@ -306,6 +305,7 @@ func Restore(w http.ResponseWriter, r *http.Request) { PrintStats bool `schema:"printStats"` FileLocks bool `schema:"fileLocks"` PublishPorts string `schema:"publishPorts"` + Pod string `schema:"pod"` }{ // override any golang type defaults } @@ -325,11 +325,12 @@ func Restore(w http.ResponseWriter, r *http.Request) { PrintStats: query.PrintStats, FileLocks: query.FileLocks, PublishPorts: strings.Fields(query.PublishPorts), + Pod: query.Pod, } var names []string if query.Import { - t, err := ioutil.TempFile("", "restore") + t, err := os.CreateTemp("", "restore") if err != nil { utils.InternalServerError(w, err) return diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index 82c1971cd..412532954 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "os" "strconv" @@ -182,7 +181,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) { switch query.Format { case define.OCIArchive, define.V2s2Archive: - tmpfile, err := ioutil.TempFile("", "api.tar") + tmpfile, err := os.CreateTemp("", "api.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return @@ -193,7 +192,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) { return } case define.OCIManifestDir, define.V2s2ManifestDir: - tmpdir, err := ioutil.TempDir("", "save") + tmpdir, err := os.MkdirTemp("", "save") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempdir: %w", err)) return @@ -279,7 +278,7 @@ func ExportImages(w http.ResponseWriter, r *http.Request) { switch query.Format { case define.V2s2Archive, define.OCIArchive: - tmpfile, err := ioutil.TempFile("", "api.tar") + tmpfile, err := os.CreateTemp("", "api.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return @@ -290,7 +289,7 @@ func ExportImages(w http.ResponseWriter, r *http.Request) { return } case define.OCIManifestDir, define.V2s2ManifestDir: - tmpdir, err := ioutil.TempDir("", "save") + tmpdir, err := os.MkdirTemp("", "save") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tmpdir: %w", err)) return @@ -329,7 +328,7 @@ func ExportImages(w http.ResponseWriter, r *http.Request) { func ImagesLoad(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) - tmpfile, err := ioutil.TempFile("", "libpod-images-load.tar") + tmpfile, err := os.CreateTemp("", "libpod-images-load.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return @@ -378,7 +377,7 @@ func ImagesImport(w http.ResponseWriter, r *http.Request) { // Check if we need to load the image from a URL or from the request's body. source := query.URL if len(query.URL) == 0 { - tmpfile, err := ioutil.TempFile("", "libpod-images-import.tar") + tmpfile, err := os.CreateTemp("", "libpod-images-import.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go index d5af72a61..c96e4936b 100644 --- a/pkg/api/handlers/libpod/manifests.go +++ b/pkg/api/handlers/libpod/manifests.go @@ -5,7 +5,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "strconv" @@ -83,7 +83,7 @@ func ManifestCreate(w http.ResponseWriter, r *http.Request) { status = http.StatusCreated } - buffer, err := ioutil.ReadAll(r.Body) + buffer, err := io.ReadAll(r.Body) if err != nil { utils.InternalServerError(w, err) return diff --git a/pkg/api/handlers/libpod/secrets.go b/pkg/api/handlers/libpod/secrets.go index 6eba65f2b..c24ac8563 100644 --- a/pkg/api/handlers/libpod/secrets.go +++ b/pkg/api/handlers/libpod/secrets.go @@ -22,6 +22,7 @@ func CreateSecret(w http.ResponseWriter, r *http.Request) { Name string `schema:"name"` Driver string `schema:"driver"` DriverOpts map[string]string `schema:"driveropts"` + Labels map[string]string `schema:"labels"` }{ // override any golang type defaults } @@ -33,6 +34,7 @@ func CreateSecret(w http.ResponseWriter, r *http.Request) { opts.Driver = query.Driver opts.DriverOpts = query.DriverOpts + opts.Labels = query.Labels ic := abi.ContainerEngine{Libpod: runtime} report, err := ic.SecretCreate(r.Context(), query.Name, r.Body, opts) diff --git a/pkg/api/server/handler_logging.go b/pkg/api/server/handler_logging.go index 699fab7a5..38ee8321c 100644 --- a/pkg/api/server/handler_logging.go +++ b/pkg/api/server/handler_logging.go @@ -2,7 +2,6 @@ package server import ( "io" - "io/ioutil" "net/http" "time" @@ -41,7 +40,7 @@ func loggingHandler() mux.MiddlewareFunc { "API": "request", "X-Reference-Id": r.Header.Get("X-Reference-Id"), }) - r.Body = ioutil.NopCloser( + r.Body = io.NopCloser( io.TeeReader(r.Body, annotated.WriterLevel(logrus.TraceLevel))) w = responseWriter{ResponseWriter: w} diff --git a/pkg/api/server/handler_rid.go b/pkg/api/server/handler_rid.go index ee278071a..3e404cc31 100644 --- a/pkg/api/server/handler_rid.go +++ b/pkg/api/server/handler_rid.go @@ -2,7 +2,7 @@ package server import ( "fmt" - "io/ioutil" + "io" "net/http" "github.com/containers/podman/v4/pkg/api/types" @@ -17,7 +17,7 @@ import ( func referenceIDHandler() mux.MiddlewareFunc { return func(h http.Handler) http.Handler { // Only log Apache access_log-like entries at Info level or below - out := ioutil.Discard + out := io.Discard if logrus.IsLevelEnabled(logrus.InfoLevel) { out = logrus.StandardLogger().Out } diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go index 311eecd17..2cf5169ba 100644 --- a/pkg/api/server/register_containers.go +++ b/pkg/api/server/register_containers.go @@ -1516,6 +1516,10 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // name: printStats // type: boolean // description: add restore statistics to the returned RestoreReport + // - in: query + // name: pod + // type: string + // description: pod to restore into // produces: // - application/json // responses: diff --git a/pkg/api/server/register_secrets.go b/pkg/api/server/register_secrets.go index 8918ad238..a60145958 100644 --- a/pkg/api/server/register_secrets.go +++ b/pkg/api/server/register_secrets.go @@ -25,6 +25,14 @@ func (s *APIServer) registerSecretHandlers(r *mux.Router) error { // type: string // description: Secret driver // default: "file" + // - in: query + // name: driveropts + // type: string + // description: Secret driver options + // - in: query + // name: labels + // type: string + // description: Labels on the secret // - in: body // name: request // description: Secret diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go index 39423dabe..14446e6b5 100644 --- a/pkg/api/server/server.go +++ b/pkg/api/server/server.go @@ -69,7 +69,6 @@ func newServer(runtime *libpod.Runtime, listener net.Listener, opts entities.Ser logrus.Debugf("CORS Headers were set to %q", opts.CorsHeaders) } - logrus.Infof("API service listening on %q", listener.Addr()) router := mux.NewRouter().UseEncodedPath() tracker := idle.NewTracker(opts.Timeout) diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go index 270cd4207..52a632b33 100644 --- a/pkg/auth/auth.go +++ b/pkg/auth/auth.go @@ -4,7 +4,6 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io/ioutil" "net/http" "os" "strings" @@ -233,7 +232,7 @@ func encodeMultiAuthConfigs(authConfigs map[string]types.DockerAuthConfig) (stri // TMPDIR will be used. func authConfigsToAuthFile(authConfigs map[string]types.DockerAuthConfig) (string, error) { // Initialize an empty temporary JSON file. - tmpFile, err := ioutil.TempFile("", "auth.json.") + tmpFile, err := os.CreateTemp("", "auth.json.") if err != nil { return "", err } diff --git a/pkg/auth/auth_test.go b/pkg/auth/auth_test.go index f25cbf2cc..90a81ac9a 100644 --- a/pkg/auth/auth_test.go +++ b/pkg/auth/auth_test.go @@ -3,7 +3,6 @@ package auth import ( "encoding/base64" "encoding/json" - "io/ioutil" "net/http" "os" "testing" @@ -37,10 +36,10 @@ func systemContextForAuthFile(t *testing.T, fileContents string) (*types.SystemC return nil, func() {} } - f, err := ioutil.TempFile("", "auth.json") + f, err := os.CreateTemp("", "auth.json") require.NoError(t, err) path := f.Name() - err = ioutil.WriteFile(path, []byte(fileContents), 0700) + err = os.WriteFile(path, []byte(fileContents), 0700) require.NoError(t, err) return &types.SystemContext{AuthFilePath: path}, func() { os.Remove(path) } } @@ -347,7 +346,7 @@ func TestAuthConfigsToAuthFile(t *testing.T) { assert.Empty(t, filePath) } else { assert.NoError(t, err) - content, err := ioutil.ReadFile(filePath) + content, err := os.ReadFile(filePath) require.NoError(t, err) assert.Contains(t, string(content), tc.expectedContains) os.Remove(filePath) diff --git a/pkg/autoupdate/autoupdate.go b/pkg/autoupdate/autoupdate.go index 9cf77d135..a0ed8ccba 100644 --- a/pkg/autoupdate/autoupdate.go +++ b/pkg/autoupdate/autoupdate.go @@ -9,8 +9,6 @@ import ( "github.com/containers/common/libimage" "github.com/containers/common/pkg/config" "github.com/containers/image/v5/docker" - "github.com/containers/image/v5/docker/reference" - "github.com/containers/image/v5/transports/alltransports" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/events" @@ -21,14 +19,6 @@ import ( "github.com/sirupsen/logrus" ) -// Label denotes the container/pod label key to specify auto-update policies in -// container labels. -const Label = "io.containers.autoupdate" - -// Label denotes the container label key to specify authfile in -// container labels. -const AuthfileLabel = "io.containers.autoupdate.authfile" - // Policy represents an auto-update policy. type Policy string @@ -102,32 +92,7 @@ func LookupPolicy(s string) (Policy, error) { return "", fmt.Errorf("invalid auto-update policy %q: valid policies are %+q", s, keys) } -// ValidateImageReference checks if the specified imageName is a fully-qualified -// image reference to the docker transport (without digest). Such a reference -// includes a domain, name and tag (e.g., quay.io/podman/stable:latest). The -// reference may also be prefixed with "docker://" explicitly indicating that -// it's a reference to the docker transport. -func ValidateImageReference(imageName string) error { - // Make sure the input image is a docker. - imageRef, err := alltransports.ParseImageName(imageName) - if err == nil && imageRef.Transport().Name() != docker.Transport.Name() { - return fmt.Errorf("auto updates require the docker image transport but image is of transport %q", imageRef.Transport().Name()) - } else if err != nil { - repo, err := reference.Parse(imageName) - if err != nil { - return fmt.Errorf("enforcing fully-qualified docker transport reference for auto updates: %w", err) - } - if _, ok := repo.(reference.NamedTagged); !ok { - return fmt.Errorf("auto updates require fully-qualified image references (no tag): %q", imageName) - } - if _, ok := repo.(reference.Digested); ok { - return fmt.Errorf("auto updates require fully-qualified image references without digest: %q", imageName) - } - } - return nil -} - -// AutoUpdate looks up containers with a specified auto-update policy and acts +/// AutoUpdate looks up containers with a specified auto-update policy and acts // accordingly. // // If the policy is set to PolicyRegistryImage, it checks if the image @@ -418,7 +383,7 @@ func (u *updater) assembleTasks(ctx context.Context) []error { // Check the container's auto-update policy which is configured // as a label. labels := ctr.Labels() - value, exists := labels[Label] + value, exists := labels[define.AutoUpdateLabel] if !exists { continue } @@ -454,7 +419,7 @@ func (u *updater) assembleTasks(ctx context.Context) []error { } t := task{ - authfile: labels[AuthfileLabel], + authfile: labels[define.AutoUpdateAuthfileLabel], auto: u, container: ctr, policy: policy, diff --git a/pkg/autoupdate/autoupdate_test.go b/pkg/autoupdate/autoupdate_test.go deleted file mode 100644 index 7a5da5bb0..000000000 --- a/pkg/autoupdate/autoupdate_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package autoupdate - -import ( - "testing" -) - -func TestValidateImageReference(t *testing.T) { - tests := []struct { - input string - valid bool - }{ - { // Fully-qualified reference - input: "quay.io/foo/bar:tag", - valid: true, - }, - { // Fully-qualified reference in transport notation - input: "docker://quay.io/foo/bar:tag", - valid: true, - }, - { // Fully-qualified reference but with digest - input: "quay.io/foo/bar@sha256:c9b1b535fdd91a9855fb7f82348177e5f019329a58c53c47272962dd60f71fc9", - valid: false, - }, - { // Reference with missing tag - input: "quay.io/foo/bar", - valid: false, - }, - { // Short name - input: "alpine", - valid: false, - }, - { // Short name with repo - input: "library/alpine", - valid: false, - }, - { // Wrong transport - input: "docker-archive:/some/path.tar", - valid: false, - }, - } - - for _, test := range tests { - err := ValidateImageReference(test.input) - if test.valid && err != nil { - t.Fatalf("parsing %q should have succeeded: %v", test.input, err) - } else if !test.valid && err == nil { - t.Fatalf("parsing %q should have failed", test.input) - } - } -} diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go index 6d7b052b7..a3677d393 100644 --- a/pkg/bindings/connection.go +++ b/pkg/bindings/connection.go @@ -59,7 +59,7 @@ func JoinURL(elements ...string) string { // NewConnection creates a new service connection without an identity func NewConnection(ctx context.Context, uri string) (context.Context, error) { - return NewConnectionWithIdentity(ctx, uri, "") + return NewConnectionWithIdentity(ctx, uri, "", false) } // NewConnectionWithIdentity takes a URI as a string and returns a context with the @@ -70,7 +70,7 @@ func NewConnection(ctx context.Context, uri string) (context.Context, error) { // For example tcp://localhost:<port> // or unix:///run/podman/podman.sock // or ssh://<user>@<host>[:port]/run/podman/podman.sock?secure=True -func NewConnectionWithIdentity(ctx context.Context, uri string, identity string) (context.Context, error) { +func NewConnectionWithIdentity(ctx context.Context, uri string, identity string, machine bool) (context.Context, error) { var ( err error ) @@ -96,10 +96,11 @@ func NewConnectionWithIdentity(ctx context.Context, uri string, identity string) return nil, err } conn, err := ssh.Dial(&ssh.ConnectionDialOptions{ - Host: uri, - Identity: identity, - User: _url.User, - Port: port, + Host: uri, + Identity: identity, + User: _url.User, + Port: port, + InsecureIsMachineConnection: machine, }, "golang") if err != nil { return nil, err diff --git a/pkg/bindings/errors.go b/pkg/bindings/errors.go index 29f087c22..d9dfa95a6 100644 --- a/pkg/bindings/errors.go +++ b/pkg/bindings/errors.go @@ -4,7 +4,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "github.com/containers/podman/v4/pkg/errorhandling" ) @@ -29,7 +29,7 @@ func (h APIResponse) Process(unmarshalInto interface{}) error { // ProcessWithError drains the response body, and processes the HTTP status code // Note: Closing the response.Body is left to the caller func (h APIResponse) ProcessWithError(unmarshalInto interface{}, unmarshalErrorInto interface{}) error { - data, err := ioutil.ReadAll(h.Response.Body) + data, err := io.ReadAll(h.Response.Body) if err != nil { return fmt.Errorf("unable to process API response: %w", err) } diff --git a/pkg/bindings/generator/generator.go b/pkg/bindings/generator/generator.go index 06be52451..78244b502 100644 --- a/pkg/bindings/generator/generator.go +++ b/pkg/bindings/generator/generator.go @@ -12,7 +12,6 @@ import ( "go/ast" "go/parser" "go/token" - "io/ioutil" "os" "os/exec" "strings" @@ -72,7 +71,7 @@ func main() { ) srcFile := os.Getenv("GOFILE") inputStructName := os.Args[1] - b, err := ioutil.ReadFile(srcFile) + b, err := os.ReadFile(srcFile) if err != nil { panic(err) } diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go index ef875c9eb..f8552cddb 100644 --- a/pkg/bindings/images/build.go +++ b/pkg/bindings/images/build.go @@ -9,7 +9,6 @@ import ( "fmt" "io" "io/fs" - "io/ioutil" "net/http" "net/url" "os" @@ -234,6 +233,14 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO if options.CacheFrom != nil { params.Set("cachefrom", options.CacheFrom.String()) } + + switch options.SkipUnusedStages { + case types.OptionalBoolTrue: + params.Set("skipunusedstages", "1") + case types.OptionalBoolFalse: + params.Set("skipunusedstages", "0") + } + if options.CacheTo != nil { params.Set("cacheto", options.CacheTo.String()) } @@ -395,11 +402,11 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO dontexcludes := []string{"!Dockerfile", "!Containerfile", "!.dockerignore", "!.containerignore"} for _, c := range containerFiles { if c == "/dev/stdin" { - content, err := ioutil.ReadAll(os.Stdin) + content, err := io.ReadAll(os.Stdin) if err != nil { return nil, err } - tmpFile, err := ioutil.TempFile("", "build") + tmpFile, err := os.CreateTemp("", "build") if err != nil { return nil, err } @@ -465,7 +472,7 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO if arr[0] == "src" { // read specified secret into a tmp file // move tmp file to tar and change secret source to relative tmp file - tmpSecretFile, err := ioutil.TempFile(options.ContextDirectory, "podman-build-secret") + tmpSecretFile, err := os.CreateTemp(options.ContextDirectory, "podman-build-secret") if err != nil { return nil, err } @@ -531,7 +538,7 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO if logrus.IsLevelEnabled(logrus.DebugLevel) { if v, found := os.LookupEnv("PODMAN_RETAIN_BUILD_ARTIFACT"); found { if keep, _ := strconv.ParseBool(v); keep { - t, _ := ioutil.TempFile("", "build_*_client") + t, _ := os.CreateTemp("", "build_*_client") defer t.Close() body = io.TeeReader(response.Body, t) } @@ -737,10 +744,10 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) { } func parseDockerignore(root string) ([]string, error) { - ignore, err := ioutil.ReadFile(filepath.Join(root, ".containerignore")) + ignore, err := os.ReadFile(filepath.Join(root, ".containerignore")) if err != nil { var dockerIgnoreErr error - ignore, dockerIgnoreErr = ioutil.ReadFile(filepath.Join(root, ".dockerignore")) + ignore, dockerIgnoreErr = os.ReadFile(filepath.Join(root, ".dockerignore")) if dockerIgnoreErr != nil && !os.IsNotExist(dockerIgnoreErr) { return nil, err } diff --git a/pkg/bindings/manifests/manifests.go b/pkg/bindings/manifests/manifests.go index 752366937..d987e51d8 100644 --- a/pkg/bindings/manifests/manifests.go +++ b/pkg/bindings/manifests/manifests.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "os" "strconv" @@ -257,7 +256,7 @@ func Modify(ctx context.Context, name string, images []string, options *ModifyOp } defer response.Body.Close() - data, err := ioutil.ReadAll(response.Body) + data, err := io.ReadAll(response.Body) if err != nil { return "", fmt.Errorf("unable to process API response: %w", err) } diff --git a/pkg/bindings/secrets/types.go b/pkg/bindings/secrets/types.go index 01c3c248d..d2f449556 100644 --- a/pkg/bindings/secrets/types.go +++ b/pkg/bindings/secrets/types.go @@ -22,4 +22,5 @@ type CreateOptions struct { Name *string Driver *string DriverOpts map[string]string + Labels map[string]string } diff --git a/pkg/bindings/secrets/types_create_options.go b/pkg/bindings/secrets/types_create_options.go index 6b1666a42..c9c88e1f3 100644 --- a/pkg/bindings/secrets/types_create_options.go +++ b/pkg/bindings/secrets/types_create_options.go @@ -61,3 +61,18 @@ func (o *CreateOptions) GetDriverOpts() map[string]string { } return o.DriverOpts } + +// WithLabels set field Labels to given value +func (o *CreateOptions) WithLabels(value map[string]string) *CreateOptions { + o.Labels = value + return o +} + +// GetLabels returns value of field Labels +func (o *CreateOptions) GetLabels() map[string]string { + if o.Labels == nil { + var z map[string]string + return z + } + return o.Labels +} diff --git a/pkg/bindings/test/auth_test.go b/pkg/bindings/test/auth_test.go index c4c4b16d8..5b148a51c 100644 --- a/pkg/bindings/test/auth_test.go +++ b/pkg/bindings/test/auth_test.go @@ -1,7 +1,6 @@ package bindings_test import ( - "io/ioutil" "os" "time" @@ -76,7 +75,7 @@ var _ = Describe("Podman images", func() { imageRef := imageRep + ":" + imageTag // Create a temporary authentication file. - tmpFile, err := ioutil.TempFile("", "auth.json.") + tmpFile, err := os.CreateTemp("", "auth.json.") Expect(err).To(BeNil()) _, err = tmpFile.Write([]byte{'{', '}'}) Expect(err).To(BeNil()) diff --git a/pkg/bindings/test/common_test.go b/pkg/bindings/test/common_test.go index 6b0175f59..f174b84f8 100644 --- a/pkg/bindings/test/common_test.go +++ b/pkg/bindings/test/common_test.go @@ -3,7 +3,6 @@ package bindings_test import ( "context" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -146,7 +145,7 @@ func newBindingTest() *bindingTest { // createTempDirinTempDir create a temp dir with prefix podman_test func createTempDirInTempDir() (string, error) { - return ioutil.TempDir("", "libpod_api") + return os.MkdirTemp("", "libpod_api") } func (b *bindingTest) startAPIService() *gexec.Session { @@ -264,7 +263,7 @@ var _ = ginkgo.SynchronizedBeforeSuite(func() []byte { // If running localized tests, the cache dir is created and populated. if the // tests are remote, this is a no-op createCache() - path, err := ioutil.TempDir("", "libpodlock") + path, err := os.MkdirTemp("", "libpodlock") if err != nil { fmt.Println(err) os.Exit(1) diff --git a/pkg/checkpoint/checkpoint_restore.go b/pkg/checkpoint/checkpoint_restore.go index e7c843143..248b9cdbf 100644 --- a/pkg/checkpoint/checkpoint_restore.go +++ b/pkg/checkpoint/checkpoint_restore.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" metadata "github.com/checkpoint-restore/checkpointctl/lib" @@ -26,7 +25,7 @@ import ( func CRImportCheckpointTar(ctx context.Context, runtime *libpod.Runtime, restoreOptions entities.RestoreOptions) ([]*libpod.Container, error) { // First get the container definition from the // tarball to a temporary directory - dir, err := ioutil.TempDir("", "checkpoint") + dir, err := os.MkdirTemp("", "checkpoint") if err != nil { return nil, err } diff --git a/pkg/checkpoint/crutils/checkpoint_restore_utils.go b/pkg/checkpoint/crutils/checkpoint_restore_utils.go index 132632322..b9db9562a 100644 --- a/pkg/checkpoint/crutils/checkpoint_restore_utils.go +++ b/pkg/checkpoint/crutils/checkpoint_restore_utils.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -237,7 +236,7 @@ func CRRuntimeSupportsPodCheckpointRestore(runtimePath string) bool { // given checkpoint archive and returns the runtime used to create // the given checkpoint archive. func CRGetRuntimeFromArchive(input string) (*string, error) { - dir, err := ioutil.TempDir("", "checkpoint") + dir, err := os.MkdirTemp("", "checkpoint") if err != nil { return nil, err } diff --git a/pkg/ctime/ctime_test.go b/pkg/ctime/ctime_test.go index abfc627da..014f15aa9 100644 --- a/pkg/ctime/ctime_test.go +++ b/pkg/ctime/ctime_test.go @@ -1,7 +1,6 @@ package ctime import ( - "io/ioutil" "os" "testing" "time" @@ -10,13 +9,13 @@ import ( func TestCreated(t *testing.T) { before := time.Now() - fileA, err := ioutil.TempFile("", "ctime-test-") + fileA, err := os.CreateTemp("", "ctime-test-") if err != nil { t.Error(err) } defer os.Remove(fileA.Name()) - fileB, err := ioutil.TempFile("", "ctime-test-") + fileB, err := os.CreateTemp("", "ctime-test-") if err != nil { t.Error(err) } diff --git a/pkg/domain/entities/engine.go b/pkg/domain/entities/engine.go index a69cf5111..d0d439a1b 100644 --- a/pkg/domain/entities/engine.go +++ b/pkg/domain/entities/engine.go @@ -54,4 +54,5 @@ type PodmanConfig struct { StorageDriver string StorageOpts []string SSHMode string + MachineMode bool } diff --git a/pkg/domain/entities/events.go b/pkg/domain/entities/events.go index de218b285..34a6fe048 100644 --- a/pkg/domain/entities/events.go +++ b/pkg/domain/entities/events.go @@ -14,7 +14,7 @@ type Event struct { // TODO: it would be nice to have full control over the types at some // point and fork such Docker types. dockerEvents.Message - HealthStatus string + HealthStatus string `json:",omitempty"` } // ConvertToLibpodEvent converts an entities event to a libpod one. @@ -34,6 +34,7 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event { image := e.Actor.Attributes["image"] name := e.Actor.Attributes["name"] details := e.Actor.Attributes + podID := e.Actor.Attributes["podId"] delete(details, "image") delete(details, "name") delete(details, "containerExitCode") @@ -47,6 +48,7 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event { Type: t, HealthStatus: e.HealthStatus, Details: libpodEvents.Details{ + PodID: podID, Attributes: details, }, } @@ -61,6 +63,7 @@ func ConvertToEntitiesEvent(e libpodEvents.Event) *Event { attributes["image"] = e.Image attributes["name"] = e.Name attributes["containerExitCode"] = strconv.Itoa(e.ContainerExitCode) + attributes["podId"] = e.PodID message := dockerEvents.Message{ // Compatibility with clients that still look for deprecated API elements Status: e.Status.String(), diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index cad11b0ab..b1eb3b005 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -335,7 +335,8 @@ type ImageSaveOptions struct { // Output - write image to the specified path. Output string // Quiet - suppress output when copying images - Quiet bool + Quiet bool + SignaturePolicy string } // ImageScpOptions provide options for securely copying images to and from a remote host diff --git a/pkg/domain/entities/secrets.go b/pkg/domain/entities/secrets.go index d8af937a7..5686b90e9 100644 --- a/pkg/domain/entities/secrets.go +++ b/pkg/domain/entities/secrets.go @@ -13,6 +13,7 @@ type SecretCreateReport struct { type SecretCreateOptions struct { Driver string DriverOpts map[string]string + Labels map[string]string } type SecretListRequest struct { @@ -55,6 +56,7 @@ type SecretVersion struct { type SecretSpec struct { Name string Driver SecretDriverSpec + Labels map[string]string } type SecretDriverSpec struct { @@ -70,6 +72,8 @@ type SecretCreateRequest struct { Data string // Driver represents a driver (default "file") Driver SecretDriverSpec + // Labels are labels on the secret + Labels map[string]string } // Secret create response diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 6934de60e..16b75829f 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io/fs" - "io/ioutil" "net/url" "os" "os/exec" @@ -340,7 +339,7 @@ func (ir *ImageEngine) Push(ctx context.Context, source string, destination stri return err } - if err := ioutil.WriteFile(options.DigestFile, []byte(manifestDigest.String()), 0644); err != nil { + if err := os.WriteFile(options.DigestFile, []byte(manifestDigest.String()), 0644); err != nil { return err } } @@ -406,6 +405,7 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string, saveOptions := &libimage.SaveOptions{} saveOptions.DirForceCompress = options.Compress saveOptions.OciAcceptUncompressedLayers = options.OciAcceptUncompressedLayers + saveOptions.SignaturePolicyPath = options.SignaturePolicy // Force signature removal to preserve backwards compat. // See https://github.com/containers/podman/pull/11669#issuecomment-925250264 @@ -910,5 +910,5 @@ func putSignature(manifestBlob []byte, mech signature.SigningMechanism, sigStore if err != nil { return err } - return ioutil.WriteFile(filepath.Join(signatureDir, sigFilename), newSig, 0644) + return os.WriteFile(filepath.Join(signatureDir, sigFilename), newSig, 0644) } diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index d447b4d00..8779acfda 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -6,11 +6,11 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strconv" "strings" + "sync" buildahDefine "github.com/containers/buildah/define" "github.com/containers/common/libimage" @@ -20,7 +20,6 @@ import ( "github.com/containers/image/v5/types" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod/define" - "github.com/containers/podman/v4/pkg/autoupdate" "github.com/containers/podman/v4/pkg/domain/entities" v1apps "github.com/containers/podman/v4/pkg/k8s.io/api/apps/v1" v1 "github.com/containers/podman/v4/pkg/k8s.io/api/core/v1" @@ -116,7 +115,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options validKinds := 0 // read yaml document - content, err := ioutil.ReadAll(body) + content, err := io.ReadAll(body) if err != nil { return nil, err } @@ -345,10 +344,6 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY return nil, err } - if (ns.IsBridge() && len(networks) == 0) || ns.IsHost() { - return nil, fmt.Errorf("invalid value passed to --network: bridge or host networking must be configured in YAML") - } - podOpt.Net.Network = ns podOpt.Net.Networks = networks podOpt.Net.NetworkOptions = netOpts @@ -699,9 +694,24 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY fmt.Println(playKubePod.ContainerErrors) } - // Wait for each proxy to receive a READY message. - for _, proxy := range sdNotifyProxies { - if err := proxy.WaitAndClose(); err != nil { + // Wait for each proxy to receive a READY message. Use a wait + // group to prevent the potential for ABBA kinds of deadlocks. + var wg sync.WaitGroup + errors := make([]error, len(sdNotifyProxies)) + for i := range sdNotifyProxies { + wg.Add(1) + go func(i int) { + err := sdNotifyProxies[i].WaitAndClose() + if err != nil { + err = fmt.Errorf("waiting for sd-notify proxy: %w", err) + } + errors[i] = err + wg.Done() + }(i) + } + wg.Wait() + for _, err := range errors { + if err != nil { return nil, err } } @@ -801,8 +811,8 @@ func (ic *ContainerEngine) getImageAndLabelInfo(ctx context.Context, cwd string, } } - setLabel(autoupdate.Label) - setLabel(autoupdate.AuthfileLabel) + setLabel(define.AutoUpdateLabel) + setLabel(define.AutoUpdateAuthfileLabel) return pulledImage, labels, nil } @@ -873,7 +883,7 @@ func (ic *ContainerEngine) playKubePVC(ctx context.Context, pvcYAML *v1.Persiste func readConfigMapFromFile(r io.Reader) (v1.ConfigMap, error) { var cm v1.ConfigMap - content, err := ioutil.ReadAll(r) + content, err := io.ReadAll(r) if err != nil { return cm, fmt.Errorf("unable to read ConfigMap YAML content: %w", err) } @@ -1005,7 +1015,7 @@ func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, body io.Reader, _ e reports := new(entities.PlayKubeReport) // read yaml document - content, err := ioutil.ReadAll(body) + content, err := io.ReadAll(body) if err != nil { return nil, err } diff --git a/pkg/domain/infra/abi/secrets.go b/pkg/domain/infra/abi/secrets.go index 47159d65a..929858c5c 100644 --- a/pkg/domain/infra/abi/secrets.go +++ b/pkg/domain/infra/abi/secrets.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "path/filepath" "strings" @@ -14,7 +13,7 @@ import ( ) func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader io.Reader, options entities.SecretCreateOptions) (*entities.SecretCreateReport, error) { - data, _ := ioutil.ReadAll(reader) + data, _ := io.ReadAll(reader) secretsPath := ic.Libpod.GetSecretsStorageDir() manager, err := ic.Libpod.SecretsManager() if err != nil { @@ -45,6 +44,7 @@ func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader storeOpts := secrets.StoreOptions{ DriverOpts: options.DriverOpts, + Labels: options.Labels, } secretID, err := manager.Store(name, data, options.Driver, storeOpts) @@ -74,6 +74,9 @@ func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string return nil, nil, fmt.Errorf("inspecting secret %s: %w", nameOrID, err) } } + if secret.Labels == nil { + secret.Labels = make(map[string]string) + } report := &entities.SecretInfoReport{ ID: secret.ID, CreatedAt: secret.CreatedAt, @@ -84,6 +87,7 @@ func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string Name: secret.Driver, Options: secret.DriverOptions, }, + Labels: secret.Labels, }, } reports = append(reports, report) diff --git a/pkg/domain/infra/abi/terminal/sigproxy_commn.go b/pkg/domain/infra/abi/terminal/sigproxy_commn.go index 3a0132ef3..d42685508 100644 --- a/pkg/domain/infra/abi/terminal/sigproxy_commn.go +++ b/pkg/domain/infra/abi/terminal/sigproxy_commn.go @@ -15,33 +15,25 @@ import ( "github.com/sirupsen/logrus" ) -// Make sure the signal buffer is sufficiently big. -// runc is using the same value. -const signalBufferSize = 2048 - // ProxySignals ... func ProxySignals(ctr *libpod.Container) { // Stop catching the shutdown signals (SIGINT, SIGTERM) - they're going // to the container now. shutdown.Stop() //nolint: errcheck - sigBuffer := make(chan os.Signal, signalBufferSize) + sigBuffer := make(chan os.Signal, signal.SignalBufferSize) signal.CatchAll(sigBuffer) logrus.Debugf("Enabling signal proxying") go func() { for s := range sigBuffer { - // Ignore SIGCHLD and SIGPIPE - these are mostly likely - // intended for the podman command itself. - // SIGURG was added because of golang 1.14 and its preemptive changes - // causing more signals to "show up". - // https://github.com/containers/podman/issues/5483 - if s == syscall.SIGCHLD || s == syscall.SIGPIPE || s == syscall.SIGURG { + syscallSignal := s.(syscall.Signal) + if signal.IsSignalIgnoredBySigProxy(syscallSignal) { continue } - if err := ctr.Kill(uint(s.(syscall.Signal))); err != nil { + if err := ctr.Kill(uint(syscallSignal)); err != nil { if errors.Is(err, define.ErrCtrStateInvalid) { logrus.Infof("Ceasing signal forwarding to container %s as it has stopped", ctr.ID()) } else { diff --git a/pkg/domain/infra/abi/trust.go b/pkg/domain/infra/abi/trust.go index c58ddff06..9b30920d7 100644 --- a/pkg/domain/infra/abi/trust.go +++ b/pkg/domain/infra/abi/trust.go @@ -3,7 +3,7 @@ package abi import ( "context" "fmt" - "io/ioutil" + "os" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/trust" @@ -18,7 +18,7 @@ func (ir *ImageEngine) ShowTrust(ctx context.Context, args []string, options ent if len(options.PolicyPath) > 0 { policyPath = options.PolicyPath } - report.Raw, err = ioutil.ReadFile(policyPath) + report.Raw, err = os.ReadFile(policyPath) if err != nil { return nil, err } diff --git a/pkg/domain/infra/runtime_abi.go b/pkg/domain/infra/runtime_abi.go index 7b5198d2f..94565c59e 100644 --- a/pkg/domain/infra/runtime_abi.go +++ b/pkg/domain/infra/runtime_abi.go @@ -21,7 +21,7 @@ func NewContainerEngine(facts *entities.PodmanConfig) (entities.ContainerEngine, r, err := NewLibpodRuntime(facts.FlagSet, facts) return r, err case entities.TunnelMode: - ctx, err := bindings.NewConnectionWithIdentity(context.Background(), facts.URI, facts.Identity) + ctx, err := bindings.NewConnectionWithIdentity(context.Background(), facts.URI, facts.Identity, facts.MachineMode) return &tunnel.ContainerEngine{ClientCtx: ctx}, err } return nil, fmt.Errorf("runtime mode '%v' is not supported", facts.EngineMode) @@ -35,7 +35,7 @@ func NewImageEngine(facts *entities.PodmanConfig) (entities.ImageEngine, error) return r, err case entities.TunnelMode: // TODO: look at me! - ctx, err := bindings.NewConnectionWithIdentity(context.Background(), facts.URI, facts.Identity) + ctx, err := bindings.NewConnectionWithIdentity(context.Background(), facts.URI, facts.Identity, facts.MachineMode) return &tunnel.ImageEngine{ClientCtx: ctx}, err } return nil, fmt.Errorf("runtime mode '%v' is not supported", facts.EngineMode) diff --git a/pkg/domain/infra/runtime_tunnel.go b/pkg/domain/infra/runtime_tunnel.go index 8a4de032f..48e6a6773 100644 --- a/pkg/domain/infra/runtime_tunnel.go +++ b/pkg/domain/infra/runtime_tunnel.go @@ -18,12 +18,12 @@ var ( connection *context.Context ) -func newConnection(uri string, identity string) (context.Context, error) { +func newConnection(uri string, identity string, machine bool) (context.Context, error) { connectionMutex.Lock() defer connectionMutex.Unlock() if connection == nil { - ctx, err := bindings.NewConnectionWithIdentity(context.Background(), uri, identity) + ctx, err := bindings.NewConnectionWithIdentity(context.Background(), uri, identity, machine) if err != nil { return ctx, err } @@ -37,7 +37,7 @@ func NewContainerEngine(facts *entities.PodmanConfig) (entities.ContainerEngine, case entities.ABIMode: return nil, fmt.Errorf("direct runtime not supported") case entities.TunnelMode: - ctx, err := newConnection(facts.URI, facts.Identity) + ctx, err := newConnection(facts.URI, facts.Identity, facts.MachineMode) return &tunnel.ContainerEngine{ClientCtx: ctx}, err } return nil, fmt.Errorf("runtime mode '%v' is not supported", facts.EngineMode) @@ -49,7 +49,7 @@ func NewImageEngine(facts *entities.PodmanConfig) (entities.ImageEngine, error) case entities.ABIMode: return nil, fmt.Errorf("direct image runtime not supported") case entities.TunnelMode: - ctx, err := newConnection(facts.URI, facts.Identity) + ctx, err := newConnection(facts.URI, facts.Identity, facts.MachineMode) return &tunnel.ImageEngine{ClientCtx: ctx}, err } return nil, fmt.Errorf("runtime mode '%v' is not supported", facts.EngineMode) diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 0dc73081d..0b573686f 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -620,6 +620,9 @@ func (ic *ContainerEngine) ContainerExecDetached(ctx context.Context, nameOrID s } func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input, output, errput *os.File) error { + if output == nil && errput == nil { + fmt.Printf("%s\n", name) + } attachErr := make(chan error) attachReady := make(chan bool) options := new(containers.AttachOptions).WithStream(true) @@ -825,6 +828,13 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta } // Attach + if opts.SigProxy { + remoteProxySignals(con.ID, func(signal string) error { + killOpts := entities.KillOptions{All: false, Latest: false, Signal: signal} + _, err := ic.ContainerKill(ctx, []string{con.ID}, killOpts) + return err + }) + } if err := startAndAttach(ic, con.ID, &opts.DetachKeys, opts.InputStream, opts.OutputStream, opts.ErrorStream); err != nil { if err == define.ErrDetach { return &report, nil diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index cc99b1b3a..9ae1ff959 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" "strconv" "strings" @@ -264,7 +263,7 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string, switch opts.Format { case "oci-dir", "docker-dir": - f, err = ioutil.TempFile("", "podman_save") + f, err = os.CreateTemp("", "podman_save") if err == nil { defer func() { _ = os.Remove(f.Name()) }() } diff --git a/pkg/domain/infra/tunnel/runtime.go b/pkg/domain/infra/tunnel/runtime.go index 6542ea5b7..75bd4ef5e 100644 --- a/pkg/domain/infra/tunnel/runtime.go +++ b/pkg/domain/infra/tunnel/runtime.go @@ -2,6 +2,12 @@ package tunnel import ( "context" + "os" + "syscall" + + "github.com/containers/podman/v4/libpod/define" + "github.com/containers/podman/v4/pkg/signal" + "github.com/sirupsen/logrus" ) // Image-related runtime using an ssh-tunnel to utilize Podman service @@ -18,3 +24,28 @@ type ContainerEngine struct { type SystemEngine struct { ClientCtx context.Context } + +func remoteProxySignals(ctrID string, killFunc func(string) error) { + sigBuffer := make(chan os.Signal, signal.SignalBufferSize) + signal.CatchAll(sigBuffer) + + logrus.Debugf("Enabling signal proxying") + + go func() { + for s := range sigBuffer { + syscallSignal := s.(syscall.Signal) + if signal.IsSignalIgnoredBySigProxy(syscallSignal) { + continue + } + signalName, err := signal.ParseSysSignalToName(syscallSignal) + if err != nil { + logrus.Infof("Ceasing signal %v forwarding to container %s as it has stopped: %s", s, ctrID, err) + } + if err := killFunc(signalName); err != nil { + if err.Error() == define.ErrCtrStateInvalid.Error() { + logrus.Debugf("Ceasing signal %q forwarding to container %s as it has stopped", signalName, ctrID) + } + } + } + }() +} diff --git a/pkg/domain/infra/tunnel/secrets.go b/pkg/domain/infra/tunnel/secrets.go index d26718b12..aa48cb764 100644 --- a/pkg/domain/infra/tunnel/secrets.go +++ b/pkg/domain/infra/tunnel/secrets.go @@ -14,7 +14,8 @@ func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader opts := new(secrets.CreateOptions). WithDriver(options.Driver). WithDriverOpts(options.DriverOpts). - WithName(name) + WithName(name). + WithLabels(options.Labels) created, err := secrets.Create(ic.ClientCtx, reader, opts) if err != nil { return nil, err diff --git a/pkg/domain/utils/scp.go b/pkg/domain/utils/scp.go index 44a0d94d7..19567551e 100644 --- a/pkg/domain/utils/scp.go +++ b/pkg/domain/utils/scp.go @@ -2,7 +2,6 @@ package utils import ( "fmt" - "io/ioutil" "net/url" "os" "os/exec" @@ -29,7 +28,7 @@ func ExecuteTransfer(src, dst string, parentFlags []string, quiet bool, sshMode return nil, nil, nil, nil, err } - f, err := ioutil.TempFile("", "podman") // open temp file for load/save output + f, err := os.CreateTemp("", "podman") // open temp file for load/save output if err != nil { return nil, nil, nil, nil, err } diff --git a/pkg/k8s.io/api/core/v1/types.go b/pkg/k8s.io/api/core/v1/types.go index 6f20cd351..4447847e3 100644 --- a/pkg/k8s.io/api/core/v1/types.go +++ b/pkg/k8s.io/api/core/v1/types.go @@ -939,15 +939,15 @@ type HTTPHeader struct { // HTTPGetAction describes an action based on HTTP Get requests. type HTTPGetAction struct { - // Path to access on the HTTP server. + // Path to access on the HTTP server. Defaults to /. // +optional Path string `json:"path,omitempty"` // Name or number of the port to access on the container. // Number must be in the range 1 to 65535. // Name must be an IANA_SVC_NAME. Port intstr.IntOrString `json:"port"` - // Host name to connect to, defaults to the pod IP. You probably want to set - // "Host" in httpHeaders instead. + // Host name to connect to. You probably want to set "Host" in httpHeaders instead. + // Defaults to the pod IP in Kubernetes, in case of Podman to localhost. // +optional Host string `json:"host,omitempty"` // Scheme to use for connecting to the host. @@ -964,9 +964,9 @@ type URIScheme string const ( // URISchemeHTTP means that the scheme used will be http:// - URISchemeHTTP URIScheme = "HTTP" + URISchemeHTTP URIScheme = "http" // URISchemeHTTPS means that the scheme used will be https:// - URISchemeHTTPS URIScheme = "HTTPS" + URISchemeHTTPS URIScheme = "https" ) // TCPSocketAction describes an action based on opening a socket diff --git a/pkg/machine/config.go b/pkg/machine/config.go index 54aa9e1b7..8c22ae6a3 100644 --- a/pkg/machine/config.go +++ b/pkg/machine/config.go @@ -5,7 +5,6 @@ package machine import ( "errors" - "io/ioutil" "net" "net/url" "os" @@ -283,7 +282,7 @@ func (m *VMFile) Delete() error { // Read the contents of a given file and return in []bytes func (m *VMFile) Read() ([]byte, error) { - return ioutil.ReadFile(m.GetPath()) + return os.ReadFile(m.GetPath()) } // NewMachineFile is a constructor for VMFile diff --git a/pkg/machine/connection.go b/pkg/machine/connection.go index 6ff761a92..93c638cc7 100644 --- a/pkg/machine/connection.go +++ b/pkg/machine/connection.go @@ -25,7 +25,8 @@ func AddConnection(uri fmt.Stringer, name, identity string, isDefault bool) erro cfg.Engine.ActiveService = name } dst := config.Destination{ - URI: uri.String(), + URI: uri.String(), + IsMachine: true, } dst.Identity = identity if cfg.Engine.ServiceDestinations == nil { diff --git a/pkg/machine/e2e/basic_test.go b/pkg/machine/e2e/basic_test.go index fa1728770..b7a11c7d9 100644 --- a/pkg/machine/e2e/basic_test.go +++ b/pkg/machine/e2e/basic_test.go @@ -1,8 +1,6 @@ package e2e_test import ( - "os" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gexec" @@ -24,10 +22,6 @@ var _ = Describe("run basic podman commands", func() { It("Basic ops", func() { // golangci-lint has trouble with actually skipping tests marked Skip // so skip it on cirrus envs and where CIRRUS_CI isn't set. - if os.Getenv("CIRRUS_CI") != "false" { - Skip("FIXME: #15347 - ssh know hosts broken - fails on PR runs and on x86_64") - } - name := randomString() i := new(initMachine) session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath).withNow()).run() diff --git a/pkg/machine/e2e/init_test.go b/pkg/machine/e2e/init_test.go index c298d3b14..ebf59dcd7 100644 --- a/pkg/machine/e2e/init_test.go +++ b/pkg/machine/e2e/init_test.go @@ -1,7 +1,6 @@ package e2e_test import ( - "io/ioutil" "os" "strconv" "time" @@ -138,9 +137,9 @@ var _ = Describe("podman machine init", func() { }) It("machine init with volume", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) - _, err = ioutil.TempFile(tmpDir, "example") + _, err = os.CreateTemp(tmpDir, "example") Expect(err).To(BeNil()) mount := tmpDir + ":/testmountdir" defer os.RemoveAll(tmpDir) diff --git a/pkg/machine/e2e/machine_test.go b/pkg/machine/e2e/machine_test.go index 5de04b9f7..5cd89c7ab 100644 --- a/pkg/machine/e2e/machine_test.go +++ b/pkg/machine/e2e/machine_test.go @@ -3,7 +3,6 @@ package e2e_test import ( "fmt" "io" - "io/ioutil" url2 "net/url" "os" "path" @@ -77,7 +76,7 @@ var _ = SynchronizedAfterSuite(func() {}, func setup() (string, *machineTestBuilder) { // Set TMPDIR if this needs a new directory - homeDir, err := ioutil.TempDir("", "podman_test") + homeDir, err := os.MkdirTemp("", "podman_test") if err != nil { Fail(fmt.Sprintf("failed to create home directory: %q", err)) } diff --git a/pkg/machine/fcos.go b/pkg/machine/fcos.go index 246f92a19..311891c26 100644 --- a/pkg/machine/fcos.go +++ b/pkg/machine/fcos.go @@ -6,7 +6,7 @@ package machine import ( "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" url2 "net/url" "os" @@ -175,7 +175,7 @@ func GetFCOSDownload(imageStream string) (*FcosDownloadInfo, error) { if err != nil { return nil, err } - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go index 366d10499..39ddce14c 100644 --- a/pkg/machine/ignition.go +++ b/pkg/machine/ignition.go @@ -7,7 +7,6 @@ import ( "encoding/json" "fmt" "io/fs" - "io/ioutil" "net/url" "os" "path/filepath" @@ -227,7 +226,7 @@ WantedBy=sysinit.target if err != nil { return err } - return ioutil.WriteFile(ign.WritePath, b, 0644) + return os.WriteFile(ign.WritePath, b, 0644) } func getDirs(usrName string) []Directory { @@ -559,7 +558,7 @@ func getCerts(certsDir string, isDir bool) []File { } func prepareCertFile(path string, name string) (File, error) { - b, err := ioutil.ReadFile(path) + b, err := os.ReadFile(path) if err != nil { logrus.Warnf("Unable to read cert file %v", err) return File{}, err diff --git a/pkg/machine/keys.go b/pkg/machine/keys.go index 94cbdac04..fce405695 100644 --- a/pkg/machine/keys.go +++ b/pkg/machine/keys.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -27,7 +26,7 @@ func CreateSSHKeys(writeLocation string) (string, error) { if err := generatekeys(writeLocation); err != nil { return "", err } - b, err := ioutil.ReadFile(writeLocation + ".pub") + b, err := os.ReadFile(writeLocation + ".pub") if err != nil { return "", err } @@ -45,7 +44,7 @@ func CreateSSHKeysPrefix(dir string, file string, passThru bool, skipExisting bo } else { fmt.Println("Keys already exist, reusing") } - b, err := ioutil.ReadFile(filepath.Join(dir, file) + ".pub") + b, err := os.ReadFile(filepath.Join(dir, file) + ".pub") if err != nil { return "", err } diff --git a/pkg/machine/pull.go b/pkg/machine/pull.go index 22a1b4c0a..9cba78237 100644 --- a/pkg/machine/pull.go +++ b/pkg/machine/pull.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" url2 "net/url" "os" @@ -191,7 +190,7 @@ func Decompress(localPath, uncompressedPath string) error { if err != nil { return err } - sourceFile, err := ioutil.ReadFile(localPath) + sourceFile, err := os.ReadFile(localPath) if err != nil { return err } diff --git a/pkg/machine/qemu/claim_darwin.go b/pkg/machine/qemu/claim_darwin.go index 66aed9ad8..c51d17bc9 100644 --- a/pkg/machine/qemu/claim_darwin.go +++ b/pkg/machine/qemu/claim_darwin.go @@ -2,7 +2,7 @@ package qemu import ( "fmt" - "io/ioutil" + "io" "net" "os" "os/user" @@ -43,7 +43,7 @@ func claimDockerSock() bool { return false } _ = con.SetReadDeadline(time.Now().Add(time.Second * 5)) - read, err := ioutil.ReadAll(con) + read, err := io.ReadAll(con) return err == nil && string(read) == "OK" } diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index 738cd74be..a6907c0df 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -12,7 +12,6 @@ import ( "errors" "fmt" "io/fs" - "io/ioutil" "net" "net/http" "net/url" @@ -391,11 +390,11 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) { // If the user provides an ignition file, we need to // copy it into the conf dir if len(opts.IgnitionPath) > 0 { - inputIgnition, err := ioutil.ReadFile(opts.IgnitionPath) + inputIgnition, err := os.ReadFile(opts.IgnitionPath) if err != nil { return false, err } - return false, ioutil.WriteFile(v.getIgnitionFile(), inputIgnition, 0644) + return false, os.WriteFile(v.getIgnitionFile(), inputIgnition, 0644) } // Write the ignition file ign := machine.DynamicIgnition{ @@ -406,6 +405,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) { WritePath: v.getIgnitionFile(), UID: v.UID, } + err = machine.NewIgnitionFile(ign) return err == nil, err } @@ -1034,7 +1034,7 @@ func (v *MachineVM) SSH(_ string, opts machine.SSHOptions) error { sshDestination := username + "@localhost" port := strconv.Itoa(v.Port) - args := []string{"-i", v.IdentityPath, "-p", port, sshDestination, "-o", "UserKnownHostsFile=/dev/null", + args := []string{"-i", v.IdentityPath, "-p", port, sshDestination, "-o", "StrictHostKeyChecking=no", "-o", "LogLevel=ERROR", "-o", "SetEnv=LC_ALL="} if len(opts.Args) > 0 { args = append(args, opts.Args...) @@ -1109,7 +1109,7 @@ func getVMInfos() ([]*machine.ListResponse, error) { vm := new(MachineVM) if strings.HasSuffix(d.Name(), ".json") { fullPath := filepath.Join(vmConfigDir, d.Name()) - b, err := ioutil.ReadFile(fullPath) + b, err := os.ReadFile(fullPath) if err != nil { return err } @@ -1539,7 +1539,7 @@ func (v *MachineVM) writeConfig() error { if err != nil { return err } - if err := ioutil.WriteFile(v.ConfigPath.GetPath(), b, 0644); err != nil { + if err := os.WriteFile(v.ConfigPath.GetPath(), b, 0644); err != nil { return err } return nil diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go index 44b82b823..81980736d 100644 --- a/pkg/machine/wsl/machine.go +++ b/pkg/machine/wsl/machine.go @@ -10,7 +10,6 @@ import ( "fmt" "io" "io/fs" - "io/ioutil" "net/url" "os" "os/exec" @@ -423,7 +422,7 @@ func (v *MachineVM) writeConfig() error { if err != nil { return err } - if err := ioutil.WriteFile(jsonFile, b, 0644); err != nil { + if err := os.WriteFile(jsonFile, b, 0644); err != nil { return fmt.Errorf("could not write machine json config: %w", err) } @@ -1285,7 +1284,7 @@ func readWinProxyTid(v *MachineVM) (uint32, uint32, string, error) { } tidFile := filepath.Join(stateDir, winSshProxyTid) - contents, err := ioutil.ReadFile(tidFile) + contents, err := os.ReadFile(tidFile) if err != nil { return 0, 0, "", err } diff --git a/pkg/machine/wsl/util_windows.go b/pkg/machine/wsl/util_windows.go index 67d1bfc5c..5f8da10ec 100644 --- a/pkg/machine/wsl/util_windows.go +++ b/pkg/machine/wsl/util_windows.go @@ -4,7 +4,6 @@ import ( "encoding/base64" "errors" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -209,7 +208,7 @@ func reboot() error { return fmt.Errorf("could not create data directory: %w", err) } commFile := filepath.Join(dataDir, "podman-relaunch.dat") - if err := ioutil.WriteFile(commFile, []byte(encoded), 0600); err != nil { + if err := os.WriteFile(commFile, []byte(encoded), 0600); err != nil { return fmt.Errorf("could not serialize command state: %w", err) } diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c index 3588313c6..fb22ed221 100644 --- a/pkg/rootless/rootless_linux.c +++ b/pkg/rootless/rootless_linux.c @@ -235,6 +235,7 @@ can_use_shortcut () if (strcmp (argv[argc], "mount") == 0 || strcmp (argv[argc], "machine") == 0 + || strcmp (argv[argc], "context") == 0 || strcmp (argv[argc], "search") == 0 || (strcmp (argv[argc], "system") == 0 && argv[argc+1] && strcmp (argv[argc+1], "service") != 0)) { diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index f3453320f..7de50eaf1 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" gosignal "os/signal" @@ -224,7 +223,7 @@ func GetConfiguredMappings() ([]idtools.IDMap, []idtools.IDMap, error) { } func copyMappings(from, to string) error { - content, err := ioutil.ReadFile(from) + content, err := os.ReadFile(from) if err != nil { return err } @@ -235,7 +234,7 @@ func copyMappings(from, to string) error { if bytes.Contains(content, []byte("4294967295")) { content = []byte("0 0 1\n1 1 4294967294\n") } - return ioutil.WriteFile(to, content, 0600) + return os.WriteFile(to, content, 0600) } func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ bool, _ int, retErr error) { @@ -343,13 +342,13 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo if !uidsMapped { logrus.Warnf("Using rootless single mapping into the namespace. This might break some images. Check /etc/subuid and /etc/subgid for adding sub*ids if not using a network user") setgroups := fmt.Sprintf("/proc/%d/setgroups", pid) - err = ioutil.WriteFile(setgroups, []byte("deny\n"), 0666) + err = os.WriteFile(setgroups, []byte("deny\n"), 0666) if err != nil { return false, -1, fmt.Errorf("cannot write setgroups file: %w", err) } logrus.Debugf("write setgroups file exited with 0") - err = ioutil.WriteFile(uidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Geteuid())), 0666) + err = os.WriteFile(uidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Geteuid())), 0666) if err != nil { return false, -1, fmt.Errorf("cannot write uid_map: %w", err) } @@ -369,7 +368,7 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo gidsMapped = err == nil } if !gidsMapped { - err = ioutil.WriteFile(gidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getegid())), 0666) + err = os.WriteFile(gidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getegid())), 0666) if err != nil { return false, -1, fmt.Errorf("cannot write gid_map: %w", err) } @@ -399,7 +398,7 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo // We have lost the race for writing the PID file, as probably another // process created a namespace and wrote the PID. // Try to join it. - data, err := ioutil.ReadFile(pausePid) + data, err := os.ReadFile(pausePid) if err == nil { var pid uint64 pid, err = strconv.ParseUint(string(data), 10, 0) @@ -469,7 +468,7 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st for _, path := range paths { if !needNewNamespace { - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { lastErr = err continue diff --git a/pkg/signal/signal_common.go b/pkg/signal/signal_common.go index fc1ecc04d..a81d0461b 100644 --- a/pkg/signal/signal_common.go +++ b/pkg/signal/signal_common.go @@ -9,6 +9,10 @@ import ( "syscall" ) +// Make sure the signal buffer is sufficiently big. +// runc is using the same value. +const SignalBufferSize = 2048 + // ParseSignal translates a string to a valid syscall signal. // It returns an error if the signal map doesn't include the given signal. func ParseSignal(rawSignal string) (syscall.Signal, error) { @@ -56,3 +60,14 @@ func StopCatch(sigc chan os.Signal) { signal.Stop(sigc) close(sigc) } + +// ParseSysSignalToName translates syscall.Signal to its name in the operating system. +// For example, syscall.Signal(9) will return "KILL" on Linux system. +func ParseSysSignalToName(s syscall.Signal) (string, error) { + for k, v := range SignalMap { + if v == s { + return k, nil + } + } + return "", fmt.Errorf("unknown syscall signal: %s", s) +} diff --git a/pkg/signal/signal_common_test.go b/pkg/signal/signal_common_test.go index c4ae6b389..bd9b230f7 100644 --- a/pkg/signal/signal_common_test.go +++ b/pkg/signal/signal_common_test.go @@ -118,3 +118,52 @@ func TestParseSignalNameOrNumber(t *testing.T) { }) } } + +func TestParseSysSignalToName(t *testing.T) { + type args struct { + signal syscall.Signal + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "Kill should work", + args: args{ + signal: syscall.SIGKILL, + }, + want: "KILL", + wantErr: false, + }, + { + name: "Non-defined signal number should not work", + args: args{ + signal: 923, + }, + want: "", + wantErr: true, + }, + { + name: "garbage should fail", + args: args{ + signal: -1, + }, + want: "", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ParseSysSignalToName(tt.args.signal) + if (err != nil) != tt.wantErr { + t.Errorf("ParseSysSignalToName() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("ParseSysSignalToName() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/signal/signal_linux.go b/pkg/signal/signal_linux.go index 5103b6033..81e4ed758 100644 --- a/pkg/signal/signal_linux.go +++ b/pkg/signal/signal_linux.go @@ -89,3 +89,11 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } + +// IsSignalIgnoredBySigProxy determines whether sig-proxy should ignore syscall signal +func IsSignalIgnoredBySigProxy(s syscall.Signal) bool { + // Ignore SIGCHLD and SIGPIPE - these are most likely intended for the podman command itself. + // SIGURG was added because of golang 1.14 and its preemptive changes causing more signals to "show up". + // https://github.com/containers/podman/issues/5483 + return s == syscall.SIGCHLD || s == syscall.SIGPIPE || s == syscall.SIGURG +} diff --git a/pkg/signal/signal_linux_mipsx.go b/pkg/signal/signal_linux_mipsx.go index cdf9ad4c5..c97eeb23d 100644 --- a/pkg/signal/signal_linux_mipsx.go +++ b/pkg/signal/signal_linux_mipsx.go @@ -90,3 +90,11 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } + +// IsSignalIgnoredBySigProxy determines whether sig-proxy should ignore syscall signal +func IsSignalIgnoredBySigProxy(s syscall.Signal) bool { + // Ignore SIGCHLD and SIGPIPE - these are most likely intended for the podman command itself. + // SIGURG was added because of golang 1.14 and its preemptive changes causing more signals to "show up". + // https://github.com/containers/podman/issues/5483 + return s == syscall.SIGCHLD || s == syscall.SIGPIPE || s == syscall.SIGURG +} diff --git a/pkg/signal/signal_unix.go b/pkg/signal/signal_unix.go index 7919e3670..01d99d7bc 100644 --- a/pkg/signal/signal_unix.go +++ b/pkg/signal/signal_unix.go @@ -87,3 +87,11 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } + +// IsSignalIgnoredBySigProxy determines whether sig-proxy should ignore syscall signal +func IsSignalIgnoredBySigProxy(s syscall.Signal) bool { + // Ignore SIGCHLD and SIGPIPE - these are most likely intended for the podman command itself. + // SIGURG was added because of golang 1.14 and its preemptive changes causing more signals to "show up". + // https://github.com/containers/podman/issues/5483 + return s == syscall.SIGCHLD || s == syscall.SIGPIPE || s == syscall.SIGURG +} diff --git a/pkg/signal/signal_unsupported.go b/pkg/signal/signal_unsupported.go index 19ae93a61..590aaf978 100644 --- a/pkg/signal/signal_unsupported.go +++ b/pkg/signal/signal_unsupported.go @@ -87,3 +87,9 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } + +// IsSignalIgnoredBySigProxy determines whether to sig-proxy should ignore syscall signal +// keep the container running or not. In unsupported OS this should not ignore any syscall signal. +func IsSignalIgnoredBySigProxy(s syscall.Signal) bool { + return false +} diff --git a/pkg/specgen/generate/config_linux_cgo.go b/pkg/specgen/generate/config_linux_cgo.go index 74ba4aeeb..6903ccb51 100644 --- a/pkg/specgen/generate/config_linux_cgo.go +++ b/pkg/specgen/generate/config_linux_cgo.go @@ -7,7 +7,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "github.com/containers/common/libimage" goSeccomp "github.com/containers/common/pkg/seccomp" @@ -47,7 +47,7 @@ func getSeccompConfig(s *specgen.SpecGenerator, configSpec *spec.Spec, img *libi if s.SeccompProfilePath != "" { logrus.Debugf("Loading seccomp profile from %q", s.SeccompProfilePath) - seccompProfile, err := ioutil.ReadFile(s.SeccompProfilePath) + seccompProfile, err := os.ReadFile(s.SeccompProfilePath) if err != nil { return nil, fmt.Errorf("opening seccomp profile failed: %w", err) } diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index 7d85fd2f3..5186a2f72 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -500,20 +500,26 @@ func setupLivenessProbe(s *specgen.SpecGenerator, containerYAML v1.Container, re probe := containerYAML.LivenessProbe probeHandler := probe.Handler - // append `exit 1` to `cmd` so healthcheck can be marked as `unhealthy`. - // append `kill 1` to `cmd` if appropriate restart policy is configured. - if restartPolicy == "always" || restartPolicy == "onfailure" { - // container will be restarted so we can kill init. - failureCmd = "kill 1" - } - // configure healthcheck on the basis of Handler Actions. switch { case probeHandler.Exec != nil: execString := strings.Join(probeHandler.Exec.Command, " ") commandString = fmt.Sprintf("%s || %s", execString, failureCmd) case probeHandler.HTTPGet != nil: - commandString = fmt.Sprintf("curl %s://%s:%d/%s || %s", probeHandler.HTTPGet.Scheme, probeHandler.HTTPGet.Host, probeHandler.HTTPGet.Port.IntValue(), probeHandler.HTTPGet.Path, failureCmd) + // set defaults as in https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#http-probes + uriScheme := v1.URISchemeHTTP + if probeHandler.HTTPGet.Scheme != "" { + uriScheme = probeHandler.HTTPGet.Scheme + } + host := "localhost" // Kubernetes default is host IP, but with Podman there is only one node + if probeHandler.HTTPGet.Host != "" { + host = probeHandler.HTTPGet.Host + } + path := "/" + if probeHandler.HTTPGet.Path != "" { + path = probeHandler.HTTPGet.Path + } + commandString = fmt.Sprintf("curl -f %s://%s:%d%s || %s", uriScheme, host, probeHandler.HTTPGet.Port.IntValue(), path, failureCmd) case probeHandler.TCPSocket != nil: commandString = fmt.Sprintf("nc -z -v %s %d || %s", probeHandler.TCPSocket.Host, probeHandler.TCPSocket.Port.IntValue(), failureCmd) } @@ -521,6 +527,10 @@ func setupLivenessProbe(s *specgen.SpecGenerator, containerYAML v1.Container, re if err != nil { return err } + // if restart policy is in place, ensure the health check enforces it + if restartPolicy == "always" || restartPolicy == "onfailure" { + s.HealthCheckOnFailureAction = define.HealthCheckOnFailureActionRestart + } return nil } return nil @@ -908,6 +918,9 @@ func getPodPorts(containers []v1.Container) []types.PortMapping { if p.HostPort != 0 && p.ContainerPort == 0 { p.ContainerPort = p.HostPort } + if p.HostPort == 0 && p.ContainerPort != 0 { + p.HostPort = p.ContainerPort + } if p.Protocol == "" { p.Protocol = "tcp" } diff --git a/pkg/specgen/generate/kube/play_test.go b/pkg/specgen/generate/kube/play_test.go index ec0dc4bcd..adf9b979a 100644 --- a/pkg/specgen/generate/kube/play_test.go +++ b/pkg/specgen/generate/kube/play_test.go @@ -11,6 +11,8 @@ import ( v1 "github.com/containers/podman/v4/pkg/k8s.io/api/core/v1" "github.com/containers/podman/v4/pkg/k8s.io/apimachinery/pkg/api/resource" v12 "github.com/containers/podman/v4/pkg/k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/containers/podman/v4/pkg/k8s.io/apimachinery/pkg/util/intstr" + "github.com/containers/podman/v4/pkg/specgen" "github.com/docker/docker/pkg/system" "github.com/stretchr/testify/assert" ) @@ -858,3 +860,59 @@ var ( }, } ) + +func TestHttpLivenessProbe(t *testing.T) { + tests := []struct { + name string + specGenerator specgen.SpecGenerator + container v1.Container + restartPolicy string + succeed bool + expectedURL string + }{ + { + "HttpLivenessProbeUrlSetCorrectly", + specgen.SpecGenerator{}, + v1.Container{ + LivenessProbe: &v1.Probe{ + Handler: v1.Handler{ + HTTPGet: &v1.HTTPGetAction{ + Scheme: "http", + Host: "127.0.0.1", + Port: intstr.FromInt(8080), + Path: "/health", + }, + }, + }, + }, + "always", + true, + "http://127.0.0.1:8080/health", + }, + { + "HttpLivenessProbeUrlUsesDefaults", + specgen.SpecGenerator{}, + v1.Container{ + LivenessProbe: &v1.Probe{ + Handler: v1.Handler{ + HTTPGet: &v1.HTTPGetAction{ + Port: intstr.FromInt(80), + }, + }, + }, + }, + "always", + true, + "http://localhost:80/", + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + err := setupLivenessProbe(&test.specGenerator, test.container, test.restartPolicy) + assert.Equal(t, err == nil, test.succeed) + assert.Contains(t, test.specGenerator.ContainerHealthCheckConfig.HealthConfig.Test, test.expectedURL) + }) + } +} diff --git a/pkg/specgen/generate/pause_image.go b/pkg/specgen/generate/pause_image.go index ddf35f230..1b502927f 100644 --- a/pkg/specgen/generate/pause_image.go +++ b/pkg/specgen/generate/pause_image.go @@ -3,7 +3,6 @@ package generate import ( "context" "fmt" - "io/ioutil" "os" buildahDefine "github.com/containers/buildah/define" @@ -62,7 +61,7 @@ func buildPauseImage(rt *libpod.Runtime, rtConfig *config.Config) (string, error COPY %s /catatonit ENTRYPOINT ["/catatonit", "-P"]`, catatonitPath) - tmpF, err := ioutil.TempFile("", "pause.containerfile") + tmpF, err := os.CreateTemp("", "pause.containerfile") if err != nil { return "", err } diff --git a/pkg/specgen/generate/validate.go b/pkg/specgen/generate/validate.go index e9ebdfce3..10997a202 100644 --- a/pkg/specgen/generate/validate.go +++ b/pkg/specgen/generate/validate.go @@ -3,7 +3,6 @@ package generate import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" @@ -180,7 +179,7 @@ func verifyContainerResourcesCgroupV2(s *specgen.SpecGenerator) ([]string, error // If running under the root cgroup try to create or reuse a "probe" cgroup to read memory values own = "podman_probe" _ = os.MkdirAll(filepath.Join("/sys/fs/cgroup", own), 0o755) - _ = ioutil.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+memory"), 0o644) + _ = os.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+memory"), 0o644) } memoryMax := filepath.Join("/sys/fs/cgroup", own, "memory.max") diff --git a/pkg/specgenutil/util.go b/pkg/specgenutil/util.go index b14e2a032..d61e57ce2 100644 --- a/pkg/specgenutil/util.go +++ b/pkg/specgenutil/util.go @@ -3,7 +3,6 @@ package specgenutil import ( "errors" "fmt" - "io/ioutil" "net" "os" "strconv" @@ -18,7 +17,7 @@ import ( // ReadPodIDFile reads the specified file and returns its content (i.e., first // line). func ReadPodIDFile(path string) (string, error) { - content, err := ioutil.ReadFile(path) + content, err := os.ReadFile(path) if err != nil { return "", fmt.Errorf("reading pod ID file: %w", err) } diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go index 8510cfd42..71e9065ea 100644 --- a/pkg/systemd/generate/containers.go +++ b/pkg/systemd/generate/containers.go @@ -78,7 +78,7 @@ Requires={{{{- range $index, $value := .Requires }}}}{{{{ if $index}}}} {{{{end} {{{{- end}}}} [Service] -Environment={{{{.EnvVariable}}}}=%n{{{{- if (eq .IdentifySpecifier true) }}}}-%i{{{{- end}}}} +Environment={{{{.EnvVariable}}}}=%n{{{{- if (eq .IdentifySpecifier true) }}}}-%i {{{{- end}}}} {{{{- if .ExtraEnvs}}}} Environment={{{{- range $index, $value := .ExtraEnvs -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}{{{{end}}}} {{{{- end}}}} @@ -254,6 +254,10 @@ func setContainerNameForTemplate(startCommand []string, info *containerInfo) ([] return startCommand, nil } +func formatOptionsString(cmd string) string { + return formatOptions(strings.Split(cmd, " ")) +} + func formatOptions(options []string) string { var formatted strings.Builder if len(options) == 0 { @@ -294,8 +298,8 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst info.Type = "forking" info.EnvVariable = define.EnvVariable info.ExecStart = "{{{{.Executable}}}} start {{{{.ContainerNameOrID}}}}" - info.ExecStop = "{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.ContainerNameOrID}}}}" - info.ExecStopPost = "{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.ContainerNameOrID}}}}" + info.ExecStop = formatOptionsString("{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}} -t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.ContainerNameOrID}}}}") + info.ExecStopPost = formatOptionsString("{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}} -t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.ContainerNameOrID}}}}") for i, env := range info.AdditionalEnvVariables { info.AdditionalEnvVariables[i] = escapeSystemdArg(env) } @@ -312,9 +316,9 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst info.NotifyAccess = "all" info.PIDFile = "" info.ContainerIDFile = "%t/%n.ctr-id" - info.ExecStartPre = "/bin/rm -f {{{{.ContainerIDFile}}}}" - info.ExecStop = "{{{{.Executable}}}} stop --ignore --cidfile={{{{.ContainerIDFile}}}}" - info.ExecStopPost = "{{{{.Executable}}}} rm -f --ignore --cidfile={{{{.ContainerIDFile}}}}" + info.ExecStartPre = formatOptionsString("/bin/rm -f {{{{.ContainerIDFile}}}}") + info.ExecStop = formatOptionsString("{{{{.Executable}}}} stop --ignore --cidfile={{{{.ContainerIDFile}}}}") + info.ExecStopPost = formatOptionsString("{{{{.Executable}}}} rm -f --ignore --cidfile={{{{.ContainerIDFile}}}}") // The create command must at least have three arguments: // /usr/bin/podman run $IMAGE index := 0 diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go index 7f92e75b8..11e8f549e 100644 --- a/pkg/systemd/generate/containers_test.go +++ b/pkg/systemd/generate/containers_test.go @@ -57,8 +57,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=82 ExecStart=/usr/bin/podman start 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 -ExecStop=/usr/bin/podman stop -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 -ExecStopPost=/usr/bin/podman stop -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 +ExecStop=/usr/bin/podman stop \ + -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 +ExecStopPost=/usr/bin/podman stop \ + -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -83,8 +85,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -107,8 +111,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -134,8 +140,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -161,8 +169,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -188,8 +198,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -217,8 +229,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -243,8 +257,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -266,7 +282,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman container run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -276,8 +293,13 @@ ExecStart=/usr/bin/podman container run \ --replace \ --name jadda-jadda \ --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space" -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -299,7 +321,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman container run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -309,8 +332,13 @@ ExecStart=/usr/bin/podman container run \ --sdnotify=container \ --name jadda-jadda \ --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space" -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -332,7 +360,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman container run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -342,8 +371,13 @@ ExecStart=/usr/bin/podman container run \ --replace \ --name jadda-jadda \ --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space" -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -365,7 +399,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -375,8 +410,13 @@ ExecStart=/usr/bin/podman run \ -d \ --name jadda-jadda \ --hostname hello-world awesome-image:latest command arg1 ... argN -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -398,7 +438,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -409,8 +450,13 @@ ExecStart=/usr/bin/podman run \ -d \ --name jadda-jadda \ --hostname hello-world awesome-image:latest command arg1 ... argN -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -432,7 +478,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -442,8 +489,13 @@ ExecStart=/usr/bin/podman run \ --detach \ --name jadda-jadda \ --hostname hello-world awesome-image:latest command arg1 ... argN -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -465,15 +517,21 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ --rm \ --sdnotify=conmon \ -d awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -496,7 +554,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -505,8 +564,13 @@ ExecStart=/usr/bin/podman run \ ` + detachparam + ` awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -530,7 +594,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -541,8 +606,13 @@ ExecStart=/usr/bin/podman run \ --name test \ -p 80:80 awesome-image:latest somecmd \ --detach=false -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -564,7 +634,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman \ --events-backend none \ --runroot /root run \ @@ -573,8 +644,13 @@ ExecStart=/usr/bin/podman \ --rm \ --sdnotify=conmon \ -d awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -596,15 +672,21 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman container run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ --rm \ --sdnotify=conmon \ -d awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -626,7 +708,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -637,8 +720,13 @@ ExecStart=/usr/bin/podman run \ --name test \ --log-driver=journald \ --log-opt=tag={{.Name}} awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -660,7 +748,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -670,8 +759,13 @@ ExecStart=/usr/bin/podman run \ --replace \ --name test awesome-image:latest sh \ -c "kill $$$$ && echo %%\\" -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -693,7 +787,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -704,8 +799,13 @@ ExecStart=/usr/bin/podman run \ --cgroups=foo \ --conmon-pidfile=foo \ --cidfile=foo alpine -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -727,7 +827,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -740,8 +841,13 @@ ExecStart=/usr/bin/podman run \ --conmon-pidfile=foo \ --cidfile=foo \ --pod-id-file /tmp/pod-foobar.pod-id-file alpine -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -764,7 +870,8 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Environment=FOO=abc "BAR=my test" USER=%%a Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -775,8 +882,13 @@ ExecStart=/usr/bin/podman run \ --env=BAR \ --env=MYENV=2 \ -e USER awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -802,8 +914,10 @@ Environment=USER=%%a Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -826,15 +940,21 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure StartLimitBurst=42 TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ --rm \ --sdnotify=conmon \ -d awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -856,7 +976,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -864,8 +985,13 @@ ExecStart=/usr/bin/podman run \ --sdnotify=conmon \ -d \ -h hostname awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -888,7 +1014,8 @@ Environment=PODMAN_SYSTEMD_UNIT=%n-%i Restart=on-failure StartLimitBurst=42 TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --name=container-foo-%i \ --cidfile=%t/%n.ctr-id \ @@ -896,8 +1023,13 @@ ExecStart=/usr/bin/podman run \ --rm \ --sdnotify=conmon \ -d awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go index 729a038a5..588bfb430 100644 --- a/pkg/systemd/generate/pods.go +++ b/pkg/systemd/generate/pods.go @@ -294,9 +294,9 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions) } info.EnvVariable = define.EnvVariable - info.ExecStart = "{{{{.Executable}}}} start {{{{.InfraNameOrID}}}}" - info.ExecStop = "{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.InfraNameOrID}}}}" - info.ExecStopPost = "{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.InfraNameOrID}}}}" + info.ExecStart = formatOptionsString("{{{{.Executable}}}} start {{{{.InfraNameOrID}}}}") + info.ExecStop = formatOptionsString("{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}} -t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.InfraNameOrID}}}}") + info.ExecStopPost = formatOptionsString("{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}} -t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.InfraNameOrID}}}}") // Assemble the ExecStart command when creating a new pod. // @@ -371,11 +371,11 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions) startCommand = append(startCommand, podCreateArgs...) startCommand = escapeSystemdArguments(startCommand) - info.ExecStartPre1 = "/bin/rm -f {{{{.PIDFile}}}} {{{{.PodIDFile}}}}" - info.ExecStartPre2 = strings.Join(startCommand, " ") - info.ExecStart = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod start --pod-id-file {{{{.PodIDFile}}}}" - info.ExecStop = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod stop --ignore --pod-id-file {{{{.PodIDFile}}}} {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}}" - info.ExecStopPost = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod rm --ignore -f --pod-id-file {{{{.PodIDFile}}}}" + info.ExecStartPre1 = formatOptionsString("/bin/rm -f {{{{.PIDFile}}}} {{{{.PodIDFile}}}}") + info.ExecStartPre2 = formatOptions(startCommand) + info.ExecStart = formatOptionsString("{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod start --pod-id-file {{{{.PodIDFile}}}}") + info.ExecStop = formatOptionsString("{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod stop --ignore --pod-id-file {{{{.PodIDFile}}}} {{{{if (ge .StopTimeout 0)}}}} -t {{{{.StopTimeout}}}}{{{{end}}}}") + info.ExecStopPost = formatOptionsString("{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod rm --ignore -f --pod-id-file {{{{.PodIDFile}}}}") } info.TimeoutStopSec = minTimeoutStopSec + info.StopTimeout diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go index 000d73e9a..c44ab111e 100644 --- a/pkg/systemd/generate/pods_test.go +++ b/pkg/systemd/generate/pods_test.go @@ -79,8 +79,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -107,8 +109,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -136,8 +140,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -164,8 +170,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -192,8 +200,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -222,8 +232,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -246,11 +258,22 @@ Before= Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id -ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --exit-policy=stop foo -ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id -ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10 -ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id +ExecStartPre=/bin/rm \ + -f %t/pod-123abc.pid %t/pod-123abc.pod-id +ExecStartPre=/usr/bin/podman pod create \ + --infra-conmon-pidfile %t/pod-123abc.pid \ + --pod-id-file %t/pod-123abc.pod-id \ + --exit-policy=stop foo +ExecStart=/usr/bin/podman pod start \ + --pod-id-file %t/pod-123abc.pod-id +ExecStop=/usr/bin/podman pod stop \ + --ignore \ + --pod-id-file %t/pod-123abc.pod-id \ + -t 10 +ExecStopPost=/usr/bin/podman pod rm \ + --ignore \ + -f \ + --pod-id-file %t/pod-123abc.pod-id PIDFile=%t/pod-123abc.pid Type=forking @@ -276,8 +299,10 @@ Restart=on-failure RestartSec=15 TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -301,11 +326,24 @@ Before=container-1.service container-2.service Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id -ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --exit-policy=stop --name foo "bar=arg with space" --replace -ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id -ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10 -ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id +ExecStartPre=/bin/rm \ + -f %t/pod-123abc.pid %t/pod-123abc.pod-id +ExecStartPre=/usr/bin/podman pod create \ + --infra-conmon-pidfile %t/pod-123abc.pid \ + --pod-id-file %t/pod-123abc.pod-id \ + --exit-policy=stop \ + --name foo "bar=arg with space" \ + --replace +ExecStart=/usr/bin/podman pod start \ + --pod-id-file %t/pod-123abc.pod-id +ExecStop=/usr/bin/podman pod stop \ + --ignore \ + --pod-id-file %t/pod-123abc.pod-id \ + -t 10 +ExecStopPost=/usr/bin/podman pod rm \ + --ignore \ + -f \ + --pod-id-file %t/pod-123abc.pod-id PIDFile=%t/pod-123abc.pid Type=forking @@ -329,11 +367,26 @@ Before=container-1.service container-2.service Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id -ExecStartPre=/usr/bin/podman --events-backend none --runroot /root pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --exit-policy=stop --name foo "bar=arg with space" --replace -ExecStart=/usr/bin/podman --events-backend none --runroot /root pod start --pod-id-file %t/pod-123abc.pod-id -ExecStop=/usr/bin/podman --events-backend none --runroot /root pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10 -ExecStopPost=/usr/bin/podman --events-backend none --runroot /root pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id +ExecStartPre=/bin/rm \ + -f %t/pod-123abc.pid %t/pod-123abc.pod-id +ExecStartPre=/usr/bin/podman \ + --events-backend none \ + --runroot /root pod create \ + --infra-conmon-pidfile %t/pod-123abc.pid \ + --pod-id-file %t/pod-123abc.pod-id \ + --exit-policy=stop \ + --name foo "bar=arg with space" \ + --replace +ExecStart=/usr/bin/podman --events-backend none --runroot /root pod start \ + --pod-id-file %t/pod-123abc.pod-id +ExecStop=/usr/bin/podman --events-backend none --runroot /root pod stop \ + --ignore \ + --pod-id-file %t/pod-123abc.pod-id \ + -t 10 +ExecStopPost=/usr/bin/podman --events-backend none --runroot /root pod rm \ + --ignore \ + -f \ + --pod-id-file %t/pod-123abc.pod-id PIDFile=%t/pod-123abc.pid Type=forking @@ -357,11 +410,24 @@ Before=container-1.service container-2.service Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id -ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --exit-policy=stop --name foo --replace -ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id -ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10 -ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id +ExecStartPre=/bin/rm \ + -f %t/pod-123abc.pid %t/pod-123abc.pod-id +ExecStartPre=/usr/bin/podman pod create \ + --infra-conmon-pidfile %t/pod-123abc.pid \ + --pod-id-file %t/pod-123abc.pod-id \ + --exit-policy=stop \ + --name foo \ + --replace +ExecStart=/usr/bin/podman pod start \ + --pod-id-file %t/pod-123abc.pod-id +ExecStop=/usr/bin/podman pod stop \ + --ignore \ + --pod-id-file %t/pod-123abc.pod-id \ + -t 10 +ExecStopPost=/usr/bin/podman pod rm \ + --ignore \ + -f \ + --pod-id-file %t/pod-123abc.pod-id PIDFile=%t/pod-123abc.pid Type=forking @@ -385,11 +451,25 @@ Before=container-1.service container-2.service Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id -ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo --label key={{someval}} --exit-policy=continue --replace -ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id -ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10 -ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id +ExecStartPre=/bin/rm \ + -f %t/pod-123abc.pid %t/pod-123abc.pod-id +ExecStartPre=/usr/bin/podman pod create \ + --infra-conmon-pidfile %t/pod-123abc.pid \ + --pod-id-file %t/pod-123abc.pod-id \ + --name foo \ + --label key={{someval}} \ + --exit-policy=continue \ + --replace +ExecStart=/usr/bin/podman pod start \ + --pod-id-file %t/pod-123abc.pod-id +ExecStop=/usr/bin/podman pod stop \ + --ignore \ + --pod-id-file %t/pod-123abc.pod-id \ + -t 10 +ExecStopPost=/usr/bin/podman pod rm \ + --ignore \ + -f \ + --pod-id-file %t/pod-123abc.pod-id PIDFile=%t/pod-123abc.pid Type=forking diff --git a/pkg/systemd/notifyproxy/notifyproxy.go b/pkg/systemd/notifyproxy/notifyproxy.go index 1bfab9ca0..4b92d9e6c 100644 --- a/pkg/systemd/notifyproxy/notifyproxy.go +++ b/pkg/systemd/notifyproxy/notifyproxy.go @@ -1,10 +1,10 @@ package notifyproxy import ( + "context" "errors" "fmt" "io" - "io/ioutil" "net" "os" "strings" @@ -49,7 +49,7 @@ type NotifyProxy struct { // New creates a NotifyProxy. The specified temp directory can be left empty. func New(tmpDir string) (*NotifyProxy, error) { - tempFile, err := ioutil.TempFile(tmpDir, "-podman-notify-proxy.sock") + tempFile, err := os.CreateTemp(tmpDir, "-podman-notify-proxy.sock") if err != nil { return nil, err } @@ -110,48 +110,75 @@ func (p *NotifyProxy) WaitAndClose() error { } }() - const bufferSize = 1024 - sBuilder := strings.Builder{} - for { - // Set a read deadline of one second such that we achieve a - // non-blocking read and can check if the container has already - // stopped running; in that case no READY message will be send - // and we're done. - if err := p.connection.SetReadDeadline(time.Now().Add(time.Second)); err != nil { - return err - } - + // Since reading from the connection is blocking, we need to spin up two + // goroutines. One waiting for the `READY` message, the other waiting + // for the container to stop running. + errorChan := make(chan error, 1) + readyChan := make(chan bool, 1) + + go func() { + // Read until the `READY` message is received or the connection + // is closed. + const bufferSize = 1024 + sBuilder := strings.Builder{} for { - buffer := make([]byte, bufferSize) - num, err := p.connection.Read(buffer) - if err != nil { - if !errors.Is(err, os.ErrDeadlineExceeded) && !errors.Is(err, io.EOF) { - return err + for { + buffer := make([]byte, bufferSize) + num, err := p.connection.Read(buffer) + if err != nil { + if !errors.Is(err, io.EOF) { + errorChan <- err + return + } + } + sBuilder.Write(buffer[:num]) + if num != bufferSize || buffer[num-1] == '\n' { + // Break as we read an entire line that + // we can inspect for the `READY` + // message. + break } } - sBuilder.Write(buffer[:num]) - if num != bufferSize || buffer[num-1] == '\n' { - break - } - } - for _, line := range strings.Split(sBuilder.String(), "\n") { - if line == daemon.SdNotifyReady { - return nil + for _, line := range strings.Split(sBuilder.String(), "\n") { + if line == daemon.SdNotifyReady { + readyChan <- true + return + } } + sBuilder.Reset() } - sBuilder.Reset() + }() - if p.container == nil { - continue - } + if p.container != nil { + // Create a cancellable context to make sure the goroutine + // below terminates. + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + select { + case <-ctx.Done(): + return + default: + state, err := p.container.State() + if err != nil { + errorChan <- err + return + } + if state != define.ContainerStateRunning { + errorChan <- fmt.Errorf("%w: %s", ErrNoReadyMessage, p.container.ID()) + return + } + time.Sleep(time.Second) + } + }() + } - state, err := p.container.State() - if err != nil { - return err - } - if state != define.ContainerStateRunning { - return fmt.Errorf("%w: %s", ErrNoReadyMessage, p.container.ID()) - } + // Wait for the ready/error channel. + select { + case <-readyChan: + return nil + case err := <-errorChan: + return err } } diff --git a/pkg/trust/policy.go b/pkg/trust/policy.go index d746e78cf..e0c5e0689 100644 --- a/pkg/trust/policy.go +++ b/pkg/trust/policy.go @@ -7,7 +7,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -72,7 +71,7 @@ type gpgIDReader func(string) []string // createTmpFile creates a temp file under dir and writes the content into it func createTmpFile(dir, pattern string, content []byte) (string, error) { - tmpfile, err := ioutil.TempFile(dir, pattern) + tmpfile, err := os.CreateTemp(dir, pattern) if err != nil { return "", err } @@ -133,7 +132,7 @@ func parseUids(colonDelimitKeys []byte) []string { // getPolicy parses policy.json into policyContent. func getPolicy(policyPath string) (policyContent, error) { var policyContentStruct policyContent - policyContent, err := ioutil.ReadFile(policyPath) + policyContent, err := os.ReadFile(policyPath) if err != nil { return policyContentStruct, fmt.Errorf("unable to read policy file: %w", err) } @@ -207,7 +206,7 @@ func AddPolicyEntries(policyPath string, input AddPolicyEntriesInput) error { _, err = os.Stat(policyPath) if !os.IsNotExist(err) { - policyContent, err := ioutil.ReadFile(policyPath) + policyContent, err := os.ReadFile(policyPath) if err != nil { return err } @@ -244,5 +243,5 @@ func AddPolicyEntries(policyPath string, input AddPolicyEntriesInput) error { if err != nil { return fmt.Errorf("setting trust policy: %w", err) } - return ioutil.WriteFile(policyPath, data, 0644) + return os.WriteFile(policyPath, data, 0644) } diff --git a/pkg/trust/registries.go b/pkg/trust/registries.go index 86d580059..ed7bca1d6 100644 --- a/pkg/trust/registries.go +++ b/pkg/trust/registries.go @@ -2,7 +2,6 @@ package trust import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -72,7 +71,7 @@ func loadAndMergeConfig(dirPath string) (*registryConfiguration, error) { continue } configPath := filepath.Join(dirPath, configName) - configBytes, err := ioutil.ReadFile(configPath) + configBytes, err := os.ReadFile(configPath) if err != nil { return nil, err } diff --git a/pkg/util/utils_freebsd.go b/pkg/util/utils_freebsd.go index 9b0d7c8c7..ba91308af 100644 --- a/pkg/util/utils_freebsd.go +++ b/pkg/util/utils_freebsd.go @@ -13,6 +13,6 @@ func GetContainerPidInformationDescriptors() ([]string, error) { return []string{}, errors.New("this function is not supported on freebsd") } -func AddPrivilegedDevices(g *generate.Generator) error { +func AddPrivilegedDevices(g *generate.Generator, systemdMode bool) error { return nil } diff --git a/pkg/util/utils_linux.go b/pkg/util/utils_linux.go index 7b2d98666..07927db1c 100644 --- a/pkg/util/utils_linux.go +++ b/pkg/util/utils_linux.go @@ -70,7 +70,7 @@ func FindDeviceNodes() (map[string]string, error) { return nodes, nil } -func AddPrivilegedDevices(g *generate.Generator) error { +func AddPrivilegedDevices(g *generate.Generator, systemdMode bool) error { hostDevices, err := getDevices("/dev") if err != nil { return err @@ -104,6 +104,9 @@ func AddPrivilegedDevices(g *generate.Generator) error { } } else { for _, d := range hostDevices { + if systemdMode && strings.HasPrefix(d.Path, "/dev/tty") { + continue + } g.AddDevice(d) } // Add resources device - need to clear the existing one first. diff --git a/podman.spec.rpkg b/podman.spec.rpkg index f970e5f25..eeaf49f63 100644 --- a/podman.spec.rpkg +++ b/podman.spec.rpkg @@ -6,7 +6,7 @@ %global with_debug 1 # _user_tmpfiles.d currently undefined on rhel -%if 0%{?rhel} +%if 0%{?fedora} <= 35 || 0%{?rhel} %global _user_tmpfilesdir %{_datadir}/user-tmpfiles.d %endif diff --git a/test/apiv2/27-containersEvents.at b/test/apiv2/27-containersEvents.at index e0a66e0ac..a5b5b24a3 100644 --- a/test/apiv2/27-containersEvents.at +++ b/test/apiv2/27-containersEvents.at @@ -20,7 +20,7 @@ t GET "libpod/events?stream=false&since=$START" 200 \ t GET "libpod/events?stream=false&since=$START" 200 \ 'select(.status | contains("start")).Action=start' \ - 'select(.status | contains("start")).HealthStatus='\ + 'select(.status | contains("start")).HealthStatus=null'\ # compat api, uses status=die (#12643) t GET "events?stream=false&since=$START" 200 \ diff --git a/test/apiv2/50-secrets.at b/test/apiv2/50-secrets.at index ed0e8fb6b..acd8f3de9 100644 --- a/test/apiv2/50-secrets.at +++ b/test/apiv2/50-secrets.at @@ -7,9 +7,6 @@ t POST secrets/create Name=mysecret Data=c2VjcmV0 200\ .ID~.* \ -# secret create unsupported labels -t POST secrets/create Name=mysecret Data=c2VjcmV0 Labels='{"fail":"fail"}' 400 - # secret create name already in use t POST secrets/create Name=mysecret Data=c2VjcmV0 409 @@ -59,8 +56,15 @@ t GET libpod/secrets/json?filters='garb1age}' 500 \ t GET libpod/secrets/json?filters='{"label":["testl' 500 \ .cause="unexpected end of JSON input" +# secret with labels +t POST secrets/create Name=labeledsecret Data=c2VjcmV0 Labels='{"foo":"bar"}' 200 +t GET secrets/labeledsecret 200 \ + .Spec.Labels.foo=bar + # secret rm t DELETE secrets/mysecret 204 +t DELETE secrets/labeledsecret 204 + # secret rm non-existent secret t DELETE secrets/bogus 404 diff --git a/test/buildah-bud/apply-podman-deltas b/test/buildah-bud/apply-podman-deltas index 999f36bf9..1ab409359 100755 --- a/test/buildah-bud/apply-podman-deltas +++ b/test/buildah-bud/apply-podman-deltas @@ -70,7 +70,10 @@ function _skip() { for t in "$@"; do if fgrep -qx "@test \"$t\" {" $BUD; then $ECHO "@test \"$t\" : $skip \"$reason\"" + # Escape slash in test name, 'custom files in /run/' t=${t//\//\\/} + # Escape star in test name, 'bud with --dns* flags' + t=${t//\*/\\\*} sed -i -e "/^\@test \"$t\" {/ a \ \ $skip \"$reason\"" $BUD else warn "[$skip] Did not find test \"$t\" in $BUD" diff --git a/test/compose/uptwice/docker-compose.yml b/test/compose/uptwice/docker-compose.yml index e06f9e554..71cc0806c 100644 --- a/test/compose/uptwice/docker-compose.yml +++ b/test/compose/uptwice/docker-compose.yml @@ -2,4 +2,5 @@ version: '3' services: app: build: . - command: sleep 10002 + command: sleep 10001 + stop_signal: SIGKILL # faster shutdown, no reason to wait 10 seconds diff --git a/test/compose/uptwice/teardown.sh b/test/compose/uptwice/teardown.sh new file mode 100644 index 000000000..115c454dc --- /dev/null +++ b/test/compose/uptwice/teardown.sh @@ -0,0 +1,3 @@ +# -*- bash -*- + +mv docker-compose.yml.bak docker-compose.yml diff --git a/test/compose/uptwice/tests.sh b/test/compose/uptwice/tests.sh index 291694d83..013b5a29a 100644 --- a/test/compose/uptwice/tests.sh +++ b/test/compose/uptwice/tests.sh @@ -1,4 +1,17 @@ # -*- bash -*- +CR=$'\r' +NL=$'\n' + +cp docker-compose.yml docker-compose.yml.bak sed -i -e 's/10001/10002/' docker-compose.yml -docker-compose up -d +output=$(docker-compose up -d 2>&1) + +# Horrible output check here but we really want to make sure that there are +# no unexpected warning/errors and the normal messages are send on stderr as +# well so we cannot check for an empty stderr. +expected="Recreating uptwice_app_1 ... ${CR}${NL}Recreating uptwice_app_1 ... done$CR" +if [ "$TEST_FLAVOR" = "compose_v2" ]; then + expected="Container uptwice-app-1 Recreate${NL}Container uptwice-app-1 Recreated${NL}Container uptwice-app-1 Starting${NL}Container uptwice-app-1 Started" +fi +is "$output" "$expected" "no error output in compose up (#15580)" diff --git a/test/e2e/benchmarks_test.go b/test/e2e/benchmarks_test.go index d1332665a..6773eae02 100644 --- a/test/e2e/benchmarks_test.go +++ b/test/e2e/benchmarks_test.go @@ -5,7 +5,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path" "strconv" @@ -108,7 +107,7 @@ var _ = Describe("Podman Benchmark Suite", func() { if f.IsDir() { continue } - raw, err := ioutil.ReadFile(path.Join(timedir, f.Name())) + raw, err := os.ReadFile(path.Join(timedir, f.Name())) if err != nil { Fail(fmt.Sprintf("Error reading timing file: %v", err)) } diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go index 424c7244e..0f6cb2a10 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -3,7 +3,6 @@ package integration import ( "bytes" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -219,10 +218,10 @@ var _ = Describe("Podman build", func() { } fakeFile := filepath.Join(os.TempDir(), "Containerfile") - Expect(ioutil.WriteFile(fakeFile, []byte(fmt.Sprintf("FROM %s", ALPINE)), 0755)).To(BeNil()) + Expect(os.WriteFile(fakeFile, []byte(fmt.Sprintf("FROM %s", ALPINE)), 0755)).To(BeNil()) targetFile := filepath.Join(targetPath, "Containerfile") - Expect(ioutil.WriteFile(targetFile, []byte("FROM scratch"), 0755)).To(BeNil()) + Expect(os.WriteFile(targetFile, []byte("FROM scratch"), 0755)).To(BeNil()) defer func() { Expect(os.RemoveAll(fakeFile)).To(BeNil()) @@ -257,7 +256,7 @@ var _ = Describe("Podman build", func() { session := podmanTest.Podman([]string{"build", "--pull-never", "build/basicalpine", "--iidfile", targetFile}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - id, _ := ioutil.ReadFile(targetFile) + id, _ := os.ReadFile(targetFile) // Verify that id is correct inspect := podmanTest.Podman([]string{"inspect", string(id)}) @@ -311,7 +310,7 @@ var _ = Describe("Podman build", func() { RUN printenv http_proxy`, ALPINE) dockerfilePath := filepath.Join(podmanTest.TempDir, "Dockerfile") - err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755) + err := os.WriteFile(dockerfilePath, []byte(dockerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "--http-proxy", "--file", dockerfilePath, podmanTest.TempDir}) session.Wait(120) @@ -330,7 +329,7 @@ RUN printenv http_proxy`, ALPINE) RUN exit 5`, ALPINE) dockerfilePath := filepath.Join(podmanTest.TempDir, "Dockerfile") - err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755) + err := os.WriteFile(dockerfilePath, []byte(dockerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "-t", "error-test", "--file", dockerfilePath, podmanTest.TempDir}) session.Wait(120) @@ -388,7 +387,7 @@ RUN exit 5`, ALPINE) err = os.Mkdir(targetSubPath, 0755) Expect(err).To(BeNil()) dummyFile := filepath.Join(targetSubPath, "dummy") - err = ioutil.WriteFile(dummyFile, []byte("dummy"), 0644) + err = os.WriteFile(dummyFile, []byte("dummy"), 0644) Expect(err).To(BeNil()) containerfile := fmt.Sprintf(`FROM %s @@ -396,7 +395,7 @@ ADD . /test RUN find /test`, ALPINE) containerfilePath := filepath.Join(targetPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) defer func() { @@ -437,7 +436,7 @@ RUN find /test`, ALPINE) containerfile := fmt.Sprintf("FROM %s", ALPINE) containerfilePath := filepath.Join(targetSubPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) defer func() { @@ -476,7 +475,7 @@ ADD . /testfilter/ RUN find /testfilter/`, ALPINE) containerfilePath := filepath.Join(targetPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) targetSubPath := filepath.Join(targetPath, "subdir") @@ -484,15 +483,15 @@ RUN find /testfilter/`, ALPINE) Expect(err).To(BeNil()) dummyFile1 := filepath.Join(targetPath, "dummy1") - err = ioutil.WriteFile(dummyFile1, []byte("dummy1"), 0644) + err = os.WriteFile(dummyFile1, []byte("dummy1"), 0644) Expect(err).To(BeNil()) dummyFile2 := filepath.Join(targetPath, "dummy2") - err = ioutil.WriteFile(dummyFile2, []byte("dummy2"), 0644) + err = os.WriteFile(dummyFile2, []byte("dummy2"), 0644) Expect(err).To(BeNil()) dummyFile3 := filepath.Join(targetSubPath, "dummy3") - err = ioutil.WriteFile(dummyFile3, []byte("dummy3"), 0644) + err = os.WriteFile(dummyFile3, []byte("dummy3"), 0644) Expect(err).To(BeNil()) defer func() { @@ -509,7 +508,7 @@ subdir**` // test .dockerignore By("Test .dockererignore") - err = ioutil.WriteFile(dockerignoreFile, []byte(dockerignoreContent), 0644) + err = os.WriteFile(dockerignoreFile, []byte(dockerignoreContent), 0644) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "-t", "test", "."}) @@ -540,18 +539,18 @@ subdir**` contents.WriteString("RUN find /testfilter/ -print\n") containerfile := filepath.Join(tempdir, "Containerfile") - Expect(ioutil.WriteFile(containerfile, contents.Bytes(), 0644)).ToNot(HaveOccurred()) + Expect(os.WriteFile(containerfile, contents.Bytes(), 0644)).ToNot(HaveOccurred()) contextDir, err := CreateTempDirInTempDir() Expect(err).ToNot(HaveOccurred()) defer os.RemoveAll(contextDir) - Expect(ioutil.WriteFile(filepath.Join(contextDir, "expected"), contents.Bytes(), 0644)). + Expect(os.WriteFile(filepath.Join(contextDir, "expected"), contents.Bytes(), 0644)). ToNot(HaveOccurred()) subdirPath := filepath.Join(contextDir, "subdir") Expect(os.MkdirAll(subdirPath, 0755)).ToNot(HaveOccurred()) - Expect(ioutil.WriteFile(filepath.Join(subdirPath, "extra"), contents.Bytes(), 0644)). + Expect(os.WriteFile(filepath.Join(subdirPath, "extra"), contents.Bytes(), 0644)). ToNot(HaveOccurred()) randomFile := filepath.Join(subdirPath, "randomFile") dd := exec.Command("dd", "if=/dev/urandom", "of="+randomFile, "bs=1G", "count=1") @@ -567,7 +566,7 @@ subdir**` }() By("Test .containerignore filtering subdirectory") - err = ioutil.WriteFile(filepath.Join(contextDir, ".containerignore"), []byte(`subdir/`), 0644) + err = os.WriteFile(filepath.Join(contextDir, ".containerignore"), []byte(`subdir/`), 0644) Expect(err).ToNot(HaveOccurred()) session := podmanTest.Podman([]string{"build", "-f", containerfile, contextDir}) @@ -597,7 +596,7 @@ subdir**` err = os.Mkdir(targetSubPath, 0755) Expect(err).To(BeNil()) dummyFile := filepath.Join(targetSubPath, "dummy") - err = ioutil.WriteFile(dummyFile, []byte("dummy"), 0644) + err = os.WriteFile(dummyFile, []byte("dummy"), 0644) Expect(err).To(BeNil()) emptyDir := filepath.Join(targetSubPath, "emptyDir") @@ -612,7 +611,7 @@ RUN find /test RUN [[ -L /test/dummy-symlink ]] && echo SYMLNKOK || echo SYMLNKERR`, ALPINE) containerfilePath := filepath.Join(targetSubPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) defer func() { @@ -641,7 +640,7 @@ RUN [[ -L /test/dummy-symlink ]] && echo SYMLNKOK || echo SYMLNKERR`, ALPINE) RUN cat /etc/hosts RUN grep CapEff /proc/self/status` - Expect(ioutil.WriteFile(containerFile, []byte(content), 0755)).To(BeNil()) + Expect(os.WriteFile(containerFile, []byte(content), 0755)).To(BeNil()) defer func() { Expect(os.RemoveAll(containerFile)).To(BeNil()) @@ -668,7 +667,7 @@ RUN grep CapEff /proc/self/status` Expect(err).To(BeNil()) containerFile := filepath.Join(targetPath, "Containerfile") - Expect(ioutil.WriteFile(containerFile, []byte(fmt.Sprintf("FROM %s", ALPINE)), 0755)).To(BeNil()) + Expect(os.WriteFile(containerFile, []byte(fmt.Sprintf("FROM %s", ALPINE)), 0755)).To(BeNil()) defer func() { Expect(os.RemoveAll(containerFile)).To(BeNil()) @@ -712,7 +711,7 @@ RUN grep CapEff /proc/self/status` RUN echo hello`, ALPINE) containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") - err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) + err := os.WriteFile(containerfilePath, []byte(containerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--timestamp", "0", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -730,7 +729,7 @@ RUN echo hello`, ALPINE) containerFile := filepath.Join(targetPath, "Containerfile") content := `FROM scratch` - Expect(ioutil.WriteFile(containerFile, []byte(content), 0755)).To(BeNil()) + Expect(os.WriteFile(containerFile, []byte(content), 0755)).To(BeNil()) session := podmanTest.Podman([]string{"build", "--log-rusage", "--pull-never", targetPath}) session.WaitWithDefaultTimeout() @@ -743,7 +742,7 @@ RUN echo hello`, ALPINE) It("podman build --arch --os flag", func() { containerfile := `FROM scratch` containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") - err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) + err := os.WriteFile(containerfilePath, []byte(containerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--arch", "foo", "--os", "bar", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -762,7 +761,7 @@ RUN echo hello`, ALPINE) It("podman build --os windows flag", func() { containerfile := `FROM scratch` containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") - err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) + err := os.WriteFile(containerfilePath, []byte(containerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--os", "windows", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -785,7 +784,7 @@ RUN echo hello`, ALPINE) containerfile := fmt.Sprintf(`FROM %s RUN ls /dev/fuse`, ALPINE) containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") - err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) + err := os.WriteFile(containerfilePath, []byte(containerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -801,7 +800,7 @@ RUN ls /dev/fuse`, ALPINE) containerfile := fmt.Sprintf(`FROM %s RUN ls /dev/test1`, ALPINE) containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") - err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) + err := os.WriteFile(containerfilePath, []byte(containerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -822,7 +821,7 @@ RUN ls /dev/test1`, ALPINE) Expect(err).To(BeNil()) err = os.Mkdir(buildRoot, 0755) Expect(err).To(BeNil()) - err = ioutil.WriteFile(containerFilePath, []byte(containerFile), 0755) + err = os.WriteFile(containerFilePath, []byte(containerFile), 0755) Expect(err).To(BeNil()) build := podmanTest.Podman([]string{"build", "-f", containerFilePath, buildRoot}) build.WaitWithDefaultTimeout() diff --git a/test/e2e/checkpoint_image_test.go b/test/e2e/checkpoint_image_test.go index 5700802e8..7ab0b5ca5 100644 --- a/test/e2e/checkpoint_image_test.go +++ b/test/e2e/checkpoint_image_test.go @@ -295,4 +295,52 @@ var _ = Describe("Podman checkpoint", func() { Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) + + It("podman run checkpoint image to restore container", func() { + SkipIfContainerized("FIXME: #15015. All checkpoint tests hang when containerized.") + // Container image must be lowercase + checkpointImage := "alpine-checkpoint-" + strings.ToLower(RandomString(6)) + containerName := "alpine-container-" + RandomString(6) + + // Create container + localRunString := []string{"run", "-d", "--name", containerName, ALPINE, "top"} + session := podmanTest.Podman(localRunString) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + containerID1 := session.OutputToString() + + // Checkpoint container, create checkpoint image + result := podmanTest.Podman([]string{"container", "checkpoint", "--create-image", checkpointImage, "--keep", containerID1}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + + // Remove existing container + result = podmanTest.Podman([]string{"rm", "-t", "1", "-f", containerName}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + + // Restore containers from image using `podman run` + result = podmanTest.Podman([]string{"run", checkpointImage}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + + // Check if the container is running + status := podmanTest.Podman([]string{"inspect", containerName, "--format={{.State.Status}}"}) + status.WaitWithDefaultTimeout() + Expect(status).Should(Exit(0)) + Expect(status.OutputToString()).To(Equal("running")) + + // Clean-up + result = podmanTest.Podman([]string{"rm", "-t", "0", "-fa"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + + result = podmanTest.Podman([]string{"rmi", checkpointImage}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + }) }) diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index a33936549..b0c1d36d3 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -1170,10 +1170,6 @@ var _ = Describe("Podman checkpoint", func() { share := share // copy into local scope, for use inside function It(testName, func() { - if podmanTest.Host.Distribution == "ubuntu" && IsRemote() { - Skip("FIXME: #15018. Cannot restore --pod under cgroupsV1 and remote") - } - if !criu.CheckForCriu(criu.PodCriuVersion) { Skip("CRIU is missing or too old.") } diff --git a/test/e2e/commit_test.go b/test/e2e/commit_test.go index 452a378c2..14814628d 100644 --- a/test/e2e/commit_test.go +++ b/test/e2e/commit_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -287,7 +286,7 @@ var _ = Describe("Podman commit", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - id, _ := ioutil.ReadFile(targetFile) + id, _ := os.ReadFile(targetFile) check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"}) check.WaitWithDefaultTimeout() data := check.InspectImageJSON() @@ -297,7 +296,7 @@ var _ = Describe("Podman commit", func() { It("podman commit should not commit secret", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -322,7 +321,7 @@ var _ = Describe("Podman commit", func() { It("podman commit should not commit env secret", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 690e2f22c..67a889b25 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -4,7 +4,6 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" "math/rand" "net" "net/url" @@ -144,7 +143,7 @@ var _ = SynchronizedBeforeSuite(func() []byte { } f.Close() } - path, err := ioutil.TempDir("", "libpodlock") + path, err := os.MkdirTemp("", "libpodlock") if err != nil { fmt.Println(err) os.Exit(1) @@ -875,7 +874,7 @@ func writeConf(conf []byte, confPath string) { fmt.Println(err) } } - if err := ioutil.WriteFile(confPath, conf, 0o777); err != nil { + if err := os.WriteFile(confPath, conf, 0o777); err != nil { fmt.Println(err) } } @@ -967,7 +966,7 @@ func (s *PodmanSessionIntegration) jq(jqCommand string) (string, error) { func (p *PodmanTestIntegration) buildImage(dockerfile, imageName string, layers string, label string) string { dockerfilePath := filepath.Join(p.TempDir, "Dockerfile") - err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755) + err := os.WriteFile(dockerfilePath, []byte(dockerfile), 0755) Expect(err).To(BeNil()) cmd := []string{"build", "--pull-never", "--layers=" + layers, "--file", dockerfilePath} if label != "" { diff --git a/test/e2e/config/containers.conf b/test/e2e/config/containers.conf index 94bb316b1..3cf20268c 100644 --- a/test/e2e/config/containers.conf +++ b/test/e2e/config/containers.conf @@ -76,3 +76,4 @@ testvol6 = "/run/docker/plugins/testvol6.sock" testvol7 = "/run/docker/plugins/testvol7.sock" testvol8 = "/run/docker/plugins/testvol8.sock" testvol9 = "/run/docker/plugins/testvol9.sock" +image = "/run/docker/plugins/image.sock" diff --git a/test/e2e/container_create_volume_test.go b/test/e2e/container_create_volume_test.go index 3c54691aa..6d6173d0f 100644 --- a/test/e2e/container_create_volume_test.go +++ b/test/e2e/container_create_volume_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -15,7 +14,7 @@ import ( func buildDataVolumeImage(pTest *PodmanTestIntegration, image, data, dest string) { // Create a dummy file for data volume dummyFile := filepath.Join(pTest.TempDir, data) - err := ioutil.WriteFile(dummyFile, []byte(data), 0644) + err := os.WriteFile(dummyFile, []byte(data), 0644) Expect(err).To(BeNil()) // Create a data volume container image but no CMD binary in it @@ -29,7 +28,7 @@ VOLUME %s/`, data, dest, dest) func createContainersConfFile(pTest *PodmanTestIntegration) { configPath := filepath.Join(pTest.TempDir, "containers.conf") containersConf := []byte("[containers]\nprepare_volume_on_create = true\n") - err := ioutil.WriteFile(configPath, containersConf, os.ModePerm) + err := os.WriteFile(configPath, containersConf, os.ModePerm) Expect(err).To(BeNil()) // Set custom containers.conf file diff --git a/test/e2e/containers_conf_test.go b/test/e2e/containers_conf_test.go index 41e78ce0e..211f6b572 100644 --- a/test/e2e/containers_conf_test.go +++ b/test/e2e/containers_conf_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -208,7 +207,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { tempdir, err = CreateTempDirInTempDir() Expect(err).ToNot(HaveOccurred()) - err := ioutil.WriteFile(conffile, []byte(fmt.Sprintf("[containers]\nvolumes=[\"%s:%s:Z\",]\n", tempdir, tempdir)), 0755) + err := os.WriteFile(conffile, []byte(fmt.Sprintf("[containers]\nvolumes=[\"%s:%s:Z\",]\n", tempdir, tempdir)), 0755) Expect(err).ToNot(HaveOccurred()) os.Setenv("CONTAINERS_CONF", conffile) @@ -406,7 +405,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { profile := filepath.Join(podmanTest.TempDir, "seccomp.json") containersConf := []byte(fmt.Sprintf("[containers]\nseccomp_profile=\"%s\"", profile)) - err = ioutil.WriteFile(configPath, containersConf, os.ModePerm) + err = os.WriteFile(configPath, containersConf, os.ModePerm) Expect(err).ToNot(HaveOccurred()) if IsRemote() { @@ -430,7 +429,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { os.Setenv("CONTAINERS_CONF", configPath) containersConf := []byte("[engine]\nimage_copy_tmp_dir=\"/foobar\"") - err = ioutil.WriteFile(configPath, containersConf, os.ModePerm) + err = os.WriteFile(configPath, containersConf, os.ModePerm) Expect(err).ToNot(HaveOccurred()) if IsRemote() { @@ -443,7 +442,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { Expect(session.OutputToString()).To(Equal("/foobar")) containersConf = []byte(fmt.Sprintf("[engine]\nimage_copy_tmp_dir=%q", storagePath)) - err = ioutil.WriteFile(configPath, containersConf, os.ModePerm) + err = os.WriteFile(configPath, containersConf, os.ModePerm) Expect(err).ToNot(HaveOccurred()) if IsRemote() { podmanTest.RestartRemoteService() @@ -455,7 +454,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { Expect(session.Out.Contents()).To(ContainSubstring(storagePath)) containersConf = []byte("[engine]\nimage_copy_tmp_dir=\"storage1\"") - err = ioutil.WriteFile(configPath, containersConf, os.ModePerm) + err = os.WriteFile(configPath, containersConf, os.ModePerm) Expect(err).ToNot(HaveOccurred()) if !IsRemote() { @@ -485,7 +484,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { os.Setenv("CONTAINERS_CONF", configPath) containersConf := []byte("[engine]\ninfra_image=\"" + infra1 + "\"") - err = ioutil.WriteFile(configPath, containersConf, os.ModePerm) + err = os.WriteFile(configPath, containersConf, os.ModePerm) Expect(err).ToNot(HaveOccurred()) if IsRemote() { @@ -520,7 +519,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { os.Setenv("CONTAINERS_CONF", configPath) defer os.Remove(configPath) - err := ioutil.WriteFile(configPath, []byte("[engine]\nremote=true"), os.ModePerm) + err := os.WriteFile(configPath, []byte("[engine]\nremote=true"), os.ModePerm) Expect(err).ToNot(HaveOccurred()) // podmanTest.Podman() cannot be used as it was initialized remote==false @@ -540,7 +539,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { } conffile := filepath.Join(podmanTest.TempDir, "container.conf") - err := ioutil.WriteFile(conffile, []byte("[containers]\ncgroups=\"disabled\"\n"), 0755) + err := os.WriteFile(conffile, []byte("[containers]\ncgroups=\"disabled\"\n"), 0755) Expect(err).ToNot(HaveOccurred()) result := podmanTest.Podman([]string{"create", ALPINE, "true"}) @@ -572,7 +571,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { It("podman containers.conf runtime", func() { SkipIfRemote("--runtime option is not available for remote commands") conffile := filepath.Join(podmanTest.TempDir, "container.conf") - err := ioutil.WriteFile(conffile, []byte("[engine]\nruntime=\"testruntime\"\n"), 0755) + err := os.WriteFile(conffile, []byte("[engine]\nruntime=\"testruntime\"\n"), 0755) Expect(err).ToNot(HaveOccurred()) os.Setenv("CONTAINERS_CONF", conffile) diff --git a/test/e2e/cp_test.go b/test/e2e/cp_test.go index 8a65b85d3..214903a16 100644 --- a/test/e2e/cp_test.go +++ b/test/e2e/cp_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "os/exec" "os/user" @@ -43,13 +42,13 @@ var _ = Describe("Podman cp", func() { // Copy a file to the container, then back to the host and make sure // that the contents match. It("podman cp file", func() { - srcFile, err := ioutil.TempFile("", "") + srcFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer srcFile.Close() defer os.Remove(srcFile.Name()) originalContent := []byte("podman cp file test") - err = ioutil.WriteFile(srcFile.Name(), originalContent, 0644) + err = os.WriteFile(srcFile.Name(), originalContent, 0644) Expect(err).To(BeNil()) // Create a container. NOTE that container mustn't be running for copying. @@ -72,7 +71,7 @@ var _ = Describe("Podman cp", func() { // Copy FROM the container. - destFile, err := ioutil.TempFile("", "") + destFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer destFile.Close() defer os.Remove(destFile.Name()) @@ -86,7 +85,7 @@ var _ = Describe("Podman cp", func() { Expect(session).Should(Exit(0)) // Now make sure the content matches. - roundtripContent, err := ioutil.ReadFile(destFile.Name()) + roundtripContent, err := os.ReadFile(destFile.Name()) Expect(err).To(BeNil()) Expect(roundtripContent).To(Equal(originalContent)) }) @@ -94,13 +93,13 @@ var _ = Describe("Podman cp", func() { // Copy a file to the container, then back to the host in --pid=host It("podman cp --pid=host file", func() { SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1") - srcFile, err := ioutil.TempFile("", "") + srcFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer srcFile.Close() defer os.Remove(srcFile.Name()) originalContent := []byte("podman cp file test") - err = ioutil.WriteFile(srcFile.Name(), originalContent, 0644) + err = os.WriteFile(srcFile.Name(), originalContent, 0644) Expect(err).To(BeNil()) // Create a container. NOTE that container mustn't be running for copying. @@ -120,7 +119,7 @@ var _ = Describe("Podman cp", func() { // Copy FROM the container. - destFile, err := ioutil.TempFile("", "") + destFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer destFile.Close() defer os.Remove(destFile.Name()) @@ -130,7 +129,7 @@ var _ = Describe("Podman cp", func() { Expect(session).Should(Exit(0)) // Now make sure the content matches. - roundtripContent, err := ioutil.ReadFile(destFile.Name()) + roundtripContent, err := os.ReadFile(destFile.Name()) Expect(err).To(BeNil()) Expect(roundtripContent).To(Equal(originalContent)) }) @@ -139,13 +138,13 @@ var _ = Describe("Podman cp", func() { // make sure that the link and the resolved path are accessible and // give the right content. It("podman cp symlink", func() { - srcFile, err := ioutil.TempFile("", "") + srcFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer srcFile.Close() defer os.Remove(srcFile.Name()) originalContent := []byte("podman cp symlink test") - err = ioutil.WriteFile(srcFile.Name(), originalContent, 0644) + err = os.WriteFile(srcFile.Name(), originalContent, 0644) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top"}) @@ -178,13 +177,13 @@ var _ = Describe("Podman cp", func() { // the path to the volume's mount point on the host, and 3) copy the // data to the volume and not the container. It("podman cp volume", func() { - srcFile, err := ioutil.TempFile("", "") + srcFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer srcFile.Close() defer os.Remove(srcFile.Name()) originalContent := []byte("podman cp volume") - err = ioutil.WriteFile(srcFile.Name(), originalContent, 0644) + err = os.WriteFile(srcFile.Name(), originalContent, 0644) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"volume", "create", "data"}) session.WaitWithDefaultTimeout() @@ -205,7 +204,7 @@ var _ = Describe("Podman cp", func() { Expect(session).Should(Exit(0)) volumeMountPoint := session.OutputToString() - copiedContent, err := ioutil.ReadFile(filepath.Join(volumeMountPoint, "file.txt")) + copiedContent, err := os.ReadFile(filepath.Join(volumeMountPoint, "file.txt")) Expect(err).To(BeNil()) Expect(copiedContent).To(Equal(originalContent)) }) @@ -214,7 +213,7 @@ var _ = Describe("Podman cp", func() { // it to the host and back to the container and make sure that we can // access it, and (roughly) the right users own it. It("podman cp from ctr chown ", func() { - srcFile, err := ioutil.TempFile("", "") + srcFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer srcFile.Close() defer os.Remove(srcFile.Name()) @@ -265,7 +264,7 @@ var _ = Describe("Podman cp", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) session = podmanTest.Podman([]string{"cp", container + ":/", tmpDir}) diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index d5920dc3e..9a18dea18 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -242,7 +241,7 @@ var _ = Describe("Podman create", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(125)) - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) defer os.RemoveAll(tmpDir) diff --git a/test/e2e/events_test.go b/test/e2e/events_test.go index bba42c3f4..c76919581 100644 --- a/test/e2e/events_test.go +++ b/test/e2e/events_test.go @@ -212,6 +212,16 @@ var _ = Describe("Podman events", func() { Expect(result).Should(Exit(0)) Expect(result.OutputToStringArray()).To(HaveLen(1)) Expect(result.OutputToString()).To(ContainSubstring("create")) + + ctrName := "testCtr" + run := podmanTest.Podman([]string{"create", "--pod", id, "--name", ctrName, ALPINE, "top"}) + run.WaitWithDefaultTimeout() + Expect(run).Should(Exit(0)) + + result2 := podmanTest.Podman([]string{"events", "--stream=false", "--filter", fmt.Sprintf("container=%s", ctrName), "--since", "30s"}) + result2.WaitWithDefaultTimeout() + Expect(result2).Should(Exit(0)) + Expect(result2.OutputToString()).To(ContainSubstring(fmt.Sprintf("pod_id=%s", id))) }) It("podman events health_status generated", func() { @@ -229,7 +239,7 @@ var _ = Describe("Podman events", func() { time.Sleep(1 * time.Second) } - result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=health_status"}) + result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=health_status", "--since", "1m"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) Expect(len(result.OutputToStringArray())).To(BeNumerically(">=", 1), "Number of health_status events") diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go index f4ee688b7..6bd13f7da 100644 --- a/test/e2e/exec_test.go +++ b/test/e2e/exec_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -545,7 +544,7 @@ RUN useradd -u 1000 auser`, fedoraMinimal) It("podman exec with env var secret", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go index cd2378bdf..08eaa4dcf 100644 --- a/test/e2e/generate_kube_test.go +++ b/test/e2e/generate_kube_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "os/user" "path/filepath" @@ -278,7 +277,7 @@ var _ = Describe("Podman generate kube", func() { if name == "root" { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -752,7 +751,7 @@ var _ = Describe("Podman generate kube", func() { kube.WaitWithDefaultTimeout() Expect(kube).Should(Exit(0)) - b, err := ioutil.ReadFile(outputFile) + b, err := os.ReadFile(outputFile) Expect(err).ShouldNot(HaveOccurred()) pod := new(v1.Pod) err = yaml.Unmarshal(b, pod) @@ -1045,7 +1044,7 @@ ENTRYPOINT ["sleep"]` targetPath, err := CreateTempDirInTempDir() Expect(err).To(BeNil()) containerfilePath := filepath.Join(targetPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) image := "generatekube:test" @@ -1135,7 +1134,7 @@ USER test1` targetPath, err := CreateTempDirInTempDir() Expect(err).To(BeNil()) containerfilePath := filepath.Join(targetPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) image := "generatekube:test" diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go index 347440faf..01c0aefab 100644 --- a/test/e2e/generate_systemd_test.go +++ b/test/e2e/generate_systemd_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "strings" @@ -108,7 +107,7 @@ var _ = Describe("Podman generate systemd", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("TimeoutStopSec=1294")) - Expect(session.OutputToString()).To(ContainSubstring(" stop -t 1234 ")) + Expect(session.OutputToString()).To(ContainSubstring("-t 1234")) }) It("podman generate systemd", func() { @@ -149,14 +148,15 @@ var _ = Describe("Podman generate systemd", func() { Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("TimeoutStopSec=65")) Expect(session.OutputToString()).ToNot(ContainSubstring("TimeoutStartSec=")) - Expect(session.OutputToString()).To(ContainSubstring("podman stop -t 5")) + Expect(session.OutputToString()).To(ContainSubstring("podman stop")) + Expect(session.OutputToString()).To(ContainSubstring("-t 5")) session = podmanTest.Podman([]string{"generate", "systemd", "--stop-timeout", "5", "--start-timeout", "123", "nginx"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("TimeoutStartSec=123")) Expect(session.OutputToString()).To(ContainSubstring("TimeoutStopSec=65")) - Expect(session.OutputToString()).To(ContainSubstring("podman stop -t 5")) + Expect(session.OutputToString()).To(ContainSubstring("-t 5")) }) It("podman generate systemd with user-defined dependencies", func() { @@ -228,7 +228,8 @@ var _ = Describe("Podman generate systemd", func() { Expect(output).To(ContainSubstring(" start foo-1")) Expect(output).To(ContainSubstring("-infra")) // infra container Expect(output).To(ContainSubstring("# container-foo-2.service")) - Expect(output).To(ContainSubstring(" stop -t 42 foo-2")) + Expect(output).To(ContainSubstring("podman stop")) + Expect(output).To(ContainSubstring("-t 42 foo-2")) Expect(output).To(ContainSubstring("BindsTo=pod-foo.service")) Expect(output).To(ContainSubstring("PIDFile=")) Expect(output).To(ContainSubstring("/userdata/conmon.pid")) @@ -539,7 +540,7 @@ var _ = Describe("Podman generate systemd", func() { }) It("podman generate systemd pod with containers --new", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "podID" defer os.RemoveAll(tmpDir) @@ -564,10 +565,21 @@ var _ = Describe("Podman generate systemd", func() { Expect(session.OutputToString()).To(ContainSubstring("# pod-foo.service")) Expect(session.OutputToString()).To(ContainSubstring("Wants=container-foo-1.service container-foo-2.service")) Expect(session.OutputToString()).To(ContainSubstring("BindsTo=pod-foo.service")) - Expect(session.OutputToString()).To(ContainSubstring("pod create --infra-conmon-pidfile %t/pod-foo.pid --pod-id-file %t/pod-foo.pod-id --exit-policy=stop --name foo")) - Expect(session.OutputToString()).To(ContainSubstring("ExecStartPre=/bin/rm -f %t/pod-foo.pid %t/pod-foo.pod-id")) - Expect(session.OutputToString()).To(ContainSubstring("pod stop --ignore --pod-id-file %t/pod-foo.pod-id -t 10")) - Expect(session.OutputToString()).To(ContainSubstring("pod rm --ignore -f --pod-id-file %t/pod-foo.pod-id")) + Expect(session.OutputToString()).To(ContainSubstring("pod create")) + Expect(session.OutputToString()).To(ContainSubstring("--infra-conmon-pidfile %t/pod-foo.pid")) + Expect(session.OutputToString()).To(ContainSubstring("--pod-id-file %t/pod-foo.pod-id")) + Expect(session.OutputToString()).To(ContainSubstring("--exit-policy=stop")) + Expect(session.OutputToString()).To(ContainSubstring("--name foo")) + Expect(session.OutputToString()).To(ContainSubstring("ExecStartPre=/bin/rm")) + Expect(session.OutputToString()).To(ContainSubstring("-f %t/pod-foo.pid %t/pod-foo.pod-id")) + Expect(session.OutputToString()).To(ContainSubstring("pod stop")) + Expect(session.OutputToString()).To(ContainSubstring("--ignore")) + Expect(session.OutputToString()).To(ContainSubstring("--pod-id-file %t/pod-foo.pod-id")) + Expect(session.OutputToString()).To(ContainSubstring("-t 10")) + Expect(session.OutputToString()).To(ContainSubstring("pod rm")) + Expect(session.OutputToString()).To(ContainSubstring("--ignore")) + Expect(session.OutputToString()).To(ContainSubstring("-f")) + Expect(session.OutputToString()).To(ContainSubstring("--pod-id-file %t/pod-foo.pod-id")) }) It("podman generate systemd --format json", func() { diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go index 969f83b19..a84fd6538 100644 --- a/test/e2e/healthcheck_run_test.go +++ b/test/e2e/healthcheck_run_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" "time" @@ -303,7 +302,7 @@ var _ = Describe("Podman healthcheck run", func() { containerfile := fmt.Sprintf(`FROM %s HEALTHCHECK CMD ls -l / 2>&1`, ALPINE) containerfilePath := filepath.Join(targetPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) defer func() { Expect(os.Chdir(cwd)).To(BeNil()) diff --git a/test/e2e/image_scp_test.go b/test/e2e/image_scp_test.go index 2c275d974..3ee2b74b5 100644 --- a/test/e2e/image_scp_test.go +++ b/test/e2e/image_scp_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "path/filepath" @@ -25,7 +24,7 @@ var _ = Describe("podman image scp", func() { BeforeEach(func() { ConfPath.Value, ConfPath.IsSet = os.LookupEnv("CONTAINERS_CONF") - conf, err := ioutil.TempFile("", "containersconf") + conf, err := os.CreateTemp("", "containersconf") Expect(err).ToNot(HaveOccurred()) os.Setenv("CONTAINERS_CONF", conf.Name()) diff --git a/test/e2e/info_test.go b/test/e2e/info_test.go index 9d31deb55..ab4f607a0 100644 --- a/test/e2e/info_test.go +++ b/test/e2e/info_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/exec" "os/user" @@ -104,7 +103,7 @@ var _ = Describe("Podman Info", func() { driver := `"overlay"` storageOpt := `"/usr/bin/fuse-overlayfs"` storageConf := []byte(fmt.Sprintf("[storage]\ndriver=%s\nrootless_storage_path=%s\n[storage.options]\nmount_program=%s", driver, rootlessStoragePath, storageOpt)) - err = ioutil.WriteFile(configPath, storageConf, os.ModePerm) + err = os.WriteFile(configPath, storageConf, os.ModePerm) Expect(err).To(BeNil()) u, err := user.Current() diff --git a/test/e2e/kill_test.go b/test/e2e/kill_test.go index 9b33e2f0d..d789a6595 100644 --- a/test/e2e/kill_test.go +++ b/test/e2e/kill_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" . "github.com/containers/podman/v4/test/utils" @@ -150,7 +149,7 @@ var _ = Describe("Podman kill", func() { }) It("podman kill --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "cid" defer os.RemoveAll(tmpDir) @@ -170,12 +169,12 @@ var _ = Describe("Podman kill", func() { }) It("podman kill multiple --cidfile", func() { - tmpDir1, err := ioutil.TempDir("", "") + tmpDir1, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile1 := tmpDir1 + "cid" defer os.RemoveAll(tmpDir1) - tmpDir2, err := ioutil.TempDir("", "") + tmpDir2, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile2 := tmpDir2 + "cid" defer os.RemoveAll(tmpDir2) @@ -202,7 +201,7 @@ var _ = Describe("Podman kill", func() { Expect(wait).Should(Exit(0)) }) - It("podman stop --all", func() { + It("podman kill --all", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) diff --git a/test/e2e/libpod_suite_remote_test.go b/test/e2e/libpod_suite_remote_test.go index 86be17eb3..499373e65 100644 --- a/test/e2e/libpod_suite_remote_test.go +++ b/test/e2e/libpod_suite_remote_test.go @@ -6,7 +6,6 @@ package integration import ( "errors" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -58,7 +57,7 @@ func (p *PodmanTestIntegration) setDefaultRegistriesConfigEnv() { func (p *PodmanTestIntegration) setRegistriesConfigEnv(b []byte) { outfile := filepath.Join(p.TempDir, "registries.conf") os.Setenv("CONTAINERS_REGISTRIES_CONF", outfile) - err := ioutil.WriteFile(outfile, b, 0644) + err := os.WriteFile(outfile, b, 0644) Expect(err).ToNot(HaveOccurred()) } diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go index ecb7a2278..b797fbb89 100644 --- a/test/e2e/libpod_suite_test.go +++ b/test/e2e/libpod_suite_test.go @@ -5,7 +5,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -48,7 +47,7 @@ func (p *PodmanTestIntegration) setDefaultRegistriesConfigEnv() { func (p *PodmanTestIntegration) setRegistriesConfigEnv(b []byte) { outfile := filepath.Join(p.TempDir, "registries.conf") os.Setenv("CONTAINERS_REGISTRIES_CONF", outfile) - err := ioutil.WriteFile(outfile, b, 0644) + err := os.WriteFile(outfile, b, 0644) Expect(err).ToNot(HaveOccurred()) } diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go index 60c53e27e..5951c1a3e 100644 --- a/test/e2e/login_logout_test.go +++ b/test/e2e/login_logout_test.go @@ -3,7 +3,6 @@ package integration import ( "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" "strconv" @@ -101,7 +100,7 @@ var _ = Describe("Podman login and logout", func() { }) readAuthInfo := func(filePath string) map[string]interface{} { - authBytes, err := ioutil.ReadFile(filePath) + authBytes, err := os.ReadFile(filePath) Expect(err).To(BeNil()) var authInfo map[string]interface{} @@ -137,12 +136,12 @@ var _ = Describe("Podman login and logout", func() { }) It("podman login and logout without registry parameter", func() { - registriesConf, err := ioutil.TempFile("", "TestLoginWithoutParameter") + registriesConf, err := os.CreateTemp("", "TestLoginWithoutParameter") Expect(err).To(BeNil()) defer registriesConf.Close() defer os.Remove(registriesConf.Name()) - err = ioutil.WriteFile(registriesConf.Name(), registriesConfWithSearch, os.ModePerm) + err = os.WriteFile(registriesConf.Name(), registriesConfWithSearch, os.ModePerm) Expect(err).To(BeNil()) // Environment is per-process, so this looks very unsafe; actually it seems fine because tests are not @@ -448,7 +447,7 @@ var _ = Describe("Podman login and logout", func() { It("podman login and logout with repository push with invalid auth.json credentials", func() { authFile := filepath.Join(podmanTest.TempDir, "auth.json") // only `server` contains the correct login data - err := ioutil.WriteFile(authFile, []byte(fmt.Sprintf(`{"auths": { + err := os.WriteFile(authFile, []byte(fmt.Sprintf(`{"auths": { "%s/podmantest": { "auth": "cG9kbWFudGVzdDp3cm9uZw==" }, "%s": { "auth": "cG9kbWFudGVzdDp0ZXN0" } }}`, server, server)), 0644) @@ -494,7 +493,7 @@ var _ = Describe("Podman login and logout", func() { Expect(session).Should(Exit(0)) // only `server + /podmantest` and `server` have the correct login data - err := ioutil.WriteFile(authFile, []byte(fmt.Sprintf(`{"auths": { + err := os.WriteFile(authFile, []byte(fmt.Sprintf(`{"auths": { "%s/podmantest/test-alpine": { "auth": "cG9kbWFudGVzdDp3cm9uZw==" }, "%s/podmantest": { "auth": "cG9kbWFudGVzdDp0ZXN0" }, "%s": { "auth": "cG9kbWFudGVzdDp0ZXN0" } diff --git a/test/e2e/manifest_test.go b/test/e2e/manifest_test.go index e38499257..b0a5e7d03 100644 --- a/test/e2e/manifest_test.go +++ b/test/e2e/manifest_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -338,7 +337,7 @@ var _ = Describe("Podman manifest", func() { for _, f := range blobs { blobPath := filepath.Join(blobsDir, f.Name()) - sourceFile, err := ioutil.ReadFile(blobPath) + sourceFile, err := os.ReadFile(blobPath) Expect(err).To(BeNil()) compressionType := archive.DetectCompression(sourceFile) diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go index b2f50ca55..4366d84aa 100644 --- a/test/e2e/network_test.go +++ b/test/e2e/network_test.go @@ -706,7 +706,7 @@ var _ = Describe("Podman network", func() { }) It("podman network prune --filter", func() { - // set custom cni directory to prevent flakes + // set custom network directory to prevent flakes since the dir is shared with all tests by default podmanTest.NetworkConfigDir = tempdir if IsRemote() { podmanTest.RestartRemoteService() @@ -754,7 +754,7 @@ var _ = Describe("Podman network", func() { }) It("podman network prune", func() { - // set custom cni directory to prevent flakes + // set custom network directory to prevent flakes since the dir is shared with all tests by default podmanTest.NetworkConfigDir = tempdir if IsRemote() { podmanTest.RestartRemoteService() diff --git a/test/e2e/pause_test.go b/test/e2e/pause_test.go index 363df2624..6500fc0e0 100644 --- a/test/e2e/pause_test.go +++ b/test/e2e/pause_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -31,7 +30,7 @@ var _ = Describe("Podman pause", func() { } if CGROUPSV2 { - b, err := ioutil.ReadFile("/proc/self/cgroup") + b, err := os.ReadFile("/proc/self/cgroup") if err != nil { Skip("cannot read self cgroup") } @@ -336,7 +335,7 @@ var _ = Describe("Podman pause", func() { }) It("podman pause --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "cid" @@ -365,7 +364,7 @@ var _ = Describe("Podman pause", func() { }) It("podman pause multiple --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile1 := tmpDir + "cid-1" tmpFile2 := tmpDir + "cid-2" diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 26460c937..651cb1074 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "fmt" - "io/ioutil" "net" "net/url" "os" @@ -134,8 +133,6 @@ spec: containers: - name: podnameEqualsContainerNameYaml image: quay.io/libpod/alpine:latest - ports: - - containerPort: 80 ` var podWithoutAName = ` @@ -240,8 +237,6 @@ spec: - "1.5" name: alpine image: quay.io/libpod/alpine:latest - ports: - - containerPort: 80 livenessProbe: exec: command: @@ -275,8 +270,6 @@ spec: - "1.5" name: alpine image: quay.io/libpod/alpine:latest - ports: - - containerPort: 80 livenessProbe: exec: command: @@ -767,7 +760,7 @@ func generateMultiDocKubeYaml(kubeObjects []string, pathname string) error { func createSecret(podmanTest *PodmanTestIntegration, name string, value []byte) { //nolint:unparam secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, value, 0755) + err := os.WriteFile(secretFilePath, value, 0755) Expect(err).To(BeNil()) secret := podmanTest.Podman([]string{"secret", "create", name, secretFilePath}) @@ -1442,7 +1435,7 @@ var _ = Describe("Podman play kube", func() { conffile := filepath.Join(podmanTest.TempDir, "container.conf") infraImage := "k8s.gcr.io/pause:3.2" - err := ioutil.WriteFile(conffile, []byte(fmt.Sprintf("[engine]\ninfra_image=\"%s\"\n", infraImage)), 0644) + err := os.WriteFile(conffile, []byte(fmt.Sprintf("[engine]\ninfra_image=\"%s\"\n", infraImage)), 0644) Expect(err).To(BeNil()) os.Setenv("CONTAINERS_CONF", conffile) @@ -2370,7 +2363,7 @@ spec: tempdir, err = CreateTempDirInTempDir() Expect(err).To(BeNil()) - err := ioutil.WriteFile(conffile, []byte(testyaml), 0755) + err := os.WriteFile(conffile, []byte(testyaml), 0755) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", conffile}) @@ -3800,7 +3793,7 @@ ENV OPENJ9_JAVA_OPTIONS=%q if name == "root" { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -3808,7 +3801,7 @@ ENV OPENJ9_JAVA_OPTIONS=%q Skip("cannot find mappings for the current user") } - initialUsernsConfig, err := ioutil.ReadFile("/proc/self/uid_map") + initialUsernsConfig, err := os.ReadFile("/proc/self/uid_map") Expect(err).To(BeNil()) if os.Geteuid() != 0 { unshare := podmanTest.Podman([]string{"unshare", "cat", "/proc/self/uid_map"}) diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go index 24d9d6854..d694efe5f 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/user" "path/filepath" @@ -332,7 +331,7 @@ var _ = Describe("Podman pod create", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - id, _ := ioutil.ReadFile(targetFile) + id, _ := os.ReadFile(targetFile) check := podmanTest.Podman([]string{"pod", "inspect", "abc"}) check.WaitWithDefaultTimeout() data := check.InspectPodToJSON() @@ -707,7 +706,7 @@ ENTRYPOINT ["sleep","99999"] name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -742,7 +741,7 @@ ENTRYPOINT ["sleep","99999"] name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -778,7 +777,7 @@ ENTRYPOINT ["sleep","99999"] name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -815,7 +814,7 @@ ENTRYPOINT ["sleep","99999"] name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go index 364ef54d5..d9f319798 100644 --- a/test/e2e/pod_rm_test.go +++ b/test/e2e/pod_rm_test.go @@ -3,7 +3,6 @@ package integration import ( "fmt" "io/fs" - "io/ioutil" "os" "path/filepath" "strings" @@ -235,7 +234,7 @@ var _ = Describe("Podman pod rm", func() { }) It("podman pod start/remove single pod via --pod-id-file", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "podID" defer os.RemoveAll(tmpDir) @@ -264,7 +263,7 @@ var _ = Describe("Podman pod rm", func() { }) It("podman pod start/remove multiple pods via --pod-id-file", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) defer os.RemoveAll(tmpDir) diff --git a/test/e2e/pod_start_test.go b/test/e2e/pod_start_test.go index 084a48636..a89613732 100644 --- a/test/e2e/pod_start_test.go +++ b/test/e2e/pod_start_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "strconv" "strings" @@ -175,7 +174,7 @@ var _ = Describe("Podman pod start", func() { }) It("podman pod start single pod via --pod-id-file", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "podID" defer os.RemoveAll(tmpDir) @@ -199,7 +198,7 @@ var _ = Describe("Podman pod start", func() { }) It("podman pod start multiple pods via --pod-id-file", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) defer os.RemoveAll(tmpDir) @@ -231,7 +230,7 @@ var _ = Describe("Podman pod start", func() { }) It("podman pod create --infra-conmon-pod create + start", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "podID" defer os.RemoveAll(tmpDir) @@ -248,7 +247,7 @@ var _ = Describe("Podman pod start", func() { Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) // infra readFirstLine := func(path string) string { - content, err := ioutil.ReadFile(path) + content, err := os.ReadFile(path) Expect(err).To(BeNil()) return strings.Split(string(content), "\n")[0] } diff --git a/test/e2e/pod_stop_test.go b/test/e2e/pod_stop_test.go index 2fe0aa486..b8a9fabc7 100644 --- a/test/e2e/pod_stop_test.go +++ b/test/e2e/pod_stop_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" . "github.com/containers/podman/v4/test/utils" @@ -181,7 +180,7 @@ var _ = Describe("Podman pod stop", func() { }) It("podman pod start/stop single pod via --pod-id-file", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "podID" defer os.RemoveAll(tmpDir) @@ -210,7 +209,7 @@ var _ = Describe("Podman pod stop", func() { }) It("podman pod start/stop multiple pods via --pod-id-file", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) defer os.RemoveAll(tmpDir) diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go index 0b1d68aea..e91569231 100644 --- a/test/e2e/prune_test.go +++ b/test/e2e/prune_test.go @@ -259,6 +259,12 @@ var _ = Describe("Podman prune", func() { }) It("podman system prune networks", func() { + // set custom network directory to prevent flakes since the dir is shared with all tests by default + podmanTest.NetworkConfigDir = tempdir + if IsRemote() { + podmanTest.RestartRemoteService() + } + // Create new network. session := podmanTest.Podman([]string{"network", "create", "test"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/push_test.go b/test/e2e/push_test.go index a73b7c87b..5af47678f 100644 --- a/test/e2e/push_test.go +++ b/test/e2e/push_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -84,7 +83,7 @@ var _ = Describe("Podman push", func() { for _, f := range blobs { blobPath := filepath.Join(blobsDir, f.Name()) - sourceFile, err := ioutil.ReadFile(blobPath) + sourceFile, err := os.ReadFile(blobPath) Expect(err).To(BeNil()) compressionType := archive.DetectCompression(sourceFile) diff --git a/test/e2e/restart_test.go b/test/e2e/restart_test.go index 9df884292..effb716a8 100644 --- a/test/e2e/restart_test.go +++ b/test/e2e/restart_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "time" @@ -251,7 +250,7 @@ var _ = Describe("Podman restart", func() { }) It("podman restart --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "cid" @@ -274,7 +273,7 @@ var _ = Describe("Podman restart", func() { }) It("podman restart multiple --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile1 := tmpDir + "cid-1" tmpFile2 := tmpDir + "cid-2" @@ -322,7 +321,7 @@ var _ = Describe("Podman restart", func() { Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together")) }) - It("podman pause --filter", func() { + It("podman restart --filter", func() { session1 := podmanTest.RunTopContainer("") session1.WaitWithDefaultTimeout() Expect(session1).Should(Exit(0)) diff --git a/test/e2e/rm_test.go b/test/e2e/rm_test.go index e76451824..e931c4419 100644 --- a/test/e2e/rm_test.go +++ b/test/e2e/rm_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" . "github.com/containers/podman/v4/test/utils" @@ -145,7 +144,7 @@ var _ = Describe("Podman rm", func() { }) It("podman rm --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "cid" @@ -166,7 +165,7 @@ var _ = Describe("Podman rm", func() { }) It("podman rm multiple --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile1 := tmpDir + "cid-1" tmpFile2 := tmpDir + "cid-2" diff --git a/test/e2e/run_apparmor_test.go b/test/e2e/run_apparmor_test.go index 18d011e6d..f486054c3 100644 --- a/test/e2e/run_apparmor_test.go +++ b/test/e2e/run_apparmor_test.go @@ -5,7 +5,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -104,7 +103,7 @@ profile aa-test-profile flags=(attach_disconnected,mediate_deleted) { } ` aaFile := filepath.Join(os.TempDir(), "aaFile") - Expect(ioutil.WriteFile(aaFile, []byte(aaProfile), 0755)).To(BeNil()) + Expect(os.WriteFile(aaFile, []byte(aaProfile), 0755)).To(BeNil()) parse := SystemExec("apparmor_parser", []string{"-Kr", aaFile}) Expect(parse).Should(Exit(0)) diff --git a/test/e2e/run_cgroup_parent_test.go b/test/e2e/run_cgroup_parent_test.go index 24cae43b1..ba3ca922e 100644 --- a/test/e2e/run_cgroup_parent_test.go +++ b/test/e2e/run_cgroup_parent_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -86,12 +85,12 @@ var _ = Describe("Podman run with --cgroup-parent", func() { containerCgroup := strings.TrimRight(strings.ReplaceAll(exec.OutputToString(), "0::", ""), "\n") // Move the container process to a sub cgroup - content, err := ioutil.ReadFile(filepath.Join(cgroupRoot, containerCgroup, "cgroup.procs")) + content, err := os.ReadFile(filepath.Join(cgroupRoot, containerCgroup, "cgroup.procs")) Expect(err).To(BeNil()) oldSubCgroupPath := filepath.Join(cgroupRoot, containerCgroup, "old-container") err = os.MkdirAll(oldSubCgroupPath, 0755) Expect(err).To(BeNil()) - err = ioutil.WriteFile(filepath.Join(oldSubCgroupPath, "cgroup.procs"), content, 0644) + err = os.WriteFile(filepath.Join(oldSubCgroupPath, "cgroup.procs"), content, 0644) Expect(err).To(BeNil()) newCgroup := fmt.Sprintf("%s/new-container", containerCgroup) diff --git a/test/e2e/run_cpu_test.go b/test/e2e/run_cpu_test.go index 19bb735ff..bdac998cf 100644 --- a/test/e2e/run_cpu_test.go +++ b/test/e2e/run_cpu_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" . "github.com/containers/podman/v4/test/utils" @@ -26,7 +25,7 @@ var _ = Describe("Podman run cpu", func() { } if CGROUPSV2 { - if err := ioutil.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+cpuset"), 0644); err != nil { + if err := os.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+cpuset"), 0644); err != nil { Skip("cpuset controller not available on the current kernel") } } diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 3fbdd4339..fb02cb410 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "net" "os" "os/exec" @@ -638,7 +637,7 @@ USER bin`, BB) Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("111")) - currentOOMScoreAdj, err := ioutil.ReadFile("/proc/self/oom_score_adj") + currentOOMScoreAdj, err := os.ReadFile("/proc/self/oom_score_adj") Expect(err).To(BeNil()) session = podmanTest.Podman([]string{"run", "--rm", fedoraMinimal, "cat", "/proc/self/oom_score_adj"}) session.WaitWithDefaultTimeout() @@ -845,7 +844,7 @@ USER bin`, BB) "stage" : [ "prestart" ] } `, hookScriptPath) - err = ioutil.WriteFile(hookJSONPath, []byte(hookJSON), 0644) + err = os.WriteFile(hookJSONPath, []byte(hookJSON), 0644) Expect(err).ToNot(HaveOccurred()) random := stringid.GenerateRandomID() @@ -853,14 +852,14 @@ USER bin`, BB) hookScript := fmt.Sprintf(`#!/bin/sh echo -n %s >%s `, random, targetFile) - err = ioutil.WriteFile(hookScriptPath, []byte(hookScript), 0755) + err = os.WriteFile(hookScriptPath, []byte(hookScript), 0755) Expect(err).ToNot(HaveOccurred()) session := podmanTest.Podman([]string{"--hooks-dir", hooksDir, "run", ALPINE, "ls"}) session.Wait(10) Expect(session).Should(Exit(0)) - b, err := ioutil.ReadFile(targetFile) + b, err := os.ReadFile(targetFile) Expect(err).ToNot(HaveOccurred()) Expect(string(b)).To(Equal(random)) }) @@ -877,19 +876,19 @@ echo -n %s >%s mountsFile := filepath.Join(containersDir, "mounts.conf") mountString := secretsDir + ":/run/secrets" - err = ioutil.WriteFile(mountsFile, []byte(mountString), 0755) + err = os.WriteFile(mountsFile, []byte(mountString), 0755) Expect(err).To(BeNil()) secretsFile := filepath.Join(secretsDir, "test.txt") secretsString := "Testing secrets mount. I am mounted!" - err = ioutil.WriteFile(secretsFile, []byte(secretsString), 0755) + err = os.WriteFile(secretsFile, []byte(secretsString), 0755) Expect(err).To(BeNil()) targetDir := tempdir + "/symlink/target" err = os.MkdirAll(targetDir, 0755) Expect(err).To(BeNil()) keyFile := filepath.Join(targetDir, "key.pem") - err = ioutil.WriteFile(keyFile, []byte(mountString), 0755) + err = os.WriteFile(keyFile, []byte(mountString), 0755) Expect(err).To(BeNil()) execSession := SystemExec("ln", []string{"-s", targetDir, filepath.Join(secretsDir, "mysymlink")}) Expect(execSession).Should(Exit(0)) @@ -908,7 +907,7 @@ echo -n %s >%s It("podman run with FIPS mode secrets", func() { SkipIfRootless("rootless can not manipulate system-fips file") fipsFile := "/etc/system-fips" - err = ioutil.WriteFile(fipsFile, []byte{}, 0755) + err = os.WriteFile(fipsFile, []byte{}, 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "ls", "/run/secrets"}) @@ -1070,7 +1069,7 @@ USER mail`, BB) filename := "test.txt" volFile := filepath.Join(vol, filename) data := "Testing --volumes-from!!!" - err = ioutil.WriteFile(volFile, []byte(data), 0755) + err = os.WriteFile(volFile, []byte(data), 0755) Expect(err).To(BeNil()) mountpoint := "/myvol/" @@ -1102,7 +1101,7 @@ USER mail`, BB) filename := "test.txt" volFile := filepath.Join(vol, filename) data := "Testing --volumes-from!!!" - err = ioutil.WriteFile(volFile, []byte(data), 0755) + err = os.WriteFile(volFile, []byte(data), 0755) Expect(err).To(BeNil()) mountpoint := "/myvol/" @@ -1469,7 +1468,7 @@ USER mail`, BB) return strings.TrimSuffix(i, "\n") } - curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup") + curCgroupsBytes, err := os.ReadFile("/proc/self/cgroup") Expect(err).ShouldNot(HaveOccurred()) curCgroups := trim(string(curCgroupsBytes)) fmt.Printf("Output:\n%s\n", curCgroups) @@ -1492,7 +1491,7 @@ USER mail`, BB) Skip("Test only works on crun") } - curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup") + curCgroupsBytes, err := os.ReadFile("/proc/self/cgroup") Expect(err).To(BeNil()) var curCgroups string = string(curCgroupsBytes) fmt.Printf("Output:\n%s\n", curCgroups) @@ -1509,7 +1508,7 @@ USER mail`, BB) pid := inspectOut[0].State.Pid Expect(pid).To(Not(Equal(0))) - ctrCgroupsBytes, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid)) + ctrCgroupsBytes, err := os.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid)) Expect(err).To(BeNil()) var ctrCgroups string = string(ctrCgroupsBytes) fmt.Printf("Output\n:%s\n", ctrCgroups) @@ -1740,7 +1739,7 @@ WORKDIR /madethis`, BB) It("podman run --secret", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1762,7 +1761,7 @@ WORKDIR /madethis`, BB) It("podman run --secret source=mysecret,type=mount", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1784,7 +1783,7 @@ WORKDIR /madethis`, BB) It("podman run --secret source=mysecret,type=mount with target", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret_target", secretFilePath}) @@ -1806,7 +1805,7 @@ WORKDIR /madethis`, BB) It("podman run --secret source=mysecret,type=mount with target at /tmp", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret_target2", secretFilePath}) @@ -1828,7 +1827,7 @@ WORKDIR /madethis`, BB) It("podman run --secret source=mysecret,type=env", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1844,7 +1843,7 @@ WORKDIR /madethis`, BB) It("podman run --secret target option", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1860,7 +1859,7 @@ WORKDIR /madethis`, BB) It("podman run --secret mount with uid, gid, mode options", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1887,7 +1886,7 @@ WORKDIR /madethis`, BB) It("podman run --secret with --user", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1903,7 +1902,7 @@ WORKDIR /madethis`, BB) It("podman run invalid secret option", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1968,7 +1967,7 @@ WORKDIR /madethis`, BB) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) readFirstLine := func(path string) string { - content, err := ioutil.ReadFile(path) + content, err := os.ReadFile(path) Expect(err).To(BeNil()) return strings.Split(string(content), "\n")[0] } diff --git a/test/e2e/run_userns_test.go b/test/e2e/run_userns_test.go index 016f67bf6..c485f1522 100644 --- a/test/e2e/run_userns_test.go +++ b/test/e2e/run_userns_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/user" "strings" @@ -55,7 +54,7 @@ var _ = Describe("Podman UserNS support", func() { if name == "root" { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -181,7 +180,7 @@ var _ = Describe("Podman UserNS support", func() { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -213,7 +212,7 @@ var _ = Describe("Podman UserNS support", func() { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -251,7 +250,7 @@ var _ = Describe("Podman UserNS support", func() { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -280,7 +279,7 @@ var _ = Describe("Podman UserNS support", func() { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go index aa8f49176..d65be97a4 100644 --- a/test/e2e/run_volume_test.go +++ b/test/e2e/run_volume_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/exec" "os/user" @@ -768,7 +767,7 @@ VOLUME /test/`, ALPINE) name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -815,7 +814,7 @@ VOLUME /test/`, ALPINE) name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } diff --git a/test/e2e/save_test.go b/test/e2e/save_test.go index afb723a63..db353c036 100644 --- a/test/e2e/save_test.go +++ b/test/e2e/save_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "os/exec" "path/filepath" @@ -46,6 +45,15 @@ var _ = Describe("Podman save", func() { Expect(save).Should(Exit(0)) }) + It("podman save signature-policy flag", func() { + SkipIfRemote("--signature-policy N/A for remote") + outfile := filepath.Join(podmanTest.TempDir, "alpine.tar") + + save := podmanTest.Podman([]string{"save", "--signature-policy", "/etc/containers/policy.json", "-o", outfile, ALPINE}) + save.WaitWithDefaultTimeout() + Expect(save).Should(Exit(0)) + }) + It("podman save oci flag", func() { outfile := filepath.Join(podmanTest.TempDir, "alpine.tar") @@ -185,7 +193,7 @@ default-docker: sigstore: file:///var/lib/containers/sigstore sigstore-staging: file:///var/lib/containers/sigstore ` - Expect(ioutil.WriteFile("/etc/containers/registries.d/default.yaml", []byte(sigstore), 0755)).To(BeNil()) + Expect(os.WriteFile("/etc/containers/registries.d/default.yaml", []byte(sigstore), 0755)).To(BeNil()) session = podmanTest.Podman([]string{"tag", ALPINE, "localhost:5000/alpine"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index f8b1bc836..77cb72056 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" "os" "strconv" "text/template" @@ -288,7 +287,7 @@ registries = ['{{.Host}}:{{.Port}}']` err = registryFileTmpl.Execute(&buffer, ep) Expect(err).ToNot(HaveOccurred()) podmanTest.setRegistriesConfigEnv(buffer.Bytes()) - err = ioutil.WriteFile(fmt.Sprintf("%s/registry4.conf", tempdir), buffer.Bytes(), 0644) + err = os.WriteFile(fmt.Sprintf("%s/registry4.conf", tempdir), buffer.Bytes(), 0644) Expect(err).ToNot(HaveOccurred()) if IsRemote() { podmanTest.RestartRemoteService() @@ -332,7 +331,7 @@ registries = ['{{.Host}}:{{.Port}}']` err = registryFileTmpl.Execute(&buffer, ep) Expect(err).ToNot(HaveOccurred()) podmanTest.setRegistriesConfigEnv(buffer.Bytes()) - err = ioutil.WriteFile(fmt.Sprintf("%s/registry5.conf", tempdir), buffer.Bytes(), 0644) + err = os.WriteFile(fmt.Sprintf("%s/registry5.conf", tempdir), buffer.Bytes(), 0644) Expect(err).ToNot(HaveOccurred()) search := podmanTest.Podman([]string{"search", image, "--tls-verify=true"}) @@ -372,7 +371,7 @@ registries = ['{{.Host}}:{{.Port}}']` err = registryFileBadTmpl.Execute(&buffer, ep) Expect(err).ToNot(HaveOccurred()) podmanTest.setRegistriesConfigEnv(buffer.Bytes()) - err = ioutil.WriteFile(fmt.Sprintf("%s/registry6.conf", tempdir), buffer.Bytes(), 0644) + err = os.WriteFile(fmt.Sprintf("%s/registry6.conf", tempdir), buffer.Bytes(), 0644) Expect(err).ToNot(HaveOccurred()) if IsRemote() { @@ -428,7 +427,7 @@ registries = ['{{.Host}}:{{.Port}}']` err = registryFileTwoTmpl.Execute(&buffer, ep3) Expect(err).ToNot(HaveOccurred()) podmanTest.setRegistriesConfigEnv(buffer.Bytes()) - err = ioutil.WriteFile(fmt.Sprintf("%s/registry8.conf", tempdir), buffer.Bytes(), 0644) + err = os.WriteFile(fmt.Sprintf("%s/registry8.conf", tempdir), buffer.Bytes(), 0644) Expect(err).ToNot(HaveOccurred()) if IsRemote() { diff --git a/test/e2e/secret_test.go b/test/e2e/secret_test.go index 902f422bd..668a4943c 100644 --- a/test/e2e/secret_test.go +++ b/test/e2e/secret_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -37,7 +36,7 @@ var _ = Describe("Podman secret", func() { It("podman secret create", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "-d", "file", "--driver-opts", "opt1=val", "a", secretFilePath}) @@ -57,7 +56,7 @@ var _ = Describe("Podman secret", func() { It("podman secret create bad name should fail", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "?!", secretFilePath}) @@ -67,7 +66,7 @@ var _ = Describe("Podman secret", func() { It("podman secret inspect", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -83,7 +82,7 @@ var _ = Describe("Podman secret", func() { It("podman secret inspect with --format", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -97,9 +96,26 @@ var _ = Describe("Podman secret", func() { Expect(inspect.OutputToString()).To(Equal(secrID)) }) + It("podman secret inspect with --pretty", func() { + secretFilePath := filepath.Join(podmanTest.TempDir, "secret") + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) + Expect(err).To(BeNil()) + + session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) + session.WaitWithDefaultTimeout() + secrID := session.OutputToString() + Expect(session).Should(Exit(0)) + + inspect := podmanTest.Podman([]string{"secret", "inspect", "--pretty", secrID}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + Expect(inspect.OutputToString()).To(ContainSubstring("Name:")) + Expect(inspect.OutputToString()).To(ContainSubstring(secrID)) + }) + It("podman secret inspect multiple secrets", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -120,18 +136,17 @@ var _ = Describe("Podman secret", func() { It("podman secret inspect bogus", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) inspect := podmanTest.Podman([]string{"secret", "inspect", "bogus"}) inspect.WaitWithDefaultTimeout() Expect(inspect).To(ExitWithError()) - }) It("podman secret ls", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -147,7 +162,7 @@ var _ = Describe("Podman secret", func() { It("podman secret ls --quiet", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) secretName := "a" @@ -177,7 +192,7 @@ var _ = Describe("Podman secret", func() { It("podman secret ls with filters", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) secret1 := "Secret1" @@ -231,7 +246,7 @@ var _ = Describe("Podman secret", func() { It("podman secret ls with Go template", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -247,7 +262,7 @@ var _ = Describe("Podman secret", func() { It("podman secret rm", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -268,7 +283,7 @@ var _ = Describe("Podman secret", func() { It("podman secret rm --all", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -310,4 +325,41 @@ var _ = Describe("Podman secret", func() { Expect(inspect.OutputToString()).To(Equal(secrID)) }) + It("podman secret with labels", func() { + secretFilePath := filepath.Join(podmanTest.TempDir, "secret") + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) + Expect(err).To(BeNil()) + + session := podmanTest.Podman([]string{"secret", "create", "--label", "foo=bar", "a", secretFilePath}) + session.WaitWithDefaultTimeout() + secrID := session.OutputToString() + Expect(session).Should(Exit(0)) + + inspect := podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.Spec.Labels}}", secrID}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + Expect(inspect.OutputToString()).To(ContainSubstring("foo:bar")) + + session = podmanTest.Podman([]string{"secret", "create", "--label", "foo=bar", "--label", "a:b", "b", secretFilePath}) + session.WaitWithDefaultTimeout() + secrID = session.OutputToString() + Expect(session).Should(Exit(0)) + + inspect = podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.Spec.Labels}}", secrID}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + Expect(inspect.OutputToString()).To(ContainSubstring("foo:bar")) + Expect(inspect.OutputToString()).To(ContainSubstring("a:b")) + + session = podmanTest.Podman([]string{"secret", "create", "c", secretFilePath}) + session.WaitWithDefaultTimeout() + secrID = session.OutputToString() + Expect(session).Should(Exit(0)) + + inspect = podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.Spec.Labels}}", secrID}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + Expect(inspect.OutputToString()).To(Equal("map[]")) + + }) }) diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go index f3e8cc015..db6f87ac0 100644 --- a/test/e2e/start_test.go +++ b/test/e2e/start_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "strconv" "strings" @@ -204,7 +203,7 @@ var _ = Describe("Podman start", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) readFirstLine := func(path string) string { - content, err := ioutil.ReadFile(path) + content, err := os.ReadFile(path) Expect(err).To(BeNil()) return strings.Split(string(content), "\n")[0] } diff --git a/test/e2e/stop_test.go b/test/e2e/stop_test.go index 23abb6d92..6f7a67139 100644 --- a/test/e2e/stop_test.go +++ b/test/e2e/stop_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "strings" @@ -276,7 +275,7 @@ var _ = Describe("Podman stop", func() { It("podman stop --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "cid" @@ -300,7 +299,7 @@ var _ = Describe("Podman stop", func() { It("podman stop multiple --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile1 := tmpDir + "cid-1" tmpFile2 := tmpDir + "cid-2" diff --git a/test/e2e/system_connection_test.go b/test/e2e/system_connection_test.go index baa31424b..31cbfe349 100644 --- a/test/e2e/system_connection_test.go +++ b/test/e2e/system_connection_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "net/url" "os" "os/exec" @@ -27,7 +26,7 @@ var _ = Describe("podman system connection", func() { BeforeEach(func() { ConfPath.Value, ConfPath.IsSet = os.LookupEnv("CONTAINERS_CONF") - conf, err := ioutil.TempFile("", "containersconf") + conf, err := os.CreateTemp("", "containersconf") Expect(err).ToNot(HaveOccurred()) os.Setenv("CONTAINERS_CONF", conf.Name()) diff --git a/test/e2e/system_service_test.go b/test/e2e/system_service_test.go index 398290426..adb3cade6 100644 --- a/test/e2e/system_service_test.go +++ b/test/e2e/system_service_test.go @@ -1,7 +1,7 @@ package integration import ( - "io/ioutil" + "io" "net" "net/http" "net/url" @@ -89,7 +89,7 @@ var _ = Describe("podman system service", func() { defer resp.Body.Close() Expect(resp).To(HaveHTTPStatus(http.StatusOK)) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) Expect(err).ShouldNot(HaveOccurred()) Expect(body).ShouldNot(BeEmpty()) diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go index 7b3552cc2..7b79a724d 100644 --- a/test/e2e/systemd_test.go +++ b/test/e2e/systemd_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -51,7 +50,7 @@ WantedBy=default.target SkipIfRootless("rootless can not write to /etc") SkipIfContainerized("test does not have systemd as pid 1") - sysFile := ioutil.WriteFile("/etc/systemd/system/redis.service", []byte(systemdUnitFile), 0644) + sysFile := os.WriteFile("/etc/systemd/system/redis.service", []byte(systemdUnitFile), 0644) Expect(sysFile).To(BeNil()) defer func() { stop := SystemExec("bash", []string{"-c", "systemctl stop redis"}) @@ -137,7 +136,7 @@ RUN mkdir -p /usr/lib/systemd/; touch /usr/lib/systemd/systemd CMD /usr/lib/systemd/systemd`, ALPINE) containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") - err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) + err := os.WriteFile(containerfilePath, []byte(containerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "-t", "systemd", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -167,7 +166,7 @@ CMD /usr/lib/systemd/systemd`, ALPINE) Expect(session).Should(Exit(0)) pidFile := strings.TrimSuffix(session.OutputToString(), "\n") - _, err := ioutil.ReadFile(pidFile) + _, err := os.ReadFile(pidFile) Expect(err).To(BeNil()) }) diff --git a/test/e2e/trust_test.go b/test/e2e/trust_test.go index eee802e43..78b4f1b23 100644 --- a/test/e2e/trust_test.go +++ b/test/e2e/trust_test.go @@ -2,7 +2,6 @@ package integration import ( "encoding/json" - "io/ioutil" "os" "path/filepath" @@ -57,7 +56,7 @@ var _ = Describe("Podman trust", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) var teststruct map[string][]map[string]string - policyContent, err := ioutil.ReadFile(policyJSON) + policyContent, err := os.ReadFile(policyJSON) if err != nil { os.Exit(1) } @@ -111,7 +110,7 @@ var _ = Describe("Podman trust", func() { session := podmanTest.Podman([]string{"image", "trust", "show", "--policypath", filepath.Join(INTEGRATION_ROOT, "test/policy.json"), "--raw"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - contents, err := ioutil.ReadFile(filepath.Join(INTEGRATION_ROOT, "test/policy.json")) + contents, err := os.ReadFile(filepath.Join(INTEGRATION_ROOT, "test/policy.json")) Expect(err).ShouldNot(HaveOccurred()) Expect(session.OutputToString()).To(BeValidJSON()) Expect(string(session.Out.Contents())).To(Equal(string(contents) + "\n")) diff --git a/test/e2e/volume_create_test.go b/test/e2e/volume_create_test.go index 499283cab..5dfa4d0fc 100644 --- a/test/e2e/volume_create_test.go +++ b/test/e2e/volume_create_test.go @@ -162,4 +162,58 @@ var _ = Describe("Podman volume create", func() { Expect(inspectOpts).Should(Exit(0)) Expect(inspectOpts.OutputToString()).To(Equal(optionStrFormatExpect)) }) + + It("image-backed volume basic functionality", func() { + podmanTest.AddImageToRWStore(fedoraMinimal) + volName := "testvol" + volCreate := podmanTest.Podman([]string{"volume", "create", "--driver", "image", "--opt", fmt.Sprintf("image=%s", fedoraMinimal), volName}) + volCreate.WaitWithDefaultTimeout() + Expect(volCreate).Should(Exit(0)) + + runCmd := podmanTest.Podman([]string{"run", "-v", fmt.Sprintf("%s:/test", volName), ALPINE, "cat", "/test/etc/redhat-release"}) + runCmd.WaitWithDefaultTimeout() + Expect(runCmd).Should(Exit(0)) + Expect(runCmd.OutputToString()).To(ContainSubstring("Fedora")) + + rmCmd := podmanTest.Podman([]string{"rmi", "--force", fedoraMinimal}) + rmCmd.WaitWithDefaultTimeout() + Expect(rmCmd).Should(Exit(0)) + + psCmd := podmanTest.Podman([]string{"ps", "-aq"}) + psCmd.WaitWithDefaultTimeout() + Expect(psCmd).Should(Exit(0)) + Expect(psCmd.OutputToString()).To(BeEmpty()) + + volumesCmd := podmanTest.Podman([]string{"volume", "ls", "-q"}) + volumesCmd.WaitWithDefaultTimeout() + Expect(volumesCmd).Should(Exit(0)) + Expect(volumesCmd.OutputToString()).To(Not(ContainSubstring(volName))) + }) + + It("image-backed volume force removal", func() { + podmanTest.AddImageToRWStore(fedoraMinimal) + volName := "testvol" + volCreate := podmanTest.Podman([]string{"volume", "create", "--driver", "image", "--opt", fmt.Sprintf("image=%s", fedoraMinimal), volName}) + volCreate.WaitWithDefaultTimeout() + Expect(volCreate).Should(Exit(0)) + + runCmd := podmanTest.Podman([]string{"run", "-v", fmt.Sprintf("%s:/test", volName), ALPINE, "cat", "/test/etc/redhat-release"}) + runCmd.WaitWithDefaultTimeout() + Expect(runCmd).Should(Exit(0)) + Expect(runCmd.OutputToString()).To(ContainSubstring("Fedora")) + + rmCmd := podmanTest.Podman([]string{"volume", "rm", "--force", volName}) + rmCmd.WaitWithDefaultTimeout() + Expect(rmCmd).Should(Exit(0)) + + psCmd := podmanTest.Podman([]string{"ps", "-aq"}) + psCmd.WaitWithDefaultTimeout() + Expect(psCmd).Should(Exit(0)) + Expect(psCmd.OutputToString()).To(BeEmpty()) + + volumesCmd := podmanTest.Podman([]string{"volume", "ls", "-q"}) + volumesCmd.WaitWithDefaultTimeout() + Expect(volumesCmd).Should(Exit(0)) + Expect(volumesCmd.OutputToString()).To(Not(ContainSubstring(volName))) + }) }) diff --git a/test/e2e/volume_plugin_test.go b/test/e2e/volume_plugin_test.go index 33cdcce5b..00498431e 100644 --- a/test/e2e/volume_plugin_test.go +++ b/test/e2e/volume_plugin_test.go @@ -60,7 +60,8 @@ var _ = Describe("Podman volume plugins", func() { Expect(err).ToNot(HaveOccurred()) // Keep this distinct within tests to avoid multiple tests using the same plugin. - pluginName := "testvol1" + // This one verifies that the "image" plugin uses a volume plugin, not the "image" driver. + pluginName := "image" plugin := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath}) plugin.WaitWithDefaultTimeout() Expect(plugin).Should(Exit(0)) @@ -77,6 +78,12 @@ var _ = Describe("Podman volume plugins", func() { Expect(arrOutput).To(HaveLen(1)) Expect(arrOutput[0]).To(ContainSubstring(volName)) + // Verify this is not an image volume. + inspect := podmanTest.Podman([]string{"volume", "inspect", volName, "--format", "{{.StorageID}}"}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + Expect(inspect.OutputToString()).To(BeEmpty()) + remove := podmanTest.Podman([]string{"volume", "rm", volName}) remove.WaitWithDefaultTimeout() Expect(remove).Should(Exit(0)) diff --git a/test/system/001-basic.bats b/test/system/001-basic.bats index 378edc013..f6b4aa1e8 100644 --- a/test/system/001-basic.bats +++ b/test/system/001-basic.bats @@ -56,14 +56,17 @@ function setup() { @test "podman --context emits reasonable output" { + if ! is_remote; then + skip "only applicable on podman-remote" + fi # All we care about here is that the command passes run_podman --context=default version # This one must fail run_podman 125 --context=swarm version is "$output" \ - "Error: podman does not support swarm, the only --context value allowed is \"default\"" \ - "--context=default or fail" + "Error: failed to resolve active destination: \"swarm\" service destination not found" \ + "--context=swarm should fail" } @test "podman can pull an image" { @@ -212,47 +215,12 @@ See 'podman version --help'" "podman version --remote" run_podman --log-level=warn info assert "$output" !~ " level=" "log-level=warn shows no logs at all" - # Force a warning (local podman only; podman-remote doesn't check versions) - if ! is_remote; then - run_podman --log-level=warn --storage-opt=mount_program=/bin/false info - assert "$output" =~ " level=warning msg=\"Failed to retrieve " \ - "log-level=warn" - - # confirm that default level is "warn", by invoking without --log-level - run_podman --storage-opt=mount_program=/bin/false info - assert "$output" =~ " level=warning msg=\"Failed to retrieve " \ - "default log level includes warning messages" - fi - run_podman --log-level=warning info assert "$output" !~ " level=" "log-level=warning shows no logs at all" run_podman --log-level=error info assert "$output" !~ " level=" "log-level=error shows no logs at all" - # error, fatal, panic: - if is_remote; then - # podman-remote does not grok --runtime; all we can do is test parsing - for level in error fatal panic; do - run_podman --log-level=$level info - assert "$output" !~ " level=" \ - "log-level=$level shows no logs at all" - done - else - # local podman only - run_podman --log-level=error --storage-opt=mount_program=/bin/false --runtime=/bin/false info - assert "$output" =~ " level=error msg=\"Getting info on OCI runtime " \ - "log-level=error shows " - assert "$output" !~ " level=warn" \ - "log-level=error does not show warnings" - - run_podman --log-level=fatal --storage-opt=mount_program=/bin/false --runtime=/bin/false info - assert "$output" !~ " level=" "log-level=fatal shows no logs at all" - - run_podman --log-level=panic --storage-opt=mount_program=/bin/false --runtime=/bin/false info - assert "$output" !~ " level=" "log-level=panic shows no logs at all" - fi - # docker compat run_podman --debug info assert "$output" =~ " level=debug " "podman --debug gives debug output" diff --git a/test/system/030-run.bats b/test/system/030-run.bats index b1ce91d14..8de1625b5 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -3,7 +3,6 @@ load helpers @test "podman run - basic tests" { - skip_if_aarch64 "FIXME: #15074 - fails on aarch64" rand=$(random_string 30) err_no_such_cmd="Error:.*/no/such/command.*[Nn]o such file or directory" @@ -549,11 +548,23 @@ json-file | f # prior to #8623 `podman run` would error out on untagged images with: # Error: both RootfsImageName and RootfsImageID must be set if either is set: invalid argument run_podman untag $IMAGE - run_podman run --rm $imageID ls + run_podman run --rm $randomname $imageID true run_podman tag $imageID $IMAGE } +@test "podman inspect includes image data" { + randomname=$(random_string 30) + + run_podman inspect $IMAGE --format "{{.ID}} {{.Digest}}" + expected="$IMAGE $output" + + run_podman run --name $randomname $IMAGE true + run_podman container inspect $randomname --format "{{.ImageName}} {{.Image}} {{.ImageDigest}}" + is "$output" "$expected" + run_podman rm -f -t0 $randomname +} + @test "Verify /run/.containerenv exist" { # Nonprivileged container: file exists, but must be empty run_podman run --rm $IMAGE stat -c '%s' /run/.containerenv @@ -621,10 +632,15 @@ json-file | f run_podman image mount $IMAGE romount="$output" + randomname=$(random_string 30) # FIXME FIXME FIXME: Remove :O once (if) #14504 is fixed! - run_podman run --rm --rootfs $romount:O echo "Hello world" + run_podman run --name=$randomname --rootfs $romount:O echo "Hello world" is "$output" "Hello world" + run_podman container inspect $randomname --format "{{.ImageDigest}}" + is "$output" "" "Empty image digest for --rootfs container" + + run_podman rm -f -t0 $randomname run_podman image unmount $IMAGE fi } @@ -892,4 +908,45 @@ $IMAGE--c_ok" \ run_podman container rm -f -t 0 c_ok c_fail_no_rm } +@test "podman run --attach stdin prints container ID" { + ctr_name="container-$(random_string 5)" + run_podman run --name $ctr_name --attach stdin $IMAGE echo hello + run_output=$output + run_podman inspect --format "{{.Id}}" $ctr_name + ctr_id=$output + is "$run_output" "$ctr_id" "Did not find container ID in the output" + run_podman rm $ctr_name +} + +# 15895: --privileged + --systemd = hide /dev/ttyNN +@test "podman run --privileged as root with systemd will not mount /dev/tty" { + skip_if_rootless "this test only makes sense as root" + + # First, confirm that we _have_ /dev/ttyNN devices on the host. + # ('skip' would be nicer in some sense... but could hide a regression. + # Fedora, RHEL, Debian, Ubuntu, Gentoo, all have /dev/ttyN, so if + # this ever triggers, it means a real problem we should know about.) + assert "$(ls /dev/tty* | grep -vx /dev/tty)" != "" \ + "Expected at least one /dev/ttyN device on host" + + # Ok now confirm that without --systemd, podman exposes ttyNN devices + run_podman run --rm -d --privileged $IMAGE ./pause + cid="$output" + + run_podman exec $cid sh -c 'ls /dev/tty*' + assert "$output" != "/dev/tty" \ + "ls /dev/tty* without systemd; should have lots of ttyN devices" + run_podman stop -t 0 $cid + + # Actual test for 15895: with --systemd, no ttyN devices are passed through + run_podman run --rm -d --privileged --systemd=always $IMAGE ./pause + cid="$output" + + run_podman exec $cid sh -c 'ls /dev/tty*' + assert "$output" = "/dev/tty" \ + "ls /dev/tty* with --systemd=always: should have no ttyN devices" + + run_podman stop -t 0 $cid +} + # vim: filetype=sh diff --git a/test/system/032-sig-proxy.bats b/test/system/032-sig-proxy.bats new file mode 100644 index 000000000..686df0e1b --- /dev/null +++ b/test/system/032-sig-proxy.bats @@ -0,0 +1,43 @@ +#!/usr/bin/env bats + +load helpers + +@test "podman sigkill" { + $PODMAN run -i --name foo $IMAGE sh -c 'trap "echo BYE;exit 0" INT;echo READY;while :;do sleep 0.1;done' & + local kidpid=$! + + # Wait for container to appear + local timeout=5 + while :;do + sleep 0.5 + run_podman '?' container exists foo + if [[ $status -eq 0 ]]; then + break + fi + timeout=$((timeout - 1)) + if [[ $timeout -eq 0 ]]; then + die "Timed out waiting for container to start" + fi + done + + wait_for_ready foo + + # Signal, and wait for container to exit + kill -INT $kidpid + local timeout=5 + while :;do + sleep 0.5 + run_podman logs foo + if [[ "$output" =~ BYE ]]; then + break + fi + timeout=$((timeout - 1)) + if [[ $timeout -eq 0 ]]; then + die "Timed out waiting for BYE from container" + fi + done + + run_podman rm -f -t0 foo +} + +# vim: filetype=sh diff --git a/test/system/070-build.bats b/test/system/070-build.bats index 87979483e..b392fd8e9 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -246,7 +246,7 @@ EOF # Now test COPY. That should fail. sed -i -e 's/ADD/COPY/' $tmpdir/Dockerfile run_podman 125 build -t copy_url $tmpdir - is "$output" ".*error building at STEP .*: source can't be a URL for COPY" + is "$output" ".* building at STEP .*: source can't be a URL for COPY" } @@ -853,7 +853,7 @@ EOF run_podman 125 build -t build_test --pull-never $tmpdir is "$output" \ - ".*Error: error creating build container: quay.io/libpod/nosuchimage:nosuchtag: image not known" \ + ".*Error: creating build container: quay.io/libpod/nosuchimage:nosuchtag: image not known" \ "--pull-never fails with expected error message" } @@ -988,7 +988,7 @@ COPY ./ ./ COPY subdir ./ EOF run_podman 125 build -t build_test $tmpdir - is "$output" ".*Error: error building at STEP \"COPY subdir ./\"" ".dockerignore was ignored" + is "$output" ".*Error: building at STEP \"COPY subdir ./\"" ".dockerignore was ignored" } @test "podman build .containerignore and .dockerignore test" { diff --git a/test/system/075-exec.bats b/test/system/075-exec.bats index 7dd43c2c3..0a6048b7e 100644 --- a/test/system/075-exec.bats +++ b/test/system/075-exec.bats @@ -6,8 +6,6 @@ load helpers @test "podman exec - basic test" { - skip_if_aarch64 "FIXME: #15074 - fails on aarch64" - rand_filename=$(random_string 20) rand_content=$(random_string 50) diff --git a/test/system/255-auto-update.bats b/test/system/255-auto-update.bats index 76f6b02e8..6f5113779 100644 --- a/test/system/255-auto-update.bats +++ b/test/system/255-auto-update.bats @@ -133,6 +133,26 @@ function _confirm_update() { die "Timed out waiting for $cname to update; old IID=$old_iid" } +@test "podman auto-update - validate input" { + # Fully-qualified image reference is required + run_podman create --label io.containers.autoupdate=registry $IMAGE + run_podman rm -f "$output" + + # Short name does not work + shortname="shortname:latest" + run_podman image tag $IMAGE $shortname + run_podman 125 create --label io.containers.autoupdate=registry $shortname + is "$output" "Error: short name: auto updates require fully-qualified image reference: \"$shortname\"" + + # Requires docker (or no) transport + archive=$PODMAN_TMPDIR/archive.tar + run_podman save -o $archive $IMAGE + run_podman 125 create --label io.containers.autoupdate=registry docker-archive:$archive + is "$output" ".*Error: auto updates require the docker image transport but image is of transport \"docker-archive\"" + + run_podman rmi $shortname +} + # This test can fail in dev. environment because of SELinux. # quick fix: chcon -t container_runtime_exec_t ./bin/podman @test "podman auto-update - label io.containers.autoupdate=image" { diff --git a/test/system/260-sdnotify.bats b/test/system/260-sdnotify.bats index 6c3ef7f3f..c4724d605 100644 --- a/test/system/260-sdnotify.bats +++ b/test/system/260-sdnotify.bats @@ -142,7 +142,6 @@ READY=1" "sdnotify sent MAINPID and READY" # These tests can fail in dev. environment because of SELinux. # quick fix: chcon -t container_runtime_exec_t ./bin/podman @test "sdnotify : container" { - skip_if_aarch64 "FIXME: #15277 sdnotify doesn't work on aarch64" # Sigh... we need to pull a humongous image because it has systemd-notify. # (IMPORTANT: fedora:32 and above silently removed systemd-notify; this # caused CI to hang. That's why we explicitly require fedora:31) @@ -248,8 +247,6 @@ READY=1" "sdnotify sent MAINPID and READY" } @test "sdnotify : play kube - with policies" { - skip_if_aarch64 "FIXME: #15277 sdnotify doesn't work on aarch64" - # Sigh... we need to pull a humongous image because it has systemd-notify. # (IMPORTANT: fedora:32 and above silently removed systemd-notify; this # caused CI to hang. That's why we explicitly require fedora:31) diff --git a/test/system/272-system-connection.bats b/test/system/272-system-connection.bats index e937a7273..402e69736 100644 --- a/test/system/272-system-connection.bats +++ b/test/system/272-system-connection.bats @@ -56,8 +56,22 @@ function _run_podman_remote() { c1="c1_$(random_string 15)" c2="c2_$(random_string 15)" - run_podman system connection add $c1 tcp://localhost:12345 - run_podman system connection add --default $c2 tcp://localhost:54321 + run_podman system connection add $c1 tcp://localhost:12345 + run_podman context create --docker "host=tcp://localhost:54321" $c2 + run_podman system connection ls + is "$output" \ + ".*$c1[ ]\+tcp://localhost:12345[ ]\+true +$c2[ ]\+tcp://localhost:54321[ ]\+false" \ + "system connection ls" + run_podman system connection ls -q + is "$(echo $(sort <<<$output))" \ + "$c1 $c2" \ + "system connection ls -q should show two names" + run_podman context ls -q + is "$(echo $(sort <<<$output))" \ + "$c1 $c2" \ + "context ls -q should show two names" + run_podman context use $c2 run_podman system connection ls is "$output" \ ".*$c1[ ]\+tcp://localhost:12345[ ]\+false @@ -66,11 +80,11 @@ $c2[ ]\+tcp://localhost:54321[ ]\+true" \ # Remove default connection; the remaining one should still not be default run_podman system connection rm $c2 - run_podman system connection ls + run_podman context ls is "$output" ".*$c1[ ]\+tcp://localhost:12345[ ]\+false" \ "system connection ls (after removing default connection)" - run_podman system connection rm $c1 + run_podman context rm $c1 } # Test tcp socket; requires starting a local server diff --git a/test/system/410-selinux.bats b/test/system/410-selinux.bats index cc86f282a..52c428884 100644 --- a/test/system/410-selinux.bats +++ b/test/system/410-selinux.bats @@ -39,12 +39,10 @@ function check_label() { } @test "podman selinux: container with label=disable" { - skip_if_aarch64 "FIXME: #15074 - fails on aarch64" check_label "--security-opt label=disable" "spc_t" } @test "podman selinux: privileged container" { - skip_if_aarch64 "FIXME: #15074 - fails on aarch64" check_label "--privileged --userns=host" "spc_t" } @@ -65,7 +63,6 @@ function check_label() { } @test "podman selinux: pid=host" { - skip_if_aarch64 "FIXME: #15074 - fails on aarch64" # FIXME this test fails when run rootless with runc: # Error: container_linux.go:367: starting container process caused: process_linux.go:495: container init caused: readonly path /proc/asound: operation not permitted: OCI permission denied if is_rootless; then diff --git a/test/system/700-play.bats b/test/system/700-play.bats index bad9544ff..5f3eb1ef2 100644 --- a/test/system/700-play.bats +++ b/test/system/700-play.bats @@ -165,8 +165,14 @@ EOF TESTDIR=$PODMAN_TMPDIR/testdir mkdir -p $TESTDIR echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml - run_podman 125 kube play --network host $PODMAN_TMPDIR/test.yaml - is "$output" ".*invalid value passed to --network: bridge or host networking must be configured in YAML" "podman plan-network should fail with --network host" + run_podman kube play --network host $PODMAN_TMPDIR/test.yaml + is "$output" "Pod:.*" "podman kube play should work with --network host" + + run_podman pod inspect --format "{{.InfraConfig.HostNetwork}}" test_pod + is "$output" "true" ".InfraConfig.HostNetwork" + run_podman stop -a -t 0 + run_podman pod rm -t 0 -f test_pod + run_podman kube play --network slirp4netns:port_handler=slirp4netns $PODMAN_TMPDIR/test.yaml run_podman pod inspect --format {{.InfraContainerID}} "${lines[1]}" infraID="$output" @@ -386,3 +392,27 @@ status: {} run_podman rm -a -f run_podman rm -f -t0 myyaml } + +@test "podman kube play - hostport" { + HOST_PORT=$(random_free_port) + echo " +apiVersion: v1 +kind: Pod +metadata: + labels: + app: test + name: test_pod +spec: + containers: + - name: server + image: $IMAGE + ports: + - name: hostp + containerPort: $HOST_PORT +" > $PODMAN_TMPDIR/testpod.yaml + + run_podman kube play $PODMAN_TMPDIR/testpod.yaml + run_podman pod inspect test_pod --format "{{.InfraConfig.PortBindings}}" + assert "$output" = "map[$HOST_PORT/tcp:[{ $HOST_PORT}]]" + run_podman kube down $PODMAN_TMPDIR/testpod.yaml +} diff --git a/test/testvol/main.go b/test/testvol/main.go index ab26e2df0..cbbf7e4b0 100644 --- a/test/testvol/main.go +++ b/test/testvol/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io/ioutil" "os" "path/filepath" "sync" @@ -78,7 +77,7 @@ func startServer(socketPath string) error { logrus.Debugf("Starting server...") if config.path == "" { - path, err := ioutil.TempDir("", "test_volume_plugin") + path, err := os.MkdirTemp("", "test_volume_plugin") if err != nil { return fmt.Errorf("getting directory for plugin: %w", err) } diff --git a/test/utils/common_function_test.go b/test/utils/common_function_test.go index 7092e40a1..724b2deb2 100644 --- a/test/utils/common_function_test.go +++ b/test/utils/common_function_test.go @@ -3,7 +3,7 @@ package utils_test import ( "encoding/json" "fmt" - "io/ioutil" + "io" "os" "reflect" "strings" @@ -113,7 +113,7 @@ var _ = Describe("Common functions test", func() { Expect(err).To(BeNil(), "Can not find the JSON file after we write it.") defer read.Close() - bytes, err := ioutil.ReadAll(read) + bytes, err := io.ReadAll(read) Expect(err).ToNot(HaveOccurred()) err = json.Unmarshal(bytes, compareData) Expect(err).ToNot(HaveOccurred()) diff --git a/test/utils/utils.go b/test/utils/utils.go index 19b287ae1..19b67dfa7 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -4,7 +4,6 @@ import ( "bufio" "encoding/json" "fmt" - "io/ioutil" "math/rand" "os" "os/exec" @@ -100,7 +99,7 @@ func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string } if timeDir := os.Getenv(EnvTimeDir); timeDir != "" { - timeFile, err := ioutil.TempFile(timeDir, ".time") + timeFile, err := os.CreateTemp(timeDir, ".time") if err != nil { Fail(fmt.Sprintf("Error creating time file: %v", err)) } @@ -374,7 +373,7 @@ func (s *PodmanSession) WaitWithTimeout(timeout int) { // CreateTempDirInTempDir create a temp dir with prefix podman_test func CreateTempDirInTempDir() (string, error) { - return ioutil.TempDir("", "podman_test") + return os.MkdirTemp("", "podman_test") } // SystemExec is used to exec a system command to check its exit code or output @@ -497,7 +496,7 @@ func WriteJSONFile(data []byte, filePath string) error { if err != nil { return err } - return ioutil.WriteFile(filePath, formatJSON, 0644) + return os.WriteFile(filePath, formatJSON, 0644) } // Containerized check the podman command run inside container @@ -506,7 +505,7 @@ func Containerized() bool { if container != "" { return true } - b, err := ioutil.ReadFile(ProcessOneCgroupPath) + b, err := os.ReadFile(ProcessOneCgroupPath) if err != nil { // shrug, if we cannot read that file, return false return false diff --git a/utils/utils.go b/utils/utils.go index 4d41ce5f8..5fb3695ce 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "fmt" "io" - "io/ioutil" "os" "os/exec" "strconv" @@ -114,7 +113,7 @@ var ( // RunsOnSystemd returns whether the system is using systemd func RunsOnSystemd() bool { runsOnSystemdOnce.Do(func() { - initCommand, err := ioutil.ReadFile("/proc/1/comm") + initCommand, err := os.ReadFile("/proc/1/comm") // On errors, default to systemd runsOnSystemd = err != nil || strings.TrimRight(string(initCommand), "\n") == "systemd" }) @@ -122,7 +121,7 @@ func RunsOnSystemd() bool { } func moveProcessPIDFileToScope(pidPath, slice, scope string) error { - data, err := ioutil.ReadFile(pidPath) + data, err := os.ReadFile(pidPath) if err != nil { // do not raise an error if the file doesn't exist if os.IsNotExist(err) { diff --git a/utils/utils_supported.go b/utils/utils_supported.go index d7d47b2bc..8844d46fd 100644 --- a/utils/utils_supported.go +++ b/utils/utils_supported.go @@ -8,7 +8,6 @@ import ( "bytes" "context" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -181,7 +180,7 @@ func moveUnderCgroup(cgroup, subtree string, processes []uint32) error { } } } else { - processesData, err := ioutil.ReadFile(filepath.Join(cgroupRoot, parts[2], "cgroup.procs")) + processesData, err := os.ReadFile(filepath.Join(cgroupRoot, parts[2], "cgroup.procs")) if err != nil { return err } diff --git a/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_unix.go b/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_unix.go new file mode 100644 index 000000000..0ee5fb86f --- /dev/null +++ b/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_unix.go @@ -0,0 +1,26 @@ +//go:build !windows +// +build !windows + +/* + Copyright © 2021 The CDI Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package cdi + +import "syscall" + +func osSync() { + syscall.Sync() +} diff --git a/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_windows.go b/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_windows.go new file mode 100644 index 000000000..c6dabf5fa --- /dev/null +++ b/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_windows.go @@ -0,0 +1,22 @@ +//go:build windows +// +build windows + +/* + Copyright © 2021 The CDI Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package cdi + +func osSync() {} diff --git a/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits.go b/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits.go index 1295f75e9..9fcecf849 100644 --- a/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits.go +++ b/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits.go @@ -27,8 +27,6 @@ import ( "github.com/container-orchestrated-devices/container-device-interface/specs-go" oci "github.com/opencontainers/runtime-spec/specs-go" ocigen "github.com/opencontainers/runtime-tools/generate" - - runc "github.com/opencontainers/runc/libcontainer/devices" ) const ( @@ -289,37 +287,6 @@ func ensureOCIHooks(spec *oci.Spec) { } } -// fillMissingInfo fills in missing mandatory attributes from the host device. -func (d *DeviceNode) fillMissingInfo() error { - if d.HostPath == "" { - d.HostPath = d.Path - } - - if d.Type != "" && (d.Major != 0 || d.Type == "p") { - return nil - } - - hostDev, err := runc.DeviceFromPath(d.HostPath, "rwm") - if err != nil { - return errors.Wrapf(err, "failed to stat CDI host device %q", d.HostPath) - } - - if d.Type == "" { - d.Type = string(hostDev.Type) - } else { - if d.Type != string(hostDev.Type) { - return errors.Errorf("CDI device (%q, %q), host type mismatch (%s, %s)", - d.Path, d.HostPath, d.Type, string(hostDev.Type)) - } - } - if d.Major == 0 && d.Type != "p" { - d.Major = hostDev.Major - d.Minor = hostDev.Minor - } - - return nil -} - // sortMounts sorts the mounts in the given OCI Spec. func sortMounts(specgen *ocigen.Generator) { mounts := specgen.Mounts() diff --git a/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_unix.go b/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_unix.go new file mode 100644 index 000000000..5d7ebcb55 --- /dev/null +++ b/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_unix.go @@ -0,0 +1,56 @@ +//go:build !windows +// +build !windows + +/* + Copyright © 2021 The CDI Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package cdi + +import ( + runc "github.com/opencontainers/runc/libcontainer/devices" + "github.com/pkg/errors" +) + +// fillMissingInfo fills in missing mandatory attributes from the host device. +func (d *DeviceNode) fillMissingInfo() error { + if d.HostPath == "" { + d.HostPath = d.Path + } + + if d.Type != "" && (d.Major != 0 || d.Type == "p") { + return nil + } + + hostDev, err := runc.DeviceFromPath(d.HostPath, "rwm") + if err != nil { + return errors.Wrapf(err, "failed to stat CDI host device %q", d.HostPath) + } + + if d.Type == "" { + d.Type = string(hostDev.Type) + } else { + if d.Type != string(hostDev.Type) { + return errors.Errorf("CDI device (%q, %q), host type mismatch (%s, %s)", + d.Path, d.HostPath, d.Type, string(hostDev.Type)) + } + } + if d.Major == 0 && d.Type != "p" { + d.Major = hostDev.Major + d.Minor = hostDev.Minor + } + + return nil +} diff --git a/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_windows.go b/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_windows.go new file mode 100644 index 000000000..fd91afa92 --- /dev/null +++ b/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_windows.go @@ -0,0 +1,27 @@ +//go:build windows +// +build windows + +/* + Copyright © 2021 The CDI Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package cdi + +import "fmt" + +// fillMissingInfo fills in missing mandatory attributes from the host device. +func (d *DeviceNode) fillMissingInfo() error { + return fmt.Errorf("unimplemented") +} diff --git a/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec.go b/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec.go index 9a5d451c9..3dfbab2f0 100644 --- a/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec.go +++ b/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec.go @@ -21,6 +21,7 @@ import ( "io/ioutil" "os" "path/filepath" + "sync" oci "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -41,6 +42,7 @@ var ( // Externally set CDI Spec validation function. specValidator func(*cdi.Spec) error + validatorLock sync.RWMutex ) // Spec represents a single CDI Spec. It is usually loaded from a @@ -249,11 +251,16 @@ func ParseSpec(data []byte) (*cdi.Spec, error) { // is used for extra CDI Spec content validation whenever a Spec file // loaded (using ReadSpec() or NewSpec()) or written (Spec.Write()). func SetSpecValidator(fn func(*cdi.Spec) error) { + validatorLock.Lock() + defer validatorLock.Unlock() specValidator = fn } // validateSpec validates the Spec using the extneral validator. func validateSpec(raw *cdi.Spec) error { + validatorLock.RLock() + defer validatorLock.RUnlock() + if specValidator == nil { return nil } diff --git a/vendor/github.com/containers/buildah/add.go b/vendor/github.com/containers/buildah/add.go index 1f820ea55..987313e18 100644 --- a/vendor/github.com/containers/buildah/add.go +++ b/vendor/github.com/containers/buildah/add.go @@ -105,7 +105,7 @@ func getURL(src string, chown *idtools.IDPair, mountpoint, renameTarget string, if lastModified != "" { d, err := time.Parse(time.RFC1123, lastModified) if err != nil { - return fmt.Errorf("error parsing last-modified time: %w", err) + return fmt.Errorf("parsing last-modified time: %w", err) } date = d } @@ -117,17 +117,17 @@ func getURL(src string, chown *idtools.IDPair, mountpoint, renameTarget string, // we can figure out how much content there is. f, err := ioutil.TempFile(mountpoint, "download") if err != nil { - return fmt.Errorf("error creating temporary file to hold %q: %w", src, err) + return fmt.Errorf("creating temporary file to hold %q: %w", src, err) } defer os.Remove(f.Name()) defer f.Close() size, err = io.Copy(f, response.Body) if err != nil { - return fmt.Errorf("error writing %q to temporary file %q: %w", src, f.Name(), err) + return fmt.Errorf("writing %q to temporary file %q: %w", src, f.Name(), err) } _, err = f.Seek(0, io.SeekStart) if err != nil { - return fmt.Errorf("error setting up to read %q from temporary file %q: %w", src, f.Name(), err) + return fmt.Errorf("setting up to read %q from temporary file %q: %w", src, f.Name(), err) } responseBody = f } @@ -155,11 +155,11 @@ func getURL(src string, chown *idtools.IDPair, mountpoint, renameTarget string, } err = tw.WriteHeader(&hdr) if err != nil { - return fmt.Errorf("error writing header: %w", err) + return fmt.Errorf("writing header: %w", err) } if _, err := io.Copy(tw, responseBody); err != nil { - return fmt.Errorf("error writing content from %q to tar stream: %w", src, err) + return fmt.Errorf("writing content from %q to tar stream: %w", src, err) } return nil @@ -208,13 +208,13 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption contextDir = string(os.PathSeparator) currentDir, err = os.Getwd() if err != nil { - return fmt.Errorf("error determining current working directory: %w", err) + return fmt.Errorf("determining current working directory: %w", err) } } else { if !filepath.IsAbs(options.ContextDir) { contextDir, err = filepath.Abs(options.ContextDir) if err != nil { - return fmt.Errorf("error converting context directory path %q to an absolute path: %w", options.ContextDir, err) + return fmt.Errorf("converting context directory path %q to an absolute path: %w", options.ContextDir, err) } } } @@ -273,14 +273,14 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption if options.Chown != "" { userUID, userGID, err = b.userForCopy(mountPoint, options.Chown) if err != nil { - return fmt.Errorf("error looking up UID/GID for %q: %w", options.Chown, err) + return fmt.Errorf("looking up UID/GID for %q: %w", options.Chown, err) } } var chmodDirsFiles *os.FileMode if options.Chmod != "" { p, err := strconv.ParseUint(options.Chmod, 8, 32) if err != nil { - return fmt.Errorf("error parsing chmod %q: %w", options.Chmod, err) + return fmt.Errorf("parsing chmod %q: %w", options.Chmod, err) } perm := os.FileMode(p) chmodDirsFiles = &perm @@ -332,7 +332,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption } destStats, err := copier.Stat(mountPoint, filepath.Join(mountPoint, b.WorkDir()), statOptions, []string{extractDirectory}) if err != nil { - return fmt.Errorf("error checking on destination %v: %w", extractDirectory, err) + return fmt.Errorf("checking on destination %v: %w", extractDirectory, err) } if (len(destStats) == 0 || len(destStats[0].Globbed) == 0) && !destMustBeDirectory && destCanBeFile { // destination doesn't exist - extract to parent and rename the incoming file to the destination's name @@ -357,7 +357,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption pm, err := fileutils.NewPatternMatcher(options.Excludes) if err != nil { - return fmt.Errorf("error processing excludes list %v: %w", options.Excludes, err) + return fmt.Errorf("processing excludes list %v: %w", options.Excludes, err) } // Make sure that, if it's a symlink, we'll chroot to the target of the link; @@ -365,7 +365,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption evalOptions := copier.EvalOptions{} evaluated, err := copier.Eval(mountPoint, extractDirectory, evalOptions) if err != nil { - return fmt.Errorf("error checking on destination %v: %w", extractDirectory, err) + return fmt.Errorf("checking on destination %v: %w", extractDirectory, err) } extractDirectory = evaluated @@ -383,7 +383,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption ChownNew: chownDirs, } if err := copier.Mkdir(mountPoint, extractDirectory, mkdirOptions); err != nil { - return fmt.Errorf("error ensuring target directory exists: %w", err) + return fmt.Errorf("ensuring target directory exists: %w", err) } // Copy each source in turn. @@ -427,10 +427,10 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption }() wg.Wait() if getErr != nil { - getErr = fmt.Errorf("error reading %q: %w", src, getErr) + getErr = fmt.Errorf("reading %q: %w", src, getErr) } if putErr != nil { - putErr = fmt.Errorf("error storing %q: %w", src, putErr) + putErr = fmt.Errorf("storing %q: %w", src, putErr) } multiErr = multierror.Append(getErr, putErr) if multiErr != nil && multiErr.ErrorOrNil() != nil { @@ -459,7 +459,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption for _, glob := range localSourceStat.Globbed { rel, err := filepath.Rel(contextDir, glob) if err != nil { - return fmt.Errorf("error computing path of %q relative to %q: %w", glob, contextDir, err) + return fmt.Errorf("computing path of %q relative to %q: %w", glob, contextDir, err) } if strings.HasPrefix(rel, ".."+string(os.PathSeparator)) { return fmt.Errorf("possible escaping context directory error: %q is outside of %q", glob, contextDir) @@ -468,7 +468,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption if rel != "." { excluded, err := pm.Matches(filepath.ToSlash(rel)) // nolint:staticcheck if err != nil { - return fmt.Errorf("error checking if %q(%q) is excluded: %w", glob, rel, err) + return fmt.Errorf("checking if %q(%q) is excluded: %w", glob, rel, err) } if excluded { // non-directories that are excluded are excluded, no question, but @@ -562,16 +562,16 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption }() wg.Wait() if getErr != nil { - getErr = fmt.Errorf("error reading %q: %w", src, getErr) + getErr = fmt.Errorf("reading %q: %w", src, getErr) } if closeErr != nil { - closeErr = fmt.Errorf("error closing %q: %w", src, closeErr) + closeErr = fmt.Errorf("closing %q: %w", src, closeErr) } if renameErr != nil { - renameErr = fmt.Errorf("error renaming %q: %w", src, renameErr) + renameErr = fmt.Errorf("renaming %q: %w", src, renameErr) } if putErr != nil { - putErr = fmt.Errorf("error storing %q: %w", src, putErr) + putErr = fmt.Errorf("storing %q: %w", src, putErr) } multiErr = multierror.Append(getErr, closeErr, renameErr, putErr) if multiErr != nil && multiErr.ErrorOrNil() != nil { diff --git a/vendor/github.com/containers/buildah/bind/mount.go b/vendor/github.com/containers/buildah/bind/mount.go index 212be3ca8..213b1f64d 100644 --- a/vendor/github.com/containers/buildah/bind/mount.go +++ b/vendor/github.com/containers/buildah/bind/mount.go @@ -35,22 +35,22 @@ func SetupIntermediateMountNamespace(spec *specs.Spec, bundlePath string) (unmou // Create a new mount namespace in which to do the things we're doing. if err := unix.Unshare(unix.CLONE_NEWNS); err != nil { - return nil, fmt.Errorf("error creating new mount namespace for %v: %w", spec.Process.Args, err) + return nil, fmt.Errorf("creating new mount namespace for %v: %w", spec.Process.Args, err) } // Make all of our mounts private to our namespace. if err := mount.MakeRPrivate("/"); err != nil { - return nil, fmt.Errorf("error making mounts private to mount namespace for %v: %w", spec.Process.Args, err) + return nil, fmt.Errorf("making mounts private to mount namespace for %v: %w", spec.Process.Args, err) } // Make sure the bundle directory is searchable. We created it with // TempDir(), so it should have started with permissions set to 0700. info, err := os.Stat(bundlePath) if err != nil { - return nil, fmt.Errorf("error checking permissions on %q: %w", bundlePath, err) + return nil, fmt.Errorf("checking permissions on %q: %w", bundlePath, err) } if err = os.Chmod(bundlePath, info.Mode()|0111); err != nil { - return nil, fmt.Errorf("error loosening permissions on %q: %w", bundlePath, err) + return nil, fmt.Errorf("loosening permissions on %q: %w", bundlePath, err) } // Figure out who needs to be able to reach these bind mounts in order @@ -117,23 +117,23 @@ func SetupIntermediateMountNamespace(spec *specs.Spec, bundlePath string) (unmou // access. mnt := filepath.Join(bundlePath, "mnt") if err = idtools.MkdirAndChown(mnt, 0100, idtools.IDPair{UID: int(rootUID), GID: int(rootGID)}); err != nil { - return unmountAll, fmt.Errorf("error creating %q owned by the container's root user: %w", mnt, err) + return unmountAll, fmt.Errorf("creating %q owned by the container's root user: %w", mnt, err) } // Make that directory private, and add it to the list of locations we // unmount at cleanup time. if err = mount.MakeRPrivate(mnt); err != nil { - return unmountAll, fmt.Errorf("error marking filesystem at %q as private: %w", mnt, err) + return unmountAll, fmt.Errorf("marking filesystem at %q as private: %w", mnt, err) } unmount = append([]string{mnt}, unmount...) // Create a bind mount for the root filesystem and add it to the list. rootfs := filepath.Join(mnt, "rootfs") if err = os.Mkdir(rootfs, 0000); err != nil { - return unmountAll, fmt.Errorf("error creating directory %q: %w", rootfs, err) + return unmountAll, fmt.Errorf("creating directory %q: %w", rootfs, err) } if err = unix.Mount(rootPath, rootfs, "", unix.MS_BIND|unix.MS_REC|unix.MS_PRIVATE, ""); err != nil { - return unmountAll, fmt.Errorf("error bind mounting root filesystem from %q to %q: %w", rootPath, rootfs, err) + return unmountAll, fmt.Errorf("bind mounting root filesystem from %q to %q: %w", rootPath, rootfs, err) } logrus.Debugf("bind mounted %q to %q", rootPath, rootfs) unmount = append([]string{rootfs}, unmount...) @@ -154,28 +154,28 @@ func SetupIntermediateMountNamespace(spec *specs.Spec, bundlePath string) (unmou logrus.Warnf("couldn't find %q on host to bind mount into container", spec.Mounts[i].Source) continue } - return unmountAll, fmt.Errorf("error checking if %q is a directory: %w", spec.Mounts[i].Source, err) + return unmountAll, fmt.Errorf("checking if %q is a directory: %w", spec.Mounts[i].Source, err) } stage := filepath.Join(mnt, fmt.Sprintf("buildah-bind-target-%d", i)) if info.IsDir() { // If the source is a directory, make one to use as the // mount target. if err = os.Mkdir(stage, 0000); err != nil { - return unmountAll, fmt.Errorf("error creating directory %q: %w", stage, err) + return unmountAll, fmt.Errorf("creating directory %q: %w", stage, err) } } else { // If the source is not a directory, create an empty // file to use as the mount target. file, err := os.OpenFile(stage, os.O_WRONLY|os.O_CREATE, 0000) if err != nil { - return unmountAll, fmt.Errorf("error creating file %q: %w", stage, err) + return unmountAll, fmt.Errorf("creating file %q: %w", stage, err) } file.Close() } // Bind mount the source from wherever it is to a place where // we know the runtime helper will be able to get to it... if err = unix.Mount(spec.Mounts[i].Source, stage, "", unix.MS_BIND|unix.MS_REC|unix.MS_PRIVATE, ""); err != nil { - return unmountAll, fmt.Errorf("error bind mounting bind object from %q to %q: %w", spec.Mounts[i].Source, stage, err) + return unmountAll, fmt.Errorf("bind mounting bind object from %q to %q: %w", spec.Mounts[i].Source, stage, err) } logrus.Debugf("bind mounted %q to %q", spec.Mounts[i].Source, stage) spec.Mounts[i].Source = stage @@ -209,7 +209,7 @@ func leaveBindMountAlone(mount specs.Mount) bool { func UnmountMountpoints(mountpoint string, mountpointsToRemove []string) error { mounts, err := mount.GetMounts() if err != nil { - return fmt.Errorf("error retrieving list of mounts: %w", err) + return fmt.Errorf("retrieving list of mounts: %w", err) } // getChildren returns the list of mount IDs that hang off of the // specified ID. @@ -273,7 +273,7 @@ func UnmountMountpoints(mountpoint string, mountpointsToRemove []string) error { logrus.Debugf("mountpoint %q is not present(?), skipping", mount.Mountpoint) continue } - return fmt.Errorf("error checking if %q is mounted: %w", mount.Mountpoint, err) + return fmt.Errorf("checking if %q is mounted: %w", mount.Mountpoint, err) } if uint64(mount.Major) != uint64(st.Dev) || uint64(mount.Minor) != uint64(st.Dev) { //nolint:unconvert // (required for some OS/arch combinations) logrus.Debugf("%q is apparently not really mounted, skipping", mount.Mountpoint) @@ -296,7 +296,7 @@ func UnmountMountpoints(mountpoint string, mountpointsToRemove []string) error { // if we're also supposed to remove this thing, do that, too if cutil.StringInSlice(mount.Mountpoint, mountpointsToRemove) { if err := os.Remove(mount.Mountpoint); err != nil { - return fmt.Errorf("error removing %q: %w", mount.Mountpoint, err) + return fmt.Errorf("removing %q: %w", mount.Mountpoint, err) } } } diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go index 41f1ba311..3802a727f 100644 --- a/vendor/github.com/containers/buildah/buildah.go +++ b/vendor/github.com/containers/buildah/buildah.go @@ -408,7 +408,7 @@ func OpenBuilder(store storage.Store, container string) (*Builder, error) { } b := &Builder{} if err = json.Unmarshal(buildstate, &b); err != nil { - return nil, fmt.Errorf("error parsing %q, read from %q: %w", string(buildstate), filepath.Join(cdir, stateFile), err) + return nil, fmt.Errorf("parsing %q, read from %q: %w", string(buildstate), filepath.Join(cdir, stateFile), err) } if b.Type != containerType { return nil, fmt.Errorf("container %q is not a %s container (is a %q container)", container, define.Package, b.Type) @@ -484,7 +484,7 @@ func OpenAllBuilders(store storage.Store) (builders []*Builder, err error) { buildstate, err := ioutil.ReadFile(filepath.Join(cdir, stateFile)) if err != nil { if errors.Is(err, os.ErrNotExist) { - logrus.Debugf("error reading %q: %v, ignoring container %q", filepath.Join(cdir, stateFile), err, container.ID) + logrus.Debugf("%v, ignoring container %q", err, container.ID) continue } return nil, err @@ -520,7 +520,7 @@ func (b *Builder) Save() error { return err } if err = ioutils.AtomicWriteFile(filepath.Join(cdir, stateFile), buildstate, 0600); err != nil { - return fmt.Errorf("error saving builder state to %q: %w", filepath.Join(cdir, stateFile), err) + return fmt.Errorf("saving builder state to %q: %w", filepath.Join(cdir, stateFile), err) } return nil } diff --git a/vendor/github.com/containers/buildah/chroot/pty_ptmx.go b/vendor/github.com/containers/buildah/chroot/pty_ptmx.go index e613c7571..b1ba96bc9 100644 --- a/vendor/github.com/containers/buildah/chroot/pty_ptmx.go +++ b/vendor/github.com/containers/buildah/chroot/pty_ptmx.go @@ -18,28 +18,28 @@ func getPtyDescriptors() (int, int, error) { // Create a pseudo-terminal -- open a copy of the master side. controlFd, err := unix.Open("/dev/ptmx", os.O_RDWR, 0600) if err != nil { - return -1, -1, fmt.Errorf("error opening PTY master using /dev/ptmx: %v", err) + return -1, -1, fmt.Errorf("opening PTY master using /dev/ptmx: %v", err) } // Set the kernel's lock to "unlocked". locked := 0 if result, _, err := unix.Syscall(unix.SYS_IOCTL, uintptr(controlFd), unix.TIOCSPTLCK, uintptr(unsafe.Pointer(&locked))); int(result) == -1 { - return -1, -1, fmt.Errorf("error unlocking PTY descriptor: %v", err) + return -1, -1, fmt.Errorf("unlocking PTY descriptor: %v", err) } // Get a handle for the other end. ptyFd, _, err := unix.Syscall(unix.SYS_IOCTL, uintptr(controlFd), unix.TIOCGPTPEER, unix.O_RDWR|unix.O_NOCTTY) if int(ptyFd) == -1 { if errno, isErrno := err.(syscall.Errno); !isErrno || (errno != syscall.EINVAL && errno != syscall.ENOTTY) { - return -1, -1, fmt.Errorf("error getting PTY descriptor: %v", err) + return -1, -1, fmt.Errorf("getting PTY descriptor: %v", err) } // EINVAL means the kernel's too old to understand TIOCGPTPEER. Try TIOCGPTN. ptyN, err := unix.IoctlGetInt(controlFd, unix.TIOCGPTN) if err != nil { - return -1, -1, fmt.Errorf("error getting PTY number: %v", err) + return -1, -1, fmt.Errorf("getting PTY number: %v", err) } ptyName := fmt.Sprintf("/dev/pts/%d", ptyN) fd, err := unix.Open(ptyName, unix.O_RDWR|unix.O_NOCTTY, 0620) if err != nil { - return -1, -1, fmt.Errorf("error opening PTY %q: %v", ptyName, err) + return -1, -1, fmt.Errorf("opening PTY %q: %v", ptyName, err) } ptyFd = uintptr(fd) } diff --git a/vendor/github.com/containers/buildah/chroot/run_common.go b/vendor/github.com/containers/buildah/chroot/run_common.go index 34952e59f..040b68286 100644 --- a/vendor/github.com/containers/buildah/chroot/run_common.go +++ b/vendor/github.com/containers/buildah/chroot/run_common.go @@ -74,7 +74,7 @@ func RunUsingChroot(spec *specs.Spec, bundlePath, homeDir string, stdin io.Reade return err } if err = ioutils.AtomicWriteFile(filepath.Join(bundlePath, "config.json"), specbytes, 0600); err != nil { - return fmt.Errorf("error storing runtime configuration: %w", err) + return fmt.Errorf("storing runtime configuration: %w", err) } logrus.Debugf("config = %v", string(specbytes)) @@ -92,14 +92,14 @@ func RunUsingChroot(spec *specs.Spec, bundlePath, homeDir string, stdin io.Reade // Create a pipe for passing configuration down to the next process. preader, pwriter, err := os.Pipe() if err != nil { - return fmt.Errorf("error creating configuration pipe: %w", err) + return fmt.Errorf("creating configuration pipe: %w", err) } config, conferr := json.Marshal(runUsingChrootSubprocOptions{ Spec: spec, BundlePath: bundlePath, }) if conferr != nil { - return fmt.Errorf("error encoding configuration for %q: %w", runUsingChrootCommand, conferr) + return fmt.Errorf("encoding configuration for %q: %w", runUsingChrootCommand, conferr) } // Set our terminal's mode to raw, to pass handling of special @@ -488,7 +488,7 @@ func runUsingChroot(spec *specs.Spec, bundlePath string, ctty *os.File, stdin io // Create a pipe for passing configuration down to the next process. preader, pwriter, err := os.Pipe() if err != nil { - return 1, fmt.Errorf("error creating configuration pipe: %w", err) + return 1, fmt.Errorf("creating configuration pipe: %w", err) } config, conferr := json.Marshal(runUsingChrootExecSubprocOptions{ Spec: spec, @@ -514,7 +514,7 @@ func runUsingChroot(spec *specs.Spec, bundlePath string, ctty *os.File, stdin io } cmd.ExtraFiles = append([]*os.File{preader}, cmd.ExtraFiles...) if err := setPlatformUnshareOptions(spec, cmd); err != nil { - return 1, fmt.Errorf("error setting platform unshare options: %w", err) + return 1, fmt.Errorf("setting platform unshare options: %w", err) } interrupted := make(chan os.Signal, 100) @@ -778,7 +778,7 @@ func parseRlimits(spec *specs.Spec) (map[int]unix.Rlimit, error) { for _, limit := range spec.Process.Rlimits { resource, recognized := rlimitsMap[strings.ToUpper(limit.Type)] if !recognized { - return nil, fmt.Errorf("error parsing limit type %q", limit.Type) + return nil, fmt.Errorf("parsing limit type %q", limit.Type) } parsed[resource] = makeRlimit(limit) } @@ -795,7 +795,7 @@ func setRlimits(spec *specs.Spec, onlyLower, onlyRaise bool) error { for resource, desired := range limits { var current unix.Rlimit if err := unix.Getrlimit(resource, ¤t); err != nil { - return fmt.Errorf("error reading %q limit: %w", rlimitsReverseMap[resource], err) + return fmt.Errorf("reading %q limit: %w", rlimitsReverseMap[resource], err) } if desired.Max > current.Max && onlyLower { // this would raise a hard limit, and we're only here to lower them @@ -806,7 +806,7 @@ func setRlimits(spec *specs.Spec, onlyLower, onlyRaise bool) error { continue } if err := unix.Setrlimit(resource, &desired); err != nil { - return fmt.Errorf("error setting %q limit to soft=%d,hard=%d (was soft=%d,hard=%d): %w", rlimitsReverseMap[resource], desired.Cur, desired.Max, current.Cur, current.Max, err) + return fmt.Errorf("setting %q limit to soft=%d,hard=%d (was soft=%d,hard=%d): %w", rlimitsReverseMap[resource], desired.Cur, desired.Max, current.Cur, current.Max, err) } } return nil diff --git a/vendor/github.com/containers/buildah/chroot/run_freebsd.go b/vendor/github.com/containers/buildah/chroot/run_freebsd.go index 239322f56..52763ee97 100644 --- a/vendor/github.com/containers/buildah/chroot/run_freebsd.go +++ b/vendor/github.com/containers/buildah/chroot/run_freebsd.go @@ -82,7 +82,7 @@ func createPlatformContainer(options runUsingChrootExecSubprocOptions) error { jconf.Set("enforce_statfs", 1) _, err := jail.CreateAndAttach(jconf) if err != nil { - return fmt.Errorf("error creating jail: %w", err) + return fmt.Errorf("creating jail: %w", err) } return nil } @@ -97,7 +97,7 @@ func makeReadOnly(mntpoint string, flags uintptr) error { var fs unix.Statfs_t // Make sure it's read-only. if err := unix.Statfs(mntpoint, &fs); err != nil { - return fmt.Errorf("error checking if directory %q was bound read-only: %w", mntpoint, err) + return fmt.Errorf("checking if directory %q was bound read-only: %w", mntpoint, err) } return nil } @@ -174,14 +174,14 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( case "nullfs": srcinfo, err = os.Stat(m.Source) if err != nil { - return undoBinds, fmt.Errorf("error examining %q for mounting in mount namespace: %w", m.Source, err) + return undoBinds, fmt.Errorf("examining %q for mounting in mount namespace: %w", m.Source, err) } } target := filepath.Join(spec.Root.Path, m.Destination) if _, err := os.Stat(target); err != nil { // If the target can't be stat()ted, check the error. if !os.IsNotExist(err) { - return undoBinds, fmt.Errorf("error examining %q for mounting in mount namespace: %w", target, err) + return undoBinds, fmt.Errorf("examining %q for mounting in mount namespace: %w", target, err) } // The target isn't there yet, so create it, and make a // note to remove it later. @@ -189,12 +189,12 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( // Leaving it here since I plan to add this to FreeBSD's nullfs. if m.Type != "nullfs" || srcinfo.IsDir() { if err = os.MkdirAll(target, 0111); err != nil { - return undoBinds, fmt.Errorf("error creating mountpoint %q in mount namespace: %w", target, err) + return undoBinds, fmt.Errorf("creating mountpoint %q in mount namespace: %w", target, err) } removes = append(removes, target) } else { if err = os.MkdirAll(filepath.Dir(target), 0111); err != nil { - return undoBinds, fmt.Errorf("error ensuring parent of mountpoint %q (%q) is present in mount namespace: %w", target, filepath.Dir(target), err) + return undoBinds, fmt.Errorf("ensuring parent of mountpoint %q (%q) is present in mount namespace: %w", target, filepath.Dir(target), err) } // Don't do this until we can support file mounts in nullfs /*var file *os.File @@ -219,7 +219,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( err = os.MkdirAll(save, 0111) } if err != nil { - return undoBinds, fmt.Errorf("error creating file mount save directory %q: %w", save, err) + return undoBinds, fmt.Errorf("creating file mount save directory %q: %w", save, err) } removes = append(removes, save) } @@ -227,7 +227,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( if _, err := os.Stat(target); err == nil { logrus.Debugf("moving %q to %q", target, savePath) if err := os.Rename(target, savePath); err != nil { - return undoBinds, fmt.Errorf("error moving %q to %q: %w", target, savePath, err) + return undoBinds, fmt.Errorf("moving %q to %q: %w", target, savePath, err) } renames = append(renames, rename{ from: target, @@ -238,12 +238,12 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( removes = append(removes, target) } if err := copyFile(m.Source, target); err != nil { - return undoBinds, fmt.Errorf("error copying %q to %q: %w", m.Source, target, err) + return undoBinds, fmt.Errorf("copying %q to %q: %w", m.Source, target, err) } } else { logrus.Debugf("bind mounting %q on %q", m.Destination, filepath.Join(spec.Root.Path, m.Destination)) if err := mount.Mount(m.Source, target, "nullfs", strings.Join(m.Options, ",")); err != nil { - return undoBinds, fmt.Errorf("error bind mounting %q from host to %q in mount namespace (%q): %w", m.Source, m.Destination, target, err) + return undoBinds, fmt.Errorf("bind mounting %q from host to %q in mount namespace (%q): %w", m.Source, m.Destination, target, err) } logrus.Debugf("bind mounted %q to %q", m.Source, target) unmounts = append(unmounts, target) @@ -251,7 +251,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( case "devfs", "fdescfs", "tmpfs": // Mount /dev, /dev/fd. if err := mount.Mount(m.Source, target, m.Type, strings.Join(m.Options, ",")); err != nil { - return undoBinds, fmt.Errorf("error mounting %q to %q in mount namespace (%q, %q): %w", m.Type, m.Destination, target, strings.Join(m.Options, ","), err) + return undoBinds, fmt.Errorf("mounting %q to %q in mount namespace (%q, %q): %w", m.Type, m.Destination, target, strings.Join(m.Options, ","), err) } logrus.Debugf("mounted a %q to %q", m.Type, target) unmounts = append(unmounts, target) diff --git a/vendor/github.com/containers/buildah/chroot/run_linux.go b/vendor/github.com/containers/buildah/chroot/run_linux.go index 7e1dcca14..f2a9c9034 100644 --- a/vendor/github.com/containers/buildah/chroot/run_linux.go +++ b/vendor/github.com/containers/buildah/chroot/run_linux.go @@ -158,7 +158,7 @@ func setApparmorProfile(spec *specs.Spec) error { return nil } if err := apparmor.ApplyProfile(spec.Process.ApparmorProfile); err != nil { - return fmt.Errorf("error setting apparmor profile to %q: %w", spec.Process.ApparmorProfile, err) + return fmt.Errorf("setting apparmor profile to %q: %w", spec.Process.ApparmorProfile, err) } return nil } @@ -167,14 +167,14 @@ func setApparmorProfile(spec *specs.Spec) error { func setCapabilities(spec *specs.Spec, keepCaps ...string) error { currentCaps, err := capability.NewPid2(0) if err != nil { - return fmt.Errorf("error reading capabilities of current process: %w", err) + return fmt.Errorf("reading capabilities of current process: %w", err) } if err := currentCaps.Load(); err != nil { - return fmt.Errorf("error loading capabilities: %w", err) + return fmt.Errorf("loading capabilities: %w", err) } caps, err := capability.NewPid2(0) if err != nil { - return fmt.Errorf("error reading capabilities of current process: %w", err) + return fmt.Errorf("reading capabilities of current process: %w", err) } capMap := map[capability.CapType][]string{ capability.BOUNDING: spec.Process.Capabilities.Bounding, @@ -195,7 +195,7 @@ func setCapabilities(spec *specs.Spec, keepCaps ...string) error { } } if cap == noCap { - return fmt.Errorf("error mapping capability %q to a number", capToSet) + return fmt.Errorf("mapping capability %q to a number", capToSet) } caps.Set(capType, cap) } @@ -208,7 +208,7 @@ func setCapabilities(spec *specs.Spec, keepCaps ...string) error { } } if cap == noCap { - return fmt.Errorf("error mapping capability %q to a number", capToSet) + return fmt.Errorf("mapping capability %q to a number", capToSet) } if currentCaps.Get(capType, cap) { caps.Set(capType, cap) @@ -216,7 +216,7 @@ func setCapabilities(spec *specs.Spec, keepCaps ...string) error { } } if err = caps.Apply(capability.CAPS | capability.BOUNDS | capability.AMBS); err != nil { - return fmt.Errorf("error setting capabilities: %w", err) + return fmt.Errorf("setting capabilities: %w", err) } return nil } @@ -233,11 +233,11 @@ func makeReadOnly(mntpoint string, flags uintptr) error { var fs unix.Statfs_t // Make sure it's read-only. if err := unix.Statfs(mntpoint, &fs); err != nil { - return fmt.Errorf("error checking if directory %q was bound read-only: %w", mntpoint, err) + return fmt.Errorf("checking if directory %q was bound read-only: %w", mntpoint, err) } if fs.Flags&unix.ST_RDONLY == 0 { if err := unix.Mount(mntpoint, mntpoint, "bind", flags|unix.MS_REMOUNT, ""); err != nil { - return fmt.Errorf("error remounting %s in mount namespace read-only: %w", mntpoint, err) + return fmt.Errorf("remounting %s in mount namespace read-only: %w", mntpoint, err) } } return nil @@ -283,16 +283,16 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( } } if err != nil { - return undoBinds, fmt.Errorf("error bind mounting /dev from host into mount namespace: %w", err) + return undoBinds, fmt.Errorf("bind mounting /dev from host into mount namespace: %w", err) } } // Make sure it's read-only. if err = unix.Statfs(subDev, &fs); err != nil { - return undoBinds, fmt.Errorf("error checking if directory %q was bound read-only: %w", subDev, err) + return undoBinds, fmt.Errorf("checking if directory %q was bound read-only: %w", subDev, err) } if fs.Flags&unix.ST_RDONLY == 0 { if err := unix.Mount(subDev, subDev, "bind", devFlags|unix.MS_REMOUNT, ""); err != nil { - return undoBinds, fmt.Errorf("error remounting /dev in mount namespace read-only: %w", err) + return undoBinds, fmt.Errorf("remounting /dev in mount namespace read-only: %w", err) } } logrus.Debugf("bind mounted %q to %q", "/dev", filepath.Join(spec.Root.Path, "/dev")) @@ -307,7 +307,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( } } if err != nil { - return undoBinds, fmt.Errorf("error bind mounting /proc from host into mount namespace: %w", err) + return undoBinds, fmt.Errorf("bind mounting /proc from host into mount namespace: %w", err) } } logrus.Debugf("bind mounted %q to %q", "/proc", filepath.Join(spec.Root.Path, "/proc")) @@ -322,7 +322,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( } } if err != nil { - return undoBinds, fmt.Errorf("error bind mounting /sys from host into mount namespace: %w", err) + return undoBinds, fmt.Errorf("bind mounting /sys from host into mount namespace: %w", err) } } if err := makeReadOnly(subSys, sysFlags); err != nil { @@ -380,14 +380,14 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( case "bind": srcinfo, err = os.Stat(m.Source) if err != nil { - return undoBinds, fmt.Errorf("error examining %q for mounting in mount namespace: %w", m.Source, err) + return undoBinds, fmt.Errorf("examining %q for mounting in mount namespace: %w", m.Source, err) } case "overlay": fallthrough case "tmpfs": srcinfo, err = os.Stat("/") if err != nil { - return undoBinds, fmt.Errorf("error examining / to use as a template for a %s: %w", m.Type, err) + return undoBinds, fmt.Errorf("examining / to use as a template for a %s: %w", m.Type, err) } } target := filepath.Join(spec.Root.Path, m.Destination) @@ -405,20 +405,20 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( if err != nil { // If the target can't be stat()ted, check the error. if !errors.Is(err, os.ErrNotExist) { - return undoBinds, fmt.Errorf("error examining %q for mounting in mount namespace: %w", target, err) + return undoBinds, fmt.Errorf("examining %q for mounting in mount namespace: %w", target, err) } // The target isn't there yet, so create it. if srcinfo.IsDir() { if err = os.MkdirAll(target, 0755); err != nil { - return undoBinds, fmt.Errorf("error creating mountpoint %q in mount namespace: %w", target, err) + return undoBinds, fmt.Errorf("creating mountpoint %q in mount namespace: %w", target, err) } } else { if err = os.MkdirAll(filepath.Dir(target), 0755); err != nil { - return undoBinds, fmt.Errorf("error ensuring parent of mountpoint %q (%q) is present in mount namespace: %w", target, filepath.Dir(target), err) + return undoBinds, fmt.Errorf("ensuring parent of mountpoint %q (%q) is present in mount namespace: %w", target, filepath.Dir(target), err) } var file *os.File if file, err = os.OpenFile(target, os.O_WRONLY|os.O_CREATE, 0755); err != nil { - return undoBinds, fmt.Errorf("error creating mountpoint %q in mount namespace: %w", target, err) + return undoBinds, fmt.Errorf("creating mountpoint %q in mount namespace: %w", target, err) } file.Close() } @@ -458,28 +458,28 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( // Do the bind mount. logrus.Debugf("bind mounting %q on %q", m.Destination, filepath.Join(spec.Root.Path, m.Destination)) if err := unix.Mount(m.Source, target, "", requestFlags, ""); err != nil { - return undoBinds, fmt.Errorf("error bind mounting %q from host to %q in mount namespace (%q): %w", m.Source, m.Destination, target, err) + return undoBinds, fmt.Errorf("bind mounting %q from host to %q in mount namespace (%q): %w", m.Source, m.Destination, target, err) } logrus.Debugf("bind mounted %q to %q", m.Source, target) case "tmpfs": // Mount a tmpfs. if err := mount.Mount(m.Source, target, m.Type, strings.Join(append(m.Options, "private"), ",")); err != nil { - return undoBinds, fmt.Errorf("error mounting tmpfs to %q in mount namespace (%q, %q): %w", m.Destination, target, strings.Join(m.Options, ","), err) + return undoBinds, fmt.Errorf("mounting tmpfs to %q in mount namespace (%q, %q): %w", m.Destination, target, strings.Join(m.Options, ","), err) } logrus.Debugf("mounted a tmpfs to %q", target) case "overlay": // Mount a overlay. if err := mount.Mount(m.Source, target, m.Type, strings.Join(append(m.Options, "private"), ",")); err != nil { - return undoBinds, fmt.Errorf("error mounting overlay to %q in mount namespace (%q, %q): %w", m.Destination, target, strings.Join(m.Options, ","), err) + return undoBinds, fmt.Errorf("mounting overlay to %q in mount namespace (%q, %q): %w", m.Destination, target, strings.Join(m.Options, ","), err) } logrus.Debugf("mounted a overlay to %q", target) } if err = unix.Statfs(target, &fs); err != nil { - return undoBinds, fmt.Errorf("error checking if directory %q was bound read-only: %w", target, err) + return undoBinds, fmt.Errorf("checking if directory %q was bound read-only: %w", target, err) } if uintptr(fs.Flags)&expectedFlags != expectedFlags { if err := unix.Mount(target, target, "bind", requestFlags|unix.MS_REMOUNT, ""); err != nil { - return undoBinds, fmt.Errorf("error remounting %q in mount namespace with expected flags: %w", target, err) + return undoBinds, fmt.Errorf("remounting %q in mount namespace with expected flags: %w", target, err) } } } @@ -494,7 +494,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( // No target, no problem. continue } - return undoBinds, fmt.Errorf("error checking %q for symlinks before marking it read-only: %w", r, err) + return undoBinds, fmt.Errorf("checking %q for symlinks before marking it read-only: %w", r, err) } // Check if the location is already read-only. var fs unix.Statfs_t @@ -503,7 +503,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( // No target, no problem. continue } - return undoBinds, fmt.Errorf("error checking if directory %q is already read-only: %w", target, err) + return undoBinds, fmt.Errorf("checking if directory %q is already read-only: %w", target, err) } if fs.Flags&unix.ST_RDONLY != 0 { continue @@ -515,23 +515,23 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( // No target, no problem. continue } - return undoBinds, fmt.Errorf("error bind mounting %q onto itself in preparation for making it read-only: %w", target, err) + return undoBinds, fmt.Errorf("bind mounting %q onto itself in preparation for making it read-only: %w", target, err) } // Remount the location read-only. if err = unix.Statfs(target, &fs); err != nil { - return undoBinds, fmt.Errorf("error checking if directory %q was bound read-only: %w", target, err) + return undoBinds, fmt.Errorf("checking if directory %q was bound read-only: %w", target, err) } if fs.Flags&unix.ST_RDONLY == 0 { if err := unix.Mount(target, target, "", roFlags|unix.MS_BIND|unix.MS_REMOUNT, ""); err != nil { - return undoBinds, fmt.Errorf("error remounting %q in mount namespace read-only: %w", target, err) + return undoBinds, fmt.Errorf("remounting %q in mount namespace read-only: %w", target, err) } } // Check again. if err = unix.Statfs(target, &fs); err != nil { - return undoBinds, fmt.Errorf("error checking if directory %q was remounted read-only: %w", target, err) + return undoBinds, fmt.Errorf("checking if directory %q was remounted read-only: %w", target, err) } if fs.Flags&unix.ST_RDONLY == 0 { - return undoBinds, fmt.Errorf("error verifying that %q in mount namespace was remounted read-only: %w", target, err) + return undoBinds, fmt.Errorf("verifying that %q in mount namespace was remounted read-only: %w", target, err) } } @@ -539,7 +539,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( roEmptyDir := filepath.Join(bundlePath, "empty") if len(spec.Linux.MaskedPaths) > 0 { if err := os.Mkdir(roEmptyDir, 0700); err != nil { - return undoBinds, fmt.Errorf("error creating empty directory %q: %w", roEmptyDir, err) + return undoBinds, fmt.Errorf("creating empty directory %q: %w", roEmptyDir, err) } } @@ -560,19 +560,19 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( // No target, no problem. continue } - return undoBinds, fmt.Errorf("error examining %q for masking in mount namespace: %w", target, err) + return undoBinds, fmt.Errorf("examining %q for masking in mount namespace: %w", target, err) } if targetinfo.IsDir() { // The target's a directory. Check if it's a read-only filesystem. var statfs unix.Statfs_t if err = unix.Statfs(target, &statfs); err != nil { - return undoBinds, fmt.Errorf("error checking if directory %q is a mountpoint: %w", target, err) + return undoBinds, fmt.Errorf("checking if directory %q is a mountpoint: %w", target, err) } isReadOnly := statfs.Flags&unix.MS_RDONLY != 0 // Check if any of the IDs we're mapping could read it. var stat unix.Stat_t if err = unix.Stat(target, &stat); err != nil { - return undoBinds, fmt.Errorf("error checking permissions on directory %q: %w", target, err) + return undoBinds, fmt.Errorf("checking permissions on directory %q: %w", target, err) } isAccessible := false if stat.Mode&unix.S_IROTH|unix.S_IXOTH != 0 { @@ -603,13 +603,13 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( directory, err := os.Open(target) if err != nil { if !os.IsPermission(err) { - return undoBinds, fmt.Errorf("error opening directory %q: %w", target, err) + return undoBinds, fmt.Errorf("opening directory %q: %w", target, err) } } else { names, err := directory.Readdirnames(0) directory.Close() if err != nil { - return undoBinds, fmt.Errorf("error reading contents of directory %q: %w", target, err) + return undoBinds, fmt.Errorf("reading contents of directory %q: %w", target, err) } hasContent = false for _, name := range names { @@ -628,14 +628,14 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( roFlags := uintptr(syscall.MS_BIND | syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_NOEXEC | syscall.MS_RDONLY) if !isReadOnly || (hasContent && isAccessible) { if err = unix.Mount(roEmptyDir, target, "bind", roFlags, ""); err != nil { - return undoBinds, fmt.Errorf("error masking directory %q in mount namespace: %w", target, err) + return undoBinds, fmt.Errorf("masking directory %q in mount namespace: %w", target, err) } if err = unix.Statfs(target, &fs); err != nil { - return undoBinds, fmt.Errorf("error checking if directory %q was mounted read-only in mount namespace: %w", target, err) + return undoBinds, fmt.Errorf("checking if directory %q was mounted read-only in mount namespace: %w", target, err) } if fs.Flags&unix.ST_RDONLY == 0 { if err = unix.Mount(target, target, "", roFlags|syscall.MS_REMOUNT, ""); err != nil { - return undoBinds, fmt.Errorf("error making sure directory %q in mount namespace is read only: %w", target, err) + return undoBinds, fmt.Errorf("making sure directory %q in mount namespace is read only: %w", target, err) } } } @@ -643,7 +643,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func( // If the target's is not a directory or os.DevNull, bind mount os.DevNull over it. if !isDevNull(targetinfo) { if err = unix.Mount(os.DevNull, target, "", uintptr(syscall.MS_BIND|syscall.MS_RDONLY|syscall.MS_PRIVATE), ""); err != nil { - return undoBinds, fmt.Errorf("error masking non-directory %q in mount namespace: %w", target, err) + return undoBinds, fmt.Errorf("masking non-directory %q in mount namespace: %w", target, err) } } } diff --git a/vendor/github.com/containers/buildah/chroot/seccomp.go b/vendor/github.com/containers/buildah/chroot/seccomp.go index aebb1a180..714dca628 100644 --- a/vendor/github.com/containers/buildah/chroot/seccomp.go +++ b/vendor/github.com/containers/buildah/chroot/seccomp.go @@ -111,11 +111,11 @@ func setSeccomp(spec *specs.Spec) error { filter, err := libseccomp.NewFilter(mapAction(spec.Linux.Seccomp.DefaultAction, spec.Linux.Seccomp.DefaultErrnoRet)) if err != nil { - return fmt.Errorf("error creating seccomp filter with default action %q: %w", spec.Linux.Seccomp.DefaultAction, err) + return fmt.Errorf("creating seccomp filter with default action %q: %w", spec.Linux.Seccomp.DefaultAction, err) } for _, arch := range spec.Linux.Seccomp.Architectures { if err = filter.AddArch(mapArch(arch)); err != nil { - return fmt.Errorf("error adding architecture %q(%q) to seccomp filter: %w", arch, mapArch(arch), err) + return fmt.Errorf("adding architecture %q(%q) to seccomp filter: %w", arch, mapArch(arch), err) } } for _, rule := range spec.Linux.Seccomp.Syscalls { @@ -131,7 +131,7 @@ func setSeccomp(spec *specs.Spec) error { for scnum := range scnames { if len(rule.Args) == 0 { if err = filter.AddRule(scnum, mapAction(rule.Action, rule.ErrnoRet)); err != nil { - return fmt.Errorf("error adding a rule (%q:%q) to seccomp filter: %w", scnames[scnum], rule.Action, err) + return fmt.Errorf("adding a rule (%q:%q) to seccomp filter: %w", scnames[scnum], rule.Action, err) } continue } @@ -140,7 +140,7 @@ func setSeccomp(spec *specs.Spec) error { for _, arg := range rule.Args { condition, err := libseccomp.MakeCondition(arg.Index, mapOp(arg.Op), arg.Value, arg.ValueTwo) if err != nil { - return fmt.Errorf("error building a seccomp condition %d:%v:%d:%d: %w", arg.Index, arg.Op, arg.Value, arg.ValueTwo, err) + return fmt.Errorf("building a seccomp condition %d:%v:%d:%d: %w", arg.Index, arg.Op, arg.Value, arg.ValueTwo, err) } if arg.Op != specs.OpEqualTo { opsAreAllEquality = false @@ -156,22 +156,22 @@ func setSeccomp(spec *specs.Spec) error { if len(rule.Args) > 1 && opsAreAllEquality && err.Error() == "two checks on same syscall argument" { for i := range conditions { if err = filter.AddRuleConditional(scnum, mapAction(rule.Action, rule.ErrnoRet), conditions[i:i+1]); err != nil { - return fmt.Errorf("error adding a conditional rule (%q:%q[%d]) to seccomp filter: %w", scnames[scnum], rule.Action, i, err) + return fmt.Errorf("adding a conditional rule (%q:%q[%d]) to seccomp filter: %w", scnames[scnum], rule.Action, i, err) } } } else { - return fmt.Errorf("error adding a conditional rule (%q:%q) to seccomp filter: %w", scnames[scnum], rule.Action, err) + return fmt.Errorf("adding a conditional rule (%q:%q) to seccomp filter: %w", scnames[scnum], rule.Action, err) } } } } if err = filter.SetNoNewPrivsBit(spec.Process.NoNewPrivileges); err != nil { - return fmt.Errorf("error setting no-new-privileges bit to %v: %w", spec.Process.NoNewPrivileges, err) + return fmt.Errorf("setting no-new-privileges bit to %v: %w", spec.Process.NoNewPrivileges, err) } err = filter.Load() filter.Release() if err != nil { - return fmt.Errorf("error activating seccomp filter: %w", err) + return fmt.Errorf("activating seccomp filter: %w", err) } return nil } @@ -189,7 +189,7 @@ func setupSeccomp(spec *specs.Spec, seccompProfilePath string) error { default: seccompProfile, err := ioutil.ReadFile(seccompProfilePath) if err != nil { - return fmt.Errorf("opening seccomp profile (%s) failed: %w", seccompProfilePath, err) + return fmt.Errorf("opening seccomp profile failed: %w", err) } seccompConfig, err := seccomp.LoadProfile(string(seccompProfile), spec) if err != nil { diff --git a/vendor/github.com/containers/buildah/chroot/selinux.go b/vendor/github.com/containers/buildah/chroot/selinux.go index 538c0e3f4..bba4b8254 100644 --- a/vendor/github.com/containers/buildah/chroot/selinux.go +++ b/vendor/github.com/containers/buildah/chroot/selinux.go @@ -17,7 +17,7 @@ func setSelinuxLabel(spec *specs.Spec) error { logrus.Debugf("setting selinux label") if spec.Process.SelinuxLabel != "" && selinux.GetEnabled() { if err := label.SetProcessLabel(spec.Process.SelinuxLabel); err != nil { - return fmt.Errorf("error setting process label to %q: %w", spec.Process.SelinuxLabel, err) + return fmt.Errorf("setting process label to %q: %w", spec.Process.SelinuxLabel, err) } } return nil diff --git a/vendor/github.com/containers/buildah/commit.go b/vendor/github.com/containers/buildah/commit.go index 727f97b06..e53fbfe87 100644 --- a/vendor/github.com/containers/buildah/commit.go +++ b/vendor/github.com/containers/buildah/commit.go @@ -146,7 +146,7 @@ func checkRegistrySourcesAllows(forWhat string, dest types.ImageReference) (inse AllowedRegistries []string `json:"allowedRegistries,omitempty"` } if err := json.Unmarshal([]byte(registrySources), &sources); err != nil { - return false, fmt.Errorf("error parsing $BUILD_REGISTRY_SOURCES (%q) as JSON: %w", registrySources, err) + return false, fmt.Errorf("parsing $BUILD_REGISTRY_SOURCES (%q) as JSON: %w", registrySources, err) } blocked := false if len(sources.BlockedRegistries) > 0 { @@ -205,7 +205,7 @@ func (b *Builder) addManifest(ctx context.Context, manifestName string, imageSpe names, err := util.ExpandNames([]string{manifestName}, systemContext, b.store) if err != nil { - return "", fmt.Errorf("error encountered while expanding manifest list name %q: %w", manifestName, err) + return "", fmt.Errorf("encountered while expanding manifest list name %q: %w", manifestName, err) } ref, err := util.VerifyTagName(imageSpec) @@ -258,7 +258,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options nameToRemove = stringid.GenerateRandomID() + "-tmp" dest2, err := is.Transport.ParseStoreReference(b.store, nameToRemove) if err != nil { - return imgID, nil, "", fmt.Errorf("error creating temporary destination reference for image: %w", err) + return imgID, nil, "", fmt.Errorf("creating temporary destination reference for image: %w", err) } dest = dest2 } @@ -267,7 +267,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options blocked, err := isReferenceBlocked(dest, systemContext) if err != nil { - return "", nil, "", fmt.Errorf("error checking if committing to registry for %q is blocked: %w", transports.ImageName(dest), err) + return "", nil, "", fmt.Errorf("checking if committing to registry for %q is blocked: %w", transports.ImageName(dest), err) } if blocked { return "", nil, "", fmt.Errorf("commit access to registry for %q is blocked by configuration", transports.ImageName(dest)) @@ -276,14 +276,14 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options // Load the system signing policy. commitPolicy, err := signature.DefaultPolicy(systemContext) if err != nil { - return "", nil, "", fmt.Errorf("error obtaining default signature policy: %w", err) + return "", nil, "", fmt.Errorf("obtaining default signature policy: %w", err) } // Override the settings for local storage to make sure that we can always read the source "image". commitPolicy.Transports[is.Transport.Name()] = storageAllowedPolicyScopes policyContext, err := signature.NewPolicyContext(commitPolicy) if err != nil { - return imgID, nil, "", fmt.Errorf("error creating new signature policy context: %w", err) + return imgID, nil, "", fmt.Errorf("creating new signature policy context: %w", err) } defer func() { if err2 := policyContext.Destroy(); err2 != nil { @@ -309,7 +309,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options // Build an image reference from which we can copy the finished image. src, err = b.makeContainerImageRef(options) if err != nil { - return imgID, nil, "", fmt.Errorf("error computing layer digests and building metadata for container %q: %w", b.ContainerID, err) + return imgID, nil, "", fmt.Errorf("computing layer digests and building metadata for container %q: %w", b.ContainerID, err) } // In case we're using caching, decide how to handle compression for a cache. // If we're using blob caching, set it up for the source. @@ -322,12 +322,12 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options } cache, err := blobcache.NewBlobCache(src, options.BlobDirectory, compress) if err != nil { - return imgID, nil, "", fmt.Errorf("error wrapping image reference %q in blob cache at %q: %w", transports.ImageName(src), options.BlobDirectory, err) + return imgID, nil, "", fmt.Errorf("wrapping image reference %q in blob cache at %q: %w", transports.ImageName(src), options.BlobDirectory, err) } maybeCachedSrc = cache cache, err = blobcache.NewBlobCache(dest, options.BlobDirectory, compress) if err != nil { - return imgID, nil, "", fmt.Errorf("error wrapping image reference %q in blob cache at %q: %w", transports.ImageName(dest), options.BlobDirectory, err) + return imgID, nil, "", fmt.Errorf("wrapping image reference %q in blob cache at %q: %w", transports.ImageName(dest), options.BlobDirectory, err) } maybeCachedDest = cache } @@ -348,7 +348,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options var manifestBytes []byte if manifestBytes, err = retryCopyImage(ctx, policyContext, maybeCachedDest, maybeCachedSrc, dest, getCopyOptions(b.store, options.ReportWriter, nil, systemContext, "", false, options.SignBy, options.OciEncryptLayers, options.OciEncryptConfig, nil), options.MaxRetries, options.RetryDelay); err != nil { - return imgID, nil, "", fmt.Errorf("error copying layers and metadata for container %q: %w", b.ContainerID, err) + return imgID, nil, "", fmt.Errorf("copying layers and metadata for container %q: %w", b.ContainerID, err) } // If we've got more names to attach, and we know how to do that for // the transport that we're writing the new image to, add them now. @@ -357,10 +357,10 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options case is.Transport.Name(): img, err := is.Transport.GetStoreImage(b.store, dest) if err != nil { - return imgID, nil, "", fmt.Errorf("error locating just-written image %q: %w", transports.ImageName(dest), err) + return imgID, nil, "", fmt.Errorf("locating just-written image %q: %w", transports.ImageName(dest), err) } if err = util.AddImageNames(b.store, "", systemContext, img, options.AdditionalTags); err != nil { - return imgID, nil, "", fmt.Errorf("error setting image names to %v: %w", append(img.Names, options.AdditionalTags...), err) + return imgID, nil, "", fmt.Errorf("setting image names to %v: %w", append(img.Names, options.AdditionalTags...), err) } logrus.Debugf("assigned names %v to image %q", img.Names, img.ID) default: @@ -370,7 +370,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options img, err := is.Transport.GetStoreImage(b.store, dest) if err != nil && !errors.Is(err, storage.ErrImageUnknown) { - return imgID, nil, "", fmt.Errorf("error locating image %q in local storage: %w", transports.ImageName(dest), err) + return imgID, nil, "", fmt.Errorf("locating image %q in local storage: %w", transports.ImageName(dest), err) } if err == nil { imgID = img.ID @@ -387,7 +387,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options logrus.Debugf("removing %v from assigned names to image %q", nameToRemove, img.ID) dest2, err := is.Transport.ParseStoreReference(b.store, "@"+imgID) if err != nil { - return imgID, nil, "", fmt.Errorf("error creating unnamed destination reference for image: %w", err) + return imgID, nil, "", fmt.Errorf("creating unnamed destination reference for image: %w", err) } dest = dest2 } @@ -400,7 +400,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options manifestDigest, err := manifest.Digest(manifestBytes) if err != nil { - return imgID, nil, "", fmt.Errorf("error computing digest of manifest of new image %q: %w", transports.ImageName(dest), err) + return imgID, nil, "", fmt.Errorf("computing digest of manifest of new image %q: %w", transports.ImageName(dest), err) } var ref reference.Canonical diff --git a/vendor/github.com/containers/buildah/config.go b/vendor/github.com/containers/buildah/config.go index aa6290186..a9883a595 100644 --- a/vendor/github.com/containers/buildah/config.go +++ b/vendor/github.com/containers/buildah/config.go @@ -28,7 +28,7 @@ import ( func unmarshalConvertedConfig(ctx context.Context, dest interface{}, img types.Image, wantedManifestMIMEType string) error { _, actualManifestMIMEType, err := img.Manifest(ctx) if err != nil { - return fmt.Errorf("error getting manifest MIME type for %q: %w", transports.ImageName(img.Reference()), err) + return fmt.Errorf("getting manifest MIME type for %q: %w", transports.ImageName(img.Reference()), err) } if wantedManifestMIMEType != actualManifestMIMEType { layerInfos := img.LayerInfos() @@ -46,16 +46,16 @@ func unmarshalConvertedConfig(ctx context.Context, dest interface{}, img types.I ManifestMIMEType: wantedManifestMIMEType, }) if err != nil { - return fmt.Errorf("error converting image %q from %q to %q: %w", transports.ImageName(img.Reference()), actualManifestMIMEType, wantedManifestMIMEType, err) + return fmt.Errorf("converting image %q from %q to %q: %w", transports.ImageName(img.Reference()), actualManifestMIMEType, wantedManifestMIMEType, err) } img = secondUpdatedImg } config, err := img.ConfigBlob(ctx) if err != nil { - return fmt.Errorf("error reading %s config from %q: %w", wantedManifestMIMEType, transports.ImageName(img.Reference()), err) + return fmt.Errorf("reading %s config from %q: %w", wantedManifestMIMEType, transports.ImageName(img.Reference()), err) } if err := json.Unmarshal(config, dest); err != nil { - return fmt.Errorf("error parsing %s configuration %q from %q: %w", wantedManifestMIMEType, string(config), transports.ImageName(img.Reference()), err) + return fmt.Errorf("parsing %s configuration %q from %q: %w", wantedManifestMIMEType, string(config), transports.ImageName(img.Reference()), err) } return nil } @@ -64,11 +64,11 @@ func (b *Builder) initConfig(ctx context.Context, img types.Image, sys *types.Sy if img != nil { // A pre-existing image, as opposed to a "FROM scratch" new one. rawManifest, manifestMIMEType, err := img.Manifest(ctx) if err != nil { - return fmt.Errorf("error reading image manifest for %q: %w", transports.ImageName(img.Reference()), err) + return fmt.Errorf("reading image manifest for %q: %w", transports.ImageName(img.Reference()), err) } rawConfig, err := img.ConfigBlob(ctx) if err != nil { - return fmt.Errorf("error reading image configuration for %q: %w", transports.ImageName(img.Reference()), err) + return fmt.Errorf("reading image configuration for %q: %w", transports.ImageName(img.Reference()), err) } b.Manifest = rawManifest b.Config = rawConfig @@ -89,7 +89,7 @@ func (b *Builder) initConfig(ctx context.Context, img types.Image, sys *types.Sy // Attempt to recover format-specific data from the manifest. v1Manifest := ociv1.Manifest{} if err := json.Unmarshal(b.Manifest, &v1Manifest); err != nil { - return fmt.Errorf("error parsing OCI manifest %q: %w", string(b.Manifest), err) + return fmt.Errorf("parsing OCI manifest %q: %w", string(b.Manifest), err) } for k, v := range v1Manifest.Annotations { // NOTE: do not override annotations that are diff --git a/vendor/github.com/containers/buildah/copier/copier.go b/vendor/github.com/containers/buildah/copier/copier.go index de464ab52..fd4c6b394 100644 --- a/vendor/github.com/containers/buildah/copier/copier.go +++ b/vendor/github.com/containers/buildah/copier/copier.go @@ -463,7 +463,7 @@ func convertToRelSubdirectory(root, directory string) (relative string, err erro } rel, err := filepath.Rel(root, directory) if err != nil { - return "", fmt.Errorf("error computing path of %q relative to %q: %w", directory, root, err) + return "", fmt.Errorf("computing path of %q relative to %q: %w", directory, root, err) } return cleanerReldirectory(rel), nil } @@ -471,7 +471,7 @@ func convertToRelSubdirectory(root, directory string) (relative string, err erro func currentVolumeRoot() (string, error) { cwd, err := os.Getwd() if err != nil { - return "", fmt.Errorf("error getting current working directory: %w", err) + return "", fmt.Errorf("getting current working directory: %w", err) } return filepath.VolumeName(cwd) + string(os.PathSeparator), nil } @@ -479,7 +479,7 @@ func currentVolumeRoot() (string, error) { func isVolumeRoot(candidate string) (bool, error) { abs, err := filepath.Abs(candidate) if err != nil { - return false, fmt.Errorf("error converting %q to an absolute path: %w", candidate, err) + return false, fmt.Errorf("converting %q to an absolute path: %w", candidate, err) } return abs == filepath.VolumeName(abs)+string(os.PathSeparator), nil } @@ -493,7 +493,7 @@ func copier(bulkReader io.Reader, bulkWriter io.Writer, req request) (*response, if req.Root == "" { wd, err := os.Getwd() if err != nil { - return nil, fmt.Errorf("error getting current working directory: %w", err) + return nil, fmt.Errorf("getting current working directory: %w", err) } req.Directory = wd } else { @@ -503,19 +503,19 @@ func copier(bulkReader io.Reader, bulkWriter io.Writer, req request) (*response, if req.Root == "" { root, err := currentVolumeRoot() if err != nil { - return nil, fmt.Errorf("error determining root of current volume: %w", err) + return nil, fmt.Errorf("determining root of current volume: %w", err) } req.Root = root } if filepath.IsAbs(req.Directory) { _, err := convertToRelSubdirectory(req.Root, req.Directory) if err != nil { - return nil, fmt.Errorf("error rewriting %q to be relative to %q: %w", req.Directory, req.Root, err) + return nil, fmt.Errorf("rewriting %q to be relative to %q: %w", req.Directory, req.Root, err) } } isAlreadyRoot, err := isVolumeRoot(req.Root) if err != nil { - return nil, fmt.Errorf("error checking if %q is a root directory: %w", req.Root, err) + return nil, fmt.Errorf("checking if %q is a root directory: %w", req.Root, err) } if !isAlreadyRoot && canChroot { return copierWithSubprocess(bulkReader, bulkWriter, req) @@ -610,7 +610,7 @@ func copierWithSubprocess(bulkReader io.Reader, bulkWriter io.Writer, req reques cmd.Stderr = &errorBuffer cmd.ExtraFiles = []*os.File{bulkReaderRead, bulkWriterWrite} if err = cmd.Start(); err != nil { - return nil, fmt.Errorf("error starting subprocess: %w", err) + return nil, fmt.Errorf("starting subprocess: %w", err) } cmdToWaitFor := cmd defer func() { @@ -632,7 +632,7 @@ func copierWithSubprocess(bulkReader io.Reader, bulkWriter io.Writer, req reques bulkWriterWrite = nil killAndReturn := func(err error, step string) (*response, error) { // nolint: unparam if err2 := cmd.Process.Kill(); err2 != nil { - return nil, fmt.Errorf("error killing subprocess: %v; %s: %w", err2, step, err) + return nil, fmt.Errorf("killing subprocess: %v; %s: %w", err2, step, err) } return nil, fmt.Errorf("%v: %w", step, err) } @@ -690,10 +690,10 @@ func copierWithSubprocess(bulkReader io.Reader, bulkWriter io.Writer, req reques } } if readError != nil { - return nil, fmt.Errorf("error passing bulk input to subprocess: %w", readError) + return nil, fmt.Errorf("passing bulk input to subprocess: %w", readError) } if writeError != nil { - return nil, fmt.Errorf("error passing bulk output from subprocess: %w", writeError) + return nil, fmt.Errorf("passing bulk output from subprocess: %w", writeError) } return resp, nil } @@ -845,7 +845,7 @@ func copierHandler(bulkReader io.Reader, bulkWriter io.Writer, req request) (*re excludes := req.Excludes() pm, err := fileutils.NewPatternMatcher(excludes) if err != nil { - return nil, nil, fmt.Errorf("error processing excludes list %v: %w", excludes, err) + return nil, nil, fmt.Errorf("processing excludes list %v: %w", excludes, err) } var idMappings *idtools.IDMappings @@ -915,7 +915,7 @@ func pathIsExcluded(root, path string, pm *fileutils.PatternMatcher) (string, bo func resolvePath(root, path string, evaluateFinalComponent bool, pm *fileutils.PatternMatcher) (string, error) { rel, err := convertToRelSubdirectory(root, path) if err != nil { - return "", fmt.Errorf("error making path %q relative to %q", path, root) + return "", fmt.Errorf("making path %q relative to %q", path, root) } workingPath := root followed := 0 @@ -952,7 +952,7 @@ func resolvePath(root, path string, evaluateFinalComponent bool, pm *fileutils.P // resolve the remaining components rel, err := convertToRelSubdirectory(root, filepath.Join(workingPath, target)) if err != nil { - return "", fmt.Errorf("error making path %q relative to %q", filepath.Join(workingPath, target), root) + return "", fmt.Errorf("making path %q relative to %q", filepath.Join(workingPath, target), root) } workingPath = root components = append(strings.Split(filepath.Clean(string(os.PathSeparator)+rel), string(os.PathSeparator)), components[1:]...) @@ -1357,7 +1357,7 @@ func copierHandlerGetOne(srcfi os.FileInfo, symlinkTarget, name, contentPath str // build the header using the name provided hdr, err := tar.FileInfoHeader(srcfi, symlinkTarget) if err != nil { - return fmt.Errorf("error generating tar header for %s (%s): %w", contentPath, symlinkTarget, err) + return fmt.Errorf("generating tar header for %s (%s): %w", contentPath, symlinkTarget, err) } if name != "" { hdr.Name = filepath.ToSlash(name) @@ -1379,7 +1379,7 @@ func copierHandlerGetOne(srcfi os.FileInfo, symlinkTarget, name, contentPath str if !options.StripXattrs { xattrs, err = Lgetxattrs(contentPath) if err != nil { - return fmt.Errorf("error getting extended attributes for %q: %w", contentPath, err) + return fmt.Errorf("getting extended attributes for %q: %w", contentPath, err) } } hdr.Xattrs = xattrs // nolint:staticcheck @@ -1391,12 +1391,12 @@ func copierHandlerGetOne(srcfi os.FileInfo, symlinkTarget, name, contentPath str if options.ExpandArchives && isArchivePath(contentPath) { f, err := os.Open(contentPath) if err != nil { - return fmt.Errorf("error opening file for reading archive contents: %w", err) + return fmt.Errorf("opening file for reading archive contents: %w", err) } defer f.Close() rc, _, err := compression.AutoDecompress(f) if err != nil { - return fmt.Errorf("error decompressing %s: %w", contentPath, err) + return fmt.Errorf("decompressing %s: %w", contentPath, err) } defer rc.Close() tr := tar.NewReader(rc) @@ -1406,22 +1406,22 @@ func copierHandlerGetOne(srcfi os.FileInfo, symlinkTarget, name, contentPath str hdr.Name = handleRename(options.Rename, hdr.Name) } if err = tw.WriteHeader(hdr); err != nil { - return fmt.Errorf("error writing tar header from %q to pipe: %w", contentPath, err) + return fmt.Errorf("writing tar header from %q to pipe: %w", contentPath, err) } if hdr.Size != 0 { n, err := io.Copy(tw, tr) if err != nil { - return fmt.Errorf("error extracting content from archive %s: %s: %w", contentPath, hdr.Name, err) + return fmt.Errorf("extracting content from archive %s: %s: %w", contentPath, hdr.Name, err) } if n != hdr.Size { - return fmt.Errorf("error extracting contents of archive %s: incorrect length for %q", contentPath, hdr.Name) + return fmt.Errorf("extracting contents of archive %s: incorrect length for %q", contentPath, hdr.Name) } tw.Flush() } hdr, err = tr.Next() } if err != io.EOF { - return fmt.Errorf("error extracting contents of archive %s: %w", contentPath, err) + return fmt.Errorf("extracting contents of archive %s: %w", contentPath, err) } return nil } @@ -1443,7 +1443,7 @@ func copierHandlerGetOne(srcfi os.FileInfo, symlinkTarget, name, contentPath str hostPair := idtools.IDPair{UID: hdr.Uid, GID: hdr.Gid} hdr.Uid, hdr.Gid, err = idMappings.ToContainer(hostPair) if err != nil { - return fmt.Errorf("error mapping host filesystem owners %#v to container filesystem owners: %w", hostPair, err) + return fmt.Errorf("mapping host filesystem owners %#v to container filesystem owners: %w", hostPair, err) } } // force ownership and/or permissions, if requested @@ -1467,29 +1467,29 @@ func copierHandlerGetOne(srcfi os.FileInfo, symlinkTarget, name, contentPath str // open the file first so that we don't write a header for it if we can't actually read it f, err = os.Open(contentPath) if err != nil { - return fmt.Errorf("error opening file for adding its contents to archive: %w", err) + return fmt.Errorf("opening file for adding its contents to archive: %w", err) } defer f.Close() } else if hdr.Typeflag == tar.TypeDir { // open the directory file first to make sure we can access it. f, err = os.Open(contentPath) if err != nil { - return fmt.Errorf("error opening directory for adding its contents to archive: %w", err) + return fmt.Errorf("opening directory for adding its contents to archive: %w", err) } defer f.Close() } // output the header if err = tw.WriteHeader(hdr); err != nil { - return fmt.Errorf("error writing header for %s (%s): %w", contentPath, hdr.Name, err) + return fmt.Errorf("writing header for %s (%s): %w", contentPath, hdr.Name, err) } if hdr.Typeflag == tar.TypeReg { // output the content n, err := io.Copy(tw, f) if err != nil { - return fmt.Errorf("error copying %s: %w", contentPath, err) + return fmt.Errorf("copying %s: %w", contentPath, err) } if n != hdr.Size { - return fmt.Errorf("error copying %s: incorrect size (expected %d bytes, read %d bytes)", contentPath, n, hdr.Size) + return fmt.Errorf("copying %s: incorrect size (expected %d bytes, read %d bytes)", contentPath, n, hdr.Size) } tw.Flush() } @@ -1671,7 +1671,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM containerPair := idtools.IDPair{UID: hdr.Uid, GID: hdr.Gid} hostPair, err := idMappings.ToHost(containerPair) if err != nil { - return fmt.Errorf("error mapping container filesystem owner 0,0 to host filesystem owners: %w", err) + return fmt.Errorf("mapping container filesystem owner 0,0 to host filesystem owners: %w", err) } hdr.Uid, hdr.Gid = hostPair.UID, hostPair.GID } @@ -1736,7 +1736,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM hdr.Linkname = handleRename(req.PutOptions.Rename, hdr.Linkname) } if linkTarget, err = resolvePath(targetDirectory, filepath.Join(req.Root, filepath.FromSlash(hdr.Linkname)), true, nil); err != nil { - return fmt.Errorf("error resolving hardlink target path %q under root %q", hdr.Linkname, req.Root) + return fmt.Errorf("resolving hardlink target path %q under root %q", hdr.Linkname, req.Root) } if err = os.Link(linkTarget, path); err != nil && errors.Is(err, os.ErrExist) { if req.PutOptions.NoOverwriteDirNonDir { @@ -1869,7 +1869,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM mode |= syscall.S_ISVTX } if err = syscall.Chmod(path, uint32(mode)); err != nil { - return fmt.Errorf("error setting additional permissions on %q to 0%o: %w", path, mode, err) + return fmt.Errorf("setting additional permissions on %q to 0%o: %w", path, mode, err) } } // set xattrs, including some that might have been reset by chown() @@ -1885,13 +1885,13 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM hdr.AccessTime = hdr.ModTime } if err = lutimes(hdr.Typeflag == tar.TypeSymlink, path, hdr.AccessTime, hdr.ModTime); err != nil { - return fmt.Errorf("error setting access and modify timestamps on %q to %s and %s: %w", path, hdr.AccessTime, hdr.ModTime, err) + return fmt.Errorf("setting access and modify timestamps on %q to %s and %s: %w", path, hdr.AccessTime, hdr.ModTime, err) } nextHeader: hdr, err = tr.Next() } if err != io.EOF { - return fmt.Errorf("error reading tar stream: expected EOF: %w", err) + return fmt.Errorf("reading tar stream: expected EOF: %w", err) } return nil } diff --git a/vendor/github.com/containers/buildah/copier/syscall_unix.go b/vendor/github.com/containers/buildah/copier/syscall_unix.go index 0f2de9354..99b2ee7b6 100644 --- a/vendor/github.com/containers/buildah/copier/syscall_unix.go +++ b/vendor/github.com/containers/buildah/copier/syscall_unix.go @@ -17,13 +17,13 @@ var canChroot = os.Getuid() == 0 func chroot(root string) (bool, error) { if canChroot { if err := os.Chdir(root); err != nil { - return false, fmt.Errorf("error changing to intended-new-root directory %q: %w", root, err) + return false, fmt.Errorf("changing to intended-new-root directory %q: %w", root, err) } if err := unix.Chroot(root); err != nil { - return false, fmt.Errorf("error chrooting to directory %q: %w", root, err) + return false, fmt.Errorf("chrooting to directory %q: %w", root, err) } if err := os.Chdir(string(os.PathSeparator)); err != nil { - return false, fmt.Errorf("error changing to just-became-root directory %q: %w", root, err) + return false, fmt.Errorf("changing to just-became-root directory %q: %w", root, err) } return true, nil } diff --git a/vendor/github.com/containers/buildah/copier/xattrs.go b/vendor/github.com/containers/buildah/copier/xattrs.go index bad057051..f5b2e731f 100644 --- a/vendor/github.com/containers/buildah/copier/xattrs.go +++ b/vendor/github.com/containers/buildah/copier/xattrs.go @@ -54,7 +54,7 @@ func Lgetxattrs(path string) (map[string]string, error) { list = list[:0] break } - return nil, fmt.Errorf("error listing extended attributes of %q: %w", path, err) + return nil, fmt.Errorf("listing extended attributes of %q: %w", path, err) } list = list[:size] break @@ -75,7 +75,7 @@ func Lgetxattrs(path string) (map[string]string, error) { attributeSize *= 2 continue } - return nil, fmt.Errorf("error getting value of extended attribute %q on %q: %w", attribute, path, err) + return nil, fmt.Errorf("getting value of extended attribute %q on %q: %w", attribute, path, err) } m[attribute] = string(attributeValue[:size]) break @@ -93,7 +93,7 @@ func Lsetxattrs(path string, xattrs map[string]string) error { for attribute, value := range xattrs { if isRelevantXattr(attribute) { if err := unix.Lsetxattr(path, attribute, []byte(value), 0); err != nil { - return fmt.Errorf("error setting value of extended attribute %q on %q: %w", attribute, path, err) + return fmt.Errorf("setting value of extended attribute %q on %q: %w", attribute, path, err) } } } diff --git a/vendor/github.com/containers/buildah/define/build.go b/vendor/github.com/containers/buildah/define/build.go index 352280433..69b2dc9b0 100644 --- a/vendor/github.com/containers/buildah/define/build.go +++ b/vendor/github.com/containers/buildah/define/build.go @@ -186,6 +186,10 @@ type BuildOptions struct { // specified, indicating that the shared, system-wide default policy // should be used. SignaturePolicyPath string + // SkipUnusedStages allows users to skip stages in a multi-stage builds + // which do not contribute anything to the target stage. Expected default + // value is true. + SkipUnusedStages types.OptionalBool // ReportWriter is an io.Writer which will be used to report the // progress of the (possible) pulling of the source image and the // writing of the new image. diff --git a/vendor/github.com/containers/buildah/define/types.go b/vendor/github.com/containers/buildah/define/types.go index 015e1e18d..fb4735baa 100644 --- a/vendor/github.com/containers/buildah/define/types.go +++ b/vendor/github.com/containers/buildah/define/types.go @@ -123,11 +123,11 @@ func TempDirForURL(dir, prefix, url string) (name string, subdir string, err err } name, err = ioutil.TempDir(dir, prefix) if err != nil { - return "", "", fmt.Errorf("error creating temporary directory for %q: %w", url, err) + return "", "", fmt.Errorf("creating temporary directory for %q: %w", url, err) } urlParsed, err := urlpkg.Parse(url) if err != nil { - return "", "", fmt.Errorf("error parsing url %q: %w", url, err) + return "", "", fmt.Errorf("parsing url %q: %w", url, err) } if strings.HasPrefix(url, "git://") || strings.HasSuffix(urlParsed.Path, ".git") { combinedOutput, gitSubDir, err := cloneToDirectory(url, name) diff --git a/vendor/github.com/containers/buildah/delete.go b/vendor/github.com/containers/buildah/delete.go index 718316844..7adb7c5ee 100644 --- a/vendor/github.com/containers/buildah/delete.go +++ b/vendor/github.com/containers/buildah/delete.go @@ -6,7 +6,7 @@ import "fmt" // be used after this method is called. func (b *Builder) Delete() error { if err := b.store.DeleteContainer(b.ContainerID); err != nil { - return fmt.Errorf("error deleting build container %q: %w", b.ContainerID, err) + return fmt.Errorf("deleting build container %q: %w", b.ContainerID, err) } b.MountPoint = "" b.Container = "" diff --git a/vendor/github.com/containers/buildah/digester.go b/vendor/github.com/containers/buildah/digester.go index 9455e3680..0ed8fa41f 100644 --- a/vendor/github.com/containers/buildah/digester.go +++ b/vendor/github.com/containers/buildah/digester.go @@ -75,7 +75,7 @@ func (t *tarFilterer) Close() error { err := t.pipeWriter.Close() t.wg.Wait() if err != nil { - return fmt.Errorf("error closing filter pipe: %w", err) + return fmt.Errorf("closing filter pipe: %w", err) } return t.err } @@ -110,7 +110,7 @@ func newTarFilterer(writeCloser io.WriteCloser, filter func(hdr *tar.Header) (sk if !skip { err = tarWriter.WriteHeader(hdr) if err != nil { - err = fmt.Errorf("error filtering tar header for %q: %w", hdr.Name, err) + err = fmt.Errorf("filtering tar header for %q: %w", hdr.Name, err) break } if hdr.Size != 0 { @@ -122,11 +122,11 @@ func newTarFilterer(writeCloser io.WriteCloser, filter func(hdr *tar.Header) (sk n, copyErr = io.Copy(tarWriter, tarReader) } if copyErr != nil { - err = fmt.Errorf("error copying content for %q: %w", hdr.Name, copyErr) + err = fmt.Errorf("copying content for %q: %w", hdr.Name, copyErr) break } if n != hdr.Size { - err = fmt.Errorf("error filtering content for %q: expected %d bytes, got %d bytes", hdr.Name, hdr.Size, n) + err = fmt.Errorf("filtering content for %q: expected %d bytes, got %d bytes", hdr.Name, hdr.Size, n) break } } @@ -134,7 +134,7 @@ func newTarFilterer(writeCloser io.WriteCloser, filter func(hdr *tar.Header) (sk hdr, err = tarReader.Next() } if err != io.EOF { - filterer.err = fmt.Errorf("error reading tar archive: %w", err) + filterer.err = fmt.Errorf("reading tar archive: %w", err) break } filterer.closedLock.Lock() diff --git a/vendor/github.com/containers/buildah/image.go b/vendor/github.com/containers/buildah/image.go index 335a6733c..cc56ff2da 100644 --- a/vendor/github.com/containers/buildah/image.go +++ b/vendor/github.com/containers/buildah/image.go @@ -167,7 +167,7 @@ func (i *containerImageRef) extractRootfs(opts ExtractRootfsOptions) (io.ReadClo var uidMap, gidMap []idtools.IDMap mountPoint, err := i.store.Mount(i.containerID, i.mountLabel) if err != nil { - return nil, nil, fmt.Errorf("error mounting container %q: %w", i.containerID, err) + return nil, nil, fmt.Errorf("mounting container %q: %w", i.containerID, err) } pipeReader, pipeWriter := io.Pipe() errChan := make(chan error, 1) @@ -190,11 +190,11 @@ func (i *containerImageRef) extractRootfs(opts ExtractRootfsOptions) (io.ReadClo }() return ioutils.NewReadCloserWrapper(pipeReader, func() error { if err = pipeReader.Close(); err != nil { - err = fmt.Errorf("error closing tar archive of container %q: %w", i.containerID, err) + err = fmt.Errorf("closing tar archive of container %q: %w", i.containerID, err) } if _, err2 := i.store.Unmount(i.containerID, false); err == nil { if err2 != nil { - err2 = fmt.Errorf("error unmounting container %q: %w", i.containerID, err2) + err2 = fmt.Errorf("unmounting container %q: %w", i.containerID, err2) } err = err2 } @@ -311,7 +311,7 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System // Make a temporary directory to hold blobs. path, err := ioutil.TempDir(os.TempDir(), define.Package) if err != nil { - return nil, fmt.Errorf("error creating temporary directory to hold layer blobs: %w", err) + return nil, fmt.Errorf("creating temporary directory to hold layer blobs: %w", err) } logrus.Debugf("using %q to hold temporary data", path) defer func() { @@ -400,7 +400,7 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System // Extract this layer, one of possibly many. rc, err = i.store.Diff("", layerID, diffOptions) if err != nil { - return nil, fmt.Errorf("error extracting %s: %w", what, err) + return nil, fmt.Errorf("extracting %s: %w", what, err) } } srcHasher := digest.Canonical.Digester() @@ -408,7 +408,7 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System layerFile, err := os.OpenFile(filepath.Join(path, "layer"), os.O_CREATE|os.O_WRONLY, 0600) if err != nil { rc.Close() - return nil, fmt.Errorf("error opening file for %s: %w", what, err) + return nil, fmt.Errorf("opening file for %s: %w", what, err) } counter := ioutils.NewWriteCounter(layerFile) @@ -427,7 +427,7 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System if err != nil { layerFile.Close() rc.Close() - return nil, fmt.Errorf("error compressing %s: %w", what, err) + return nil, fmt.Errorf("compressing %s: %w", what, err) } writer := io.MultiWriter(writeCloser, srcHasher.Hash()) // Scrub any local user names that might correspond to UIDs or GIDs of @@ -478,11 +478,11 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System } if err != nil { - return nil, fmt.Errorf("error storing %s to file: %w", what, err) + return nil, fmt.Errorf("storing %s to file: %w", what, err) } if i.compression == archive.Uncompressed { if size != counter.Count { - return nil, fmt.Errorf("error storing %s to file: inconsistent layer size (copied %d, wrote %d)", what, size, counter.Count) + return nil, fmt.Errorf("storing %s to file: inconsistent layer size (copied %d, wrote %d)", what, size, counter.Count) } } else { size = counter.Count @@ -491,7 +491,7 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System // Rename the layer so that we can more easily find it by digest later. finalBlobName := filepath.Join(path, destHasher.Digest().String()) if err = os.Rename(filepath.Join(path, "layer"), finalBlobName); err != nil { - return nil, fmt.Errorf("error storing %s to file while renaming %q to %q: %w", what, filepath.Join(path, "layer"), finalBlobName, err) + return nil, fmt.Errorf("storing %s to file while renaming %q to %q: %w", what, filepath.Join(path, "layer"), finalBlobName, err) } // Add a note in the manifest about the layer. The blobs are identified by their possibly- // compressed blob digests. @@ -596,7 +596,7 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System // Encode the image configuration blob. oconfig, err := json.Marshal(&oimage) if err != nil { - return nil, fmt.Errorf("error encoding %#v as json: %w", oimage, err) + return nil, fmt.Errorf("encoding %#v as json: %w", oimage, err) } logrus.Debugf("OCIv1 config = %s", oconfig) @@ -608,14 +608,14 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System // Encode the manifest. omanifestbytes, err := json.Marshal(&omanifest) if err != nil { - return nil, fmt.Errorf("error encoding %#v as json: %w", omanifest, err) + return nil, fmt.Errorf("encoding %#v as json: %w", omanifest, err) } logrus.Debugf("OCIv1 manifest = %s", omanifestbytes) // Encode the image configuration blob. dconfig, err := json.Marshal(&dimage) if err != nil { - return nil, fmt.Errorf("error encoding %#v as json: %w", dimage, err) + return nil, fmt.Errorf("encoding %#v as json: %w", dimage, err) } logrus.Debugf("Docker v2s2 config = %s", dconfig) @@ -627,7 +627,7 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System // Encode the manifest. dmanifestbytes, err := json.Marshal(&dmanifest) if err != nil { - return nil, fmt.Errorf("error encoding %#v as json: %w", dmanifest, err) + return nil, fmt.Errorf("encoding %#v as json: %w", dmanifest, err) } logrus.Debugf("Docker v2s2 manifest = %s", dmanifestbytes) @@ -698,7 +698,7 @@ func (i *containerImageRef) Transport() types.ImageTransport { func (i *containerImageSource) Close() error { err := os.RemoveAll(i.path) if err != nil { - return fmt.Errorf("error removing layer blob directory: %w", err) + return fmt.Errorf("removing layer blob directory: %w", err) } return nil } @@ -764,13 +764,13 @@ func (i *containerImageSource) GetBlob(ctx context.Context, blob types.BlobInfo, } if err != nil || layerReadCloser == nil || size == -1 { logrus.Debugf("error reading layer %q: %v", blob.Digest.String(), err) - return nil, -1, fmt.Errorf("error opening layer blob: %w", err) + return nil, -1, fmt.Errorf("opening layer blob: %w", err) } logrus.Debugf("reading layer %q", blob.Digest.String()) closer := func() error { logrus.Debugf("finished reading layer %q", blob.Digest.String()) if err := layerReadCloser.Close(); err != nil { - return fmt.Errorf("error closing layer %q after reading: %w", blob.Digest.String(), err) + return fmt.Errorf("closing layer %q after reading: %w", blob.Digest.String(), err) } return nil } @@ -781,7 +781,7 @@ func (b *Builder) makeContainerImageRef(options CommitOptions) (*containerImageR var name reference.Named container, err := b.store.Container(b.ContainerID) if err != nil { - return nil, fmt.Errorf("error locating container %q: %w", b.ContainerID, err) + return nil, fmt.Errorf("locating container %q: %w", b.ContainerID, err) } if len(container.Names) > 0 { if parsed, err2 := reference.ParseNamed(container.Names[0]); err2 == nil { @@ -798,11 +798,11 @@ func (b *Builder) makeContainerImageRef(options CommitOptions) (*containerImageR } oconfig, err := json.Marshal(&b.OCIv1) if err != nil { - return nil, fmt.Errorf("error encoding OCI-format image configuration %#v: %w", b.OCIv1, err) + return nil, fmt.Errorf("encoding OCI-format image configuration %#v: %w", b.OCIv1, err) } dconfig, err := json.Marshal(&b.Docker) if err != nil { - return nil, fmt.Errorf("error encoding docker-format image configuration %#v: %w", b.Docker, err) + return nil, fmt.Errorf("encoding docker-format image configuration %#v: %w", b.Docker, err) } var created *time.Time if options.HistoryTimestamp != nil { @@ -858,7 +858,7 @@ func (b *Builder) makeContainerImageRef(options CommitOptions) (*containerImageR func (b *Builder) ExtractRootfs(options CommitOptions, opts ExtractRootfsOptions) (io.ReadCloser, chan error, error) { src, err := b.makeContainerImageRef(options) if err != nil { - return nil, nil, fmt.Errorf("error creating image reference for container %q to extract its contents: %w", b.ContainerID, err) + return nil, nil, fmt.Errorf("creating image reference for container %q to extract its contents: %w", b.ContainerID, err) } return src.extractRootfs(opts) } diff --git a/vendor/github.com/containers/buildah/imagebuildah/build.go b/vendor/github.com/containers/buildah/imagebuildah/build.go index a1810d6ad..293e5bc96 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/build.go +++ b/vendor/github.com/containers/buildah/imagebuildah/build.go @@ -68,7 +68,7 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B } if len(paths) == 0 { - return "", nil, errors.New("error building: no dockerfiles specified") + return "", nil, errors.New("building: no dockerfiles specified") } if len(options.Platforms) > 1 && options.IIDFile != "" { return "", nil, fmt.Errorf("building multiple images, but iidfile %q can only be used to store one image ID", options.IIDFile) @@ -138,7 +138,7 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B dinfo, err = contents.Stat() if err != nil { contents.Close() - return "", nil, fmt.Errorf("error reading info about %q: %w", dfile, err) + return "", nil, fmt.Errorf("reading info about %q: %w", dfile, err) } if dinfo.Mode().IsRegular() && dinfo.Size() == 0 { contents.Close() @@ -171,7 +171,7 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B if options.JobSemaphore == nil { if options.Jobs != nil { if *options.Jobs < 0 { - return "", nil, errors.New("error building: invalid value for jobs. It must be a positive integer") + return "", nil, errors.New("building: invalid value for jobs. It must be a positive integer") } if *options.Jobs > 0 { options.JobSemaphore = semaphore.NewWeighted(int64(*options.Jobs)) @@ -371,10 +371,10 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B return id, ref, nil } -func buildDockerfilesOnce(ctx context.Context, store storage.Store, logger *logrus.Logger, logPrefix string, options define.BuildOptions, dockerfiles []string, dockerfilecontents [][]byte) (string, reference.Canonical, error) { +func buildDockerfilesOnce(ctx context.Context, store storage.Store, logger *logrus.Logger, logPrefix string, options define.BuildOptions, containerFiles []string, dockerfilecontents [][]byte) (string, reference.Canonical, error) { mainNode, err := imagebuilder.ParseDockerfile(bytes.NewReader(dockerfilecontents[0])) if err != nil { - return "", nil, fmt.Errorf("error parsing main Dockerfile: %s: %w", dockerfiles[0], err) + return "", nil, fmt.Errorf("parsing main Dockerfile: %s: %w", containerFiles[0], err) } warnOnUnsetBuildArgs(logger, mainNode, options.Args) @@ -416,8 +416,8 @@ func buildDockerfilesOnce(ctx context.Context, store storage.Store, logger *logr for i, d := range dockerfilecontents[1:] { additionalNode, err := imagebuilder.ParseDockerfile(bytes.NewReader(d)) if err != nil { - dockerfiles := dockerfiles[1:] - return "", nil, fmt.Errorf("error parsing additional Dockerfile %s: %w", dockerfiles[i], err) + containerFiles := containerFiles[1:] + return "", nil, fmt.Errorf("parsing additional Dockerfile %s: %w", containerFiles[i], err) } mainNode.Children = append(mainNode.Children, additionalNode.Children...) } @@ -443,16 +443,16 @@ func buildDockerfilesOnce(ctx context.Context, store storage.Store, logger *logr labelLine = fmt.Sprintf("LABEL %q=%q\n", key, value) additionalNode, err := imagebuilder.ParseDockerfile(strings.NewReader(labelLine)) if err != nil { - return "", nil, fmt.Errorf("error while adding additional LABEL steps: %w", err) + return "", nil, fmt.Errorf("while adding additional LABEL steps: %w", err) } mainNode.Children = append(mainNode.Children, additionalNode.Children...) } } } - exec, err := newExecutor(logger, logPrefix, store, options, mainNode) + exec, err := newExecutor(logger, logPrefix, store, options, mainNode, containerFiles) if err != nil { - return "", nil, fmt.Errorf("error creating build executor: %w", err) + return "", nil, fmt.Errorf("creating build executor: %w", err) } b := imagebuilder.NewBuilder(options.Args) defaultContainerConfig, err := config.Default() @@ -462,7 +462,7 @@ func buildDockerfilesOnce(ctx context.Context, store storage.Store, logger *logr b.Env = append(defaultContainerConfig.GetDefaultEnv(), b.Env...) stages, err := imagebuilder.NewStages(mainNode, b) if err != nil { - return "", nil, fmt.Errorf("error reading multiple stages: %w", err) + return "", nil, fmt.Errorf("reading multiple stages: %w", err) } if options.Target != "" { stagesTargeted, ok := stages.ThroughTarget(options.Target) @@ -506,7 +506,7 @@ func preprocessContainerfileContents(logger *logrus.Logger, containerfile string cppPath, err := exec.LookPath(cppCommand) if err != nil { if errors.Is(err, exec.ErrNotFound) { - err = fmt.Errorf("error: %v: .in support requires %s to be installed", err, cppCommand) + err = fmt.Errorf("%v: .in support requires %s to be installed", err, cppCommand) } return nil, err } @@ -518,7 +518,7 @@ func preprocessContainerfileContents(logger *logrus.Logger, containerfile string if flags, ok := os.LookupEnv("BUILDAH_CPPFLAGS"); ok { args, err := shellwords.Parse(flags) if err != nil { - return nil, fmt.Errorf("error parsing BUILDAH_CPPFLAGS %q: %v", flags, err) + return nil, fmt.Errorf("parsing BUILDAH_CPPFLAGS %q: %v", flags, err) } cppArgs = append(cppArgs, args...) } @@ -536,7 +536,7 @@ func preprocessContainerfileContents(logger *logrus.Logger, containerfile string logger.Warnf("Ignoring %s\n", stderrBuffer.String()) } if stdoutBuffer.Len() == 0 { - return nil, fmt.Errorf("error preprocessing %s: preprocessor produced no output: %w", containerfile, err) + return nil, fmt.Errorf("preprocessing %s: preprocessor produced no output: %w", containerfile, err) } } return &stdoutBuffer, nil @@ -677,14 +677,14 @@ func platformsForBaseImages(ctx context.Context, logger *logrus.Logger, dockerfi func baseImages(dockerfilenames []string, dockerfilecontents [][]byte, from string, args map[string]string, additionalBuildContext map[string]*define.AdditionalBuildContext) ([]string, error) { mainNode, err := imagebuilder.ParseDockerfile(bytes.NewReader(dockerfilecontents[0])) if err != nil { - return nil, fmt.Errorf("error parsing main Dockerfile: %s: %w", dockerfilenames[0], err) + return nil, fmt.Errorf("parsing main Dockerfile: %s: %w", dockerfilenames[0], err) } for i, d := range dockerfilecontents[1:] { additionalNode, err := imagebuilder.ParseDockerfile(bytes.NewReader(d)) if err != nil { dockerfilenames := dockerfilenames[1:] - return nil, fmt.Errorf("error parsing additional Dockerfile %s: %w", dockerfilenames[i], err) + return nil, fmt.Errorf("parsing additional Dockerfile %s: %w", dockerfilenames[i], err) } mainNode.Children = append(mainNode.Children, additionalNode.Children...) } @@ -697,7 +697,7 @@ func baseImages(dockerfilenames []string, dockerfilecontents [][]byte, from stri b.Env = defaultContainerConfig.GetDefaultEnv() stages, err := imagebuilder.NewStages(mainNode, b) if err != nil { - return nil, fmt.Errorf("error reading multiple stages: %w", err) + return nil, fmt.Errorf("reading multiple stages: %w", err) } var baseImages []string nicknames := make(map[string]bool) diff --git a/vendor/github.com/containers/buildah/imagebuildah/executor.go b/vendor/github.com/containers/buildah/imagebuildah/executor.go index ddd2dfc48..d30b1356e 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/executor.go +++ b/vendor/github.com/containers/buildah/imagebuildah/executor.go @@ -82,6 +82,7 @@ type Executor struct { out io.Writer err io.Writer signaturePolicyPath string + skipUnusedStages types.OptionalBool systemContext *types.SystemContext reportWriter io.Writer isolation define.Isolation @@ -151,7 +152,7 @@ type imageTypeAndHistoryAndDiffIDs struct { } // newExecutor creates a new instance of the imagebuilder.Executor interface. -func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, options define.BuildOptions, mainNode *parser.Node) (*Executor, error) { +func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, options define.BuildOptions, mainNode *parser.Node, containerFiles []string) (*Executor, error) { defaultContainerConfig, err := config.Default() if err != nil { return nil, fmt.Errorf("failed to get container config: %w", err) @@ -159,7 +160,7 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o excludes := options.Excludes if len(excludes) == 0 { - excludes, options.IgnoreFile, err = parse.ContainerIgnoreFile(options.ContextDirectory, options.IgnoreFile) + excludes, options.IgnoreFile, err = parse.ContainerIgnoreFile(options.ContextDirectory, options.IgnoreFile, containerFiles) if err != nil { return nil, err } @@ -237,6 +238,7 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o outputFormat: options.OutputFormat, additionalTags: options.AdditionalTags, signaturePolicyPath: options.SignaturePolicyPath, + skipUnusedStages: options.SkipUnusedStages, systemContext: options.SystemContext, log: options.Log, in: options.In, @@ -402,7 +404,7 @@ func (b *Executor) waitForStage(ctx context.Context, name string, stages imagebu b.stagesSemaphore.Release(1) time.Sleep(time.Millisecond * 10) if err := b.stagesSemaphore.Acquire(ctx, 1); err != nil { - return true, fmt.Errorf("error reacquiring job semaphore: %w", err) + return true, fmt.Errorf("reacquiring job semaphore: %w", err) } } } @@ -417,20 +419,20 @@ func (b *Executor) getImageTypeAndHistoryAndDiffIDs(ctx context.Context, imageID } imageRef, err := is.Transport.ParseStoreReference(b.store, "@"+imageID) if err != nil { - return "", nil, nil, fmt.Errorf("error getting image reference %q: %w", imageID, err) + return "", nil, nil, fmt.Errorf("getting image reference %q: %w", imageID, err) } ref, err := imageRef.NewImage(ctx, nil) if err != nil { - return "", nil, nil, fmt.Errorf("error creating new image from reference to image %q: %w", imageID, err) + return "", nil, nil, fmt.Errorf("creating new image from reference to image %q: %w", imageID, err) } defer ref.Close() oci, err := ref.OCIConfig(ctx) if err != nil { - return "", nil, nil, fmt.Errorf("error getting possibly-converted OCI config of image %q: %w", imageID, err) + return "", nil, nil, fmt.Errorf("getting possibly-converted OCI config of image %q: %w", imageID, err) } manifestBytes, manifestFormat, err := ref.Manifest(ctx) if err != nil { - return "", nil, nil, fmt.Errorf("error getting manifest of image %q: %w", imageID, err) + return "", nil, nil, fmt.Errorf("getting manifest of image %q: %w", imageID, err) } if manifestFormat == "" && len(manifestBytes) > 0 { manifestFormat = manifest.GuessMIMEType(manifestBytes) @@ -539,7 +541,7 @@ func markDependencyStagesForTarget(dependencyMap map[string]*stageDependencyInfo // over each of the one or more parsed Dockerfiles and stages. func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (imageID string, ref reference.Canonical, err error) { if len(stages) == 0 { - return "", nil, errors.New("error building: no stages to build") + return "", nil, errors.New("building: no stages to build") } var cleanupImages []string cleanupStages := make(map[int]*StageExecutor) @@ -792,9 +794,10 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image return } // Skip stage if it is not needed by TargetStage - // or any of its dependency stages. + // or any of its dependency stages and `SkipUnusedStages` + // is not set to `false`. if stageDependencyInfo, ok := dependencyMap[stages[index].Name]; ok { - if !stageDependencyInfo.NeededByTarget { + if !stageDependencyInfo.NeededByTarget && b.skipUnusedStages != types.OptionalBoolFalse { logrus.Debugf("Skipping stage with Name %q and index %d since its not needed by the target stage", stages[index].Name, index) ch <- Result{ Index: index, @@ -873,18 +876,18 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image case is.Transport.Name(): img, err := is.Transport.GetStoreImage(b.store, dest) if err != nil { - return imageID, ref, fmt.Errorf("error locating just-written image %q: %w", transports.ImageName(dest), err) + return imageID, ref, fmt.Errorf("locating just-written image %q: %w", transports.ImageName(dest), err) } if len(b.additionalTags) > 0 { if err = util.AddImageNames(b.store, "", b.systemContext, img, b.additionalTags); err != nil { - return imageID, ref, fmt.Errorf("error setting image names to %v: %w", append(img.Names, b.additionalTags...), err) + return imageID, ref, fmt.Errorf("setting image names to %v: %w", append(img.Names, b.additionalTags...), err) } logrus.Debugf("assigned names %v to image %q", img.Names, img.ID) } // Report back the caller the tags applied, if any. img, err = is.Transport.GetStoreImage(b.store, dest) if err != nil { - return imageID, ref, fmt.Errorf("error locating just-written image %q: %w", transports.ImageName(dest), err) + return imageID, ref, fmt.Errorf("locating just-written image %q: %w", transports.ImageName(dest), err) } for _, name := range img.Names { fmt.Fprintf(b.out, "Successfully tagged %s\n", name) diff --git a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go index 9d8214fbd..de0e16bcc 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go +++ b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go @@ -93,10 +93,10 @@ func (s *StageExecutor) Preserve(path string) error { // except ensure that it exists. createdDirPerms := os.FileMode(0755) if err := copier.Mkdir(s.mountPoint, filepath.Join(s.mountPoint, path), copier.MkdirOptions{ChmodNew: &createdDirPerms}); err != nil { - return fmt.Errorf("error ensuring volume path exists: %w", err) + return fmt.Errorf("ensuring volume path exists: %w", err) } if err := s.volumeCacheInvalidate(path); err != nil { - return fmt.Errorf("error ensuring volume path %q is preserved: %w", filepath.Join(s.mountPoint, path), err) + return fmt.Errorf("ensuring volume path %q is preserved: %w", filepath.Join(s.mountPoint, path), err) } return nil } @@ -123,14 +123,14 @@ func (s *StageExecutor) Preserve(path string) error { archivedPath = evaluated path = string(os.PathSeparator) + symLink } else { - return fmt.Errorf("error evaluating path %q: %w", path, err) + return fmt.Errorf("evaluating path %q: %w", path, err) } st, err := os.Stat(archivedPath) if errors.Is(err, os.ErrNotExist) { createdDirPerms := os.FileMode(0755) if err = copier.Mkdir(s.mountPoint, archivedPath, copier.MkdirOptions{ChmodNew: &createdDirPerms}); err != nil { - return fmt.Errorf("error ensuring volume path exists: %w", err) + return fmt.Errorf("ensuring volume path exists: %w", err) } st, err = os.Stat(archivedPath) } @@ -142,7 +142,7 @@ func (s *StageExecutor) Preserve(path string) error { if !s.volumes.Add(path) { // This path is not a subdirectory of a volume path that we're // already preserving, so adding it to the list should work. - return fmt.Errorf("error adding %q to the volume cache", path) + return fmt.Errorf("adding %q to the volume cache", path) } s.volumeCache[path] = cacheFile // Now prune cache files for volumes that are now supplanted by this one. @@ -207,14 +207,14 @@ func (s *StageExecutor) volumeCacheSaveVFS() (mounts []specs.Mount, err error) { for cachedPath, cacheFile := range s.volumeCache { archivedPath, err := copier.Eval(s.mountPoint, filepath.Join(s.mountPoint, cachedPath), copier.EvalOptions{}) if err != nil { - return nil, fmt.Errorf("error evaluating volume path: %w", err) + return nil, fmt.Errorf("evaluating volume path: %w", err) } relativePath, err := filepath.Rel(s.mountPoint, archivedPath) if err != nil { - return nil, fmt.Errorf("error converting %q into a path relative to %q: %w", archivedPath, s.mountPoint, err) + return nil, fmt.Errorf("converting %q into a path relative to %q: %w", archivedPath, s.mountPoint, err) } if strings.HasPrefix(relativePath, ".."+string(os.PathSeparator)) { - return nil, fmt.Errorf("error converting %q into a path relative to %q", archivedPath, s.mountPoint) + return nil, fmt.Errorf("converting %q into a path relative to %q", archivedPath, s.mountPoint) } _, err = os.Stat(cacheFile) if err == nil { @@ -226,7 +226,7 @@ func (s *StageExecutor) volumeCacheSaveVFS() (mounts []specs.Mount, err error) { } createdDirPerms := os.FileMode(0755) if err := copier.Mkdir(s.mountPoint, archivedPath, copier.MkdirOptions{ChmodNew: &createdDirPerms}); err != nil { - return nil, fmt.Errorf("error ensuring volume path exists: %w", err) + return nil, fmt.Errorf("ensuring volume path exists: %w", err) } logrus.Debugf("caching contents of volume %q in %q", archivedPath, cacheFile) cache, err := os.Create(cacheFile) @@ -236,12 +236,12 @@ func (s *StageExecutor) volumeCacheSaveVFS() (mounts []specs.Mount, err error) { defer cache.Close() rc, err := chrootarchive.Tar(archivedPath, nil, s.mountPoint) if err != nil { - return nil, fmt.Errorf("error archiving %q: %w", archivedPath, err) + return nil, fmt.Errorf("archiving %q: %w", archivedPath, err) } defer rc.Close() _, err = io.Copy(cache, rc) if err != nil { - return nil, fmt.Errorf("error archiving %q to %q: %w", archivedPath, cacheFile, err) + return nil, fmt.Errorf("archiving %q to %q: %w", archivedPath, cacheFile, err) } mount := specs.Mount{ Source: archivedPath, @@ -259,7 +259,7 @@ func (s *StageExecutor) volumeCacheRestoreVFS() (err error) { for cachedPath, cacheFile := range s.volumeCache { archivedPath, err := copier.Eval(s.mountPoint, filepath.Join(s.mountPoint, cachedPath), copier.EvalOptions{}) if err != nil { - return fmt.Errorf("error evaluating volume path: %w", err) + return fmt.Errorf("evaluating volume path: %w", err) } logrus.Debugf("restoring contents of volume %q from %q", archivedPath, cacheFile) cache, err := os.Open(cacheFile) @@ -276,7 +276,7 @@ func (s *StageExecutor) volumeCacheRestoreVFS() (err error) { } err = chrootarchive.Untar(cache, archivedPath, nil) if err != nil { - return fmt.Errorf("error extracting archive at %q: %w", archivedPath, err) + return fmt.Errorf("extracting archive at %q: %w", archivedPath, err) } if st, ok := s.volumeCacheInfo[cachedPath]; ok { if err := os.Chmod(archivedPath, st.Mode()); err != nil { @@ -488,7 +488,7 @@ func (s *StageExecutor) runStageMountPoints(mountList []string) (map[string]inte if len(arr) < 2 { return nil, fmt.Errorf("Invalid --mount command: %s", flag) } - tokens := strings.Split(arr[1], ",") + tokens := strings.Split(flag, ",") for _, val := range tokens { kv := strings.SplitN(val, "=", 2) switch kv[0] { @@ -593,7 +593,7 @@ func (s *StageExecutor) Run(run imagebuilder.Run, config docker.Config) error { if stdin == nil { devNull, err := os.Open(os.DevNull) if err != nil { - return fmt.Errorf("error opening %q for reading: %v", os.DevNull, err) + return fmt.Errorf("opening %q for reading: %v", os.DevNull, err) } defer devNull.Close() stdin = devNull @@ -602,6 +602,7 @@ func (s *StageExecutor) Run(run imagebuilder.Run, config docker.Config) error { Args: s.executor.runtimeArgs, Cmd: config.Cmd, ContextDir: s.executor.contextDir, + ConfigureNetwork: s.executor.configureNetwork, Entrypoint: config.Entrypoint, Env: config.Env, Hostname: config.Hostname, @@ -624,10 +625,9 @@ func (s *StageExecutor) Run(run imagebuilder.Run, config docker.Config) error { User: config.User, WorkingDir: config.WorkingDir, } + if config.NetworkDisabled { options.ConfigureNetwork = buildah.NetworkDisabled - } else { - options.ConfigureNetwork = buildah.NetworkEnabled } args := run.Args @@ -686,7 +686,7 @@ func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBCo base, err := ib.From(node) if err != nil { logrus.Debugf("prepare(node.Children=%#v)", node.Children) - return nil, fmt.Errorf("error determining starting point for build: %w", err) + return nil, fmt.Errorf("determining starting point for build: %w", err) } from = base } @@ -755,7 +755,7 @@ func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBCo builder, err = buildah.NewBuilder(ctx, s.executor.store, builderOptions) if err != nil { - return nil, fmt.Errorf("error creating build container: %w", err) + return nil, fmt.Errorf("creating build container: %w", err) } // If executor's ProcessLabel and MountLabel is empty means this is the first stage @@ -817,7 +817,7 @@ func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBCo if err2 := builder.Delete(); err2 != nil { logrus.Debugf("error deleting container which we failed to update: %v", err2) } - return nil, fmt.Errorf("error updating build context: %w", err) + return nil, fmt.Errorf("updating build context: %w", err) } } mountPoint, err := builder.Mount(builder.MountLabel) @@ -825,7 +825,7 @@ func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBCo if err2 := builder.Delete(); err2 != nil { logrus.Debugf("error deleting container which we failed to mount: %v", err2) } - return nil, fmt.Errorf("error mounting new container: %w", err) + return nil, fmt.Errorf("mounting new container: %w", err) } if rebase { // Make this our "current" working container. @@ -1014,7 +1014,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, // the case, we need to commit() to create a new image. logCommit(s.output, -1) if imgID, ref, err = s.commit(ctx, s.getCreatedBy(nil, ""), false, s.output, s.executor.squash); err != nil { - return "", nil, fmt.Errorf("error committing base container: %w", err) + return "", nil, fmt.Errorf("committing base container: %w", err) } // Generate build output if needed. if canGenerateBuildOutput { @@ -1064,7 +1064,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, // Resolve any arguments in this instruction. step := ib.Step() if err := step.Resolve(node); err != nil { - return "", nil, fmt.Errorf("error resolving step %+v: %w", *node, err) + return "", nil, fmt.Errorf("resolving step %+v: %w", *node, err) } logrus.Debugf("Parsed Step: %+v", *step) if !s.executor.quiet { @@ -1150,7 +1150,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, err := ib.Run(step, s, noRunsRemaining) if err != nil { logrus.Debugf("Error building at step %+v: %v", *step, err) - return "", nil, fmt.Errorf("error building at STEP \"%s\": %w", step.Message, err) + return "", nil, fmt.Errorf("building at STEP \"%s\": %w", step.Message, err) } // In case we added content, retrieve its digest. addedContentSummary := s.getContentSummaryAfterAddingContent() @@ -1175,7 +1175,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, logCommit(s.output, i) imgID, ref, err = s.commit(ctx, s.getCreatedBy(node, addedContentSummary), false, s.output, s.executor.squash) if err != nil { - return "", nil, fmt.Errorf("error committing container for step %+v: %w", *step, err) + return "", nil, fmt.Errorf("committing container for step %+v: %w", *step, err) } logImageID(imgID) // Generate build output if needed. @@ -1236,7 +1236,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, if canMatchCacheOnlyAfterRun { if err = ib.Run(step, s, noRunsRemaining); err != nil { logrus.Debugf("Error building at step %+v: %v", *step, err) - return "", nil, fmt.Errorf("error building at STEP \"%s\": %w", step.Message, err) + return "", nil, fmt.Errorf("building at STEP \"%s\": %w", step.Message, err) } // Retrieve the digest info for the content that we just copied // into the rootfs. @@ -1251,7 +1251,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, } cacheID, err = s.intermediateImageExists(ctx, node, addedContentSummary, s.stepRequiresLayer(step)) if err != nil { - return "", nil, fmt.Errorf("error checking if cached image exists from a previous build: %w", err) + return "", nil, fmt.Errorf("checking if cached image exists from a previous build: %w", err) } // All the best effort to find cache on localstorage have failed try pulling // cache from remote repo if `--cache-from` was configured. @@ -1263,7 +1263,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, logCachePulled(cacheKey) cacheID, err = s.intermediateImageExists(ctx, node, addedContentSummary, s.stepRequiresLayer(step)) if err != nil { - return "", nil, fmt.Errorf("error checking if cached image exists from a previous build: %w", err) + return "", nil, fmt.Errorf("checking if cached image exists from a previous build: %w", err) } if cacheID != "" { pulledAndUsedCacheImage = true @@ -1282,7 +1282,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, // Process the instruction directly. if err = ib.Run(step, s, noRunsRemaining); err != nil { logrus.Debugf("Error building at step %+v: %v", *step, err) - return "", nil, fmt.Errorf("error building at STEP \"%s\": %w", step.Message, err) + return "", nil, fmt.Errorf("building at STEP \"%s\": %w", step.Message, err) } // In case we added content, retrieve its digest. @@ -1300,7 +1300,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, if checkForLayers { cacheID, err = s.intermediateImageExists(ctx, node, addedContentSummary, s.stepRequiresLayer(step)) if err != nil { - return "", nil, fmt.Errorf("error checking if cached image exists from a previous build: %w", err) + return "", nil, fmt.Errorf("checking if cached image exists from a previous build: %w", err) } } } else { @@ -1318,7 +1318,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, err := ib.Run(step, s, noRunsRemaining) if err != nil { logrus.Debugf("Error building at step %+v: %v", *step, err) - return "", nil, fmt.Errorf("error building at STEP \"%s\": %w", step.Message, err) + return "", nil, fmt.Errorf("building at STEP \"%s\": %w", step.Message, err) } } } @@ -1351,7 +1351,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, // can be part of build-cache. imgID, ref, err = s.commit(ctx, s.getCreatedBy(node, addedContentSummary), !s.stepRequiresLayer(step), commitName, false) if err != nil { - return "", nil, fmt.Errorf("error committing container for step %+v: %w", *step, err) + return "", nil, fmt.Errorf("committing container for step %+v: %w", *step, err) } // Generate build output if needed. if canGenerateBuildOutput { @@ -1385,7 +1385,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, // is the last instruction of the last stage. imgID, ref, err = s.commit(ctx, s.getCreatedBy(node, addedContentSummary), !s.stepRequiresLayer(step), commitName, true) if err != nil { - return "", nil, fmt.Errorf("error committing final squash step %+v: %w", *step, err) + return "", nil, fmt.Errorf("committing final squash step %+v: %w", *step, err) } // Generate build output if needed. if canGenerateBuildOutput { @@ -1436,7 +1436,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, // ID that we really should not be pulling anymore (see // containers/podman/issues/10307). if _, err := s.prepare(ctx, imgID, false, true, define.PullNever); err != nil { - return "", nil, fmt.Errorf("error preparing container for next step: %w", err) + return "", nil, fmt.Errorf("preparing container for next step: %w", err) } } } @@ -1648,27 +1648,27 @@ func (s *StageExecutor) tagExistingImage(ctx context.Context, cacheID, output st // Look up the source image, expecting it to be in local storage src, err := is.Transport.ParseStoreReference(s.executor.store, cacheID) if err != nil { - return "", nil, fmt.Errorf("error getting source imageReference for %q: %w", cacheID, err) + return "", nil, fmt.Errorf("getting source imageReference for %q: %w", cacheID, err) } options := cp.Options{ RemoveSignatures: true, // more like "ignore signatures", since they don't get removed when src and dest are the same image } manifestBytes, err := cp.Image(ctx, policyContext, dest, src, &options) if err != nil { - return "", nil, fmt.Errorf("error copying image %q: %w", cacheID, err) + return "", nil, fmt.Errorf("copying image %q: %w", cacheID, err) } manifestDigest, err := manifest.Digest(manifestBytes) if err != nil { - return "", nil, fmt.Errorf("error computing digest of manifest for image %q: %w", cacheID, err) + return "", nil, fmt.Errorf("computing digest of manifest for image %q: %w", cacheID, err) } img, err := is.Transport.GetStoreImage(s.executor.store, dest) if err != nil { - return "", nil, fmt.Errorf("error locating new copy of image %q (i.e., %q): %w", cacheID, transports.ImageName(dest), err) + return "", nil, fmt.Errorf("locating new copy of image %q (i.e., %q): %w", cacheID, transports.ImageName(dest), err) } var ref reference.Canonical if dref := dest.DockerReference(); dref != nil { if ref, err = reference.WithDigest(dref, manifestDigest); err != nil { - return "", nil, fmt.Errorf("error computing canonical reference for new image %q (i.e., %q): %w", cacheID, transports.ImageName(dest), err) + return "", nil, fmt.Errorf("computing canonical reference for new image %q (i.e., %q): %w", cacheID, transports.ImageName(dest), err) } } return img.ID, ref, nil @@ -1688,7 +1688,7 @@ func (s *StageExecutor) generateCacheKey(ctx context.Context, currNode *parser.N if s.builder.FromImageID != "" { manifestType, baseHistory, diffIDs, err = s.executor.getImageTypeAndHistoryAndDiffIDs(ctx, s.builder.FromImageID) if err != nil { - return "", fmt.Errorf("error getting history of base image %q: %w", s.builder.FromImageID, err) + return "", fmt.Errorf("getting history of base image %q: %w", s.builder.FromImageID, err) } for i := 0; i < len(diffIDs); i++ { fmt.Fprintln(hash, diffIDs[i].String()) @@ -1788,14 +1788,14 @@ func (s *StageExecutor) intermediateImageExists(ctx context.Context, currNode *p // Get the list of images available in the image store images, err := s.executor.store.Images() if err != nil { - return "", fmt.Errorf("error getting image list from store: %w", err) + return "", fmt.Errorf("getting image list from store: %w", err) } var baseHistory []v1.History var baseDiffIDs []digest.Digest if s.builder.FromImageID != "" { _, baseHistory, baseDiffIDs, err = s.executor.getImageTypeAndHistoryAndDiffIDs(ctx, s.builder.FromImageID) if err != nil { - return "", fmt.Errorf("error getting history of base image %q: %w", s.builder.FromImageID, err) + return "", fmt.Errorf("getting history of base image %q: %w", s.builder.FromImageID, err) } } for _, image := range images { @@ -1815,7 +1815,7 @@ func (s *StageExecutor) intermediateImageExists(ctx context.Context, currNode *p if image.TopLayer != "" { imageTopLayer, err = s.executor.store.Layer(image.TopLayer) if err != nil { - return "", fmt.Errorf("error getting top layer info: %w", err) + return "", fmt.Errorf("getting top layer info: %w", err) } // Figure out which layer from this image we should // compare our container's base layer to. @@ -2010,7 +2010,7 @@ func (s *StageExecutor) commit(ctx context.Context, createdBy string, emptyLayer if imageRef != nil { if dref := imageRef.DockerReference(); dref != nil { if ref, err = reference.WithDigest(dref, manifestDigest); err != nil { - return "", nil, fmt.Errorf("error computing canonical reference for new image %q: %w", imgID, err) + return "", nil, fmt.Errorf("computing canonical reference for new image %q: %w", imgID, err) } } } diff --git a/vendor/github.com/containers/buildah/import.go b/vendor/github.com/containers/buildah/import.go index 70dccad94..9f925a1db 100644 --- a/vendor/github.com/containers/buildah/import.go +++ b/vendor/github.com/containers/buildah/import.go @@ -34,14 +34,14 @@ func importBuilderDataFromImage(ctx context.Context, store storage.Store, system } src, err := ref.NewImageSource(ctx, systemContext) if err != nil { - return nil, fmt.Errorf("error instantiating image source: %w", err) + return nil, fmt.Errorf("instantiating image source: %w", err) } defer src.Close() imageDigest := "" manifestBytes, manifestType, err := src.GetManifest(ctx, nil) if err != nil { - return nil, fmt.Errorf("error loading image manifest for %q: %w", transports.ImageName(ref), err) + return nil, fmt.Errorf("loading image manifest for %q: %w", transports.ImageName(ref), err) } if manifestDigest, err := manifest.Digest(manifestBytes); err == nil { imageDigest = manifestDigest.String() @@ -51,18 +51,18 @@ func importBuilderDataFromImage(ctx context.Context, store storage.Store, system if manifest.MIMETypeIsMultiImage(manifestType) { list, err := manifest.ListFromBlob(manifestBytes, manifestType) if err != nil { - return nil, fmt.Errorf("error parsing image manifest for %q as list: %w", transports.ImageName(ref), err) + return nil, fmt.Errorf("parsing image manifest for %q as list: %w", transports.ImageName(ref), err) } instance, err := list.ChooseInstance(systemContext) if err != nil { - return nil, fmt.Errorf("error finding an appropriate image in manifest list %q: %w", transports.ImageName(ref), err) + return nil, fmt.Errorf("finding an appropriate image in manifest list %q: %w", transports.ImageName(ref), err) } instanceDigest = &instance } image, err := image.FromUnparsedImage(ctx, systemContext, image.UnparsedInstance(src, instanceDigest)) if err != nil { - return nil, fmt.Errorf("error instantiating image for %q instance %q: %w", transports.ImageName(ref), instanceDigest, err) + return nil, fmt.Errorf("instantiating image for %q instance %q: %w", transports.ImageName(ref), instanceDigest, err) } imageName := "" @@ -73,7 +73,7 @@ func importBuilderDataFromImage(ctx context.Context, store storage.Store, system if img.TopLayer != "" { layer, err4 := store.Layer(img.TopLayer) if err4 != nil { - return nil, fmt.Errorf("error reading information about image's top layer: %w", err4) + return nil, fmt.Errorf("reading information about image's top layer: %w", err4) } uidmap, gidmap = convertStorageIDMaps(layer.UIDMap, layer.GIDMap) } @@ -110,7 +110,7 @@ func importBuilderDataFromImage(ctx context.Context, store storage.Store, system } if err := builder.initConfig(ctx, image, systemContext); err != nil { - return nil, fmt.Errorf("error preparing image configuration: %w", err) + return nil, fmt.Errorf("preparing image configuration: %w", err) } return builder, nil @@ -147,7 +147,7 @@ func importBuilder(ctx context.Context, store storage.Store, options ImportOptio err = builder.Save() if err != nil { - return nil, fmt.Errorf("error saving builder state: %w", err) + return nil, fmt.Errorf("saving builder state: %w", err) } return builder, nil @@ -167,7 +167,7 @@ func importBuilderFromImage(ctx context.Context, store storage.Store, options Im builder, err := importBuilderDataFromImage(ctx, store, systemContext, img.ID, "", "") if err != nil { - return nil, fmt.Errorf("error importing build settings from image %q: %w", options.Image, err) + return nil, fmt.Errorf("importing build settings from image %q: %w", options.Image, err) } builder.setupLogger() diff --git a/vendor/github.com/containers/buildah/install.md b/vendor/github.com/containers/buildah/install.md index 4bd6aa821..ce9b38030 100644 --- a/vendor/github.com/containers/buildah/install.md +++ b/vendor/github.com/containers/buildah/install.md @@ -23,11 +23,11 @@ sudo yum -y install buildah #### [Debian](https://debian.org) The buildah package is available in -the [Bullseye (testing) branch](https://packages.debian.org/bullseye/buildah), which -will be the next stable release (Debian 11) as well as Debian Unstable/Sid. +the [Bullseye](https://packages.debian.org/bullseye/buildah), which +is the current stable release (Debian 11), as well as Debian Unstable/Sid. ```bash -# Debian Testing/Bullseye or Unstable/Sid +# Debian Stable/Bullseye or Unstable/Sid sudo apt-get update sudo apt-get -y install buildah ``` diff --git a/vendor/github.com/containers/buildah/internal/parse/parse.go b/vendor/github.com/containers/buildah/internal/parse/parse.go index f0ea3c820..23af9aeb0 100644 --- a/vendor/github.com/containers/buildah/internal/parse/parse.go +++ b/vendor/github.com/containers/buildah/internal/parse/parse.go @@ -59,6 +59,9 @@ func GetBindMount(ctx *types.SystemContext, args []string, contextDir string, st for _, val := range args { kv := strings.SplitN(val, "=", 2) switch kv[0] { + case "type": + // This is already processed + continue case "bind-nonrecursive": newMount.Options = append(newMount.Options, "bind") bindNonRecursive = true @@ -209,6 +212,9 @@ func GetCacheMount(args []string, store storage.Store, imageMountLabel string, a for _, val := range args { kv := strings.SplitN(val, "=", 2) switch kv[0] { + case "type": + // This is already processed + continue case "nosuid", "nodev", "noexec": // TODO: detect duplication of these options. // (Is this necessary?) @@ -497,6 +503,8 @@ func GetVolumes(ctx *types.SystemContext, store storage.Store, volumes []string, // buildah run --mount type=bind,src=/etc/resolv.conf,target=/etc/resolv.conf ... // buildah run --mount type=tmpfs,target=/dev/shm ... func getMounts(ctx *types.SystemContext, store storage.Store, mounts []string, contextDir string) (map[string]specs.Mount, []string, []string, error) { + // If `type` is not set default to "bind" + mountType := TypeBind finalMounts := make(map[string]specs.Mount) mountedImages := make([]string, 0) lockedTargets := make([]string, 0) @@ -507,19 +515,20 @@ func getMounts(ctx *types.SystemContext, store storage.Store, mounts []string, c // to allow a more robust parsing of the mount format and to give // precise errors regarding supported format versus supported options. for _, mount := range mounts { - arr := strings.SplitN(mount, ",", 2) - if len(arr) < 2 { + tokens := strings.Split(mount, ",") + if len(tokens) < 2 { return nil, mountedImages, lockedTargets, fmt.Errorf("%q: %w", mount, errInvalidSyntax) } - kv := strings.Split(arr[0], "=") - // TODO: type is not explicitly required in Docker. - // If not specified, it defaults to "volume". - if len(kv) != 2 || kv[0] != "type" { - return nil, mountedImages, lockedTargets, fmt.Errorf("%q: %w", mount, errInvalidSyntax) + for _, field := range tokens { + if strings.HasPrefix(field, "type=") { + kv := strings.Split(field, "=") + if len(kv) != 2 { + return nil, mountedImages, lockedTargets, fmt.Errorf("%q: %w", mount, errInvalidSyntax) + } + mountType = kv[1] + } } - - tokens := strings.Split(arr[1], ",") - switch kv[1] { + switch mountType { case TypeBind: mount, image, err := GetBindMount(ctx, tokens, contextDir, store, "", nil) if err != nil { @@ -550,7 +559,7 @@ func getMounts(ctx *types.SystemContext, store storage.Store, mounts []string, c } finalMounts[mount.Destination] = mount default: - return nil, mountedImages, lockedTargets, fmt.Errorf("invalid filesystem type %q", kv[1]) + return nil, mountedImages, lockedTargets, fmt.Errorf("invalid filesystem type %q", mountType) } } @@ -569,6 +578,9 @@ func GetTmpfsMount(args []string) (specs.Mount, error) { for _, val := range args { kv := strings.SplitN(val, "=", 2) switch kv[0] { + case "type": + // This is already processed + continue case "ro", "nosuid", "nodev", "noexec": newMount.Options = append(newMount.Options, kv[0]) case "readonly": diff --git a/vendor/github.com/containers/buildah/mount.go b/vendor/github.com/containers/buildah/mount.go index 3b1ff5820..932c1bb78 100644 --- a/vendor/github.com/containers/buildah/mount.go +++ b/vendor/github.com/containers/buildah/mount.go @@ -7,13 +7,13 @@ import "fmt" func (b *Builder) Mount(label string) (string, error) { mountpoint, err := b.store.Mount(b.ContainerID, label) if err != nil { - return "", fmt.Errorf("error mounting build container %q: %w", b.ContainerID, err) + return "", fmt.Errorf("mounting build container %q: %w", b.ContainerID, err) } b.MountPoint = mountpoint err = b.Save() if err != nil { - return "", fmt.Errorf("error saving updated state for build container %q: %w", b.ContainerID, err) + return "", fmt.Errorf("saving updated state for build container %q: %w", b.ContainerID, err) } return mountpoint, nil } @@ -21,7 +21,7 @@ func (b *Builder) Mount(label string) (string, error) { func (b *Builder) setMountPoint(mountPoint string) error { b.MountPoint = mountPoint if err := b.Save(); err != nil { - return fmt.Errorf("error saving updated state for build container %q: %w", b.ContainerID, err) + return fmt.Errorf("saving updated state for build container %q: %w", b.ContainerID, err) } return nil } @@ -30,17 +30,17 @@ func (b *Builder) setMountPoint(mountPoint string) error { func (b *Builder) Mounted() (bool, error) { mountCnt, err := b.store.Mounted(b.ContainerID) if err != nil { - return false, fmt.Errorf("error determining if mounting build container %q is mounted: %w", b.ContainerID, err) + return false, fmt.Errorf("determining if mounting build container %q is mounted: %w", b.ContainerID, err) } mounted := mountCnt > 0 if mounted && b.MountPoint == "" { ctr, err := b.store.Container(b.ContainerID) if err != nil { - return mountCnt > 0, fmt.Errorf("error determining if mounting build container %q is mounted: %w", b.ContainerID, err) + return mountCnt > 0, fmt.Errorf("determining if mounting build container %q is mounted: %w", b.ContainerID, err) } layer, err := b.store.Layer(ctr.LayerID) if err != nil { - return mountCnt > 0, fmt.Errorf("error determining if mounting build container %q is mounted: %w", b.ContainerID, err) + return mountCnt > 0, fmt.Errorf("determining if mounting build container %q is mounted: %w", b.ContainerID, err) } return mounted, b.setMountPoint(layer.MountPoint) } diff --git a/vendor/github.com/containers/buildah/new.go b/vendor/github.com/containers/buildah/new.go index 0ebda161b..11f0933bc 100644 --- a/vendor/github.com/containers/buildah/new.go +++ b/vendor/github.com/containers/buildah/new.go @@ -190,12 +190,12 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions if ref != nil { srcSrc, err := ref.NewImageSource(ctx, systemContext) if err != nil { - return nil, fmt.Errorf("error instantiating image for %q: %w", transports.ImageName(ref), err) + return nil, fmt.Errorf("instantiating image for %q: %w", transports.ImageName(ref), err) } defer srcSrc.Close() manifestBytes, manifestType, err := srcSrc.GetManifest(ctx, nil) if err != nil { - return nil, fmt.Errorf("error loading image manifest for %q: %w", transports.ImageName(ref), err) + return nil, fmt.Errorf("loading image manifest for %q: %w", transports.ImageName(ref), err) } if manifestDigest, err := manifest.Digest(manifestBytes); err == nil { imageDigest = manifestDigest.String() @@ -204,17 +204,17 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions if manifest.MIMETypeIsMultiImage(manifestType) { list, err := manifest.ListFromBlob(manifestBytes, manifestType) if err != nil { - return nil, fmt.Errorf("error parsing image manifest for %q as list: %w", transports.ImageName(ref), err) + return nil, fmt.Errorf("parsing image manifest for %q as list: %w", transports.ImageName(ref), err) } instance, err := list.ChooseInstance(systemContext) if err != nil { - return nil, fmt.Errorf("error finding an appropriate image in manifest list %q: %w", transports.ImageName(ref), err) + return nil, fmt.Errorf("finding an appropriate image in manifest list %q: %w", transports.ImageName(ref), err) } instanceDigest = &instance } src, err = image.FromUnparsedImage(ctx, systemContext, image.UnparsedInstance(srcSrc, instanceDigest)) if err != nil { - return nil, fmt.Errorf("error instantiating image for %q instance %q: %w", transports.ImageName(ref), instanceDigest, err) + return nil, fmt.Errorf("instantiating image for %q instance %q: %w", transports.ImageName(ref), instanceDigest, err) } } @@ -263,7 +263,7 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions break } if !errors.Is(err, storage.ErrDuplicateName) || options.Container != "" { - return nil, fmt.Errorf("error creating container: %w", err) + return nil, fmt.Errorf("creating container: %w", err) } tmpName = fmt.Sprintf("%s-%d", name, rand.Int()%conflict) conflict = conflict * 10 @@ -333,16 +333,16 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions if options.Mount { _, err = builder.Mount(container.MountLabel()) if err != nil { - return nil, fmt.Errorf("error mounting build container %q: %w", builder.ContainerID, err) + return nil, fmt.Errorf("mounting build container %q: %w", builder.ContainerID, err) } } if err := builder.initConfig(ctx, src, systemContext); err != nil { - return nil, fmt.Errorf("error preparing image configuration: %w", err) + return nil, fmt.Errorf("preparing image configuration: %w", err) } err = builder.Save() if err != nil { - return nil, fmt.Errorf("error saving builder state for container %q: %w", builder.ContainerID, err) + return nil, fmt.Errorf("saving builder state for container %q: %w", builder.ContainerID, err) } return builder, nil diff --git a/vendor/github.com/containers/buildah/pkg/chrootuser/user.go b/vendor/github.com/containers/buildah/pkg/chrootuser/user.go index 9fffc6d70..4614ecf90 100644 --- a/vendor/github.com/containers/buildah/pkg/chrootuser/user.go +++ b/vendor/github.com/containers/buildah/pkg/chrootuser/user.go @@ -76,9 +76,9 @@ func GetUser(rootdir, userspec string) (uint32, uint32, string, error) { return uint32(uid64), uint32(gid64), homedir, nil } - err = fmt.Errorf("error determining run uid: %w", uerr) + err = fmt.Errorf("determining run uid: %w", uerr) if uerr == nil { - err = fmt.Errorf("error determining run gid: %w", gerr) + err = fmt.Errorf("determining run gid: %w", gerr) } return 0, 0, homedir, err @@ -94,7 +94,7 @@ func GetGroup(rootdir, groupspec string) (uint32, error) { gid64, gerr = lookupGroupInContainer(rootdir, groupspec) } if gerr != nil { - return 0, fmt.Errorf("error looking up group for gid %q: %w", groupspec, gerr) + return 0, fmt.Errorf("looking up group for gid %q: %w", groupspec, gerr) } return uint32(gid64), nil } @@ -103,7 +103,7 @@ func GetGroup(rootdir, groupspec string) (uint32, error) { func GetAdditionalGroupsForUser(rootdir string, userid uint64) ([]uint32, error) { gids, err := lookupAdditionalGroupsForUIDInContainer(rootdir, userid) if err != nil { - return nil, fmt.Errorf("error looking up supplemental groups for uid %d: %w", userid, err) + return nil, fmt.Errorf("looking up supplemental groups for uid %d: %w", userid, err) } return gids, nil } diff --git a/vendor/github.com/containers/buildah/pkg/cli/build.go b/vendor/github.com/containers/buildah/pkg/cli/build.go index 4ff104a4b..99a78d853 100644 --- a/vendor/github.com/containers/buildah/pkg/cli/build.go +++ b/vendor/github.com/containers/buildah/pkg/cli/build.go @@ -20,6 +20,8 @@ import ( "github.com/containers/buildah/pkg/util" "github.com/containers/common/pkg/auth" "github.com/containers/image/v5/docker/reference" + "github.com/containers/image/v5/types" + "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -47,6 +49,18 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) ( output := "" cleanTmpFile := false tags := []string{} + if iopts.Network == "none" { + if c.Flag("dns").Changed { + return options, nil, nil, errors.New("the --dns option cannot be used with --network=none") + } + if c.Flag("dns-option").Changed { + return options, nil, nil, errors.New("the --dns-option option cannot be used with --network=none") + } + if c.Flag("dns-search").Changed { + return options, nil, nil, errors.New("the --dns-search option cannot be used with --network=none") + } + + } if c.Flag("tag").Changed { tags = iopts.Tag if len(tags) > 0 { @@ -147,7 +161,7 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) ( // The context directory could be a URL. Try to handle that. tempDir, subDir, err := define.TempDirForURL("", "buildah", cliArgs[0]) if err != nil { - return options, nil, nil, fmt.Errorf("error prepping temporary context directory: %w", err) + return options, nil, nil, fmt.Errorf("prepping temporary context directory: %w", err) } if tempDir != "" { // We had to download it to a temporary directory. @@ -158,7 +172,7 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) ( // Nope, it was local. Use it as is. absDir, err := filepath.Abs(cliArgs[0]) if err != nil { - return options, nil, nil, fmt.Errorf("error determining path to directory: %w", err) + return options, nil, nil, fmt.Errorf("determining path to directory: %w", err) } contextDir = absDir } @@ -176,7 +190,7 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) ( contextDir, err = filepath.EvalSymlinks(contextDir) if err != nil { - return options, nil, nil, fmt.Errorf("error evaluating symlinks in build context path: %w", err) + return options, nil, nil, fmt.Errorf("evaluating symlinks in build context path: %w", err) } var stdin io.Reader @@ -197,7 +211,7 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) ( systemContext, err := parse.SystemContextFromOptions(c) if err != nil { - return options, nil, nil, fmt.Errorf("error building system context: %w", err) + return options, nil, nil, fmt.Errorf("building system context: %w", err) } isolation, err := parse.IsolationOption(iopts.Isolation) @@ -253,7 +267,7 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) ( } usernsOption, idmappingOptions, err := parse.IDMappingOptions(c, isolation) if err != nil { - return options, nil, nil, fmt.Errorf("error parsing ID mapping options: %w", err) + return options, nil, nil, fmt.Errorf("parsing ID mapping options: %w", err) } namespaceOptions.AddOrReplace(usernsOption...) @@ -269,7 +283,7 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) ( var excludes []string if iopts.IgnoreFile != "" { - if excludes, _, err = parse.ContainerIgnoreFile(contextDir, iopts.IgnoreFile); err != nil { + if excludes, _, err = parse.ContainerIgnoreFile(contextDir, iopts.IgnoreFile, containerfiles); err != nil { return options, nil, nil, err } } @@ -309,6 +323,18 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) ( if err != nil { return options, nil, nil, fmt.Errorf("unable to parse value provided %q as --cache-ttl: %w", iopts.CacheTTL, err) } + // If user explicitly specified `--cache-ttl=0s` + // it would effectively mean that user is asking + // to use no cache at all. In such use cases + // buildah can skip looking for cache entierly + // by setting `--no-cache=true` internally. + if int64(cacheTTL) == 0 { + logrus.Debug("Setting --no-cache=true since --cache-ttl was set to 0s which effectively means user wants to ignore cache") + if c.Flag("no-cache").Changed && !iopts.NoCache { + return options, nil, nil, fmt.Errorf("cannot use --cache-ttl with duration as 0 and --no-cache=false") + } + iopts.NoCache = true + } } var pullPushRetryDelay time.Duration pullPushRetryDelay, err = time.ParseDuration(iopts.RetryDelay) @@ -318,6 +344,16 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) ( // Following log line is used in integration test. logrus.Debugf("Setting MaxPullPushRetries to %d and PullPushRetryDelay to %v", iopts.Retry, pullPushRetryDelay) + if c.Flag("network").Changed && c.Flag("isolation").Changed { + if isolation == define.IsolationChroot { + if ns := namespaceOptions.Find(string(specs.NetworkNamespace)); ns != nil { + if !ns.Host { + return options, nil, nil, fmt.Errorf("cannot set --network other than host with --isolation %s", c.Flag("isolation").Value.String()) + } + } + } + } + options = define.BuildOptions{ AddCapabilities: iopts.CapAdd, AdditionalBuildContexts: additionalBuildContext, @@ -378,6 +414,7 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) ( RusageLogFile: iopts.RusageLogFile, SignBy: iopts.SignBy, SignaturePolicyPath: iopts.SignaturePolicy, + SkipUnusedStages: types.NewOptionalBool(iopts.SkipUnusedStages), Squash: iopts.Squash, SystemContext: systemContext, Target: iopts.Target, diff --git a/vendor/github.com/containers/buildah/pkg/cli/common.go b/vendor/github.com/containers/buildah/pkg/cli/common.go index 00b6bd33b..7f42210b5 100644 --- a/vendor/github.com/containers/buildah/pkg/cli/common.go +++ b/vendor/github.com/containers/buildah/pkg/cli/common.go @@ -89,6 +89,7 @@ type BudResults struct { SignaturePolicy string SignBy string Squash bool + SkipUnusedStages bool Stdin bool Tag []string BuildOutput string @@ -260,6 +261,7 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet { if err := fs.MarkHidden("signature-policy"); err != nil { panic(fmt.Sprintf("error marking the signature-policy flag as hidden: %v", err)) } + fs.BoolVar(&flags.SkipUnusedStages, "skip-unused-stages", true, "skips stages in multi-stage builds which do not affect the final target") fs.BoolVar(&flags.Squash, "squash", false, "squash newly built layers into a single new layer") fs.StringArrayVar(&flags.SSH, "ssh", []string{}, "SSH agent socket or keys to expose to the build. (format: default|<id>[=<socket>|<key>[,<key>]])") fs.BoolVar(&flags.Stdin, "stdin", false, "pass stdin into containers") diff --git a/vendor/github.com/containers/buildah/pkg/parse/parse.go b/vendor/github.com/containers/buildah/pkg/parse/parse.go index bbbfb2fc2..b3f260357 100644 --- a/vendor/github.com/containers/buildah/pkg/parse/parse.go +++ b/vendor/github.com/containers/buildah/pkg/parse/parse.go @@ -18,6 +18,7 @@ import ( "github.com/containers/buildah/define" internalParse "github.com/containers/buildah/internal/parse" "github.com/containers/buildah/pkg/sshagent" + "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/parse" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/types" @@ -35,9 +36,9 @@ import ( const ( // SeccompDefaultPath defines the default seccomp path - SeccompDefaultPath = "/usr/share/containers/seccomp.json" + SeccompDefaultPath = config.SeccompDefaultPath // SeccompOverridePath if this exists it overrides the default seccomp path - SeccompOverridePath = "/etc/crio/seccomp.json" + SeccompOverridePath = config.SeccompOverridePath // TypeBind is the type for mounting host dir TypeBind = "bind" // TypeTmpfs is the type for mounting tmpfs @@ -811,15 +812,15 @@ func parseIDMap(spec []string) (m [][3]uint32, err error) { for len(args) >= 3 { cid, err := strconv.ParseUint(args[0], 10, 32) if err != nil { - return nil, fmt.Errorf("error parsing container ID %q from mapping %q as a number: %w", args[0], s, err) + return nil, fmt.Errorf("parsing container ID %q from mapping %q as a number: %w", args[0], s, err) } hostid, err := strconv.ParseUint(args[1], 10, 32) if err != nil { - return nil, fmt.Errorf("error parsing host ID %q from mapping %q as a number: %w", args[1], s, err) + return nil, fmt.Errorf("parsing host ID %q from mapping %q as a number: %w", args[1], s, err) } size, err := strconv.ParseUint(args[2], 10, 32) if err != nil { - return nil, fmt.Errorf("error parsing %q from mapping %q as a number: %w", args[2], s, err) + return nil, fmt.Errorf("parsing %q from mapping %q as a number: %w", args[2], s, err) } m = append(m, [3]uint32{uint32(cid), uint32(hostid), uint32(size)}) args = args[3:] @@ -1074,11 +1075,32 @@ func SSH(sshSources []string) (map[string]*sshagent.Source, error) { return parsed, nil } -func ContainerIgnoreFile(contextDir, path string) ([]string, string, error) { +// ContainerIgnoreFile consumes path to `dockerignore` or `containerignore` +// and returns list of files to exclude along with the path to processed ignore +// file. Deprecated since this might become internal only, please avoid relying +// on this function. +func ContainerIgnoreFile(contextDir, path string, containerFiles []string) ([]string, string, error) { if path != "" { excludes, err := imagebuilder.ParseIgnore(path) return excludes, path, err } + // If path was not supplied give priority to `<containerfile>.containerignore` first. + for _, containerfile := range containerFiles { + if !filepath.IsAbs(containerfile) { + containerfile = filepath.Join(contextDir, containerfile) + } + containerfileIgnore := "" + if _, err := os.Stat(containerfile + ".containerignore"); err == nil { + containerfileIgnore = containerfile + ".containerignore" + } + if _, err := os.Stat(containerfile + ".dockerignore"); err == nil { + containerfileIgnore = containerfile + ".dockerignore" + } + if containerfileIgnore != "" { + excludes, err := imagebuilder.ParseIgnore(containerfileIgnore) + return excludes, containerfileIgnore, err + } + } path = filepath.Join(contextDir, ".containerignore") excludes, err := imagebuilder.ParseIgnore(path) if errors.Is(err, os.ErrNotExist) { diff --git a/vendor/github.com/containers/buildah/pkg/parse/parse_unix.go b/vendor/github.com/containers/buildah/pkg/parse/parse_unix.go index a8b1d1a9a..ff8ce854e 100644 --- a/vendor/github.com/containers/buildah/pkg/parse/parse_unix.go +++ b/vendor/github.com/containers/buildah/pkg/parse/parse_unix.go @@ -20,7 +20,7 @@ func DeviceFromPath(device string) (define.ContainerDevices, error) { } srcInfo, err := os.Stat(src) if err != nil { - return nil, fmt.Errorf("error getting info of source device %s: %w", src, err) + return nil, fmt.Errorf("getting info of source device %s: %w", src, err) } if !srcInfo.IsDir() { @@ -37,7 +37,7 @@ func DeviceFromPath(device string) (define.ContainerDevices, error) { // If source device is a directory srcDevices, err := devices.GetDevices(src) if err != nil { - return nil, fmt.Errorf("error getting source devices from directory %s: %w", src, err) + return nil, fmt.Errorf("getting source devices from directory %s: %w", src, err) } for _, d := range srcDevices { d.Path = filepath.Join(dst, filepath.Base(d.Path)) diff --git a/vendor/github.com/containers/buildah/pkg/rusage/rusage_unix.go b/vendor/github.com/containers/buildah/pkg/rusage/rusage_unix.go index e0b9d37b3..317046fc3 100644 --- a/vendor/github.com/containers/buildah/pkg/rusage/rusage_unix.go +++ b/vendor/github.com/containers/buildah/pkg/rusage/rusage_unix.go @@ -17,7 +17,7 @@ func get() (Rusage, error) { var rusage syscall.Rusage err := syscall.Getrusage(syscall.RUSAGE_CHILDREN, &rusage) if err != nil { - return Rusage{}, fmt.Errorf("error getting resource usage: %w", err) + return Rusage{}, fmt.Errorf("getting resource usage: %w", err) } r := Rusage{ Date: time.Now(), diff --git a/vendor/github.com/containers/buildah/pkg/rusage/rusage_unsupported.go b/vendor/github.com/containers/buildah/pkg/rusage/rusage_unsupported.go index 46dd5ebe7..54ed77fad 100644 --- a/vendor/github.com/containers/buildah/pkg/rusage/rusage_unsupported.go +++ b/vendor/github.com/containers/buildah/pkg/rusage/rusage_unsupported.go @@ -9,7 +9,7 @@ import ( ) func get() (Rusage, error) { - return Rusage{}, fmt.Errorf("error getting resource usage: %w", syscall.ENOTSUP) + return Rusage{}, fmt.Errorf("getting resource usage: %w", syscall.ENOTSUP) } // Supported returns true if resource usage counters are supported on this OS. diff --git a/vendor/github.com/containers/buildah/push.go b/vendor/github.com/containers/buildah/push.go index a161bb279..1f4439147 100644 --- a/vendor/github.com/containers/buildah/push.go +++ b/vendor/github.com/containers/buildah/push.go @@ -32,7 +32,7 @@ func cacheLookupReferenceFunc(directory string, compress types.LayerCompression) } ref, err := blobcache.NewBlobCache(ref, directory, compress) if err != nil { - return nil, fmt.Errorf("error using blobcache %q: %w", directory, err) + return nil, fmt.Errorf("using blobcache %q: %w", directory, err) } return ref, nil } @@ -135,7 +135,7 @@ func Push(ctx context.Context, image string, dest types.ImageReference, options manifestDigest, err := manifest.Digest(manifestBytes) if err != nil { - return nil, "", fmt.Errorf("error computing digest of manifest of new image %q: %w", transports.ImageName(dest), err) + return nil, "", fmt.Errorf("computing digest of manifest of new image %q: %w", transports.ImageName(dest), err) } var ref reference.Canonical diff --git a/vendor/github.com/containers/buildah/run_common.go b/vendor/github.com/containers/buildah/run_common.go index f5a5ec850..6bd20d8df 100644 --- a/vendor/github.com/containers/buildah/run_common.go +++ b/vendor/github.com/containers/buildah/run_common.go @@ -98,7 +98,7 @@ func (b *Builder) addResolvConf(rdir string, chownOpts *idtools.IDPair, dnsServe Searches: searches, Options: options, }); err != nil { - return "", fmt.Errorf("error building resolv.conf for container %s: %w", b.ContainerID, err) + return "", fmt.Errorf("building resolv.conf for container %s: %w", b.ContainerID, err) } uid := 0 @@ -165,7 +165,7 @@ func (b *Builder) generateHostname(rdir, hostname string, chownOpts *idtools.IDP cfile := filepath.Join(rdir, filepath.Base(hostnamePath)) if err = ioutils.AtomicWriteFile(cfile, hostnameBuffer.Bytes(), 0644); err != nil { - return "", fmt.Errorf("error writing /etc/hostname into the container: %w", err) + return "", fmt.Errorf("writing /etc/hostname into the container: %w", err) } uid := 0 @@ -419,10 +419,10 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, moreCreateArgs [ // Write the runtime configuration. specbytes, err := json.Marshal(spec) if err != nil { - return 1, fmt.Errorf("error encoding configuration %#v as json: %w", spec, err) + return 1, fmt.Errorf("encoding configuration %#v as json: %w", spec, err) } if err = ioutils.AtomicWriteFile(filepath.Join(bundlePath, "config.json"), specbytes, 0600); err != nil { - return 1, fmt.Errorf("error storing runtime configuration: %w", err) + return 1, fmt.Errorf("storing runtime configuration: %w", err) } logrus.Debugf("config = %v", string(specbytes)) @@ -451,7 +451,7 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, moreCreateArgs [ copyPipes := false finishCopy := make([]int, 2) if err = unix.Pipe(finishCopy); err != nil { - return 1, fmt.Errorf("error creating pipe for notifying to stop stdio: %w", err) + return 1, fmt.Errorf("creating pipe for notifying to stop stdio: %w", err) } finishedCopy := make(chan struct{}, 1) var pargs []string @@ -463,7 +463,7 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, moreCreateArgs [ socketPath := filepath.Join(bundlePath, "console.sock") consoleListener, err = net.ListenUnix("unix", &net.UnixAddr{Name: socketPath, Net: "unix"}) if err != nil { - return 1, fmt.Errorf("error creating socket %q to receive terminal descriptor: %w", consoleListener.Addr(), err) + return 1, fmt.Errorf("creating socket %q to receive terminal descriptor: %w", consoleListener.Addr(), err) } // Add console socket arguments. moreCreateArgs = append(moreCreateArgs, "--console-socket", socketPath) @@ -542,13 +542,13 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, moreCreateArgs [ logrus.Debugf("Running %q", create.Args) err = create.Run() if err != nil { - return 1, fmt.Errorf("error from %s creating container for %v: %s: %w", runtime, pargs, runCollectOutput(options.Logger, errorFds, closeBeforeReadingErrorFds), err) + return 1, fmt.Errorf("from %s creating container for %v: %s: %w", runtime, pargs, runCollectOutput(options.Logger, errorFds, closeBeforeReadingErrorFds), err) } defer func() { err2 := del.Run() if err2 != nil { if err == nil { - err = fmt.Errorf("error deleting container: %w", err2) + err = fmt.Errorf("deleting container: %w", err2) } else { options.Logger.Infof("error from %s deleting container: %v", runtime, err2) } @@ -562,7 +562,7 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, moreCreateArgs [ } pid, err := strconv.Atoi(strings.TrimSpace(string(pidValue))) if err != nil { - return 1, fmt.Errorf("error parsing pid %s as a number: %w", string(pidValue), err) + return 1, fmt.Errorf("parsing pid %s as a number: %w", string(pidValue), err) } var stopped uint32 var reaping sync.WaitGroup @@ -608,7 +608,7 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, moreCreateArgs [ logrus.Debugf("Running %q", start.Args) err = start.Run() if err != nil { - return 1, fmt.Errorf("error from %s starting container: %w", runtime, err) + return 1, fmt.Errorf("from %s starting container: %w", runtime, err) } defer func() { if atomic.LoadUint32(&stopped) == 0 { @@ -642,10 +642,10 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, moreCreateArgs [ // container exited break } - return 1, fmt.Errorf("error reading container state from %s (got output: %q): %w", runtime, string(stateOutput), err) + return 1, fmt.Errorf("reading container state from %s (got output: %q): %w", runtime, string(stateOutput), err) } if err = json.Unmarshal(stateOutput, &state); err != nil { - return 1, fmt.Errorf("error parsing container state %q from %s: %w", string(stateOutput), runtime, err) + return 1, fmt.Errorf("parsing container state %q from %s: %w", string(stateOutput), runtime, err) } switch state.Status { case "running": @@ -964,7 +964,7 @@ func runAcceptTerminal(logger *logrus.Logger, consoleListener *net.UnixListener, defer consoleListener.Close() c, err := consoleListener.AcceptUnix() if err != nil { - return -1, fmt.Errorf("error accepting socket descriptor connection: %w", err) + return -1, fmt.Errorf("accepting socket descriptor connection: %w", err) } defer c.Close() // Expect a control message over our new connection. @@ -972,7 +972,7 @@ func runAcceptTerminal(logger *logrus.Logger, consoleListener *net.UnixListener, oob := make([]byte, 8192) n, oobn, _, _, err := c.ReadMsgUnix(b, oob) if err != nil { - return -1, fmt.Errorf("error reading socket descriptor: %w", err) + return -1, fmt.Errorf("reading socket descriptor: %w", err) } if n > 0 { logrus.Debugf("socket descriptor is for %q", string(b[:n])) @@ -983,7 +983,7 @@ func runAcceptTerminal(logger *logrus.Logger, consoleListener *net.UnixListener, // Parse the control message. scm, err := unix.ParseSocketControlMessage(oob[:oobn]) if err != nil { - return -1, fmt.Errorf("error parsing out-of-bound data as a socket control message: %w", err) + return -1, fmt.Errorf("parsing out-of-bound data as a socket control message: %w", err) } logrus.Debugf("control messages: %v", scm) // Expect to get a descriptor. @@ -991,7 +991,7 @@ func runAcceptTerminal(logger *logrus.Logger, consoleListener *net.UnixListener, for i := range scm { fds, err := unix.ParseUnixRights(&scm[i]) if err != nil { - return -1, fmt.Errorf("error parsing unix rights control message: %v: %w", &scm[i], err) + return -1, fmt.Errorf("parsing unix rights control message: %v: %w", &scm[i], err) } logrus.Debugf("fds: %v", fds) if len(fds) == 0 { @@ -1106,7 +1106,7 @@ func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options Run Isolation: isolation, }) if conferr != nil { - return fmt.Errorf("error encoding configuration for %q: %w", runUsingRuntimeCommand, conferr) + return fmt.Errorf("encoding configuration for %q: %w", runUsingRuntimeCommand, conferr) } cmd := reexec.Command(runUsingRuntimeCommand) setPdeathsig(cmd) @@ -1126,13 +1126,13 @@ func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options Run cmd.Env = util.MergeEnv(os.Environ(), []string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())}) preader, pwriter, err := os.Pipe() if err != nil { - return fmt.Errorf("error creating configuration pipe: %w", err) + return fmt.Errorf("creating configuration pipe: %w", err) } confwg.Add(1) go func() { _, conferr = io.Copy(pwriter, bytes.NewReader(config)) if conferr != nil { - conferr = fmt.Errorf("error while copying configuration down pipe to child process: %w", conferr) + conferr = fmt.Errorf("while copying configuration down pipe to child process: %w", conferr) } confwg.Done() }() @@ -1143,14 +1143,14 @@ func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options Run if configureNetwork { containerCreateR.file, containerCreateW.file, err = os.Pipe() if err != nil { - return fmt.Errorf("error creating container create pipe: %w", err) + return fmt.Errorf("creating container create pipe: %w", err) } defer containerCreateR.Close() defer containerCreateW.Close() containerStartR.file, containerStartW.file, err = os.Pipe() if err != nil { - return fmt.Errorf("error creating container start pipe: %w", err) + return fmt.Errorf("creating container start pipe: %w", err) } defer containerStartR.Close() defer containerStartW.Close() @@ -1161,7 +1161,7 @@ func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options Run defer preader.Close() defer pwriter.Close() if err := cmd.Start(); err != nil { - return fmt.Errorf("error while starting runtime: %w", err) + return fmt.Errorf("while starting runtime: %w", err) } interrupted := make(chan os.Signal, 100) @@ -1191,7 +1191,7 @@ func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options Run } pid, err := strconv.Atoi(strings.TrimSpace(string(pidValue))) if err != nil { - return fmt.Errorf("error parsing pid %s as a number: %w", string(pidValue), err) + return fmt.Errorf("parsing pid %s as a number: %w", string(pidValue), err) } teardown, netstatus, err := b.runConfigureNetwork(pid, isolation, options, configureNetworks, containerName) @@ -1227,7 +1227,7 @@ func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options Run } if err := cmd.Wait(); err != nil { - return fmt.Errorf("error while running runtime: %w", err) + return fmt.Errorf("while running runtime: %w", err) } confwg.Wait() signal.Stop(interrupted) @@ -1280,7 +1280,7 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st // After this point we need to know the per-container persistent storage directory. cdir, err := b.store.ContainerDirectory(b.ContainerID) if err != nil { - return nil, fmt.Errorf("error determining work directory for container %q: %w", b.ContainerID, err) + return nil, fmt.Errorf("determining work directory for container %q: %w", b.ContainerID, err) } // Figure out which UID and GID to tell the subscriptions package to use @@ -1408,7 +1408,7 @@ func runSetupBuiltinVolumes(mountLabel, mountPoint, containerDir string, builtin } logrus.Debugf("populating directory %q for volume %q using contents of %q", volumePath, volume, srcPath) if err = extractWithTar(mountPoint, srcPath, volumePath); err != nil && !errors.Is(err, os.ErrNotExist) { - return nil, fmt.Errorf("error populating directory %q for volume %q using contents of %q: %w", volumePath, volume, srcPath, err) + return nil, fmt.Errorf("populating directory %q for volume %q using contents of %q: %w", volumePath, volume, srcPath, err) } } // Add the bind mount. @@ -1445,6 +1445,8 @@ func cleanableDestinationListFromMounts(mounts []spec.Mount) []string { // runSetupRunMounts sets up mounts that exist only in this RUN, not in subsequent runs func (b *Builder) runSetupRunMounts(mounts []string, sources runMountInfo, idMaps IDMaps) ([]spec.Mount, *runMountArtifacts, error) { + // If `type` is not set default to "bind" + mountType := internalParse.TypeBind mountTargets := make([]string, 0, 10) tmpFiles := make([]string, 0, len(mounts)) mountImages := make([]string, 0, 10) @@ -1452,20 +1454,19 @@ func (b *Builder) runSetupRunMounts(mounts []string, sources runMountInfo, idMap agents := make([]*sshagent.AgentServer, 0, len(mounts)) sshCount := 0 defaultSSHSock := "" - tokens := []string{} lockedTargets := []string{} for _, mount := range mounts { - arr := strings.SplitN(mount, ",", 2) - - kv := strings.Split(arr[0], "=") - if len(kv) != 2 || kv[0] != "type" { - return nil, nil, errors.New("invalid mount type") - } - if len(arr) == 2 { - tokens = strings.Split(arr[1], ",") + tokens := strings.Split(mount, ",") + for _, field := range tokens { + if strings.HasPrefix(field, "type=") { + kv := strings.Split(field, "=") + if len(kv) != 2 { + return nil, nil, errors.New("invalid mount type") + } + mountType = kv[1] + } } - - switch kv[1] { + switch mountType { case "secret": mount, envFile, err := b.getSecretMount(tokens, sources.Secrets, idMaps) if err != nil { @@ -1520,7 +1521,7 @@ func (b *Builder) runSetupRunMounts(mounts []string, sources runMountInfo, idMap mountTargets = append(mountTargets, mount.Destination) lockedTargets = lockedPaths default: - return nil, nil, fmt.Errorf("invalid mount type %q", kv[1]) + return nil, nil, fmt.Errorf("invalid mount type %q", mountType) } } artifacts := &runMountArtifacts{ @@ -1578,6 +1579,9 @@ func (b *Builder) getSecretMount(tokens []string, secrets map[string]define.Secr for _, val := range tokens { kv := strings.SplitN(val, "=", 2) switch kv[0] { + case "type": + // This is already processed + continue case "id": id = kv[1] case "target", "dst", "destination": @@ -1698,6 +1702,9 @@ func (b *Builder) getSSHMount(tokens []string, count int, sshsources map[string] return nil, nil, errInvalidSyntax } switch kv[0] { + case "type": + // This is already processed + continue case "id": id = kv[1] case "target", "dst", "destination": diff --git a/vendor/github.com/containers/buildah/run_freebsd.go b/vendor/github.com/containers/buildah/run_freebsd.go index b8d141eec..27982560b 100644 --- a/vendor/github.com/containers/buildah/run_freebsd.go +++ b/vendor/github.com/containers/buildah/run_freebsd.go @@ -90,7 +90,7 @@ func (b *Builder) Run(command []string, options RunOptions) error { gp, err := generate.New("freebsd") if err != nil { - return fmt.Errorf("error generating new 'freebsd' runtime spec: %w", err) + return fmt.Errorf("generating new 'freebsd' runtime spec: %w", err) } g := &gp @@ -123,7 +123,7 @@ func (b *Builder) Run(command []string, options RunOptions) error { } mountPoint, err := b.Mount(b.MountLabel) if err != nil { - return fmt.Errorf("error mounting container %q: %w", b.ContainerID, err) + return fmt.Errorf("mounting container %q: %w", b.ContainerID, err) } defer func() { if err := b.Unmount(); err != nil { @@ -216,7 +216,7 @@ func (b *Builder) Run(command []string, options RunOptions) error { runArtifacts, err := b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, volumes, b.CommonBuildOpts.Volumes, options.RunMounts, runMountInfo) if err != nil { - return fmt.Errorf("error resolving mountpoints for container %q: %w", b.ContainerID, err) + return fmt.Errorf("resolving mountpoints for container %q: %w", b.ContainerID, err) } if runArtifacts.SSHAuthSock != "" { sshenv := "SSH_AUTH_SOCK=" + runArtifacts.SSHAuthSock @@ -316,7 +316,7 @@ func (b *Builder) runSetupVolumeMounts(mountLabel string, volumeMounts []string, // Make sure the overlay directory is clean before running _, err := b.store.ContainerDirectory(b.ContainerID) if err != nil { - return nil, fmt.Errorf("error looking up container directory for %s: %w", b.ContainerID, err) + return nil, fmt.Errorf("looking up container directory for %s: %w", b.ContainerID, err) } parseMount := func(mountType, host, container string, options []string) (specs.Mount, error) { @@ -542,7 +542,7 @@ func runMakeStdioPipe(uid, gid int) ([][]int, error) { for i := range stdioPipe { stdioPipe[i] = make([]int, 2) if err := unix.Pipe(stdioPipe[i]); err != nil { - return nil, fmt.Errorf("error creating pipe for container FD %d: %w", i, err) + return nil, fmt.Errorf("creating pipe for container FD %d: %w", i, err) } } return stdioPipe, nil diff --git a/vendor/github.com/containers/buildah/run_linux.go b/vendor/github.com/containers/buildah/run_linux.go index a5d51732f..d4707e39a 100644 --- a/vendor/github.com/containers/buildah/run_linux.go +++ b/vendor/github.com/containers/buildah/run_linux.go @@ -88,7 +88,7 @@ func (b *Builder) Run(command []string, options RunOptions) error { gp, err := generate.New("linux") if err != nil { - return fmt.Errorf("error generating new 'linux' runtime spec: %w", err) + return fmt.Errorf("generating new 'linux' runtime spec: %w", err) } g := &gp @@ -122,7 +122,7 @@ func (b *Builder) Run(command []string, options RunOptions) error { setupSelinux(g, b.ProcessLabel, b.MountLabel) mountPoint, err := b.Mount(b.MountLabel) if err != nil { - return fmt.Errorf("error mounting container %q: %w", b.ContainerID, err) + return fmt.Errorf("mounting container %q: %w", b.ContainerID, err) } defer func() { if err := b.Unmount(); err != nil { @@ -327,7 +327,7 @@ rootless=%d runArtifacts, err := b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, volumes, b.CommonBuildOpts.Volumes, options.RunMounts, runMountInfo) if err != nil { - return fmt.Errorf("error resolving mountpoints for container %q: %w", b.ContainerID, err) + return fmt.Errorf("resolving mountpoints for container %q: %w", b.ContainerID, err) } if runArtifacts.SSHAuthSock != "" { sshenv := "SSH_AUTH_SOCK=" + runArtifacts.SSHAuthSock @@ -506,7 +506,7 @@ func setupRootlessNetwork(pid int) (teardown func(), err error) { b := make([]byte, 1) for { if err := rootlessSlirpSyncR.SetDeadline(time.Now().Add(1 * time.Second)); err != nil { - return nil, fmt.Errorf("error setting slirp4netns pipe timeout: %w", err) + return nil, fmt.Errorf("setting slirp4netns pipe timeout: %w", err) } if _, err := rootlessSlirpSyncR.Read(b); err == nil { break @@ -552,7 +552,7 @@ func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, optio netns := fmt.Sprintf("/proc/%d/ns/net", pid) netFD, err := unix.Open(netns, unix.O_RDONLY, 0) if err != nil { - return nil, nil, fmt.Errorf("error opening network namespace: %w", err) + return nil, nil, fmt.Errorf("opening network namespace: %w", err) } mynetns := fmt.Sprintf("/proc/%d/fd/%d", unix.Getpid(), netFD) @@ -589,17 +589,17 @@ func runMakeStdioPipe(uid, gid int) ([][]int, error) { for i := range stdioPipe { stdioPipe[i] = make([]int, 2) if err := unix.Pipe(stdioPipe[i]); err != nil { - return nil, fmt.Errorf("error creating pipe for container FD %d: %w", i, err) + return nil, fmt.Errorf("creating pipe for container FD %d: %w", i, err) } } if err := unix.Fchown(stdioPipe[unix.Stdin][0], uid, gid); err != nil { - return nil, fmt.Errorf("error setting owner of stdin pipe descriptor: %w", err) + return nil, fmt.Errorf("setting owner of stdin pipe descriptor: %w", err) } if err := unix.Fchown(stdioPipe[unix.Stdout][1], uid, gid); err != nil { - return nil, fmt.Errorf("error setting owner of stdout pipe descriptor: %w", err) + return nil, fmt.Errorf("setting owner of stdout pipe descriptor: %w", err) } if err := unix.Fchown(stdioPipe[unix.Stderr][1], uid, gid); err != nil { - return nil, fmt.Errorf("error setting owner of stderr pipe descriptor: %w", err) + return nil, fmt.Errorf("setting owner of stderr pipe descriptor: %w", err) } return stdioPipe, nil } @@ -633,20 +633,20 @@ func setupNamespaces(logger *logrus.Logger, g *generate.Generator, namespaceOpti } if namespaceOption.Host { if err := g.RemoveLinuxNamespace(namespaceOption.Name); err != nil { - return false, nil, false, fmt.Errorf("error removing %q namespace for run: %w", namespaceOption.Name, err) + return false, nil, false, fmt.Errorf("removing %q namespace for run: %w", namespaceOption.Name, err) } } else if err := g.AddOrReplaceLinuxNamespace(namespaceOption.Name, namespaceOption.Path); err != nil { if namespaceOption.Path == "" { - return false, nil, false, fmt.Errorf("error adding new %q namespace for run: %w", namespaceOption.Name, err) + return false, nil, false, fmt.Errorf("adding new %q namespace for run: %w", namespaceOption.Name, err) } - return false, nil, false, fmt.Errorf("error adding %q namespace %q for run: %w", namespaceOption.Name, namespaceOption.Path, err) + return false, nil, false, fmt.Errorf("adding %q namespace %q for run: %w", namespaceOption.Name, namespaceOption.Path, err) } } // If we've got mappings, we're going to have to create a user namespace. if len(idmapOptions.UIDMap) > 0 || len(idmapOptions.GIDMap) > 0 || configureUserns { if err := g.AddOrReplaceLinuxNamespace(string(specs.UserNamespace), ""); err != nil { - return false, nil, false, fmt.Errorf("error adding new %q namespace for run: %w", string(specs.UserNamespace), err) + return false, nil, false, fmt.Errorf("adding new %q namespace for run: %w", string(specs.UserNamespace), err) } hostUidmap, hostGidmap, err := unshare.GetHostIDMappings("") if err != nil { @@ -670,17 +670,17 @@ func setupNamespaces(logger *logrus.Logger, g *generate.Generator, namespaceOpti } if !specifiedNetwork { if err := g.AddOrReplaceLinuxNamespace(string(specs.NetworkNamespace), ""); err != nil { - return false, nil, false, fmt.Errorf("error adding new %q namespace for run: %w", string(specs.NetworkNamespace), err) + return false, nil, false, fmt.Errorf("adding new %q namespace for run: %w", string(specs.NetworkNamespace), err) } configureNetwork = (policy != define.NetworkDisabled) } } else { if err := g.RemoveLinuxNamespace(string(specs.UserNamespace)); err != nil { - return false, nil, false, fmt.Errorf("error removing %q namespace for run: %w", string(specs.UserNamespace), err) + return false, nil, false, fmt.Errorf("removing %q namespace for run: %w", string(specs.UserNamespace), err) } if !specifiedNetwork { if err := g.RemoveLinuxNamespace(string(specs.NetworkNamespace)); err != nil { - return false, nil, false, fmt.Errorf("error removing %q namespace for run: %w", string(specs.NetworkNamespace), err) + return false, nil, false, fmt.Errorf("removing %q namespace for run: %w", string(specs.NetworkNamespace), err) } } } @@ -726,7 +726,9 @@ func (b *Builder) configureNamespaces(g *generate.Generator, options *RunOptions options.ConfigureNetwork = networkPolicy } } - + if networkPolicy == NetworkDisabled { + namespaceOptions.AddOrReplace(define.NamespaceOptions{{Name: string(specs.NetworkNamespace), Host: false}}...) + } configureNetwork, configureNetworks, configureUTS, err := setupNamespaces(options.Logger, g, namespaceOptions, b.IDMappingOptions, networkPolicy) if err != nil { return false, nil, err @@ -796,10 +798,10 @@ func (b *Builder) runSetupVolumeMounts(mountLabel string, volumeMounts []string, // Make sure the overlay directory is clean before running containerDir, err := b.store.ContainerDirectory(b.ContainerID) if err != nil { - return nil, fmt.Errorf("error looking up container directory for %s: %w", b.ContainerID, err) + return nil, fmt.Errorf("looking up container directory for %s: %w", b.ContainerID, err) } if err := overlay.CleanupContent(containerDir); err != nil { - return nil, fmt.Errorf("error cleaning up overlay content for %s: %w", b.ContainerID, err) + return nil, fmt.Errorf("cleaning up overlay content for %s: %w", b.ContainerID, err) } parseMount := func(mountType, host, container string, options []string) (specs.Mount, error) { @@ -966,16 +968,16 @@ func setupReadOnlyPaths(g *generate.Generator) { func setupCapAdd(g *generate.Generator, caps ...string) error { for _, cap := range caps { if err := g.AddProcessCapabilityBounding(cap); err != nil { - return fmt.Errorf("error adding %q to the bounding capability set: %w", cap, err) + return fmt.Errorf("adding %q to the bounding capability set: %w", cap, err) } if err := g.AddProcessCapabilityEffective(cap); err != nil { - return fmt.Errorf("error adding %q to the effective capability set: %w", cap, err) + return fmt.Errorf("adding %q to the effective capability set: %w", cap, err) } if err := g.AddProcessCapabilityPermitted(cap); err != nil { - return fmt.Errorf("error adding %q to the permitted capability set: %w", cap, err) + return fmt.Errorf("adding %q to the permitted capability set: %w", cap, err) } if err := g.AddProcessCapabilityAmbient(cap); err != nil { - return fmt.Errorf("error adding %q to the ambient capability set: %w", cap, err) + return fmt.Errorf("adding %q to the ambient capability set: %w", cap, err) } } return nil @@ -984,16 +986,16 @@ func setupCapAdd(g *generate.Generator, caps ...string) error { func setupCapDrop(g *generate.Generator, caps ...string) error { for _, cap := range caps { if err := g.DropProcessCapabilityBounding(cap); err != nil { - return fmt.Errorf("error removing %q from the bounding capability set: %w", cap, err) + return fmt.Errorf("removing %q from the bounding capability set: %w", cap, err) } if err := g.DropProcessCapabilityEffective(cap); err != nil { - return fmt.Errorf("error removing %q from the effective capability set: %w", cap, err) + return fmt.Errorf("removing %q from the effective capability set: %w", cap, err) } if err := g.DropProcessCapabilityPermitted(cap); err != nil { - return fmt.Errorf("error removing %q from the permitted capability set: %w", cap, err) + return fmt.Errorf("removing %q from the permitted capability set: %w", cap, err) } if err := g.DropProcessCapabilityAmbient(cap); err != nil { - return fmt.Errorf("error removing %q from the ambient capability set: %w", cap, err) + return fmt.Errorf("removing %q from the ambient capability set: %w", cap, err) } } return nil diff --git a/vendor/github.com/containers/buildah/seccomp.go b/vendor/github.com/containers/buildah/seccomp.go index 668123233..0f9a2c48b 100644 --- a/vendor/github.com/containers/buildah/seccomp.go +++ b/vendor/github.com/containers/buildah/seccomp.go @@ -24,7 +24,7 @@ func setupSeccomp(spec *specs.Spec, seccompProfilePath string) error { default: seccompProfile, err := ioutil.ReadFile(seccompProfilePath) if err != nil { - return fmt.Errorf("opening seccomp profile (%s) failed: %w", seccompProfilePath, err) + return fmt.Errorf("opening seccomp profile failed: %w", err) } seccompConfig, err := seccomp.LoadProfile(string(seccompProfile), spec) if err != nil { diff --git a/vendor/github.com/containers/buildah/unmount.go b/vendor/github.com/containers/buildah/unmount.go index ae9726ee3..66c8ce41a 100644 --- a/vendor/github.com/containers/buildah/unmount.go +++ b/vendor/github.com/containers/buildah/unmount.go @@ -6,12 +6,12 @@ import "fmt" func (b *Builder) Unmount() error { _, err := b.store.Unmount(b.ContainerID, false) if err != nil { - return fmt.Errorf("error unmounting build container %q: %w", b.ContainerID, err) + return fmt.Errorf("unmounting build container %q: %w", b.ContainerID, err) } b.MountPoint = "" err = b.Save() if err != nil { - return fmt.Errorf("error saving updated state for build container %q: %w", b.ContainerID, err) + return fmt.Errorf("saving updated state for build container %q: %w", b.ContainerID, err) } return nil } diff --git a/vendor/github.com/containers/buildah/util.go b/vendor/github.com/containers/buildah/util.go index b362dec84..ddc97cc6e 100644 --- a/vendor/github.com/containers/buildah/util.go +++ b/vendor/github.com/containers/buildah/util.go @@ -151,7 +151,7 @@ func ReserveSELinuxLabels(store storage.Store, id string) error { if selinuxGetEnabled() { containers, err := store.Containers() if err != nil { - return fmt.Errorf("error getting list of containers: %w", err) + return fmt.Errorf("getting list of containers: %w", err) } for _, c := range containers { @@ -169,7 +169,7 @@ func ReserveSELinuxLabels(store storage.Store, id string) error { } // Prevent different containers from using same MCS label if err := label.ReserveLabel(b.ProcessLabel); err != nil { - return fmt.Errorf("error reserving SELinux label %q: %w", b.ProcessLabel, err) + return fmt.Errorf("reserving SELinux label %q: %w", b.ProcessLabel, err) } } } @@ -219,10 +219,10 @@ func extractWithTar(root, src, dest string) error { wg.Wait() if getErr != nil { - return fmt.Errorf("error reading %q: %w", src, getErr) + return fmt.Errorf("reading %q: %w", src, getErr) } if putErr != nil { - return fmt.Errorf("error copying contents of %q to %q: %w", src, dest, putErr) + return fmt.Errorf("copying contents of %q to %q: %w", src, dest, putErr) } return nil } diff --git a/vendor/github.com/containers/buildah/util/util.go b/vendor/github.com/containers/buildah/util/util.go index 6a9049e68..4c67af703 100644 --- a/vendor/github.com/containers/buildah/util/util.go +++ b/vendor/github.com/containers/buildah/util/util.go @@ -118,18 +118,18 @@ func ExpandNames(names []string, systemContext *types.SystemContext, store stora var name reference.Named nameList, _, err := resolveName(n, systemContext, store) if err != nil { - return nil, fmt.Errorf("error parsing name %q: %w", n, err) + return nil, fmt.Errorf("parsing name %q: %w", n, err) } if len(nameList) == 0 { named, err := reference.ParseNormalizedNamed(n) if err != nil { - return nil, fmt.Errorf("error parsing name %q: %w", n, err) + return nil, fmt.Errorf("parsing name %q: %w", n, err) } name = named } else { named, err := reference.ParseNormalizedNamed(nameList[0]) if err != nil { - return nil, fmt.Errorf("error parsing name %q: %w", nameList[0], err) + return nil, fmt.Errorf("parsing name %q: %w", nameList[0], err) } name = named } @@ -169,7 +169,7 @@ func ResolveNameToReferences( ) (refs []types.ImageReference, err error) { names, transport, err := resolveName(image, systemContext, store) if err != nil { - return nil, fmt.Errorf("error parsing name %q: %w", image, err) + return nil, fmt.Errorf("parsing name %q: %w", image, err) } if transport != DefaultTransport { @@ -185,7 +185,7 @@ func ResolveNameToReferences( refs = append(refs, ref) } if len(refs) == 0 { - return nil, fmt.Errorf("error locating images with names %v", names) + return nil, fmt.Errorf("locating images with names %v", names) } return refs, nil } @@ -206,7 +206,7 @@ func AddImageNames(store storage.Store, firstRegistry string, systemContext *typ for _, tag := range addNames { if err := localImage.Tag(tag); err != nil { - return fmt.Errorf("error tagging image %s: %w", image.ID, err) + return fmt.Errorf("tagging image %s: %w", image.ID, err) } } diff --git a/vendor/github.com/containers/common/libimage/image.go b/vendor/github.com/containers/common/libimage/image.go index 3cc843ed3..0130532c2 100644 --- a/vendor/github.com/containers/common/libimage/image.go +++ b/vendor/github.com/containers/common/libimage/image.go @@ -477,8 +477,10 @@ func (i *Image) removeRecursive(ctx context.Context, rmMap map[string]*RemoveIma } report.Untagged = append(report.Untagged, i.Names()...) - for _, name := range i.Names() { - i.runtime.writeEvent(&Event{ID: i.ID(), Name: name, Time: time.Now(), Type: EventTypeImageUntag}) + if i.runtime.eventChannel != nil { + for _, name := range i.Names() { + i.runtime.writeEvent(&Event{ID: i.ID(), Name: name, Time: time.Now(), Type: EventTypeImageUntag}) + } } if !hasChildren { diff --git a/vendor/github.com/containers/common/libimage/platform.go b/vendor/github.com/containers/common/libimage/platform.go index 736a193f6..4d5dde310 100644 --- a/vendor/github.com/containers/common/libimage/platform.go +++ b/vendor/github.com/containers/common/libimage/platform.go @@ -6,6 +6,7 @@ import ( "runtime" "github.com/containerd/containerd/platforms" + v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" ) @@ -20,9 +21,18 @@ const ( ) // NormalizePlatform normalizes (according to the OCI spec) the specified os, -// arch and variant. If left empty, the individual item will not be normalized. +// arch and variant. If left empty, the individual item will be normalized. func NormalizePlatform(rawOS, rawArch, rawVariant string) (os, arch, variant string) { - rawPlatform := toPlatformString(rawOS, rawArch, rawVariant) + platformSpec := v1.Platform{ + OS: rawOS, + Architecture: rawArch, + Variant: rawVariant, + } + normalizedSpec := platforms.Normalize(platformSpec) + if normalizedSpec.Variant == "" && rawVariant != "" { + normalizedSpec.Variant = rawVariant + } + rawPlatform := toPlatformString(normalizedSpec.OS, normalizedSpec.Architecture, normalizedSpec.Variant) normalizedPlatform, err := platforms.Parse(rawPlatform) if err != nil { logrus.Debugf("Error normalizing platform: %v", err) @@ -38,7 +48,7 @@ func NormalizePlatform(rawOS, rawArch, rawVariant string) (os, arch, variant str arch = normalizedPlatform.Architecture } variant = rawVariant - if rawVariant != "" { + if rawVariant != "" || (rawVariant == "" && normalizedPlatform.Variant != "") { variant = normalizedPlatform.Variant } return os, arch, variant @@ -63,6 +73,9 @@ func toPlatformString(os, arch, variant string) string { // * 2) a bool indicating whether architecture, os or variant were set (some callers need that to decide whether they need to throw an error) // * 3) a fatal error that occurred prior to check for matches (e.g., storage errors etc.) func (i *Image) matchesPlatform(ctx context.Context, os, arch, variant string) (error, bool, error) { + if err := i.isCorrupted(""); err != nil { + return err, false, nil + } inspectInfo, err := i.inspectInfo(ctx) if err != nil { return nil, false, fmt.Errorf("inspecting image: %w", err) diff --git a/vendor/github.com/containers/common/libnetwork/types/network.go b/vendor/github.com/containers/common/libnetwork/types/network.go index de8655377..2e8948998 100644 --- a/vendor/github.com/containers/common/libnetwork/types/network.go +++ b/vendor/github.com/containers/common/libnetwork/types/network.go @@ -199,6 +199,7 @@ type NetAddress struct { // PerNetworkOptions are options which should be set on a per network basis. type PerNetworkOptions struct { // StaticIPs for this container. Optional. + // swagger:type []string StaticIPs []net.IP `json:"static_ips,omitempty"` // Aliases contains a list of names which the dns server should resolve // to this container. Should only be set when DNSEnabled is true on the Network. @@ -207,6 +208,7 @@ type PerNetworkOptions struct { // Optional. Aliases []string `json:"aliases,omitempty"` // StaticMac for this container. Optional. + // swagger:strfmt string StaticMAC HardwareAddr `json:"static_mac,omitempty"` // InterfaceName for this container. Required in the backend. // Optional in the frontend. Will be filled with ethX (where X is a integer) when empty. diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go index 858f961b6..cde7cec53 100644 --- a/vendor/github.com/containers/common/pkg/config/config.go +++ b/vendor/github.com/containers/common/pkg/config/config.go @@ -613,6 +613,9 @@ type Destination struct { // Identity file with ssh key, optional Identity string `toml:"identity,omitempty"` + + // isMachine describes if the remote destination is a machine. + IsMachine bool `toml:"is_machine,omitempty"` } // NewConfig creates a new Config. It starts with an empty config and, if @@ -1235,32 +1238,32 @@ func Reload() (*Config, error) { return defConfig() } -func (c *Config) ActiveDestination() (uri, identity string, err error) { +func (c *Config) ActiveDestination() (uri, identity string, machine bool, err error) { if uri, found := os.LookupEnv("CONTAINER_HOST"); found { if v, found := os.LookupEnv("CONTAINER_SSHKEY"); found { identity = v } - return uri, identity, nil + return uri, identity, false, nil } connEnv := os.Getenv("CONTAINER_CONNECTION") switch { case connEnv != "": d, found := c.Engine.ServiceDestinations[connEnv] if !found { - return "", "", fmt.Errorf("environment variable CONTAINER_CONNECTION=%q service destination not found", connEnv) + return "", "", false, fmt.Errorf("environment variable CONTAINER_CONNECTION=%q service destination not found", connEnv) } - return d.URI, d.Identity, nil + return d.URI, d.Identity, d.IsMachine, nil case c.Engine.ActiveService != "": d, found := c.Engine.ServiceDestinations[c.Engine.ActiveService] if !found { - return "", "", fmt.Errorf("%q service destination not found", c.Engine.ActiveService) + return "", "", false, fmt.Errorf("%q service destination not found", c.Engine.ActiveService) } - return d.URI, d.Identity, nil + return d.URI, d.Identity, d.IsMachine, nil case c.Engine.RemoteURI != "": - return c.Engine.RemoteURI, c.Engine.RemoteIdentity, nil + return c.Engine.RemoteURI, c.Engine.RemoteIdentity, false, nil } - return "", "", errors.New("no service destination configured") + return "", "", false, errors.New("no service destination configured") } var ( diff --git a/vendor/github.com/containers/common/pkg/config/config_linux.go b/vendor/github.com/containers/common/pkg/config/config_linux.go index 4f0889f29..0f622bb78 100644 --- a/vendor/github.com/containers/common/pkg/config/config_linux.go +++ b/vendor/github.com/containers/common/pkg/config/config_linux.go @@ -23,7 +23,7 @@ func customConfigFile() (string, error) { if path, found := os.LookupEnv("CONTAINERS_CONF"); found { return path, nil } - if unshare.IsRootless() { + if unshare.GetRootlessUID() > 0 { path, err := rootlessConfigPath() if err != nil { return "", err @@ -34,7 +34,7 @@ func customConfigFile() (string, error) { } func ifRootlessConfigPath() (string, error) { - if unshare.IsRootless() { + if unshare.GetRootlessUID() > 0 { path, err := rootlessConfigPath() if err != nil { return "", err diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go index 3a3a558a1..c5fca7f0c 100644 --- a/vendor/github.com/containers/common/pkg/config/default.go +++ b/vendor/github.com/containers/common/pkg/config/default.go @@ -180,7 +180,7 @@ func DefaultConfig() (*Config, error) { } defaultEngineConfig.SignaturePolicyPath = DefaultSignaturePolicyPath - if unshare.IsRootless() { + if useUserConfigLocations() { configHome, err := homedir.GetConfigHome() if err != nil { return nil, err @@ -289,7 +289,7 @@ func defaultConfigFromMemory() (*EngineConfig, error) { return nil, err } } - storeOpts, err := types.DefaultStoreOptions(unshare.IsRootless(), unshare.GetRootlessUID()) + storeOpts, err := types.DefaultStoreOptions(useUserConfigLocations(), unshare.GetRootlessUID()) if err != nil { return nil, err } @@ -427,7 +427,7 @@ func defaultConfigFromMemory() (*EngineConfig, error) { } func defaultTmpDir() (string, error) { - if !unshare.IsRootless() { + if !useUserConfigLocations() { return getLibpodTmpDir(), nil } @@ -679,3 +679,10 @@ func getDefaultSSHConfig() string { dirname := homedir.Get() return filepath.Join(dirname, ".ssh", "config") } + +func useUserConfigLocations() bool { + // NOTE: For now we want Windows to use system locations. + // GetRootlessUID == -1 on Windows, so exclude negative range + return unshare.GetRootlessUID() > 0 +} + diff --git a/vendor/github.com/containers/common/pkg/ssh/connection_golang.go b/vendor/github.com/containers/common/pkg/ssh/connection_golang.go index a5c1be89c..8ec3c45ed 100644 --- a/vendor/github.com/containers/common/pkg/ssh/connection_golang.go +++ b/vendor/github.com/containers/common/pkg/ssh/connection_golang.go @@ -3,6 +3,7 @@ package ssh import ( "bytes" "encoding/json" + "errors" "fmt" "io" "net" @@ -70,7 +71,7 @@ func golangConnectionDial(options ConnectionDialOptions) (*ConnectionDialReport, if err != nil { return nil, err } - cfg, err := ValidateAndConfigure(uri, options.Identity) + cfg, err := ValidateAndConfigure(uri, options.Identity, options.InsecureIsMachineConnection) if err != nil { return nil, err } @@ -84,12 +85,15 @@ func golangConnectionDial(options ConnectionDialOptions) (*ConnectionDialReport, } func golangConnectionExec(options ConnectionExecOptions) (*ConnectionExecReport, error) { + if !strings.HasPrefix(options.Host, "ssh://") { + options.Host = "ssh://" + options.Host + } _, uri, err := Validate(options.User, options.Host, options.Port, options.Identity) if err != nil { return nil, err } - cfg, err := ValidateAndConfigure(uri, options.Identity) + cfg, err := ValidateAndConfigure(uri, options.Identity, false) if err != nil { return nil, err } @@ -111,11 +115,15 @@ func golangConnectionScp(options ConnectionScpOptions) (*ConnectionScpReport, er return nil, err } + // removed for parsing + if !strings.HasPrefix(host, "ssh://") { + host = "ssh://" + host + } _, uri, err := Validate(options.User, host, options.Port, options.Identity) if err != nil { return nil, err } - cfg, err := ValidateAndConfigure(uri, options.Identity) + cfg, err := ValidateAndConfigure(uri, options.Identity, false) if err != nil { return nil, err } @@ -209,7 +217,7 @@ func GetUserInfo(uri *url.URL) (*url.Userinfo, error) { // ValidateAndConfigure will take a ssh url and an identity key (rsa and the like) and ensure the information given is valid // iden iden can be blank to mean no identity key // once the function validates the information it creates and returns an ssh.ClientConfig. -func ValidateAndConfigure(uri *url.URL, iden string) (*ssh.ClientConfig, error) { +func ValidateAndConfigure(uri *url.URL, iden string, insecureIsMachineConnection bool) (*ssh.ClientConfig, error) { var signers []ssh.Signer passwd, passwdSet := uri.User.Password() if iden != "" { // iden might be blank if coming from image scp or if no validation is needed @@ -272,23 +280,61 @@ func ValidateAndConfigure(uri *url.URL, iden string) (*ssh.ClientConfig, error) if err != nil { return nil, err } - keyFilePath := filepath.Join(homedir.Get(), ".ssh", "known_hosts") - known, err := knownhosts.New(keyFilePath) - if err != nil { - return nil, fmt.Errorf("creating host key callback function for %s: %w", keyFilePath, err) + + var callback ssh.HostKeyCallback + if insecureIsMachineConnection { + callback = ssh.InsecureIgnoreHostKey() + } else { + callback = ssh.HostKeyCallback(func(host string, remote net.Addr, pubKey ssh.PublicKey) error { + keyFilePath := filepath.Join(homedir.Get(), ".ssh", "known_hosts") + known, err := knownhosts.New(keyFilePath) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + logrus.Warn("please create a known_hosts file. The next time this host is connected to, podman will add it to known_hosts") + return nil + } + return err + } + // we need to check if there is an error from reading known hosts for this public key and if there is an error, what is it, and why is it happening? + // if it is a key mismatch we want to error since we know the host using another key + // however, if it is a general error not because of a known key, we want to add our key to the known_hosts file + hErr := known(host, remote, pubKey) + var keyErr *knownhosts.KeyError + // if keyErr.Want is not empty, we are receiving a different key meaning the host is known but we are using the wrong key + as := errors.As(hErr, &keyErr) + switch { + case as && len(keyErr.Want) > 0: + logrus.Warnf("ssh host key mismatch for host %s, got key %s of type %s", host, ssh.FingerprintSHA256(pubKey), pubKey.Type()) + return keyErr + // if keyErr.Want is empty that just means we do not know this host yet, add it. + case as && len(keyErr.Want) == 0: + // write to known_hosts + err := addKnownHostsEntry(host, pubKey) + if err != nil { + if os.IsNotExist(err) { + logrus.Warn("podman will soon require a known_hosts file to function properly.") + return nil + } + return err + } + case hErr != nil: + return hErr + } + return nil + }) } cfg := &ssh.ClientConfig{ User: uri.User.Username(), Auth: authMethods, - HostKeyCallback: known, + HostKeyCallback: callback, Timeout: tick, } return cfg, nil } func getUDS(uri *url.URL, iden string) (string, error) { - cfg, err := ValidateAndConfigure(uri, iden) + cfg, err := ValidateAndConfigure(uri, iden, false) if err != nil { return "", fmt.Errorf("failed to validate: %w", err) } @@ -324,3 +370,20 @@ func getUDS(uri *url.URL, iden string) (string, error) { } return info.Host.RemoteSocket.Path, nil } + +// addKnownHostsEntry adds (host, pubKey) to user’s known_hosts. +func addKnownHostsEntry(host string, pubKey ssh.PublicKey) error { + hd := homedir.Get() + known := filepath.Join(hd, ".ssh", "known_hosts") + f, err := os.OpenFile(known, os.O_APPEND|os.O_WRONLY, 0o600) + if err != nil { + return err + } + defer f.Close() + l := knownhosts.Line([]string{host}, pubKey) + if _, err = f.WriteString("\n" + l + "\n"); err != nil { + return err + } + logrus.Infof("key %s added to %s", ssh.FingerprintSHA256(pubKey), known) + return nil +} diff --git a/vendor/github.com/containers/common/pkg/ssh/types.go b/vendor/github.com/containers/common/pkg/ssh/types.go index f22b5fba9..16512c43f 100644 --- a/vendor/github.com/containers/common/pkg/ssh/types.go +++ b/vendor/github.com/containers/common/pkg/ssh/types.go @@ -27,12 +27,13 @@ type ConnectionCreateOptions struct { } type ConnectionDialOptions struct { - Host string - Identity string - User *url.Userinfo - Port int - Auth []string - Timeout time.Duration + Host string + Identity string + User *url.Userinfo + Port int + Auth []string + Timeout time.Duration + InsecureIsMachineConnection bool } type ConnectionDialReport struct { diff --git a/vendor/github.com/containers/common/pkg/ssh/utils.go b/vendor/github.com/containers/common/pkg/ssh/utils.go index c15745015..b05105d9c 100644 --- a/vendor/github.com/containers/common/pkg/ssh/utils.go +++ b/vendor/github.com/containers/common/pkg/ssh/utils.go @@ -21,6 +21,7 @@ func Validate(user *url.Userinfo, path string, port int, identity string) (*conf if strings.Contains(path, "/run") { sock = strings.Split(path, "/run")[1] } + // url.Parse NEEDS ssh://, if this ever fails or returns some nonsense, that is why. uri, err := url.Parse(path) if err != nil { return nil, nil, err @@ -33,9 +34,9 @@ func Validate(user *url.Userinfo, path string, port int, identity string) (*conf if uri.Port() == "" { if port != 0 { - uri.Host = net.JoinHostPort(uri.Hostname(), strconv.Itoa(port)) + uri.Host = net.JoinHostPort(uri.Host, strconv.Itoa(port)) } else { - uri.Host = net.JoinHostPort(uri.Hostname(), "22") + uri.Host = net.JoinHostPort(uri.Host, "22") } } diff --git a/vendor/github.com/containers/common/pkg/util/util_supported.go b/vendor/github.com/containers/common/pkg/util/util_supported.go index 6d7060af4..0cd53af53 100644 --- a/vendor/github.com/containers/common/pkg/util/util_supported.go +++ b/vendor/github.com/containers/common/pkg/util/util_supported.go @@ -11,6 +11,7 @@ import ( "sync" "syscall" + "github.com/containers/storage/pkg/homedir" "github.com/containers/storage/pkg/unshare" "github.com/sirupsen/logrus" ) @@ -31,7 +32,10 @@ func GetRuntimeDir() (string, error) { var rootlessRuntimeDirError error rootlessRuntimeDirOnce.Do(func() { - runtimeDir := os.Getenv("XDG_RUNTIME_DIR") + runtimeDir, err := homedir.GetRuntimeDir() + if err != nil { + logrus.Debug(err) + } if runtimeDir != "" { st, err := os.Stat(runtimeDir) if err != nil { diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go index 34e9fe6ba..297966b70 100644 --- a/vendor/github.com/containers/common/version/version.go +++ b/vendor/github.com/containers/common/version/version.go @@ -1,4 +1,4 @@ package version // Version is the version of the build. -const Version = "0.49.2-dev" +const Version = "0.50.1" diff --git a/vendor/github.com/containers/image/v5/pkg/docker/config/config.go b/vendor/github.com/containers/image/v5/pkg/docker/config/config.go index 9623546d8..0790a47f2 100644 --- a/vendor/github.com/containers/image/v5/pkg/docker/config/config.go +++ b/vendor/github.com/containers/image/v5/pkg/docker/config/config.go @@ -683,7 +683,7 @@ func findCredentialsInFile(key, registry, path string, legacyFormat bool) (types // keys we prefer exact matches as well. for _, key := range keys { if val, exists := auths.AuthConfigs[key]; exists { - return decodeDockerAuth(val) + return decodeDockerAuth(path, key, val) } } @@ -698,7 +698,7 @@ func findCredentialsInFile(key, registry, path string, legacyFormat bool) (types registry = normalizeRegistry(registry) for k, v := range auths.AuthConfigs { if normalizeAuthFileKey(k, legacyFormat) == registry { - return decodeDockerAuth(v) + return decodeDockerAuth(path, k, v) } } @@ -729,9 +729,9 @@ func authKeysForKey(key string) (res []string) { return res } -// decodeDockerAuth decodes the username and password, which is -// encoded in base64. -func decodeDockerAuth(conf dockerAuthConfig) (types.DockerAuthConfig, error) { +// decodeDockerAuth decodes the username and password from conf, +// which is entry key in path. +func decodeDockerAuth(path, key string, conf dockerAuthConfig) (types.DockerAuthConfig, error) { decoded, err := base64.StdEncoding.DecodeString(conf.Auth) if err != nil { return types.DockerAuthConfig{}, err @@ -740,6 +740,11 @@ func decodeDockerAuth(conf dockerAuthConfig) (types.DockerAuthConfig, error) { parts := strings.SplitN(string(decoded), ":", 2) if len(parts) != 2 { // if it's invalid just skip, as docker does + if len(decoded) > 0 { // Docker writes "auths": { "$host": {} } entries if a credential helper is used, don’t warn about those + logrus.Warnf(`Error parsing the "auth" field of a credential entry %q in %q, missing semicolon`, key, path) // Don’t include the text of decoded, because that might put secrets into a log. + } else { + logrus.Debugf("Found an empty credential entry %q in %q (an unhandled credential helper marker?), moving on", key, path) + } return types.DockerAuthConfig{}, nil } diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go index ca5f4a42d..999673727 100644 --- a/vendor/github.com/containers/image/v5/version/version.go +++ b/vendor/github.com/containers/image/v5/version/version.go @@ -6,12 +6,12 @@ const ( // VersionMajor is for an API incompatible changes VersionMajor = 5 // VersionMinor is for functionality in a backwards-compatible manner - VersionMinor = 22 + VersionMinor = 23 // VersionPatch is for backwards-compatible bug fixes - VersionPatch = 1 + VersionPatch = 0 // VersionDev indicates development branch. Releases will be empty string. - VersionDev = "-dev" + VersionDev = "" ) // Version is the specification version that the package types support. diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION index 6d41d503d..b978278f0 100644 --- a/vendor/github.com/containers/storage/VERSION +++ b/vendor/github.com/containers/storage/VERSION @@ -1 +1 @@ -1.42.1-dev +1.43.0 diff --git a/vendor/github.com/containers/storage/containers.go b/vendor/github.com/containers/storage/containers.go index 81c9894c5..4f2b61f52 100644 --- a/vendor/github.com/containers/storage/containers.go +++ b/vendor/github.com/containers/storage/containers.go @@ -3,7 +3,6 @@ package storage import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" "sync" @@ -144,26 +143,26 @@ func copyContainer(c *Container) *Container { } func (c *Container) MountLabel() string { - if label, ok := c.Flags["MountLabel"].(string); ok { + if label, ok := c.Flags[mountLabelFlag].(string); ok { return label } return "" } func (c *Container) ProcessLabel() string { - if label, ok := c.Flags["ProcessLabel"].(string); ok { + if label, ok := c.Flags[processLabelFlag].(string); ok { return label } return "" } func (c *Container) MountOpts() []string { - switch c.Flags["MountOpts"].(type) { + switch c.Flags[mountOptsFlag].(type) { case []string: - return c.Flags["MountOpts"].([]string) + return c.Flags[mountOptsFlag].([]string) case []interface{}: var mountOpts []string - for _, v := range c.Flags["MountOpts"].([]interface{}) { + for _, v := range c.Flags[mountOptsFlag].([]interface{}) { if flag, ok := v.(string); ok { mountOpts = append(mountOpts, flag) } @@ -197,7 +196,7 @@ func (r *containerStore) datapath(id, key string) string { func (r *containerStore) Load() error { needSave := false rpath := r.containerspath() - data, err := ioutil.ReadFile(rpath) + data, err := os.ReadFile(rpath) if err != nil && !os.IsNotExist(err) { return err } @@ -321,10 +320,10 @@ func (r *containerStore) Create(id string, names []string, image, layer, metadat return nil, ErrDuplicateID } if options.MountOpts != nil { - options.Flags["MountOpts"] = append([]string{}, options.MountOpts...) + options.Flags[mountOptsFlag] = append([]string{}, options.MountOpts...) } if options.Volatile { - options.Flags["Volatile"] = true + options.Flags[volatileFlag] = true } names = dedupeNames(names) for _, name := range names { @@ -484,7 +483,7 @@ func (r *containerStore) BigData(id, key string) ([]byte, error) { if !ok { return nil, ErrContainerUnknown } - return ioutil.ReadFile(r.datapath(c.ID, key)) + return os.ReadFile(r.datapath(c.ID, key)) } func (r *containerStore) BigDataSize(id, key string) (int64, error) { diff --git a/vendor/github.com/containers/storage/drivers/aufs/aufs.go b/vendor/github.com/containers/storage/drivers/aufs/aufs.go index f0eb6d2fd..2642874be 100644 --- a/vendor/github.com/containers/storage/drivers/aufs/aufs.go +++ b/vendor/github.com/containers/storage/drivers/aufs/aufs.go @@ -29,7 +29,6 @@ import ( "fmt" "io" "io/fs" - "io/ioutil" "os" "os/exec" "path" @@ -170,7 +169,7 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error) for _, path := range []string{"mnt", "diff"} { p := filepath.Join(home, path) - entries, err := ioutil.ReadDir(p) + entries, err := os.ReadDir(p) if err != nil { logger.WithError(err).WithField("dir", p).Error("error reading dir entries") continue @@ -730,14 +729,14 @@ func (a *Driver) aufsMount(ro []string, rw, target string, options graphdriver.M // version of aufs. func useDirperm() bool { enableDirpermLock.Do(func() { - base, err := ioutil.TempDir("", "storage-aufs-base") + base, err := os.MkdirTemp("", "storage-aufs-base") if err != nil { logrus.Errorf("Checking dirperm1: %v", err) return } defer os.RemoveAll(base) - union, err := ioutil.TempDir("", "storage-aufs-union") + union, err := os.MkdirTemp("", "storage-aufs-union") if err != nil { logrus.Errorf("Checking dirperm1: %v", err) return diff --git a/vendor/github.com/containers/storage/drivers/aufs/dirs.go b/vendor/github.com/containers/storage/drivers/aufs/dirs.go index d2325fc46..27e621633 100644 --- a/vendor/github.com/containers/storage/drivers/aufs/dirs.go +++ b/vendor/github.com/containers/storage/drivers/aufs/dirs.go @@ -1,17 +1,17 @@ +//go:build linux // +build linux package aufs import ( "bufio" - "io/ioutil" "os" "path" ) // Return all the directories func loadIds(root string) ([]string, error) { - dirs, err := ioutil.ReadDir(root) + dirs, err := os.ReadDir(root) if err != nil { return nil, err } diff --git a/vendor/github.com/containers/storage/drivers/aufs/mount_unsupported.go b/vendor/github.com/containers/storage/drivers/aufs/mount_unsupported.go deleted file mode 100644 index d030b0663..000000000 --- a/vendor/github.com/containers/storage/drivers/aufs/mount_unsupported.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build !linux - -package aufs - -import "errors" - -// MsRemount declared to specify a non-linux system mount. -const MsRemount = 0 - -func mount(source string, target string, fstype string, flags uintptr, data string) (err error) { - return errors.New("mount is not implemented on this platform") -} diff --git a/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go b/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go index be44390da..0b5d1c510 100644 --- a/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go +++ b/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go @@ -18,7 +18,6 @@ import "C" import ( "fmt" "io/fs" - "io/ioutil" "math" "os" "path" @@ -524,7 +523,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error { if err := idtools.MkdirAllAs(quotas, 0700, rootUID, rootGID); err != nil { return err } - if err := ioutil.WriteFile(path.Join(quotas, id), []byte(fmt.Sprint(driver.options.size)), 0644); err != nil { + if err := os.WriteFile(path.Join(quotas, id), []byte(fmt.Sprint(driver.options.size)), 0644); err != nil { return err } } @@ -643,7 +642,7 @@ func (d *Driver) Get(id string, options graphdriver.MountOpts) (string, error) { return "", fmt.Errorf("%s: not a directory", dir) } - if quota, err := ioutil.ReadFile(d.quotasDirID(id)); err == nil { + if quota, err := os.ReadFile(d.quotasDirID(id)); err == nil { if size, err := strconv.ParseUint(string(quota), 10, 64); err == nil && size >= d.options.minSpace { if err := d.enableQuota(); err != nil { return "", err diff --git a/vendor/github.com/containers/storage/drivers/btrfs/version_none.go b/vendor/github.com/containers/storage/drivers/btrfs/version_none.go index 905e834e3..a61d8fbd9 100644 --- a/vendor/github.com/containers/storage/drivers/btrfs/version_none.go +++ b/vendor/github.com/containers/storage/drivers/btrfs/version_none.go @@ -1,4 +1,5 @@ -// +build !linux btrfs_noversion !cgo +//go:build linux && btrfs_noversion && cgo +// +build linux,btrfs_noversion,cgo package btrfs diff --git a/vendor/github.com/containers/storage/drivers/devmapper/device_setup.go b/vendor/github.com/containers/storage/drivers/devmapper/device_setup.go index c5a64a500..96c4cdacb 100644 --- a/vendor/github.com/containers/storage/drivers/devmapper/device_setup.go +++ b/vendor/github.com/containers/storage/drivers/devmapper/device_setup.go @@ -8,7 +8,6 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -154,7 +153,7 @@ func readLVMConfig(root string) (directLVMConfig, error) { var cfg directLVMConfig p := filepath.Join(root, "setup-config.json") - b, err := ioutil.ReadFile(p) + b, err := os.ReadFile(p) if err != nil { if os.IsNotExist(err) { return cfg, nil @@ -178,7 +177,7 @@ func writeLVMConfig(root string, cfg directLVMConfig) error { if err != nil { return fmt.Errorf("marshalling direct lvm config: %w", err) } - if err := ioutil.WriteFile(p, b, 0600); err != nil { + if err := os.WriteFile(p, b, 0600); err != nil { return fmt.Errorf("writing direct lvm config to file: %w", err) } return nil @@ -242,7 +241,7 @@ func setupDirectLVM(cfg directLVMConfig) error { } profile := fmt.Sprintf("activation{\nthin_pool_autoextend_threshold=%d\nthin_pool_autoextend_percent=%d\n}", cfg.AutoExtendThreshold, cfg.AutoExtendPercent) - err = ioutil.WriteFile(lvmProfileDir+"/storage-thinpool.profile", []byte(profile), 0600) + err = os.WriteFile(lvmProfileDir+"/storage-thinpool.profile", []byte(profile), 0600) if err != nil { return fmt.Errorf("writing storage thinp autoextend profile: %w", err) } diff --git a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go index 6989a4381..697a16fda 100644 --- a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go +++ b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go @@ -9,7 +9,6 @@ import ( "fmt" "io" "io/fs" - "io/ioutil" "os" "os/exec" "path" @@ -331,7 +330,7 @@ func (devices *DeviceSet) removeMetadata(info *devInfo) error { // Given json data and file path, write it to disk func (devices *DeviceSet) writeMetaFile(jsonData []byte, filePath string) error { - tmpFile, err := ioutil.TempFile(devices.metadataDir(), ".tmp") + tmpFile, err := os.CreateTemp(devices.metadataDir(), ".tmp") if err != nil { return fmt.Errorf("devmapper: Error creating metadata file: %s", err) } @@ -630,7 +629,7 @@ func (devices *DeviceSet) createFilesystem(info *devInfo) (err error) { func (devices *DeviceSet) migrateOldMetaData() error { // Migrate old metadata file - jsonData, err := ioutil.ReadFile(devices.oldMetadataFile()) + jsonData, err := os.ReadFile(devices.oldMetadataFile()) if err != nil && !os.IsNotExist(err) { return err } @@ -955,7 +954,7 @@ func (devices *DeviceSet) createRegisterSnapDevice(hash string, baseInfo *devInf func (devices *DeviceSet) loadMetadata(hash string) *devInfo { info := &devInfo{Hash: hash, devices: devices} - jsonData, err := ioutil.ReadFile(devices.metadataFile(info)) + jsonData, err := os.ReadFile(devices.metadataFile(info)) if err != nil { logrus.Debugf("devmapper: Failed to read %s with err: %v", devices.metadataFile(info), err) return nil @@ -1276,11 +1275,11 @@ func (devices *DeviceSet) setupBaseImage() error { } func setCloseOnExec(name string) { - fileInfos, _ := ioutil.ReadDir("/proc/self/fd") - for _, i := range fileInfos { - link, _ := os.Readlink(filepath.Join("/proc/self/fd", i.Name())) + fileEntries, _ := os.ReadDir("/proc/self/fd") + for _, e := range fileEntries { + link, _ := os.Readlink(filepath.Join("/proc/self/fd", e.Name())) if link == name { - fd, err := strconv.Atoi(i.Name()) + fd, err := strconv.Atoi(e.Name()) if err == nil { unix.CloseOnExec(fd) } @@ -1370,7 +1369,7 @@ func (devices *DeviceSet) ResizePool(size int64) error { } func (devices *DeviceSet) loadTransactionMetaData() error { - jsonData, err := ioutil.ReadFile(devices.transactionMetaFile()) + jsonData, err := os.ReadFile(devices.transactionMetaFile()) if err != nil { // There is no active transaction. This will be the case // during upgrade. @@ -1451,7 +1450,7 @@ func (devices *DeviceSet) processPendingTransaction() error { } func (devices *DeviceSet) loadDeviceSetMetaData() error { - jsonData, err := ioutil.ReadFile(devices.deviceSetMetaFile()) + jsonData, err := os.ReadFile(devices.deviceSetMetaFile()) if err != nil { // For backward compatibility return success if file does // not exist. @@ -2258,7 +2257,7 @@ func (devices *DeviceSet) cancelDeferredRemoval(info *devInfo) error { } func (devices *DeviceSet) unmountAndDeactivateAll(dir string) { - files, err := ioutil.ReadDir(dir) + files, err := os.ReadDir(dir) if err != nil { logrus.Warnf("devmapper: unmountAndDeactivate: %s", err) return diff --git a/vendor/github.com/containers/storage/drivers/devmapper/driver.go b/vendor/github.com/containers/storage/drivers/devmapper/driver.go index d2f165e26..f9f775a5d 100644 --- a/vendor/github.com/containers/storage/drivers/devmapper/driver.go +++ b/vendor/github.com/containers/storage/drivers/devmapper/driver.go @@ -1,10 +1,10 @@ +//go:build linux && cgo // +build linux,cgo package devmapper import ( "fmt" - "io/ioutil" "os" "path" "strconv" @@ -227,7 +227,7 @@ func (d *Driver) Get(id string, options graphdriver.MountOpts) (string, error) { if _, err := os.Stat(idFile); err != nil && os.IsNotExist(err) { // Create an "id" file with the container/image id in it to help reconstruct this in case // of later problems - if err := ioutil.WriteFile(idFile, []byte(id), 0600); err != nil { + if err := os.WriteFile(idFile, []byte(id), 0600); err != nil { d.ctr.Decrement(mp) d.DeviceSet.UnmountDevice(id, mp) return "", err diff --git a/vendor/github.com/containers/storage/drivers/devmapper/jsoniter.go b/vendor/github.com/containers/storage/drivers/devmapper/jsoniter.go index 54db6ab4a..52f0e863e 100644 --- a/vendor/github.com/containers/storage/drivers/devmapper/jsoniter.go +++ b/vendor/github.com/containers/storage/drivers/devmapper/jsoniter.go @@ -1,3 +1,6 @@ +//go:build linux && cgo +// +build linux,cgo + package devmapper import jsoniter "github.com/json-iterator/go" diff --git a/vendor/github.com/containers/storage/drivers/driver.go b/vendor/github.com/containers/storage/drivers/driver.go index d4f92e682..7d96ebe54 100644 --- a/vendor/github.com/containers/storage/drivers/driver.go +++ b/vendor/github.com/containers/storage/drivers/driver.go @@ -48,7 +48,7 @@ type CreateOpts struct { ignoreChownErrors bool } -// MountOpts contains optional arguments for LayerStope.Mount() methods. +// MountOpts contains optional arguments for Driver.Get() methods. type MountOpts struct { // Mount label is the MAC Labels to assign to mount point (SELINUX) MountLabel string diff --git a/vendor/github.com/containers/storage/drivers/driver_linux.go b/vendor/github.com/containers/storage/drivers/driver_linux.go index 7c527d279..b9e57a60d 100644 --- a/vendor/github.com/containers/storage/drivers/driver_linux.go +++ b/vendor/github.com/containers/storage/drivers/driver_linux.go @@ -7,6 +7,7 @@ import ( "path/filepath" "github.com/containers/storage/pkg/mount" + "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) @@ -127,9 +128,14 @@ var ( // GetFSMagic returns the filesystem id given the path. func GetFSMagic(rootpath string) (FsMagic, error) { var buf unix.Statfs_t - if err := unix.Statfs(filepath.Dir(rootpath), &buf); err != nil { + path := filepath.Dir(rootpath) + if err := unix.Statfs(path, &buf); err != nil { return 0, err } + + if _, ok := FsNames[FsMagic(buf.Type)]; !ok { + logrus.Debugf("Unknown filesystem type %#x reported for %s", buf.Type, path) + } return FsMagic(buf.Type), nil } diff --git a/vendor/github.com/containers/storage/drivers/fsdiff.go b/vendor/github.com/containers/storage/drivers/fsdiff.go index f0e091004..5022037dc 100644 --- a/vendor/github.com/containers/storage/drivers/fsdiff.go +++ b/vendor/github.com/containers/storage/drivers/fsdiff.go @@ -33,10 +33,11 @@ type NaiveDiffDriver struct { // NewNaiveDiffDriver returns a fully functional driver that wraps the // given ProtoDriver and adds the capability of the following methods which // it may or may not support on its own: -// Diff(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) (io.ReadCloser, error) -// Changes(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) ([]archive.Change, error) -// ApplyDiff(id, parent string, options ApplyDiffOpts) (size int64, err error) -// DiffSize(id string, idMappings *idtools.IDMappings, parent, parentMappings *idtools.IDMappings, mountLabel string) (size int64, err error) +// +// Diff(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) (io.ReadCloser, error) +// Changes(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) ([]archive.Change, error) +// ApplyDiff(id, parent string, options ApplyDiffOpts) (size int64, err error) +// DiffSize(id string, idMappings *idtools.IDMappings, parent, parentMappings *idtools.IDMappings, mountLabel string) (size int64, err error) func NewNaiveDiffDriver(driver ProtoDriver, updater LayerIDMapUpdater) Driver { return &NaiveDiffDriver{ProtoDriver: driver, LayerIDMapUpdater: updater} } @@ -109,7 +110,7 @@ func (gdw *NaiveDiffDriver) Diff(id string, idMappings *idtools.IDMappings, pare // are extracted from tar's with full second precision on modified time. // We need this hack here to make sure calls within same second receive // correct result. - time.Sleep(startTime.Truncate(time.Second).Add(time.Second).Sub(time.Now())) + time.Sleep(time.Until(startTime.Truncate(time.Second).Add(time.Second))) return err }), nil } diff --git a/vendor/github.com/containers/storage/drivers/overlay/check.go b/vendor/github.com/containers/storage/drivers/overlay/check.go index c43ab4c1e..0a0ad7dd5 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/check.go +++ b/vendor/github.com/containers/storage/drivers/overlay/check.go @@ -6,7 +6,6 @@ package overlay import ( "errors" "fmt" - "io/ioutil" "os" "path" "path/filepath" @@ -27,7 +26,7 @@ import ( // directory or the kernel enable CONFIG_OVERLAY_FS_REDIRECT_DIR. // When these exist naive diff should be used. func doesSupportNativeDiff(d, mountOpts string) error { - td, err := ioutil.TempDir(d, "opaque-bug-check") + td, err := os.MkdirTemp(d, "opaque-bug-check") if err != nil { return err } @@ -82,7 +81,7 @@ func doesSupportNativeDiff(d, mountOpts string) error { }() // Touch file in d to force copy up of opaque directory "d" from "l2" to "l3" - if err := ioutil.WriteFile(filepath.Join(td, "merged", "d", "f"), []byte{}, 0644); err != nil { + if err := os.WriteFile(filepath.Join(td, "merged", "d", "f"), []byte{}, 0644); err != nil { return fmt.Errorf("failed to write to merged directory: %w", err) } @@ -121,7 +120,7 @@ func doesSupportNativeDiff(d, mountOpts string) error { // copying up a file from a lower layer unless/until its contents are being // modified func doesMetacopy(d, mountOpts string) (bool, error) { - td, err := ioutil.TempDir(d, "metacopy-check") + td, err := os.MkdirTemp(d, "metacopy-check") if err != nil { return false, err } @@ -158,7 +157,7 @@ func doesMetacopy(d, mountOpts string) (bool, error) { } if err := unix.Mount("overlay", filepath.Join(td, "merged"), "overlay", uintptr(flags), opts); err != nil { if errors.Is(err, unix.EINVAL) { - logrus.Info("metacopy option not supported on this kernel", mountOpts) + logrus.Infof("overlay: metacopy option not supported on this kernel, checked using options %q", mountOpts) return false, nil } return false, fmt.Errorf("failed to mount overlay for metacopy check with %q options: %w", mountOpts, err) @@ -186,7 +185,7 @@ func doesMetacopy(d, mountOpts string) (bool, error) { // doesVolatile checks if the filesystem supports the "volatile" mount option func doesVolatile(d string) (bool, error) { - td, err := ioutil.TempDir(d, "volatile-check") + td, err := os.MkdirTemp(d, "volatile-check") if err != nil { return false, err } @@ -224,7 +223,7 @@ func doesVolatile(d string) (bool, error) { // supportsIdmappedLowerLayers checks if the kernel supports mounting overlay on top of // a idmapped lower layer. func supportsIdmappedLowerLayers(home string) (bool, error) { - layerDir, err := ioutil.TempDir(home, "compat") + layerDir, err := os.MkdirTemp(home, "compat") if err != nil { return false, err } diff --git a/vendor/github.com/containers/storage/drivers/overlay/idmapped_utils.go b/vendor/github.com/containers/storage/drivers/overlay/idmapped_utils.go index 4b7b0db44..a7924ff3b 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/idmapped_utils.go +++ b/vendor/github.com/containers/storage/drivers/overlay/idmapped_utils.go @@ -5,7 +5,6 @@ package overlay import ( "fmt" - "io/ioutil" "os" "syscall" "unsafe" @@ -133,7 +132,7 @@ func createUsernsProcess(uidMaps []idtools.IDMap, gidMaps []idtools.IDMap) (int, for _, m := range idmap { mappings = mappings + fmt.Sprintf("%d %d %d\n", m.ContainerID, m.HostID, m.Size) } - return ioutil.WriteFile(fmt.Sprintf("/proc/%d/%s", pid, fname), []byte(mappings), 0600) + return os.WriteFile(fmt.Sprintf("/proc/%d/%s", pid, fname), []byte(mappings), 0600) } if err := writeMappings("uid_map", uidMaps); err != nil { cleanupFunc() diff --git a/vendor/github.com/containers/storage/drivers/overlay/jsoniter.go b/vendor/github.com/containers/storage/drivers/overlay/jsoniter.go index 2a1e9d0cc..bedda3507 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/jsoniter.go +++ b/vendor/github.com/containers/storage/drivers/overlay/jsoniter.go @@ -1,3 +1,6 @@ +//go:build linux +// +build linux + package overlay import jsoniter "github.com/json-iterator/go" diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go index 434d43521..844d2c793 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go +++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "path" @@ -346,7 +345,7 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error) logrus.Warnf("Network file system detected as backing store. Enforcing overlay option `force_mask=\"%o\"`. Add it to storage.conf to silence this warning", m) } - if err := ioutil.WriteFile(getMountProgramFlagFile(home), []byte("true"), 0600); err != nil { + if err := os.WriteFile(getMountProgramFlagFile(home), []byte("true"), 0600); err != nil { return nil, err } } else { @@ -579,11 +578,11 @@ func cachedFeatureSet(feature string, set bool) string { } func cachedFeatureCheck(runhome, feature string) (supported bool, text string, err error) { - content, err := ioutil.ReadFile(filepath.Join(runhome, cachedFeatureSet(feature, true))) + content, err := os.ReadFile(filepath.Join(runhome, cachedFeatureSet(feature, true))) if err == nil { return true, string(content), nil } - content, err = ioutil.ReadFile(filepath.Join(runhome, cachedFeatureSet(feature, false))) + content, err = os.ReadFile(filepath.Join(runhome, cachedFeatureSet(feature, false))) if err == nil { return false, string(content), nil } @@ -607,7 +606,7 @@ func SupportsNativeOverlay(home, runhome string) (bool, error) { } var contents string - flagContent, err := ioutil.ReadFile(getMountProgramFlagFile(home)) + flagContent, err := os.ReadFile(getMountProgramFlagFile(home)) if err == nil { contents = strings.TrimSpace(string(flagContent)) } @@ -620,7 +619,7 @@ func SupportsNativeOverlay(home, runhome string) (bool, error) { if err != nil && !os.IsNotExist(err) { return false, err } - if err := ioutil.WriteFile(getMountProgramFlagFile(home), []byte(fmt.Sprintf("%t", needsMountProgram)), 0600); err != nil && !os.IsNotExist(err) { + if err := os.WriteFile(getMountProgramFlagFile(home), []byte(fmt.Sprintf("%t", needsMountProgram)), 0600); err != nil && !os.IsNotExist(err) { return false, err } if needsMountProgram { @@ -656,7 +655,7 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI logLevel = logrus.DebugLevel } - layerDir, err := ioutil.TempDir(home, "compat") + layerDir, err := os.MkdirTemp(home, "compat") if err != nil { patherr, ok := err.(*os.PathError) if ok && patherr.Err == syscall.ENOSPC { @@ -715,7 +714,7 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI logrus.Debugf("overlay: test mount with multiple lowers succeeded") return supportsDType, nil } - logrus.Debugf("overlay: test mount with multiple lowers failed %v", err) + logrus.Debugf("overlay: test mount with multiple lowers failed: %v", err) } flags = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lower1Dir, upperDir, workDir) if selinux.GetEnabled() { @@ -727,7 +726,7 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI logrus.StandardLogger().Logf(logLevel, "overlay: test mount with multiple lowers failed, but succeeded with a single lower") return supportsDType, fmt.Errorf("kernel too old to provide multiple lowers feature for overlay: %w", graphdriver.ErrNotSupported) } - logrus.Debugf("overlay: test mount with a single lower failed %v", err) + logrus.Debugf("overlay: test mount with a single lower failed: %v", err) } logrus.StandardLogger().Logf(logLevel, "'overlay' is not supported over %s at %q", backingFs, home) return supportsDType, fmt.Errorf("'overlay' is not supported over %s at %q: %w", backingFs, home, graphdriver.ErrIncompatibleFS) @@ -1008,7 +1007,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, disable } // Write link id to link file - if err := ioutil.WriteFile(path.Join(dir, "link"), []byte(lid), 0644); err != nil { + if err := os.WriteFile(path.Join(dir, "link"), []byte(lid), 0644); err != nil { return err } @@ -1029,7 +1028,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, disable return err } if lower != "" { - if err := ioutil.WriteFile(path.Join(dir, lowerFile), []byte(lower), 0666); err != nil { + if err := os.WriteFile(path.Join(dir, lowerFile), []byte(lower), 0666); err != nil { return err } } @@ -1072,7 +1071,7 @@ func (d *Driver) getLower(parent string) (string, error) { } // Read Parent link fileA - parentLink, err := ioutil.ReadFile(path.Join(parentDir, "link")) + parentLink, err := os.ReadFile(path.Join(parentDir, "link")) if err != nil { if !os.IsNotExist(err) { return "", err @@ -1081,14 +1080,14 @@ func (d *Driver) getLower(parent string) (string, error) { if err := d.recreateSymlinks(); err != nil { return "", fmt.Errorf("recreating the links: %w", err) } - parentLink, err = ioutil.ReadFile(path.Join(parentDir, "link")) + parentLink, err = os.ReadFile(path.Join(parentDir, "link")) if err != nil { return "", err } } lowers := []string{path.Join(linkDir, string(parentLink))} - parentLower, err := ioutil.ReadFile(path.Join(parentDir, lowerFile)) + parentLower, err := os.ReadFile(path.Join(parentDir, lowerFile)) if err == nil { parentLowers := strings.Split(string(parentLower), ":") lowers = append(lowers, parentLowers...) @@ -1117,7 +1116,7 @@ func (d *Driver) dir2(id string) (string, bool) { func (d *Driver) getLowerDirs(id string) ([]string, error) { var lowersArray []string - lowers, err := ioutil.ReadFile(path.Join(d.dir(id), lowerFile)) + lowers, err := os.ReadFile(path.Join(d.dir(id), lowerFile)) if err == nil { for _, s := range strings.Split(string(lowers), ":") { lower := d.dir(s) @@ -1186,7 +1185,7 @@ func (d *Driver) optsAppendMappings(opts string, uidMaps, gidMaps []idtools.IDMa // Remove cleans the directories that are created for this id. func (d *Driver) Remove(id string) error { dir := d.dir(id) - lid, err := ioutil.ReadFile(path.Join(dir, "link")) + lid, err := os.ReadFile(path.Join(dir, "link")) if err == nil { if err := os.RemoveAll(path.Join(d.home, linkDir, string(lid))); err != nil { logrus.Debugf("Failed to remove link: %v", err) @@ -1209,7 +1208,7 @@ func (d *Driver) recreateSymlinks() error { const maxIterations = 10 // List all the directories under the home directory - dirs, err := ioutil.ReadDir(d.home) + dirs, err := os.ReadDir(d.home) if err != nil { return fmt.Errorf("reading driver home directory %q: %w", d.home, err) } @@ -1228,11 +1227,11 @@ func (d *Driver) recreateSymlinks() error { // the layer's "link" file that points to the layer's "diff" directory. for _, dir := range dirs { // Skip over the linkDir and anything that is not a directory - if dir.Name() == linkDir || !dir.Mode().IsDir() { + if dir.Name() == linkDir || !dir.IsDir() { continue } // Read the "link" file under each layer to get the name of the symlink - data, err := ioutil.ReadFile(path.Join(d.dir(dir.Name()), "link")) + data, err := os.ReadFile(path.Join(d.dir(dir.Name()), "link")) if err != nil { errs = multierror.Append(errs, fmt.Errorf("reading name of symlink for %q: %w", dir.Name(), err)) continue @@ -1257,7 +1256,7 @@ func (d *Driver) recreateSymlinks() error { linkDirFullPath := filepath.Join(d.home, "l") // Now check if we somehow lost a "link" file, by making sure // that each symlink we have corresponds to one. - links, err := ioutil.ReadDir(linkDirFullPath) + links, err := os.ReadDir(linkDirFullPath) if err != nil { errs = multierror.Append(errs, err) continue @@ -1287,11 +1286,11 @@ func (d *Driver) recreateSymlinks() error { // it has the basename of our symlink in it. targetID := targetComponents[1] linkFile := filepath.Join(d.dir(targetID), "link") - data, err := ioutil.ReadFile(linkFile) + data, err := os.ReadFile(linkFile) if err != nil || string(data) != link.Name() { // NOTE: If two or more links point to the same target, we will update linkFile // with every value of link.Name(), and set madeProgress = true every time. - if err := ioutil.WriteFile(linkFile, []byte(link.Name()), 0644); err != nil { + if err := os.WriteFile(linkFile, []byte(link.Name()), 0644); err != nil { errs = multierror.Append(errs, fmt.Errorf("correcting link for layer %s: %w", targetID, err)) continue } @@ -1311,7 +1310,7 @@ func (d *Driver) recreateSymlinks() error { } // Get creates and mounts the required file system for the given id and returns the mount path. -func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr error) { +func (d *Driver) Get(id string, options graphdriver.MountOpts) (string, error) { return d.get(id, false, options) } @@ -1346,7 +1345,12 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO if !d.usingMetacopy { if hasMetacopyOption(optsList) { if d.options.mountProgram == "" { - logrus.StandardLogger().Logf(logLevel, "Ignoring global metacopy option, not supported with booted kernel") + release := "" + var uts unix.Utsname + if err := unix.Uname(&uts); err == nil { + release = " " + string(uts.Release[:]) + " " + string(uts.Version[:]) + } + logrus.StandardLogger().Logf(logLevel, "Ignoring global metacopy option, not supported with booted kernel"+release) } else { logrus.Debugf("Ignoring global metacopy option, the mount program doesn't support it") } @@ -1361,7 +1365,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO } } - lowers, err := ioutil.ReadFile(path.Join(dir, lowerFile)) + lowers, err := os.ReadFile(path.Join(dir, lowerFile)) if err != nil && !os.IsNotExist(err) { return "", err } @@ -1377,7 +1381,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO // Check if $link/../diff{1-*} exist. If they do, add them, in order, as the front of the lowers // lists that we're building. "diff" itself is the upper, so it won't be in the lists. - link, err := ioutil.ReadFile(path.Join(dir, "link")) + link, err := os.ReadFile(path.Join(dir, "link")) if err != nil { if !os.IsNotExist(err) { return "", err @@ -1386,7 +1390,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO if err := d.recreateSymlinks(); err != nil { return "", fmt.Errorf("recreating the links: %w", err) } - link, err = ioutil.ReadFile(path.Join(dir, "link")) + link, err = os.ReadFile(path.Join(dir, "link")) if err != nil { return "", err } @@ -1652,7 +1656,7 @@ func (d *Driver) Put(id string) error { if count := d.ctr.Decrement(mountpoint); count > 0 { return nil } - if _, err := ioutil.ReadFile(path.Join(dir, lowerFile)); err != nil && !os.IsNotExist(err) { + if _, err := os.ReadFile(path.Join(dir, lowerFile)); err != nil && !os.IsNotExist(err) { return err } @@ -1661,7 +1665,7 @@ func (d *Driver) Put(id string) error { mappedRoot := filepath.Join(d.home, id, "mapped") // It should not happen, but cleanup any mapped mount if it was leaked. if _, err := os.Stat(mappedRoot); err == nil { - mounts, err := ioutil.ReadDir(mappedRoot) + mounts, err := os.ReadDir(mappedRoot) if err == nil { // Go through all of the mapped mounts. for _, m := range mounts { @@ -1809,7 +1813,7 @@ func (d *Driver) ApplyDiffWithDiffer(id, parent string, options *graphdriver.App if err != nil && !os.IsExist(err) { return graphdriver.DriverWithDifferOutput{}, err } - applyDir, err = ioutil.TempDir(d.getStagingDir(), "") + applyDir, err = os.MkdirTemp(d.getStagingDir(), "") if err != nil { return graphdriver.DriverWithDifferOutput{}, err } @@ -2170,7 +2174,7 @@ func (al *additionalLayer) CreateAs(id, parent string) error { } // tell the additional layer store that we use this layer. // mark this layer as "additional layer" - if err := ioutil.WriteFile(path.Join(dir, "additionallayer"), []byte(al.path), 0644); err != nil { + if err := os.WriteFile(path.Join(dir, "additionallayer"), []byte(al.path), 0644); err != nil { return err } notifyUseAdditionalLayer(al.path) @@ -2178,7 +2182,7 @@ func (al *additionalLayer) CreateAs(id, parent string) error { } func (d *Driver) getAdditionalLayerPathByID(id string) (string, error) { - al, err := ioutil.ReadFile(path.Join(d.dir(id), "additionallayer")) + al, err := os.ReadFile(path.Join(d.dir(id), "additionallayer")) if err != nil { return "", err } diff --git a/vendor/github.com/containers/storage/drivers/quota/projectquota.go b/vendor/github.com/containers/storage/drivers/quota/projectquota.go index 0e6a47fc9..ed4c7eaa5 100644 --- a/vendor/github.com/containers/storage/drivers/quota/projectquota.go +++ b/vendor/github.com/containers/storage/drivers/quota/projectquota.go @@ -52,7 +52,6 @@ struct fsxattr { import "C" import ( "fmt" - "io/ioutil" "math" "os" "path" @@ -123,11 +122,9 @@ func generateUniqueProjectID(path string) (uint32, error) { // This is a way to prevent xfs_quota management from conflicting with // containers/storage. -// // Then try to create a test directory with the next project id and set a quota // on it. If that works, continue to scan existing containers to map allocated // project ids. -// func NewControl(basePath string) (*Control, error) { // // Get project id of parent dir as minimal id to be used by driver @@ -336,7 +333,7 @@ func setProjectID(targetPath string, projectID uint32) error { // findNextProjectID - find the next project id to be used for containers // by scanning driver home directory to find used project ids func (q *Control) findNextProjectID(home string) error { - files, err := ioutil.ReadDir(home) + files, err := os.ReadDir(home) if err != nil { return fmt.Errorf("read directory failed : %s", home) } diff --git a/vendor/github.com/containers/storage/drivers/windows/windows.go b/vendor/github.com/containers/storage/drivers/windows/windows.go index 7baf6c075..7def16cd3 100644 --- a/vendor/github.com/containers/storage/drivers/windows/windows.go +++ b/vendor/github.com/containers/storage/drivers/windows/windows.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path" "path/filepath" @@ -24,7 +23,7 @@ import ( "github.com/Microsoft/go-winio" "github.com/Microsoft/go-winio/backuptar" "github.com/Microsoft/hcsshim" - "github.com/containers/storage/drivers" + graphdriver "github.com/containers/storage/drivers" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/directory" "github.com/containers/storage/pkg/idtools" @@ -475,7 +474,7 @@ func (d *Driver) Put(id string) error { // We use this opportunity to cleanup any -removing folders which may be // still left if the daemon was killed while it was removing a layer. func (d *Driver) Cleanup() error { - items, err := ioutil.ReadDir(d.info.HomeDir) + items, err := os.ReadDir(d.info.HomeDir) if err != nil { if os.IsNotExist(err) { return nil @@ -870,7 +869,7 @@ func writeLayer(layerData io.Reader, home string, id string, parentLayerPaths .. // resolveID computes the layerID information based on the given id. func (d *Driver) resolveID(id string) (string, error) { - content, err := ioutil.ReadFile(filepath.Join(d.dir(id), "layerID")) + content, err := os.ReadFile(filepath.Join(d.dir(id), "layerID")) if os.IsNotExist(err) { return id, nil } else if err != nil { @@ -881,13 +880,13 @@ func (d *Driver) resolveID(id string) (string, error) { // setID stores the layerId in disk. func (d *Driver) setID(id, altID string) error { - return ioutil.WriteFile(filepath.Join(d.dir(id), "layerId"), []byte(altID), 0600) + return os.WriteFile(filepath.Join(d.dir(id), "layerId"), []byte(altID), 0600) } // getLayerChain returns the layer chain information. func (d *Driver) getLayerChain(id string) ([]string, error) { jPath := filepath.Join(d.dir(id), "layerchain.json") - content, err := ioutil.ReadFile(jPath) + content, err := os.ReadFile(jPath) if os.IsNotExist(err) { return nil, nil } else if err != nil { @@ -911,7 +910,7 @@ func (d *Driver) setLayerChain(id string, chain []string) error { } jPath := filepath.Join(d.dir(id), "layerchain.json") - err = ioutil.WriteFile(jPath, content, 0600) + err = os.WriteFile(jPath, content, 0600) if err != nil { return fmt.Errorf("unable to write layerchain file - %s", err) } diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs.go b/vendor/github.com/containers/storage/drivers/zfs/zfs.go index eedaeed9d..0d4001783 100644 --- a/vendor/github.com/containers/storage/drivers/zfs/zfs.go +++ b/vendor/github.com/containers/storage/drivers/zfs/zfs.go @@ -18,7 +18,7 @@ import ( "github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/mount" "github.com/containers/storage/pkg/parsers" - "github.com/mistifyio/go-zfs" + zfs "github.com/mistifyio/go-zfs/v3" "github.com/opencontainers/selinux/go-selinux/label" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" diff --git a/vendor/github.com/containers/storage/images.go b/vendor/github.com/containers/storage/images.go index ad3389722..c76a6c9f9 100644 --- a/vendor/github.com/containers/storage/images.go +++ b/vendor/github.com/containers/storage/images.go @@ -3,7 +3,6 @@ package storage import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -261,7 +260,7 @@ func (i *Image) recomputeDigests() error { func (r *imageStore) Load() error { shouldSave := false rpath := r.imagespath() - data, err := ioutil.ReadFile(rpath) + data, err := os.ReadFile(rpath) if err != nil && !os.IsNotExist(err) { return err } @@ -636,7 +635,7 @@ func (r *imageStore) BigData(id, key string) ([]byte, error) { if !ok { return nil, fmt.Errorf("locating image with ID %q: %w", id, ErrImageUnknown) } - return ioutil.ReadFile(r.datapath(image.ID, key)) + return os.ReadFile(r.datapath(image.ID, key)) } func (r *imageStore) BigDataSize(id, key string) (int64, error) { diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go index 0863648ae..c23f0b26b 100644 --- a/vendor/github.com/containers/storage/layers.go +++ b/vendor/github.com/containers/storage/layers.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path" "path/filepath" @@ -352,7 +351,7 @@ func (r *layerStore) Load() error { } else { r.layerspathModified = info.ModTime() } - data, err := ioutil.ReadFile(rpath) + data, err := os.ReadFile(rpath) if err != nil && !os.IsNotExist(err) { return err } @@ -443,7 +442,7 @@ func (r *layerStore) LoadLocked() error { func (r *layerStore) loadMounts() error { mounts := make(map[string]*Layer) mpath := r.mountspath() - data, err := ioutil.ReadFile(mpath) + data, err := os.ReadFile(mpath) if err != nil && !os.IsNotExist(err) { return err } @@ -564,6 +563,8 @@ func (s *store) newLayerStore(rundir string, layerdir string, driver drivers.Dri uidMap: copyIDMap(s.uidMap), gidMap: copyIDMap(s.gidMap), } + rlstore.Lock() + defer rlstore.Unlock() if err := rlstore.Load(); err != nil { return nil, err } @@ -585,6 +586,8 @@ func newROLayerStore(rundir string, layerdir string, driver drivers.Driver) (ROL bymount: make(map[string]*Layer), byname: make(map[string]*Layer), } + rlstore.RLock() + defer rlstore.Unlock() if err := rlstore.Load(); err != nil { return nil, err } @@ -754,7 +757,7 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab templateUncompressedDigest, templateUncompressedSize = templateLayer.UncompressedDigest, templateLayer.UncompressedSize templateCompressionType = templateLayer.CompressionType templateUIDs, templateGIDs = append([]uint32{}, templateLayer.UIDs...), append([]uint32{}, templateLayer.GIDs...) - templateTSdata, tserr = ioutil.ReadFile(r.tspath(templateLayer.ID)) + templateTSdata, tserr = os.ReadFile(r.tspath(templateLayer.ID)) if tserr != nil && !os.IsNotExist(tserr) { return nil, -1, tserr } @@ -1389,6 +1392,9 @@ func (r *layerStore) Wipe() error { for id := range r.byid { ids = append(ids, id) } + sort.Slice(ids, func(i, j int) bool { + return r.byid[ids[i]].Created.After(r.byid[ids[j]].Created) + }) for _, id := range ids { if err := r.Delete(id); err != nil { return err @@ -1668,7 +1674,7 @@ func (r *layerStore) applyDiffWithOptions(to string, layerOptions *LayerOptions, if compressedDigester != nil { compressedWriter = compressedDigester.Hash() } else { - compressedWriter = ioutil.Discard + compressedWriter = io.Discard } compressedCounter := ioutils.NewWriteCounter(compressedWriter) defragmented = io.TeeReader(defragmented, compressedCounter) diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go index fc9ca3602..82c0adeb7 100644 --- a/vendor/github.com/containers/storage/pkg/archive/archive.go +++ b/vendor/github.com/containers/storage/pkg/archive/archive.go @@ -9,7 +9,6 @@ import ( "fmt" "io" "io/fs" - "io/ioutil" "os" "path/filepath" "runtime" @@ -76,6 +75,7 @@ const ( solaris = "solaris" windows = "windows" darwin = "darwin" + freebsd = "freebsd" ) var xattrsToIgnore = map[string]interface{}{ @@ -483,7 +483,7 @@ func newTarAppender(idMapping *idtools.IDMappings, writer io.Writer, chownOpts * } // canonicalTarName provides a platform-independent and consistent posix-style -//path for files and directories to be archived regardless of the platform. +// path for files and directories to be archived regardless of the platform. func canonicalTarName(name string, isDir bool) (string, error) { name, err := CanonicalTarNameForPath(name) if err != nil { @@ -672,7 +672,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L if !strings.HasPrefix(targetPath, extractDir) { return breakoutError(fmt.Errorf("invalid hardlink %q -> %q", targetPath, hdr.Linkname)) } - if err := os.Link(targetPath, path); err != nil { + if err := handleLLink(targetPath, path); err != nil { return err } @@ -1106,7 +1106,9 @@ loop: // Untar reads a stream of bytes from `archive`, parses it as a tar archive, // and unpacks it into the directory at `dest`. // The archive may be compressed with one of the following algorithms: -// identity (uncompressed), gzip, bzip2, xz. +// +// identity (uncompressed), gzip, bzip2, xz. +// // FIXME: specify behavior when target path exists vs. doesn't exist. func Untar(tarArchive io.Reader, dest string, options *TarOptions) error { return untarHandler(tarArchive, dest, options, true) @@ -1347,7 +1349,7 @@ func remapIDs(readIDMappings, writeIDMappings *idtools.IDMappings, chownOpts *id // of that file as an archive. The archive can only be read once - as soon as reading completes, // the file will be deleted. func NewTempArchive(src io.Reader, dir string) (*TempArchive, error) { - f, err := ioutil.TempFile(dir, "") + f, err := os.CreateTemp(dir, "") if err != nil { return nil, err } diff --git a/vendor/github.com/containers/storage/pkg/archive/archive_freebsd.go b/vendor/github.com/containers/storage/pkg/archive/archive_freebsd.go index fe22eb433..36017c3bf 100644 --- a/vendor/github.com/containers/storage/pkg/archive/archive_freebsd.go +++ b/vendor/github.com/containers/storage/pkg/archive/archive_freebsd.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "syscall" + "unsafe" "github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/system" @@ -111,16 +112,18 @@ func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo, forceMask * if forceMask != nil { permissionsMask = *forceMask } - if hdr.Typeflag == tar.TypeLink { - if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) { - if err := os.Chmod(path, permissionsMask); err != nil { - return err - } - } - } else if hdr.Typeflag != tar.TypeSymlink { - if err := os.Chmod(path, permissionsMask); err != nil { - return err - } + p, err := unix.BytePtrFromString(path) + if err != nil { + return err + } + _, _, e1 := unix.Syscall(unix.SYS_LCHMOD, uintptr(unsafe.Pointer(p)), uintptr(permissionsMask), 0) + if e1 != 0 { + return e1 } return nil } + +// Hardlink without following symlinks +func handleLLink(targetPath string, path string) error { + return unix.Linkat(unix.AT_FDCWD, targetPath, unix.AT_FDCWD, path, 0) +} diff --git a/vendor/github.com/containers/storage/pkg/archive/archive_unix.go b/vendor/github.com/containers/storage/pkg/archive/archive_unix.go index 7c3e442da..d0fb33066 100644 --- a/vendor/github.com/containers/storage/pkg/archive/archive_unix.go +++ b/vendor/github.com/containers/storage/pkg/archive/archive_unix.go @@ -1,3 +1,4 @@ +//go:build !windows && !freebsd // +build !windows,!freebsd package archive @@ -97,7 +98,7 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error { mode |= unix.S_IFIFO } - return system.Mknod(path, mode, int(system.Mkdev(hdr.Devmajor, hdr.Devminor))) + return system.Mknod(path, mode, system.Mkdev(hdr.Devmajor, hdr.Devminor)) } func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo, forceMask *os.FileMode) error { @@ -118,3 +119,13 @@ func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo, forceMask * } return nil } + +// Hardlink without symlinks +func handleLLink(targetPath, path string) error { + // Note: on Linux, the link syscall will not follow symlinks. + // This behavior is implementation-dependent since + // POSIX.1-2008 so to make it clear that we need non-symlink + // following here we use the linkat syscall which has a flags + // field to select symlink following or not. + return unix.Linkat(unix.AT_FDCWD, targetPath, unix.AT_FDCWD, path, 0) +} diff --git a/vendor/github.com/containers/storage/pkg/archive/archive_windows.go b/vendor/github.com/containers/storage/pkg/archive/archive_windows.go index 8e7a2fd02..e44011775 100644 --- a/vendor/github.com/containers/storage/pkg/archive/archive_windows.go +++ b/vendor/github.com/containers/storage/pkg/archive/archive_windows.go @@ -78,3 +78,8 @@ func getFileUIDGID(stat interface{}) (idtools.IDPair, error) { // no notion of file ownership mapping yet on Windows return idtools.IDPair{0, 0}, nil } + +// Hardlink without following symlinks +func handleLLink(targetPath string, path string) error { + return os.Link(targetPath, path) +} diff --git a/vendor/github.com/containers/storage/pkg/archive/changes.go b/vendor/github.com/containers/storage/pkg/archive/changes.go index c7bb25d0f..6cd9e35e9 100644 --- a/vendor/github.com/containers/storage/pkg/archive/changes.go +++ b/vendor/github.com/containers/storage/pkg/archive/changes.go @@ -5,7 +5,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "os" "path/filepath" "reflect" @@ -403,7 +402,7 @@ func ChangesDirs(newDir string, newMappings *idtools.IDMappings, oldDir string, oldRoot, newRoot *FileInfo ) if oldDir == "" { - emptyDir, err := ioutil.TempDir("", "empty") + emptyDir, err := os.MkdirTemp("", "empty") if err != nil { return nil, err } diff --git a/vendor/github.com/containers/storage/pkg/archive/copy.go b/vendor/github.com/containers/storage/pkg/archive/copy.go index 6298a674d..2c714e8da 100644 --- a/vendor/github.com/containers/storage/pkg/archive/copy.go +++ b/vendor/github.com/containers/storage/pkg/archive/copy.go @@ -4,7 +4,6 @@ import ( "archive/tar" "errors" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -255,7 +254,7 @@ func PrepareArchiveCopy(srcContent io.Reader, srcInfo, dstInfo CopyInfo) (dstDir // The destination exists as a directory. No alteration // to srcContent is needed as its contents can be // simply extracted to the destination directory. - return dstInfo.Path, ioutil.NopCloser(srcContent), nil + return dstInfo.Path, io.NopCloser(srcContent), nil case dstInfo.Exists && srcInfo.IsDir: // The destination exists as some type of file and the source // content is a directory. This is an error condition since diff --git a/vendor/github.com/containers/storage/pkg/archive/diff.go b/vendor/github.com/containers/storage/pkg/archive/diff.go index 59a3207fd..7e835d44b 100644 --- a/vendor/github.com/containers/storage/pkg/archive/diff.go +++ b/vendor/github.com/containers/storage/pkg/archive/diff.go @@ -5,7 +5,6 @@ import ( "fmt" "io" "io/fs" - "io/ioutil" "os" "path/filepath" "runtime" @@ -102,7 +101,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, basename := filepath.Base(hdr.Name) aufsHardlinks[basename] = hdr if aufsTempdir == "" { - if aufsTempdir, err = ioutil.TempDir("", "storageplnk"); err != nil { + if aufsTempdir, err = os.MkdirTemp("", "storageplnk"); err != nil { return 0, err } defer os.RemoveAll(aufsTempdir) diff --git a/vendor/github.com/containers/storage/pkg/chrootarchive/archive.go b/vendor/github.com/containers/storage/pkg/chrootarchive/archive.go index d66c98b30..b5d8961e5 100644 --- a/vendor/github.com/containers/storage/pkg/chrootarchive/archive.go +++ b/vendor/github.com/containers/storage/pkg/chrootarchive/archive.go @@ -4,7 +4,6 @@ import ( stdtar "archive/tar" "fmt" "io" - "io/ioutil" "os" "path/filepath" "sync" @@ -31,7 +30,8 @@ func NewArchiverWithChown(tarIDMappings *idtools.IDMappings, chownOpts *idtools. // Untar reads a stream of bytes from `archive`, parses it as a tar archive, // and unpacks it into the directory at `dest`. // The archive may be compressed with one of the following algorithms: -// identity (uncompressed), gzip, bzip2, xz. +// +// identity (uncompressed), gzip, bzip2, xz. func Untar(tarArchive io.Reader, dest string, options *archive.TarOptions) error { return untarHandler(tarArchive, dest, options, true, dest) } @@ -82,7 +82,7 @@ func untarHandler(tarArchive io.Reader, dest string, options *archive.TarOptions } } - r := ioutil.NopCloser(tarArchive) + r := io.NopCloser(tarArchive) if decompress { decompressedArchive, err := archive.DecompressStream(tarArchive) if err != nil { diff --git a/vendor/github.com/containers/storage/pkg/chrootarchive/archive_unix.go b/vendor/github.com/containers/storage/pkg/chrootarchive/archive_unix.go index 2d64c2800..8cc0f33b3 100644 --- a/vendor/github.com/containers/storage/pkg/chrootarchive/archive_unix.go +++ b/vendor/github.com/containers/storage/pkg/chrootarchive/archive_unix.go @@ -9,7 +9,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "os" "path/filepath" "runtime" @@ -111,7 +110,7 @@ func invokeUnpack(decompressedArchive io.Reader, dest string, options *archive.T // when `xz -d -c -q | storage-untar ...` failed on storage-untar side, // we need to exhaust `xz`'s output, otherwise the `xz` side will be // pending on write pipe forever - io.Copy(ioutil.Discard, decompressedArchive) + io.Copy(io.Discard, decompressedArchive) return fmt.Errorf("processing tar file(%s): %w", output, err) } 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 255882174..09ef6d5de 100644 --- a/vendor/github.com/containers/storage/pkg/chrootarchive/chroot_linux.go +++ b/vendor/github.com/containers/storage/pkg/chrootarchive/chroot_linux.go @@ -2,7 +2,6 @@ package chrootarchive import ( "fmt" - "io/ioutil" "net" "os" "os/user" @@ -51,7 +50,7 @@ func chroot(path string) (err error) { } // setup oldRoot for pivot_root - pivotDir, err := ioutil.TempDir(path, ".pivot_root") + pivotDir, err := os.MkdirTemp(path, ".pivot_root") if err != nil { return fmt.Errorf("setting up pivot dir: %w", err) } diff --git a/vendor/github.com/containers/storage/pkg/chrootarchive/diff_darwin.go b/vendor/github.com/containers/storage/pkg/chrootarchive/diff_darwin.go index d6326c808..52c677bc7 100644 --- a/vendor/github.com/containers/storage/pkg/chrootarchive/diff_darwin.go +++ b/vendor/github.com/containers/storage/pkg/chrootarchive/diff_darwin.go @@ -3,7 +3,6 @@ package chrootarchive import ( "fmt" "io" - "io/ioutil" "os" "path/filepath" @@ -26,7 +25,7 @@ func applyLayerHandler(dest string, layer io.Reader, options *archive.TarOptions layer = decompressed } - tmpDir, err := ioutil.TempDir(os.Getenv("temp"), "temp-storage-extract") + tmpDir, err := os.MkdirTemp(os.Getenv("temp"), "temp-storage-extract") if err != nil { return 0, fmt.Errorf("ApplyLayer failed to create temp-storage-extract under %s. %s", dest, err) } diff --git a/vendor/github.com/containers/storage/pkg/chrootarchive/diff_unix.go b/vendor/github.com/containers/storage/pkg/chrootarchive/diff_unix.go index 511c61761..90f453913 100644 --- a/vendor/github.com/containers/storage/pkg/chrootarchive/diff_unix.go +++ b/vendor/github.com/containers/storage/pkg/chrootarchive/diff_unix.go @@ -8,7 +8,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "os" "path/filepath" "runtime" @@ -56,7 +55,7 @@ func applyLayer() { options.InUserNS = true } - if tmpDir, err = ioutil.TempDir("/", "temp-storage-extract"); err != nil { + if tmpDir, err = os.MkdirTemp("/", "temp-storage-extract"); err != nil { fatal(err) } diff --git a/vendor/github.com/containers/storage/pkg/chrootarchive/diff_windows.go b/vendor/github.com/containers/storage/pkg/chrootarchive/diff_windows.go index 8f8e88bfb..8bfff5d65 100644 --- a/vendor/github.com/containers/storage/pkg/chrootarchive/diff_windows.go +++ b/vendor/github.com/containers/storage/pkg/chrootarchive/diff_windows.go @@ -3,7 +3,6 @@ package chrootarchive import ( "fmt" "io" - "io/ioutil" "os" "path/filepath" @@ -30,7 +29,7 @@ func applyLayerHandler(dest string, layer io.Reader, options *archive.TarOptions layer = decompressed } - tmpDir, err := ioutil.TempDir(os.Getenv("temp"), "temp-storage-extract") + tmpDir, err := os.MkdirTemp(os.Getenv("temp"), "temp-storage-extract") if err != nil { return 0, fmt.Errorf("ApplyLayer failed to create temp-storage-extract under %s. %s", dest, err) } diff --git a/vendor/github.com/containers/storage/pkg/chrootarchive/init_unix.go b/vendor/github.com/containers/storage/pkg/chrootarchive/init_unix.go index 45caec972..274a946e2 100644 --- a/vendor/github.com/containers/storage/pkg/chrootarchive/init_unix.go +++ b/vendor/github.com/containers/storage/pkg/chrootarchive/init_unix.go @@ -1,3 +1,4 @@ +//go:build !windows && !darwin // +build !windows,!darwin package chrootarchive @@ -5,7 +6,6 @@ package chrootarchive import ( "fmt" "io" - "io/ioutil" "os" "github.com/containers/storage/pkg/reexec" @@ -25,5 +25,5 @@ func fatal(err error) { // flush consumes all the bytes from the reader discarding // any errors func flush(r io.Reader) (bytes int64, err error) { - return io.Copy(ioutil.Discard, r) + return io.Copy(io.Discard, r) } diff --git a/vendor/github.com/containers/storage/pkg/chunked/cache_linux.go b/vendor/github.com/containers/storage/pkg/chunked/cache_linux.go index c88091393..727956799 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/cache_linux.go +++ b/vendor/github.com/containers/storage/pkg/chunked/cache_linux.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "sort" "strconv" @@ -128,7 +127,7 @@ func (c *layersCache) load() error { } defer manifestReader.Close() - manifest, err := ioutil.ReadAll(manifestReader) + manifest, err := io.ReadAll(manifestReader) if err != nil { return fmt.Errorf("open manifest file for layer %q: %w", r.ID, err) } @@ -334,7 +333,7 @@ func writeCache(manifest []byte, id string, dest setBigData) (*metadata, error) }() defer pipeReader.Close() - counter := ioutils.NewWriteCounter(ioutil.Discard) + counter := ioutils.NewWriteCounter(io.Discard) r := io.TeeReader(pipeReader, counter) diff --git a/vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go b/vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go index aeb7cfd4f..362c168d0 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go +++ b/vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go @@ -8,7 +8,6 @@ import ( "bufio" "encoding/base64" "io" - "io/ioutil" "github.com/containers/storage/pkg/chunked/internal" "github.com/containers/storage/pkg/ioutils" @@ -21,9 +20,7 @@ const holesThreshold = int64(1 << 10) type holesFinder struct { reader *bufio.Reader - fileOff int64 zeros int64 - from int64 threshold int64 state int @@ -432,7 +429,7 @@ func zstdChunkedWriterWithLevel(out io.Writer, metadata map[string]string, level go func() { ch <- writeZstdChunkedStream(out, metadata, r, level) - io.Copy(ioutil.Discard, r) + io.Copy(io.Discard, r) r.Close() close(ch) }() diff --git a/vendor/github.com/containers/storage/pkg/chunked/storage.go b/vendor/github.com/containers/storage/pkg/chunked/storage.go index 9212cbbcf..f0bd36273 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/storage.go +++ b/vendor/github.com/containers/storage/pkg/chunked/storage.go @@ -1,7 +1,6 @@ package chunked import ( - "fmt" "io" ) @@ -22,5 +21,5 @@ type ErrBadRequest struct { } func (e ErrBadRequest) Error() string { - return fmt.Sprintf("bad request") + return "bad request" } 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 7278f2d88..83d6e2f88 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go +++ b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go @@ -8,7 +8,6 @@ import ( "fmt" "hash" "io" - "io/ioutil" "os" "path/filepath" "reflect" @@ -657,7 +656,7 @@ func (c *chunkedDiffer) prepareCompressedStreamToFile(partCompression compressed // Only the missing chunk in the requested part refers to a hole. // The received data must be discarded. limitReader := io.LimitReader(from, mf.CompressedSize) - _, err := io.CopyBuffer(ioutil.Discard, limitReader, c.copyBuffer) + _, err := io.CopyBuffer(io.Discard, limitReader, c.copyBuffer) return fileTypeHole, err case partCompression == fileTypeZstdChunked: c.rawReader = io.LimitReader(from, mf.CompressedSize) @@ -856,7 +855,7 @@ func (c *chunkedDiffer) storeMissingFiles(streams chan io.ReadCloser, errs chan for _, mf := range missingPart.Chunks { if mf.Gap > 0 { limitReader := io.LimitReader(part, mf.Gap) - _, err := io.CopyBuffer(ioutil.Discard, limitReader, c.copyBuffer) + _, err := io.CopyBuffer(io.Discard, limitReader, c.copyBuffer) if err != nil { Err = err goto exit @@ -906,7 +905,7 @@ func (c *chunkedDiffer) storeMissingFiles(streams chan io.ReadCloser, errs chan goto exit } if c.rawReader != nil { - if _, err := io.CopyBuffer(ioutil.Discard, c.rawReader, c.copyBuffer); err != nil { + if _, err := io.CopyBuffer(io.Discard, c.rawReader, c.copyBuffer); err != nil { Err = err goto exit } diff --git a/vendor/github.com/containers/storage/pkg/directory/directory.go b/vendor/github.com/containers/storage/pkg/directory/directory.go index b0ce706e5..829fe59f3 100644 --- a/vendor/github.com/containers/storage/pkg/directory/directory.go +++ b/vendor/github.com/containers/storage/pkg/directory/directory.go @@ -1,7 +1,6 @@ package directory import ( - "io/ioutil" "os" "path/filepath" ) @@ -15,7 +14,7 @@ type DiskUsage struct { // MoveToSubdir moves all contents of a directory to a subdirectory underneath the original path func MoveToSubdir(oldpath, subdir string) error { - infos, err := ioutil.ReadDir(oldpath) + infos, err := os.ReadDir(oldpath) if err != nil { return err } diff --git a/vendor/github.com/containers/storage/pkg/fileutils/fileutils_unix.go b/vendor/github.com/containers/storage/pkg/fileutils/fileutils_unix.go index 92056c1d5..92e0263d8 100644 --- a/vendor/github.com/containers/storage/pkg/fileutils/fileutils_unix.go +++ b/vendor/github.com/containers/storage/pkg/fileutils/fileutils_unix.go @@ -1,10 +1,10 @@ +//go:build linux || freebsd // +build linux freebsd package fileutils import ( "fmt" - "io/ioutil" "os" "github.com/sirupsen/logrus" @@ -13,7 +13,7 @@ import ( // GetTotalUsedFds Returns the number of used File Descriptors by // reading it via /proc filesystem. func GetTotalUsedFds() int { - if fds, err := ioutil.ReadDir(fmt.Sprintf("/proc/%d/fd", os.Getpid())); err != nil { + if fds, err := os.ReadDir(fmt.Sprintf("/proc/%d/fd", os.Getpid())); err != nil { logrus.Errorf("%v", err) } else { return len(fds) diff --git a/vendor/github.com/containers/storage/pkg/fsutils/fsutils_linux.go b/vendor/github.com/containers/storage/pkg/fsutils/fsutils_linux.go index e6094b55b..9854cac1c 100644 --- a/vendor/github.com/containers/storage/pkg/fsutils/fsutils_linux.go +++ b/vendor/github.com/containers/storage/pkg/fsutils/fsutils_linux.go @@ -1,10 +1,10 @@ +//go:build linux // +build linux package fsutils import ( "fmt" - "io/ioutil" "os" "unsafe" @@ -12,14 +12,14 @@ import ( ) func locateDummyIfEmpty(path string) (string, error) { - children, err := ioutil.ReadDir(path) + children, err := os.ReadDir(path) if err != nil { return "", err } if len(children) != 0 { return "", nil } - dummyFile, err := ioutil.TempFile(path, "fsutils-dummy") + dummyFile, err := os.CreateTemp(path, "fsutils-dummy") if err != nil { return "", err } diff --git a/vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go b/vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go index 33177bdf3..37dc9159f 100644 --- a/vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go +++ b/vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package homedir @@ -46,7 +47,7 @@ func GetShortcutString() string { // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html func GetRuntimeDir() (string, error) { if xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR"); xdgRuntimeDir != "" { - return xdgRuntimeDir, nil + return filepath.EvalSymlinks(xdgRuntimeDir) } return "", errors.New("could not get XDG_RUNTIME_DIR") } diff --git a/vendor/github.com/containers/storage/pkg/idtools/idtools.go b/vendor/github.com/containers/storage/pkg/idtools/idtools.go index a7f4eaf13..a57609067 100644 --- a/vendor/github.com/containers/storage/pkg/idtools/idtools.go +++ b/vendor/github.com/containers/storage/pkg/idtools/idtools.go @@ -3,7 +3,6 @@ package idtools import ( "bufio" "fmt" - "io/ioutil" "os" "os/user" "runtime" @@ -219,7 +218,7 @@ func getOverflowUID() int { overflowUIDOnce.Do(func() { // 65534 is the value on older kernels where /proc/sys/kernel/overflowuid is not present overflowUID = 65534 - if content, err := ioutil.ReadFile("/proc/sys/kernel/overflowuid"); err == nil { + if content, err := os.ReadFile("/proc/sys/kernel/overflowuid"); err == nil { if tmp, err := strconv.Atoi(string(content)); err == nil { overflowUID = tmp } @@ -233,7 +232,7 @@ func getOverflowGID() int { overflowGIDOnce.Do(func() { // 65534 is the value on older kernels where /proc/sys/kernel/overflowgid is not present overflowGID = 65534 - if content, err := ioutil.ReadFile("/proc/sys/kernel/overflowgid"); err == nil { + if content, err := os.ReadFile("/proc/sys/kernel/overflowgid"); err == nil { if tmp, err := strconv.Atoi(string(content)); err == nil { overflowGID = tmp } diff --git a/vendor/github.com/containers/storage/pkg/ioutils/fswriters.go b/vendor/github.com/containers/storage/pkg/ioutils/fswriters.go index cd12470f9..a74893e81 100644 --- a/vendor/github.com/containers/storage/pkg/ioutils/fswriters.go +++ b/vendor/github.com/containers/storage/pkg/ioutils/fswriters.go @@ -2,7 +2,6 @@ package ioutils import ( "io" - "io/ioutil" "os" "path/filepath" ) @@ -28,7 +27,7 @@ func SetDefaultOptions(opts AtomicFileWriterOptions) { // temporary file and closing it atomically changes the temporary file to // destination path. Writing and closing concurrently is not allowed. func NewAtomicFileWriterWithOpts(filename string, perm os.FileMode, opts *AtomicFileWriterOptions) (io.WriteCloser, error) { - f, err := ioutil.TempFile(filepath.Dir(filename), ".tmp-"+filepath.Base(filename)) + f, err := os.CreateTemp(filepath.Dir(filename), ".tmp-"+filepath.Base(filename)) if err != nil { return nil, err } @@ -124,7 +123,7 @@ type AtomicWriteSet struct { // commit. If no temporary directory is given the system // default is used. func NewAtomicWriteSet(tmpDir string) (*AtomicWriteSet, error) { - td, err := ioutil.TempDir(tmpDir, "write-set-") + td, err := os.MkdirTemp(tmpDir, "write-set-") if err != nil { return nil, err } diff --git a/vendor/github.com/containers/storage/pkg/ioutils/temp_unix.go b/vendor/github.com/containers/storage/pkg/ioutils/temp_unix.go index 1539ad21b..9d5af610e 100644 --- a/vendor/github.com/containers/storage/pkg/ioutils/temp_unix.go +++ b/vendor/github.com/containers/storage/pkg/ioutils/temp_unix.go @@ -1,10 +1,11 @@ +//go:build !windows // +build !windows package ioutils -import "io/ioutil" +import "os" -// TempDir on Unix systems is equivalent to ioutil.TempDir. +// TempDir on Unix systems is equivalent to os.MkdirTemp. func TempDir(dir, prefix string) (string, error) { - return ioutil.TempDir(dir, prefix) + return os.MkdirTemp(dir, prefix) } diff --git a/vendor/github.com/containers/storage/pkg/ioutils/temp_windows.go b/vendor/github.com/containers/storage/pkg/ioutils/temp_windows.go index c719c120b..2c2242d69 100644 --- a/vendor/github.com/containers/storage/pkg/ioutils/temp_windows.go +++ b/vendor/github.com/containers/storage/pkg/ioutils/temp_windows.go @@ -1,16 +1,17 @@ +//go:build windows // +build windows package ioutils import ( - "io/ioutil" + "os" "github.com/containers/storage/pkg/longpath" ) -// TempDir is the equivalent of ioutil.TempDir, except that the result is in Windows longpath format. +// TempDir is the equivalent of os.MkdirTemp, except that the result is in Windows longpath format. func TempDir(dir, prefix string) (string, error) { - tempDir, err := ioutil.TempDir(dir, prefix) + tempDir, err := os.MkdirTemp(dir, prefix) if err != nil { return "", err } diff --git a/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go b/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go index b04c1ad05..3c242016d 100644 --- a/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go +++ b/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go @@ -65,19 +65,19 @@ func newLastWriterID() []byte { } // openLock opens the file at path and returns the corresponding file -// descriptor. Note that the path is opened read-only when ro is set. If ro -// is unset, openLock will open the path read-write and create the file if -// necessary. +// descriptor. The path is opened either read-only or read-write, +// depending on the value of ro argument. +// +// openLock will create the file and its parent directories, +// if necessary. func openLock(path string, ro bool) (fd int, err error) { + flags := unix.O_CLOEXEC | os.O_CREATE if ro { - fd, err = unix.Open(path, os.O_RDONLY|unix.O_CLOEXEC|os.O_CREATE, 0) + flags |= os.O_RDONLY } else { - fd, err = unix.Open(path, - os.O_RDWR|unix.O_CLOEXEC|os.O_CREATE, - unix.S_IRUSR|unix.S_IWUSR|unix.S_IRGRP|unix.S_IROTH, - ) + flags |= os.O_RDWR } - + fd, err = unix.Open(path, flags, 0o644) if err == nil { return } @@ -91,7 +91,7 @@ func openLock(path string, ro bool) (fd int, err error) { return openLock(path, ro) } - return + return fd, &os.PathError{Op: "open", Path: path, Err: err} } // createLockerForPath returns a Locker object, possibly (depending on the platform) @@ -158,7 +158,7 @@ func (l *lockfile) lock(lType int16, recursive bool) { // If we're the first reference on the lock, we need to open the file again. fd, err := openLock(l.file, l.ro) if err != nil { - panic(fmt.Sprintf("error opening %q: %v", l.file, err)) + panic(err) } l.fd = uintptr(fd) diff --git a/vendor/github.com/containers/storage/pkg/system/mknod.go b/vendor/github.com/containers/storage/pkg/system/mknod.go index c276ce8e8..d3d0ed8a1 100644 --- a/vendor/github.com/containers/storage/pkg/system/mknod.go +++ b/vendor/github.com/containers/storage/pkg/system/mknod.go @@ -1,3 +1,4 @@ +//go:build !windows && !freebsd // +build !windows,!freebsd package system @@ -8,8 +9,8 @@ import ( // Mknod creates a filesystem node (file, device special file or named pipe) named path // with attributes specified by mode and dev. -func Mknod(path string, mode uint32, dev int) error { - return unix.Mknod(path, mode, dev) +func Mknod(path string, mode uint32, dev uint32) error { + return unix.Mknod(path, mode, int(dev)) } // Mkdev is used to build the value of linux devices (in /dev/) which specifies major diff --git a/vendor/github.com/containers/storage/pkg/system/mknod_freebsd.go b/vendor/github.com/containers/storage/pkg/system/mknod_freebsd.go index d09005589..53c3f2837 100644 --- a/vendor/github.com/containers/storage/pkg/system/mknod_freebsd.go +++ b/vendor/github.com/containers/storage/pkg/system/mknod_freebsd.go @@ -1,3 +1,4 @@ +//go:build freebsd // +build freebsd package system @@ -17,6 +18,6 @@ func Mknod(path string, mode uint32, dev uint64) error { // Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes. // They are, from low to high: the lower 8 bits of the minor, then 12 bits of the major, // then the top 12 bits of the minor. -func Mkdev(major int64, minor int64) uint32 { - return uint32(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff)) +func Mkdev(major int64, minor int64) uint64 { + return uint64(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff)) } diff --git a/vendor/github.com/containers/storage/pkg/system/rm.go b/vendor/github.com/containers/storage/pkg/system/rm.go index b65121f1d..5d63dc741 100644 --- a/vendor/github.com/containers/storage/pkg/system/rm.go +++ b/vendor/github.com/containers/storage/pkg/system/rm.go @@ -35,6 +35,9 @@ func EnsureRemoveAll(dir string) error { } for { + if err := resetFileFlags(dir); err != nil { + return fmt.Errorf("resetting file flags: %w", err) + } err := os.RemoveAll(dir) if err == nil { return nil diff --git a/vendor/github.com/containers/storage/pkg/system/rm_common.go b/vendor/github.com/containers/storage/pkg/system/rm_common.go new file mode 100644 index 000000000..117eb1d6d --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/system/rm_common.go @@ -0,0 +1,10 @@ +//go:build !freebsd +// +build !freebsd + +package system + +// Reset file flags in a directory tree. This allows EnsureRemoveAll +// to delete trees which have the immutable flag set. +func resetFileFlags(dir string) error { + return nil +} diff --git a/vendor/github.com/containers/storage/pkg/system/rm_freebsd.go b/vendor/github.com/containers/storage/pkg/system/rm_freebsd.go new file mode 100644 index 000000000..35896c11d --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/system/rm_freebsd.go @@ -0,0 +1,32 @@ +package system + +import ( + "io/fs" + "path/filepath" + "unsafe" + + "golang.org/x/sys/unix" +) + +func lchflags(path string, flags int) (err error) { + p, err := unix.BytePtrFromString(path) + if err != nil { + return err + } + _, _, e1 := unix.Syscall(unix.SYS_LCHFLAGS, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) + if e1 != 0 { + return e1 + } + return nil +} + +// Reset file flags in a directory tree. This allows EnsureRemoveAll +// to delete trees which have the immutable flag set. +func resetFileFlags(dir string) error { + return filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error { + if err := lchflags(path, 0); err != nil { + return err + } + return nil + }) +} diff --git a/vendor/github.com/containers/storage/pkg/system/utimes_freebsd.go b/vendor/github.com/containers/storage/pkg/system/utimes_freebsd.go index 6a7752437..edc588a63 100644 --- a/vendor/github.com/containers/storage/pkg/system/utimes_freebsd.go +++ b/vendor/github.com/containers/storage/pkg/system/utimes_freebsd.go @@ -10,13 +10,14 @@ import ( // LUtimesNano is used to change access and modification time of the specified path. // It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm. func LUtimesNano(path string, ts []syscall.Timespec) error { + atFdCwd := unix.AT_FDCWD + var _path *byte _path, err := unix.BytePtrFromString(path) if err != nil { return err } - - if _, _, err := unix.Syscall(unix.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != unix.ENOSYS { + if _, _, err := unix.Syscall6(unix.SYS_UTIMENSAT, uintptr(atFdCwd), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), unix.AT_SYMLINK_NOFOLLOW, 0, 0); err != 0 && err != unix.ENOSYS { return err } diff --git a/vendor/github.com/containers/storage/pkg/unshare/unshare_linux.go b/vendor/github.com/containers/storage/pkg/unshare/unshare_linux.go index b7ad1e19e..3fc36201c 100644 --- a/vendor/github.com/containers/storage/pkg/unshare/unshare_linux.go +++ b/vendor/github.com/containers/storage/pkg/unshare/unshare_linux.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "os/signal" @@ -390,7 +389,7 @@ const ( // hasFullUsersMappings checks whether the current user namespace has all the IDs mapped. func hasFullUsersMappings() (bool, error) { - content, err := ioutil.ReadFile("/proc/self/uid_map") + content, err := os.ReadFile("/proc/self/uid_map") if err != nil { return false, err } diff --git a/vendor/github.com/containers/storage/storage.conf b/vendor/github.com/containers/storage/storage.conf index 1814b4727..1294f6a9a 100644 --- a/vendor/github.com/containers/storage/storage.conf +++ b/vendor/github.com/containers/storage/storage.conf @@ -65,7 +65,7 @@ pull_options = {enable_partial_images = "false", use_hard_links = "false", ostre # Remap-UIDs/GIDs is the mapping from UIDs/GIDs as they should appear inside of # a container, to the UIDs/GIDs as they should appear outside of the container, # and the length of the range of UIDs/GIDs. Additional mapped sets can be -# listed and will be needed by libraries, but there are limits to the number of +# listed and will be heeded by libraries, but there are limits to the number of # mappings which the kernel will allow when you later attempt to run a # container. # diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go index afcf8ee70..fb1faaa13 100644 --- a/vendor/github.com/containers/storage/store.go +++ b/vendor/github.com/containers/storage/store.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path/filepath" "reflect" @@ -38,6 +37,13 @@ const ( removeNames ) +const ( + volatileFlag = "Volatile" + mountLabelFlag = "MountLabel" + processLabelFlag = "ProcessLabel" + mountOptsFlag = "MountOpts" +) + var ( stores []*store storesLock sync.Mutex @@ -632,16 +638,17 @@ type store struct { // If StoreOptions `options` haven't been fully populated, then DefaultStoreOptions are used. // // These defaults observe environment variables: -// * `STORAGE_DRIVER` for the name of the storage driver to attempt to use -// * `STORAGE_OPTS` for the string of options to pass to the driver +// - `STORAGE_DRIVER` for the name of the storage driver to attempt to use +// - `STORAGE_OPTS` for the string of options to pass to the driver // // Note that we do some of this work in a child process. The calling process's // main() function needs to import our pkg/reexec package and should begin with // something like this in order to allow us to properly start that child // process: -// if reexec.Init() { -// return -// } +// +// if reexec.Init() { +// return +// } func GetStore(options types.StoreOptions) (Store, error) { defaultOpts, err := types.Options() if err != nil { @@ -1399,11 +1406,10 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat if options.Flags == nil { options.Flags = make(map[string]interface{}) } - plabel, _ := options.Flags["ProcessLabel"].(string) - mlabel, _ := options.Flags["MountLabel"].(string) - if (plabel == "" && mlabel != "") || - (plabel != "" && mlabel == "") { - return nil, errors.New("processLabel and Mountlabel must either not be specified or both specified") + plabel, _ := options.Flags[processLabelFlag].(string) + mlabel, _ := options.Flags[mountLabelFlag].(string) + if (plabel == "" && mlabel != "") || (plabel != "" && mlabel == "") { + return nil, errors.New("ProcessLabel and Mountlabel must either not be specified or both specified") } if plabel == "" { @@ -1411,11 +1417,12 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat if err != nil { return nil, err } - options.Flags["ProcessLabel"] = processLabel - options.Flags["MountLabel"] = mountLabel + mlabel = mountLabel + options.Flags[processLabelFlag] = processLabel + options.Flags[mountLabelFlag] = mountLabel } - clayer, err := rlstore.Create(layer, imageTopLayer, nil, options.Flags["MountLabel"].(string), options.StorageOpt, layerOptions, true) + clayer, err := rlstore.Create(layer, imageTopLayer, nil, mlabel, options.StorageOpt, layerOptions, true) if err != nil { return nil, err } @@ -2790,8 +2797,10 @@ func (s *store) Mount(id, mountLabel string) (string, error) { options.GidMaps = container.GIDMap options.Options = container.MountOpts() if !s.disableVolatile { - if v, found := container.Flags["Volatile"]; found { - options.Volatile = v.(bool) + if v, found := container.Flags[volatileFlag]; found { + if b, ok := v.(bool); ok { + options.Volatile = b + } } } } @@ -3541,7 +3550,7 @@ func (s *store) FromContainerDirectory(id, file string) ([]byte, error) { if err != nil { return nil, err } - return ioutil.ReadFile(filepath.Join(dir, file)) + return os.ReadFile(filepath.Join(dir, file)) } func (s *store) SetContainerRunDirectoryFile(id, file string, data []byte) error { @@ -3561,7 +3570,7 @@ func (s *store) FromContainerRunDirectory(id, file string) ([]byte, error) { if err != nil { return nil, err } - return ioutil.ReadFile(filepath.Join(dir, file)) + return os.ReadFile(filepath.Join(dir, file)) } func (s *store) Shutdown(force bool) ([]string, error) { diff --git a/vendor/github.com/containers/storage/types/options.go b/vendor/github.com/containers/storage/types/options.go index 5421c02da..4c873b45f 100644 --- a/vendor/github.com/containers/storage/types/options.go +++ b/vendor/github.com/containers/storage/types/options.go @@ -38,17 +38,44 @@ var ( ) func loadDefaultStoreOptions() { - defaultStoreOptions.RunRoot = defaultRunRoot - defaultStoreOptions.GraphRoot = defaultGraphRoot defaultStoreOptions.GraphDriverName = "" + setDefaults := func() { + // reload could set values to empty for run and graph root if config does not contains anything + if defaultStoreOptions.RunRoot == "" { + defaultStoreOptions.RunRoot = defaultRunRoot + } + if defaultStoreOptions.GraphRoot == "" { + defaultStoreOptions.GraphRoot = defaultGraphRoot + } + } + setDefaults() + if path, ok := os.LookupEnv(storageConfEnv); ok { defaultOverrideConfigFile = path if err := ReloadConfigurationFileIfNeeded(path, &defaultStoreOptions); err != nil { loadDefaultStoreOptionsErr = err return } - } else if _, err := os.Stat(defaultOverrideConfigFile); err == nil { + setDefaults() + return + } + + if path, ok := os.LookupEnv("XDG_CONFIG_HOME"); ok { + homeConfigFile := filepath.Join(path, "containers", "storage.conf") + if _, err := os.Stat(homeConfigFile); err == nil { + // user storage.conf in XDG_CONFIG_HOME if it exists + defaultOverrideConfigFile = homeConfigFile + } else { + if !os.IsNotExist(err) { + loadDefaultStoreOptionsErr = err + return + } + } + } + + _, err := os.Stat(defaultOverrideConfigFile) + if err == nil { // The DefaultConfigFile(rootless) function returns the path // of the used storage.conf file, by returning defaultConfigFile // If override exists containers/storage uses it by default. @@ -57,22 +84,18 @@ func loadDefaultStoreOptions() { loadDefaultStoreOptionsErr = err return } - } else { - if !os.IsNotExist(err) { - logrus.Warningf("Attempting to use %s, %v", defaultConfigFile, err) - } - if err := ReloadConfigurationFileIfNeeded(defaultConfigFile, &defaultStoreOptions); err != nil && !errors.Is(err, os.ErrNotExist) { - loadDefaultStoreOptionsErr = err - return - } + setDefaults() + return } - // reload could set values to empty for run and graph root if config does not contains anything - if defaultStoreOptions.RunRoot == "" { - defaultStoreOptions.RunRoot = defaultRunRoot + + if !os.IsNotExist(err) { + logrus.Warningf("Attempting to use %s, %v", defaultConfigFile, err) } - if defaultStoreOptions.GraphRoot == "" { - defaultStoreOptions.GraphRoot = defaultGraphRoot + if err := ReloadConfigurationFileIfNeeded(defaultConfigFile, &defaultStoreOptions); err != nil && !errors.Is(err, os.ErrNotExist) { + loadDefaultStoreOptionsErr = err + return } + setDefaults() } // defaultStoreOptionsIsolated is an internal implementation detail of DefaultStoreOptions to allow testing. diff --git a/vendor/github.com/containers/storage/types/utils.go b/vendor/github.com/containers/storage/types/utils.go index 88641d424..c54de7635 100644 --- a/vendor/github.com/containers/storage/types/utils.go +++ b/vendor/github.com/containers/storage/types/utils.go @@ -3,7 +3,6 @@ package types import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" "strconv" @@ -75,7 +74,7 @@ func getRootlessRuntimeDirIsolated(env rootlessRuntimeDirEnvironment) (string, e return runtimeDir, nil } - initCommand, err := ioutil.ReadFile(env.getProcCommandFile()) + initCommand, err := os.ReadFile(env.getProcCommandFile()) if err != nil || string(initCommand) == "systemd" { runUserDir := env.getRunUserDir() if isRootlessRuntimeDirOwner(runUserDir, env) { diff --git a/vendor/github.com/containers/storage/userns.go b/vendor/github.com/containers/storage/userns.go index e0e530275..6e200ec12 100644 --- a/vendor/github.com/containers/storage/userns.go +++ b/vendor/github.com/containers/storage/userns.go @@ -226,7 +226,7 @@ func (s *store) getAutoUserNS(options *types.AutoUserNsOptions, image *Image) ([ return nil, nil, fmt.Errorf("cannot read mappings: %w", err) } - // Look every container that is using a user namespace and store + // Look at every container that is using a user namespace and store // the intervals that are already used. containers, err := s.Containers() if err != nil { diff --git a/vendor/github.com/containers/storage/utils.go b/vendor/github.com/containers/storage/utils.go index 37d4b79b0..ae9600e68 100644 --- a/vendor/github.com/containers/storage/utils.go +++ b/vendor/github.com/containers/storage/utils.go @@ -16,12 +16,12 @@ func GetRootlessRuntimeDir(rootlessUID int) (string, error) { return types.GetRootlessRuntimeDir(rootlessUID) } -// DefaultStoreOptionsAutoDetectUID returns the default storage ops for containers +// DefaultStoreOptionsAutoDetectUID returns the default storage options for containers func DefaultStoreOptionsAutoDetectUID() (types.StoreOptions, error) { return types.DefaultStoreOptionsAutoDetectUID() } -// DefaultStoreOptions returns the default storage ops for containers +// DefaultStoreOptions returns the default storage options for containers func DefaultStoreOptions(rootless bool, rootlessUID int) (types.StoreOptions, error) { return types.DefaultStoreOptions(rootless, rootlessUID) } diff --git a/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go b/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go index da8b594e7..91d9d4bba 100644 --- a/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go +++ b/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go @@ -169,8 +169,8 @@ func Erase(helper Helper, reader io.Reader) error { return helper.Delete(serverURL) } -//List returns all the serverURLs of keys in -//the OS store as a list of strings +// List returns all the serverURLs of keys in +// the OS store as a list of strings func List(helper Helper, writer io.Writer) error { accts, err := helper.List() if err != nil { @@ -179,8 +179,8 @@ func List(helper Helper, writer io.Writer) error { return json.NewEncoder(writer).Encode(accts) } -//PrintVersion outputs the current version. +// PrintVersion outputs the current version. func PrintVersion(writer io.Writer) error { - fmt.Fprintln(writer, Version) + fmt.Fprintf(writer, "%s (%s) %s\n", Name, Package, Version) return nil } diff --git a/vendor/github.com/docker/docker-credential-helpers/credentials/version.go b/vendor/github.com/docker/docker-credential-helpers/credentials/version.go index 185e36796..84377c263 100644 --- a/vendor/github.com/docker/docker-credential-helpers/credentials/version.go +++ b/vendor/github.com/docker/docker-credential-helpers/credentials/version.go @@ -1,4 +1,16 @@ package credentials -// Version holds a string describing the current version -const Version = "0.6.4" +var ( + // Name is filled at linking time + Name = "" + + // Package is filled at linking time + Package = "github.com/docker/docker-credential-helpers" + + // Version holds the complete version number. Filled in at linking time. + Version = "v0.0.0+unknown" + + // Revision is filled with the VCS (e.g. git) revision being used to build + // the program at linking time. + Revision = "" +) diff --git a/vendor/github.com/google/go-cmp/cmp/compare.go b/vendor/github.com/google/go-cmp/cmp/compare.go index fd2b3a42b..087320da7 100644 --- a/vendor/github.com/google/go-cmp/cmp/compare.go +++ b/vendor/github.com/google/go-cmp/cmp/compare.go @@ -13,21 +13,21 @@ // // The primary features of cmp are: // -// • When the default behavior of equality does not suit the needs of the test, -// custom equality functions can override the equality operation. -// For example, an equality function may report floats as equal so long as they -// are within some tolerance of each other. +// - When the default behavior of equality does not suit the test's needs, +// custom equality functions can override the equality operation. +// For example, an equality function may report floats as equal so long as +// they are within some tolerance of each other. // -// • Types that have an Equal method may use that method to determine equality. -// This allows package authors to determine the equality operation for the types -// that they define. +// - Types with an Equal method may use that method to determine equality. +// This allows package authors to determine the equality operation +// for the types that they define. // -// • If no custom equality functions are used and no Equal method is defined, -// equality is determined by recursively comparing the primitive kinds on both -// values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, unexported -// fields are not compared by default; they result in panics unless suppressed -// by using an Ignore option (see cmpopts.IgnoreUnexported) or explicitly -// compared using the Exporter option. +// - If no custom equality functions are used and no Equal method is defined, +// equality is determined by recursively comparing the primitive kinds on +// both values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, +// unexported fields are not compared by default; they result in panics +// unless suppressed by using an Ignore option (see cmpopts.IgnoreUnexported) +// or explicitly compared using the Exporter option. package cmp import ( @@ -45,25 +45,25 @@ import ( // Equal reports whether x and y are equal by recursively applying the // following rules in the given order to x and y and all of their sub-values: // -// • Let S be the set of all Ignore, Transformer, and Comparer options that -// remain after applying all path filters, value filters, and type filters. -// If at least one Ignore exists in S, then the comparison is ignored. -// If the number of Transformer and Comparer options in S is greater than one, -// then Equal panics because it is ambiguous which option to use. -// If S contains a single Transformer, then use that to transform the current -// values and recursively call Equal on the output values. -// If S contains a single Comparer, then use that to compare the current values. -// Otherwise, evaluation proceeds to the next rule. +// - Let S be the set of all Ignore, Transformer, and Comparer options that +// remain after applying all path filters, value filters, and type filters. +// If at least one Ignore exists in S, then the comparison is ignored. +// If the number of Transformer and Comparer options in S is non-zero, +// then Equal panics because it is ambiguous which option to use. +// If S contains a single Transformer, then use that to transform +// the current values and recursively call Equal on the output values. +// If S contains a single Comparer, then use that to compare the current values. +// Otherwise, evaluation proceeds to the next rule. // -// • If the values have an Equal method of the form "(T) Equal(T) bool" or -// "(T) Equal(I) bool" where T is assignable to I, then use the result of -// x.Equal(y) even if x or y is nil. Otherwise, no such method exists and -// evaluation proceeds to the next rule. +// - If the values have an Equal method of the form "(T) Equal(T) bool" or +// "(T) Equal(I) bool" where T is assignable to I, then use the result of +// x.Equal(y) even if x or y is nil. Otherwise, no such method exists and +// evaluation proceeds to the next rule. // -// • Lastly, try to compare x and y based on their basic kinds. -// Simple kinds like booleans, integers, floats, complex numbers, strings, and -// channels are compared using the equivalent of the == operator in Go. -// Functions are only equal if they are both nil, otherwise they are unequal. +// - Lastly, try to compare x and y based on their basic kinds. +// Simple kinds like booleans, integers, floats, complex numbers, strings, +// and channels are compared using the equivalent of the == operator in Go. +// Functions are only equal if they are both nil, otherwise they are unequal. // // Structs are equal if recursively calling Equal on all fields report equal. // If a struct contains unexported fields, Equal panics unless an Ignore option @@ -144,7 +144,7 @@ func rootStep(x, y interface{}) PathStep { // so that they have the same parent type. var t reflect.Type if !vx.IsValid() || !vy.IsValid() || vx.Type() != vy.Type() { - t = reflect.TypeOf((*interface{})(nil)).Elem() + t = anyType if vx.IsValid() { vvx := reflect.New(t).Elem() vvx.Set(vx) @@ -639,7 +639,9 @@ type dynChecker struct{ curr, next int } // Next increments the state and reports whether a check should be performed. // // Checks occur every Nth function call, where N is a triangular number: +// // 0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ... +// // See https://en.wikipedia.org/wiki/Triangular_number // // This sequence ensures that the cost of checks drops significantly as diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go index bc196b16c..a248e5436 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go @@ -127,9 +127,9 @@ var randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0 // This function returns an edit-script, which is a sequence of operations // needed to convert one list into the other. The following invariants for // the edit-script are maintained: -// • eq == (es.Dist()==0) -// • nx == es.LenX() -// • ny == es.LenY() +// - eq == (es.Dist()==0) +// - nx == es.LenX() +// - ny == es.LenY() // // This algorithm is not guaranteed to be an optimal solution (i.e., one that // produces an edit-script with a minimal Levenshtein distance). This algorithm @@ -169,12 +169,13 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) { // A diagonal edge is equivalent to a matching symbol between both X and Y. // Invariants: - // • 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx - // • 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny + // - 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx + // - 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny // // In general: - // • fwdFrontier.X < revFrontier.X - // • fwdFrontier.Y < revFrontier.Y + // - fwdFrontier.X < revFrontier.X + // - fwdFrontier.Y < revFrontier.Y + // // Unless, it is time for the algorithm to terminate. fwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)} revPath := path{-1, point{nx, ny}, make(EditScript, 0)} @@ -195,19 +196,21 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) { // computing sub-optimal edit-scripts between two lists. // // The algorithm is approximately as follows: - // • Searching for differences switches back-and-forth between - // a search that starts at the beginning (the top-left corner), and - // a search that starts at the end (the bottom-right corner). The goal of - // the search is connect with the search from the opposite corner. - // • As we search, we build a path in a greedy manner, where the first - // match seen is added to the path (this is sub-optimal, but provides a - // decent result in practice). When matches are found, we try the next pair - // of symbols in the lists and follow all matches as far as possible. - // • When searching for matches, we search along a diagonal going through - // through the "frontier" point. If no matches are found, we advance the - // frontier towards the opposite corner. - // • This algorithm terminates when either the X coordinates or the - // Y coordinates of the forward and reverse frontier points ever intersect. + // - Searching for differences switches back-and-forth between + // a search that starts at the beginning (the top-left corner), and + // a search that starts at the end (the bottom-right corner). + // The goal of the search is connect with the search + // from the opposite corner. + // - As we search, we build a path in a greedy manner, + // where the first match seen is added to the path (this is sub-optimal, + // but provides a decent result in practice). When matches are found, + // we try the next pair of symbols in the lists and follow all matches + // as far as possible. + // - When searching for matches, we search along a diagonal going through + // through the "frontier" point. If no matches are found, + // we advance the frontier towards the opposite corner. + // - This algorithm terminates when either the X coordinates or the + // Y coordinates of the forward and reverse frontier points ever intersect. // This algorithm is correct even if searching only in the forward direction // or in the reverse direction. We do both because it is commonly observed @@ -389,6 +392,7 @@ type point struct{ X, Y int } func (p *point) add(dx, dy int) { p.X += dx; p.Y += dy } // zigzag maps a consecutive sequence of integers to a zig-zag sequence. +// // [0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...] func zigzag(x int) int { if x&1 != 0 { diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go b/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go deleted file mode 100644 index 9147a2997..000000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2017, The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package value - -import ( - "math" - "reflect" -) - -// IsZero reports whether v is the zero value. -// This does not rely on Interface and so can be used on unexported fields. -func IsZero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Bool: - return v.Bool() == false - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return math.Float64bits(v.Float()) == 0 - case reflect.Complex64, reflect.Complex128: - return math.Float64bits(real(v.Complex())) == 0 && math.Float64bits(imag(v.Complex())) == 0 - case reflect.String: - return v.String() == "" - case reflect.UnsafePointer: - return v.Pointer() == 0 - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: - return v.IsNil() - case reflect.Array: - for i := 0; i < v.Len(); i++ { - if !IsZero(v.Index(i)) { - return false - } - } - return true - case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - if !IsZero(v.Field(i)) { - return false - } - } - return true - } - return false -} diff --git a/vendor/github.com/google/go-cmp/cmp/options.go b/vendor/github.com/google/go-cmp/cmp/options.go index e57b9eb53..1f9ca9c48 100644 --- a/vendor/github.com/google/go-cmp/cmp/options.go +++ b/vendor/github.com/google/go-cmp/cmp/options.go @@ -33,6 +33,7 @@ type Option interface { } // applicableOption represents the following types: +// // Fundamental: ignore | validator | *comparer | *transformer // Grouping: Options type applicableOption interface { @@ -43,6 +44,7 @@ type applicableOption interface { } // coreOption represents the following types: +// // Fundamental: ignore | validator | *comparer | *transformer // Filters: *pathFilter | *valuesFilter type coreOption interface { @@ -336,9 +338,9 @@ func (tr transformer) String() string { // both implement T. // // The equality function must be: -// • Symmetric: equal(x, y) == equal(y, x) -// • Deterministic: equal(x, y) == equal(x, y) -// • Pure: equal(x, y) does not modify x or y +// - Symmetric: equal(x, y) == equal(y, x) +// - Deterministic: equal(x, y) == equal(x, y) +// - Pure: equal(x, y) does not modify x or y func Comparer(f interface{}) Option { v := reflect.ValueOf(f) if !function.IsType(v.Type(), function.Equal) || v.IsNil() { @@ -430,7 +432,7 @@ func AllowUnexported(types ...interface{}) Option { } // Result represents the comparison result for a single node and -// is provided by cmp when calling Result (see Reporter). +// is provided by cmp when calling Report (see Reporter). type Result struct { _ [0]func() // Make Result incomparable flags resultFlags diff --git a/vendor/github.com/google/go-cmp/cmp/path.go b/vendor/github.com/google/go-cmp/cmp/path.go index c71003463..a0a588502 100644 --- a/vendor/github.com/google/go-cmp/cmp/path.go +++ b/vendor/github.com/google/go-cmp/cmp/path.go @@ -41,13 +41,13 @@ type PathStep interface { // The type of each valid value is guaranteed to be identical to Type. // // In some cases, one or both may be invalid or have restrictions: - // • For StructField, both are not interface-able if the current field - // is unexported and the struct type is not explicitly permitted by - // an Exporter to traverse unexported fields. - // • For SliceIndex, one may be invalid if an element is missing from - // either the x or y slice. - // • For MapIndex, one may be invalid if an entry is missing from - // either the x or y map. + // - For StructField, both are not interface-able if the current field + // is unexported and the struct type is not explicitly permitted by + // an Exporter to traverse unexported fields. + // - For SliceIndex, one may be invalid if an element is missing from + // either the x or y slice. + // - For MapIndex, one may be invalid if an entry is missing from + // either the x or y map. // // The provided values must not be mutated. Values() (vx, vy reflect.Value) @@ -94,6 +94,7 @@ func (pa Path) Index(i int) PathStep { // The simplified path only contains struct field accesses. // // For example: +// // MyMap.MySlices.MyField func (pa Path) String() string { var ss []string @@ -108,6 +109,7 @@ func (pa Path) String() string { // GoString returns the path to a specific node using Go syntax. // // For example: +// // (*root.MyMap["key"].(*mypkg.MyStruct).MySlices)[2][3].MyField func (pa Path) GoString() string { var ssPre, ssPost []string @@ -159,7 +161,7 @@ func (ps pathStep) String() string { if ps.typ == nil { return "<nil>" } - s := ps.typ.String() + s := value.TypeString(ps.typ, false) if s == "" || strings.ContainsAny(s, "{}\n") { return "root" // Type too simple or complex to print } @@ -282,7 +284,7 @@ type typeAssertion struct { func (ta TypeAssertion) Type() reflect.Type { return ta.typ } func (ta TypeAssertion) Values() (vx, vy reflect.Value) { return ta.vx, ta.vy } -func (ta TypeAssertion) String() string { return fmt.Sprintf(".(%v)", ta.typ) } +func (ta TypeAssertion) String() string { return fmt.Sprintf(".(%v)", value.TypeString(ta.typ, false)) } // Transform is a transformation from the parent type to the current type. type Transform struct{ *transform } diff --git a/vendor/github.com/google/go-cmp/cmp/report_compare.go b/vendor/github.com/google/go-cmp/cmp/report_compare.go index 1ef65ac1d..2050bf6b4 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_compare.go +++ b/vendor/github.com/google/go-cmp/cmp/report_compare.go @@ -7,8 +7,6 @@ package cmp import ( "fmt" "reflect" - - "github.com/google/go-cmp/cmp/internal/value" ) // numContextRecords is the number of surrounding equal records to print. @@ -117,7 +115,7 @@ func (opts formatOptions) FormatDiff(v *valueNode, ptrs *pointerReferences) (out // For leaf nodes, format the value based on the reflect.Values alone. // As a special case, treat equal []byte as a leaf nodes. - isBytes := v.Type.Kind() == reflect.Slice && v.Type.Elem() == reflect.TypeOf(byte(0)) + isBytes := v.Type.Kind() == reflect.Slice && v.Type.Elem() == byteType isEqualBytes := isBytes && v.NumDiff+v.NumIgnored+v.NumTransformed == 0 if v.MaxDepth == 0 || isEqualBytes { switch opts.DiffMode { @@ -248,11 +246,11 @@ func (opts formatOptions) formatDiffList(recs []reportRecord, k reflect.Kind, pt var isZero bool switch opts.DiffMode { case diffIdentical: - isZero = value.IsZero(r.Value.ValueX) || value.IsZero(r.Value.ValueY) + isZero = r.Value.ValueX.IsZero() || r.Value.ValueY.IsZero() case diffRemoved: - isZero = value.IsZero(r.Value.ValueX) + isZero = r.Value.ValueX.IsZero() case diffInserted: - isZero = value.IsZero(r.Value.ValueY) + isZero = r.Value.ValueY.IsZero() } if isZero { continue diff --git a/vendor/github.com/google/go-cmp/cmp/report_reflect.go b/vendor/github.com/google/go-cmp/cmp/report_reflect.go index 287b89358..2ab41fad3 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_reflect.go +++ b/vendor/github.com/google/go-cmp/cmp/report_reflect.go @@ -16,6 +16,13 @@ import ( "github.com/google/go-cmp/cmp/internal/value" ) +var ( + anyType = reflect.TypeOf((*interface{})(nil)).Elem() + stringType = reflect.TypeOf((*string)(nil)).Elem() + bytesType = reflect.TypeOf((*[]byte)(nil)).Elem() + byteType = reflect.TypeOf((*byte)(nil)).Elem() +) + type formatValueOptions struct { // AvoidStringer controls whether to avoid calling custom stringer // methods like error.Error or fmt.Stringer.String. @@ -184,7 +191,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, } for i := 0; i < v.NumField(); i++ { vv := v.Field(i) - if value.IsZero(vv) { + if vv.IsZero() { continue // Elide fields with zero values } if len(list) == maxLen { @@ -205,7 +212,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, } // Check whether this is a []byte of text data. - if t.Elem() == reflect.TypeOf(byte(0)) { + if t.Elem() == byteType { b := v.Bytes() isPrintSpace := func(r rune) bool { return unicode.IsPrint(r) || unicode.IsSpace(r) } if len(b) > 0 && utf8.Valid(b) && len(bytes.TrimFunc(b, isPrintSpace)) == 0 { diff --git a/vendor/github.com/google/go-cmp/cmp/report_slices.go b/vendor/github.com/google/go-cmp/cmp/report_slices.go index 68b5c1ae1..23e444f62 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_slices.go +++ b/vendor/github.com/google/go-cmp/cmp/report_slices.go @@ -104,7 +104,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { case t.Kind() == reflect.String: sx, sy = vx.String(), vy.String() isString = true - case t.Kind() == reflect.Slice && t.Elem() == reflect.TypeOf(byte(0)): + case t.Kind() == reflect.Slice && t.Elem() == byteType: sx, sy = string(vx.Bytes()), string(vy.Bytes()) isString = true case t.Kind() == reflect.Array: @@ -147,7 +147,10 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { }) efficiencyLines := float64(esLines.Dist()) / float64(len(esLines)) efficiencyBytes := float64(esBytes.Dist()) / float64(len(esBytes)) - isPureLinedText = efficiencyLines < 4*efficiencyBytes + quotedLength := len(strconv.Quote(sx + sy)) + unquotedLength := len(sx) + len(sy) + escapeExpansionRatio := float64(quotedLength) / float64(unquotedLength) + isPureLinedText = efficiencyLines < 4*efficiencyBytes || escapeExpansionRatio > 1.1 } } @@ -171,12 +174,13 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { // differences in a string literal. This format is more readable, // but has edge-cases where differences are visually indistinguishable. // This format is avoided under the following conditions: - // • A line starts with `"""` - // • A line starts with "..." - // • A line contains non-printable characters - // • Adjacent different lines differ only by whitespace + // - A line starts with `"""` + // - A line starts with "..." + // - A line contains non-printable characters + // - Adjacent different lines differ only by whitespace // // For example: + // // """ // ... // 3 identical lines // foo @@ -231,7 +235,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { var out textNode = &textWrap{Prefix: "(", Value: list2, Suffix: ")"} switch t.Kind() { case reflect.String: - if t != reflect.TypeOf(string("")) { + if t != stringType { out = opts.FormatType(t, out) } case reflect.Slice: @@ -326,12 +330,12 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { switch t.Kind() { case reflect.String: out = &textWrap{Prefix: "strings.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)} - if t != reflect.TypeOf(string("")) { + if t != stringType { out = opts.FormatType(t, out) } case reflect.Slice: out = &textWrap{Prefix: "bytes.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)} - if t != reflect.TypeOf([]byte(nil)) { + if t != bytesType { out = opts.FormatType(t, out) } } @@ -446,7 +450,6 @@ func (opts formatOptions) formatDiffSlice( // {NumIdentical: 3}, // {NumInserted: 1}, // ] -// func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) { var prevMode byte lastStats := func(mode byte) *diffStats { @@ -503,7 +506,6 @@ func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) // {NumIdentical: 8, NumRemoved: 12, NumInserted: 3}, // {NumIdentical: 63}, // ] -// func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats { groups, groupsOrig := groups[:0], groups for i, ds := range groupsOrig { @@ -548,7 +550,6 @@ func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStat // {NumRemoved: 9}, // {NumIdentical: 64}, // incremented by 10 // ] -// func cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []diffStats { var ix, iy int // indexes into sequence x and y for i, ds := range groups { diff --git a/vendor/github.com/google/go-cmp/cmp/report_text.go b/vendor/github.com/google/go-cmp/cmp/report_text.go index 0fd46d7ff..388fcf571 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_text.go +++ b/vendor/github.com/google/go-cmp/cmp/report_text.go @@ -393,6 +393,7 @@ func (s diffStats) Append(ds diffStats) diffStats { // String prints a humanly-readable summary of coalesced records. // // Example: +// // diffStats{Name: "Field", NumIgnored: 5}.String() => "5 ignored fields" func (s diffStats) String() string { var ss []string diff --git a/vendor/github.com/klauspost/compress/README.md b/vendor/github.com/klauspost/compress/README.md index ad5c63a82..3c00c1af9 100644 --- a/vendor/github.com/klauspost/compress/README.md +++ b/vendor/github.com/klauspost/compress/README.md @@ -17,6 +17,23 @@ This package provides various compression algorithms. # changelog
+* Sept 16, 2022 (v1.15.10)
+
+ * zstd: Add [WithDecodeAllCapLimit](https://pkg.go.dev/github.com/klauspost/compress@v1.15.10/zstd#WithDecodeAllCapLimit) https://github.com/klauspost/compress/pull/649
+ * Add Go 1.19 - deprecate Go 1.16 https://github.com/klauspost/compress/pull/651
+ * flate: Improve level 5+6 compression https://github.com/klauspost/compress/pull/656
+ * zstd: Improve "better" compresssion https://github.com/klauspost/compress/pull/657
+ * s2: Improve "best" compression https://github.com/klauspost/compress/pull/658
+ * s2: Improve "better" compression. https://github.com/klauspost/compress/pull/635
+ * s2: Slightly faster non-assembly decompression https://github.com/klauspost/compress/pull/646
+ * Use arrays for constant size copies https://github.com/klauspost/compress/pull/659
+
+* July 21, 2022 (v1.15.9)
+
+ * zstd: Fix decoder crash on amd64 (no BMI) on invalid input https://github.com/klauspost/compress/pull/645
+ * zstd: Disable decoder extended memory copies (amd64) due to possible crashes https://github.com/klauspost/compress/pull/644
+ * zstd: Allow single segments up to "max decoded size" by @klauspost in https://github.com/klauspost/compress/pull/643
+
* July 13, 2022 (v1.15.8)
* gzip: fix stack exhaustion bug in Reader.Read https://github.com/klauspost/compress/pull/641
@@ -91,15 +108,15 @@ This package provides various compression algorithms. * gzhttp: Add zstd to transport by @klauspost in [#400](https://github.com/klauspost/compress/pull/400)
* gzhttp: Make content-type optional by @klauspost in [#510](https://github.com/klauspost/compress/pull/510)
-<details>
- <summary>See Details</summary>
Both compression and decompression now supports "synchronous" stream operations. This means that whenever "concurrency" is set to 1, they will operate without spawning goroutines.
Stream decompression is now faster on asynchronous, since the goroutine allocation much more effectively splits the workload. On typical streams this will typically use 2 cores fully for decompression. When a stream has finished decoding no goroutines will be left over, so decoders can now safely be pooled and still be garbage collected.
While the release has been extensively tested, it is recommended to testing when upgrading.
-</details>
+<details>
+ <summary>See changes to v1.14.x</summary>
+
* Feb 22, 2022 (v1.14.4)
* flate: Fix rare huffman only (-2) corruption. [#503](https://github.com/klauspost/compress/pull/503)
* zip: Update deprecated CreateHeaderRaw to correctly call CreateRaw by @saracen in [#502](https://github.com/klauspost/compress/pull/502)
@@ -125,6 +142,7 @@ While the release has been extensively tested, it is recommended to testing when * zstd: Performance improvement in [#420]( https://github.com/klauspost/compress/pull/420) [#456](https://github.com/klauspost/compress/pull/456) [#437](https://github.com/klauspost/compress/pull/437) [#467](https://github.com/klauspost/compress/pull/467) [#468](https://github.com/klauspost/compress/pull/468)
* zstd: add arm64 xxhash assembly in [#464](https://github.com/klauspost/compress/pull/464)
* Add garbled for binaries for s2 in [#445](https://github.com/klauspost/compress/pull/445)
+</details>
<details>
<summary>See changes to v1.13.x</summary>
diff --git a/vendor/github.com/klauspost/compress/flate/deflate.go b/vendor/github.com/klauspost/compress/flate/deflate.go index f8435998e..07265dded 100644 --- a/vendor/github.com/klauspost/compress/flate/deflate.go +++ b/vendor/github.com/klauspost/compress/flate/deflate.go @@ -131,7 +131,8 @@ func (d *compressor) fillDeflate(b []byte) int { s := d.state if s.index >= 2*windowSize-(minMatchLength+maxMatchLength) { // shift the window by windowSize - copy(d.window[:], d.window[windowSize:2*windowSize]) + //copy(d.window[:], d.window[windowSize:2*windowSize]) + *(*[windowSize]byte)(d.window) = *(*[windowSize]byte)(d.window[windowSize:]) s.index -= windowSize d.windowEnd -= windowSize if d.blockStart >= windowSize { @@ -373,6 +374,12 @@ func hash4(b []byte) uint32 { return hash4u(binary.LittleEndian.Uint32(b), hashBits) } +// hash4 returns the hash of u to fit in a hash table with h bits. +// Preferably h should be a constant and should always be <32. +func hash4u(u uint32, h uint8) uint32 { + return (u * prime4bytes) >> (32 - h) +} + // bulkHash4 will compute hashes using the same // algorithm as hash4 func bulkHash4(b []byte, dst []uint32) { diff --git a/vendor/github.com/klauspost/compress/flate/dict_decoder.go b/vendor/github.com/klauspost/compress/flate/dict_decoder.go index 71c75a065..bb36351a5 100644 --- a/vendor/github.com/klauspost/compress/flate/dict_decoder.go +++ b/vendor/github.com/klauspost/compress/flate/dict_decoder.go @@ -7,19 +7,19 @@ package flate // dictDecoder implements the LZ77 sliding dictionary as used in decompression. // LZ77 decompresses data through sequences of two forms of commands: // -// * Literal insertions: Runs of one or more symbols are inserted into the data -// stream as is. This is accomplished through the writeByte method for a -// single symbol, or combinations of writeSlice/writeMark for multiple symbols. -// Any valid stream must start with a literal insertion if no preset dictionary -// is used. +// - Literal insertions: Runs of one or more symbols are inserted into the data +// stream as is. This is accomplished through the writeByte method for a +// single symbol, or combinations of writeSlice/writeMark for multiple symbols. +// Any valid stream must start with a literal insertion if no preset dictionary +// is used. // -// * Backward copies: Runs of one or more symbols are copied from previously -// emitted data. Backward copies come as the tuple (dist, length) where dist -// determines how far back in the stream to copy from and length determines how -// many bytes to copy. Note that it is valid for the length to be greater than -// the distance. Since LZ77 uses forward copies, that situation is used to -// perform a form of run-length encoding on repeated runs of symbols. -// The writeCopy and tryWriteCopy are used to implement this command. +// - Backward copies: Runs of one or more symbols are copied from previously +// emitted data. Backward copies come as the tuple (dist, length) where dist +// determines how far back in the stream to copy from and length determines how +// many bytes to copy. Note that it is valid for the length to be greater than +// the distance. Since LZ77 uses forward copies, that situation is used to +// perform a form of run-length encoding on repeated runs of symbols. +// The writeCopy and tryWriteCopy are used to implement this command. // // For performance reasons, this implementation performs little to no sanity // checks about the arguments. As such, the invariants documented for each diff --git a/vendor/github.com/klauspost/compress/flate/fast_encoder.go b/vendor/github.com/klauspost/compress/flate/fast_encoder.go index f781aaa62..24caf5f70 100644 --- a/vendor/github.com/klauspost/compress/flate/fast_encoder.go +++ b/vendor/github.com/klauspost/compress/flate/fast_encoder.go @@ -58,17 +58,6 @@ const ( prime8bytes = 0xcf1bbcdcb7a56463 ) -func load32(b []byte, i int) uint32 { - // Help the compiler eliminate bounds checks on the read so it can be done in a single read. - b = b[i:] - b = b[:4] - return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 -} - -func load64(b []byte, i int) uint64 { - return binary.LittleEndian.Uint64(b[i:]) -} - func load3232(b []byte, i int32) uint32 { return binary.LittleEndian.Uint32(b[i:]) } @@ -77,10 +66,6 @@ func load6432(b []byte, i int32) uint64 { return binary.LittleEndian.Uint64(b[i:]) } -func hash(u uint32) uint32 { - return (u * 0x1e35a7bd) >> tableShift -} - type tableEntry struct { offset int32 } @@ -104,7 +89,8 @@ func (e *fastGen) addBlock(src []byte) int32 { } // Move down offset := int32(len(e.hist)) - maxMatchOffset - copy(e.hist[0:maxMatchOffset], e.hist[offset:]) + // copy(e.hist[0:maxMatchOffset], e.hist[offset:]) + *(*[maxMatchOffset]byte)(e.hist) = *(*[maxMatchOffset]byte)(e.hist[offset:]) e.cur += offset e.hist = e.hist[:maxMatchOffset] } @@ -114,39 +100,36 @@ func (e *fastGen) addBlock(src []byte) int32 { return s } -// hash4 returns the hash of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <32. -func hash4u(u uint32, h uint8) uint32 { - return (u * prime4bytes) >> (32 - h) -} - type tableEntryPrev struct { Cur tableEntry Prev tableEntry } -// hash4x64 returns the hash of the lowest 4 bytes of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <32. -func hash4x64(u uint64, h uint8) uint32 { - return (uint32(u) * prime4bytes) >> ((32 - h) & reg8SizeMask32) -} - // hash7 returns the hash of the lowest 7 bytes of u to fit in a hash table with h bits. // Preferably h should be a constant and should always be <64. func hash7(u uint64, h uint8) uint32 { return uint32(((u << (64 - 56)) * prime7bytes) >> ((64 - h) & reg8SizeMask64)) } -// hash8 returns the hash of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <64. -func hash8(u uint64, h uint8) uint32 { - return uint32((u * prime8bytes) >> ((64 - h) & reg8SizeMask64)) -} - -// hash6 returns the hash of the lowest 6 bytes of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <64. -func hash6(u uint64, h uint8) uint32 { - return uint32(((u << (64 - 48)) * prime6bytes) >> ((64 - h) & reg8SizeMask64)) +// hashLen returns a hash of the lowest mls bytes of with length output bits. +// mls must be >=3 and <=8. Any other value will return hash for 4 bytes. +// length should always be < 32. +// Preferably length and mls should be a constant for inlining. +func hashLen(u uint64, length, mls uint8) uint32 { + switch mls { + case 3: + return (uint32(u<<8) * prime3bytes) >> (32 - length) + case 5: + return uint32(((u << (64 - 40)) * prime5bytes) >> (64 - length)) + case 6: + return uint32(((u << (64 - 48)) * prime6bytes) >> (64 - length)) + case 7: + return uint32(((u << (64 - 56)) * prime7bytes) >> (64 - length)) + case 8: + return uint32((u * prime8bytes) >> (64 - length)) + default: + return (uint32(u) * prime4bytes) >> (32 - length) + } } // matchlen will return the match length between offsets and t in src. diff --git a/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go b/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go index 40ef45c2f..89a5dd89f 100644 --- a/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go +++ b/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go @@ -265,9 +265,9 @@ func (w *huffmanBitWriter) writeBytes(bytes []byte) { // Codes 0-15 are single byte codes. Codes 16-18 are followed by additional // information. Code badCode is an end marker // -// numLiterals The number of literals in literalEncoding -// numOffsets The number of offsets in offsetEncoding -// litenc, offenc The literal and offset encoder to use +// numLiterals The number of literals in literalEncoding +// numOffsets The number of offsets in offsetEncoding +// litenc, offenc The literal and offset encoder to use func (w *huffmanBitWriter) generateCodegen(numLiterals int, numOffsets int, litEnc, offEnc *huffmanEncoder) { for i := range w.codegenFreq { w.codegenFreq[i] = 0 @@ -460,9 +460,9 @@ func (w *huffmanBitWriter) writeOutBits() { // Write the header of a dynamic Huffman block to the output stream. // -// numLiterals The number of literals specified in codegen -// numOffsets The number of offsets specified in codegen -// numCodegens The number of codegens used in codegen +// numLiterals The number of literals specified in codegen +// numOffsets The number of offsets specified in codegen +// numCodegens The number of codegens used in codegen func (w *huffmanBitWriter) writeDynamicHeader(numLiterals int, numOffsets int, numCodegens int, isEof bool) { if w.err != nil { return @@ -790,9 +790,11 @@ func (w *huffmanBitWriter) fillTokens() { // and offsetEncoding. // The number of literal and offset tokens is returned. func (w *huffmanBitWriter) indexTokens(t *tokens, filled bool) (numLiterals, numOffsets int) { - copy(w.literalFreq[:], t.litHist[:]) - copy(w.literalFreq[256:], t.extraHist[:]) - copy(w.offsetFreq[:], t.offHist[:offsetCodeCount]) + //copy(w.literalFreq[:], t.litHist[:]) + *(*[256]uint16)(w.literalFreq[:]) = t.litHist + //copy(w.literalFreq[256:], t.extraHist[:]) + *(*[32]uint16)(w.literalFreq[256:]) = t.extraHist + w.offsetFreq = t.offHist if t.n == 0 { return diff --git a/vendor/github.com/klauspost/compress/flate/huffman_code.go b/vendor/github.com/klauspost/compress/flate/huffman_code.go index 5ac144f28..be7b58b47 100644 --- a/vendor/github.com/klauspost/compress/flate/huffman_code.go +++ b/vendor/github.com/klauspost/compress/flate/huffman_code.go @@ -168,13 +168,18 @@ func (h *huffmanEncoder) canReuseBits(freq []uint16) int { // The cases of 0, 1, and 2 literals are handled by special case code. // // list An array of the literals with non-zero frequencies -// and their associated frequencies. The array is in order of increasing -// frequency, and has as its last element a special element with frequency -// MaxInt32 +// +// and their associated frequencies. The array is in order of increasing +// frequency, and has as its last element a special element with frequency +// MaxInt32 +// // maxBits The maximum number of bits that should be used to encode any literal. -// Must be less than 16. +// +// Must be less than 16. +// // return An integer array in which array[i] indicates the number of literals -// that should be encoded in i bits. +// +// that should be encoded in i bits. func (h *huffmanEncoder) bitCounts(list []literalNode, maxBits int32) []int32 { if maxBits >= maxBitsLimit { panic("flate: maxBits too large") diff --git a/vendor/github.com/klauspost/compress/flate/level1.go b/vendor/github.com/klauspost/compress/flate/level1.go index 0f14f8d63..703b9a89a 100644 --- a/vendor/github.com/klauspost/compress/flate/level1.go +++ b/vendor/github.com/klauspost/compress/flate/level1.go @@ -19,6 +19,7 @@ func (e *fastEncL1) Encode(dst *tokens, src []byte) { const ( inputMargin = 12 - 1 minNonLiteralBlockSize = 1 + 1 + inputMargin + hashBytes = 5 ) if debugDeflate && e.cur < 0 { panic(fmt.Sprint("e.cur < 0: ", e.cur)) @@ -68,7 +69,7 @@ func (e *fastEncL1) Encode(dst *tokens, src []byte) { sLimit := int32(len(src) - inputMargin) // nextEmit is where in src the next emitLiteral should start from. - cv := load3232(src, s) + cv := load6432(src, s) for { const skipLog = 5 @@ -77,7 +78,7 @@ func (e *fastEncL1) Encode(dst *tokens, src []byte) { nextS := s var candidate tableEntry for { - nextHash := hash(cv) + nextHash := hashLen(cv, tableBits, hashBytes) candidate = e.table[nextHash] nextS = s + doEvery + (s-nextEmit)>>skipLog if nextS > sLimit { @@ -86,16 +87,16 @@ func (e *fastEncL1) Encode(dst *tokens, src []byte) { now := load6432(src, nextS) e.table[nextHash] = tableEntry{offset: s + e.cur} - nextHash = hash(uint32(now)) + nextHash = hashLen(now, tableBits, hashBytes) offset := s - (candidate.offset - e.cur) - if offset < maxMatchOffset && cv == load3232(src, candidate.offset-e.cur) { + if offset < maxMatchOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) { e.table[nextHash] = tableEntry{offset: nextS + e.cur} break } // Do one right away... - cv = uint32(now) + cv = now s = nextS nextS++ candidate = e.table[nextHash] @@ -103,11 +104,11 @@ func (e *fastEncL1) Encode(dst *tokens, src []byte) { e.table[nextHash] = tableEntry{offset: s + e.cur} offset = s - (candidate.offset - e.cur) - if offset < maxMatchOffset && cv == load3232(src, candidate.offset-e.cur) { + if offset < maxMatchOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) { e.table[nextHash] = tableEntry{offset: nextS + e.cur} break } - cv = uint32(now) + cv = now s = nextS } @@ -198,9 +199,9 @@ func (e *fastEncL1) Encode(dst *tokens, src []byte) { } if s >= sLimit { // Index first pair after match end. - if int(s+l+4) < len(src) { - cv := load3232(src, s) - e.table[hash(cv)] = tableEntry{offset: s + e.cur} + if int(s+l+8) < len(src) { + cv := load6432(src, s) + e.table[hashLen(cv, tableBits, hashBytes)] = tableEntry{offset: s + e.cur} } goto emitRemainder } @@ -213,16 +214,16 @@ func (e *fastEncL1) Encode(dst *tokens, src []byte) { // three load32 calls. x := load6432(src, s-2) o := e.cur + s - 2 - prevHash := hash(uint32(x)) + prevHash := hashLen(x, tableBits, hashBytes) e.table[prevHash] = tableEntry{offset: o} x >>= 16 - currHash := hash(uint32(x)) + currHash := hashLen(x, tableBits, hashBytes) candidate = e.table[currHash] e.table[currHash] = tableEntry{offset: o + 2} offset := s - (candidate.offset - e.cur) if offset > maxMatchOffset || uint32(x) != load3232(src, candidate.offset-e.cur) { - cv = uint32(x >> 8) + cv = x >> 8 s++ break } diff --git a/vendor/github.com/klauspost/compress/flate/level2.go b/vendor/github.com/klauspost/compress/flate/level2.go index 8603fbd55..876dfbe30 100644 --- a/vendor/github.com/klauspost/compress/flate/level2.go +++ b/vendor/github.com/klauspost/compress/flate/level2.go @@ -16,6 +16,7 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) { const ( inputMargin = 12 - 1 minNonLiteralBlockSize = 1 + 1 + inputMargin + hashBytes = 5 ) if debugDeflate && e.cur < 0 { @@ -66,7 +67,7 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) { sLimit := int32(len(src) - inputMargin) // nextEmit is where in src the next emitLiteral should start from. - cv := load3232(src, s) + cv := load6432(src, s) for { // When should we start skipping if we haven't found matches in a long while. const skipLog = 5 @@ -75,7 +76,7 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) { nextS := s var candidate tableEntry for { - nextHash := hash4u(cv, bTableBits) + nextHash := hashLen(cv, bTableBits, hashBytes) s = nextS nextS = s + doEvery + (s-nextEmit)>>skipLog if nextS > sLimit { @@ -84,16 +85,16 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) { candidate = e.table[nextHash] now := load6432(src, nextS) e.table[nextHash] = tableEntry{offset: s + e.cur} - nextHash = hash4u(uint32(now), bTableBits) + nextHash = hashLen(now, bTableBits, hashBytes) offset := s - (candidate.offset - e.cur) - if offset < maxMatchOffset && cv == load3232(src, candidate.offset-e.cur) { + if offset < maxMatchOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) { e.table[nextHash] = tableEntry{offset: nextS + e.cur} break } // Do one right away... - cv = uint32(now) + cv = now s = nextS nextS++ candidate = e.table[nextHash] @@ -101,10 +102,10 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) { e.table[nextHash] = tableEntry{offset: s + e.cur} offset = s - (candidate.offset - e.cur) - if offset < maxMatchOffset && cv == load3232(src, candidate.offset-e.cur) { + if offset < maxMatchOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) { break } - cv = uint32(now) + cv = now } // A 4-byte match has been found. We'll later see if more than 4 bytes @@ -154,9 +155,9 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) { if s >= sLimit { // Index first pair after match end. - if int(s+l+4) < len(src) { - cv := load3232(src, s) - e.table[hash4u(cv, bTableBits)] = tableEntry{offset: s + e.cur} + if int(s+l+8) < len(src) { + cv := load6432(src, s) + e.table[hashLen(cv, bTableBits, hashBytes)] = tableEntry{offset: s + e.cur} } goto emitRemainder } @@ -164,15 +165,15 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) { // Store every second hash in-between, but offset by 1. for i := s - l + 2; i < s-5; i += 7 { x := load6432(src, i) - nextHash := hash4u(uint32(x), bTableBits) + nextHash := hashLen(x, bTableBits, hashBytes) e.table[nextHash] = tableEntry{offset: e.cur + i} // Skip one x >>= 16 - nextHash = hash4u(uint32(x), bTableBits) + nextHash = hashLen(x, bTableBits, hashBytes) e.table[nextHash] = tableEntry{offset: e.cur + i + 2} // Skip one x >>= 16 - nextHash = hash4u(uint32(x), bTableBits) + nextHash = hashLen(x, bTableBits, hashBytes) e.table[nextHash] = tableEntry{offset: e.cur + i + 4} } @@ -184,17 +185,17 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) { // three load32 calls. x := load6432(src, s-2) o := e.cur + s - 2 - prevHash := hash4u(uint32(x), bTableBits) - prevHash2 := hash4u(uint32(x>>8), bTableBits) + prevHash := hashLen(x, bTableBits, hashBytes) + prevHash2 := hashLen(x>>8, bTableBits, hashBytes) e.table[prevHash] = tableEntry{offset: o} e.table[prevHash2] = tableEntry{offset: o + 1} - currHash := hash4u(uint32(x>>16), bTableBits) + currHash := hashLen(x>>16, bTableBits, hashBytes) candidate = e.table[currHash] e.table[currHash] = tableEntry{offset: o + 2} offset := s - (candidate.offset - e.cur) if offset > maxMatchOffset || uint32(x>>16) != load3232(src, candidate.offset-e.cur) { - cv = uint32(x >> 24) + cv = x >> 24 s++ break } diff --git a/vendor/github.com/klauspost/compress/flate/level3.go b/vendor/github.com/klauspost/compress/flate/level3.go index 039639f89..7aa2b72a1 100644 --- a/vendor/github.com/klauspost/compress/flate/level3.go +++ b/vendor/github.com/klauspost/compress/flate/level3.go @@ -11,10 +11,11 @@ type fastEncL3 struct { // Encode uses a similar algorithm to level 2, will check up to two candidates. func (e *fastEncL3) Encode(dst *tokens, src []byte) { const ( - inputMargin = 8 - 1 + inputMargin = 12 - 1 minNonLiteralBlockSize = 1 + 1 + inputMargin tableBits = 16 tableSize = 1 << tableBits + hashBytes = 5 ) if debugDeflate && e.cur < 0 { @@ -69,20 +70,20 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) { sLimit := int32(len(src) - inputMargin) // nextEmit is where in src the next emitLiteral should start from. - cv := load3232(src, s) + cv := load6432(src, s) for { - const skipLog = 6 + const skipLog = 7 nextS := s var candidate tableEntry for { - nextHash := hash4u(cv, tableBits) + nextHash := hashLen(cv, tableBits, hashBytes) s = nextS nextS = s + 1 + (s-nextEmit)>>skipLog if nextS > sLimit { goto emitRemainder } candidates := e.table[nextHash] - now := load3232(src, nextS) + now := load6432(src, nextS) // Safe offset distance until s + 4... minOffset := e.cur + s - (maxMatchOffset - 4) @@ -96,8 +97,8 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) { continue } - if cv == load3232(src, candidate.offset-e.cur) { - if candidates.Prev.offset < minOffset || cv != load3232(src, candidates.Prev.offset-e.cur) { + if uint32(cv) == load3232(src, candidate.offset-e.cur) { + if candidates.Prev.offset < minOffset || uint32(cv) != load3232(src, candidates.Prev.offset-e.cur) { break } // Both match and are valid, pick longest. @@ -112,7 +113,7 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) { // We only check if value mismatches. // Offset will always be invalid in other cases. candidate = candidates.Prev - if candidate.offset > minOffset && cv == load3232(src, candidate.offset-e.cur) { + if candidate.offset > minOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) { break } } @@ -164,9 +165,9 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) { if s >= sLimit { t += l // Index first pair after match end. - if int(t+4) < len(src) && t > 0 { - cv := load3232(src, t) - nextHash := hash4u(cv, tableBits) + if int(t+8) < len(src) && t > 0 { + cv = load6432(src, t) + nextHash := hashLen(cv, tableBits, hashBytes) e.table[nextHash] = tableEntryPrev{ Prev: e.table[nextHash].Cur, Cur: tableEntry{offset: e.cur + t}, @@ -176,8 +177,8 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) { } // Store every 5th hash in-between. - for i := s - l + 2; i < s-5; i += 5 { - nextHash := hash4u(load3232(src, i), tableBits) + for i := s - l + 2; i < s-5; i += 6 { + nextHash := hashLen(load6432(src, i), tableBits, hashBytes) e.table[nextHash] = tableEntryPrev{ Prev: e.table[nextHash].Cur, Cur: tableEntry{offset: e.cur + i}} @@ -185,23 +186,23 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) { // We could immediately start working at s now, but to improve // compression we first update the hash table at s-2 to s. x := load6432(src, s-2) - prevHash := hash4u(uint32(x), tableBits) + prevHash := hashLen(x, tableBits, hashBytes) e.table[prevHash] = tableEntryPrev{ Prev: e.table[prevHash].Cur, Cur: tableEntry{offset: e.cur + s - 2}, } x >>= 8 - prevHash = hash4u(uint32(x), tableBits) + prevHash = hashLen(x, tableBits, hashBytes) e.table[prevHash] = tableEntryPrev{ Prev: e.table[prevHash].Cur, Cur: tableEntry{offset: e.cur + s - 1}, } x >>= 8 - currHash := hash4u(uint32(x), tableBits) + currHash := hashLen(x, tableBits, hashBytes) candidates := e.table[currHash] - cv = uint32(x) + cv = x e.table[currHash] = tableEntryPrev{ Prev: candidates.Cur, Cur: tableEntry{offset: s + e.cur}, @@ -212,17 +213,17 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) { minOffset := e.cur + s - (maxMatchOffset - 4) if candidate.offset > minOffset { - if cv == load3232(src, candidate.offset-e.cur) { + if uint32(cv) == load3232(src, candidate.offset-e.cur) { // Found a match... continue } candidate = candidates.Prev - if candidate.offset > minOffset && cv == load3232(src, candidate.offset-e.cur) { + if candidate.offset > minOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) { // Match at prev... continue } } - cv = uint32(x >> 8) + cv = x >> 8 s++ break } diff --git a/vendor/github.com/klauspost/compress/flate/level4.go b/vendor/github.com/klauspost/compress/flate/level4.go index 1cbffa1ae..23c08b325 100644 --- a/vendor/github.com/klauspost/compress/flate/level4.go +++ b/vendor/github.com/klauspost/compress/flate/level4.go @@ -12,6 +12,7 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) { const ( inputMargin = 12 - 1 minNonLiteralBlockSize = 1 + 1 + inputMargin + hashShortBytes = 4 ) if debugDeflate && e.cur < 0 { panic(fmt.Sprint("e.cur < 0: ", e.cur)) @@ -80,7 +81,7 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) { nextS := s var t int32 for { - nextHashS := hash4x64(cv, tableBits) + nextHashS := hashLen(cv, tableBits, hashShortBytes) nextHashL := hash7(cv, tableBits) s = nextS @@ -168,7 +169,7 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) { // Index first pair after match end. if int(s+8) < len(src) { cv := load6432(src, s) - e.table[hash4x64(cv, tableBits)] = tableEntry{offset: s + e.cur} + e.table[hashLen(cv, tableBits, hashShortBytes)] = tableEntry{offset: s + e.cur} e.bTable[hash7(cv, tableBits)] = tableEntry{offset: s + e.cur} } goto emitRemainder @@ -183,7 +184,7 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) { t2 := tableEntry{offset: t.offset + 1} e.bTable[hash7(cv, tableBits)] = t e.bTable[hash7(cv>>8, tableBits)] = t2 - e.table[hash4u(uint32(cv>>8), tableBits)] = t2 + e.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2 i += 3 for ; i < s-1; i += 3 { @@ -192,7 +193,7 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) { t2 := tableEntry{offset: t.offset + 1} e.bTable[hash7(cv, tableBits)] = t e.bTable[hash7(cv>>8, tableBits)] = t2 - e.table[hash4u(uint32(cv>>8), tableBits)] = t2 + e.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2 } } } @@ -201,7 +202,7 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) { // compression we first update the hash table at s-1 and at s. x := load6432(src, s-1) o := e.cur + s - 1 - prevHashS := hash4x64(x, tableBits) + prevHashS := hashLen(x, tableBits, hashShortBytes) prevHashL := hash7(x, tableBits) e.table[prevHashS] = tableEntry{offset: o} e.bTable[prevHashL] = tableEntry{offset: o} diff --git a/vendor/github.com/klauspost/compress/flate/level5.go b/vendor/github.com/klauspost/compress/flate/level5.go index 4b97576bd..83ef50ba4 100644 --- a/vendor/github.com/klauspost/compress/flate/level5.go +++ b/vendor/github.com/klauspost/compress/flate/level5.go @@ -12,6 +12,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) { const ( inputMargin = 12 - 1 minNonLiteralBlockSize = 1 + 1 + inputMargin + hashShortBytes = 4 ) if debugDeflate && e.cur < 0 { panic(fmt.Sprint("e.cur < 0: ", e.cur)) @@ -88,7 +89,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) { var l int32 var t int32 for { - nextHashS := hash4x64(cv, tableBits) + nextHashS := hashLen(cv, tableBits, hashShortBytes) nextHashL := hash7(cv, tableBits) s = nextS @@ -105,7 +106,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) { eLong := &e.bTable[nextHashL] eLong.Cur, eLong.Prev = entry, eLong.Cur - nextHashS = hash4x64(next, tableBits) + nextHashS = hashLen(next, tableBits, hashShortBytes) nextHashL = hash7(next, tableBits) t = lCandidate.Cur.offset - e.cur @@ -191,14 +192,21 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) { // Try to locate a better match by checking the end of best match... if sAt := s + l; l < 30 && sAt < sLimit { + // Allow some bytes at the beginning to mismatch. + // Sweet spot is 2/3 bytes depending on input. + // 3 is only a little better when it is but sometimes a lot worse. + // The skipped bytes are tested in Extend backwards, + // and still picked up as part of the match if they do. + const skipBeginning = 2 eLong := e.bTable[hash7(load6432(src, sAt), tableBits)].Cur.offset - // Test current - t2 := eLong - e.cur - l - off := s - t2 + t2 := eLong - e.cur - l + skipBeginning + s2 := s + skipBeginning + off := s2 - t2 if t2 >= 0 && off < maxMatchOffset && off > 0 { - if l2 := e.matchlenLong(s, t2, src); l2 > l { + if l2 := e.matchlenLong(s2, t2, src); l2 > l { t = t2 l = l2 + s = s2 } } } @@ -250,7 +258,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) { if i < s-1 { cv := load6432(src, i) t := tableEntry{offset: i + e.cur} - e.table[hash4x64(cv, tableBits)] = t + e.table[hashLen(cv, tableBits, hashShortBytes)] = t eLong := &e.bTable[hash7(cv, tableBits)] eLong.Cur, eLong.Prev = t, eLong.Cur @@ -263,7 +271,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) { // We only have enough bits for a short entry at i+2 cv >>= 8 t = tableEntry{offset: t.offset + 1} - e.table[hash4x64(cv, tableBits)] = t + e.table[hashLen(cv, tableBits, hashShortBytes)] = t // Skip one - otherwise we risk hitting 's' i += 4 @@ -273,7 +281,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) { t2 := tableEntry{offset: t.offset + 1} eLong := &e.bTable[hash7(cv, tableBits)] eLong.Cur, eLong.Prev = t, eLong.Cur - e.table[hash4u(uint32(cv>>8), tableBits)] = t2 + e.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2 } } } @@ -282,7 +290,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) { // compression we first update the hash table at s-1 and at s. x := load6432(src, s-1) o := e.cur + s - 1 - prevHashS := hash4x64(x, tableBits) + prevHashS := hashLen(x, tableBits, hashShortBytes) prevHashL := hash7(x, tableBits) e.table[prevHashS] = tableEntry{offset: o} eLong := &e.bTable[prevHashL] diff --git a/vendor/github.com/klauspost/compress/flate/level6.go b/vendor/github.com/klauspost/compress/flate/level6.go index 62888edf3..f1e9d98fa 100644 --- a/vendor/github.com/klauspost/compress/flate/level6.go +++ b/vendor/github.com/klauspost/compress/flate/level6.go @@ -12,6 +12,7 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) { const ( inputMargin = 12 - 1 minNonLiteralBlockSize = 1 + 1 + inputMargin + hashShortBytes = 4 ) if debugDeflate && e.cur < 0 { panic(fmt.Sprint("e.cur < 0: ", e.cur)) @@ -90,7 +91,7 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) { var l int32 var t int32 for { - nextHashS := hash4x64(cv, tableBits) + nextHashS := hashLen(cv, tableBits, hashShortBytes) nextHashL := hash7(cv, tableBits) s = nextS nextS = s + doEvery + (s-nextEmit)>>skipLog @@ -107,7 +108,7 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) { eLong.Cur, eLong.Prev = entry, eLong.Cur // Calculate hashes of 'next' - nextHashS = hash4x64(next, tableBits) + nextHashS = hashLen(next, tableBits, hashShortBytes) nextHashL = hash7(next, tableBits) t = lCandidate.Cur.offset - e.cur @@ -213,24 +214,33 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) { // Try to locate a better match by checking the end-of-match... if sAt := s + l; sAt < sLimit { + // Allow some bytes at the beginning to mismatch. + // Sweet spot is 2/3 bytes depending on input. + // 3 is only a little better when it is but sometimes a lot worse. + // The skipped bytes are tested in Extend backwards, + // and still picked up as part of the match if they do. + const skipBeginning = 2 eLong := &e.bTable[hash7(load6432(src, sAt), tableBits)] // Test current - t2 := eLong.Cur.offset - e.cur - l - off := s - t2 + t2 := eLong.Cur.offset - e.cur - l + skipBeginning + s2 := s + skipBeginning + off := s2 - t2 if off < maxMatchOffset { if off > 0 && t2 >= 0 { - if l2 := e.matchlenLong(s, t2, src); l2 > l { + if l2 := e.matchlenLong(s2, t2, src); l2 > l { t = t2 l = l2 + s = s2 } } // Test next: - t2 = eLong.Prev.offset - e.cur - l - off := s - t2 + t2 = eLong.Prev.offset - e.cur - l + skipBeginning + off := s2 - t2 if off > 0 && off < maxMatchOffset && t2 >= 0 { - if l2 := e.matchlenLong(s, t2, src); l2 > l { + if l2 := e.matchlenLong(s2, t2, src); l2 > l { t = t2 l = l2 + s = s2 } } } @@ -277,7 +287,7 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) { // Index after match end. for i := nextS + 1; i < int32(len(src))-8; i += 2 { cv := load6432(src, i) - e.table[hash4x64(cv, tableBits)] = tableEntry{offset: i + e.cur} + e.table[hashLen(cv, tableBits, hashShortBytes)] = tableEntry{offset: i + e.cur} eLong := &e.bTable[hash7(cv, tableBits)] eLong.Cur, eLong.Prev = tableEntry{offset: i + e.cur}, eLong.Cur } @@ -292,7 +302,7 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) { t2 := tableEntry{offset: t.offset + 1} eLong := &e.bTable[hash7(cv, tableBits)] eLong2 := &e.bTable[hash7(cv>>8, tableBits)] - e.table[hash4x64(cv, tableBits)] = t + e.table[hashLen(cv, tableBits, hashShortBytes)] = t eLong.Cur, eLong.Prev = t, eLong.Cur eLong2.Cur, eLong2.Prev = t2, eLong2.Cur } diff --git a/vendor/github.com/klauspost/compress/huff0/decompress.go b/vendor/github.com/klauspost/compress/huff0/decompress.go index c0c48bd70..42a237eac 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress.go @@ -763,17 +763,20 @@ func (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) { 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 { + if len(out)-bufoff < dstEvery*3 { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 2") } + //copy(out, buf[0][:]) + //copy(out[dstEvery:], buf[1][:]) + //copy(out[dstEvery*2:], buf[2][:]) + *(*[bufoff]byte)(out) = buf[0] + *(*[bufoff]byte)(out[dstEvery:]) = buf[1] + *(*[bufoff]byte)(out[dstEvery*2:]) = buf[2] + *(*[bufoff]byte)(out[dstEvery*3:]) = buf[3] + out = out[bufoff:] + decoded += bufoff * 4 } } if off > 0 { @@ -997,17 +1000,22 @@ func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) { 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 { + if len(out)-bufoff < dstEvery*3 { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 2") } + + //copy(out, buf[0][:]) + //copy(out[dstEvery:], buf[1][:]) + //copy(out[dstEvery*2:], buf[2][:]) + // copy(out[dstEvery*3:], buf[3][:]) + *(*[bufoff]byte)(out) = buf[0] + *(*[bufoff]byte)(out[dstEvery:]) = buf[1] + *(*[bufoff]byte)(out[dstEvery*2:]) = buf[2] + *(*[bufoff]byte)(out[dstEvery*3:]) = buf[3] + out = out[bufoff:] + decoded += bufoff * 4 } } if off > 0 { diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go index 9f3e9f79e..ba7e8e6b0 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go @@ -14,12 +14,14 @@ import ( // decompress4x_main_loop_x86 is an x86 assembler implementation // of Decompress4X when tablelog > 8. +// //go:noescape 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_main_loop_amd64(ctx *decompress4xContext) @@ -145,11 +147,13 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { // decompress4x_main_loop_x86 is an x86 assembler implementation // of Decompress1X when tablelog > 8. +// //go:noescape func decompress1x_main_loop_amd64(ctx *decompress1xContext) // decompress4x_main_loop_x86 is an x86 with BMI2 assembler implementation // of Decompress1X when tablelog > 8. +// //go:noescape func decompress1x_main_loop_bmi2(ctx *decompress1xContext) diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s index dd1a5aecd..8d2187a2c 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s @@ -1,7 +1,6 @@ // 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), $0-8 diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_generic.go b/vendor/github.com/klauspost/compress/huff0/decompress_generic.go index 4f6f37cb2..908c17de6 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_generic.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_generic.go @@ -122,17 +122,21 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { 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 { + if len(out)-bufoff < dstEvery*3 { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 2") } + //copy(out, buf[0][:]) + //copy(out[dstEvery:], buf[1][:]) + //copy(out[dstEvery*2:], buf[2][:]) + //copy(out[dstEvery*3:], buf[3][:]) + *(*[bufoff]byte)(out) = buf[0] + *(*[bufoff]byte)(out[dstEvery:]) = buf[1] + *(*[bufoff]byte)(out[dstEvery*2:]) = buf[2] + *(*[bufoff]byte)(out[dstEvery*3:]) = buf[3] + out = out[bufoff:] + decoded += bufoff * 4 } } if off > 0 { diff --git a/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go b/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go index 511bba65d..298c4f8e9 100644 --- a/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go +++ b/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go @@ -18,6 +18,7 @@ func load64(b []byte, i int) uint64 { // emitLiteral writes a literal chunk and returns the number of bytes written. // // It assumes that: +// // dst is long enough to hold the encoded bytes // 1 <= len(lit) && len(lit) <= 65536 func emitLiteral(dst, lit []byte) int { @@ -42,6 +43,7 @@ func emitLiteral(dst, lit []byte) int { // emitCopy writes a copy chunk and returns the number of bytes written. // // It assumes that: +// // dst is long enough to hold the encoded bytes // 1 <= offset && offset <= 65535 // 4 <= length && length <= 65535 @@ -89,6 +91,7 @@ func emitCopy(dst []byte, offset, length int) int { // src[i:i+k-j] and src[j:k] have the same contents. // // It assumes that: +// // 0 <= i && i < j && j <= len(src) func extendMatch(src []byte, i, j int) int { for ; j < len(src) && src[i] == src[j]; i, j = i+1, j+1 { @@ -105,8 +108,9 @@ func hash(u, shift uint32) uint32 { // been written. // // It also assumes that: +// // len(dst) >= MaxEncodedLen(len(src)) && -// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize +// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize func encodeBlock(dst, src []byte) (d int) { // Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive. // The table element type is uint16, as s < sLimit and sLimit < len(src) diff --git a/vendor/github.com/klauspost/compress/zstd/README.md b/vendor/github.com/klauspost/compress/zstd/README.md index beb7fa872..65b38abed 100644 --- a/vendor/github.com/klauspost/compress/zstd/README.md +++ b/vendor/github.com/klauspost/compress/zstd/README.md @@ -12,6 +12,8 @@ The `zstd` package is provided as open source software using a Go standard licen Currently the package is heavily optimized for 64 bit processors and will be significantly slower on 32 bit processors. +For seekable zstd streams, see [this excellent package](https://github.com/SaveTheRbtz/zstd-seekable-format-go). + ## Installation Install using `go get -u github.com/klauspost/compress`. The package is located in `github.com/klauspost/compress/zstd`. diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go index 7eed729be..f52d1aed6 100644 --- a/vendor/github.com/klauspost/compress/zstd/blockdec.go +++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path/filepath" "sync" @@ -651,7 +650,7 @@ func (b *blockDec) prepareSequences(in []byte, hist *history) (err error) { fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.matchLengths.fse)) fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.offsets.fse)) buf.Write(in) - ioutil.WriteFile(filepath.Join("testdata", "seqs", fn), buf.Bytes(), os.ModePerm) + os.WriteFile(filepath.Join("testdata", "seqs", fn), buf.Bytes(), os.ModePerm) } return nil diff --git a/vendor/github.com/klauspost/compress/zstd/bytebuf.go b/vendor/github.com/klauspost/compress/zstd/bytebuf.go index 2ad02070d..176788f25 100644 --- a/vendor/github.com/klauspost/compress/zstd/bytebuf.go +++ b/vendor/github.com/klauspost/compress/zstd/bytebuf.go @@ -7,7 +7,6 @@ package zstd import ( "fmt" "io" - "io/ioutil" ) type byteBuffer interface { @@ -124,7 +123,7 @@ func (r *readerWrapper) readByte() (byte, error) { } func (r *readerWrapper) skipN(n int64) error { - n2, err := io.CopyN(ioutil.Discard, r.r, n) + n2, err := io.CopyN(io.Discard, r.r, n) if n2 != n { err = io.ErrUnexpectedEOF } diff --git a/vendor/github.com/klauspost/compress/zstd/decoder.go b/vendor/github.com/klauspost/compress/zstd/decoder.go index d212f4737..78c10755f 100644 --- a/vendor/github.com/klauspost/compress/zstd/decoder.go +++ b/vendor/github.com/klauspost/compress/zstd/decoder.go @@ -35,6 +35,7 @@ type Decoder struct { br readerWrapper enabled bool inFrame bool + dstBuf []byte } frame *frameDec @@ -187,21 +188,23 @@ func (d *Decoder) Reset(r io.Reader) error { } // If bytes buffer and < 5MB, do sync decoding anyway. - if bb, ok := r.(byter); ok && bb.Len() < 5<<20 { + if bb, ok := r.(byter); ok && bb.Len() < d.o.decodeBufsBelow && !d.o.limitToCap { bb2 := bb if debugDecoder { println("*bytes.Buffer detected, doing sync decode, len:", bb.Len()) } b := bb2.Bytes() var dst []byte - if cap(d.current.b) > 0 { - dst = d.current.b + if cap(d.syncStream.dstBuf) > 0 { + dst = d.syncStream.dstBuf[:0] } - dst, err := d.DecodeAll(b, dst[:0]) + dst, err := d.DecodeAll(b, dst) if err == nil { err = io.EOF } + // Save output buffer + d.syncStream.dstBuf = dst d.current.b = dst d.current.err = err d.current.flushed = true @@ -216,6 +219,7 @@ func (d *Decoder) Reset(r io.Reader) error { d.current.err = nil d.current.flushed = false d.current.d = nil + d.syncStream.dstBuf = nil // Ensure no-one else is still running... d.streamWg.Wait() @@ -312,6 +316,7 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { // Grab a block decoder and frame decoder. block := <-d.decoders frame := block.localFrame + initialSize := len(dst) defer func() { if debugDecoder { printf("re-adding decoder: %p", block) @@ -354,7 +359,16 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { return dst, ErrWindowSizeExceeded } if frame.FrameContentSize != fcsUnknown { - if frame.FrameContentSize > d.o.maxDecodedSize-uint64(len(dst)) { + if frame.FrameContentSize > d.o.maxDecodedSize-uint64(len(dst)-initialSize) { + if debugDecoder { + println("decoder size exceeded; fcs:", frame.FrameContentSize, "> mcs:", d.o.maxDecodedSize-uint64(len(dst)-initialSize), "len:", len(dst)) + } + return dst, ErrDecoderSizeExceeded + } + if d.o.limitToCap && frame.FrameContentSize > uint64(cap(dst)-len(dst)) { + if debugDecoder { + println("decoder size exceeded; fcs:", frame.FrameContentSize, "> (cap-len)", cap(dst)-len(dst)) + } return dst, ErrDecoderSizeExceeded } if cap(dst)-len(dst) < int(frame.FrameContentSize) { @@ -364,7 +378,7 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { } } - if cap(dst) == 0 { + if cap(dst) == 0 && !d.o.limitToCap { // Allocate len(input) * 2 by default if nothing is provided // and we didn't get frame content size. size := len(input) * 2 @@ -382,6 +396,9 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { if err != nil { return dst, err } + if uint64(len(dst)-initialSize) > d.o.maxDecodedSize { + return dst, ErrDecoderSizeExceeded + } if len(frame.bBuf) == 0 { if debugDecoder { println("frame dbuf empty") @@ -667,6 +684,7 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch if debugDecoder { println("Async 1: new history, recent:", block.async.newHist.recentOffsets) } + hist.reset() hist.decoders = block.async.newHist.decoders hist.recentOffsets = block.async.newHist.recentOffsets hist.windowSize = block.async.newHist.windowSize @@ -698,6 +716,7 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch seqExecute <- block } close(seqExecute) + hist.reset() }() var wg sync.WaitGroup @@ -721,6 +740,7 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch if debugDecoder { println("Async 2: new history") } + hist.reset() hist.windowSize = block.async.newHist.windowSize hist.allocFrameBuffer = block.async.newHist.allocFrameBuffer if block.async.newHist.dict != nil { @@ -802,13 +822,14 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch if debugDecoder { println("decoder goroutines finished") } + hist.reset() }() + var hist history decodeStream: for { - var hist history var hasErr bool - + hist.reset() decodeBlock := func(block *blockDec) { if hasErr { if block != nil { @@ -852,6 +873,10 @@ decodeStream: } } if err == nil && d.frame.WindowSize > d.o.maxWindowSize { + if debugDecoder { + println("decoder size exceeded, fws:", d.frame.WindowSize, "> mws:", d.o.maxWindowSize) + } + err = ErrDecoderSizeExceeded } if err != nil { @@ -920,5 +945,6 @@ decodeStream: } close(seqDecode) wg.Wait() + hist.reset() d.frame.history.b = frameHistCache } diff --git a/vendor/github.com/klauspost/compress/zstd/decoder_options.go b/vendor/github.com/klauspost/compress/zstd/decoder_options.go index c70e6fa0f..f42448e69 100644 --- a/vendor/github.com/klauspost/compress/zstd/decoder_options.go +++ b/vendor/github.com/klauspost/compress/zstd/decoder_options.go @@ -14,20 +14,23 @@ type DOption func(*decoderOptions) error // options retains accumulated state of multiple options. type decoderOptions struct { - lowMem bool - concurrent int - maxDecodedSize uint64 - maxWindowSize uint64 - dicts []dict - ignoreChecksum bool + lowMem bool + concurrent int + maxDecodedSize uint64 + maxWindowSize uint64 + dicts []dict + ignoreChecksum bool + limitToCap bool + decodeBufsBelow int } func (o *decoderOptions) setDefault() { *o = decoderOptions{ // use less ram: true for now, but may change. - lowMem: true, - concurrent: runtime.GOMAXPROCS(0), - maxWindowSize: MaxWindowSize, + lowMem: true, + concurrent: runtime.GOMAXPROCS(0), + maxWindowSize: MaxWindowSize, + decodeBufsBelow: 128 << 10, } if o.concurrent > 4 { o.concurrent = 4 @@ -114,6 +117,29 @@ func WithDecoderMaxWindow(size uint64) DOption { } } +// WithDecodeAllCapLimit will limit DecodeAll to decoding cap(dst)-len(dst) bytes, +// or any size set in WithDecoderMaxMemory. +// This can be used to limit decoding to a specific maximum output size. +// Disabled by default. +func WithDecodeAllCapLimit(b bool) DOption { + return func(o *decoderOptions) error { + o.limitToCap = b + return nil + } +} + +// WithDecodeBuffersBelow will fully decode readers that have a +// `Bytes() []byte` and `Len() int` interface similar to bytes.Buffer. +// This typically uses less allocations but will have the full decompressed object in memory. +// Note that DecodeAllCapLimit will disable this, as well as giving a size of 0 or less. +// Default is 128KiB. +func WithDecodeBuffersBelow(size int) DOption { + return func(o *decoderOptions) error { + o.decodeBufsBelow = size + return nil + } +} + // IgnoreChecksum allows to forcibly ignore checksum checking. func IgnoreChecksum(b bool) DOption { return func(o *decoderOptions) error { diff --git a/vendor/github.com/klauspost/compress/zstd/enc_best.go b/vendor/github.com/klauspost/compress/zstd/enc_best.go index 96028ecd8..dbbb88d92 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_best.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_best.go @@ -32,6 +32,7 @@ type match struct { length int32 rep int32 est int32 + _ [12]byte // Aligned size to cache line: 4+4+4+4+4 bytes + 12 bytes padding = 32 bytes } const highScore = 25000 diff --git a/vendor/github.com/klauspost/compress/zstd/enc_better.go b/vendor/github.com/klauspost/compress/zstd/enc_better.go index c769f6941..d70e3fd3d 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_better.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_better.go @@ -416,15 +416,23 @@ encodeLoop: // Try to find a better match by searching for a long match at the end of the current best match if s+matched < sLimit { + // Allow some bytes at the beginning to mismatch. + // Sweet spot is around 3 bytes, but depends on input. + // The skipped bytes are tested in Extend backwards, + // and still picked up as part of the match if they do. + const skipBeginning = 3 + nextHashL := hashLen(load6432(src, s+matched), betterLongTableBits, betterLongLen) - cv := load3232(src, s) + s2 := s + skipBeginning + cv := load3232(src, s2) candidateL := e.longTable[nextHashL] - coffsetL := candidateL.offset - e.cur - matched - if coffsetL >= 0 && coffsetL < s && s-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) { + coffsetL := candidateL.offset - e.cur - matched + skipBeginning + if coffsetL >= 0 && coffsetL < s2 && s2-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) { // Found a long match, at least 4 bytes. - matchedNext := e.matchlen(s+4, coffsetL+4, src) + 4 + matchedNext := e.matchlen(s2+4, coffsetL+4, src) + 4 if matchedNext > matched { t = coffsetL + s = s2 matched = matchedNext if debugMatches { println("long match at end-of-match") @@ -434,12 +442,13 @@ encodeLoop: // Check prev long... if true { - coffsetL = candidateL.prev - e.cur - matched - if coffsetL >= 0 && coffsetL < s && s-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) { + coffsetL = candidateL.prev - e.cur - matched + skipBeginning + if coffsetL >= 0 && coffsetL < s2 && s2-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) { // Found a long match, at least 4 bytes. - matchedNext := e.matchlen(s+4, coffsetL+4, src) + 4 + matchedNext := e.matchlen(s2+4, coffsetL+4, src) + 4 if matchedNext > matched { t = coffsetL + s = s2 matched = matchedNext if debugMatches { println("prev long match at end-of-match") diff --git a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go index 7ff0c64fa..1f4a9a245 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go @@ -1103,7 +1103,8 @@ func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) { } if allDirty || dirtyShardCnt > dLongTableShardCnt/2 { - copy(e.longTable[:], e.dictLongTable) + //copy(e.longTable[:], e.dictLongTable) + e.longTable = *(*[dFastLongTableSize]tableEntry)(e.dictLongTable) for i := range e.longTableShardDirty { e.longTableShardDirty[i] = false } @@ -1114,7 +1115,9 @@ func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) { continue } - copy(e.longTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize], e.dictLongTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize]) + // copy(e.longTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize], e.dictLongTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize]) + *(*[dLongTableShardSize]tableEntry)(e.longTable[i*dLongTableShardSize:]) = *(*[dLongTableShardSize]tableEntry)(e.dictLongTable[i*dLongTableShardSize:]) + e.longTableShardDirty[i] = false } } diff --git a/vendor/github.com/klauspost/compress/zstd/enc_fast.go b/vendor/github.com/klauspost/compress/zstd/enc_fast.go index f51ab529a..181edc02b 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_fast.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_fast.go @@ -871,7 +871,8 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) { const shardCnt = tableShardCnt const shardSize = tableShardSize if e.allDirty || dirtyShardCnt > shardCnt*4/6 { - copy(e.table[:], e.dictTable) + //copy(e.table[:], e.dictTable) + e.table = *(*[tableSize]tableEntry)(e.dictTable) for i := range e.tableShardDirty { e.tableShardDirty[i] = false } @@ -883,7 +884,8 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) { continue } - copy(e.table[i*shardSize:(i+1)*shardSize], e.dictTable[i*shardSize:(i+1)*shardSize]) + //copy(e.table[i*shardSize:(i+1)*shardSize], e.dictTable[i*shardSize:(i+1)*shardSize]) + *(*[shardSize]tableEntry)(e.table[i*shardSize:]) = *(*[shardSize]tableEntry)(e.dictTable[i*shardSize:]) e.tableShardDirty[i] = false } e.allDirty = false diff --git a/vendor/github.com/klauspost/compress/zstd/framedec.go b/vendor/github.com/klauspost/compress/zstd/framedec.go index 9568a4ba3..b6c505417 100644 --- a/vendor/github.com/klauspost/compress/zstd/framedec.go +++ b/vendor/github.com/klauspost/compress/zstd/framedec.go @@ -343,7 +343,7 @@ func (d *frameDec) consumeCRC() error { return nil } -// runDecoder will create a sync decoder that will decode a block of data. +// runDecoder will run the decoder for the remainder of the frame. func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { saved := d.history.b @@ -353,12 +353,23 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { // Store input length, so we only check new data. crcStart := len(dst) d.history.decoders.maxSyncLen = 0 + if d.o.limitToCap { + d.history.decoders.maxSyncLen = uint64(cap(dst) - len(dst)) + } if d.FrameContentSize != fcsUnknown { - d.history.decoders.maxSyncLen = d.FrameContentSize + uint64(len(dst)) + if !d.o.limitToCap || d.FrameContentSize+uint64(len(dst)) < d.history.decoders.maxSyncLen { + d.history.decoders.maxSyncLen = d.FrameContentSize + uint64(len(dst)) + } if d.history.decoders.maxSyncLen > d.o.maxDecodedSize { + if debugDecoder { + println("maxSyncLen:", d.history.decoders.maxSyncLen, "> maxDecodedSize:", d.o.maxDecodedSize) + } return dst, ErrDecoderSizeExceeded } - if uint64(cap(dst)) < d.history.decoders.maxSyncLen { + if debugDecoder { + println("maxSyncLen:", d.history.decoders.maxSyncLen) + } + if !d.o.limitToCap && uint64(cap(dst)) < d.history.decoders.maxSyncLen { // Alloc for output dst2 := make([]byte, len(dst), d.history.decoders.maxSyncLen+compressedBlockOverAlloc) copy(dst2, dst) @@ -378,7 +389,13 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { if err != nil { break } - if uint64(len(d.history.b)) > d.o.maxDecodedSize { + if uint64(len(d.history.b)-crcStart) > d.o.maxDecodedSize { + println("runDecoder: maxDecodedSize exceeded", uint64(len(d.history.b)-crcStart), ">", d.o.maxDecodedSize) + err = ErrDecoderSizeExceeded + break + } + if d.o.limitToCap && len(d.history.b) > cap(dst) { + println("runDecoder: cap exceeded", uint64(len(d.history.b)), ">", cap(dst)) err = ErrDecoderSizeExceeded break } diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go index c881d28d8..d04a829b0 100644 --- a/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go @@ -21,7 +21,8 @@ type buildDtableAsmContext struct { // buildDtable_asm is an x86 assembly implementation of fseDecoder.buildDtable. // Function returns non-zero exit code on error. -// go:noescape +// +//go:noescape func buildDtable_asm(s *fseDecoder, ctx *buildDtableAsmContext) int // please keep in sync with _generate/gen_fse.go diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s index da32b4420..bcde39869 100644 --- a/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s @@ -1,7 +1,6 @@ // Code generated by command: go run gen_fse.go -out ../fse_decoder_amd64.s -pkg=zstd. DO NOT EDIT. //go:build !appengine && !noasm && gc && !noasm -// +build !appengine,!noasm,gc,!noasm // func buildDtable_asm(s *fseDecoder, ctx *buildDtableAsmContext) int TEXT ·buildDtable_asm(SB), $0-24 diff --git a/vendor/github.com/klauspost/compress/zstd/history.go b/vendor/github.com/klauspost/compress/zstd/history.go index 28b40153c..09164856d 100644 --- a/vendor/github.com/klauspost/compress/zstd/history.go +++ b/vendor/github.com/klauspost/compress/zstd/history.go @@ -37,24 +37,21 @@ func (h *history) reset() { h.ignoreBuffer = 0 h.error = false h.recentOffsets = [3]int{1, 4, 8} - if f := h.decoders.litLengths.fse; f != nil && !f.preDefined { - fseDecoderPool.Put(f) - } - if f := h.decoders.offsets.fse; f != nil && !f.preDefined { - fseDecoderPool.Put(f) - } - if f := h.decoders.matchLengths.fse; f != nil && !f.preDefined { - fseDecoderPool.Put(f) - } + h.decoders.freeDecoders() h.decoders = sequenceDecs{br: h.decoders.br} + h.freeHuffDecoder() + h.huffTree = nil + h.dict = nil + //printf("history created: %+v (l: %d, c: %d)", *h, len(h.b), cap(h.b)) +} + +func (h *history) freeHuffDecoder() { if h.huffTree != nil { if h.dict == nil || h.dict.litEnc != h.huffTree { huffDecoderPool.Put(h.huffTree) + h.huffTree = nil } } - h.huffTree = nil - h.dict = nil - //printf("history created: %+v (l: %d, c: %d)", *h, len(h.b), cap(h.b)) } func (h *history) setDict(dict *dict) { diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec.go b/vendor/github.com/klauspost/compress/zstd/seqdec.go index df0447203..f833d1541 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec.go @@ -99,6 +99,21 @@ func (s *sequenceDecs) initialize(br *bitReader, hist *history, out []byte) erro return nil } +func (s *sequenceDecs) freeDecoders() { + if f := s.litLengths.fse; f != nil && !f.preDefined { + fseDecoderPool.Put(f) + s.litLengths.fse = nil + } + if f := s.offsets.fse; f != nil && !f.preDefined { + fseDecoderPool.Put(f) + s.offsets.fse = nil + } + if f := s.matchLengths.fse; f != nil && !f.preDefined { + fseDecoderPool.Put(f) + s.matchLengths.fse = nil + } +} + // execute will execute the decoded sequence with the provided history. // The sequence must be evaluated before being sent. func (s *sequenceDecs) execute(seqs []seqVals, hist []byte) error { @@ -299,7 +314,10 @@ func (s *sequenceDecs) decodeSync(hist []byte) error { } size := ll + ml + len(out) if size-startSize > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", size-startSize, maxBlockSize) + if size-startSize == 424242 { + panic("here") + } + return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) } if size > cap(out) { // Not enough size, which can happen under high volume block streaming conditions @@ -411,7 +429,7 @@ func (s *sequenceDecs) decodeSync(hist []byte) error { // Check if space for literals if size := len(s.literals) + len(s.out) - startSize; size > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", size, maxBlockSize) + return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) } // Add final literals diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go index 7598c1018..191384adf 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go @@ -32,18 +32,22 @@ type decodeSyncAsmContext struct { // sequenceDecs_decodeSync_amd64 implements the main loop of sequenceDecs.decodeSync in x86 asm. // // Please refer to seqdec_generic.go for the reference implementation. +// //go:noescape func sequenceDecs_decodeSync_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int // sequenceDecs_decodeSync_bmi2 implements the main loop of sequenceDecs.decodeSync in x86 asm with BMI2 extensions. +// //go:noescape func sequenceDecs_decodeSync_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int // sequenceDecs_decodeSync_safe_amd64 does the same as above, but does not write more than output buffer. +// //go:noescape func sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int // sequenceDecs_decodeSync_safe_bmi2 does the same as above, but does not write more than output buffer. +// //go:noescape func sequenceDecs_decodeSync_safe_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int @@ -135,7 +139,7 @@ func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { if debugDecoder { println("msl:", s.maxSyncLen, "cap", cap(s.out), "bef:", startSize, "sz:", size-startSize, "mbs:", maxBlockSize, "outsz:", cap(s.out)-startSize) } - return true, fmt.Errorf("output (%d) bigger than max block size (%d)", size-startSize, maxBlockSize) + return true, fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) default: return true, fmt.Errorf("sequenceDecs_decode returned erronous code %d", errCode) @@ -143,7 +147,8 @@ func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { s.seqSize += ctx.litRemain if s.seqSize > maxBlockSize { - return true, fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize) + return true, fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) + } err := br.close() if err != nil { @@ -201,20 +206,24 @@ const errorNotEnoughSpace = 5 // sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm. // // Please refer to seqdec_generic.go for the reference implementation. +// //go:noescape func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int // sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm. // // Please refer to seqdec_generic.go for the reference implementation. +// //go:noescape func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int // sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm with BMI2 extensions. +// //go:noescape func sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int // sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm with BMI2 extensions. +// //go:noescape func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int @@ -281,7 +290,7 @@ func (s *sequenceDecs) decode(seqs []seqVals) error { s.seqSize += ctx.litRemain if s.seqSize > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize) + return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) } err := br.close() if err != nil { @@ -308,10 +317,12 @@ type executeAsmContext struct { // Returns false if a match offset is too big. // // Please refer to seqdec_generic.go for the reference implementation. +// //go:noescape func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool // Same as above, but with safe memcopies +// //go:noescape func sequenceDecs_executeSimple_safe_amd64(ctx *executeAsmContext) bool diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s index 27e76774c..52e5703c2 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s @@ -1,7 +1,6 @@ // Code generated by command: go run gen.go -out ../seqdec_amd64.s -pkg=zstd. DO NOT EDIT. //go:build !appengine && !noasm && gc && !noasm -// +build !appengine,!noasm,gc,!noasm // func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int // Requires: CMOV diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go b/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go index c3452bc3a..ac2a80d29 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go @@ -111,7 +111,7 @@ func (s *sequenceDecs) decode(seqs []seqVals) error { } s.seqSize += ll + ml if s.seqSize > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize) + return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) } litRemain -= ll if litRemain < 0 { @@ -149,7 +149,7 @@ func (s *sequenceDecs) decode(seqs []seqVals) error { } s.seqSize += litRemain if s.seqSize > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize) + return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) } err := br.close() if err != nil { diff --git a/vendor/github.com/klauspost/pgzip/.travis.yml b/vendor/github.com/klauspost/pgzip/.travis.yml index acfec4bb0..34704000e 100644 --- a/vendor/github.com/klauspost/pgzip/.travis.yml +++ b/vendor/github.com/klauspost/pgzip/.travis.yml @@ -1,3 +1,7 @@ + +arch: + - amd64 + - ppc64le language: go os: diff --git a/vendor/github.com/klauspost/pgzip/LICENSE b/vendor/github.com/klauspost/pgzip/LICENSE index 3909da410..2bdc0d751 100644 --- a/vendor/github.com/klauspost/pgzip/LICENSE +++ b/vendor/github.com/klauspost/pgzip/LICENSE @@ -1,4 +1,4 @@ -MIT License +The MIT License (MIT) Copyright (c) 2014 Klaus Post @@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/github.com/klauspost/pgzip/README.md b/vendor/github.com/klauspost/pgzip/README.md index 171b978fd..ecc8726fa 100644 --- a/vendor/github.com/klauspost/pgzip/README.md +++ b/vendor/github.com/klauspost/pgzip/README.md @@ -104,13 +104,12 @@ Content is [Matt Mahoneys 10GB corpus](http://mattmahoney.net/dc/10gb.html). Com Compressor | MB/sec | speedup | size | size overhead (lower=better) ------------|----------|---------|------|--------- -[gzip](http://golang.org/pkg/compress/gzip) (golang) | 15.44MB/s (1 thread) | 1.0x | 4781329307 | 0% -[gzip](http://github.com/klauspost/compress/gzip) (klauspost) | 135.04MB/s (1 thread) | 8.74x | 4894858258 | +2.37% -[pgzip](https://github.com/klauspost/pgzip) (klauspost) | 1573.23MB/s| 101.9x | 4902285651 | +2.53% -[bgzf](https://godoc.org/github.com/biogo/hts/bgzf) (biogo) | 361.40MB/s | 23.4x | 4869686090 | +1.85% -[pargzip](https://godoc.org/github.com/golang/build/pargzip) (builder) | 306.01MB/s | 19.8x | 4786890417 | +0.12% +[gzip](http://golang.org/pkg/compress/gzip) (golang) | 16.91MB/s (1 thread) | 1.0x | 4781329307 | 0% +[gzip](http://github.com/klauspost/compress/gzip) (klauspost) | 127.10MB/s (1 thread) | 7.52x | 4885366806 | +2.17% +[pgzip](https://github.com/klauspost/pgzip) (klauspost) | 2085.35MB/s| 123.34x | 4886132566 | +2.19% +[pargzip](https://godoc.org/github.com/golang/build/pargzip) (builder) | 334.04MB/s | 19.76x | 4786890417 | +0.12% -pgzip also contains a [linear time compression](https://github.com/klauspost/compress#linear-time-compression-huffman-only) mode, that will allow compression at ~250MB per core per second, independent of the content. +pgzip also contains a [huffman only compression](https://github.com/klauspost/compress#linear-time-compression-huffman-only) mode, that will allow compression at ~450MB per core per second, largely independent of the content. See the [complete sheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing) for different content types and compression settings. @@ -123,7 +122,7 @@ In the example above, the numbers are as follows on a 4 CPU machine: Decompressor | Time | Speedup -------------|------|-------- [gzip](http://golang.org/pkg/compress/gzip) (golang) | 1m28.85s | 0% -[pgzip](https://github.com/klauspost/pgzip) (golang) | 43.48s | 104% +[pgzip](https://github.com/klauspost/pgzip) (klauspost) | 43.48s | 104% But wait, since gzip decompression is inherently singlethreaded (aside from CRC calculation) how can it be more than 100% faster? Because pgzip due to its design also acts as a buffer. When using unbuffered gzip, you are also waiting for io when you are decompressing. If the gzip decoder can keep up, it will always have data ready for your reader, and you will not be waiting for input to the gzip decompressor to complete. diff --git a/vendor/github.com/klauspost/pgzip/gunzip.go b/vendor/github.com/klauspost/pgzip/gunzip.go index d1ae730b2..3c4b32f16 100644 --- a/vendor/github.com/klauspost/pgzip/gunzip.go +++ b/vendor/github.com/klauspost/pgzip/gunzip.go @@ -513,6 +513,19 @@ func (z *Reader) Read(p []byte) (n int, err error) { func (z *Reader) WriteTo(w io.Writer) (n int64, err error) { total := int64(0) + avail := z.current[z.roff:] + if len(avail) != 0 { + n, err := w.Write(avail) + if n != len(avail) { + return total, io.ErrShortWrite + } + total += int64(n) + if err != nil { + return total, err + } + z.blockPool <- z.current + z.current = nil + } for { if z.err != nil { return total, z.err diff --git a/vendor/github.com/mistifyio/go-zfs/.gitignore b/vendor/github.com/mistifyio/go-zfs/.gitignore deleted file mode 100644 index 8000dd9db..000000000 --- a/vendor/github.com/mistifyio/go-zfs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.vagrant diff --git a/vendor/github.com/mistifyio/go-zfs/.travis.yml b/vendor/github.com/mistifyio/go-zfs/.travis.yml deleted file mode 100644 index acbd39cef..000000000 --- a/vendor/github.com/mistifyio/go-zfs/.travis.yml +++ /dev/null @@ -1,43 +0,0 @@ -language: go -dist: trusty -sudo: required -cache: - directories: - - $HOME/.ccache - - $HOME/zfs - -branches: - only: - - master - -env: - - rel=0.6.5.11 - - rel=0.7.6 - -go: - - "1.10.x" - - master - -before_install: - - export MAKEFLAGS=-j$(($(grep -c '^processor' /proc/cpuinfo) * 2 + 1)) - - export PATH=/usr/lib/ccache:$PATH - - go get github.com/alecthomas/gometalinter - - gometalinter --install --update - - sudo apt-get update -y && sudo apt-get install -y libattr1-dev libblkid-dev linux-headers-$(uname -r) tree uuid-dev - - mkdir -p $HOME/zfs - - cd $HOME/zfs - - [[ -d spl-$rel.tar.gz ]] || curl -L https://github.com/zfsonlinux/zfs/releases/download/zfs-$rel/spl-$rel.tar.gz | tar xz - - [[ -d zfs-$rel.tar.gz ]] || curl -L https://github.com/zfsonlinux/zfs/releases/download/zfs-$rel/zfs-$rel.tar.gz | tar xz - - (cd spl-$rel && ./configure --prefix=/usr && make && sudo make install) - - (cd zfs-$rel && ./configure --prefix=/usr && make && sudo make install) - - sudo modprobe zfs - - cd $TRAVIS_BUILD_DIR - -script: - - sudo -E $(which go) test -v ./... - - gometalinter --vendor --vendored-linters ./... || true - - gometalinter --errors --vendor --vendored-linters ./... - -notifications: - email: false - irc: "chat.freenode.net#cerana" diff --git a/vendor/github.com/mistifyio/go-zfs/Vagrantfile b/vendor/github.com/mistifyio/go-zfs/Vagrantfile deleted file mode 100644 index 3bd6e120b..000000000 --- a/vendor/github.com/mistifyio/go-zfs/Vagrantfile +++ /dev/null @@ -1,34 +0,0 @@ - -VAGRANTFILE_API_VERSION = "2" - -Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - config.vm.box = "ubuntu/trusty64" - config.ssh.forward_agent = true - - config.vm.synced_folder ".", "/home/vagrant/go/src/github.com/mistifyio/go-zfs", create: true - - config.vm.provision "shell", inline: <<EOF -cat << END > /etc/profile.d/go.sh -export GOPATH=\\$HOME/go -export PATH=\\$GOPATH/bin:/usr/local/go/bin:\\$PATH -END - -chown -R vagrant /home/vagrant/go - -apt-get update -apt-get install -y software-properties-common curl -apt-add-repository --yes ppa:zfs-native/stable -apt-get update -apt-get install -y ubuntu-zfs - -cd /home/vagrant -curl -z go1.3.3.linux-amd64.tar.gz -L -O https://storage.googleapis.com/golang/go1.3.3.linux-amd64.tar.gz -tar -C /usr/local -zxf /home/vagrant/go1.3.3.linux-amd64.tar.gz - -cat << END > /etc/sudoers.d/go -Defaults env_keep += "GOPATH" -END - -EOF - -end diff --git a/vendor/github.com/mistifyio/go-zfs/utils_notsolaris.go b/vendor/github.com/mistifyio/go-zfs/utils_notsolaris.go deleted file mode 100644 index a46f73060..000000000 --- a/vendor/github.com/mistifyio/go-zfs/utils_notsolaris.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !solaris - -package zfs - -import ( - "strings" -) - -// List of ZFS properties to retrieve from zfs list command on a non-Solaris platform -var dsPropList = []string{"name", "origin", "used", "available", "mountpoint", "compression", "type", "volsize", "quota", "referenced", "written", "logicalused", "usedbydataset"} - -var dsPropListOptions = strings.Join(dsPropList, ",") - -// List of Zpool properties to retrieve from zpool list command on a non-Solaris platform -var zpoolPropList = []string{"name", "health", "allocated", "size", "free", "readonly", "dedupratio", "fragmentation", "freeing", "leaked"} -var zpoolPropListOptions = strings.Join(zpoolPropList, ",") -var zpoolArgs = []string{"get", "-p", zpoolPropListOptions} diff --git a/vendor/github.com/mistifyio/go-zfs/utils_solaris.go b/vendor/github.com/mistifyio/go-zfs/utils_solaris.go deleted file mode 100644 index 0a7e90f22..000000000 --- a/vendor/github.com/mistifyio/go-zfs/utils_solaris.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build solaris - -package zfs - -import ( - "strings" -) - -// List of ZFS properties to retrieve from zfs list command on a Solaris platform -var dsPropList = []string{"name", "origin", "used", "available", "mountpoint", "compression", "type", "volsize", "quota", "referenced"} - -var dsPropListOptions = strings.Join(dsPropList, ",") - -// List of Zpool properties to retrieve from zpool list command on a non-Solaris platform -var zpoolPropList = []string{"name", "health", "allocated", "size", "free", "readonly", "dedupratio"} -var zpoolPropListOptions = strings.Join(zpoolPropList, ",") -var zpoolArgs = []string{"get", "-p", zpoolPropListOptions} diff --git a/vendor/github.com/mistifyio/go-zfs/v3/.envrc b/vendor/github.com/mistifyio/go-zfs/v3/.envrc new file mode 100644 index 000000000..f310aea66 --- /dev/null +++ b/vendor/github.com/mistifyio/go-zfs/v3/.envrc @@ -0,0 +1,4 @@ +has nix && use nix +dotenv_if_exists +PATH_add bin +path_add GOBIN bin diff --git a/vendor/github.com/mistifyio/go-zfs/v3/.gitignore b/vendor/github.com/mistifyio/go-zfs/v3/.gitignore new file mode 100644 index 000000000..0867490ad --- /dev/null +++ b/vendor/github.com/mistifyio/go-zfs/v3/.gitignore @@ -0,0 +1,6 @@ +bin +go-zfs.test +.vagrant + +# added by lint-install +out/ diff --git a/vendor/github.com/mistifyio/go-zfs/v3/.golangci.yml b/vendor/github.com/mistifyio/go-zfs/v3/.golangci.yml new file mode 100644 index 000000000..499c3eca1 --- /dev/null +++ b/vendor/github.com/mistifyio/go-zfs/v3/.golangci.yml @@ -0,0 +1,207 @@ +run: + # The default runtime timeout is 1m, which doesn't work well on Github Actions. + timeout: 4m + +# NOTE: This file is populated by the lint-install tool. Local adjustments may be overwritten. +linters-settings: + cyclop: + # NOTE: This is a very high transitional threshold + max-complexity: 37 + package-average: 34.0 + skip-tests: true + + gocognit: + # NOTE: This is a very high transitional threshold + min-complexity: 98 + + dupl: + threshold: 200 + + goconst: + min-len: 4 + min-occurrences: 5 + ignore-tests: true + + gosec: + excludes: + - G107 # Potential HTTP request made with variable url + - G204 # Subprocess launched with function call as argument or cmd arguments + - G404 # Use of weak random number generator (math/rand instead of crypto/rand + + errorlint: + # these are still common in Go: for instance, exit errors. + asserts: false + + exhaustive: + default-signifies-exhaustive: true + + nestif: + min-complexity: 8 + + nolintlint: + require-explanation: true + allow-unused: false + require-specific: true + + revive: + ignore-generated-header: true + severity: warning + rules: + - name: atomic + - name: blank-imports + - name: bool-literal-in-expr + - name: confusing-naming + - name: constant-logical-expr + - name: context-as-argument + - name: context-keys-type + - name: deep-exit + - name: defer + - name: range-val-in-closure + - name: range-val-address + - name: dot-imports + - name: error-naming + - name: error-return + - name: error-strings + - name: errorf + - name: exported + - name: identical-branches + - name: if-return + - name: import-shadowing + - name: increment-decrement + - name: indent-error-flow + - name: indent-error-flow + - name: package-comments + - name: range + - name: receiver-naming + - name: redefines-builtin-id + - name: superfluous-else + - name: struct-tag + - name: time-naming + - name: unexported-naming + - name: unexported-return + - name: unnecessary-stmt + - name: unreachable-code + - name: unused-parameter + - name: var-declaration + - name: var-naming + - name: unconditional-recursion + - name: waitgroup-by-value + + staticcheck: + go: "1.16" + + unused: + go: "1.16" + +output: + sort-results: true + +linters: + disable-all: true + enable: + - asciicheck + - bodyclose + - cyclop + - deadcode + - dogsled + - dupl + - durationcheck + - errcheck + - errname + - errorlint + - exhaustive + - exportloopref + - forcetypeassert + - gocognit + - goconst + - gocritic + - godot + - gofmt + - gofumpt + - gosec + - goheader + - goimports + - goprintffuncname + - gosimple + - govet + - ifshort + - importas + - ineffassign + - makezero + - misspell + - nakedret + - nestif + - nilerr + - noctx + - nolintlint + - predeclared + # disabling for the initial iteration of the linting tool + # - promlinter + - revive + - rowserrcheck + - sqlclosecheck + - staticcheck + - structcheck + - stylecheck + - thelper + - tparallel + - typecheck + - unconvert + - unparam + - unused + - varcheck + - wastedassign + - whitespace + + # Disabled linters, due to being misaligned with Go practices + # - exhaustivestruct + # - gochecknoglobals + # - gochecknoinits + # - goconst + # - godox + # - goerr113 + # - gomnd + # - lll + # - nlreturn + # - testpackage + # - wsl + # Disabled linters, due to not being relevant to our code base: + # - maligned + # - prealloc "For most programs usage of prealloc will be a premature optimization." + # Disabled linters due to bad error messages or bugs + # - tagliatelle + +issues: + # Excluding configuration per-path, per-linter, per-text and per-source + exclude-rules: + - path: _test\.go + linters: + - dupl + - errcheck + - forcetypeassert + - gocyclo + - gosec + - noctx + + - path: .*cmd.* + linters: + - noctx + + - path: main\.go + linters: + - noctx + + - path: .*cmd.* + text: "deep-exit" + + - path: main\.go + text: "deep-exit" + + # This check is of questionable value + - linters: + - tparallel + text: "call t.Parallel on the top level as well as its subtests" + + # Don't hide lint issues just because there are many of them + max-same-issues: 0 + max-issues-per-linter: 0 diff --git a/vendor/github.com/mistifyio/go-zfs/v3/.yamllint b/vendor/github.com/mistifyio/go-zfs/v3/.yamllint new file mode 100644 index 000000000..9a08ad176 --- /dev/null +++ b/vendor/github.com/mistifyio/go-zfs/v3/.yamllint @@ -0,0 +1,16 @@ +--- +extends: default + +rules: + braces: + max-spaces-inside: 1 + brackets: + max-spaces-inside: 1 + comments: disable + comments-indentation: disable + document-start: disable + line-length: + level: warning + max: 160 + allow-non-breakable-inline-mappings: true + truthy: disable diff --git a/vendor/github.com/mistifyio/go-zfs/v3/CHANGELOG.md b/vendor/github.com/mistifyio/go-zfs/v3/CHANGELOG.md new file mode 100644 index 000000000..349245d03 --- /dev/null +++ b/vendor/github.com/mistifyio/go-zfs/v3/CHANGELOG.md @@ -0,0 +1,250 @@ +# Change Log + +All notable changes to this project will be documented in this file. +This project adheres to [Semantic Versioning](http://semver.org/). +This change log follows the advice of [Keep a CHANGELOG](https://github.com/olivierlacan/keep-a-changelog). + +## [Unreleased] + +## [3.0.0] - 2022-03-30 + +### Added + +- Rename, Mount and Unmount methods +- Parse more fields into Zpool type: + - dedupratio + - fragmentation + - freeing + - leaked + - readonly +- Parse more fields into Dataset type: + - referenced +- Incremental Send +- Parse numbers in exact format +- Support for Solaris (non-blockint, best-effort status) +- Debug logging for command invocation +- Use GitHub Actions for CI +- Nix shell for dev env reproducibility +- Direnv file for ease of dev +- Formatting/lint checks (enforced by CI) +- Go Module +- FreeBSD based vagrant machine + +### Changed + +- Temporarily adjust TestDiff expected strings depending on ZFS version +- Use one `zfs list`/`zpool list` call instead of many `zfs get`/`zpool get` +- ZFS docs links now point to OpenZFS pages +- Ubuntu vagrant box changed to generic/ubuntu2004 + +### Fixed + +- `GetProperty` returning `VALUE` instead of the actual value + +### Shortlog + + Amit Krishnan (1): + Issue #39 and Issue #40 - Enable Solaris support for go-zfs Switch from zfs/zpool get to zfs/zpool list for better performance Signed-off-by: Amit Krishnan <krish.amit@gmail.com> + + Anand Patil (3): + Added Rename + Small fix to rename. + Added mount and umount methods + + Brian Akins (1): + Add 'referenced' to zfs properties + + Brian Bickerton (3): + Add debug logging before and after running external zfs command + Don't export the default no-op logger + Update uuid package repo url + + Dmitry Teselkin (1): + Issue #52 - fix parseLine for fragmentation field + + Edward Betts (1): + correct spelling mistake + + Justin Cormack (1): + Switch to google/uuid which is the maintained version of pborman/uuid + + Manuel Mendez (40): + rename Umount -> Unmount to follow zfs command name + add missing Unmount/Mount docs + always allocate largest Mount slice + add travis config + travis: update to go 1.7 + travis: get go deps first + test: add nok helper to verify an error occurred + test: add test for Dataset.GetProperty + ci: swap #cerana on freenode for slack + ci: install new deps for 0.7 relases + ci: bump zol versions + ci: bump go versions + ci: use better gometalinter invocations + ci: add ccache + ci: set env earlier in before_install + fix test nok error printing + test: restructure TestDiff to deal with different order of changes + test: better unicode path handling in TestDiff + travis: bump zfs and go versions + cache zfs artifacts + Add nix-shell and direnv goodness + prettierify all the files + Add go based tools + Add Makefile and rules.mk files + gofumptize the code base + Use tinkerbell/lint-install to setup linters + make golangci-lint happy + Update CONTRIBUTING.md with make based approach + Add GitHub Actions + Drop Travis CI + One sentence per line + Update documentation links to openzfs-docs pages + Format Vagrantfile using rufo + Add go-zfs.test to .gitignore + test: Avoid reptitive/duplicate error logging and quitting + test: Use t.Logf instead of fmt.Printf + test: Better cleanup and error handling in zpoolTest + test: Do not mark TestDatasets as a t.Helper. + test: Change zpoolTest to a pure helper that returns a clean up function + test: Move helpers to a different file + vagrant: Add set -euxo pipefail to provision script + vagrant: Update to generic/ubuntu2004 + vagrant: Minor fixes to Vagrantfile + vagrant: Update to go 1.17.8 + vagrant: Run go tests as part of provision script + vagrant: Indent heredoc script + vagrant: Add freebsd machine + + Matt Layher (1): + Parse more fields into Zpool type + + Michael Crosby (1): + Add incremental send + + Rikard Gynnerstedt (1): + remove command name from joined args + + Sebastiaan van Stijn (1): + Add go.mod and rename to github.com/mistifyio/go-zfs/v3 (v3.0.0) + + mikudeko (1): + Fix GetProperty always returning 'VALUE' + +## [2.1.1] - 2015-05-29 + +### Fixed + +- Ignoring first pool listed +- Incorrect `zfs get` argument ordering + +### Shortlog + + Alexey Guskov (1): + zfs command uses different order of arguments on freebsd + + Brian Akins (4): + test that ListZpools returns expected zpool + test error first + test error first + fix test to check correct return value + + James Cunningham (1): + Fix Truncating First Zpool + + Pat Norton (2): + Added Use of Go Tools + Update CONTRIBUTING.md + +## [2.1.0] - 2014-12-08 + +### Added + +- Parse hardlink modification count returned from `zfs diff` + +### Fixed + +- Continuing instead of erroring when rolling back a non-snapshot + +### Shortlog + + Brian Akins (2): + need to return the error here + use named struct fields + + Jörg Thalheim (1): + zfs diff handle hardlinks modification now + +## [2.0.0] - 2014-12-02 + +### Added + +- Flags for Destroy: + - DESTROY_DEFAULT + - DESTROY_DEFER_DELETION (`zfs destroy ... -d`) + - DESTROY_FORCE (`zfs destroy ... -f`) + - DESTROY_RECURSIVE_CLONES (`zfs destroy ... -R`) + - DESTROY_RECURSIVE (`zfs destroy ... -r`) + - etc +- Diff method (`zfs diff`) +- LogicalUsed and Origin properties to Dataset +- Type constants for Dataset +- State constants for Zpool +- Logger interface +- Improve documentation + +### Shortlog + + Brian Akins (8): + remove reflection + style change for switches + need to check for error + keep in scope + go 1.3.3 + golint cleanup + Just test if logical used is greater than 0, as this appears to be implementation specific + add docs to satisfy golint + + Jörg Thalheim (8): + Add deferred flag to zfs.Destroy() + add Logicalused property + Add Origin property + gofmt + Add zfs.Diff + Add Logger + add recursive destroy with clones + use CamelCase-style constants + + Matt Layher (4): + Improve documentation, document common ZFS operations, provide more references + Add zpool state constants, for easier health checking + Add dataset type constants, for easier type checking + Fix string split in command.Run(), use strings.Fields() instead of strings.Split() + +## [1.0.0] - 2014-11-12 + +### Shortlog + + Brian Akins (7): + add godoc badge + Add example + add information about zpool to struct and parser + Add Quota + add Children call + add Children call + fix snapshot tests + + Brian Bickerton (3): + MIST-150 Change Snapshot second paramater from properties map[string][string] to recursive bool + MIST-150 Add Rollback method and related tests + MIST-160 Add SendSnapshot streaming method and tests + + Matt Layher (1): + Add Error struct type and tests, enabling easier error return checking + +[3.0.0]: https://github.com/mistifyio/go-zfs/compare/v2.1.1...v3.0.0 +[2.1.1]: https://github.com/mistifyio/go-zfs/compare/v2.1.0...v2.1.1 +[2.1.0]: https://github.com/mistifyio/go-zfs/compare/v2.0.0...v2.1.0 +[2.0.0]: https://github.com/mistifyio/go-zfs/compare/v1.0.0...v2.0.0 +[1.0.0]: https://github.com/mistifyio/go-zfs/compare/v0.0.0...v1.0.0 diff --git a/vendor/github.com/mistifyio/go-zfs/CONTRIBUTING.md b/vendor/github.com/mistifyio/go-zfs/v3/CONTRIBUTING.md index f1880c19e..9f625d564 100644 --- a/vendor/github.com/mistifyio/go-zfs/CONTRIBUTING.md +++ b/vendor/github.com/mistifyio/go-zfs/v3/CONTRIBUTING.md @@ -1,20 +1,23 @@ -## How to Contribute ## +## How to Contribute -We always welcome contributions to help make `go-zfs` better. Please take a moment to read this document if you would like to contribute. +We always welcome contributions to help make `go-zfs` better. +Please take a moment to read this document if you would like to contribute. -### Reporting issues ### +### Reporting issues We use [Github issues](https://github.com/mistifyio/go-zfs/issues) to track bug reports, feature requests, and submitting pull requests. If you find a bug: -* Use the GitHub issue search to check whether the bug has already been reported. -* If the issue has been fixed, try to reproduce the issue using the latest `master` branch of the repository. -* If the issue still reproduces or has not yet been reported, try to isolate the problem before opening an issue, if possible. Also provide the steps taken to reproduce the bug. +- Use the GitHub issue search to check whether the bug has already been reported. +- If the issue has been fixed, try to reproduce the issue using the latest `master` branch of the repository. +- If the issue still reproduces or has not yet been reported, try to isolate the problem before opening an issue, if possible. Also provide the steps taken to reproduce the bug. -### Pull requests ### +### Pull requests -We welcome bug fixes, improvements, and new features. Before embarking on making significant changes, please open an issue and ask first so that you do not risk duplicating efforts or spending time working on something that may be out of scope. For minor items, just open a pull request. +We welcome bug fixes, improvements, and new features. +Before embarking on making significant changes, please open an issue and ask first so that you do not risk duplicating efforts or spending time working on something that may be out of scope. +For minor items, just open a pull request. [Fork the project](https://help.github.com/articles/fork-a-repo), clone your fork, and add the upstream to your remote: @@ -28,11 +31,13 @@ If you need to pull new changes committed upstream: $ git fetch upstream $ git merge upstream/master -Don' work directly on master as this makes it harder to merge later. Create a feature branch for your fix or new feature: +Don' work directly on master as this makes it harder to merge later. +Create a feature branch for your fix or new feature: $ git checkout -b <feature-branch-name> -Please try to commit your changes in logical chunks. Ideally, you should include the issue number in the commit message. +Please try to commit your changes in logical chunks. +Ideally, you should include the issue number in the commit message. $ git commit -m "Issue #<issue-number> - <commit-message>" @@ -40,21 +45,20 @@ Push your feature branch to your fork. $ git push origin <feature-branch-name> -[Open a Pull Request](https://help.github.com/articles/using-pull-requests) against the upstream master branch. Please give your pull request a clear title and description and note which issue(s) your pull request fixes. +[Open a Pull Request](https://help.github.com/articles/using-pull-requests) against the upstream master branch. +Please give your pull request a clear title and description and note which issue(s) your pull request fixes. -* All Go code should be formatted using [gofmt](http://golang.org/cmd/gofmt/). -* Every exported function should have [documentation](http://blog.golang.org/godoc-documenting-go-code) and corresponding [tests](http://golang.org/doc/code.html#Testing). +- All linters should be happy (can be run with `make verify`). +- Every exported function should have [documentation](http://blog.golang.org/godoc-documenting-go-code) and corresponding [tests](http://golang.org/doc/code.html#Testing). **Important:** By submitting a patch, you agree to allow the project owners to license your work under the [Apache 2.0 License](./LICENSE). -### Go Tools ### -For consistency and to catch minor issues for all of go code, please run the following: -* goimports -* go vet -* golint -* errcheck +### Go Tools + +For consistency and to catch minor issues for all of go code, please run `make verify`. Many editors can execute the above on save. ----- +--- + Guidelines based on http://azkaban.github.io/contributing.html diff --git a/vendor/github.com/mistifyio/go-zfs/LICENSE b/vendor/github.com/mistifyio/go-zfs/v3/LICENSE index f4c265cfe..f4c265cfe 100644 --- a/vendor/github.com/mistifyio/go-zfs/LICENSE +++ b/vendor/github.com/mistifyio/go-zfs/v3/LICENSE diff --git a/vendor/github.com/mistifyio/go-zfs/v3/Makefile b/vendor/github.com/mistifyio/go-zfs/v3/Makefile new file mode 100644 index 000000000..1c5f55e8c --- /dev/null +++ b/vendor/github.com/mistifyio/go-zfs/v3/Makefile @@ -0,0 +1,19 @@ +help: ## Print this help + @grep --no-filename -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sed 's/:.*## /·/' | sort | column -t -W 2 -s '·' -c $(shell tput cols) + +all: test ## Run tests + +-include rules.mk +-include lint.mk + +test: ## Run tests + go test ./... + +verify: gofumpt prettier lint ## Verify code style, is lint free, freshness ... + git diff | (! grep .) + +fix: gofumpt-fix prettier-fix ## Fix code formatting errors + +tools: ${toolsBins} ## Build Go based build tools + +.PHONY: all help test tools verify diff --git a/vendor/github.com/mistifyio/go-zfs/README.md b/vendor/github.com/mistifyio/go-zfs/v3/README.md index fef80d727..c91183300 100644 --- a/vendor/github.com/mistifyio/go-zfs/README.md +++ b/vendor/github.com/mistifyio/go-zfs/v3/README.md @@ -1,12 +1,12 @@ -# Go Wrapper for ZFS # +# Go Wrapper for ZFS Simple wrappers for ZFS command line tools. [![GoDoc](https://godoc.org/github.com/mistifyio/go-zfs?status.svg)](https://godoc.org/github.com/mistifyio/go-zfs) -## Requirements ## +## Requirements -You need a working ZFS setup. To use on Ubuntu 14.04, setup ZFS: +You need a working ZFS setup. To use on Ubuntu 14.04, setup ZFS: sudo apt-get install python-software-properties sudo apt-add-repository ppa:zfs-native/stable @@ -17,13 +17,13 @@ Developed using Go 1.3, but currently there isn't anything 1.3 specific. Don't u Generally you need root privileges to use anything zfs related. -## Status ## +## Status This has been only been tested on Ubuntu 14.04 In the future, we hope to work directly with libzfs. -# Hacking # +# Hacking The tests have decent examples for most functions. @@ -48,7 +48,6 @@ err := f.Destroy() ``` -# Contributing # +# Contributing See the [contributing guidelines](./CONTRIBUTING.md) - diff --git a/vendor/github.com/mistifyio/go-zfs/v3/Vagrantfile b/vendor/github.com/mistifyio/go-zfs/v3/Vagrantfile new file mode 100644 index 000000000..7d8d2decd --- /dev/null +++ b/vendor/github.com/mistifyio/go-zfs/v3/Vagrantfile @@ -0,0 +1,33 @@ +GOVERSION = "1.17.8" + +Vagrant.configure("2") do |config| + config.vm.define "ubuntu" do |ubuntu| + ubuntu.vm.box = "generic/ubuntu2004" + end + config.vm.define "freebsd" do |freebsd| + freebsd.vm.box = "generic/freebsd13" + end + config.ssh.forward_agent = true + config.vm.synced_folder ".", "/home/vagrant/go/src/github.com/mistifyio/go-zfs", create: true + config.vm.provision "shell", inline: <<-EOF + set -euxo pipefail + + os=$(uname -s|tr '[A-Z]' '[a-z]') + case $os in + linux) apt-get update -y && apt-get install -y --no-install-recommends gcc libc-dev zfsutils-linux ;; + esac + + cd /tmp + curl -fLO --retry-max-time 30 --retry 10 https://go.dev/dl/go#{GOVERSION}.$os-amd64.tar.gz + tar -C /usr/local -zxf go#{GOVERSION}.$os-amd64.tar.gz + ln -nsf /usr/local/go/bin/go /usr/local/bin/go + rm -rf go*.tar.gz + + chown -R vagrant:vagrant /home/vagrant/go + cd /home/vagrant/go/src/github.com/mistifyio/go-zfs + go test -c + sudo ./go-zfs.test -test.v + CGO_ENABLED=0 go test -c + sudo ./go-zfs.test -test.v + EOF +end diff --git a/vendor/github.com/mistifyio/go-zfs/error.go b/vendor/github.com/mistifyio/go-zfs/v3/error.go index 5408ccdb5..5408ccdb5 100644 --- a/vendor/github.com/mistifyio/go-zfs/error.go +++ b/vendor/github.com/mistifyio/go-zfs/v3/error.go diff --git a/vendor/github.com/mistifyio/go-zfs/v3/lint.mk b/vendor/github.com/mistifyio/go-zfs/v3/lint.mk new file mode 100644 index 000000000..a1e0a4fd3 --- /dev/null +++ b/vendor/github.com/mistifyio/go-zfs/v3/lint.mk @@ -0,0 +1,75 @@ +# BEGIN: lint-install -makefile lint.mk . +# http://github.com/tinkerbell/lint-install + +.PHONY: lint +lint: _lint + +LINT_ARCH := $(shell uname -m) +LINT_OS := $(shell uname) +LINT_OS_LOWER := $(shell echo $(LINT_OS) | tr '[:upper:]' '[:lower:]') +LINT_ROOT := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) + +# shellcheck and hadolint lack arm64 native binaries: rely on x86-64 emulation +ifeq ($(LINT_OS),Darwin) + ifeq ($(LINT_ARCH),arm64) + LINT_ARCH=x86_64 + endif +endif + +LINTERS := +FIXERS := + +SHELLCHECK_VERSION ?= v0.8.0 +SHELLCHECK_BIN := out/linters/shellcheck-$(SHELLCHECK_VERSION)-$(LINT_ARCH) +$(SHELLCHECK_BIN): + mkdir -p out/linters + rm -rf out/linters/shellcheck-* + curl -sSfL https://github.com/koalaman/shellcheck/releases/download/$(SHELLCHECK_VERSION)/shellcheck-$(SHELLCHECK_VERSION).$(LINT_OS_LOWER).$(LINT_ARCH).tar.xz | tar -C out/linters -xJf - + mv out/linters/shellcheck-$(SHELLCHECK_VERSION)/shellcheck $@ + rm -rf out/linters/shellcheck-$(SHELLCHECK_VERSION)/shellcheck + +LINTERS += shellcheck-lint +shellcheck-lint: $(SHELLCHECK_BIN) + $(SHELLCHECK_BIN) $(shell find . -name "*.sh") + +FIXERS += shellcheck-fix +shellcheck-fix: $(SHELLCHECK_BIN) + $(SHELLCHECK_BIN) $(shell find . -name "*.sh") -f diff | { read -t 1 line || exit 0; { echo "$$line" && cat; } | git apply -p2; } + +GOLANGCI_LINT_CONFIG := $(LINT_ROOT)/.golangci.yml +GOLANGCI_LINT_VERSION ?= v1.43.0 +GOLANGCI_LINT_BIN := out/linters/golangci-lint-$(GOLANGCI_LINT_VERSION)-$(LINT_ARCH) +$(GOLANGCI_LINT_BIN): + mkdir -p out/linters + rm -rf out/linters/golangci-lint-* + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b out/linters $(GOLANGCI_LINT_VERSION) + mv out/linters/golangci-lint $@ + +LINTERS += golangci-lint-lint +golangci-lint-lint: $(GOLANGCI_LINT_BIN) + find . -name go.mod -execdir "$(GOLANGCI_LINT_BIN)" run -c "$(GOLINT_CONFIG)" \; + +FIXERS += golangci-lint-fix +golangci-lint-fix: $(GOLANGCI_LINT_BIN) + find . -name go.mod -execdir "$(GOLANGCI_LINT_BIN)" run -c "$(GOLINT_CONFIG)" --fix \; + +YAMLLINT_VERSION ?= 1.26.3 +YAMLLINT_ROOT := out/linters/yamllint-$(YAMLLINT_VERSION) +YAMLLINT_BIN := $(YAMLLINT_ROOT)/dist/bin/yamllint +$(YAMLLINT_BIN): + mkdir -p out/linters + rm -rf out/linters/yamllint-* + curl -sSfL https://github.com/adrienverge/yamllint/archive/refs/tags/v$(YAMLLINT_VERSION).tar.gz | tar -C out/linters -zxf - + cd $(YAMLLINT_ROOT) && pip3 install --target dist . + +LINTERS += yamllint-lint +yamllint-lint: $(YAMLLINT_BIN) + PYTHONPATH=$(YAMLLINT_ROOT)/dist $(YAMLLINT_ROOT)/dist/bin/yamllint . + +.PHONY: _lint $(LINTERS) +_lint: $(LINTERS) + +.PHONY: fix $(FIXERS) +fix: $(FIXERS) + +# END: lint-install -makefile lint.mk . diff --git a/vendor/github.com/mistifyio/go-zfs/v3/rules.mk b/vendor/github.com/mistifyio/go-zfs/v3/rules.mk new file mode 100644 index 000000000..4746c978a --- /dev/null +++ b/vendor/github.com/mistifyio/go-zfs/v3/rules.mk @@ -0,0 +1,49 @@ +# Only use the recipes defined in these makefiles +MAKEFLAGS += --no-builtin-rules +.SUFFIXES: +# Delete target files if there's an error +# This avoids a failure to then skip building on next run if the output is created by shell redirection for example +# Not really necessary for now, but just good to have already if it becomes necessary later. +.DELETE_ON_ERROR: +# Treat the whole recipe as a one shell script/invocation instead of one-per-line +.ONESHELL: +# Use bash instead of plain sh +SHELL := bash +.SHELLFLAGS := -o pipefail -euc + +version := $(shell git rev-parse --short HEAD) +tag := $(shell git tag --points-at HEAD) +ifneq (,$(tag)) +version := $(tag)-$(version) +endif +LDFLAGS := -ldflags "-X main.version=$(version)" +export CGO_ENABLED := 0 + +ifeq ($(origin GOBIN), undefined) +GOBIN := ${PWD}/bin +export GOBIN +PATH := ${GOBIN}:${PATH} +export PATH +endif + +toolsBins := $(addprefix bin/,$(notdir $(shell grep '^\s*_' tooling/tools.go | awk -F'"' '{print $$2}'))) + +# installs cli tools defined in tools.go +$(toolsBins): tooling/go.mod tooling/go.sum tooling/tools.go +$(toolsBins): CMD=$(shell awk -F'"' '/$(@F)"/ {print $$2}' tooling/tools.go) +$(toolsBins): + cd tooling && go install $(CMD) + +.PHONY: gofumpt +gofumpt: bin/gofumpt + gofumpt -s -d . + +gofumpt-fix: bin/gofumpt + gofumpt -s -w . + +.PHONY: prettier prettier-fix +prettier: + prettier --list-different --ignore-path .gitignore . + +prettier-fix: + prettier --write --ignore-path .gitignore . diff --git a/vendor/github.com/mistifyio/go-zfs/v3/shell.nix b/vendor/github.com/mistifyio/go-zfs/v3/shell.nix new file mode 100644 index 000000000..e0ea24c16 --- /dev/null +++ b/vendor/github.com/mistifyio/go-zfs/v3/shell.nix @@ -0,0 +1,26 @@ +let _pkgs = import <nixpkgs> { }; +in { pkgs ? import (_pkgs.fetchFromGitHub { + owner = "NixOS"; + repo = "nixpkgs"; + #branch@date: 21.11@2022-02-13 + rev = "560ad8a2f89586ab1a14290f128ad6a393046065"; + sha256 = "0s0dv1clfpjyzy4p6ywxvzmwx9ddbr2yl77jf1wqdbr0x1206hb8"; +}) { } }: + +with pkgs; + +mkShell { + buildInputs = [ + git + gnumake + gnused + go + nixfmt + nodePackages.prettier + python3Packages.pip + python3Packages.setuptools + rufo + shfmt + vagrant + ]; +} diff --git a/vendor/github.com/mistifyio/go-zfs/utils.go b/vendor/github.com/mistifyio/go-zfs/v3/utils.go index c18c2c3da..0c2cce7d9 100644 --- a/vendor/github.com/mistifyio/go-zfs/utils.go +++ b/vendor/github.com/mistifyio/go-zfs/v3/utils.go @@ -21,7 +21,6 @@ type command struct { } func (c *command) Run(arg ...string) ([][]string, error) { - cmd := exec.Command(c.Command, arg...) var stdout, stderr bytes.Buffer @@ -34,7 +33,6 @@ func (c *command) Run(arg ...string) ([][]string, error) { if c.Stdin != nil { cmd.Stdin = c.Stdin - } cmd.Stderr = &stderr @@ -42,16 +40,14 @@ func (c *command) Run(arg ...string) ([][]string, error) { joinedArgs := strings.Join(cmd.Args, " ") logger.Log([]string{"ID:" + id, "START", joinedArgs}) - err := cmd.Run() - logger.Log([]string{"ID:" + id, "FINISH"}) - - if err != nil { + if err := cmd.Run(); err != nil { return nil, &Error{ Err: err, Debug: strings.Join([]string{cmd.Path, joinedArgs[1:]}, " "), Stderr: stderr.String(), } } + logger.Log([]string{"ID:" + id, "FINISH"}) // assume if you passed in something for stdout, that you know what to do with it if c.Stdout != nil { @@ -60,7 +56,7 @@ func (c *command) Run(arg ...string) ([][]string, error) { lines := strings.Split(stdout.String(), "\n") - //last line is always blank + // last line is always blank lines = lines[0 : len(lines)-1] output := make([][]string, len(lines)) @@ -92,33 +88,33 @@ func setUint(field *uint64, value string) error { return nil } -func (ds *Dataset) parseLine(line []string) error { +func (d *Dataset) parseLine(line []string) error { var err error if len(line) != len(dsPropList) { - return errors.New("Output does not match what is expected on this platform") + return errors.New("output does not match what is expected on this platform") } - setString(&ds.Name, line[0]) - setString(&ds.Origin, line[1]) + setString(&d.Name, line[0]) + setString(&d.Origin, line[1]) - if err = setUint(&ds.Used, line[2]); err != nil { + if err = setUint(&d.Used, line[2]); err != nil { return err } - if err = setUint(&ds.Avail, line[3]); err != nil { + if err = setUint(&d.Avail, line[3]); err != nil { return err } - setString(&ds.Mountpoint, line[4]) - setString(&ds.Compression, line[5]) - setString(&ds.Type, line[6]) + setString(&d.Mountpoint, line[4]) + setString(&d.Compression, line[5]) + setString(&d.Type, line[6]) - if err = setUint(&ds.Volsize, line[7]); err != nil { + if err = setUint(&d.Volsize, line[7]); err != nil { return err } - if err = setUint(&ds.Quota, line[8]); err != nil { + if err = setUint(&d.Quota, line[8]); err != nil { return err } - if err = setUint(&ds.Referenced, line[9]); err != nil { + if err = setUint(&d.Referenced, line[9]); err != nil { return err } @@ -126,17 +122,13 @@ func (ds *Dataset) parseLine(line []string) error { return nil } - if err = setUint(&ds.Written, line[10]); err != nil { + if err = setUint(&d.Written, line[10]); err != nil { return err } - if err = setUint(&ds.Logicalused, line[11]); err != nil { + if err = setUint(&d.Logicalused, line[11]); err != nil { return err } - if err = setUint(&ds.Usedbydataset, line[12]); err != nil { - return err - } - - return nil + return setUint(&d.Usedbydataset, line[12]) } /* @@ -156,12 +148,12 @@ func unescapeFilepath(path string) (string, error) { for i := 0; i < llen; { if path[i] == '\\' { if llen < i+4 { - return "", fmt.Errorf("Invalid octal code: too short") + return "", fmt.Errorf("invalid octal code: too short") } octalCode := path[(i + 1):(i + 4)] val, err := strconv.ParseUint(octalCode, 8, 8) if err != nil { - return "", fmt.Errorf("Invalid octal code: %v", err) + return "", fmt.Errorf("invalid octal code: %w", err) } buf = append(buf, byte(val)) i += 4 @@ -179,6 +171,7 @@ var changeTypeMap = map[string]ChangeType{ "M": Modified, "R": Renamed, } + var inodeTypeMap = map[string]InodeType{ "B": BlockDevice, "C": CharacterDevice, @@ -191,51 +184,51 @@ var inodeTypeMap = map[string]InodeType{ "F": File, } -// matches (+1) or (-1) -var referenceCountRegex = regexp.MustCompile("\\(([+-]\\d+?)\\)") +// matches (+1) or (-1). +var referenceCountRegex = regexp.MustCompile(`\(([+-]\d+?)\)`) func parseReferenceCount(field string) (int, error) { matches := referenceCountRegex.FindStringSubmatch(field) if matches == nil { - return 0, fmt.Errorf("Regexp does not match") + return 0, fmt.Errorf("regexp does not match") } return strconv.Atoi(matches[1]) } func parseInodeChange(line []string) (*InodeChange, error) { - llen := len(line) + llen := len(line) // nolint:ifshort // llen *is* actually used if llen < 1 { - return nil, fmt.Errorf("Empty line passed") + return nil, fmt.Errorf("empty line passed") } changeType := changeTypeMap[line[0]] if changeType == 0 { - return nil, fmt.Errorf("Unknown change type '%s'", line[0]) + return nil, fmt.Errorf("unknown change type '%s'", line[0]) } switch changeType { case Renamed: if llen != 4 { - return nil, fmt.Errorf("Mismatching number of fields: expect 4, got: %d", llen) + return nil, fmt.Errorf("mismatching number of fields: expect 4, got: %d", llen) } case Modified: if llen != 4 && llen != 3 { - return nil, fmt.Errorf("Mismatching number of fields: expect 3..4, got: %d", llen) + return nil, fmt.Errorf("mismatching number of fields: expect 3..4, got: %d", llen) } default: if llen != 3 { - return nil, fmt.Errorf("Mismatching number of fields: expect 3, got: %d", llen) + return nil, fmt.Errorf("mismatching number of fields: expect 3, got: %d", llen) } } inodeType := inodeTypeMap[line[1]] if inodeType == 0 { - return nil, fmt.Errorf("Unknown inode type '%s'", line[1]) + return nil, fmt.Errorf("unknown inode type '%s'", line[1]) } path, err := unescapeFilepath(line[2]) if err != nil { - return nil, fmt.Errorf("Failed to parse filename: %v", err) + return nil, fmt.Errorf("failed to parse filename: %w", err) } var newPath string @@ -244,13 +237,13 @@ func parseInodeChange(line []string) (*InodeChange, error) { case Renamed: newPath, err = unescapeFilepath(line[3]) if err != nil { - return nil, fmt.Errorf("Failed to parse filename: %v", err) + return nil, fmt.Errorf("failed to parse filename: %w", err) } case Modified: if llen == 4 { referenceCount, err = parseReferenceCount(line[3]) if err != nil { - return nil, fmt.Errorf("Failed to parse reference count: %v", err) + return nil, fmt.Errorf("failed to parse reference count: %w", err) } } default: @@ -266,18 +259,19 @@ func parseInodeChange(line []string) (*InodeChange, error) { }, nil } -// example input -//M / /testpool/bar/ -//+ F /testpool/bar/hello.txt -//M / /testpool/bar/hello.txt (+1) -//M / /testpool/bar/hello-hardlink +// example input for parseInodeChanges +// M / /testpool/bar/ +// + F /testpool/bar/hello.txt +// M / /testpool/bar/hello.txt (+1) +// M / /testpool/bar/hello-hardlink + func parseInodeChanges(lines [][]string) ([]*InodeChange, error) { changes := make([]*InodeChange, len(lines)) for i, line := range lines { c, err := parseInodeChange(line) if err != nil { - return nil, fmt.Errorf("Failed to parse line %d of zfs diff: %v, got: '%s'", i, err, line) + return nil, fmt.Errorf("failed to parse line %d of zfs diff: %w, got: '%s'", i, err, line) } changes[i] = c } @@ -290,7 +284,7 @@ func listByType(t, filter string) ([]*Dataset, error) { if filter != "" { args = append(args, filter) } - out, err := zfs(args...) + out, err := zfsOutput(args...) if err != nil { return nil, err } diff --git a/vendor/github.com/mistifyio/go-zfs/v3/utils_notsolaris.go b/vendor/github.com/mistifyio/go-zfs/v3/utils_notsolaris.go new file mode 100644 index 000000000..ef1beac90 --- /dev/null +++ b/vendor/github.com/mistifyio/go-zfs/v3/utils_notsolaris.go @@ -0,0 +1,19 @@ +//go:build !solaris +// +build !solaris + +package zfs + +import "strings" + +var ( + // List of ZFS properties to retrieve from zfs list command on a non-Solaris platform. + dsPropList = []string{"name", "origin", "used", "available", "mountpoint", "compression", "type", "volsize", "quota", "referenced", "written", "logicalused", "usedbydataset"} + + dsPropListOptions = strings.Join(dsPropList, ",") + + // List of Zpool properties to retrieve from zpool list command on a non-Solaris platform. + zpoolPropList = []string{"name", "health", "allocated", "size", "free", "readonly", "dedupratio", "fragmentation", "freeing", "leaked"} + + zpoolPropListOptions = strings.Join(zpoolPropList, ",") + zpoolArgs = []string{"get", "-p", zpoolPropListOptions} +) diff --git a/vendor/github.com/mistifyio/go-zfs/v3/utils_solaris.go b/vendor/github.com/mistifyio/go-zfs/v3/utils_solaris.go new file mode 100644 index 000000000..c6bf6d87a --- /dev/null +++ b/vendor/github.com/mistifyio/go-zfs/v3/utils_solaris.go @@ -0,0 +1,19 @@ +//go:build solaris +// +build solaris + +package zfs + +import "strings" + +var ( + // List of ZFS properties to retrieve from zfs list command on a Solaris platform + dsPropList = []string{"name", "origin", "used", "available", "mountpoint", "compression", "type", "volsize", "quota", "referenced"} + + dsPropListOptions = strings.Join(dsPropList, ",") + + // List of Zpool properties to retrieve from zpool list command on a non-Solaris platform + zpoolPropList = []string{"name", "health", "allocated", "size", "free", "readonly", "dedupratio"} + + zpoolPropListOptions = strings.Join(zpoolPropList, ",") + zpoolArgs = []string{"get", "-p", zpoolPropListOptions} +) diff --git a/vendor/github.com/mistifyio/go-zfs/zfs.go b/vendor/github.com/mistifyio/go-zfs/v3/zfs.go index 4e5087ffe..1166bdc21 100644 --- a/vendor/github.com/mistifyio/go-zfs/zfs.go +++ b/vendor/github.com/mistifyio/go-zfs/v3/zfs.go @@ -9,19 +9,18 @@ import ( "strings" ) -// ZFS dataset types, which can indicate if a dataset is a filesystem, -// snapshot, or volume. +// ZFS dataset types, which can indicate if a dataset is a filesystem, snapshot, or volume. const ( DatasetFilesystem = "filesystem" DatasetSnapshot = "snapshot" DatasetVolume = "volume" ) -// Dataset is a ZFS dataset. A dataset could be a clone, filesystem, snapshot, -// or volume. The Type struct member can be used to determine a dataset's type. +// Dataset is a ZFS dataset. A dataset could be a clone, filesystem, snapshot, or volume. +// The Type struct member can be used to determine a dataset's type. // // The field definitions can be found in the ZFS manual: -// http://www.freebsd.org/cgi/man.cgi?zfs(8). +// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. type Dataset struct { Name string Origin string @@ -38,10 +37,10 @@ type Dataset struct { Referenced uint64 } -// InodeType is the type of inode as reported by Diff +// InodeType is the type of inode as reported by Diff. type InodeType int -// Types of Inodes +// Types of Inodes. const ( _ = iota // 0 == unknown type BlockDevice InodeType = iota @@ -55,10 +54,10 @@ const ( File ) -// ChangeType is the type of inode change as reported by Diff +// ChangeType is the type of inode change as reported by Diff. type ChangeType int -// Types of Changes +// Types of Changes. const ( _ = iota // 0 == unknown type Removed ChangeType = iota @@ -67,10 +66,10 @@ const ( Renamed ) -// DestroyFlag is the options flag passed to Destroy +// DestroyFlag is the options flag passed to Destroy. type DestroyFlag int -// Valid destroy options +// Valid destroy options. const ( DestroyDefault DestroyFlag = 1 << iota DestroyRecursive = 1 << iota @@ -79,7 +78,7 @@ const ( DestroyForceUmount = 1 << iota ) -// InodeChange represents a change as reported by Diff +// InodeChange represents a change as reported by Diff. type InodeChange struct { Change ChangeType Type InodeType @@ -88,65 +87,65 @@ type InodeChange struct { ReferenceCountChange int } -// Logger can be used to log commands/actions +// Logger can be used to log commands/actions. type Logger interface { Log(cmd []string) } type defaultLogger struct{} -func (*defaultLogger) Log(cmd []string) { - return +func (*defaultLogger) Log([]string) { } var logger Logger = &defaultLogger{} -// SetLogger set a log handler to log all commands including arguments before -// they are executed +// SetLogger set a log handler to log all commands including arguments before they are executed. func SetLogger(l Logger) { if l != nil { logger = l } } +// zfs is a helper function to wrap typical calls to zfs that ignores stdout. +func zfs(arg ...string) error { + _, err := zfsOutput(arg...) + return err +} + // zfs is a helper function to wrap typical calls to zfs. -func zfs(arg ...string) ([][]string, error) { +func zfsOutput(arg ...string) ([][]string, error) { c := command{Command: "zfs"} return c.Run(arg...) } // Datasets returns a slice of ZFS datasets, regardless of type. -// A filter argument may be passed to select a dataset with the matching name, -// or empty string ("") may be used to select all datasets. +// A filter argument may be passed to select a dataset with the matching name, or empty string ("") may be used to select all datasets. func Datasets(filter string) ([]*Dataset, error) { return listByType("all", filter) } // Snapshots returns a slice of ZFS snapshots. -// A filter argument may be passed to select a snapshot with the matching name, -// or empty string ("") may be used to select all snapshots. +// A filter argument may be passed to select a snapshot with the matching name, or empty string ("") may be used to select all snapshots. func Snapshots(filter string) ([]*Dataset, error) { return listByType(DatasetSnapshot, filter) } // Filesystems returns a slice of ZFS filesystems. -// A filter argument may be passed to select a filesystem with the matching name, -// or empty string ("") may be used to select all filesystems. +// A filter argument may be passed to select a filesystem with the matching name, or empty string ("") may be used to select all filesystems. func Filesystems(filter string) ([]*Dataset, error) { return listByType(DatasetFilesystem, filter) } // Volumes returns a slice of ZFS volumes. -// A filter argument may be passed to select a volume with the matching name, -// or empty string ("") may be used to select all volumes. +// A filter argument may be passed to select a volume with the matching name, or empty string ("") may be used to select all volumes. func Volumes(filter string) ([]*Dataset, error) { return listByType(DatasetVolume, filter) } -// GetDataset retrieves a single ZFS dataset by name. This dataset could be -// any valid ZFS dataset type, such as a clone, filesystem, snapshot, or volume. +// GetDataset retrieves a single ZFS dataset by name. +// This dataset could be any valid ZFS dataset type, such as a clone, filesystem, snapshot, or volume. func GetDataset(name string) (*Dataset, error) { - out, err := zfs("list", "-Hp", "-o", dsPropListOptions, name) + out, err := zfsOutput("list", "-Hp", "-o", dsPropListOptions, name) if err != nil { return nil, err } @@ -174,8 +173,7 @@ func (d *Dataset) Clone(dest string, properties map[string]string) (*Dataset, er args = append(args, propsSlice(properties)...) } args = append(args, []string{d.Name, dest}...) - _, err := zfs(args...) - if err != nil { + if err := zfs(args...); err != nil { return nil, err } return GetDataset(dest) @@ -192,8 +190,7 @@ func (d *Dataset) Unmount(force bool) (*Dataset, error) { args = append(args, "-f") } args = append(args, d.Name) - _, err := zfs(args...) - if err != nil { + if err := zfs(args...); err != nil { return nil, err } return GetDataset(d.Name) @@ -214,20 +211,17 @@ func (d *Dataset) Mount(overlay bool, options []string) (*Dataset, error) { args = append(args, strings.Join(options, ",")) } args = append(args, d.Name) - _, err := zfs(args...) - if err != nil { + if err := zfs(args...); err != nil { return nil, err } return GetDataset(d.Name) } -// ReceiveSnapshot receives a ZFS stream from the input io.Reader, creates a -// new snapshot with the specified name, and streams the input data into the -// newly-created snapshot. +// ReceiveSnapshot receives a ZFS stream from the input io.Reader. +// A new snapshot is created with the specified name, and streams the input data into the newly-created snapshot. func ReceiveSnapshot(input io.Reader, name string) (*Dataset, error) { c := command{Command: "zfs", Stdin: input} - _, err := c.Run("receive", name) - if err != nil { + if _, err := c.Run("receive", name); err != nil { return nil, err } return GetDataset(name) @@ -245,10 +239,21 @@ func (d *Dataset) SendSnapshot(output io.Writer) error { return err } -// CreateVolume creates a new ZFS volume with the specified name, size, and -// properties. -// A full list of available ZFS properties may be found here: -// https://www.freebsd.org/cgi/man.cgi?zfs(8). +// IncrementalSend sends a ZFS stream of a snapshot to the input io.Writer using the baseSnapshot as the starting point. +// An error will be returned if the input dataset is not of snapshot type. +func (d *Dataset) IncrementalSend(baseSnapshot *Dataset, output io.Writer) error { + if d.Type != DatasetSnapshot || baseSnapshot.Type != DatasetSnapshot { + return errors.New("can only send snapshots") + } + c := command{Command: "zfs", Stdout: output} + _, err := c.Run("send", "-i", baseSnapshot.Name, d.Name) + return err +} + +// CreateVolume creates a new ZFS volume with the specified name, size, and properties. +// +// A full list of available ZFS properties may be found in the ZFS manual: +// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. func CreateVolume(name string, size uint64, properties map[string]string) (*Dataset, error) { args := make([]string, 4, 5) args[0] = "create" @@ -259,17 +264,15 @@ func CreateVolume(name string, size uint64, properties map[string]string) (*Data args = append(args, propsSlice(properties)...) } args = append(args, name) - _, err := zfs(args...) - if err != nil { + if err := zfs(args...); err != nil { return nil, err } return GetDataset(name) } -// Destroy destroys a ZFS dataset. If the destroy bit flag is set, any -// descendents of the dataset will be recursively destroyed, including snapshots. -// If the deferred bit flag is set, the snapshot is marked for deferred -// deletion. +// Destroy destroys a ZFS dataset. +// If the destroy bit flag is set, any descendents of the dataset will be recursively destroyed, including snapshots. +// If the deferred bit flag is set, the snapshot is marked for deferred deletion. func (d *Dataset) Destroy(flags DestroyFlag) error { args := make([]string, 1, 3) args[0] = "destroy" @@ -290,25 +293,26 @@ func (d *Dataset) Destroy(flags DestroyFlag) error { } args = append(args, d.Name) - _, err := zfs(args...) + err := zfs(args...) return err } // SetProperty sets a ZFS property on the receiving dataset. -// A full list of available ZFS properties may be found here: -// https://www.freebsd.org/cgi/man.cgi?zfs(8). +// +// A full list of available ZFS properties may be found in the ZFS manual: +// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. func (d *Dataset) SetProperty(key, val string) error { prop := strings.Join([]string{key, val}, "=") - _, err := zfs("set", prop, d.Name) + err := zfs("set", prop, d.Name) return err } -// GetProperty returns the current value of a ZFS property from the -// receiving dataset. -// A full list of available ZFS properties may be found here: -// https://www.freebsd.org/cgi/man.cgi?zfs(8). +// GetProperty returns the current value of a ZFS property from the receiving dataset. +// +// A full list of available ZFS properties may be found in the ZFS manual: +// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. func (d *Dataset) GetProperty(key string) (string, error) { - out, err := zfs("get", "-H", key, d.Name) + out, err := zfsOutput("get", "-H", key, d.Name) if err != nil { return "", err } @@ -317,7 +321,7 @@ func (d *Dataset) GetProperty(key string) (string, error) { } // Rename renames a dataset. -func (d *Dataset) Rename(name string, createParent bool, recursiveRenameSnapshots bool) (*Dataset, error) { +func (d *Dataset) Rename(name string, createParent, recursiveRenameSnapshots bool) (*Dataset, error) { args := make([]string, 3, 5) args[0] = "rename" args[1] = d.Name @@ -328,8 +332,7 @@ func (d *Dataset) Rename(name string, createParent bool, recursiveRenameSnapshot if recursiveRenameSnapshots { args = append(args, "-r") } - _, err := zfs(args...) - if err != nil { + if err := zfs(args...); err != nil { return d, err } @@ -341,10 +344,10 @@ func (d *Dataset) Snapshots() ([]*Dataset, error) { return Snapshots(d.Name) } -// CreateFilesystem creates a new ZFS filesystem with the specified name and -// properties. -// A full list of available ZFS properties may be found here: -// https://www.freebsd.org/cgi/man.cgi?zfs(8). +// CreateFilesystem creates a new ZFS filesystem with the specified name and properties. +// +// A full list of available ZFS properties may be found in the ZFS manual: +// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. func CreateFilesystem(name string, properties map[string]string) (*Dataset, error) { args := make([]string, 1, 4) args[0] = "create" @@ -354,16 +357,14 @@ func CreateFilesystem(name string, properties map[string]string) (*Dataset, erro } args = append(args, name) - _, err := zfs(args...) - if err != nil { + if err := zfs(args...); err != nil { return nil, err } return GetDataset(name) } -// Snapshot creates a new ZFS snapshot of the receiving dataset, using the -// specified name. Optionally, the snapshot can be taken recursively, creating -// snapshots of all descendent filesystems in a single, atomic operation. +// Snapshot creates a new ZFS snapshot of the receiving dataset, using the specified name. +// Optionally, the snapshot can be taken recursively, creating snapshots of all descendent filesystems in a single, atomic operation. func (d *Dataset) Snapshot(name string, recursive bool) (*Dataset, error) { args := make([]string, 1, 4) args[0] = "snapshot" @@ -372,17 +373,15 @@ func (d *Dataset) Snapshot(name string, recursive bool) (*Dataset, error) { } snapName := fmt.Sprintf("%s@%s", d.Name, name) args = append(args, snapName) - _, err := zfs(args...) - if err != nil { + if err := zfs(args...); err != nil { return nil, err } return GetDataset(snapName) } // Rollback rolls back the receiving ZFS dataset to a previous snapshot. -// Optionally, intermediate snapshots can be destroyed. A ZFS snapshot -// rollback cannot be completed without this option, if more recent -// snapshots exist. +// Optionally, intermediate snapshots can be destroyed. +// A ZFS snapshot rollback cannot be completed without this option, if more recent snapshots exist. // An error will be returned if the input dataset is not of snapshot type. func (d *Dataset) Rollback(destroyMoreRecent bool) error { if d.Type != DatasetSnapshot { @@ -396,13 +395,12 @@ func (d *Dataset) Rollback(destroyMoreRecent bool) error { } args = append(args, d.Name) - _, err := zfs(args...) + err := zfs(args...) return err } // Children returns a slice of children of the receiving ZFS dataset. -// A recursion depth may be specified, or a depth of 0 allows unlimited -// recursion. +// A recursion depth may be specified, or a depth of 0 allows unlimited recursion. func (d *Dataset) Children(depth uint64) ([]*Dataset, error) { args := []string{"list"} if depth > 0 { @@ -414,7 +412,7 @@ func (d *Dataset) Children(depth uint64) ([]*Dataset, error) { args = append(args, "-t", "all", "-Hp", "-o", dsPropListOptions) args = append(args, d.Name) - out, err := zfs(args...) + out, err := zfsOutput(args...) if err != nil { return nil, err } @@ -436,11 +434,10 @@ func (d *Dataset) Children(depth uint64) ([]*Dataset, error) { } // Diff returns changes between a snapshot and the given ZFS dataset. -// The snapshot name must include the filesystem part as it is possible to -// compare clones with their origin snapshots. +// The snapshot name must include the filesystem part as it is possible to compare clones with their origin snapshots. func (d *Dataset) Diff(snapshot string) ([]*InodeChange, error) { - args := []string{"diff", "-FH", snapshot, d.Name}[:] - out, err := zfs(args...) + args := []string{"diff", "-FH", snapshot, d.Name} + out, err := zfsOutput(args...) if err != nil { return nil, err } diff --git a/vendor/github.com/mistifyio/go-zfs/zpool.go b/vendor/github.com/mistifyio/go-zfs/v3/zpool.go index d8db945d7..2f7071305 100644 --- a/vendor/github.com/mistifyio/go-zfs/zpool.go +++ b/vendor/github.com/mistifyio/go-zfs/v3/zpool.go @@ -1,8 +1,9 @@ package zfs -// ZFS zpool states, which can indicate if a pool is online, offline, -// degraded, etc. More information regarding zpool states can be found here: -// https://docs.oracle.com/cd/E19253-01/819-5461/gamno/index.html. +// ZFS zpool states, which can indicate if a pool is online, offline, degraded, etc. +// +// More information regarding zpool states can be found in the ZFS manual: +// https://openzfs.github.io/openzfs-docs/man/7/zpoolconcepts.7.html#Device_Failure_and_Recovery const ( ZpoolOnline = "ONLINE" ZpoolDegraded = "DEGRADED" @@ -12,8 +13,8 @@ const ( ZpoolRemoved = "REMOVED" ) -// Zpool is a ZFS zpool. A pool is a top-level structure in ZFS, and can -// contain many descendent datasets. +// Zpool is a ZFS zpool. +// A pool is a top-level structure in ZFS, and can contain many descendent datasets. type Zpool struct { Name string Health string @@ -27,8 +28,14 @@ type Zpool struct { DedupRatio float64 } +// zpool is a helper function to wrap typical calls to zpool and ignores stdout. +func zpool(arg ...string) error { + _, err := zpoolOutput(arg...) + return err +} + // zpool is a helper function to wrap typical calls to zpool. -func zpool(arg ...string) ([][]string, error) { +func zpoolOutput(arg ...string) ([][]string, error) { c := command{Command: "zpool"} return c.Run(arg...) } @@ -37,7 +44,7 @@ func zpool(arg ...string) ([][]string, error) { func GetZpool(name string) (*Zpool, error) { args := zpoolArgs args = append(args, name) - out, err := zpool(args...) + out, err := zpoolOutput(args...) if err != nil { return nil, err } @@ -65,10 +72,11 @@ func (z *Zpool) Snapshots() ([]*Dataset, error) { return Snapshots(z.Name) } -// CreateZpool creates a new ZFS zpool with the specified name, properties, -// and optional arguments. -// A full list of available ZFS properties and command-line arguments may be -// found here: https://www.freebsd.org/cgi/man.cgi?zfs(8). +// CreateZpool creates a new ZFS zpool with the specified name, properties, and optional arguments. +// +// A full list of available ZFS properties and command-line arguments may be found in the ZFS manual: +// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. +// https://openzfs.github.io/openzfs-docs/man/8/zpool-create.8.html func CreateZpool(name string, properties map[string]string, args ...string) (*Zpool, error) { cli := make([]string, 1, 4) cli[0] = "create" @@ -77,8 +85,7 @@ func CreateZpool(name string, properties map[string]string, args ...string) (*Zp } cli = append(cli, name) cli = append(cli, args...) - _, err := zpool(cli...) - if err != nil { + if err := zpool(cli...); err != nil { return nil, err } @@ -87,14 +94,14 @@ func CreateZpool(name string, properties map[string]string, args ...string) (*Zp // Destroy destroys a ZFS zpool by name. func (z *Zpool) Destroy() error { - _, err := zpool("destroy", z.Name) + err := zpool("destroy", z.Name) return err } // ListZpools list all ZFS zpools accessible on the current system. func ListZpools() ([]*Zpool, error) { args := []string{"list", "-Ho", "name"} - out, err := zpool(args...) + out, err := zpoolOutput(args...) if err != nil { return nil, err } diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go index 581cf7cdf..6f9e6fd3a 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go @@ -59,4 +59,13 @@ const ( // AnnotationBaseImageName is the annotation key for the image reference of the image's base image. AnnotationBaseImageName = "org.opencontainers.image.base.name" + + // AnnotationArtifactCreated is the annotation key for the date and time on which the artifact was built, conforming to RFC 3339. + AnnotationArtifactCreated = "org.opencontainers.artifact.created" + + // AnnotationArtifactDescription is the annotation key for the human readable description for the artifact. + AnnotationArtifactDescription = "org.opencontainers.artifact.description" + + // AnnotationReferrersFiltersApplied is the annotation key for the comma separated list of filters applied by the registry in the referrers listing. + AnnotationReferrersFiltersApplied = "org.opencontainers.referrers.filtersApplied" ) diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/artifact.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/artifact.go new file mode 100644 index 000000000..2a18ce106 --- /dev/null +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/artifact.go @@ -0,0 +1,34 @@ +// Copyright 2022 The Linux Foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +// Artifact describes an artifact manifest. +// This structure provides `application/vnd.oci.artifact.manifest.v1+json` mediatype when marshalled to JSON. +type Artifact struct { + // MediaType is the media type of the object this schema refers to. + MediaType string `json:"mediaType"` + + // ArtifactType is the IANA media type of the artifact this schema refers to. + ArtifactType string `json:"artifactType"` + + // Blobs is a collection of blobs referenced by this manifest. + Blobs []Descriptor `json:"blobs,omitempty"` + + // Refers is an optional link to any existing manifest within the repository. + Refers *Descriptor `json:"refers,omitempty"` + + // Annotations contains arbitrary metadata for the artifact manifest. + Annotations map[string]string `json:"annotations,omitempty"` +} diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go index 6e442a085..9654aa5af 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go @@ -1,4 +1,4 @@ -// Copyright 2016 The Linux Foundation +// Copyright 2016-2022 The Linux Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,10 +35,18 @@ type Descriptor struct { // Annotations contains arbitrary metadata relating to the targeted content. Annotations map[string]string `json:"annotations,omitempty"` + // Data is an embedding of the targeted content. This is encoded as a base64 + // string when marshalled to JSON (automatically, by encoding/json). If + // present, Data can be used directly to avoid fetching the targeted content. + Data []byte `json:"data,omitempty"` + // Platform describes the platform which the image in the manifest runs on. // // This should only be used when referring to a manifest. Platform *Platform `json:"platform,omitempty"` + + // ArtifactType is the IANA media type of this artifact. + ArtifactType string `json:"artifactType,omitempty"` } // Platform describes the platform which the image in the manifest runs on. diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go index 8212d520c..7f2df9863 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go @@ -1,4 +1,4 @@ -// Copyright 2016 The Linux Foundation +// Copyright 2016-2022 The Linux Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,6 +30,9 @@ type Manifest struct { // Layers is an indexed list of layers referenced by the manifest. Layers []Descriptor `json:"layers"` + // Refers is an optional link to any existing manifest within the repository. + Refers *Descriptor `json:"refers,omitempty"` + // Annotations contains arbitrary metadata for the image manifest. Annotations map[string]string `json:"annotations,omitempty"` } diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go index 4f35ac134..935b481e3 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go @@ -54,4 +54,7 @@ const ( // MediaTypeImageConfig specifies the media type for the image configuration. MediaTypeImageConfig = "application/vnd.oci.image.config.v1+json" + + // MediaTypeArtifactManifest specifies the media type for a content descriptor. + MediaTypeArtifactManifest = "application/vnd.oci.artifact.manifest.v1+json" ) diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/version.go b/vendor/github.com/opencontainers/image-spec/specs-go/version.go index 31f99cf64..bf4d8cc7e 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/version.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/version.go @@ -20,12 +20,12 @@ const ( // VersionMajor is for an API incompatible changes VersionMajor = 1 // VersionMinor is for functionality in a backwards-compatible manner - VersionMinor = 0 + VersionMinor = 1 // VersionPatch is for backwards-compatible bug fixes - VersionPatch = 2 + VersionPatch = 0 // VersionDev indicates development branch. Releases will be empty string. - VersionDev = "-dev" + VersionDev = "-rc1" ) // Version is the specification version that the package types support. diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/doc.go b/vendor/github.com/opencontainers/selinux/go-selinux/doc.go index 0ac7d819e..57a15c9a1 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/doc.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/doc.go @@ -9,6 +9,5 @@ Usage: if selinux.EnforceMode() != selinux.Enforcing { selinux.SetEnforceMode(selinux.Enforcing) } - */ package selinux diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go index 12de0ae5d..f61a56015 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go @@ -3,8 +3,6 @@ package label import ( "errors" "fmt" - "os" - "os/user" "strings" "github.com/opencontainers/selinux/go-selinux" @@ -113,50 +111,6 @@ func Relabel(path string, fileLabel string, shared bool) error { return nil } - exclude_paths := map[string]bool{ - "/": true, - "/bin": true, - "/boot": true, - "/dev": true, - "/etc": true, - "/etc/passwd": true, - "/etc/pki": true, - "/etc/shadow": true, - "/home": true, - "/lib": true, - "/lib64": true, - "/media": true, - "/opt": true, - "/proc": true, - "/root": true, - "/run": true, - "/sbin": true, - "/srv": true, - "/sys": true, - "/tmp": true, - "/usr": true, - "/var": true, - "/var/lib": true, - "/var/log": true, - } - - if home := os.Getenv("HOME"); home != "" { - exclude_paths[home] = true - } - - if sudoUser := os.Getenv("SUDO_USER"); sudoUser != "" { - if usr, err := user.Lookup(sudoUser); err == nil { - exclude_paths[usr.HomeDir] = true - } - } - - if path != "/" { - path = strings.TrimSuffix(path, "/") - } - if exclude_paths[path] { - return fmt.Errorf("SELinux relabeling of %s is not allowed", path) - } - if shared { c, err := selinux.NewContext(fileLabel) if err != nil { diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go index 02d206239..f21c80c5a 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux package label diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/rchcon.go b/vendor/github.com/opencontainers/selinux/go-selinux/rchcon.go index feb739d32..8bff29355 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/rchcon.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/rchcon.go @@ -1,3 +1,4 @@ +//go:build linux && go1.16 // +build linux,go1.16 package selinux @@ -11,7 +12,18 @@ import ( ) func rchcon(fpath, label string) error { + fastMode := false + // If the current label matches the new label, assume + // other labels are correct. + if cLabel, err := lFileLabel(fpath); err == nil && cLabel == label { + fastMode = true + } return pwalkdir.Walk(fpath, func(p string, _ fs.DirEntry, _ error) error { + if fastMode { + if cLabel, err := lFileLabel(fpath); err == nil && cLabel == label { + return nil + } + } e := lSetFileLabel(p, label) // Walk a file tree can race with removal, so ignore ENOENT. if errors.Is(e, os.ErrNotExist) { diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/rchcon_go115.go b/vendor/github.com/opencontainers/selinux/go-selinux/rchcon_go115.go index ecc7abfac..303cb1890 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/rchcon_go115.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/rchcon_go115.go @@ -1,3 +1,4 @@ +//go:build linux && !go1.16 // +build linux,!go1.16 package selinux diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go index ee602ab96..4582cc9e0 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go @@ -11,6 +11,7 @@ import ( "io/ioutil" "math/big" "os" + "os/user" "path" "path/filepath" "strconv" @@ -1072,21 +1073,6 @@ func copyLevel(src, dest string) (string, error) { return tcon.Get(), nil } -// Prevent users from relabeling system files -func badPrefix(fpath string) error { - if fpath == "" { - return ErrEmptyPath - } - - badPrefixes := []string{"/usr"} - for _, prefix := range badPrefixes { - if strings.HasPrefix(fpath, prefix) { - return fmt.Errorf("relabeling content in %s is not allowed", prefix) - } - } - return nil -} - // chcon changes the fpath file object to the SELinux label label. // If fpath is a directory and recurse is true, then chcon walks the // directory tree setting the label. @@ -1097,12 +1083,70 @@ func chcon(fpath string, label string, recurse bool) error { if label == "" { return nil } - if err := badPrefix(fpath); err != nil { - return err + + exclude_paths := map[string]bool{ + "/": true, + "/bin": true, + "/boot": true, + "/dev": true, + "/etc": true, + "/etc/passwd": true, + "/etc/pki": true, + "/etc/shadow": true, + "/home": true, + "/lib": true, + "/lib64": true, + "/media": true, + "/opt": true, + "/proc": true, + "/root": true, + "/run": true, + "/sbin": true, + "/srv": true, + "/sys": true, + "/tmp": true, + "/usr": true, + "/var": true, + "/var/lib": true, + "/var/log": true, + } + + if home := os.Getenv("HOME"); home != "" { + exclude_paths[home] = true + } + + if sudoUser := os.Getenv("SUDO_USER"); sudoUser != "" { + if usr, err := user.Lookup(sudoUser); err == nil { + exclude_paths[usr.HomeDir] = true + } + } + + if fpath != "/" { + fpath = strings.TrimSuffix(fpath, "/") + } + if exclude_paths[fpath] { + return fmt.Errorf("SELinux relabeling of %s is not allowed", fpath) } if !recurse { - return setFileLabel(fpath, label) + err := lSetFileLabel(fpath, label) + if err != nil { + // Check if file doesn't exist, must have been removed + if errors.Is(err, os.ErrNotExist) { + return nil + } + // Check if current label is correct on disk + flabel, nerr := lFileLabel(fpath) + if nerr == nil && flabel == label { + return nil + } + // Check if file doesn't exist, must have been removed + if errors.Is(nerr, os.ErrNotExist) { + return nil + } + return err + } + return nil } return rchcon(fpath, label) diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go index 78743b020..20d888031 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux package selinux diff --git a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/certificate.go b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/certificate.go index 21c268550..348f47bdc 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/certificate.go +++ b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/certificate.go @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package cryptoutils implements support for working with encoded certificates, public keys, and private keys package cryptoutils import ( @@ -58,6 +59,7 @@ func MarshalCertificatesToPEM(certs []*x509.Certificate) ([]byte, error) { func UnmarshalCertificatesFromPEM(pemBytes []byte) ([]*x509.Certificate, error) { result := []*x509.Certificate{} remaining := pemBytes + remaining = bytes.TrimSpace(remaining) for len(remaining) > 0 { var certDer *pem.Block @@ -82,6 +84,7 @@ func UnmarshalCertificatesFromPEM(pemBytes []byte) ([]*x509.Certificate, error) func UnmarshalCertificatesFromPEMLimited(pemBytes []byte, iterations int) ([]*x509.Certificate, error) { result := []*x509.Certificate{} remaining := pemBytes + remaining = bytes.TrimSpace(remaining) count := 0 for len(remaining) > 0 { diff --git a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/doc.go b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/doc.go new file mode 100644 index 000000000..4e7e73d55 --- /dev/null +++ b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/doc.go @@ -0,0 +1,17 @@ +// +// Copyright 2022 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package cryptoutils contains utilities related to handling cryptographic materials. +package cryptoutils diff --git a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/password.go b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/password.go index 31011f34c..89dd05e01 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/password.go +++ b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/password.go @@ -18,7 +18,7 @@ package cryptoutils import ( "errors" "fmt" - "io/ioutil" + "io" "os" "golang.org/x/term" @@ -50,7 +50,7 @@ func readPasswordFn() func() ([]byte, error) { } // Handle piped in passwords. return func() ([]byte, error) { - return ioutil.ReadAll(os.Stdin) + return io.ReadAll(os.Stdin) } } diff --git a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/privatekey.go b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/privatekey.go index d97bf36bf..b1a0dad05 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/privatekey.go +++ b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/privatekey.go @@ -31,7 +31,11 @@ import ( const ( // PrivateKeyPEMType is the string "PRIVATE KEY" to be used during PEM encoding and decoding - PrivateKeyPEMType PEMType = "PRIVATE KEY" + PrivateKeyPEMType PEMType = "PRIVATE KEY" + // ECPrivateKeyPEMType is the string "EC PRIVATE KEY" used to parse SEC 1 EC private keys + ECPrivateKeyPEMType PEMType = "EC PRIVATE KEY" + // PKCS1PrivateKeyPEMType is the string "RSA PRIVATE KEY" used to parse PKCS#1-encoded private keys + PKCS1PrivateKeyPEMType PEMType = "RSA PRIVATE KEY" encryptedCosignPrivateKeyPEMType PEMType = "ENCRYPTED COSIGN PRIVATE KEY" // EncryptedSigstorePrivateKeyPEMType is the string "ENCRYPTED SIGSTORE PRIVATE KEY" to be used during PEM encoding and decoding EncryptedSigstorePrivateKeyPEMType PEMType = "ENCRYPTED SIGSTORE PRIVATE KEY" @@ -106,6 +110,10 @@ func UnmarshalPEMToPrivateKey(pemBytes []byte, pf PassFunc) (crypto.PrivateKey, switch derBlock.Type { case string(PrivateKeyPEMType): return x509.ParsePKCS8PrivateKey(derBlock.Bytes) + case string(PKCS1PrivateKeyPEMType): + return x509.ParsePKCS1PrivateKey(derBlock.Bytes) + case string(ECPrivateKeyPEMType): + return x509.ParseECPrivateKey(derBlock.Bytes) case string(EncryptedSigstorePrivateKeyPEMType), string(encryptedCosignPrivateKeyPEMType): derBytes := derBlock.Bytes if pf != nil { @@ -123,7 +131,7 @@ func UnmarshalPEMToPrivateKey(pemBytes []byte, pf PassFunc) (crypto.PrivateKey, return x509.ParsePKCS8PrivateKey(derBytes) } - return nil, fmt.Errorf("unknown PEM file type: %v", derBlock.Type) + return nil, fmt.Errorf("unknown private key PEM file type: %v", derBlock.Type) } // MarshalPrivateKeyToDER converts a crypto.PrivateKey into a PKCS8 ASN.1 DER byte slice @@ -134,7 +142,7 @@ func MarshalPrivateKeyToDER(priv crypto.PrivateKey) ([]byte, error) { return x509.MarshalPKCS8PrivateKey(priv) } -// MarshalPrivateKeyToPEM converts a crypto.PrivateKey into a PEM-encoded byte slice +// MarshalPrivateKeyToPEM converts a crypto.PrivateKey into a PKCS#8 PEM-encoded byte slice func MarshalPrivateKeyToPEM(priv crypto.PrivateKey) ([]byte, error) { derBytes, err := MarshalPrivateKeyToDER(priv) if err != nil { diff --git a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/publickey.go b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/publickey.go index e9f48decb..d2b94d4d9 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/publickey.go +++ b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/publickey.go @@ -37,6 +37,8 @@ import ( const ( // PublicKeyPEMType is the string "PUBLIC KEY" to be used during PEM encoding and decoding PublicKeyPEMType PEMType = "PUBLIC KEY" + // PKCS1PublicKeyPEMType is the string "RSA PUBLIC KEY" used to parse PKCS#1-encoded public keys + PKCS1PublicKeyPEMType PEMType = "RSA PUBLIC KEY" ) // subjectPublicKeyInfo is used to construct a subject key ID. @@ -55,6 +57,8 @@ func UnmarshalPEMToPublicKey(pemBytes []byte) (crypto.PublicKey, error) { switch derBytes.Type { case string(PublicKeyPEMType): return x509.ParsePKIXPublicKey(derBytes.Bytes) + case string(PKCS1PublicKeyPEMType): + return x509.ParsePKCS1PublicKey(derBytes.Bytes) default: return nil, fmt.Errorf("unknown Public key PEM file type: %v. Are you passing the correct public key?", derBytes.Type) diff --git a/vendor/github.com/sigstore/sigstore/pkg/signature/options/context.go b/vendor/github.com/sigstore/sigstore/pkg/signature/options/context.go index 903e6261b..2282a863e 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/signature/options/context.go +++ b/vendor/github.com/sigstore/sigstore/pkg/signature/options/context.go @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package options defines options for KMS clients package options import ( diff --git a/vendor/github.com/sigstore/sigstore/pkg/signature/options/doc.go b/vendor/github.com/sigstore/sigstore/pkg/signature/options/doc.go new file mode 100644 index 000000000..ebdeda22b --- /dev/null +++ b/vendor/github.com/sigstore/sigstore/pkg/signature/options/doc.go @@ -0,0 +1,17 @@ +// +// Copyright 2022 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package options contains functional options for the various SignerVerifiers +package options diff --git a/vendor/github.com/sigstore/sigstore/pkg/signature/payload/doc.go b/vendor/github.com/sigstore/sigstore/pkg/signature/payload/doc.go new file mode 100644 index 000000000..3664185a0 --- /dev/null +++ b/vendor/github.com/sigstore/sigstore/pkg/signature/payload/doc.go @@ -0,0 +1,17 @@ +// +// Copyright 2022 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package payload contains types and utilities related to the Cosign signature format. +package payload diff --git a/vendor/github.com/sigstore/sigstore/pkg/signature/payload/payload.go b/vendor/github.com/sigstore/sigstore/pkg/signature/payload/payload.go index c58368433..8b61aa15f 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/signature/payload/payload.go +++ b/vendor/github.com/sigstore/sigstore/pkg/signature/payload/payload.go @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package payload defines a container image package payload import ( diff --git a/vendor/github.com/sigstore/sigstore/pkg/signature/signer.go b/vendor/github.com/sigstore/sigstore/pkg/signature/signer.go index 6dad67d08..3bd3823cb 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/signature/signer.go +++ b/vendor/github.com/sigstore/sigstore/pkg/signature/signer.go @@ -22,7 +22,7 @@ import ( "crypto/rsa" "errors" "io" - "io/ioutil" + "os" "path/filepath" // these ensure we have the implementations loaded @@ -77,7 +77,7 @@ func LoadSigner(privateKey crypto.PrivateKey, hashFunc crypto.Hash) (Signer, err // RSAPSSSigner is desired instead, use the LoadRSAPSSSigner() and // cryptoutils.UnmarshalPEMToPrivateKey() methods directly. func LoadSignerFromPEMFile(path string, hashFunc crypto.Hash, pf cryptoutils.PassFunc) (Signer, error) { - fileBytes, err := ioutil.ReadFile(filepath.Clean(path)) + fileBytes, err := os.ReadFile(filepath.Clean(path)) if err != nil { return nil, err } diff --git a/vendor/github.com/sigstore/sigstore/pkg/signature/signerverifier.go b/vendor/github.com/sigstore/sigstore/pkg/signature/signerverifier.go index 9592654ed..90667f2a8 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/signature/signerverifier.go +++ b/vendor/github.com/sigstore/sigstore/pkg/signature/signerverifier.go @@ -21,7 +21,7 @@ import ( "crypto/ed25519" "crypto/rsa" "errors" - "io/ioutil" + "os" "path/filepath" "github.com/sigstore/sigstore/pkg/cryptoutils" @@ -57,7 +57,7 @@ func LoadSignerVerifier(privateKey crypto.PrivateKey, hashFunc crypto.Hash) (Sig // RSAPSSSignerVerifier is desired instead, use the LoadRSAPSSSignerVerifier() and // cryptoutils.UnmarshalPEMToPrivateKey() methods directly. func LoadSignerVerifierFromPEMFile(path string, hashFunc crypto.Hash, pf cryptoutils.PassFunc) (SignerVerifier, error) { - fileBytes, err := ioutil.ReadFile(filepath.Clean(path)) + fileBytes, err := os.ReadFile(filepath.Clean(path)) if err != nil { return nil, err } diff --git a/vendor/github.com/sigstore/sigstore/pkg/signature/verifier.go b/vendor/github.com/sigstore/sigstore/pkg/signature/verifier.go index ea8660efc..9ca604929 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/signature/verifier.go +++ b/vendor/github.com/sigstore/sigstore/pkg/signature/verifier.go @@ -22,7 +22,7 @@ import ( "crypto/rsa" "errors" "io" - "io/ioutil" + "os" "path/filepath" "github.com/sigstore/sigstore/pkg/cryptoutils" @@ -86,7 +86,7 @@ func LoadUnsafeVerifier(publicKey crypto.PublicKey) (Verifier, error) { // If the publickey is an RSA key, a RSAPKCS1v15Verifier will be returned. If a // RSAPSSVerifier is desired instead, use the LoadRSAPSSVerifier() and cryptoutils.UnmarshalPEMToPublicKey() methods directly. func LoadVerifierFromPEMFile(path string, hashFunc crypto.Hash) (Verifier, error) { - fileBytes, err := ioutil.ReadFile(filepath.Clean(path)) + fileBytes, err := os.ReadFile(filepath.Clean(path)) if err != nil { return nil, err } diff --git a/vendor/github.com/sylabs/sif/v2/pkg/sif/descriptor.go b/vendor/github.com/sylabs/sif/v2/pkg/sif/descriptor.go index 86fac669a..03ed2b042 100644 --- a/vendor/github.com/sylabs/sif/v2/pkg/sif/descriptor.go +++ b/vendor/github.com/sylabs/sif/v2/pkg/sif/descriptor.go @@ -56,6 +56,11 @@ type cryptoMessage struct { Messagetype MessageType } +// sbom represents the SIF SBOM data object descriptor. +type sbom struct { + Format SBOMFormat +} + var errNameTooLarge = errors.New("name value too large") // setName encodes name into the name field of d. @@ -230,6 +235,22 @@ func (d Descriptor) CryptoMessageMetadata() (FormatType, MessageType, error) { return m.Formattype, m.Messagetype, nil } +// SBOMMetadata gets metadata for a SBOM data object. +func (d Descriptor) SBOMMetadata() (SBOMFormat, error) { + if got, want := d.raw.DataType, DataSBOM; got != want { + return 0, &unexpectedDataTypeError{got, []DataType{want}} + } + + var s sbom + + b := bytes.NewReader(d.raw.Extra[:]) + if err := binary.Read(b, binary.LittleEndian, &s); err != nil { + return 0, fmt.Errorf("%w", err) + } + + return s.Format, nil +} + // GetData returns the data object associated with descriptor d. func (d Descriptor) GetData() ([]byte, error) { b := make([]byte, d.raw.Size) diff --git a/vendor/github.com/sylabs/sif/v2/pkg/sif/descriptor_input.go b/vendor/github.com/sylabs/sif/v2/pkg/sif/descriptor_input.go index 1b8dda20c..3e81c394f 100644 --- a/vendor/github.com/sylabs/sif/v2/pkg/sif/descriptor_input.go +++ b/vendor/github.com/sylabs/sif/v2/pkg/sif/descriptor_input.go @@ -226,6 +226,24 @@ func OptSignatureMetadata(ht crypto.Hash, fp []byte) DescriptorInputOpt { } } +// OptSBOMMetadata sets metadata for a SBOM data object. The SBOM format is set to f. +// +// If this option is applied to a data object with an incompatible type, an error is returned. +func OptSBOMMetadata(f SBOMFormat) DescriptorInputOpt { + return func(t DataType, opts *descriptorOpts) error { + if got, want := t, DataSBOM; got != want { + return &unexpectedDataTypeError{got, []DataType{want}} + } + + s := sbom{ + Format: f, + } + + opts.extra = s + return nil + } +} + // DescriptorInput describes a new data object. type DescriptorInput struct { dt DataType @@ -241,7 +259,7 @@ const DefaultObjectGroup = 1 // // It is possible (and often necessary) to store additional metadata related to certain types of // data objects. Consider supplying options such as OptCryptoMessageMetadata, OptPartitionMetadata, -// and OptSignatureMetadata for this purpose. +// OptSignatureMetadata, and OptSBOMMetadata for this purpose. // // By default, the data object will be placed in the default data object group (1). To override // this behavior, use OptNoGroup or OptGroupID. To link this data object, use OptLinkedID or diff --git a/vendor/github.com/sylabs/sif/v2/pkg/sif/sif.go b/vendor/github.com/sylabs/sif/v2/pkg/sif/sif.go index e0faaedb3..2d1c2091d 100644 --- a/vendor/github.com/sylabs/sif/v2/pkg/sif/sif.go +++ b/vendor/github.com/sylabs/sif/v2/pkg/sif/sif.go @@ -132,6 +132,7 @@ const ( DataGenericJSON // generic JSON meta-data DataGeneric // generic / raw data DataCryptoMessage // cryptographic message data object + DataSBOM // software bill of materials ) // String returns a human-readable representation of t. @@ -153,6 +154,8 @@ func (t DataType) String() string { return "Generic/Raw" case DataCryptoMessage: return "Cryptographic Message" + case DataSBOM: + return "SBOM" } return "Unknown" } @@ -267,6 +270,44 @@ func (t MessageType) String() string { return "Unknown" } +// SBOMFormat represents the format used to store an SBOM object. +type SBOMFormat int32 + +// List of supported SBOM formats. +const ( + SBOMFormatCycloneDXJSON SBOMFormat = iota + 1 // CycloneDX (JSON) + SBOMFormatCycloneDXXML // CycloneDX (XML) + SBOMFormatGitHubJSON // GitHub dependency snapshot (JSON) + SBOMFormatSPDXJSON // SPDX (JSON) + SBOMFormatSPDXRDF // SPDX (RDF/xml) + SBOMFormatSPDXTagValue // SPDX (tag/value) + SBOMFormatSPDXYAML // SPDX (YAML) + SBOMFormatSyftJSON // Syft (JSON) +) + +// String returns a human-readable representation of f. +func (f SBOMFormat) String() string { + switch f { + case SBOMFormatCycloneDXJSON: + return "cyclonedx-json" + case SBOMFormatCycloneDXXML: + return "cyclonedx-xml" + case SBOMFormatGitHubJSON: + return "github-json" + case SBOMFormatSPDXJSON: + return "spdx-json" + case SBOMFormatSPDXRDF: + return "spdx-rdf" + case SBOMFormatSPDXTagValue: + return "spdx-tag-value" + case SBOMFormatSPDXYAML: + return "spdx-yaml" + case SBOMFormatSyftJSON: + return "syft-json" + } + return "unknown" +} + // header describes a loaded SIF file. type header struct { LaunchScript [hdrLaunchLen]byte diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_generic.go b/vendor/golang.org/x/crypto/chacha20/chacha_generic.go index a2ecf5c32..93eb5ae6d 100644 --- a/vendor/golang.org/x/crypto/chacha20/chacha_generic.go +++ b/vendor/golang.org/x/crypto/chacha20/chacha_generic.go @@ -12,7 +12,7 @@ import ( "errors" "math/bits" - "golang.org/x/crypto/internal/subtle" + "golang.org/x/crypto/internal/alias" ) const ( @@ -189,7 +189,7 @@ func (s *Cipher) XORKeyStream(dst, src []byte) { panic("chacha20: output smaller than input") } dst = dst[:len(src)] - if subtle.InexactOverlap(dst, src) { + if alias.InexactOverlap(dst, src) { panic("chacha20: invalid buffer overlap") } diff --git a/vendor/golang.org/x/crypto/internal/subtle/aliasing.go b/vendor/golang.org/x/crypto/internal/alias/alias.go index 4fad24f8d..69c17f822 100644 --- a/vendor/golang.org/x/crypto/internal/subtle/aliasing.go +++ b/vendor/golang.org/x/crypto/internal/alias/alias.go @@ -5,9 +5,8 @@ //go:build !purego // +build !purego -// Package subtle implements functions that are often useful in cryptographic -// code but require careful thought to use correctly. -package subtle // import "golang.org/x/crypto/internal/subtle" +// Package alias implements memory aliasing tests. +package alias import "unsafe" diff --git a/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go b/vendor/golang.org/x/crypto/internal/alias/alias_purego.go index 80ccbed2c..4775b0a43 100644 --- a/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go +++ b/vendor/golang.org/x/crypto/internal/alias/alias_purego.go @@ -5,9 +5,8 @@ //go:build purego // +build purego -// Package subtle implements functions that are often useful in cryptographic -// code but require careful thought to use correctly. -package subtle // import "golang.org/x/crypto/internal/subtle" +// Package alias implements memory aliasing tests. +package alias // This is the Google App Engine standard variant based on reflect // because the unsafe package and cgo are disallowed. diff --git a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go b/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go index a2973e626..f3c3242a0 100644 --- a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go +++ b/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go @@ -35,8 +35,8 @@ This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html. package secretbox // import "golang.org/x/crypto/nacl/secretbox" import ( + "golang.org/x/crypto/internal/alias" "golang.org/x/crypto/internal/poly1305" - "golang.org/x/crypto/internal/subtle" "golang.org/x/crypto/salsa20/salsa" ) @@ -88,7 +88,7 @@ func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte { copy(poly1305Key[:], firstBlock[:]) ret, out := sliceForAppend(out, len(message)+poly1305.TagSize) - if subtle.AnyOverlap(out, message) { + if alias.AnyOverlap(out, message) { panic("nacl: invalid buffer overlap") } @@ -147,7 +147,7 @@ func Open(out, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool) { } ret, out := sliceForAppend(out, len(box)-Overhead) - if subtle.AnyOverlap(out, box) { + if alias.AnyOverlap(out, box) { panic("nacl: invalid buffer overlap") } diff --git a/vendor/golang.org/x/crypto/openpgp/packet/opaque.go b/vendor/golang.org/x/crypto/openpgp/packet/opaque.go index 456d807f2..398447731 100644 --- a/vendor/golang.org/x/crypto/openpgp/packet/opaque.go +++ b/vendor/golang.org/x/crypto/openpgp/packet/opaque.go @@ -7,7 +7,6 @@ package packet import ( "bytes" "io" - "io/ioutil" "golang.org/x/crypto/openpgp/errors" ) @@ -26,7 +25,7 @@ type OpaquePacket struct { } func (op *OpaquePacket) parse(r io.Reader) (err error) { - op.Contents, err = ioutil.ReadAll(r) + op.Contents, err = io.ReadAll(r) return } diff --git a/vendor/golang.org/x/crypto/openpgp/packet/private_key.go b/vendor/golang.org/x/crypto/openpgp/packet/private_key.go index 81abb7cef..192aac376 100644 --- a/vendor/golang.org/x/crypto/openpgp/packet/private_key.go +++ b/vendor/golang.org/x/crypto/openpgp/packet/private_key.go @@ -13,7 +13,6 @@ import ( "crypto/rsa" "crypto/sha1" "io" - "io/ioutil" "math/big" "strconv" "time" @@ -133,7 +132,7 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) { } } - pk.encryptedData, err = ioutil.ReadAll(r) + pk.encryptedData, err = io.ReadAll(r) if err != nil { return } diff --git a/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go index 6126030eb..1a1a62964 100644 --- a/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go +++ b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go @@ -236,7 +236,7 @@ func (w *seMDCWriter) Close() (err error) { return w.w.Close() } -// noOpCloser is like an ioutil.NopCloser, but for an io.Writer. +// noOpCloser is like an io.NopCloser, but for an io.Writer. type noOpCloser struct { w io.Writer } diff --git a/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go b/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go index d19ffbc78..ff7ef5307 100644 --- a/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go +++ b/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go @@ -9,7 +9,6 @@ import ( "image" "image/jpeg" "io" - "io/ioutil" ) const UserAttrImageSubpacket = 1 @@ -56,7 +55,7 @@ func NewUserAttribute(contents ...*OpaqueSubpacket) *UserAttribute { func (uat *UserAttribute) parse(r io.Reader) (err error) { // RFC 4880, section 5.13 - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err != nil { return } diff --git a/vendor/golang.org/x/crypto/openpgp/packet/userid.go b/vendor/golang.org/x/crypto/openpgp/packet/userid.go index d6bea7d4a..359a462eb 100644 --- a/vendor/golang.org/x/crypto/openpgp/packet/userid.go +++ b/vendor/golang.org/x/crypto/openpgp/packet/userid.go @@ -6,7 +6,6 @@ package packet import ( "io" - "io/ioutil" "strings" ) @@ -66,7 +65,7 @@ func NewUserId(name, comment, email string) *UserId { func (uid *UserId) parse(r io.Reader) (err error) { // RFC 4880, section 5.11 - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err != nil { return } diff --git a/vendor/golang.org/x/crypto/openpgp/write.go b/vendor/golang.org/x/crypto/openpgp/write.go index 4ee71784e..b89d48b81 100644 --- a/vendor/golang.org/x/crypto/openpgp/write.go +++ b/vendor/golang.org/x/crypto/openpgp/write.go @@ -402,7 +402,7 @@ func (s signatureWriter) Close() error { return s.encryptedData.Close() } -// noOpCloser is like an ioutil.NopCloser, but for an io.Writer. +// noOpCloser is like an io.NopCloser, but for an io.Writer. // TODO: we have two of these in OpenPGP packages alone. This probably needs // to be promoted somewhere more common. type noOpCloser struct { diff --git a/vendor/golang.org/x/crypto/ssh/agent/client.go b/vendor/golang.org/x/crypto/ssh/agent/client.go index 3c4d18a15..eb6bc7179 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/client.go +++ b/vendor/golang.org/x/crypto/ssh/agent/client.go @@ -226,7 +226,9 @@ var ErrExtensionUnsupported = errors.New("agent: extension unsupported") type extensionAgentMsg struct { ExtensionType string `sshtype:"27"` - Contents []byte + // NOTE: this matches OpenSSH's PROTOCOL.agent, not the IETF draft [PROTOCOL.agent], + // so that it matches what OpenSSH actually implements in the wild. + Contents []byte `ssh:"rest"` } // Key represents a protocol 2 public key as defined in diff --git a/vendor/golang.org/x/crypto/ssh/cipher.go b/vendor/golang.org/x/crypto/ssh/cipher.go index 770e8a663..c3062cfd1 100644 --- a/vendor/golang.org/x/crypto/ssh/cipher.go +++ b/vendor/golang.org/x/crypto/ssh/cipher.go @@ -15,7 +15,6 @@ import ( "fmt" "hash" "io" - "io/ioutil" "golang.org/x/crypto/chacha20" "golang.org/x/crypto/internal/poly1305" @@ -497,7 +496,7 @@ func (c *cbcCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) // data, to make distinguishing between // failing MAC and failing length check more // difficult. - io.CopyN(ioutil.Discard, r, int64(c.oracleCamouflage)) + io.CopyN(io.Discard, r, int64(c.oracleCamouflage)) } } return p, err diff --git a/vendor/golang.org/x/crypto/ssh/session.go b/vendor/golang.org/x/crypto/ssh/session.go index eca31a22d..acef62259 100644 --- a/vendor/golang.org/x/crypto/ssh/session.go +++ b/vendor/golang.org/x/crypto/ssh/session.go @@ -13,7 +13,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "sync" ) @@ -124,7 +123,7 @@ type Session struct { // output and error. // // If either is nil, Run connects the corresponding file - // descriptor to an instance of ioutil.Discard. There is a + // descriptor to an instance of io.Discard. There is a // fixed amount of buffering that is shared for the two streams. // If either blocks it may eventually cause the remote // command to block. @@ -506,7 +505,7 @@ func (s *Session) stdout() { return } if s.Stdout == nil { - s.Stdout = ioutil.Discard + s.Stdout = io.Discard } s.copyFuncs = append(s.copyFuncs, func() error { _, err := io.Copy(s.Stdout, s.ch) @@ -519,7 +518,7 @@ func (s *Session) stderr() { return } if s.Stderr == nil { - s.Stderr = ioutil.Discard + s.Stderr = io.Discard } s.copyFuncs = append(s.copyFuncs, func() error { _, err := io.Copy(s.Stderr, s.ch.Stderr()) diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go index 0a54bdbcc..2cb9c408f 100644 --- a/vendor/golang.org/x/net/context/go17.go +++ b/vendor/golang.org/x/net/context/go17.go @@ -32,7 +32,7 @@ var DeadlineExceeded = context.DeadlineExceeded // call cancel as soon as the operations running in this Context complete. func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { ctx, f := context.WithCancel(parent) - return ctx, CancelFunc(f) + return ctx, f } // WithDeadline returns a copy of the parent context with the deadline adjusted @@ -46,7 +46,7 @@ func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { // call cancel as soon as the operations running in this Context complete. func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { ctx, f := context.WithDeadline(parent, deadline) - return ctx, CancelFunc(f) + return ctx, f } // WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). diff --git a/vendor/golang.org/x/net/html/render.go b/vendor/golang.org/x/net/html/render.go index b46d81ca6..497e13204 100644 --- a/vendor/golang.org/x/net/html/render.go +++ b/vendor/golang.org/x/net/html/render.go @@ -85,7 +85,7 @@ func render1(w writer, n *Node) error { if _, err := w.WriteString("<!--"); err != nil { return err } - if _, err := w.WriteString(n.Data); err != nil { + if err := escape(w, n.Data); err != nil { return err } if _, err := w.WriteString("-->"); err != nil { @@ -96,7 +96,7 @@ func render1(w writer, n *Node) error { if _, err := w.WriteString("<!DOCTYPE "); err != nil { return err } - if _, err := w.WriteString(n.Data); err != nil { + if err := escape(w, n.Data); err != nil { return err } if n.Attr != nil { diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go index 877709f99..be3c75414 100644 --- a/vendor/golang.org/x/net/html/token.go +++ b/vendor/golang.org/x/net/html/token.go @@ -110,9 +110,9 @@ func (t Token) String() string { case SelfClosingTagToken: return "<" + t.tagString() + "/>" case CommentToken: - return "<!--" + t.Data + "-->" + return "<!--" + EscapeString(t.Data) + "-->" case DoctypeToken: - return "<!DOCTYPE " + t.Data + ">" + return "<!DOCTYPE " + EscapeString(t.Data) + ">" } return "Invalid(" + strconv.Itoa(int(t.Type)) + ")" } diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index 0178647ee..184ac45fe 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -23,7 +23,7 @@ const frameHeaderLen = 9 var padZeros = make([]byte, 255) // zeros for padding // A FrameType is a registered frame type as defined in -// http://http2.github.io/http2-spec/#rfc.section.11.2 +// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2 type FrameType uint8 const ( @@ -146,7 +146,7 @@ func typeFrameParser(t FrameType) frameParser { // A FrameHeader is the 9 byte header of all HTTP/2 frames. // -// See http://http2.github.io/http2-spec/#FrameHeader +// See https://httpwg.org/specs/rfc7540.html#FrameHeader type FrameHeader struct { valid bool // caller can access []byte fields in the Frame @@ -575,7 +575,7 @@ func (fr *Framer) checkFrameOrder(f Frame) error { // A DataFrame conveys arbitrary, variable-length sequences of octets // associated with a stream. -// See http://http2.github.io/http2-spec/#rfc.section.6.1 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1 type DataFrame struct { FrameHeader data []byte @@ -698,7 +698,7 @@ func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []by // endpoints communicate, such as preferences and constraints on peer // behavior. // -// See http://http2.github.io/http2-spec/#SETTINGS +// See https://httpwg.org/specs/rfc7540.html#SETTINGS type SettingsFrame struct { FrameHeader p []byte @@ -837,7 +837,7 @@ func (f *Framer) WriteSettingsAck() error { // A PingFrame is a mechanism for measuring a minimal round trip time // from the sender, as well as determining whether an idle connection // is still functional. -// See http://http2.github.io/http2-spec/#rfc.section.6.7 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7 type PingFrame struct { FrameHeader Data [8]byte @@ -870,7 +870,7 @@ func (f *Framer) WritePing(ack bool, data [8]byte) error { } // A GoAwayFrame informs the remote peer to stop creating streams on this connection. -// See http://http2.github.io/http2-spec/#rfc.section.6.8 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8 type GoAwayFrame struct { FrameHeader LastStreamID uint32 @@ -934,7 +934,7 @@ func parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p } // A WindowUpdateFrame is used to implement flow control. -// See http://http2.github.io/http2-spec/#rfc.section.6.9 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9 type WindowUpdateFrame struct { FrameHeader Increment uint32 // never read with high bit set @@ -1123,7 +1123,7 @@ func (f *Framer) WriteHeaders(p HeadersFrameParam) error { } // A PriorityFrame specifies the sender-advised priority of a stream. -// See http://http2.github.io/http2-spec/#rfc.section.6.3 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3 type PriorityFrame struct { FrameHeader PriorityParam @@ -1193,7 +1193,7 @@ func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error { } // A RSTStreamFrame allows for abnormal termination of a stream. -// See http://http2.github.io/http2-spec/#rfc.section.6.4 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4 type RSTStreamFrame struct { FrameHeader ErrCode ErrCode @@ -1225,7 +1225,7 @@ func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error { } // A ContinuationFrame is used to continue a sequence of header block fragments. -// See http://http2.github.io/http2-spec/#rfc.section.6.10 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10 type ContinuationFrame struct { FrameHeader headerFragBuf []byte @@ -1266,7 +1266,7 @@ func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlock } // A PushPromiseFrame is used to initiate a server stream. -// See http://http2.github.io/http2-spec/#rfc.section.6.6 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6 type PushPromiseFrame struct { FrameHeader PromiseID uint32 diff --git a/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go index 97f17831f..6886dc163 100644 --- a/vendor/golang.org/x/net/http2/hpack/encode.go +++ b/vendor/golang.org/x/net/http2/hpack/encode.go @@ -191,7 +191,7 @@ func appendTableSize(dst []byte, v uint32) []byte { // bit prefix, to dst and returns the extended buffer. // // See -// http://http2.github.io/http2-spec/compression.html#integer.representation +// https://httpwg.org/specs/rfc7541.html#integer.representation func appendVarInt(dst []byte, n byte, i uint64) []byte { k := uint64((1 << n) - 1) if i < k { diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go index 85f18a2b0..ebdfbee96 100644 --- a/vendor/golang.org/x/net/http2/hpack/hpack.go +++ b/vendor/golang.org/x/net/http2/hpack/hpack.go @@ -59,7 +59,7 @@ func (hf HeaderField) String() string { // Size returns the size of an entry per RFC 7541 section 4.1. func (hf HeaderField) Size() uint32 { - // http://http2.github.io/http2-spec/compression.html#rfc.section.4.1 + // https://httpwg.org/specs/rfc7541.html#rfc.section.4.1 // "The size of the dynamic table is the sum of the size of // its entries. The size of an entry is the sum of its name's // length in octets (as defined in Section 5.2), its value's @@ -158,7 +158,7 @@ func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) { } type dynamicTable struct { - // http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2 + // https://httpwg.org/specs/rfc7541.html#rfc.section.2.3.2 table headerFieldTable size uint32 // in bytes maxSize uint32 // current maxSize @@ -307,27 +307,27 @@ func (d *Decoder) parseHeaderFieldRepr() error { case b&128 != 0: // Indexed representation. // High bit set? - // http://http2.github.io/http2-spec/compression.html#rfc.section.6.1 + // https://httpwg.org/specs/rfc7541.html#rfc.section.6.1 return d.parseFieldIndexed() case b&192 == 64: // 6.2.1 Literal Header Field with Incremental Indexing // 0b10xxxxxx: top two bits are 10 - // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.1 + // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1 return d.parseFieldLiteral(6, indexedTrue) case b&240 == 0: // 6.2.2 Literal Header Field without Indexing // 0b0000xxxx: top four bits are 0000 - // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2 + // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2 return d.parseFieldLiteral(4, indexedFalse) case b&240 == 16: // 6.2.3 Literal Header Field never Indexed // 0b0001xxxx: top four bits are 0001 - // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.3 + // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3 return d.parseFieldLiteral(4, indexedNever) case b&224 == 32: // 6.3 Dynamic Table Size Update // Top three bits are '001'. - // http://http2.github.io/http2-spec/compression.html#rfc.section.6.3 + // https://httpwg.org/specs/rfc7541.html#rfc.section.6.3 return d.parseDynamicTableSizeUpdate() } @@ -420,7 +420,7 @@ var errVarintOverflow = DecodingError{errors.New("varint integer overflow")} // readVarInt reads an unsigned variable length integer off the // beginning of p. n is the parameter as described in -// http://http2.github.io/http2-spec/compression.html#rfc.section.5.1. +// https://httpwg.org/specs/rfc7541.html#rfc.section.5.1. // // n must always be between 1 and 8. // diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index 479ba4b2b..6f2df2818 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -55,14 +55,14 @@ const ( ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" // SETTINGS_MAX_FRAME_SIZE default - // http://http2.github.io/http2-spec/#rfc.section.6.5.2 + // https://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2 initialMaxFrameSize = 16384 // NextProtoTLS is the NPN/ALPN protocol negotiated during // HTTP/2's TLS setup. NextProtoTLS = "h2" - // http://http2.github.io/http2-spec/#SettingValues + // https://httpwg.org/specs/rfc7540.html#SettingValues initialHeaderTableSize = 4096 initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size @@ -111,7 +111,7 @@ func (st streamState) String() string { // Setting is a setting parameter: which setting it is, and its value. type Setting struct { // ID is which setting is being set. - // See http://http2.github.io/http2-spec/#SettingValues + // See https://httpwg.org/specs/rfc7540.html#SettingFormat ID SettingID // Val is the value. @@ -143,7 +143,7 @@ func (s Setting) Valid() error { } // A SettingID is an HTTP/2 setting as defined in -// http://http2.github.io/http2-spec/#iana-settings +// https://httpwg.org/specs/rfc7540.html#iana-settings type SettingID uint16 const ( diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index 47524a61a..fd873b9af 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -1371,6 +1371,9 @@ func (sc *serverConn) startGracefulShutdownInternal() { func (sc *serverConn) goAway(code ErrCode) { sc.serveG.check() if sc.inGoAway { + if sc.goAwayCode == ErrCodeNo { + sc.goAwayCode = code + } return } sc.inGoAway = true @@ -1747,6 +1750,12 @@ func (sc *serverConn) processData(f *DataFrame) error { // Sender sending more than they'd declared? if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes { + if sc.inflow.available() < int32(f.Length) { + return sc.countError("data_flow", streamError(id, ErrCodeFlowControl)) + } + sc.inflow.take(int32(f.Length)) + sc.sendWindowUpdate(nil, int(f.Length)) // conn-level + st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes)) // RFC 7540, sec 8.1.2.6: A request or response is also malformed if the // value of a content-length header field does not equal the sum of the @@ -2223,6 +2232,9 @@ func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler didPanic := true defer func() { rw.rws.stream.cancelCtx() + if req.MultipartForm != nil { + req.MultipartForm.RemoveAll() + } if didPanic { e := recover() sc.writeFrameFromHandler(FrameWriteRequest{ diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 4ded4dfd5..90fdc28cf 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -67,13 +67,23 @@ const ( // A Transport internally caches connections to servers. It is safe // for concurrent use by multiple goroutines. type Transport struct { - // DialTLS specifies an optional dial function for creating - // TLS connections for requests. + // DialTLSContext specifies an optional dial function with context for + // creating TLS connections for requests. // - // If DialTLS is nil, tls.Dial is used. + // If DialTLSContext and DialTLS is nil, tls.Dial is used. // // If the returned net.Conn has a ConnectionState method like tls.Conn, // it will be used to set http.Response.TLS. + DialTLSContext func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) + + // DialTLS specifies an optional dial function for creating + // TLS connections for requests. + // + // If DialTLSContext and DialTLS is nil, tls.Dial is used. + // + // Deprecated: Use DialTLSContext instead, which allows the transport + // to cancel dials as soon as they are no longer needed. + // If both are set, DialTLSContext takes priority. DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error) // TLSClientConfig specifies the TLS configuration to use with @@ -592,7 +602,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b if err != nil { return nil, err } - tconn, err := t.dialTLS(ctx)("tcp", addr, t.newTLSConfig(host)) + tconn, err := t.dialTLS(ctx, "tcp", addr, t.newTLSConfig(host)) if err != nil { return nil, err } @@ -613,24 +623,25 @@ func (t *Transport) newTLSConfig(host string) *tls.Config { return cfg } -func (t *Transport) dialTLS(ctx context.Context) func(string, string, *tls.Config) (net.Conn, error) { - if t.DialTLS != nil { - return t.DialTLS +func (t *Transport) dialTLS(ctx context.Context, network, addr string, tlsCfg *tls.Config) (net.Conn, error) { + if t.DialTLSContext != nil { + return t.DialTLSContext(ctx, network, addr, tlsCfg) + } else if t.DialTLS != nil { + return t.DialTLS(network, addr, tlsCfg) } - return func(network, addr string, cfg *tls.Config) (net.Conn, error) { - tlsCn, err := t.dialTLSWithContext(ctx, network, addr, cfg) - if err != nil { - return nil, err - } - state := tlsCn.ConnectionState() - if p := state.NegotiatedProtocol; p != NextProtoTLS { - return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS) - } - if !state.NegotiatedProtocolIsMutual { - return nil, errors.New("http2: could not negotiate protocol mutually") - } - return tlsCn, nil + + tlsCn, err := t.dialTLSWithContext(ctx, network, addr, tlsCfg) + if err != nil { + return nil, err + } + state := tlsCn.ConnectionState() + if p := state.NegotiatedProtocol; p != NextProtoTLS { + return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS) + } + if !state.NegotiatedProtocolIsMutual { + return nil, errors.New("http2: could not negotiate protocol mutually") } + return tlsCn, nil } // disableKeepAlives reports whether connections should be closed as diff --git a/vendor/golang.org/x/sys/plan9/syscall.go b/vendor/golang.org/x/sys/plan9/syscall.go index ea971285f..67e5b0115 100644 --- a/vendor/golang.org/x/sys/plan9/syscall.go +++ b/vendor/golang.org/x/sys/plan9/syscall.go @@ -80,8 +80,7 @@ func BytePtrToString(p *byte) string { ptr = unsafe.Pointer(uintptr(ptr) + 1) } - s := unsafe.Slice((*byte)(unsafe.Pointer(p)), n) - return string(s) + return string(unsafe.Slice(p, n)) } // Single-word zero for use when we need a valid pointer to 0 bytes. diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh index 3b2335d5f..1b2b424a7 100644 --- a/vendor/golang.org/x/sys/unix/mkall.sh +++ b/vendor/golang.org/x/sys/unix/mkall.sh @@ -214,11 +214,6 @@ esac if [ "$GOOSARCH" == "aix_ppc64" ]; then # aix/ppc64 script generates files instead of writing to stdin. echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ; - elif [ "$GOOS" == "darwin" ]; then - # 1.12 and later, syscalls via libSystem - echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; - # 1.13 and later, syscalls via libSystem (including syscallPtr) - echo "$mksyscall -tags $GOOS,$GOARCH,go1.13 syscall_darwin.1_13.go |gofmt >zsyscall_$GOOSARCH.1_13.go"; elif [ "$GOOS" == "illumos" ]; then # illumos code generation requires a --illumos switch echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go"; diff --git a/vendor/golang.org/x/sys/unix/syscall.go b/vendor/golang.org/x/sys/unix/syscall.go index 9916e5e85..63e8c8383 100644 --- a/vendor/golang.org/x/sys/unix/syscall.go +++ b/vendor/golang.org/x/sys/unix/syscall.go @@ -80,8 +80,7 @@ func BytePtrToString(p *byte) string { ptr = unsafe.Pointer(uintptr(ptr) + 1) } - s := unsafe.Slice((*byte)(unsafe.Pointer(p)), n) - return string(s) + return string(unsafe.Slice(p, n)) } // Single-word zero for use when we need a valid pointer to 0 bytes. diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go b/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go deleted file mode 100644 index b0098607c..000000000 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build darwin && go1.12 && !go1.13 -// +build darwin,go1.12,!go1.13 - -package unix - -import ( - "unsafe" -) - -const _SYS_GETDIRENTRIES64 = 344 - -func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { - // To implement this using libSystem we'd need syscall_syscallPtr for - // fdopendir. However, syscallPtr was only added in Go 1.13, so we fall - // back to raw syscalls for this func on Go 1.12. - var p unsafe.Pointer - if len(buf) > 0 { - p = unsafe.Pointer(&buf[0]) - } else { - p = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0) - n = int(r0) - if e1 != 0 { - return n, errnoErr(e1) - } - return n, nil -} diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go b/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go deleted file mode 100644 index 1259f6df5..000000000 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build darwin && go1.13 -// +build darwin,go1.13 - -package unix - -import "unsafe" - -//sys closedir(dir uintptr) (err error) -//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) - -func fdopendir(fd int) (dir uintptr, err error) { - r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0) - dir = uintptr(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_fdopendir_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib" - -func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { - // Simulate Getdirentries using fdopendir/readdir_r/closedir. - // We store the number of entries to skip in the seek - // offset of fd. See issue #31368. - // It's not the full required semantics, but should handle the case - // of calling Getdirentries or ReadDirent repeatedly. - // It won't handle assigning the results of lseek to *basep, or handle - // the directory being edited underfoot. - skip, err := Seek(fd, 0, 1 /* SEEK_CUR */) - if err != nil { - return 0, err - } - - // We need to duplicate the incoming file descriptor - // because the caller expects to retain control of it, but - // fdopendir expects to take control of its argument. - // Just Dup'ing the file descriptor is not enough, as the - // result shares underlying state. Use Openat to make a really - // new file descriptor referring to the same directory. - fd2, err := Openat(fd, ".", O_RDONLY, 0) - if err != nil { - return 0, err - } - d, err := fdopendir(fd2) - if err != nil { - Close(fd2) - return 0, err - } - defer closedir(d) - - var cnt int64 - for { - var entry Dirent - var entryp *Dirent - e := readdir_r(d, &entry, &entryp) - if e != 0 { - return n, errnoErr(e) - } - if entryp == nil { - break - } - if skip > 0 { - skip-- - cnt++ - continue - } - - reclen := int(entry.Reclen) - if reclen > len(buf) { - // Not enough room. Return for now. - // The counter will let us know where we should start up again. - // Note: this strategy for suspending in the middle and - // restarting is O(n^2) in the length of the directory. Oh well. - break - } - - // Copy entry into return buffer. - s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen) - copy(buf, s) - - buf = buf[reclen:] - n += reclen - cnt++ - } - // Set the seek offset of the input fd to record - // how many files we've already returned. - _, err = Seek(fd, cnt, 0 /* SEEK_SET */) - if err != nil { - return n, err - } - - return n, nil -} diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 4f87f16ea..1f6338218 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -19,6 +19,96 @@ import ( "unsafe" ) +//sys closedir(dir uintptr) (err error) +//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) + +func fdopendir(fd int) (dir uintptr, err error) { + r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0) + dir = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fdopendir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib" + +func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { + // Simulate Getdirentries using fdopendir/readdir_r/closedir. + // We store the number of entries to skip in the seek + // offset of fd. See issue #31368. + // It's not the full required semantics, but should handle the case + // of calling Getdirentries or ReadDirent repeatedly. + // It won't handle assigning the results of lseek to *basep, or handle + // the directory being edited underfoot. + skip, err := Seek(fd, 0, 1 /* SEEK_CUR */) + if err != nil { + return 0, err + } + + // We need to duplicate the incoming file descriptor + // because the caller expects to retain control of it, but + // fdopendir expects to take control of its argument. + // Just Dup'ing the file descriptor is not enough, as the + // result shares underlying state. Use Openat to make a really + // new file descriptor referring to the same directory. + fd2, err := Openat(fd, ".", O_RDONLY, 0) + if err != nil { + return 0, err + } + d, err := fdopendir(fd2) + if err != nil { + Close(fd2) + return 0, err + } + defer closedir(d) + + var cnt int64 + for { + var entry Dirent + var entryp *Dirent + e := readdir_r(d, &entry, &entryp) + if e != 0 { + return n, errnoErr(e) + } + if entryp == nil { + break + } + if skip > 0 { + skip-- + cnt++ + continue + } + + reclen := int(entry.Reclen) + if reclen > len(buf) { + // Not enough room. Return for now. + // The counter will let us know where we should start up again. + // Note: this strategy for suspending in the middle and + // restarting is O(n^2) in the length of the directory. Oh well. + break + } + + // Copy entry into return buffer. + s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen) + copy(buf, s) + + buf = buf[reclen:] + n += reclen + cnt++ + } + // Set the seek offset of the input fd to record + // how many files we've already returned. + _, err = Seek(fd, cnt, 0 /* SEEK_SET */) + if err != nil { + return n, err + } + + return n, nil +} + // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 diff --git a/vendor/golang.org/x/sys/unix/xattr_bsd.go b/vendor/golang.org/x/sys/unix/xattr_bsd.go index 25df1e378..663b3779d 100644 --- a/vendor/golang.org/x/sys/unix/xattr_bsd.go +++ b/vendor/golang.org/x/sys/unix/xattr_bsd.go @@ -160,13 +160,12 @@ func Lremovexattr(link string, attr string) (err error) { } func Listxattr(file string, dest []byte) (sz int, err error) { - d := initxattrdest(dest, 0) destsiz := len(dest) // FreeBSD won't allow you to list xattrs from multiple namespaces - s := 0 + s, pos := 0, 0 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { - stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz) + stmp, e := ListxattrNS(file, nsid, dest[pos:]) /* Errors accessing system attrs are ignored so that * we can implement the Linux-like behavior of omitting errors that @@ -175,66 +174,102 @@ func Listxattr(file string, dest []byte) (sz int, err error) { * Linux will still error if we ask for user attributes on a file that * we don't have read permissions on, so don't ignore those errors */ - if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { - continue - } else if e != nil { + if e != nil { + if e == EPERM && nsid != EXTATTR_NAMESPACE_USER { + continue + } return s, e } s += stmp - destsiz -= s - if destsiz < 0 { - destsiz = 0 + pos = s + if pos > destsiz { + pos = destsiz } - d = initxattrdest(dest, s) } return s, nil } -func Flistxattr(fd int, dest []byte) (sz int, err error) { +func ListxattrNS(file string, nsid int, dest []byte) (sz int, err error) { d := initxattrdest(dest, 0) destsiz := len(dest) - s := 0 + s, e := ExtattrListFile(file, nsid, uintptr(d), destsiz) + if e != nil { + return 0, err + } + + return s, nil +} + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + destsiz := len(dest) + + s, pos := 0, 0 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { - stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz) - if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { - continue - } else if e != nil { + stmp, e := FlistxattrNS(fd, nsid, dest[pos:]) + + if e != nil { + if e == EPERM && nsid != EXTATTR_NAMESPACE_USER { + continue + } return s, e } s += stmp - destsiz -= s - if destsiz < 0 { - destsiz = 0 + pos = s + if pos > destsiz { + pos = destsiz } - d = initxattrdest(dest, s) } return s, nil } -func Llistxattr(link string, dest []byte) (sz int, err error) { +func FlistxattrNS(fd int, nsid int, dest []byte) (sz int, err error) { d := initxattrdest(dest, 0) destsiz := len(dest) - s := 0 + s, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz) + if e != nil { + return 0, err + } + + return s, nil +} + +func Llistxattr(link string, dest []byte) (sz int, err error) { + destsiz := len(dest) + + s, pos := 0, 0 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { - stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz) - if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { - continue - } else if e != nil { + stmp, e := LlistxattrNS(link, nsid, dest[pos:]) + + if e != nil { + if e == EPERM && nsid != EXTATTR_NAMESPACE_USER { + continue + } return s, e } s += stmp - destsiz -= s - if destsiz < 0 { - destsiz = 0 + pos = s + if pos > destsiz { + pos = destsiz } - d = initxattrdest(dest, s) + } + + return s, nil +} + +func LlistxattrNS(link string, nsid int, dest []byte) (sz int, err error) { + d := initxattrdest(dest, 0) + destsiz := len(dest) + + s, e := ExtattrListLink(link, nsid, uintptr(d), destsiz) + if e != nil { + return 0, err } return s, nil diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go deleted file mode 100644 index a06eb0932..000000000 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go +++ /dev/null @@ -1,40 +0,0 @@ -// go run mksyscall.go -tags darwin,amd64,go1.13 syscall_darwin.1_13.go -// Code generated by the command above; see README.md. DO NOT EDIT. - -//go:build darwin && amd64 && go1.13 -// +build darwin,amd64,go1.13 - -package unix - -import ( - "syscall" - "unsafe" -) - -var _ syscall.Errno - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func closedir(dir uintptr) (err error) { - _, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_closedir_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) { - r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result))) - res = Errno(r0) - return -} - -var libc_readdir_r_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib" diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s deleted file mode 100644 index f5bb40eda..000000000 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s +++ /dev/null @@ -1,25 +0,0 @@ -// go run mkasm.go darwin amd64 -// Code generated by the command above; DO NOT EDIT. - -//go:build go1.13 -// +build go1.13 - -#include "textflag.h" - -TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_fdopendir(SB) - -GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8 -DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB) - -TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_closedir(SB) - -GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8 -DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB) - -TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_readdir_r(SB) - -GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8 -DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index 467deed76..c2461c496 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -1,8 +1,8 @@ -// go run mksyscall.go -tags darwin,amd64,go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go +// go run mksyscall.go -tags darwin,amd64 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go // Code generated by the command above; see README.md. DO NOT EDIT. -//go:build darwin && amd64 && go1.12 -// +build darwin,amd64,go1.12 +//go:build darwin && amd64 +// +build darwin,amd64 package unix @@ -463,6 +463,32 @@ var libc_munlockall_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func closedir(dir uintptr) (err error) { + _, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_closedir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) { + r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result))) + res = Errno(r0) + return +} + +var libc_readdir_r_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]int32) (err error) { _, _, e1 := syscall_rawSyscall(libc_pipe_trampoline_addr, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s index b41467a0e..95fe4c0eb 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s @@ -1,11 +1,14 @@ // go run mkasm.go darwin amd64 // Code generated by the command above; DO NOT EDIT. -//go:build go1.12 -// +build go1.12 - #include "textflag.h" +TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fdopendir(SB) + +GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB) + TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgroups(SB) @@ -174,6 +177,18 @@ TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8 DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB) +TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_closedir(SB) + +GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB) + +TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_readdir_r(SB) + +GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB) + TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pipe(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go deleted file mode 100644 index cec595d55..000000000 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go +++ /dev/null @@ -1,40 +0,0 @@ -// go run mksyscall.go -tags darwin,arm64,go1.13 syscall_darwin.1_13.go -// Code generated by the command above; see README.md. DO NOT EDIT. - -//go:build darwin && arm64 && go1.13 -// +build darwin,arm64,go1.13 - -package unix - -import ( - "syscall" - "unsafe" -) - -var _ syscall.Errno - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func closedir(dir uintptr) (err error) { - _, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_closedir_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) { - r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result))) - res = Errno(r0) - return -} - -var libc_readdir_r_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib" diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s deleted file mode 100644 index 0c3f76bc2..000000000 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s +++ /dev/null @@ -1,25 +0,0 @@ -// go run mkasm.go darwin arm64 -// Code generated by the command above; DO NOT EDIT. - -//go:build go1.13 -// +build go1.13 - -#include "textflag.h" - -TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_fdopendir(SB) - -GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8 -DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB) - -TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_closedir(SB) - -GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8 -DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB) - -TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_readdir_r(SB) - -GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8 -DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index 35938d34f..26a0fdc50 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -1,8 +1,8 @@ -// go run mksyscall.go -tags darwin,arm64,go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_arm64.go +// go run mksyscall.go -tags darwin,arm64 syscall_bsd.go syscall_darwin.go syscall_darwin_arm64.go // Code generated by the command above; see README.md. DO NOT EDIT. -//go:build darwin && arm64 && go1.12 -// +build darwin,arm64,go1.12 +//go:build darwin && arm64 +// +build darwin,arm64 package unix @@ -463,6 +463,32 @@ var libc_munlockall_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func closedir(dir uintptr) (err error) { + _, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_closedir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) { + r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result))) + res = Errno(r0) + return +} + +var libc_readdir_r_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]int32) (err error) { _, _, e1 := syscall_rawSyscall(libc_pipe_trampoline_addr, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s index e1f9204a2..efa5b4c98 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s @@ -1,11 +1,14 @@ // go run mkasm.go darwin arm64 // Code generated by the command above; DO NOT EDIT. -//go:build go1.12 -// +build go1.12 - #include "textflag.h" +TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fdopendir(SB) + +GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB) + TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgroups(SB) @@ -174,6 +177,18 @@ TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8 DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB) +TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_closedir(SB) + +GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB) + +TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_readdir_r(SB) + +GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB) + TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pipe(SB) diff --git a/vendor/golang.org/x/sys/windows/syscall.go b/vendor/golang.org/x/sys/windows/syscall.go index 72074d582..8732cdb95 100644 --- a/vendor/golang.org/x/sys/windows/syscall.go +++ b/vendor/golang.org/x/sys/windows/syscall.go @@ -30,8 +30,6 @@ import ( "strings" "syscall" "unsafe" - - "golang.org/x/sys/internal/unsafeheader" ) // ByteSliceFromString returns a NUL-terminated slice of bytes @@ -83,13 +81,7 @@ func BytePtrToString(p *byte) string { ptr = unsafe.Pointer(uintptr(ptr) + 1) } - var s []byte - h := (*unsafeheader.Slice)(unsafe.Pointer(&s)) - h.Data = unsafe.Pointer(p) - h.Len = n - h.Cap = n - - return string(s) + return string(unsafe.Slice(p, n)) } // Single-word zero for use when we need a valid pointer to 0 bytes. diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index e27913817..3f2cbb638 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -138,13 +138,7 @@ func UTF16PtrToString(p *uint16) string { ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p)) } - var s []uint16 - h := (*unsafeheader.Slice)(unsafe.Pointer(&s)) - h.Data = unsafe.Pointer(p) - h.Len = n - h.Cap = n - - return string(utf16.Decode(s)) + return string(utf16.Decode(unsafe.Slice(p, n))) } func Getpagesize() int { return 4096 } @@ -364,6 +358,15 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) //sys GetActiveProcessorCount(groupNumber uint16) (ret uint32) //sys GetMaximumProcessorCount(groupNumber uint16) (ret uint32) +//sys EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) = user32.EnumWindows +//sys EnumChildWindows(hwnd HWND, enumFunc uintptr, param unsafe.Pointer) = user32.EnumChildWindows +//sys GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, err error) = user32.GetClassNameW +//sys GetDesktopWindow() (hwnd HWND) = user32.GetDesktopWindow +//sys GetForegroundWindow() (hwnd HWND) = user32.GetForegroundWindow +//sys IsWindow(hwnd HWND) (isWindow bool) = user32.IsWindow +//sys IsWindowUnicode(hwnd HWND) (isUnicode bool) = user32.IsWindowUnicode +//sys IsWindowVisible(hwnd HWND) (isVisible bool) = user32.IsWindowVisible +//sys GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) = user32.GetGUIThreadInfo // Volume Management Functions //sys DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW @@ -439,6 +442,10 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys RtlAddFunctionTable(functionTable *RUNTIME_FUNCTION, entryCount uint32, baseAddress uintptr) (ret bool) = ntdll.RtlAddFunctionTable //sys RtlDeleteFunctionTable(functionTable *RUNTIME_FUNCTION) (ret bool) = ntdll.RtlDeleteFunctionTable +// Desktop Window Manager API (Dwmapi) +//sys DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) = dwmapi.DwmGetWindowAttribute +//sys DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) = dwmapi.DwmSetWindowAttribute + // syscall interface implementation for other packages // GetCurrentProcess returns the handle for the current process. diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index f9eaca528..0c4add974 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -3213,3 +3213,48 @@ type ModuleInfo struct { } const ALL_PROCESSOR_GROUPS = 0xFFFF + +type Rect struct { + Left int32 + Top int32 + Right int32 + Bottom int32 +} + +type GUIThreadInfo struct { + Size uint32 + Flags uint32 + Active HWND + Focus HWND + Capture HWND + MenuOwner HWND + MoveSize HWND + CaretHandle HWND + CaretRect Rect +} + +const ( + DWMWA_NCRENDERING_ENABLED = 1 + DWMWA_NCRENDERING_POLICY = 2 + DWMWA_TRANSITIONS_FORCEDISABLED = 3 + DWMWA_ALLOW_NCPAINT = 4 + DWMWA_CAPTION_BUTTON_BOUNDS = 5 + DWMWA_NONCLIENT_RTL_LAYOUT = 6 + DWMWA_FORCE_ICONIC_REPRESENTATION = 7 + DWMWA_FLIP3D_POLICY = 8 + DWMWA_EXTENDED_FRAME_BOUNDS = 9 + DWMWA_HAS_ICONIC_BITMAP = 10 + DWMWA_DISALLOW_PEEK = 11 + DWMWA_EXCLUDED_FROM_PEEK = 12 + DWMWA_CLOAK = 13 + DWMWA_CLOAKED = 14 + DWMWA_FREEZE_REPRESENTATION = 15 + DWMWA_PASSIVE_UPDATE_MODE = 16 + DWMWA_USE_HOSTBACKDROPBRUSH = 17 + DWMWA_USE_IMMERSIVE_DARK_MODE = 20 + DWMWA_WINDOW_CORNER_PREFERENCE = 33 + DWMWA_BORDER_COLOR = 34 + DWMWA_CAPTION_COLOR = 35 + DWMWA_TEXT_COLOR = 36 + DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 37 +) diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 52d4742cb..96ba8559c 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -40,6 +40,7 @@ var ( modadvapi32 = NewLazySystemDLL("advapi32.dll") modcrypt32 = NewLazySystemDLL("crypt32.dll") moddnsapi = NewLazySystemDLL("dnsapi.dll") + moddwmapi = NewLazySystemDLL("dwmapi.dll") modiphlpapi = NewLazySystemDLL("iphlpapi.dll") modkernel32 = NewLazySystemDLL("kernel32.dll") modmswsock = NewLazySystemDLL("mswsock.dll") @@ -175,6 +176,8 @@ var ( procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W") procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W") procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree") + procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute") + procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx") @@ -444,9 +447,18 @@ var ( procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW") procSHGetKnownFolderPath = modshell32.NewProc("SHGetKnownFolderPath") procShellExecuteW = modshell32.NewProc("ShellExecuteW") + procEnumChildWindows = moduser32.NewProc("EnumChildWindows") + procEnumWindows = moduser32.NewProc("EnumWindows") procExitWindowsEx = moduser32.NewProc("ExitWindowsEx") + procGetClassNameW = moduser32.NewProc("GetClassNameW") + procGetDesktopWindow = moduser32.NewProc("GetDesktopWindow") + procGetForegroundWindow = moduser32.NewProc("GetForegroundWindow") + procGetGUIThreadInfo = moduser32.NewProc("GetGUIThreadInfo") procGetShellWindow = moduser32.NewProc("GetShellWindow") procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId") + procIsWindow = moduser32.NewProc("IsWindow") + procIsWindowUnicode = moduser32.NewProc("IsWindowUnicode") + procIsWindowVisible = moduser32.NewProc("IsWindowVisible") procMessageBoxW = moduser32.NewProc("MessageBoxW") procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock") procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock") @@ -1525,6 +1537,22 @@ func DnsRecordListFree(rl *DNSRecord, freetype uint32) { return } +func DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) { + r0, _, _ := syscall.Syscall6(procDwmGetWindowAttribute.Addr(), 4, uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size), 0, 0) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) { + r0, _, _ := syscall.Syscall6(procDwmSetWindowAttribute.Addr(), 4, uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size), 0, 0) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) if r0 != 0 { @@ -3802,6 +3830,19 @@ func ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *ui return } +func EnumChildWindows(hwnd HWND, enumFunc uintptr, param unsafe.Pointer) { + syscall.Syscall(procEnumChildWindows.Addr(), 3, uintptr(hwnd), uintptr(enumFunc), uintptr(param)) + return +} + +func EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) { + r1, _, e1 := syscall.Syscall(procEnumWindows.Addr(), 2, uintptr(enumFunc), uintptr(param), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func ExitWindowsEx(flags uint32, reason uint32) (err error) { r1, _, e1 := syscall.Syscall(procExitWindowsEx.Addr(), 2, uintptr(flags), uintptr(reason), 0) if r1 == 0 { @@ -3810,6 +3851,35 @@ func ExitWindowsEx(flags uint32, reason uint32) (err error) { return } +func GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, err error) { + r0, _, e1 := syscall.Syscall(procGetClassNameW.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(className)), uintptr(maxCount)) + copied = int32(r0) + if copied == 0 { + err = errnoErr(e1) + } + return +} + +func GetDesktopWindow() (hwnd HWND) { + r0, _, _ := syscall.Syscall(procGetDesktopWindow.Addr(), 0, 0, 0, 0) + hwnd = HWND(r0) + return +} + +func GetForegroundWindow() (hwnd HWND) { + r0, _, _ := syscall.Syscall(procGetForegroundWindow.Addr(), 0, 0, 0, 0) + hwnd = HWND(r0) + return +} + +func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) { + r1, _, e1 := syscall.Syscall(procGetGUIThreadInfo.Addr(), 2, uintptr(thread), uintptr(unsafe.Pointer(info)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetShellWindow() (shellWindow HWND) { r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0) shellWindow = HWND(r0) @@ -3825,6 +3895,24 @@ func GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) { return } +func IsWindow(hwnd HWND) (isWindow bool) { + r0, _, _ := syscall.Syscall(procIsWindow.Addr(), 1, uintptr(hwnd), 0, 0) + isWindow = r0 != 0 + return +} + +func IsWindowUnicode(hwnd HWND) (isUnicode bool) { + r0, _, _ := syscall.Syscall(procIsWindowUnicode.Addr(), 1, uintptr(hwnd), 0, 0) + isUnicode = r0 != 0 + return +} + +func IsWindowVisible(hwnd HWND) (isVisible bool) { + r0, _, _ := syscall.Syscall(procIsWindowVisible.Addr(), 1, uintptr(hwnd), 0, 0) + isVisible = r0 != 0 + return +} + func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) { r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0) ret = int32(r0) diff --git a/vendor/modules.txt b/vendor/modules.txt index f06b92015..714e6fbfa 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -64,7 +64,7 @@ github.com/checkpoint-restore/go-criu/v5/stats # github.com/chzyer/readline v1.5.1 ## explicit; go 1.15 github.com/chzyer/readline -# github.com/container-orchestrated-devices/container-device-interface v0.5.1 +# github.com/container-orchestrated-devices/container-device-interface v0.5.2 ## explicit; go 1.17 github.com/container-orchestrated-devices/container-device-interface/pkg/cdi github.com/container-orchestrated-devices/container-device-interface/specs-go @@ -97,7 +97,7 @@ github.com/containernetworking/cni/pkg/version # github.com/containernetworking/plugins v1.1.1 ## explicit; go 1.17 github.com/containernetworking/plugins/pkg/ns -# github.com/containers/buildah v1.27.1-0.20220907121344-97a52b13bb27 +# github.com/containers/buildah v1.27.1-0.20220921131114-d3064796af36 ## explicit; go 1.17 github.com/containers/buildah github.com/containers/buildah/bind @@ -120,7 +120,7 @@ github.com/containers/buildah/pkg/rusage github.com/containers/buildah/pkg/sshagent github.com/containers/buildah/pkg/util github.com/containers/buildah/util -# github.com/containers/common v0.49.2-0.20220909190843-e5685792b5d7 +# github.com/containers/common v0.50.1 ## explicit; go 1.17 github.com/containers/common/libimage github.com/containers/common/libimage/define @@ -174,7 +174,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.22.1-0.20220907162003-651744379993 +# github.com/containers/image/v5 v5.23.0 ## explicit; go 1.17 github.com/containers/image/v5/copy github.com/containers/image/v5/directory @@ -266,7 +266,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.42.1-0.20220911223137-e11b246de159 +# github.com/containers/storage v1.43.0 ## explicit; go 1.16 github.com/containers/storage github.com/containers/storage/drivers @@ -388,8 +388,8 @@ github.com/docker/docker/pkg/parsers github.com/docker/docker/pkg/pools github.com/docker/docker/pkg/stdcopy github.com/docker/docker/pkg/system -# github.com/docker/docker-credential-helpers v0.6.4 -## explicit; go 1.13 +# github.com/docker/docker-credential-helpers v0.7.0 +## explicit; go 1.18 github.com/docker/docker-credential-helpers/client github.com/docker/docker-credential-helpers/credentials # github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 @@ -438,7 +438,7 @@ github.com/golang/protobuf/ptypes github.com/golang/protobuf/ptypes/any github.com/golang/protobuf/ptypes/duration github.com/golang/protobuf/ptypes/timestamp -# github.com/google/go-cmp v0.5.8 +# github.com/google/go-cmp v0.5.9 ## explicit; go 1.13 github.com/google/go-cmp/cmp github.com/google/go-cmp/cmp/internal/diff @@ -476,8 +476,6 @@ github.com/hashicorp/errwrap # github.com/hashicorp/go-multierror v1.1.1 ## explicit; go 1.13 github.com/hashicorp/go-multierror -# github.com/honeycombio/libhoney-go v1.15.8 -## explicit; go 1.14 # github.com/imdario/mergo v0.3.13 ## explicit; go 1.13 github.com/imdario/mergo @@ -490,8 +488,8 @@ github.com/jinzhu/copier # github.com/json-iterator/go v1.1.12 ## explicit; go 1.12 github.com/json-iterator/go -# github.com/klauspost/compress v1.15.9 -## explicit; go 1.16 +# github.com/klauspost/compress v1.15.11 +## explicit; go 1.17 github.com/klauspost/compress github.com/klauspost/compress/flate github.com/klauspost/compress/fse @@ -500,7 +498,7 @@ github.com/klauspost/compress/internal/cpuinfo github.com/klauspost/compress/internal/snapref github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash -# github.com/klauspost/pgzip v1.2.5 +# github.com/klauspost/pgzip v1.2.6-0.20220930104621-17e8dac29df8 ## explicit github.com/klauspost/pgzip # github.com/kr/fs v0.1.0 @@ -534,9 +532,9 @@ github.com/mattn/go-shellwords # github.com/miekg/pkcs11 v1.1.1 ## explicit; go 1.12 github.com/miekg/pkcs11 -# github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible -## explicit -github.com/mistifyio/go-zfs +# github.com/mistifyio/go-zfs/v3 v3.0.0 +## explicit; go 1.14 +github.com/mistifyio/go-zfs/v3 # github.com/moby/sys/mount v0.3.3 ## explicit; go 1.16 github.com/moby/sys/mount @@ -613,8 +611,8 @@ github.com/onsi/gomega/types # github.com/opencontainers/go-digest v1.0.0 ## explicit; go 1.13 github.com/opencontainers/go-digest -# github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 -## explicit; go 1.11 +# github.com/opencontainers/image-spec v1.1.0-rc1 +## explicit; go 1.17 github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 # github.com/opencontainers/runc v1.1.4 => github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc @@ -640,7 +638,7 @@ github.com/opencontainers/runtime-tools/generate github.com/opencontainers/runtime-tools/generate/seccomp github.com/opencontainers/runtime-tools/specerror github.com/opencontainers/runtime-tools/validate -# github.com/opencontainers/selinux v1.10.1 +# github.com/opencontainers/selinux v1.10.2 ## explicit; go 1.13 github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label @@ -692,8 +690,8 @@ github.com/rootless-containers/rootlesskit/pkg/port/portutil # github.com/seccomp/libseccomp-golang v0.10.0 ## explicit; go 1.14 github.com/seccomp/libseccomp-golang -# github.com/sigstore/sigstore v1.4.0 -## explicit; go 1.17 +# github.com/sigstore/sigstore v1.4.2 +## explicit; go 1.18 github.com/sigstore/sigstore/pkg/cryptoutils github.com/sigstore/sigstore/pkg/signature github.com/sigstore/sigstore/pkg/signature/options @@ -715,7 +713,7 @@ github.com/stefanberger/go-pkcs11uri ## explicit; go 1.13 github.com/stretchr/testify/assert github.com/stretchr/testify/require -# github.com/sylabs/sif/v2 v2.7.2 +# github.com/sylabs/sif/v2 v2.8.0 ## explicit; go 1.18 github.com/sylabs/sif/v2/pkg/sif # github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 @@ -724,7 +722,7 @@ github.com/syndtr/gocapability/capability # github.com/tchap/go-patricia v2.3.0+incompatible ## explicit github.com/tchap/go-patricia/patricia -# github.com/theupdateframework/go-tuf v0.4.0 +# github.com/theupdateframework/go-tuf v0.5.1 ## explicit; go 1.18 github.com/theupdateframework/go-tuf/encrypted # github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 @@ -762,6 +760,8 @@ github.com/vishvananda/netlink/nl # github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f ## explicit; go 1.12 github.com/vishvananda/netns +# github.com/vmihailenco/msgpack/v5 v5.3.5 +## explicit; go 1.11 # github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb ## explicit github.com/xeipuuv/gojsonpointer @@ -784,7 +784,7 @@ go.opencensus.io/internal go.opencensus.io/trace go.opencensus.io/trace/internal go.opencensus.io/trace/tracestate -# golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa +# golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 ## explicit; go 1.17 golang.org/x/crypto/blowfish golang.org/x/crypto/cast5 @@ -792,8 +792,8 @@ golang.org/x/crypto/chacha20 golang.org/x/crypto/curve25519 golang.org/x/crypto/curve25519/internal/field golang.org/x/crypto/ed25519 +golang.org/x/crypto/internal/alias golang.org/x/crypto/internal/poly1305 -golang.org/x/crypto/internal/subtle golang.org/x/crypto/nacl/secretbox golang.org/x/crypto/ocsp golang.org/x/crypto/openpgp @@ -810,7 +810,7 @@ golang.org/x/crypto/ssh golang.org/x/crypto/ssh/agent golang.org/x/crypto/ssh/internal/bcrypt_pbkdf golang.org/x/crypto/ssh/knownhosts -# golang.org/x/net v0.0.0-20220722155237-a158d28d115b +# golang.org/x/net v0.0.0-20220909164309-bea034e7d591 ## explicit; go 1.17 golang.org/x/net/context golang.org/x/net/html @@ -826,7 +826,7 @@ golang.org/x/net/trace ## explicit golang.org/x/sync/errgroup golang.org/x/sync/semaphore -# golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 +# golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 ## explicit; go 1.17 golang.org/x/sys/cpu golang.org/x/sys/execabs |