summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml4
-rw-r--r--.golangci.yml1
-rw-r--r--Makefile2
-rw-r--r--cmd/podman/containers/clone.go9
-rw-r--r--cmd/podman/containers/create.go6
-rw-r--r--cmd/podman/containers/export.go4
-rw-r--r--cmd/podman/containers/run.go4
-rw-r--r--cmd/podman/images/load.go4
-rw-r--r--cmd/podman/images/save.go4
-rw-r--r--cmd/podman/machine/init.go15
-rw-r--r--cmd/podman/machine/set.go7
-rw-r--r--cmd/podman/volumes/unmount.go1
-rwxr-xr-xcontrib/cirrus/logformatter2
-rwxr-xr-xcontrib/cirrus/pr-should-include-tests3
-rwxr-xr-xcontrib/cirrus/runner.sh67
-rwxr-xr-xcontrib/cirrus/setup_environment.sh5
-rw-r--r--contrib/podmanimage/README.md2
-rw-r--r--contrib/remote/containers.conf2
-rw-r--r--docs/source/markdown/podman-build.1.md2
-rw-r--r--docs/source/markdown/podman-container-clone.1.md4
-rw-r--r--docs/source/markdown/podman-image-scp.1.md2
-rw-r--r--docs/source/markdown/podman-image-unmount.1.md2
-rw-r--r--docs/source/markdown/podman-machine-init.1.md6
-rw-r--r--docs/source/markdown/podman-machine-set.1.md20
-rw-r--r--go.mod7
-rw-r--r--go.sum17
-rwxr-xr-xhack/make-and-check-size5
-rw-r--r--libpod/container_inspect.go4
-rw-r--r--libpod/container_internal_linux.go7
-rw-r--r--libpod/define/container_inspect.go2
-rw-r--r--libpod/healthcheck_linux.go2
-rw-r--r--libpod/networking_slirp4netns.go2
-rw-r--r--libpod/options.go3
-rw-r--r--libpod/runtime_ctr.go4
-rw-r--r--pkg/api/handlers/libpod/manifests.go18
-rw-r--r--pkg/api/server/register_manifest.go4
-rw-r--r--pkg/bindings/README.md8
-rw-r--r--pkg/bindings/containers/attach.go2
-rw-r--r--pkg/bindings/containers/term_unix.go8
-rw-r--r--pkg/bindings/containers/term_windows.go10
-rw-r--r--pkg/bindings/test/images_test.go18
-rw-r--r--pkg/bindings/test/secrets_test.go2
-rw-r--r--pkg/domain/entities/containers.go1
-rw-r--r--pkg/domain/infra/abi/containers.go2
-rw-r--r--pkg/domain/infra/abi/images.go6
-rw-r--r--pkg/domain/infra/abi/terminal/terminal_linux.go6
-rw-r--r--pkg/domain/infra/tunnel/pods.go4
-rw-r--r--pkg/machine/config.go4
-rw-r--r--pkg/machine/fcos.go4
-rw-r--r--pkg/machine/qemu/config.go8
-rw-r--r--pkg/machine/qemu/machine.go20
-rw-r--r--pkg/machine/wsl/machine.go22
-rw-r--r--pkg/specgen/generate/container.go2
-rw-r--r--pkg/specgen/generate/container_create.go2
-rw-r--r--pkg/specgen/generate/kube/kube.go6
-rw-r--r--pkg/specgenutil/volumes.go11
-rw-r--r--pkg/systemd/dbus.go3
-rw-r--r--pkg/terminal/util.go6
-rw-r--r--pkg/util/utils.go4
-rw-r--r--rootless.md2
-rw-r--r--test/e2e/checkpoint_test.go2
-rw-r--r--test/e2e/common_test.go15
-rw-r--r--test/e2e/container_clone_test.go32
-rw-r--r--test/e2e/create_test.go9
-rw-r--r--test/e2e/exec_test.go2
-rw-r--r--test/e2e/libpod_suite_remote_test.go3
-rw-r--r--test/e2e/login_logout_test.go2
-rw-r--r--test/e2e/mount_rootless_test.go2
-rw-r--r--test/e2e/network_test.go2
-rw-r--r--test/e2e/pod_create_test.go8
-rw-r--r--test/e2e/push_test.go1
-rw-r--r--test/e2e/run_volume_test.go5
-rw-r--r--test/e2e/systemd_activate_test.go2
-rw-r--r--test/system/000-TEMPLATE10
-rw-r--r--test/system/001-basic.bats26
-rw-r--r--test/system/015-help.bats21
-rw-r--r--test/system/030-run.bats53
-rw-r--r--test/system/035-logs.bats5
-rw-r--r--test/system/040-ps.bats5
-rw-r--r--test/system/045-start.bats5
-rw-r--r--test/system/050-stop.bats17
-rw-r--r--test/system/065-cp.bats28
-rw-r--r--test/system/070-build.bats56
-rw-r--r--test/system/090-events.bats5
-rw-r--r--test/system/120-load.bats10
-rw-r--r--test/system/160-volumes.bats4
-rw-r--r--test/system/180-blkio.bats3
-rw-r--r--test/system/190-run-ipcns.bats42
-rw-r--r--test/system/200-pod.bats17
-rw-r--r--test/system/250-systemd.bats60
-rw-r--r--test/system/255-auto-update.bats11
-rw-r--r--test/system/270-socket-activation.bats2
-rw-r--r--test/system/400-unprivileged-access.bats4
-rw-r--r--test/system/410-selinux.bats10
-rw-r--r--test/system/450-interactive.bats4
-rw-r--r--test/system/500-networking.bats65
-rw-r--r--test/system/520-checkpoint.bats18
-rw-r--r--test/system/600-completion.bats11
-rw-r--r--test/system/750-trust.bats3
-rw-r--r--test/system/helpers.bash113
-rw-r--r--test/upgrade/test-upgrade.bats8
-rw-r--r--test/utils/common_function_test.go3
-rw-r--r--test/utils/utils.go4
-rw-r--r--test/version/main.go2
-rw-r--r--utils/utils_supported.go7
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go10
-rw-r--r--vendor/github.com/containers/common/pkg/config/containers.conf41
-rw-r--r--vendor/github.com/containers/common/pkg/config/default.go6
-rw-r--r--vendor/github.com/containers/common/pkg/secrets/shelldriver/shelldriver.go25
-rw-r--r--vendor/github.com/containers/image/v5/copy/copy.go11
-rw-r--r--vendor/github.com/containers/image/v5/directory/directory_dest.go15
-rw-r--r--vendor/github.com/containers/image/v5/directory/directory_src.go5
-rw-r--r--vendor/github.com/containers/image/v5/docker/docker_client.go3
-rw-r--r--vendor/github.com/containers/image/v5/docker/docker_image_dest.go3
-rw-r--r--vendor/github.com/containers/image/v5/docker/docker_image_src.go9
-rw-r--r--vendor/github.com/containers/image/v5/docker/internal/tarfile/reader.go3
-rw-r--r--vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go5
-rw-r--r--vendor/github.com/containers/image/v5/docker/lookaside.go3
-rw-r--r--vendor/github.com/containers/image/v5/internal/iolimits/iolimits.go3
-rw-r--r--vendor/github.com/containers/image/v5/internal/streamdigest/stream_digest.go3
-rw-r--r--vendor/github.com/containers/image/v5/oci/archive/oci_transport.go3
-rw-r--r--vendor/github.com/containers/image/v5/oci/layout/oci_dest.go9
-rw-r--r--vendor/github.com/containers/image/v5/oci/layout/oci_src.go3
-rw-r--r--vendor/github.com/containers/image/v5/openshift/openshift-copies.go5
-rw-r--r--vendor/github.com/containers/image/v5/ostree/ostree_dest.go23
-rw-r--r--vendor/github.com/containers/image/v5/ostree/ostree_src.go3
-rw-r--r--vendor/github.com/containers/image/v5/pkg/blobcache/blobcache.go13
-rw-r--r--vendor/github.com/containers/image/v5/pkg/compression/compression.go7
-rw-r--r--vendor/github.com/containers/image/v5/pkg/docker/config/config.go3
-rw-r--r--vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go9
-rw-r--r--vendor/github.com/containers/image/v5/pkg/tlsclientconfig/tlsclientconfig.go7
-rw-r--r--vendor/github.com/containers/image/v5/sif/load.go7
-rw-r--r--vendor/github.com/containers/image/v5/sif/src.go5
-rw-r--r--vendor/github.com/containers/image/v5/signature/mechanism.go4
-rw-r--r--vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go3
-rw-r--r--vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go6
-rw-r--r--vendor/github.com/containers/image/v5/signature/policy_config.go3
-rw-r--r--vendor/github.com/containers/image/v5/signature/policy_eval_signedby.go4
-rw-r--r--vendor/github.com/containers/image/v5/storage/storage_image.go13
-rw-r--r--vendor/github.com/containers/image/v5/tarball/tarball_src.go7
-rw-r--r--vendor/github.com/containers/image/v5/tarball/tarball_transport.go4
-rw-r--r--vendor/github.com/containers/storage/Makefile18
-rw-r--r--vendor/github.com/containers/storage/drivers/driver_freebsd.go29
-rw-r--r--vendor/github.com/containers/storage/drivers/register/register_zfs.go2
-rw-r--r--vendor/github.com/containers/storage/drivers/zfs/zfs.go4
-rw-r--r--vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go5
-rw-r--r--vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go5
-rw-r--r--vendor/github.com/containers/storage/layers.go10
-rw-r--r--vendor/github.com/containers/storage/storage.conf-freebsd205
-rw-r--r--vendor/github.com/mitchellh/mapstructure/CHANGELOG.md83
-rw-r--r--vendor/github.com/mitchellh/mapstructure/LICENSE21
-rw-r--r--vendor/github.com/mitchellh/mapstructure/README.md46
-rw-r--r--vendor/github.com/mitchellh/mapstructure/decode_hooks.go257
-rw-r--r--vendor/github.com/mitchellh/mapstructure/error.go50
-rw-r--r--vendor/github.com/mitchellh/mapstructure/go.mod3
-rw-r--r--vendor/github.com/mitchellh/mapstructure/mapstructure.go1467
-rw-r--r--vendor/golang.org/x/crypto/ssh/terminal/terminal.go76
-rw-r--r--vendor/modules.txt12
158 files changed, 1068 insertions, 2642 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index c984c8859..cf97f4467 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -101,6 +101,10 @@ ext_svc_check_task:
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"
make install.tools
setup_script: &setup '$GOSRC/$SCRIPT_BASE/setup_environment.sh'
diff --git a/.golangci.yml b/.golangci.yml
index 956e528ef..8a922775a 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -32,7 +32,6 @@ linters:
- predeclared
- thelper
- ifshort
- - staticcheck
- forbidigo
- exhaustive
- unparam
diff --git a/Makefile b/Makefile
index e94d4cf73..502323906 100644
--- a/Makefile
+++ b/Makefile
@@ -877,7 +877,7 @@ install.tools: .install.goimports .install.gitvalidation .install.md2man .instal
.PHONY: .install.golangci-lint
.install.golangci-lint: .gopathok
- VERSION=1.45.0 GOBIN=$(GOBIN) ./hack/install_golangci.sh
+ VERSION=1.45.2 GOBIN=$(GOBIN) ./hack/install_golangci.sh
.PHONY: .install.bats
.install.bats: .gopathok
diff --git a/cmd/podman/containers/clone.go b/cmd/podman/containers/clone.go
index 8a1473608..6912da1fc 100644
--- a/cmd/podman/containers/clone.go
+++ b/cmd/podman/containers/clone.go
@@ -38,6 +38,9 @@ func cloneFlags(cmd *cobra.Command) {
runFlagName := "run"
flags.BoolVar(&ctrClone.Run, runFlagName, false, "run the new container")
+ forceFlagName := "force"
+ flags.BoolVarP(&ctrClone.Force, forceFlagName, "f", false, "force the existing container to be destroyed")
+
common.DefineCreateFlags(cmd, &ctrClone.CreateOpts, false, true)
}
func init() {
@@ -52,7 +55,7 @@ func init() {
func clone(cmd *cobra.Command, args []string) error {
switch len(args) {
case 0:
- return errors.Wrapf(define.ErrInvalidArg, "Must Specify at least 1 argument")
+ return errors.Wrapf(define.ErrInvalidArg, "must specify at least 1 argument")
case 2:
ctrClone.CreateOpts.Name = args[1]
case 3:
@@ -68,6 +71,10 @@ func clone(cmd *cobra.Command, args []string) error {
ctrClone.RawImageName = rawImageName
}
}
+ if ctrClone.Force && !ctrClone.Destroy {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot set --force without --destroy")
+ }
+
ctrClone.ID = args[0]
ctrClone.CreateOpts.IsClone = true
rep, err := registry.ContainerEngine().ContainerClone(registry.GetContext(), ctrClone)
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index bbc449a1e..b202e404f 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -286,8 +286,6 @@ func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra
if !isInfra && c.Flag("entrypoint").Changed {
val := c.Flag("entrypoint").Value.String()
vals.Entrypoint = &val
- } else if isInfra && c.Flag("infra-command").Changed {
-
}
// Docker-compatibility: the "-h" flag for run/create is reserved for
@@ -297,7 +295,7 @@ func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra
}
func PullImage(imageName string, cliVals entities.ContainerCreateOptions) (string, error) {
- pullPolicy, err := config.ValidatePullPolicy(cliVals.Pull)
+ pullPolicy, err := config.ParsePullPolicy(cliVals.Pull)
if err != nil {
return "", err
}
@@ -383,7 +381,7 @@ func createPodIfNecessary(cmd *cobra.Command, s *specgen.SpecGenerator, netOpts
podSpec := entities.PodSpec{}
podGen := specgen.NewPodSpecGenerator()
podSpec.PodSpecGen = *podGen
- podGen, err = entities.ToPodSpecGen(*&podSpec.PodSpecGen, &createOptions)
+ podGen, err = entities.ToPodSpecGen(podSpec.PodSpecGen, &createOptions)
if err != nil {
return nil, err
}
diff --git a/cmd/podman/containers/export.go b/cmd/podman/containers/export.go
index 0fed94e86..681df93e0 100644
--- a/cmd/podman/containers/export.go
+++ b/cmd/podman/containers/export.go
@@ -11,7 +11,7 @@ import (
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/pkg/errors"
"github.com/spf13/cobra"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
var (
@@ -69,7 +69,7 @@ func init() {
func export(cmd *cobra.Command, args []string) error {
if len(exportOpts.Output) == 0 {
file := os.Stdout
- if terminal.IsTerminal(int(file.Fd())) {
+ if term.IsTerminal(int(file.Fd())) {
return errors.Errorf("refusing to export to terminal. Use -o flag or redirect")
}
exportOpts.Output = "/dev/stdout"
diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go
index 1d98eb3b3..4ad8d3183 100644
--- a/cmd/podman/containers/run.go
+++ b/cmd/podman/containers/run.go
@@ -18,7 +18,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
var (
@@ -112,7 +112,7 @@ func run(cmd *cobra.Command, args []string) error {
var err error
// TODO: Breaking change should be made fatal in next major Release
- if cliVals.TTY && cliVals.Interactive && !terminal.IsTerminal(int(os.Stdin.Fd())) {
+ if cliVals.TTY && cliVals.Interactive && !term.IsTerminal(int(os.Stdin.Fd())) {
logrus.Warnf("The input device is not a TTY. The --tty and --interactive flags might not work properly")
}
diff --git a/cmd/podman/images/load.go b/cmd/podman/images/load.go
index 30f88b02b..6f85fb7e7 100644
--- a/cmd/podman/images/load.go
+++ b/cmd/podman/images/load.go
@@ -16,7 +16,7 @@ import (
"github.com/containers/podman/v4/pkg/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
var (
@@ -90,7 +90,7 @@ func load(cmd *cobra.Command, args []string) error {
return err
}
} else {
- if terminal.IsTerminal(int(os.Stdin.Fd())) {
+ if term.IsTerminal(int(os.Stdin.Fd())) {
return errors.Errorf("cannot read from terminal. Use command-line redirection or the --input flag.")
}
outFile, err := ioutil.TempFile(util.Tmpdir(), "podman")
diff --git a/cmd/podman/images/save.go b/cmd/podman/images/save.go
index a9fe675e1..fb642bafd 100644
--- a/cmd/podman/images/save.go
+++ b/cmd/podman/images/save.go
@@ -14,7 +14,7 @@ import (
"github.com/containers/podman/v4/pkg/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
var (
@@ -109,7 +109,7 @@ func save(cmd *cobra.Command, args []string) (finalErr error) {
if len(saveOpts.Output) == 0 {
saveOpts.Quiet = true
fi := os.Stdout
- if terminal.IsTerminal(int(fi.Fd())) {
+ if term.IsTerminal(int(fi.Fd())) {
return errors.Errorf("refusing to save to terminal. Use -o flag or redirect")
}
pipePath, cleanup, err := setupPipe()
diff --git a/cmd/podman/machine/init.go b/cmd/podman/machine/init.go
index 2d0afbf05..06c1f7248 100644
--- a/cmd/podman/machine/init.go
+++ b/cmd/podman/machine/init.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/podman/v4/pkg/machine"
"github.com/pkg/errors"
"github.com/spf13/cobra"
+ "github.com/spf13/pflag"
)
var (
@@ -106,8 +107,18 @@ func init() {
flags.StringVar(&initOpts.IgnitionPath, IgnitionPathFlagName, "", "Path to ignition file")
_ = initCmd.RegisterFlagCompletionFunc(IgnitionPathFlagName, completion.AutocompleteDefault)
- rootfulFlagName := "rootful"
- flags.BoolVar(&initOpts.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")
+ rootfullFlagName := "rootfull"
+ flags.BoolVar(&initOpts.Rootfull, rootfullFlagName, false, "Whether this machine should prefer rootfull container execution")
+ flags.SetNormalizeFunc(aliasFlags)
+}
+
+// aliasFlags is a function to handle backwards compatibility with old flags
+func aliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ switch name {
+ case "rootful":
+ name = "rootfull"
+ }
+ return pflag.NormalizedName(name)
}
// TODO should we allow for a users to append to the qemu cmdline?
diff --git a/cmd/podman/machine/set.go b/cmd/podman/machine/set.go
index 4c15f1de1..b1dfb51da 100644
--- a/cmd/podman/machine/set.go
+++ b/cmd/podman/machine/set.go
@@ -17,7 +17,7 @@ var (
Long: "Sets an updatable virtual machine setting",
RunE: setMachine,
Args: cobra.MaximumNArgs(1),
- Example: `podman machine set --rootful=false`,
+ Example: `podman machine set --rootfull=false`,
ValidArgsFunction: completion.AutocompleteNone,
}
)
@@ -33,8 +33,9 @@ func init() {
})
flags := setCmd.Flags()
- rootfulFlagName := "rootful"
- flags.BoolVar(&setOpts.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")
+ rootfullFlagName := "rootfull"
+ flags.BoolVar(&setOpts.Rootfull, rootfullFlagName, false, "Whether this machine should prefer rootfull container execution")
+ flags.SetNormalizeFunc(aliasFlags)
}
func setMachine(cmd *cobra.Command, args []string) error {
diff --git a/cmd/podman/volumes/unmount.go b/cmd/podman/volumes/unmount.go
index dd0cebc06..af79e49ef 100644
--- a/cmd/podman/volumes/unmount.go
+++ b/cmd/podman/volumes/unmount.go
@@ -37,7 +37,6 @@ func volumeUnmount(cmd *cobra.Command, args []string) error {
return err
}
for _, r := range reports {
- var errs utils.OutputErrors
if r.Err == nil {
fmt.Println(r.Id)
} else {
diff --git a/contrib/cirrus/logformatter b/contrib/cirrus/logformatter
index 3ec839aa8..3c52e612b 100755
--- a/contrib/cirrus/logformatter
+++ b/contrib/cirrus/logformatter
@@ -204,7 +204,7 @@ END_HTML
print { $out_fh } "<pre> <!-- begin processed output -->\n";
- # Assume rootful prompt, check for rootless (here and in log itself, below)
+ # Assume rootfull prompt, check for rootless (here and in log itself, below)
my $Prompt = '#';
$Prompt = '$' if $test_name =~ /rootless/;
diff --git a/contrib/cirrus/pr-should-include-tests b/contrib/cirrus/pr-should-include-tests
index 8103df41d..0d39047a6 100755
--- a/contrib/cirrus/pr-should-include-tests
+++ b/contrib/cirrus/pr-should-include-tests
@@ -30,8 +30,7 @@ fi
# Nothing changed under test subdirectory.
#
# This is OK if the only files being touched are "safe" ones.
-filtered_changes=$(git diff --name-status $base $head |
- awk '{print $2}' |
+filtered_changes=$(git diff --name-only $base $head |
fgrep -vx .cirrus.yml |
fgrep -vx .gitignore |
fgrep -vx Makefile |
diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh
index f33c6af29..8f956d7f5 100755
--- a/contrib/cirrus/runner.sh
+++ b/contrib/cirrus/runner.sh
@@ -46,6 +46,8 @@ function _run_validate() {
}
function _run_unit() {
+ _bail_if_test_can_be_skipped test/goecho test/version
+
# shellcheck disable=SC2154
if [[ "$PODBIN_NAME" != "podman" ]]; then
# shellcheck disable=SC2154
@@ -55,31 +57,45 @@ function _run_unit() {
}
function _run_apiv2() {
+ _bail_if_test_can_be_skipped test/apiv2
+
source .venv/requests/bin/activate
make localapiv2 |& logformatter
}
function _run_compose() {
+ _bail_if_test_can_be_skipped test/compose
+
./test/compose/test-compose |& logformatter
}
function _run_compose_v2() {
+ _bail_if_test_can_be_skipped test/compose
+
./test/compose/test-compose |& logformatter
}
function _run_int() {
+ _bail_if_test_can_be_skipped test/e2e
+
dotest integration
}
function _run_sys() {
+ _bail_if_test_can_be_skipped test/system
+
dotest system
}
function _run_upgrade_test() {
+ _bail_if_test_can_be_skipped test/upgrade
+
bats test/upgrade |& logformatter
}
function _run_bud() {
+ _bail_if_test_can_be_skipped test/buildah-bud
+
./test/buildah-bud/run-buildah-bud-tests |& logformatter
}
@@ -217,6 +233,9 @@ function _run_build() {
}
function _run_altbuild() {
+ # We can skip all these steps for test-only PRs, but not doc-only ones
+ _bail_if_test_can_be_skipped docs
+
local -a arches
local arch
req_env_vars ALT_NAME
@@ -345,6 +364,54 @@ dotest() {
|& logformatter
}
+# Optimization: will exit if the only PR diffs are under docs/ or tests/
+# with the exception of any given arguments. E.g., don't run e2e or upgrade
+# or bud tests if the only PR changes are in test/system.
+function _bail_if_test_can_be_skipped() {
+ local head base diffs
+
+ # Cirrus sets these for PRs but not cron. In cron, we never want to skip.
+ for v in CIRRUS_CHANGE_IN_REPO DEST_BRANCH; do
+ if [[ -z "${!v}" ]]; then
+ msg "[ _cannot do selective skip: \$$v is undefined ]"
+ return 0
+ fi
+ done
+ # And if this one *is* defined, it means we're not in PR-land; don't skip.
+ if [[ -n "$CIRRUS_TAG" ]]; then
+ msg "[ _cannot do selective skip: \$CIRRUS_TAG is defined ]"
+ return 0
+ fi
+
+ head=$CIRRUS_CHANGE_IN_REPO
+ base=$(git merge-base $DEST_BRANCH $head)
+ diffs=$(git diff --name-only $base $head)
+
+ # If PR touches any files in an argument directory, we cannot skip
+ for subdir in "$@"; do
+ if egrep -q "^$subdir/" <<<"$diffs"; then
+ return 0
+ fi
+ done
+
+ # PR does not touch any files under our input directories. Now see
+ # if the PR touches files outside of the following directories, by
+ # filtering these out from the diff results.
+ for subdir in docs test; do
+ # || true needed because we're running with set -e
+ diffs=$(egrep -v "^$subdir/" <<<"$diffs" || true)
+ done
+
+ # If we still have diffs, they indicate files outside of docs & test.
+ # It is not safe to skip.
+ if [[ -n "$diffs" ]]; then
+ return 0
+ fi
+
+ msg "SKIPPING: This is a doc- and/or test-only PR with no changes under $*"
+ exit 0
+}
+
# Nearly every task in .cirrus.yml makes use of this shell script
# wrapped by /usr/bin/time to collect runtime statistics. Because the
# --output option is used to log stats to a file, every child-process
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index 906a898b2..a7d0f7fa1 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -41,6 +41,11 @@ cp hack/podman-registry /bin
# Make sure cni network plugins directory exists
mkdir -p /etc/cni/net.d
+# 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"
+
# Ensure that all lower-level contexts and child-processes have
# ready access to higher level orchestration (e.g Cirrus-CI)
# variables.
diff --git a/contrib/podmanimage/README.md b/contrib/podmanimage/README.md
index 4f184ca28..58c14be72 100644
--- a/contrib/podmanimage/README.md
+++ b/contrib/podmanimage/README.md
@@ -70,4 +70,4 @@ file to `/etc/modules.load.d`. See `man modules-load.d` for more details.
### Blog Post with Details
-Dan Walsh wrote a blog post on the [Enable Sysadmin](https://www.redhat.com/sysadmin/) site titled [How to use Podman inside of a container](https://www.redhat.com/sysadmin/podman-inside-container). In it, he details how to use these images as a rootful and as a rootless user. Please refer to this blog for more detailed information.
+Dan Walsh wrote a blog post on the [Enable Sysadmin](https://www.redhat.com/sysadmin/) site titled [How to use Podman inside of a container](https://www.redhat.com/sysadmin/podman-inside-container). In it, he details how to use these images as a rootfull and as a rootless user. Please refer to this blog for more detailed information.
diff --git a/contrib/remote/containers.conf b/contrib/remote/containers.conf
index 9b0b62c42..45f58171a 100644
--- a/contrib/remote/containers.conf
+++ b/contrib/remote/containers.conf
@@ -7,5 +7,5 @@
# Default Remote URI to access the Podman service.
# Examples:
# remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock
-# remote rootful ssh://root@10.10.1.136:22/run/podman/podman.sock
+# remote rootfull ssh://root@10.10.1.136:22/run/podman/podman.sock
# remote_uri= ""
diff --git a/docs/source/markdown/podman-build.1.md b/docs/source/markdown/podman-build.1.md
index 1080581d7..5793ecae5 100644
--- a/docs/source/markdown/podman-build.1.md
+++ b/docs/source/markdown/podman-build.1.md
@@ -429,7 +429,7 @@ 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 (default)
-- **\<network name|ID\>**: Join the network with the given name or ID, e.g. use `--network mynet` to join the network with the name mynet. Only supported for rootful users.
+- **\<network name|ID\>**: Join the network with the given name or ID, e.g. use `--network mynet` to join the network with the name mynet. Only supported for rootfull users.
#### **--no-cache**
diff --git a/docs/source/markdown/podman-container-clone.1.md b/docs/source/markdown/podman-container-clone.1.md
index 7d5e1c262..69423113d 100644
--- a/docs/source/markdown/podman-container-clone.1.md
+++ b/docs/source/markdown/podman-container-clone.1.md
@@ -125,6 +125,10 @@ If none are specified, the original container's CPU memory nodes are used.
Remove the original container that we are cloning once used to mimic the configuration.
+#### **--force**, **-f**
+
+Force removal of the original container that we are cloning. Can only be used in conjunction with **--destroy**.
+
#### **--memory**, **-m**=*limit*
Memory limit (format: `<number>[<unit>]`, where unit = b (bytes), k (kilobytes), m (megabytes), or g (gigabytes))
diff --git a/docs/source/markdown/podman-image-scp.1.md b/docs/source/markdown/podman-image-scp.1.md
index 1d902da91..6d5a51298 100644
--- a/docs/source/markdown/podman-image-scp.1.md
+++ b/docs/source/markdown/podman-image-scp.1.md
@@ -8,7 +8,7 @@ podman-image-scp - Securely copy an image from one host to another
## DESCRIPTION
**podman image scp** copies container images between hosts on a network. You can load to the remote host or from the remote host as well as in between two remote hosts.
-Note: `::` is used to specify the image name depending on if you are saving or loading. Images can also be transferred from rootful to rootless storage on the same machine without using sshd. This feature is not supported on the remote client, including Mac and Windows (excluding WSL2) machines.
+Note: `::` is used to specify the image name depending on if you are saving or loading. Images can also be transferred from rootfull to rootless storage on the same machine without using sshd. This feature is not supported on the remote client, including Mac and Windows (excluding WSL2) machines.
**podman image scp [GLOBAL OPTIONS]**
diff --git a/docs/source/markdown/podman-image-unmount.1.md b/docs/source/markdown/podman-image-unmount.1.md
index f2d75f15f..394811bd4 100644
--- a/docs/source/markdown/podman-image-unmount.1.md
+++ b/docs/source/markdown/podman-image-unmount.1.md
@@ -38,7 +38,7 @@ Unmount image with a given ID
podman image unmount imageID
```
-Unmount multiple images wit given IDs
+Unmount multiple images with given IDs
```
podman image unmount imageID1 imageID2 imageID3
```
diff --git a/docs/source/markdown/podman-machine-init.1.md b/docs/source/markdown/podman-machine-init.1.md
index 33947bbba..e42c5025b 100644
--- a/docs/source/markdown/podman-machine-init.1.md
+++ b/docs/source/markdown/podman-machine-init.1.md
@@ -59,9 +59,9 @@ Memory (in MB).
Start the virtual machine immediately after it has been initialized.
-#### **--rootful**=*true|false*
+#### **--rootfull**=*true|false*
-Whether this machine should prefer rootful (`true`) or rootless (`false`)
+Whether this machine should prefer rootfull (`true`) or rootless (`false`)
container execution. This option will also determine the remote connection default
if there is no existing remote connection configurations.
@@ -95,7 +95,7 @@ Driver to use for mounting volumes from the host, such as `virtfs`.
```
$ podman machine init
$ podman machine init myvm
-$ podman machine init --rootful
+$ podman machine init --rootfull
$ podman machine init --disk-size 50
$ podman machine init --memory=1024 myvm
$ podman machine init -v /Users:/mnt/Users
diff --git a/docs/source/markdown/podman-machine-set.1.md b/docs/source/markdown/podman-machine-set.1.md
index a4918eacf..e69a7dc14 100644
--- a/docs/source/markdown/podman-machine-set.1.md
+++ b/docs/source/markdown/podman-machine-set.1.md
@@ -19,39 +19,39 @@ subset can be changed after machine initialization.
Print usage statement.
-#### **--rootful**=*true|false*
+#### **--rootfull**=*true|false*
-Whether this machine should prefer rootful (`true`) or rootless (`false`)
+Whether this machine should prefer rootfull (`true`) or rootless (`false`)
container execution. This option will also update the current podman
remote connection default if it is currently pointing at the specified
machine name (or `podman-machine-default` if no name is specified).
Unlike [**podman system connection default**](podman-system-connection-default.1.md)
-this option will also make the API socket, if available, forward to the rootful/rootless
+this option will also make the API socket, if available, forward to the rootfull/rootless
socket in the VM.
## EXAMPLES
-To switch the default VM `podman-machine-default` from rootless to rootful:
+To switch the default VM `podman-machine-default` from rootless to rootfull:
```
-$ podman machine set --rootful
+$ podman machine set --rootfull
```
or more explicitly:
```
-$ podman machine set --rootful=true
+$ podman machine set --rootfull=true
```
-To switch the default VM `podman-machine-default` from rootful to rootless:
+To switch the default VM `podman-machine-default` from rootfull to rootless:
```
-$ podman machine set --rootful=false
+$ podman machine set --rootfull=false
```
-To switch the VM `myvm` from rootless to rootful:
+To switch the VM `myvm` from rootless to rootfull:
```
-$ podman machine set --rootful myvm
+$ podman machine set --rootfull myvm
```
## SEE ALSO
diff --git a/go.mod b/go.mod
index fcc1949fa..141f59525 100644
--- a/go.mod
+++ b/go.mod
@@ -12,12 +12,12 @@ require (
github.com/containernetworking/cni v1.0.1
github.com/containernetworking/plugins v1.1.1
github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057
- github.com/containers/common v0.47.5-0.20220421072908-49f1a40067b2
+ github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb
github.com/containers/conmon v2.0.20+incompatible
- github.com/containers/image/v5 v5.21.1-0.20220405081457-d1b64686e1d0
+ github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c
github.com/containers/ocicrypt v1.1.3
github.com/containers/psgo v1.7.2
- github.com/containers/storage v1.39.1-0.20220414183333-eea4e0f5f1f9
+ github.com/containers/storage v1.39.1-0.20220421071128-4899f8265d63
github.com/coreos/go-systemd/v22 v22.3.2
github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3
github.com/cyphar/filepath-securejoin v0.2.3
@@ -68,6 +68,7 @@ require (
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8
+ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
golang.org/x/text v0.3.7
google.golang.org/protobuf v1.28.0
gopkg.in/inf.v0 v0.9.1
diff --git a/go.sum b/go.sum
index a2a119dc4..8f32ac243 100644
--- a/go.sum
+++ b/go.sum
@@ -126,6 +126,7 @@ github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmU
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/ProtonMail/go-crypto v0.0.0-20210920160938-87db9fbc61c7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/ProtonMail/go-crypto v0.0.0-20220113124808-70ae35bab23f/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
+github.com/ProtonMail/go-crypto v0.0.0-20220407094043-a94812496cf5/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
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=
@@ -356,14 +357,14 @@ github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19
github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057 h1:lKSxhMBpcHyyQrj2QJYzcm56uiSeibRdSL2KoppF6rg=
github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057/go.mod h1:iSoopbYRb6K4b5c3hXgXNkGTI/T085t2+XiGjceud94=
github.com/containers/common v0.47.5-0.20220331143923-5f14ec785c18/go.mod h1:Vr2Fn6EdzD6JNAbz8L8bTv3uWLv2p31Ih2O3EAK6Hyc=
-github.com/containers/common v0.47.5-0.20220421072908-49f1a40067b2 h1:NadhQUF7FRaZkDeW7xDcU3nxk7kV6b2yRmwGWDp+BNY=
-github.com/containers/common v0.47.5-0.20220421072908-49f1a40067b2/go.mod h1:BBq6jdyjXvJh69YzQPvIuZjBho0MRdA0XGaqBnsO+1Y=
+github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb h1:TBrx1KcmWcesByqTb4Cq7F6bg7bDOjqCf6+6rbi8x4k=
+github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb/go.mod h1:r80nWTmJrG9EoLkuI6WfbWQDUNQVqkVuB8Oaj1VVjOA=
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.19.2-0.20220224100137-1045fb70b094/go.mod h1:XoYK6kE0dpazFNcuS+a8lra+QfbC6s8tzv+cUuCrZpE=
github.com/containers/image/v5 v5.20.1-0.20220404163228-d03e80fc66b3/go.mod h1:2nEPM0WuinC/0ssPsMv5Iy8YaRueUUTmTp3C7bn5uro=
-github.com/containers/image/v5 v5.21.1-0.20220405081457-d1b64686e1d0 h1:Md1CckW9KSYkdtMdKG70Fc+YqCCVgT+HAr7NS9Ilf8E=
-github.com/containers/image/v5 v5.21.1-0.20220405081457-d1b64686e1d0/go.mod h1:JhGkIpC7vKBpLc6mTBE4S8cZUAD+8HgicsxYaLv6BsQ=
+github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c h1:hshgYt6RAs4L0KhOEc2/qLF++2MryOfAXvTWmxYu4v4=
+github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c/go.mod h1:qpUuaiE2mON6xMA0PRO9GteyH9+KT+C6WygZzL5RhnE=
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=
@@ -380,8 +381,8 @@ github.com/containers/storage v1.38.2/go.mod h1:INP0RPLHWBxx+pTsO5uiHlDUGHDFvWZP
github.com/containers/storage v1.38.3-0.20220301151551-d06b0f81c0aa/go.mod h1:LkkL34WRi4dI4jt9Cp+ImdZi/P5i36glSHimT5CP5zM=
github.com/containers/storage v1.39.0/go.mod h1:UAD0cKLouN4BOQRgZut/nMjrh/EnTCjSNPgp4ZuGWMs=
github.com/containers/storage v1.39.1-0.20220330193934-f3200eb5a5d9/go.mod h1:IMa2AfBI+Fxxk2hQqLTGhpJX6z2pZS1/I785QJeUwUY=
-github.com/containers/storage v1.39.1-0.20220414183333-eea4e0f5f1f9 h1:cB2AvqxpfyqyyffXtDN0txJhD0lIaZWktbSRI92WpN4=
-github.com/containers/storage v1.39.1-0.20220414183333-eea4e0f5f1f9/go.mod h1:hFiHLMgNU0r3MiUpE97hEBaEKCN8fEIuEEBXoFC9eN0=
+github.com/containers/storage v1.39.1-0.20220421071128-4899f8265d63 h1:57UXh6fThYqCUJ6iFwHnlFNoWSWlXylkW4H1VRs05mM=
+github.com/containers/storage v1.39.1-0.20220421071128-4899f8265d63/go.mod h1:hFiHLMgNU0r3MiUpE97hEBaEKCN8fEIuEEBXoFC9eN0=
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=
@@ -994,7 +995,6 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
@@ -1314,8 +1314,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/sylabs/release-tools v0.1.0/go.mod h1:pqP/z/11/rYMQ0OM/Nn7TxGijw7KfZwW9UolD/J1TUo=
github.com/sylabs/sif/v2 v2.3.2/go.mod h1:IrLX2pzmQ2O4qgv5iy3HdKJcBNYds9DTMd9Je8A9tX4=
-github.com/sylabs/sif/v2 v2.4.2 h1:L4jcqeOF33JfSnH+8GJKC7/ooVpzpZ2K7wotGG4ZzqQ=
github.com/sylabs/sif/v2 v2.4.2/go.mod h1:6gQvzNKRIqr4FS08XBfHpkpnxv9b7h58GLkSJ1zdK9A=
+github.com/sylabs/sif/v2 v2.6.0 h1:nrWbtSAavp4T6gETg/QgZXxs67qTpSNEgqs2H1y228w=
+github.com/sylabs/sif/v2 v2.6.0/go.mod h1:TiyBWsgWeh5yBeQFNuQnvROwswqK7YJT8JA1L53bsXQ=
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=
diff --git a/hack/make-and-check-size b/hack/make-and-check-size
index f2345b815..5b0021d12 100755
--- a/hack/make-and-check-size
+++ b/hack/make-and-check-size
@@ -92,9 +92,10 @@ if [[ ! -d $context_dir ]]; then
fi
# This is the original (and primary) purpose of this check: if 'make' fails,
-# there is no point in continuing
+# there is no point in continuing. Show at least the commit title since
+# the ID may not match anything human recognisable.
echo
-echo "Building: $(git rev-parse HEAD)"
+echo "Building: $(git log -n 1 --no-show-signature --oneline)"
make
# Determine size of each built file.
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 14290ca0d..76e0e9e13 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -367,7 +367,7 @@ func (c *Container) generateInspectContainerConfig(spec *spec.Spec) *define.Insp
// Leave empty if not explicitly overwritten by user
if len(c.config.Entrypoint) != 0 {
- ctrConfig.Entrypoint = c.config.Entrypoint
+ ctrConfig.Entrypoint = strings.Join(c.config.Entrypoint, " ")
}
if len(c.config.Labels) != 0 {
@@ -845,7 +845,7 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
// Do not include if privileged - assumed that all devices will be
// included.
var err error
- hostConfig.Devices, err = c.GetDevices(*&hostConfig.Privileged, *ctrSpec, deviceNodes)
+ hostConfig.Devices, err = c.GetDevices(hostConfig.Privileged, *ctrSpec, deviceNodes)
if err != nil {
return nil, err
}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index f8d0a124c..6ffd99649 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -399,6 +399,9 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
}
+ // NewFromSpec() is deprecated according to its comment
+ // however the recommended replace just causes a nil map panic
+ //nolint:staticcheck
g := generate.NewFromSpec(c.config.Spec)
// If network namespace was requested, add it now
@@ -1520,6 +1523,10 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO
func (c *Container) generateContainerSpec() error {
// Make sure the newly created config.json exists on disk
+
+ // NewFromSpec() is deprecated according to its comment
+ // however the recommended replace just causes a nil map panic
+ //nolint:staticcheck
g := generate.NewFromSpec(c.config.Spec)
if err := c.saveSpec(g.Config); err != nil {
diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go
index 444fbff62..ae2ce9724 100644
--- a/libpod/define/container_inspect.go
+++ b/libpod/define/container_inspect.go
@@ -44,7 +44,7 @@ type InspectContainerConfig struct {
// Container working directory
WorkingDir string `json:"WorkingDir"`
// Container entrypoint
- Entrypoint []string `json:"Entrypoint"`
+ Entrypoint string `json:"Entrypoint"`
// On-build arguments - presently unused. More of Buildah's domain.
OnBuild *string `json:"OnBuild"`
// Container labels
diff --git a/libpod/healthcheck_linux.go b/libpod/healthcheck_linux.go
index 51def1927..45b3a0e41 100644
--- a/libpod/healthcheck_linux.go
+++ b/libpod/healthcheck_linux.go
@@ -56,7 +56,7 @@ func (c *Container) startTimer() error {
return errors.Wrapf(err, "unable to get systemd connection to start healthchecks")
}
defer conn.Close()
- _, err = conn.StartUnit(fmt.Sprintf("%s.service", c.ID()), "fail", nil)
+ _, err = conn.StartUnitContext(context.Background(), fmt.Sprintf("%s.service", c.ID()), "fail", nil)
return err
}
diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go
index 4a0ef0b3a..4b1203dc3 100644
--- a/libpod/networking_slirp4netns.go
+++ b/libpod/networking_slirp4netns.go
@@ -210,7 +210,7 @@ func createBasicSlirp4netnsCmdArgs(options *slirp4netnsNetworkOptions, features
return cmdArgs, nil
}
-// setupSlirp4netns can be called in rootful as well as in rootless
+// setupSlirp4netns can be called in rootfull as well as in rootless
func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error {
path := r.config.Engine.NetworkCmdPath
if path == "" {
diff --git a/libpod/options.go b/libpod/options.go
index ffd0e6037..4e597201a 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -936,6 +936,9 @@ func WithUserNSFrom(nsCtr *Container) CtrCreateOption {
if err := JSONDeepCopy(nsCtr.IDMappings(), &ctr.config.IDMappings); err != nil {
return err
}
+ // NewFromSpec() is deprecated according to its comment
+ // however the recommended replace just causes a nil map panic
+ //nolint:staticcheck
g := generate.NewFromSpec(ctr.config.Spec)
g.ClearLinuxUIDMappings()
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 7edd49fd1..a62c2b607 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -397,6 +397,10 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
if ctr.restoreFromCheckpoint {
// Remove information about bind mount
// for new container from imported checkpoint
+
+ // NewFromSpec() is deprecated according to its comment
+ // however the recommended replace just causes a nil map panic
+ //nolint:staticcheck
g := generate.NewFromSpec(ctr.config.Spec)
g.RemoveMount("/dev/shm")
ctr.config.ShmDir = ""
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go
index b823a56b6..15d4b9f89 100644
--- a/pkg/api/handlers/libpod/manifests.go
+++ b/pkg/api/handlers/libpod/manifests.go
@@ -100,10 +100,10 @@ func ManifestCreate(w http.ResponseWriter, r *http.Request) {
// gather all images for manifest list
var images []string
if len(query.Images) > 0 {
- images = append(query.Images)
+ images = query.Images
}
if len(body.Images) > 0 {
- images = append(body.Images)
+ images = body.Images
}
id, err := imageEngine.ManifestAdd(r.Context(), query.Name, images, body.ManifestAddOptions)
@@ -153,10 +153,10 @@ func ManifestInspect(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, schema2List)
}
-// ManifestAdd remove digest from manifest list
+// ManifestAddV3 remove digest from manifest list
//
-// Deprecated: As of 4.0.0 use ManifestModify instead
-func ManifestAdd(w http.ResponseWriter, r *http.Request) {
+// As of 4.0.0 use ManifestModify instead
+func ManifestAddV3(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
// Wrapper to support 3.x with 4.x libpod
@@ -206,10 +206,10 @@ func ManifestAdd(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: newID})
}
-// ManifestRemoveDigest remove digest from manifest list
+// ManifestRemoveDigestV3 remove digest from manifest list
//
-// Deprecated: As of 4.0.0 use ManifestModify instead
-func ManifestRemoveDigest(w http.ResponseWriter, r *http.Request) {
+// As of 4.0.0 use ManifestModify instead
+func ManifestRemoveDigestV3(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
query := struct {
@@ -242,7 +242,7 @@ func ManifestRemoveDigest(w http.ResponseWriter, r *http.Request) {
// ManifestPushV3 push image to registry
//
-// Deprecated: As of 4.0.0 use ManifestPush instead
+// As of 4.0.0 use ManifestPush instead
func ManifestPushV3(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
diff --git a/pkg/api/server/register_manifest.go b/pkg/api/server/register_manifest.go
index 58def109e..50a49bc1e 100644
--- a/pkg/api/server/register_manifest.go
+++ b/pkg/api/server/register_manifest.go
@@ -167,7 +167,7 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error {
// $ref: "#/responses/BadParamError"
// 500:
// $ref: "#/responses/InternalError"
- v3.Handle("/{name:.*}/add", s.APIHandler(libpod.ManifestAdd)).Methods(http.MethodPost)
+ v3.Handle("/{name:.*}/add", s.APIHandler(libpod.ManifestAddV3)).Methods(http.MethodPost)
// swagger:operation DELETE /libpod/manifests/{name} manifests ManifestDeleteV3Libpod
// ---
// summary: Remove image from a manifest list
@@ -197,7 +197,7 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error {
// $ref: "#/responses/NoSuchManifest"
// 500:
// $ref: "#/responses/InternalError"
- v3.Handle("/{name:.*}", s.APIHandler(libpod.ManifestRemoveDigest)).Methods(http.MethodDelete)
+ v3.Handle("/{name:.*}", s.APIHandler(libpod.ManifestRemoveDigestV3)).Methods(http.MethodDelete)
// swagger:operation DELETE /libpod/manifests/{name} manifests ManifestDeleteLibpod
// ---
// summary: Delete manifest list
diff --git a/pkg/bindings/README.md b/pkg/bindings/README.md
index ebc8a13d1..713adb104 100644
--- a/pkg/bindings/README.md
+++ b/pkg/bindings/README.md
@@ -9,7 +9,7 @@ The bindings require that the Podman system service is running for the specified
by calling the service directly.
### Starting the service with system
-The command to start the Podman service differs slightly depending on the user that is running the service. For a rootful service,
+The command to start the Podman service differs slightly depending on the user that is running the service. For a rootfull service,
start the service like this:
```
# systemctl start podman.socket
@@ -26,7 +26,7 @@ It can be handy to run the system service manually. Doing so allows you to enab
$ podman --log-level=debug system service -t0
```
If you do not provide a specific path for the socket, a default is provided. The location of that socket for
-rootful connections is `/run/podman/podman.sock` and for rootless it is `/run/USERID#/podman/podman.sock`. For more
+rootfull connections is `/run/podman/podman.sock` and for rootless it is `/run/USERID#/podman/podman.sock`. For more
information about the Podman system service, see `man podman-system-service`.
### Creating a connection
@@ -35,7 +35,7 @@ as they will be required to compile a Go program making use of the bindings.
The first step for using the bindings is to create a connection to the socket. As mentioned earlier, the destination
-of the socket depends on the user who owns it. In this case, a rootful connection is made.
+of the socket depends on the user who owns it. In this case, a rootfull connection is made.
```
import (
@@ -59,7 +59,7 @@ The `conn` variable returned from the `bindings.NewConnection` function can then
to interact with containers.
### Examples
-The following examples build upon the connection example from above. They are all rootful connections as well.
+The following examples build upon the connection example from above. They are all rootfull connections as well.
Note: Optional arguments to the bindings methods are set using With*() methods on *Option structures.
Composite types are not duplicated rather the address is used. As such, you should not change an underlying
diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go
index 80702ea98..d84b47052 100644
--- a/pkg/bindings/containers/attach.go
+++ b/pkg/bindings/containers/attach.go
@@ -20,7 +20,7 @@ import (
"github.com/moby/term"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- "golang.org/x/crypto/ssh/terminal"
+ terminal "golang.org/x/term"
)
// The CloseWriter interface is used to determine whether we can do a one-sided
diff --git a/pkg/bindings/containers/term_unix.go b/pkg/bindings/containers/term_unix.go
index 2c976393f..e14f50813 100644
--- a/pkg/bindings/containers/term_unix.go
+++ b/pkg/bindings/containers/term_unix.go
@@ -9,11 +9,11 @@ import (
"os/signal"
sig "github.com/containers/podman/v4/pkg/signal"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
-func makeRawTerm(stdin *os.File) (*terminal.State, error) {
- return terminal.MakeRaw(int(stdin.Fd()))
+func makeRawTerm(stdin *os.File) (*term.State, error) {
+ return term.MakeRaw(int(stdin.Fd()))
}
func notifyWinChange(ctx context.Context, winChange chan os.Signal, stdin *os.File, stdout *os.File) {
@@ -21,5 +21,5 @@ func notifyWinChange(ctx context.Context, winChange chan os.Signal, stdin *os.Fi
}
func getTermSize(stdin *os.File, stdout *os.File) (width, height int, err error) {
- return terminal.GetSize(int(stdin.Fd()))
+ return term.GetSize(int(stdin.Fd()))
}
diff --git a/pkg/bindings/containers/term_windows.go b/pkg/bindings/containers/term_windows.go
index 11d4bd50d..e710e2998 100644
--- a/pkg/bindings/containers/term_windows.go
+++ b/pkg/bindings/containers/term_windows.go
@@ -6,12 +6,12 @@ import (
"time"
sig "github.com/containers/podman/v4/pkg/signal"
- "golang.org/x/crypto/ssh/terminal"
"golang.org/x/sys/windows"
+ "golang.org/x/term"
)
-func makeRawTerm(stdin *os.File) (*terminal.State, error) {
- state, err := terminal.MakeRaw(int(stdin.Fd()))
+func makeRawTerm(stdin *os.File) (*term.State, error) {
+ state, err := term.MakeRaw(int(stdin.Fd()))
if err != nil {
return nil, err
}
@@ -51,7 +51,7 @@ func notifyWinChange(ctx context.Context, winChange chan os.Signal, stdin *os.Fi
break
}
- w, h, err := terminal.GetSize(int(stdout.Fd()))
+ w, h, err := term.GetSize(int(stdout.Fd()))
if err != nil {
continue
}
@@ -65,5 +65,5 @@ func notifyWinChange(ctx context.Context, winChange chan os.Signal, stdin *os.Fi
}
func getTermSize(stdin *os.File, stdout *os.File) (width, height int, err error) {
- return terminal.GetSize(int(stdout.Fd()))
+ return term.GetSize(int(stdout.Fd()))
}
diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go
index d667a2dee..a005be6ac 100644
--- a/pkg/bindings/test/images_test.go
+++ b/pkg/bindings/test/images_test.go
@@ -103,7 +103,7 @@ var _ = Describe("Podman images", func() {
Expect(len(errs)).To(BeZero())
Expect(inspectData.ID).To(Equal(response.Deleted[0]))
- inspectData, err = images.GetImage(bt.conn, busybox.shortName, nil)
+ _, err = images.GetImage(bt.conn, busybox.shortName, nil)
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusNotFound))
@@ -118,7 +118,7 @@ var _ = Describe("Podman images", func() {
// try to remove the image "alpine". This should fail since we are not force
// deleting hence image cannot be deleted until the container is deleted.
- response, errs = images.Remove(bt.conn, []string{alpine.shortName}, nil)
+ _, errs = images.Remove(bt.conn, []string{alpine.shortName}, nil)
code, _ = bindings.CheckResponseCode(errs[0])
// FIXME FIXME FIXME: #12441: another invalid error
// FIXME FIXME FIXME: this time msg="Image used by SHA: ..."
@@ -126,7 +126,7 @@ var _ = Describe("Podman images", func() {
// Removing the image "alpine" where force = true
options := new(images.RemoveOptions).WithForce(true)
- response, errs = images.Remove(bt.conn, []string{alpine.shortName}, options)
+ _, errs = images.Remove(bt.conn, []string{alpine.shortName}, options)
Expect(errs).To(Or(HaveLen(0), BeNil()))
// To be extra sure, check if the previously created container
// is gone as well.
@@ -135,11 +135,11 @@ var _ = Describe("Podman images", func() {
Expect(code).To(BeNumerically("==", http.StatusNotFound))
// Now make sure both images are gone.
- inspectData, err = images.GetImage(bt.conn, busybox.shortName, nil)
+ _, err = images.GetImage(bt.conn, busybox.shortName, nil)
code, _ = bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusNotFound))
- inspectData, err = images.GetImage(bt.conn, alpine.shortName, nil)
+ _, err = images.GetImage(bt.conn, alpine.shortName, nil)
code, _ = bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusNotFound))
})
@@ -230,8 +230,8 @@ var _ = Describe("Podman images", func() {
Expect(err).ToNot(HaveOccurred())
Expect(exists).To(BeFalse())
f, err := os.Open(filepath.Join(ImageCacheDir, alpine.tarballName))
- defer f.Close()
Expect(err).ToNot(HaveOccurred())
+ defer f.Close()
names, err := images.Load(bt.conn, f)
Expect(err).ToNot(HaveOccurred())
Expect(names.Names[0]).To(Equal(alpine.name))
@@ -252,8 +252,6 @@ var _ = Describe("Podman images", func() {
Expect(names.Names[0]).To(Equal(alpine.name))
// load with a bad repo name should trigger a 500
- f, err = os.Open(filepath.Join(ImageCacheDir, alpine.tarballName))
- Expect(err).ToNot(HaveOccurred())
_, errs = images.Remove(bt.conn, []string{alpine.name}, nil)
Expect(len(errs)).To(BeZero())
exists, err = images.Exists(bt.conn, alpine.name, nil)
@@ -265,8 +263,8 @@ var _ = Describe("Podman images", func() {
// Export an image
exportPath := filepath.Join(bt.tempDirPath, alpine.tarballName)
w, err := os.Create(filepath.Join(bt.tempDirPath, alpine.tarballName))
- defer w.Close()
Expect(err).ToNot(HaveOccurred())
+ defer w.Close()
err = images.Export(bt.conn, []string{alpine.name}, w, nil)
Expect(err).ToNot(HaveOccurred())
_, err = os.Stat(exportPath)
@@ -283,8 +281,8 @@ var _ = Describe("Podman images", func() {
Expect(err).ToNot(HaveOccurred())
Expect(exists).To(BeFalse())
f, err := os.Open(filepath.Join(ImageCacheDir, alpine.tarballName))
- defer f.Close()
Expect(err).ToNot(HaveOccurred())
+ defer f.Close()
changes := []string{"CMD /bin/foobar"}
testMessage := "test_import"
options := new(images.ImportOptions).WithMessage(testMessage).WithChanges(changes).WithReference(alpine.name)
diff --git a/pkg/bindings/test/secrets_test.go b/pkg/bindings/test/secrets_test.go
index 377f49b2f..b4595f025 100644
--- a/pkg/bindings/test/secrets_test.go
+++ b/pkg/bindings/test/secrets_test.go
@@ -64,7 +64,7 @@ var _ = Describe("Podman secrets", func() {
Expect(data.Spec.Name).To(Equal(name))
// inspecting non-existent secret should fail
- data, err = secrets.Inspect(connText, "notasecret", nil)
+ _, err = secrets.Inspect(connText, "notasecret", nil)
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusNotFound))
})
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index 3d1d7a6d2..ae60e5b96 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -477,4 +477,5 @@ type ContainerCloneOptions struct {
Image string
RawImageName string
Run bool
+ Force bool
}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 46ef01b80..b56c36015 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -1630,7 +1630,7 @@ func (ic *ContainerEngine) ContainerClone(ctx context.Context, ctrCloneOpts enti
if ctrCloneOpts.Destroy {
var time *uint
- err := ic.Libpod.RemoveContainer(context.Background(), c, false, false, time)
+ err = ic.Libpod.RemoveContainer(context.Background(), c, ctrCloneOpts.Force, false, time)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 74478b26d..43440b594 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -367,7 +367,7 @@ func (ir *ImageEngine) Transfer(ctx context.Context, source entities.ImageScpOpt
if rootless.IsRootless() && (len(dest.User) == 0 || dest.User == "root") { // if we are rootless and do not have a destination user we can just use sudo
return transferRootless(source, dest, podman, parentFlags)
}
- return transferRootful(source, dest, podman, parentFlags)
+ return transferRootfull(source, dest, podman, parentFlags)
}
func (ir *ImageEngine) Tag(ctx context.Context, nameOrID string, tags []string, options entities.ImageTagOptions) error {
@@ -785,8 +785,8 @@ func transferRootless(source entities.ImageScpOptions, dest entities.ImageScpOpt
return cmdLoad.Run()
}
-// TransferRootful creates new podman processes using exec.Command and a new uid/gid alongside a cleared environment
-func transferRootful(source entities.ImageScpOptions, dest entities.ImageScpOptions, podman string, parentFlags []string) error {
+// transferRootfull creates new podman processes using exec.Command and a new uid/gid alongside a cleared environment
+func transferRootfull(source entities.ImageScpOptions, dest entities.ImageScpOptions, podman string, parentFlags []string) error {
basicCommand := []string{podman}
basicCommand = append(basicCommand, parentFlags...)
saveCommand := append(basicCommand, "save")
diff --git a/pkg/domain/infra/abi/terminal/terminal_linux.go b/pkg/domain/infra/abi/terminal/terminal_linux.go
index 153b19fdb..62d36f28d 100644
--- a/pkg/domain/infra/abi/terminal/terminal_linux.go
+++ b/pkg/domain/infra/abi/terminal/terminal_linux.go
@@ -10,13 +10,13 @@ import (
"github.com/containers/podman/v4/libpod/define"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
// ExecAttachCtr execs and attaches to a container
func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpod.ExecConfig, streams *define.AttachStreams) (int, error) {
var resize chan define.TerminalSize
- haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
+ haveTerminal := term.IsTerminal(int(os.Stdin.Fd()))
// Check if we are attached to a terminal. If we are, generate resize
// events, and set the terminal to raw mode
@@ -42,7 +42,7 @@ func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpo
func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool) error { //nolint: interfacer
resize := make(chan define.TerminalSize)
- haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
+ haveTerminal := term.IsTerminal(int(os.Stdin.Fd()))
// Check if we are attached to a terminal. If we are, generate resize
// events, and set the terminal to raw mode
diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go
index 4f44e7e4a..2dbdfcf80 100644
--- a/pkg/domain/infra/tunnel/pods.go
+++ b/pkg/domain/infra/tunnel/pods.go
@@ -42,14 +42,14 @@ func (ic *ContainerEngine) PodKill(ctx context.Context, namesOrIds []string, opt
return reports, nil
}
-func (ic *ContainerEngine) PodLogs(_ context.Context, nameOrIDs string, options entities.PodLogsOptions) error {
+func (ic *ContainerEngine) PodLogs(ctx context.Context, nameOrIDs string, options entities.PodLogsOptions) error {
// PodLogsOptions are similar but contains few extra fields like ctrName
// So cast other values as is so we can re-use the code
containerLogsOpts := entities.PodLogsOptionsToContainerLogsOptions(options)
// interface only accepts slice, keep everything consistent
name := []string{options.ContainerName}
- return ic.ContainerLogs(nil, name, containerLogsOpts)
+ return ic.ContainerLogs(ctx, name, containerLogsOpts)
}
func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, options entities.PodPauseOptions) ([]*entities.PodPauseReport, error) {
diff --git a/pkg/machine/config.go b/pkg/machine/config.go
index 6c2fab0e5..5dc5f6105 100644
--- a/pkg/machine/config.go
+++ b/pkg/machine/config.go
@@ -28,7 +28,7 @@ type InitOptions struct {
URI url.URL
Username string
ReExec bool
- Rootful bool
+ Rootfull bool
// The numerical userid of the user that called machine
UID string
}
@@ -95,7 +95,7 @@ type ListResponse struct {
}
type SetOptions struct {
- Rootful bool
+ Rootfull bool
}
type SSHOptions struct {
diff --git a/pkg/machine/fcos.go b/pkg/machine/fcos.go
index 6215ae08f..ad1be15c7 100644
--- a/pkg/machine/fcos.go
+++ b/pkg/machine/fcos.go
@@ -139,7 +139,7 @@ func getStreamURL(streamType string) url2.URL {
// This should get Exported and stay put as it will apply to all fcos downloads
// getFCOS parses fedoraCoreOS's stream and returns the image download URL and the release version
-func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) {
+func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) { // nolint:staticcheck
var (
fcosstable stream.Stream
altMeta release.Release
@@ -149,6 +149,8 @@ func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) {
// This is being hard set to testing. Once podman4 is in the
// fcos trees, we should remove it and re-release at least on
// macs.
+ // TODO: remove when podman4.0 is in coreos
+ // nolint:staticcheck
imageStream = "podman-testing"
switch imageStream {
diff --git a/pkg/machine/qemu/config.go b/pkg/machine/qemu/config.go
index 4d4e3a6c1..6ab25b951 100644
--- a/pkg/machine/qemu/config.go
+++ b/pkg/machine/qemu/config.go
@@ -57,8 +57,8 @@ type MachineVMV1 struct {
QMPMonitor Monitorv1
// RemoteUsername of the vm user
RemoteUsername string
- // Whether this machine should run in a rootful or rootless manner
- Rootful bool
+ // Whether this machine should run in a rootfull or rootless manner
+ Rootfull bool
// UID is the numerical id of the user that called machine
UID int
}
@@ -99,8 +99,8 @@ type ImageConfig struct {
// HostUser describes the host user
type HostUser struct {
- // Whether this machine should run in a rootful or rootless manner
- Rootful bool
+ // Whether this machine should run in a rootfull or rootless manner
+ Rootfull bool
// UID is the numerical id of the user that called machine
UID int
}
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index a3dedeedb..4cfd4e8b0 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -204,7 +204,7 @@ func migrateVM(configPath string, config []byte, vm *MachineVM) error {
vm.QMPMonitor = qmpMonitor
vm.ReadySocket = readySocket
vm.RemoteUsername = old.RemoteUsername
- vm.Rootful = old.Rootful
+ vm.Rootfull = old.Rootfull
vm.UID = old.UID
// Backup the original config file
@@ -258,7 +258,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
)
sshDir := filepath.Join(homedir.Get(), ".ssh")
v.IdentityPath = filepath.Join(sshDir, v.Name)
- v.Rootful = opts.Rootful
+ v.Rootfull = opts.Rootfull
switch opts.ImagePath {
case Testing, Next, Stable, "":
@@ -356,8 +356,8 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
names := []string{v.Name, v.Name + "-root"}
// The first connection defined when connections is empty will become the default
- // regardless of IsDefault, so order according to rootful
- if opts.Rootful {
+ // regardless of IsDefault, so order according to rootfull
+ if opts.Rootfull {
uris[0], names[0], uris[1], names[1] = uris[1], names[1], uris[0], names[0]
}
@@ -435,7 +435,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
}
func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
- if v.Rootful == opts.Rootful {
+ if v.Rootfull == opts.Rootfull {
return nil
}
@@ -459,7 +459,7 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
if changeCon {
newDefault := v.Name
- if opts.Rootful {
+ if opts.Rootfull {
newDefault += "-root"
}
if err := machine.ChangeDefault(newDefault); err != nil {
@@ -467,7 +467,7 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
}
}
- v.Rootful = opts.Rootful
+ v.Rootfull = opts.Rootfull
return v.writeConfig()
}
@@ -1117,7 +1117,7 @@ func (v *MachineVM) setupAPIForwarding(cmd []string) ([]string, string, apiForwa
destSock := fmt.Sprintf("/run/user/%d/podman/podman.sock", v.UID)
forwardUser := "core"
- if v.Rootful {
+ if v.Rootfull {
destSock = "/run/podman/podman.sock"
forwardUser = "root"
}
@@ -1323,11 +1323,11 @@ func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forward
}
waitAndPingAPI(forwardSock)
- if !v.Rootful {
+ if !v.Rootfull {
fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n")
fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n")
fmt.Printf("issues with non-podman clients, you can switch using the following command: \n")
- fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
+ fmt.Printf("\n\tpodman machine set --rootfull%s\n\n", suffix)
}
fmt.Printf("API forwarding listening on: %s\n", forwardSock)
diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go
index dff7bfef9..dc3f33fa7 100644
--- a/pkg/machine/wsl/machine.go
+++ b/pkg/machine/wsl/machine.go
@@ -165,8 +165,8 @@ type MachineVM struct {
Port int
// RemoteUsername of the vm user
RemoteUsername string
- // Whether this machine should run in a rootful or rootless manner
- Rootful bool
+ // Whether this machine should run in a rootfull or rootless manner
+ Rootfull bool
}
type ExitCodeError struct {
@@ -232,7 +232,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
homeDir := homedir.Get()
sshDir := filepath.Join(homeDir, ".ssh")
v.IdentityPath = filepath.Join(sshDir, v.Name)
- v.Rootful = opts.Rootful
+ v.Rootfull = opts.Rootfull
if err := downloadDistro(v, opts); err != nil {
return false, err
@@ -316,8 +316,8 @@ func setupConnections(v *MachineVM, opts machine.InitOptions, sshDir string) err
names := []string{v.Name, v.Name + "-root"}
// The first connection defined when connections is empty will become the default
- // regardless of IsDefault, so order according to rootful
- if opts.Rootful {
+ // regardless of IsDefault, so order according to rootfull
+ if opts.Rootfull {
uris[0], names[0], uris[1], names[1] = uris[1], names[1], uris[0], names[0]
}
@@ -733,7 +733,7 @@ func pipeCmdPassThrough(name string, input string, arg ...string) error {
}
func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
- if v.Rootful == opts.Rootful {
+ if v.Rootfull == opts.Rootfull {
return nil
}
@@ -744,7 +744,7 @@ func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
if changeCon {
newDefault := v.Name
- if opts.Rootful {
+ if opts.Rootfull {
newDefault += "-root"
}
if err := machine.ChangeDefault(newDefault); err != nil {
@@ -752,7 +752,7 @@ func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
}
}
- v.Rootful = opts.Rootful
+ v.Rootfull = opts.Rootfull
return v.writeConfig()
}
@@ -768,7 +768,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
return errors.Wrap(err, "WSL bootstrap script failed")
}
- if !v.Rootful {
+ if !v.Rootfull {
fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n")
fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n")
fmt.Printf("issues with non-podman clients, you can switch using the following command: \n")
@@ -777,7 +777,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
if name != machine.DefaultMachineName {
suffix = " " + name
}
- fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
+ fmt.Printf("\n\tpodman machine set --rootfull%s\n\n", suffix)
}
globalName, pipeName, err := launchWinProxy(v)
@@ -833,7 +833,7 @@ func launchWinProxy(v *MachineVM) (bool, string, error) {
destSock := "/run/user/1000/podman/podman.sock"
forwardUser := v.RemoteUsername
- if v.Rootful {
+ if v.Rootfull {
destSock = "/run/podman/podman.sock"
forwardUser = "root"
}
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 5f4218899..81286b962 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -346,7 +346,7 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error {
return nil
}
-// ConfigToSpec takes a completed container config and converts it back into a specgenerator for purposes of cloning an exisiting container
+// ConfigToSpec takes a completed container config and converts it back into a specgenerator for purposes of cloning an existing container
func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, contaierID string) (*libpod.Container, *libpod.InfraInherit, error) {
c, err := rt.LookupContainer(contaierID)
if err != nil {
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 5667a02e8..021b88280 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -293,7 +293,7 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
"/usr/sbin/init": true,
"/usr/local/sbin/init": true,
}
- // Grab last command incase this is launched from a shell
+ // Grab last command in case this is launched from a shell
cmd := command
if len(command) > 2 {
// Podman build will add "/bin/sh" "-c" to
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index df751a780..51f9fa535 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -82,7 +82,7 @@ func ToPodOpt(ctx context.Context, podName string, p entities.PodCreateOptions,
}
// dns options
if options := dnsConfig.Options; len(options) > 0 {
- dnsOptions := make([]string, 0)
+ dnsOptions := make([]string, 0, len(options))
for _, opts := range options {
d := opts.Name
if opts.Value != nil {
@@ -90,6 +90,7 @@ func ToPodOpt(ctx context.Context, podName string, p entities.PodCreateOptions,
}
dnsOptions = append(dnsOptions, d)
}
+ p.Net.DNSOptions = dnsOptions
}
}
return p, nil
@@ -281,9 +282,6 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
annotations = opts.Annotations
}
if opts.PodInfraID != "" {
- if annotations == nil {
-
- }
annotations[ann.SandboxID] = opts.PodInfraID
annotations[ann.ContainerType] = ann.ContainerTypeContainer
}
diff --git a/pkg/specgenutil/volumes.go b/pkg/specgenutil/volumes.go
index aa07de0af..95ce420f8 100644
--- a/pkg/specgenutil/volumes.go
+++ b/pkg/specgenutil/volumes.go
@@ -1,6 +1,7 @@
package specgenutil
import (
+ "encoding/csv"
"fmt"
"path/filepath"
"strings"
@@ -152,7 +153,15 @@ func findMountType(input string) (mountType string, tokens []string, err error)
// Split by comma, iterate over the slice and look for
// "type=$mountType". Everything else is appended to tokens.
found := false
- for _, s := range strings.Split(input, ",") {
+ csvReader := csv.NewReader(strings.NewReader(input))
+ records, err := csvReader.ReadAll()
+ if err != nil {
+ return "", nil, err
+ }
+ if len(records) != 1 {
+ return "", nil, errInvalidSyntax
+ }
+ for _, s := range records[0] {
kv := strings.Split(s, "=")
if found || !(len(kv) == 2 && kv[0] == "type") {
tokens = append(tokens, s)
diff --git a/pkg/systemd/dbus.go b/pkg/systemd/dbus.go
index 44feb8308..b35f778ab 100644
--- a/pkg/systemd/dbus.go
+++ b/pkg/systemd/dbus.go
@@ -1,6 +1,7 @@
package systemd
import (
+ "context"
"fmt"
"os"
"path/filepath"
@@ -140,5 +141,5 @@ func ConnectToDBUS() (*dbus.Conn, error) {
if rootless.IsRootless() {
return newRootlessConnection()
}
- return dbus.NewSystemdConnection()
+ return dbus.NewSystemdConnectionContext(context.Background())
}
diff --git a/pkg/terminal/util.go b/pkg/terminal/util.go
index 04e12f6b3..0f0968c30 100644
--- a/pkg/terminal/util.go
+++ b/pkg/terminal/util.go
@@ -14,7 +14,7 @@ import (
"github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/knownhosts"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
var (
@@ -29,9 +29,9 @@ var (
// Additionally, all input after `<secret>/n` is queued to podman command.
func ReadPassword(prompt string) (pw []byte, err error) {
fd := int(os.Stdin.Fd())
- if terminal.IsTerminal(fd) {
+ if term.IsTerminal(fd) {
fmt.Fprint(os.Stderr, prompt)
- pw, err = terminal.ReadPassword(fd)
+ pw, err = term.ReadPassword(fd)
fmt.Fprintln(os.Stderr)
return
}
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index aed9aebfc..9842a0f73 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -28,7 +28,7 @@ import (
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
var containerConfig *config.Config
@@ -65,7 +65,7 @@ func ParseRegistryCreds(creds string) (*types.DockerAuthConfig, error) {
}
if password == "" {
fmt.Print("Password: ")
- termPassword, err := terminal.ReadPassword(0)
+ termPassword, err := term.ReadPassword(0)
if err != nil {
return nil, errors.Wrapf(err, "could not read password from terminal")
}
diff --git a/rootless.md b/rootless.md
index 39c961d2a..d485290f2 100644
--- a/rootless.md
+++ b/rootless.md
@@ -18,7 +18,7 @@ can easily fail
* Some system unit configuration options do not work in the rootless container
* systemd fails to apply several options and failures are silently ignored (e.g. CPUShares, MemoryLimit). Should work on cgroup V2.
* Use of certain options will cause service startup failures (e.g. PrivateNetwork). The systemd services requiring `PrivateNetwork` can be made to work by passing `--cap-add SYS_ADMIN`, but the security implications should be carefully evaluated. In most cases, it's better to create an override.conf drop-in that sets `PrivateNetwork=no`. This also applies to containers run by root.
-* Can not share container images with CRI-O or other rootful users
+* Can not share container images with CRI-O or other rootfull users
* Difficult to use additional stores for sharing content
* Does not work on NFS or parallel filesystem homedirs (e.g. [GPFS](https://www.ibm.com/support/knowledgecenter/en/SSFKCN/gpfs_welcome.html))
* NFS and parallel filesystems enforce file creation on different UIDs on the server side and does not understand User Namespace.
diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go
index 7b2dd89c9..2dc99bdc9 100644
--- a/test/e2e/checkpoint_test.go
+++ b/test/e2e/checkpoint_test.go
@@ -1061,7 +1061,7 @@ var _ = Describe("Podman checkpoint", func() {
// Open a network connection to the redis server via initial port mapping
// This should fail
- conn, err = net.DialTimeout("tcp4", fmt.Sprintf("localhost:%d", randomPort), time.Duration(3)*time.Second)
+ _, err = net.DialTimeout("tcp4", fmt.Sprintf("localhost:%d", randomPort), time.Duration(3)*time.Second)
Expect(err).ToNot(BeNil())
Expect(err.Error()).To(ContainSubstring("connection refused"))
// Open a network connection to the redis server via new port mapping
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index 9580230b5..f808eb2b6 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -858,18 +858,15 @@ func (p *PodmanTestIntegration) makeOptions(args []string, noEvents, noCache boo
eventsType = "none"
}
- networkBackend := p.NetworkBackend.ToString()
- networkDir := p.NetworkConfigDir
- if p.NetworkBackend == Netavark {
- networkDir = p.NetworkConfigDir
- }
podmanOptions := strings.Split(fmt.Sprintf("%s--root %s --runroot %s --runtime %s --conmon %s --network-config-dir %s --cgroup-manager %s --tmpdir %s --events-backend %s",
- debug, p.Root, p.RunRoot, p.OCIRuntime, p.ConmonBinary, networkDir, p.CgroupManager, p.TmpDir, eventsType), " ")
+ debug, p.Root, p.RunRoot, p.OCIRuntime, p.ConmonBinary, p.NetworkConfigDir, p.CgroupManager, p.TmpDir, eventsType), " ")
if os.Getenv("HOOK_OPTION") != "" {
podmanOptions = append(podmanOptions, os.Getenv("HOOK_OPTION"))
}
- podmanOptions = append(podmanOptions, "--network-backend", networkBackend)
+ if !p.RemoteTest {
+ podmanOptions = append(podmanOptions, "--network-backend", p.NetworkBackend.ToString())
+ }
podmanOptions = append(podmanOptions, strings.Split(p.StorageOptions, " ")...)
if !noCache {
@@ -883,11 +880,11 @@ func (p *PodmanTestIntegration) makeOptions(args []string, noEvents, noCache boo
func writeConf(conf []byte, confPath string) {
if _, err := os.Stat(filepath.Dir(confPath)); os.IsNotExist(err) {
- if err := os.MkdirAll(filepath.Dir(confPath), 777); err != nil {
+ if err := os.MkdirAll(filepath.Dir(confPath), 0o777); err != nil {
fmt.Println(err)
}
}
- if err := ioutil.WriteFile(confPath, conf, 777); err != nil {
+ if err := ioutil.WriteFile(confPath, conf, 0o777); err != nil {
fmt.Println(err)
}
}
diff --git a/test/e2e/container_clone_test.go b/test/e2e/container_clone_test.go
index 1d5944d1a..1ff4b3b5f 100644
--- a/test/e2e/container_clone_test.go
+++ b/test/e2e/container_clone_test.go
@@ -235,4 +235,36 @@ var _ = Describe("Podman container clone", func() {
Expect(ctrInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode).Should(ContainSubstring("container:"))
})
+
+ It("podman container clone --destroy --force test", func() {
+ create := podmanTest.Podman([]string{"create", ALPINE})
+ create.WaitWithDefaultTimeout()
+ Expect(create).To(Exit(0))
+ clone := podmanTest.Podman([]string{"container", "clone", "--destroy", create.OutputToString()})
+ clone.WaitWithDefaultTimeout()
+ Expect(clone).To(Exit(0))
+
+ inspect := podmanTest.Podman([]string{"inspect", create.OutputToString()})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).ToNot(Exit(0))
+
+ run := podmanTest.Podman([]string{"run", "-dt", ALPINE})
+ run.WaitWithDefaultTimeout()
+ Expect(run).To(Exit(0))
+ clone = podmanTest.Podman([]string{"container", "clone", "--destroy", "-f", run.OutputToString()})
+ clone.WaitWithDefaultTimeout()
+ Expect(clone).To(Exit(0))
+
+ inspect = podmanTest.Podman([]string{"inspect", run.OutputToString()})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).ToNot(Exit(0))
+
+ run = podmanTest.Podman([]string{"run", "-dt", ALPINE})
+ run.WaitWithDefaultTimeout()
+ Expect(run).To(Exit(0))
+ clone = podmanTest.Podman([]string{"container", "clone", "-f", run.OutputToString()})
+ clone.WaitWithDefaultTimeout()
+ Expect(clone).ToNot(Exit(0))
+
+ })
})
diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go
index 11f8b5abf..4c3b5604a 100644
--- a/test/e2e/create_test.go
+++ b/test/e2e/create_test.go
@@ -118,7 +118,7 @@ var _ = Describe("Podman create", func() {
result := podmanTest.Podman([]string{"inspect", "entrypoint_test", "--format", "{{.Config.Entrypoint}}"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
- Expect(result.OutputToString()).To(Equal("[/bin/foobar]"))
+ Expect(result.OutputToString()).To(Equal("/bin/foobar"))
})
It("podman create --entrypoint \"\"", func() {
@@ -130,7 +130,7 @@ var _ = Describe("Podman create", func() {
result := podmanTest.Podman([]string{"inspect", session.OutputToString(), "--format", "{{.Config.Entrypoint}}"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
- Expect(result.OutputToString()).To(Equal("[]"))
+ Expect(result.OutputToString()).To(Equal(""))
})
It("podman create --entrypoint json", func() {
@@ -143,7 +143,7 @@ var _ = Describe("Podman create", func() {
result := podmanTest.Podman([]string{"inspect", "entrypoint_json", "--format", "{{.Config.Entrypoint}}"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
- Expect(result.OutputToString()).To(Equal("[/bin/foo -c]"))
+ Expect(result.OutputToString()).To(Equal("/bin/foo -c"))
})
It("podman create --mount flag with multiple mounts", func() {
@@ -281,8 +281,7 @@ var _ = Describe("Podman create", func() {
Expect(ctrJSON).To(HaveLen(1))
Expect(ctrJSON[0].Config.Cmd).To(HaveLen(1))
Expect(ctrJSON[0].Config.Cmd[0]).To(Equal("redis-server"))
- Expect(ctrJSON[0].Config.Entrypoint).To(HaveLen(1))
- Expect(ctrJSON[0].Config.Entrypoint[0]).To(Equal("docker-entrypoint.sh"))
+ Expect(ctrJSON[0].Config.Entrypoint).To(Equal("docker-entrypoint.sh"))
})
It("podman create --pull", func() {
diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go
index 3987746d0..4cfaa9a2e 100644
--- a/test/e2e/exec_test.go
+++ b/test/e2e/exec_test.go
@@ -123,7 +123,7 @@ var _ = Describe("Podman exec", func() {
})
It("podman exec in keep-id container drops privileges", func() {
- SkipIfNotRootless("This function is not enabled for rootful podman")
+ SkipIfNotRootless("This function is not enabled for rootfull podman")
ctrName := "testctr1"
testCtr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "--userns=keep-id", ALPINE, "top"})
testCtr.WaitWithDefaultTimeout()
diff --git a/test/e2e/libpod_suite_remote_test.go b/test/e2e/libpod_suite_remote_test.go
index dddcf5c14..9ad2bf7b9 100644
--- a/test/e2e/libpod_suite_remote_test.go
+++ b/test/e2e/libpod_suite_remote_test.go
@@ -137,6 +137,9 @@ func getRemoteOptions(p *PodmanTestIntegration, args []string) []string {
if os.Getenv("HOOK_OPTION") != "" {
podmanOptions = append(podmanOptions, os.Getenv("HOOK_OPTION"))
}
+ if p.NetworkBackend.ToString() == "netavark" {
+ podmanOptions = append(podmanOptions, "--network-backend", "netavark")
+ }
podmanOptions = append(podmanOptions, strings.Split(p.StorageOptions, " ")...)
podmanOptions = append(podmanOptions, args...)
return podmanOptions
diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go
index 77549a9a8..001779cdf 100644
--- a/test/e2e/login_logout_test.go
+++ b/test/e2e/login_logout_test.go
@@ -188,6 +188,8 @@ var _ = Describe("Podman login and logout", func() {
Expect(session).To(ExitWithError())
session = podmanTest.Podman([]string{"logout", "--authfile", authFile, server})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
})
It("podman login and logout with --tls-verify", func() {
diff --git a/test/e2e/mount_rootless_test.go b/test/e2e/mount_rootless_test.go
index 30d7ce8a9..830c2dcda 100644
--- a/test/e2e/mount_rootless_test.go
+++ b/test/e2e/mount_rootless_test.go
@@ -17,7 +17,7 @@ var _ = Describe("Podman mount", func() {
)
BeforeEach(func() {
- SkipIfNotRootless("This function is not enabled for rootful podman")
+ SkipIfNotRootless("This function is not enabled for rootfull podman")
SkipIfRemote("Podman mount not supported for remote connections")
tempdir, err = CreateTempDirInTempDir()
if err != nil {
diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go
index 89a9005f5..a7981a4d8 100644
--- a/test/e2e/network_test.go
+++ b/test/e2e/network_test.go
@@ -254,7 +254,7 @@ var _ = Describe("Podman network", func() {
expectedNetworks := []string{name}
if !rootless.IsRootless() {
- // rootful image contains "podman/cni/87-podman-bridge.conflist" for "podman" network
+ // rootfull image contains "podman/cni/87-podman-bridge.conflist" for "podman" network
expectedNetworks = append(expectedNetworks, "podman")
}
session := podmanTest.Podman(append([]string{"network", "inspect"}, expectedNetworks...))
diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go
index dc43ce6fd..8def80213 100644
--- a/test/e2e/pod_create_test.go
+++ b/test/e2e/pod_create_test.go
@@ -368,7 +368,7 @@ var _ = Describe("Podman pod create", func() {
check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID})
check1.WaitWithDefaultTimeout()
Expect(check1).Should(Exit(0))
- Expect(check1.OutputToString()).To(Equal("[/catatonit -P]"))
+ Expect(check1.OutputToString()).To(Equal("/catatonit -P"))
// check the Path and Args
check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID})
@@ -391,7 +391,7 @@ var _ = Describe("Podman pod create", func() {
check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID})
check1.WaitWithDefaultTimeout()
Expect(check1).Should(Exit(0))
- Expect(check1.OutputToString()).To(Equal("[/pause1]"))
+ Expect(check1.OutputToString()).To(Equal("/pause1"))
// check the Path and Args
check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID})
@@ -418,7 +418,7 @@ entrypoint ["/fromimage"]
check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID})
check1.WaitWithDefaultTimeout()
Expect(check1).Should(Exit(0))
- Expect(check1.OutputToString()).To(Equal("[/fromimage]"))
+ Expect(check1.OutputToString()).To(Equal("/fromimage"))
// check the Path and Args
check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID})
@@ -445,7 +445,7 @@ entrypoint ["/fromimage"]
check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID})
check1.WaitWithDefaultTimeout()
Expect(check1).Should(Exit(0))
- Expect(check1.OutputToString()).To(Equal("[/fromcommand]"))
+ Expect(check1.OutputToString()).To(Equal("/fromcommand"))
// check the Path and Args
check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID})
diff --git a/test/e2e/push_test.go b/test/e2e/push_test.go
index a8a98fc07..3b571ab20 100644
--- a/test/e2e/push_test.go
+++ b/test/e2e/push_test.go
@@ -220,6 +220,7 @@ var _ = Describe("Podman push", func() {
if setup.LineInOutputContains("Active: inactive") {
setup = SystemExec("systemctl", []string{"start", "docker"})
+ Expect(setup).Should(Exit(0))
defer func() {
stop := SystemExec("systemctl", []string{"stop", "docker"})
Expect(stop).Should(Exit(0))
diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go
index 4887197f6..0be84e11b 100644
--- a/test/e2e/run_volume_test.go
+++ b/test/e2e/run_volume_test.go
@@ -120,6 +120,11 @@ var _ = Describe("Podman run with volumes", func() {
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
+ // test csv escaping
+ session = podmanTest.Podman([]string{"run", "--rm", "--mount=type=tmpfs,tmpfs-size=512M,\"destination=/test,\"", ALPINE, "ls", "/test,"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
session = podmanTest.Podman([]string{"run", "--rm", "--mount", "type=bind,src=/tmp,target=/tmp,tmpcopyup", ALPINE, "true"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
diff --git a/test/e2e/systemd_activate_test.go b/test/e2e/systemd_activate_test.go
index d5434868d..04acafe1b 100644
--- a/test/e2e/systemd_activate_test.go
+++ b/test/e2e/systemd_activate_test.go
@@ -97,7 +97,7 @@ var _ = Describe("Systemd activate", func() {
// Emulate 'systemd stop podman.service'
activateSession.Signal(syscall.SIGTERM)
- time.Sleep(2)
+ time.Sleep(100 * time.Millisecond)
Eventually(activateSession).Should(Exit(0))
abiSession := podman("inspect", "--format={{.State.Running}}", containerName)
diff --git a/test/system/000-TEMPLATE b/test/system/000-TEMPLATE
index 85e25e921..a6a9ca141 100644
--- a/test/system/000-TEMPLATE
+++ b/test/system/000-TEMPLATE
@@ -10,7 +10,7 @@ load helpers
@test "podman subcmd - description of this particular test" {
args="some sort of argument list"
run_podman subcmd $args
- is "$output" "what we expect" "output from 'podman subcmd $args'"
+ assert "$output" == "what we expect" "output from 'podman subcmd $args'"
}
# vim: filetype=sh
@@ -66,7 +66,7 @@ function teardown() {
# FIXME: example of dprint. This will trigger if PODMAN_TEST_DEBUG=FOO
# FIXME: ...or anything that matches the name assigned in the @test line.
dprint "podman logs $cid -> '$output'"
- is "$output" "what are we expecting?" "description of this check"
+ assert "$output" == "what are we expecting?" "description of this check"
# Clean up
run_podman rm $cid
@@ -90,7 +90,7 @@ size | -\\\?[0-9]\\\+
run_podman history --format json $IMAGE
# FIXME: parse_table is what does all the work, giving us test cases.
- parse_table "$tests" | while read field expect; do
+ while read field expect; do
# FIXME: this shows a drawback of BATS and bash: we can't include '|'
# FIXME: in the table, but we need to because some images don't
# FIXME: have a CID. So, yeah, this is ugly -- but rare.
@@ -104,10 +104,10 @@ size | -\\\?[0-9]\\\+
# FIXME: please be sure to note the third field!
# FIXME: that's the test name. Make it something useful! Include
# FIXME: loop variables whenever possible. Don't just say "my test"
- is "$actual" "$expect\$" "jq .[$i].$field"
+ assert "$actual" =~ "$expect\$" "jq .[$i].$field"
i=$(expr $i + 1)
done
- done
+ done < <(parse_table "$tests")
}
diff --git a/test/system/001-basic.bats b/test/system/001-basic.bats
index 582efa058..0d2a99d4b 100644
--- a/test/system/001-basic.bats
+++ b/test/system/001-basic.bats
@@ -28,9 +28,7 @@ function setup() {
# Test that build date is reasonable, e.g. after 2019-01-01
local built=$(expr "$output" : ".*Built: \+\(.*\)" | head -n1)
local built_t=$(date --date="$built" +%s)
- if [ $built_t -lt 1546300800 ]; then
- die "Preposterous 'Built' time in podman version: '$built'"
- fi
+ assert "$built_t" -gt 1546300800 "Preposterous 'Built' time in podman version"
}
@test "podman info" {
@@ -114,29 +112,25 @@ See 'podman version --help'" "podman version --remote"
# By default, podman should include '--remote' in its help output
run_podman --help
- is "$output" ".* --remote " "podman --help includes the --remote option"
+ assert "$output" =~ " --remote " "podman --help includes the --remote option"
# When it detects CONTAINER_HOST or _CONNECTION, --remote is not an option
CONTAINER_HOST=foobar run_podman --help
- if grep -- " --remote " <<<"$output"; then
- die "podman --help, with CONTAINER_HOST set, is showing --remote"
- fi
+ assert "$output" !~ " --remote " \
+ "podman --help, with CONTAINER_HOST set, should not show --remote"
CONTAINER_CONNECTION=foobar run_podman --help
- if grep -- " --remote " <<<"$output"; then
- die "podman --help, with CONTAINER_CONNECTION set, is showing --remote"
- fi
+ assert "$output" !~ " --remote " \
+ "podman --help, with CONTAINER_CONNECTION set, should not show --remote"
# When it detects --url or --connection, --remote is not an option
run_podman --url foobar --help
- if grep -- " --remote " <<<"$output"; then
- die "podman --help, with --url set, is showing --remote"
- fi
+ assert "$output" !~ " --remote " \
+ "podman --help, with --url set, should not show --remote"
run_podman --connection foobar --help
- if grep -- " --remote " <<<"$output"; then
- die "podman --help, with --connection set, is showing --remote"
- fi
+ assert "$output" !~ " --remote " \
+ "podman --help, with --connection set, should not show --remote"
}
# Check that just calling "podman-remote" prints the usage message even
diff --git a/test/system/015-help.bats b/test/system/015-help.bats
index 4eeea85bf..5757d51dc 100644
--- a/test/system/015-help.bats
+++ b/test/system/015-help.bats
@@ -27,7 +27,7 @@ function check_help() {
# The line immediately after 'Usage:' gives us a 1-line synopsis
usage=$(echo "$full_help" | grep -A1 '^Usage:' | tail -1)
- [ -n "$usage" ] || die "podman $cmd: no Usage message found"
+ assert "$usage" != "" "podman $cmd: no Usage message found"
# e.g. 'podman ps' should not show 'podman container ps' in usage
# Trailing space in usage handles 'podman system renumber' which
@@ -42,14 +42,12 @@ function check_help() {
fi
# We had someone write upper-case '[OPTIONS]' once. Prevent it.
- if expr "$usage" : '.*\[OPTION' >/dev/null; then
- die "'options' string must be lower-case in usage: $usage"
- fi
+ assert "$usage" !~ '\[OPTION' \
+ "'options' string must be lower-case in usage"
# We had someone do 'podman foo ARG [options]' one time. Yeah, no.
- if expr "$usage" : '.*[A-Z].*\[option' >/dev/null; then
- die "'options' must precede arguments in usage: $usage"
- fi
+ assert "$usage" !~ '[A-Z].*\[option' \
+ "'options' must precede arguments in usage"
# Cross-check: if usage includes '[options]', there must be a
# longer 'Options:' section in the full --help output; vice-versa,
@@ -169,16 +167,15 @@ function check_help() {
# This can happen if the output of --help changes, such as between
# the old command parser and cobra.
- [ $count -gt 0 ] || \
- die "Internal error: no commands found in 'podman help $@' list"
+ assert "$count" -gt 0 \
+ "Internal error: no commands found in 'podman help $*' list"
# Sanity check: make sure the special loops above triggered at least once.
# (We've had situations where a typo makes the conditional never run)
if [ -z "$*" ]; then
for i in subcommands required_args takes_no_args fixed_args; do
- if [[ -z ${found[$i]} ]]; then
- die "Internal error: '$i' subtest did not trigger"
- fi
+ assert "${found[$i]}" != "" \
+ "Internal error: '$i' subtest did not trigger"
done
fi
}
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index aa75a6462..087f74690 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -78,12 +78,11 @@ echo $rand | 0 | $rand
skip_if_remote "TODO Fix this for remote case"
run_podman run --rm --uidmap 0:100:10000 $IMAGE mount
- run grep /sys/kernel <(echo "$output")
- is "$output" "" "unwanted /sys/kernel in 'mount' output"
+ assert "$output" !~ /sys/kernel "unwanted /sys/kernel in 'mount' output"
run_podman run --rm --net host --uidmap 0:100:10000 $IMAGE mount
- run grep /sys/kernel <(echo "$output")
- is "$output" "" "unwanted /sys/kernel in 'mount' output (with --net=host)"
+ assert "$output" !~ /sys/kernel \
+ "unwanted /sys/kernel in 'mount' output (with --net=host)"
}
# 'run --rm' goes through different code paths and may lose exit status.
@@ -696,10 +695,8 @@ json-file | f
# This operation should take
# exactly 10 seconds. Give it some leeway.
delta_t=$(( $t1 - $t0 ))
- [ $delta_t -gt 8 ] ||\
- die "podman stop: ran too quickly! ($delta_t seconds; expected >= 10)"
- [ $delta_t -le 14 ] ||\
- die "podman stop: took too long ($delta_t seconds; expected ~10)"
+ assert "$delta_t" -gt 8 "podman stop: ran too quickly!"
+ assert "$delta_t" -le 14 "podman stop: took too long"
run_podman rm $cid
}
@@ -757,34 +754,40 @@ EOF
@test "podman run defaultenv" {
run_podman run --rm $IMAGE printenv
- is "$output" ".*TERM=xterm" "output matches TERM"
- is "$output" ".*container=podman" "output matches container=podman"
+ assert "$output" =~ "TERM=xterm" "env includes TERM"
+ assert "$output" =~ "container=podman" "env includes container=podman"
run_podman run --unsetenv=TERM --rm $IMAGE printenv
- is "$output" ".*container=podman" "output matches container=podman"
- run grep TERM <<<$output
- is "$output" "" "unwanted TERM environment variable despite --unsetenv=TERM"
+ assert "$output" =~ "container=podman" "env includes container=podman"
+ assert "$output" != "TERM" "unwanted TERM environment variable despite --unsetenv=TERM"
run_podman run --unsetenv-all --rm $IMAGE /bin/printenv
- run grep TERM <<<$output
- is "$output" "" "unwanted TERM environment variable despite --unsetenv-all"
- run grep container <<<$output
- is "$output" "" "unwanted container environment variable despite --unsetenv-all"
- run grep PATH <<<$output
- is "$output" "" "unwanted PATH environment variable despite --unsetenv-all"
+ for v in TERM container PATH; do
+ assert "$output" !~ "$v" "variable present despite --unsetenv-all"
+ done
run_podman run --unsetenv-all --env TERM=abc --rm $IMAGE /bin/printenv
- is "$output" ".*TERM=abc" "missing TERM environment variable despite TERM being set on commandline"
+ assert "$output" =~ "TERM=abc" \
+ "missing TERM environment variable despite TERM being set on commandline"
}
@test "podman run - no /etc/hosts" {
+ if [[ -z "$container" ]]; then
+ skip "Test is too dangerous to run in a non-container environment"
+ fi
skip_if_rootless "cannot move /etc/hosts file as a rootless user"
- tmpfile=$PODMAN_TMPDIR/hosts
- mv /etc/hosts $tmpfile
+
+ local hosts_tmp=/etc/hosts.RENAME-ME-BACK-TO-JUST-HOSTS
+ if [[ -e $hosts_tmp ]]; then
+ die "Internal error: leftover backup hosts file: $hosts_tmp"
+ fi
+ mv /etc/hosts $hosts_tmp
run_podman '?' run --rm --add-host "foo.com:1.2.3.4" $IMAGE cat "/etc/hosts"
- mv $tmpfile /etc/hosts
- is "$status" 0 "podman run without /etc/hosts file should work"
- is "$output" "1.2.3.4 foo.com.*" "users can add hosts even without /etc/hosts"
+ mv $hosts_tmp /etc/hosts
+ assert "$status" = 0 \
+ "podman run without /etc/hosts file should work"
+ assert "$output" =~ "^1\.2\.3\.4 foo.com.*" \
+ "users can add hosts even without /etc/hosts"
}
# rhbz#1854566 : $IMAGE has incorrect permission 555 on the root '/' filesystem
diff --git a/test/system/035-logs.bats b/test/system/035-logs.bats
index e38cdb383..97d984ef1 100644
--- a/test/system/035-logs.bats
+++ b/test/system/035-logs.bats
@@ -224,9 +224,8 @@ $s_after"
retries=$((retries - 1))
sleep 0.1
done
- if [[ $retries -eq 0 ]]; then
- die "Timed out waiting for before&after in podman logs: $output"
- fi
+ assert $retries -gt 0 \
+ "Timed out waiting for before&after in podman logs: $output"
run_podman logs --until $before test
is "$output" "" "podman logs --until before"
diff --git a/test/system/040-ps.bats b/test/system/040-ps.bats
index 6fc0b9b6e..f450caf7c 100644
--- a/test/system/040-ps.bats
+++ b/test/system/040-ps.bats
@@ -98,9 +98,8 @@ RUN sleep 30
EOF
local t1=$SECONDS
local delta_t=$((t1 - t0))
- if [[ $delta_t -gt 10 ]]; then
- die "podman build did not get killed within 10 seconds (actual time: $delta_t seconds)"
- fi
+ assert $delta_t -le 10 \
+ "podman build did not get killed within 10 seconds"
run_podman ps -a
is "${#lines[@]}" "1" "podman ps -a does not see buildah containers"
diff --git a/test/system/045-start.bats b/test/system/045-start.bats
index 31e924ca5..ad8483bba 100644
--- a/test/system/045-start.bats
+++ b/test/system/045-start.bats
@@ -21,9 +21,8 @@ load helpers
is "$output" ".*$cid_none_implicit" "started: container with no --restart"
is "$output" ".*$cid_none_explicit" "started: container with --restart=no"
is "$output" ".*$cid_on_failure" "started: container with --restart=on-failure"
- if [[ $output =~ $cid_always ]]; then
- die "podman start --all restarted a running container"
- fi
+ assert "$output" !~ "$cid_always" \
+ "podman start --all should not restart a running container"
run_podman wait $cid_none_implicit $cid_none_explicit $cid_on_failure
diff --git a/test/system/050-stop.bats b/test/system/050-stop.bats
index 7dd8f98e8..c2dfba84d 100644
--- a/test/system/050-stop.bats
+++ b/test/system/050-stop.bats
@@ -22,10 +22,8 @@ load helpers
# The initial SIGTERM is ignored, so this operation should take
# exactly 10 seconds. Give it some leeway.
delta_t=$(( $t1 - $t0 ))
- [ $delta_t -gt 8 ] ||\
- die "podman stop: ran too quickly! ($delta_t seconds; expected >= 10)"
- [ $delta_t -le 14 ] ||\
- die "podman stop: took too long ($delta_t seconds; expected ~10)"
+ assert $delta_t -gt 8 "podman stop: ran too quickly!"
+ assert $delta_t -le 14 "podman stop: took too long"
run_podman rm $cid
}
@@ -103,8 +101,7 @@ load helpers
# The 'stop' command should return almost instantaneously
delta_t=$(( $t1 - $t0 ))
- [ $delta_t -le 2 ] ||\
- die "podman stop: took too long ($delta_t seconds; expected <= 2)"
+ assert $delta_t -le 2 "podman stop: took too long"
run_podman rm $cid
done
@@ -138,9 +135,7 @@ load helpers
break
fi
timeout=$((timeout - 1))
- if [[ $timeout -eq 0 ]]; then
- die "Timed out waiting for container to receive SIGERM"
- fi
+ assert $timeout -gt 0 "Timed out waiting for container to receive SIGTERM"
sleep 0.5
done
@@ -154,9 +149,7 @@ load helpers
# Time check: make sure we were able to run 'ps' before the container
# exited. If this takes too long, it means ps had to wait for lock.
local delta_t=$(( $SECONDS - t0 ))
- if [[ $delta_t -gt 5 ]]; then
- die "Operations took too long ($delta_t seconds)"
- fi
+ assert $delta_t -le 5 "Operations took too long"
run_podman kill stopme
run_podman wait stopme
diff --git a/test/system/065-cp.bats b/test/system/065-cp.bats
index 260ad4800..cfbeff3ae 100644
--- a/test/system/065-cp.bats
+++ b/test/system/065-cp.bats
@@ -593,20 +593,22 @@ ${randomcontent[1]}" "$description"
# RUNNING container
# NOTE: /dest does not exist yet but is expected to be created during copy
run_podman cp cpcontainer:/tmp/sub/weirdlink $destdir/dest
- run cat $destdir/dest/containerfile0 $destdir/dest/containerfile1
- is "${lines[0]}" "${randomcontent[0]}" "eval symlink - running container"
- is "${lines[1]}" "${randomcontent[1]}" "eval symlink - running container"
+ for i in 0 1; do
+ assert "$(< $destdir/dest/containerfile$i)" = "${randomcontent[$i]}" \
+ "eval symlink - running container - file $i/1"
+ done
run_podman kill cpcontainer
run_podman rm -t 0 -f cpcontainer
- run rm -rf $srcdir/dest
+ rm -rf $srcdir/dest
# CREATED container
run_podman create --name cpcontainer $cpimage
run_podman cp cpcontainer:/tmp/sub/weirdlink $destdir/dest
- run cat $destdir/dest/containerfile0 $destdir/dest/containerfile1
- is "${lines[0]}" "${randomcontent[0]}" "eval symlink - created container"
- is "${lines[1]}" "${randomcontent[1]}" "eval symlink - created container"
+ for i in 0 1; do
+ assert "$(< $destdir/dest/containerfile$i)" = "${randomcontent[$i]}" \
+ "eval symlink - created container - file $i/1"
+ done
run_podman rm -t 0 -f cpcontainer
run_podman rmi $cpimage
}
@@ -928,20 +930,16 @@ ${randomcontent[1]}" "$description"
# Copy file.
$PODMAN cp cpcontainer:/tmp/file.txt - > $srcdir/stdout.tar
- if [ $? -ne 0 ]; then
- die "Command failed: podman cp ... - | cat"
- fi
tar xvf $srcdir/stdout.tar -C $srcdir
- is "$(< $srcdir/file.txt)" "$rand_content"
- run 1 ls $srcdir/empty.txt
+ is "$(< $srcdir/file.txt)" "$rand_content" "File contents: file.txt"
+ if [[ -e "$srcdir/empty.txt" ]]; then
+ die "File should not exist, but does: empty.txt"
+ fi
rm -f $srcdir/*
# Copy directory.
$PODMAN cp cpcontainer:/tmp - > $srcdir/stdout.tar
- if [ $? -ne 0 ]; then
- die "Command failed: podman cp ... - | cat : $output"
- fi
tar xvf $srcdir/stdout.tar -C $srcdir
is "$(< $srcdir/tmp/file.txt)" "$rand_content"
diff --git a/test/system/070-build.bats b/test/system/070-build.bats
index 7466c3b74..b7e0ab447 100644
--- a/test/system/070-build.bats
+++ b/test/system/070-build.bats
@@ -60,21 +60,18 @@ EOF
# Now confirm that each volume got a unique device ID
run_podman run --rm build_test stat -c '%D' / /a /a/b /a/b/c /\[ /\[/etc /\[/etc/foo, /etc /etc/bar\]
# First, the non-volumes should all be the same...
- is "${lines[0]}" "${lines[1]}" "devnum( / ) = devnum( /a )"
- is "${lines[0]}" "${lines[2]}" "devnum( / ) = devnum( /a/b )"
- is "${lines[0]}" "${lines[4]}" "devnum( / ) = devnum( /[ )"
- is "${lines[0]}" "${lines[5]}" "devnum( / ) = devnum( /[etc )"
- is "${lines[0]}" "${lines[7]}" "devnum( / ) = devnum( /etc )"
- is "${lines[6]}" "${lines[8]}" "devnum( /[etc/foo, ) = devnum( /etc/bar] )"
+ assert "${lines[0]}" = "${lines[1]}" "devnum( / ) = devnum( /a )"
+ assert "${lines[0]}" = "${lines[2]}" "devnum( / ) = devnum( /a/b )"
+ assert "${lines[0]}" = "${lines[4]}" "devnum( / ) = devnum( /[ )"
+ assert "${lines[0]}" = "${lines[5]}" "devnum( / ) = devnum( /[etc )"
+ assert "${lines[0]}" = "${lines[7]}" "devnum( / ) = devnum( /etc )"
+ assert "${lines[6]}" = "${lines[8]}" "devnum( /[etc/foo, ) = devnum( /etc/bar] )"
# ...then, each volume should be different
- if [[ "${lines[0]}" = "${lines[3]}" ]]; then
- die "devnum( / ) (${lines[0]}) = devnum( volume0 ) (${lines[3]}) -- they should differ"
- fi
- if [[ "${lines[0]}" = "${lines[6]}" ]]; then
- die "devnum( / ) (${lines[0]}) = devnum( volume1 ) (${lines[6]}) -- they should differ"
- fi
+ assert "${lines[0]}" != "${lines[3]}" "devnum( / ) != devnum( volume0 )"
+ assert "${lines[0]}" != "${lines[6]}" "devnum( / ) != devnum( volume1 )"
+
# FIXME: is this expected? I thought /a/b/c and /[etc/foo, would differ
- is "${lines[3]}" "${lines[6]}" "devnum( volume0 ) = devnum( volume1 )"
+ assert "${lines[3]}" = "${lines[6]}" "devnum( volume0 ) = devnum( volume1 )"
run_podman rmi -f build_test
}
@@ -106,7 +103,7 @@ EOF
rand_content=$(random_string 50)
tmpdir=$PODMAN_TMPDIR/build-test
- run mkdir -p $tmpdir
+ mkdir -p $tmpdir
containerfile=$tmpdir/Containerfile
cat >$containerfile <<EOF
FROM $IMAGE
@@ -122,7 +119,7 @@ EOF
# Test on the CLI and via containers.conf
tmpdir=$PODMAN_TMPDIR/build-test
- run mkdir -p $tmpdir
+ mkdir -p $tmpdir
containerfile=$tmpdir/Containerfile
cat >$containerfile <<EOF
FROM $IMAGE
@@ -146,10 +143,10 @@ EOF
@test "podman build - cache (#3920)" {
# Make an empty test directory, with a subdirectory used for tar
tmpdir=$PODMAN_TMPDIR/build-test
- mkdir -p $tmpdir/subtest || die "Could not mkdir $tmpdir/subtest"
+ mkdir -p $tmpdir/subtest
echo "This is the ORIGINAL file" > $tmpdir/subtest/myfile1
- run tar -C $tmpdir -cJf $tmpdir/myfile.tar.xz subtest
+ tar -C $tmpdir -cJf $tmpdir/myfile.tar.xz subtest
cat >$tmpdir/Dockerfile <<EOF
FROM $IMAGE
@@ -169,7 +166,7 @@ EOF
# Step 2: Recreate the tarfile, with new content. Rerun podman build.
echo "This is a NEW file" >| $tmpdir/subtest/myfile2
- run tar -C $tmpdir -cJf $tmpdir/myfile.tar.xz subtest
+ tar -C $tmpdir -cJf $tmpdir/myfile.tar.xz subtest
run_podman build -t build_test -f $tmpdir/Dockerfile $tmpdir
is "$output" ".*COMMIT" "COMMIT seen in log"
@@ -371,9 +368,8 @@ EOF
-t build_test -f build-test/Containerfile build-test
local iid="${lines[-1]}"
- if [[ $output =~ missing.*build.argument ]]; then
- die "podman did not see the given --build-arg(s)"
- fi
+ assert "$output" !~ "missing.*build.argument" \
+ "podman did not see the given --build-arg(s)"
# Make sure 'podman build' had the secret mounted
is "$output" ".*$secret_contents.*" "podman build has /run/secrets mounted"
@@ -449,9 +445,7 @@ EOF
run_podman image inspect build_test
# (Assert that output is formatted, not a one-line blob: #8011)
- if [[ "${#lines[*]}" -lt 10 ]]; then
- die "Output from 'image inspect' is only ${#lines[*]} lines; see #8011"
- fi
+ assert "${#lines[*]}" -ge 10 "Output from 'image inspect'; see #8011"
tests="
Env[1] | MYENV1=$s_env1
@@ -591,12 +585,11 @@ EOF
for f in ${files[@]}; do
if [[ $f =~ ^- ]]; then
f=${f##-}
- if [[ $output =~ $f ]]; then
- die "File '$f' found in image; it should have been ignored via $ignorefile"
- fi
+ assert "$output" !~ "$f" \
+ "File '$f' should have been ignored via $ignorefile"
else
- is "$output" ".*$newdir/$f" \
- "File '$f' should exist in container (no match in $ignorefile)"
+ assert "$output" =~ "$newdir/$f" \
+ "File '$f' should exist in container (no match in $ignorefile)"
fi
done
@@ -727,7 +720,7 @@ a${random3}z"
@test "podman build --layers test" {
rand_content=$(random_string 50)
tmpdir=$PODMAN_TMPDIR/build-test
- run mkdir -p $tmpdir
+ mkdir -p $tmpdir
containerfile=$tmpdir/Containerfile
cat >$containerfile <<EOF
FROM $IMAGE
@@ -870,8 +863,7 @@ FROM $IMAGE
EOF
run_podman build -t build_test --format=docker --logfile=$tmpdir/logfile $tmpbuilddir
- run cat $tmpdir/logfile
- is "$output" ".*COMMIT" "COMMIT seen in log"
+ assert "$(< $tmpdir/logfile)" =~ "COMMIT" "COMMIT seen in log"
run_podman rmi -f build_test
}
diff --git a/test/system/090-events.bats b/test/system/090-events.bats
index cac0a177c..128802360 100644
--- a/test/system/090-events.bats
+++ b/test/system/090-events.bats
@@ -126,8 +126,7 @@ function _events_disjunctive_filters() {
events_logfile_path="$events_file"
EOF
CONTAINERS_CONF="$containersconf" run_podman --events-backend=file pull $IMAGE
- run cat $events_file
- is "$output" ".*\"Name\":\"$IMAGE" "test"
+ assert "$(< $events_file)" =~ "\"Name\":\"$IMAGE\"" "Image found in events"
}
function _populate_events_file() {
@@ -172,7 +171,7 @@ EOF
[engine]
events_logger="file"
events_logfile_path="$eventsFile"
-# The limit of 4750 is the *exact* half of the inital events file.
+# The limit of 4750 is the *exact* half of the initial events file.
events_logfile_max_size=4750
EOF
diff --git a/test/system/120-load.bats b/test/system/120-load.bats
index 8bf785081..45e0b3362 100644
--- a/test/system/120-load.bats
+++ b/test/system/120-load.bats
@@ -52,9 +52,7 @@ verify_iid_and_name() {
# which redirects stdout and stderr. Here we need to guarantee
# that podman's stdout is a pipe, not any other form of redirection
$PODMAN save --format oci-archive $fqin | cat >$archive
- if [ "$status" -ne 0 ]; then
- die "Command failed: podman save ... | cat"
- fi
+ assert "$?" -eq 0 "Command failed: podman save ... | cat"
# Make sure we can reload it
run_podman rmi $fqin
@@ -265,9 +263,7 @@ verify_iid_and_name() {
# which redirects stdout and stderr. Here we need to guarantee
# that podman's stdout is a pipe, not any other form of redirection
$PODMAN save -m $img1 $img2 | cat >$archive
- if [ "$status" -ne 0 ]; then
- die "Command failed: podman save ... | cat"
- fi
+ assert "$?" -eq 0 "Command failed: podman save ... | cat"
run_podman rmi -f $img1 $img2
run_podman load -i $archive
@@ -284,7 +280,7 @@ verify_iid_and_name() {
# Create a tarball, unpack it and make sure the layers are uncompressed.
run_podman save -o $archive --format oci-archive --uncompressed $IMAGE
- run tar -C $untar -xvf $archive
+ tar -C $untar -xvf $archive
run file $untar/blobs/sha256/*
is "$output" ".*POSIX tar archive" "layers are uncompressed"
}
diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats
index 1a558c599..5b0460723 100644
--- a/test/system/160-volumes.bats
+++ b/test/system/160-volumes.bats
@@ -283,9 +283,7 @@ EOF
# (Assert that output is formatted, not a one-line blob: #8011)
run_podman volume inspect ${v[1]}
- if [[ "${#lines[*]}" -lt 10 ]]; then
- die "Output from 'volume inspect' is only ${#lines[*]} lines; see #8011"
- fi
+ assert "${#lines[*]}" -ge 10 "Output from 'volume inspect'; see #8011"
# Run two containers: one mounting v1, one mounting v2 & v3
run_podman run --name c1 --volume ${v[1]}:/vol1 $IMAGE date
diff --git a/test/system/180-blkio.bats b/test/system/180-blkio.bats
index 7999c9ec5..7b7fb0201 100644
--- a/test/system/180-blkio.bats
+++ b/test/system/180-blkio.bats
@@ -31,7 +31,8 @@ function teardown() {
losetup -f ${lofile}
run losetup -l --noheadings --output BACK-FILE,NAME,MAJ:MIN
- is "$output" ".\+" "Empty output from losetup"
+ assert "$status" -eq 0 "losetup: status"
+ assert "$output" != "" "losetup: output"
lodevice=$(awk "\$1 == \"$lofile\" { print \$2 }" <<<"$output")
lomajmin=$(awk "\$1 == \"$lofile\" { print \$3 }" <<<"$output")
diff --git a/test/system/190-run-ipcns.bats b/test/system/190-run-ipcns.bats
index 9327d8ec7..db1d716d7 100644
--- a/test/system/190-run-ipcns.bats
+++ b/test/system/190-run-ipcns.bats
@@ -7,30 +7,25 @@
load helpers
@test "podman --ipc=host" {
- run readlink /proc/self/ns/ipc
- hostipc=$output
+ hostipc="$(readlink /proc/self/ns/ipc)"
run_podman run --rm --ipc=host $IMAGE readlink /proc/self/ns/ipc
is "$output" "$hostipc" "HostIPC and container IPC should be same"
}
@test "podman --ipc=none" {
- run readlink /proc/self/ns/ipc
- hostipc=$output
+ hostipc="$(readlink /proc/self/ns/ipc)"
run_podman run --rm --ipc=none $IMAGE readlink /proc/self/ns/ipc
- if [[ $output == "$hostipc" ]]; then
- die "hostipc and containeripc should be different"
- fi
+ assert "$output" != "$hostipc" "containeripc should != hostipc"
+
run_podman 1 run --rm --ipc=none $IMAGE ls /dev/shm
is "$output" "ls: /dev/shm: No such file or directory" "Should fail with missing /dev/shm"
}
@test "podman --ipc=private" {
- run readlink /proc/self/ns/ipc
- hostipc=$output
+ hostipc="$(readlink /proc/self/ns/ipc)"
run_podman run -d --ipc=private --name test $IMAGE sleep 100
- if [[ $output == "$hostipc" ]]; then
- die "hostipc and containeripc should be different"
- fi
+ assert "$output" != "$hostipc" "containeripc should != hostipc"
+
run_podman 125 run --ipc=container:test --rm $IMAGE readlink /proc/self/ns/ipc
is "$output" ".*is not allowed: non-shareable IPC (hint: use IpcMode:shareable for the donor container)" "Containers should not share private ipc namespace"
run_podman stop -t 0 test
@@ -38,31 +33,26 @@ load helpers
}
@test "podman --ipc=shareable" {
- run readlink /proc/self/ns/ipc
- hostipc=$output
+ hostipc="$(readlink /proc/self/ns/ipc)"
run_podman run -d --ipc=shareable --name test $IMAGE sleep 100
- if [[ $output == "$hostipc" ]]; then
- die "hostipc and containeripc should be different"
- fi
+ assert "$output" != "$hostipc" "containeripc(shareable) should != hostipc"
+
run_podman run --ipc=container:test --rm $IMAGE readlink /proc/self/ns/ipc
- if [[ $output == "$hostipc" ]]; then
- die "hostipc and containeripc should be different"
- fi
+ assert "$output" != "$hostipc" "containeripc(:test) should != hostipc"
+
run_podman stop -t 0 test
run_podman rm test
}
@test "podman --ipc=container@test" {
- run readlink /proc/self/ns/ipc
- hostipc=$output
+ hostipc="$(readlink /proc/self/ns/ipc)"
run_podman run -d --name test $IMAGE sleep 100
run_podman exec test readlink /proc/self/ns/ipc
- if [[ $output == "$hostipc" ]]; then
- die "hostipc and containeripc should be different"
- fi
+ assert "$output" != "$hostipc" "containeripc(exec) should != hostipc"
+
testipc=$output
run_podman run --ipc=container:test --rm $IMAGE readlink /proc/self/ns/ipc
- is "$output" "$testipc" "Containers should share ipc namespace"
+ assert "$output" = "$testipc" "Containers should share ipc namespace"
run_podman stop -t 0 test
run_podman rm test
}
diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats
index e6f4ecdbc..56449dcad 100644
--- a/test/system/200-pod.bats
+++ b/test/system/200-pod.bats
@@ -59,7 +59,7 @@ function teardown() {
skip_if_remote "CONTAINERS_CONF only effects server side"
image="i.do/not/exist:image"
tmpdir=$PODMAN_TMPDIR/pod-test
- run mkdir -p $tmpdir
+ mkdir -p $tmpdir
containersconf=$tmpdir/containers.conf
cat >$containersconf <<EOF
[engine]
@@ -86,9 +86,7 @@ EOF
# (Assert that output is formatted, not a one-line blob: #8021)
run_podman pod inspect $podname
- if [[ "${#lines[*]}" -lt 10 ]]; then
- die "Output from 'pod inspect' is only ${#lines[*]} lines; see #8011"
- fi
+ assert "${#lines[*]}" -ge 10 "Output from 'pod inspect'; see #8011"
# Randomly-assigned port in the 5xxx range
port=$(random_free_port)
@@ -234,7 +232,7 @@ EOF
local infra_cid="$output"
# confirm that entrypoint is what we set
run_podman container inspect --format '{{.Config.Entrypoint}}' $infra_cid
- is "$output" "[$infra_command]" "infra-command took effect"
+ is "$output" "$infra_command" "infra-command took effect"
# confirm that infra container name is set
run_podman container inspect --format '{{.Name}}' $infra_cid
is "$output" "$infra_name" "infra-name took effect"
@@ -322,10 +320,11 @@ EOF
run_podman --noout pod create --name $pod_name --infra-name "$infra_name" --infra-image "$infra_image"
is "$output" "" "output from pod create should be empty"
- run_podman '?' pod create --infra-name "$infra_name"
- if [ $status -eq 0 ]; then
- die "Podman should fail when user try to create two pods with the same infra-name value"
- fi
+
+ run_podman 125 pod create --infra-name "$infra_name"
+ assert "$output" =~ "^Error: .*: the container name \"$infra_name\" is already in use by .* You have to remove that container to be able to reuse that name.: that name is already in use" \
+ "Trying to create two pods with same infra-name"
+
run_podman pod rm -f $pod_name
run_podman rmi $infra_image
}
diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats
index 6c72e14e8..d0da654ad 100644
--- a/test/system/250-systemd.bats
+++ b/test/system/250-systemd.bats
@@ -18,9 +18,15 @@ function setup() {
}
function teardown() {
- run '?' systemctl stop "$SERVICE_NAME"
- rm -f "$UNIT_FILE"
- systemctl daemon-reload
+ if [[ -e "$UNIT_FILE" ]]; then
+ run systemctl stop "$SERVICE_NAME"
+ if [ $status -ne 0 ]; then
+ echo "# WARNING: systemctl stop failed in teardown: $output" >&3
+ fi
+
+ rm -f "$UNIT_FILE"
+ systemctl daemon-reload
+ fi
run_podman rmi -a
basic_teardown
@@ -36,41 +42,23 @@ function service_setup() {
# Also test enabling services (see #12438).
run systemctl enable "$SERVICE_NAME"
- if [ $status -ne 0 ]; then
- die "Error enabling systemd unit $SERVICE_NAME, output: $output"
- fi
+ assert $status -eq 0 "Error enabling systemd unit $SERVICE_NAME: $output"
run systemctl start "$SERVICE_NAME"
- if [ $status -ne 0 ]; then
- die "Error starting systemd unit $SERVICE_NAME, output: $output"
- fi
+ assert $status -eq 0 "Error starting systemd unit $SERVICE_NAME: $output"
run systemctl status "$SERVICE_NAME"
- if [ $status -ne 0 ]; then
- die "Non-zero status of systemd unit $SERVICE_NAME, output: $output"
- fi
+ assert $status -eq 0 "systemctl status $SERVICE_NAME: $output"
}
# Helper to stop a systemd service running a container
function service_cleanup() {
local status=$1
run systemctl stop "$SERVICE_NAME"
- if [ $status -ne 0 ]; then
- die "Error stopping systemd unit $SERVICE_NAME, output: $output"
- fi
+ assert $status -eq 0 "Error stopping systemd unit $SERVICE_NAME: $output"
run systemctl disable "$SERVICE_NAME"
- if [ $status -ne 0 ]; then
- die "Error disbling systemd unit $SERVICE_NAME, output: $output"
- fi
-
- if [[ -z "$status" ]]; then
- run systemctl is-active "$SERVICE_NAME"
- if [ $status -ne 0 ]; then
- die "Error checking stauts of systemd unit $SERVICE_NAME, output: $output"
- fi
- is "$output" "$status" "$SERVICE_NAME not in expected state"
- fi
+ assert $status -eq 0 "Error disabling systemd unit $SERVICE_NAME: $output"
rm -f "$UNIT_FILE"
systemctl daemon-reload
@@ -230,27 +218,13 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
INSTANCE="$SERVICE_NAME@1.service"
run systemctl start "$INSTANCE"
- if [ $status -ne 0 ]; then
- die "Error starting systemd unit $INSTANCE, output: $output"
- fi
+ assert $status -eq 0 "Error starting systemd unit $INSTANCE: $output"
run systemctl status "$INSTANCE"
- if [ $status -ne 0 ]; then
- die "Non-zero status of systemd unit $INSTANCE, output: $output"
- fi
+ assert $status -eq 0 "systemctl status $INSTANCE: $output"
run systemctl stop "$INSTANCE"
- if [ $status -ne 0 ]; then
- die "Error stopping systemd unit $INSTANCE, output: $output"
- fi
-
- if [[ -z "$status" ]]; then
- run systemctl is-active "$INSTANCE"
- if [ $status -ne 0 ]; then
- die "Error checking stauts of systemd unit $INSTANCE, output: $output"
- fi
- is "$output" "$status" "$INSTANCE not in expected state"
- fi
+ assert $status -eq 0 "Error stopping systemd unit $INSTANCE: $output"
rm -f "$TEMPLATE_FILE_PREFIX@.service"
systemctl daemon-reload
diff --git a/test/system/255-auto-update.bats b/test/system/255-auto-update.bats
index 5a8bf4218..6cdae2ada 100644
--- a/test/system/255-auto-update.bats
+++ b/test/system/255-auto-update.bats
@@ -178,9 +178,8 @@ function _confirm_update() {
is "$output" "$oldID" "container rolled back to previous image"
run_podman container inspect --format "{{.ID}}" $cname
- if [[ $output == $containerID ]]; then
- die "container has not been restarted during rollback (previous id: $containerID, current id: $output)"
- fi
+ assert "$output" != "$containerID" \
+ "container has not been restarted during rollback"
}
@test "podman auto-update - label io.containers.autoupdate=disabled" {
@@ -329,11 +328,9 @@ EOF
for cname in "${cnames[@]}"; do
run_podman inspect --format "{{.Image}}" $cname
if [[ -n "${expect_update[$cname]}" ]]; then
- if [[ "$output" == "$img_id" ]]; then
- die "$cname: image ID ($output) did not change"
- fi
+ assert "$output" != "$img_id" "$cname: image ID did not change"
else
- is "$output" "$img_id" "Image should not be changed."
+ assert "$output" = "$img_id" "Image ID should not be changed."
fi
done
}
diff --git a/test/system/270-socket-activation.bats b/test/system/270-socket-activation.bats
index 6d582be18..19f68abdd 100644
--- a/test/system/270-socket-activation.bats
+++ b/test/system/270-socket-activation.bats
@@ -90,7 +90,7 @@ function teardown() {
@test "podman system service - socket activation - kill rootless pause" {
if ! is_rootless; then
- skip "there is no pause process when running rootful"
+ skip "there is no pause process when running rootfull"
fi
run_podman run -d $IMAGE sleep 90
cid="$output"
diff --git a/test/system/400-unprivileged-access.bats b/test/system/400-unprivileged-access.bats
index cf0d0e6bf..710ff066c 100644
--- a/test/system/400-unprivileged-access.bats
+++ b/test/system/400-unprivileged-access.bats
@@ -128,9 +128,7 @@ EOF
# number of links, major, and minor (see below for why). Do it all
# in one go, to avoid multiple podman-runs
run_podman '?' run --rm $IMAGE stat -c'%n:%F:%h:%T:%t' /dev/null ${subset[@]}
- if [[ $status -gt 1 ]]; then
- die "Unexpected exit status $status: expected 0 or 1"
- fi
+ assert $status -le 1 "stat exit status: expected 0 or 1"
local devnull=
for result in "${lines[@]}"; do
diff --git a/test/system/410-selinux.bats b/test/system/410-selinux.bats
index 056a056f6..21ac4cb8f 100644
--- a/test/system/410-selinux.bats
+++ b/test/system/410-selinux.bats
@@ -135,9 +135,8 @@ function check_label() {
# net NS: do not share context
run_podman run --rm --net container:myctr $IMAGE cat -v /proc/self/attr/current
- if [[ "$output" = "$context_c1" ]]; then
- die "run --net : context ($output) is same as running container (it should not be)"
- fi
+ assert "$output" != "$context_c1" \
+ "run --net : context should != context of running container"
# The 'myctr2' above was not run with --rm, so it still exists, and
# we can't remove the original container until this one is gone.
@@ -189,9 +188,8 @@ function check_label() {
# Even after #7902, labels (':c123,c456') should be different
run_podman run --rm --pod myselinuxpod $IMAGE cat -v /proc/self/attr/current
- if [[ "$output" = "$context_c1" ]]; then
- die "context ($output) is the same on two separate containers, it should have been different"
- fi
+ assert "$output" != "$context_c1" \
+ "context of two separate containers should be different"
run_podman pod rm myselinuxpod
}
diff --git a/test/system/450-interactive.bats b/test/system/450-interactive.bats
index b817fe1a7..a642a2e95 100644
--- a/test/system/450-interactive.bats
+++ b/test/system/450-interactive.bats
@@ -27,9 +27,7 @@ function setup() {
retries=5
while [[ ! -e $PODMAN_TEST_PTY ]]; do
retries=$(( retries - 1 ))
- if [[ $retries -eq 0 ]]; then
- die "Timed out waiting for $PODMAN_TEST_PTY"
- fi
+ assert $retries -gt 0 "Timed out waiting for $PODMAN_TEST_PTY"
sleep 0.5
done
}
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index 1b5e27e95..108abdf23 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -6,16 +6,12 @@
load helpers
@test "podman network - basic tests" {
- heading="*NETWORK*ID*NAME*DRIVER*"
+ heading="NETWORK *ID *NAME *DRIVER"
run_podman network ls
- if [[ ${output} != ${heading} ]]; then
- die "network ls expected heading is not available"
- fi
+ assert "${lines[0]}" =~ "^$heading\$" "network ls header missing"
run_podman network ls --noheading
- if [[ ${output} = ${heading} ]]; then
- die "network ls --noheading did not remove heading: $output"
- fi
+ assert "$output" !~ "$heading" "network ls --noheading shows header anyway"
# check deterministic list order
local net1=a-$(random_string 10)
@@ -175,9 +171,7 @@ load helpers
# (Assert that output is formatted, not a one-line blob: #8011)
run_podman network inspect $mynetname
- if [[ "${#lines[*]}" -lt 5 ]]; then
- die "Output from 'pod inspect' is only ${#lines[*]} lines; see #8011"
- fi
+ assert "${#lines[*]}" -ge 5 "Output from 'pod inspect'; see #8011"
run_podman run --rm --network $mynetname $IMAGE ip a
is "$output" ".* inet ${mysubnet}\.2/24 brd ${mysubnet}\.255 " \
@@ -266,9 +260,7 @@ load helpers
# check that we cannot curl (timeout after 5 sec)
run timeout 5 curl -s $SERVER/index.txt
- if [ "$status" -ne 124 ]; then
- die "curl did not timeout, status code: $status"
- fi
+ assert $status -eq 124 "curl did not time out"
fi
# reload the network to recreate the iptables rules
@@ -367,16 +359,11 @@ load helpers
# ipv4 slirp
run_podman run --rm --network slirp4netns:enable_ipv6=false $IMAGE cat /etc/resolv.conf
- if grep -E "$ipv6_regex" <<< $output; then
- die "resolv.conf contains a ipv6 nameserver"
- fi
+ assert "$output" !~ "$ipv6_regex" "resolv.conf should not contain ipv6 nameserver"
# ipv6 slirp
run_podman run --rm --network slirp4netns:enable_ipv6=true $IMAGE cat /etc/resolv.conf
- # "is" does not like the ipv6 regex
- if ! grep -E "$ipv6_regex" <<< $output; then
- die "resolv.conf does not contain a ipv6 nameserver"
- fi
+ assert "$output" =~ "$ipv6_regex" "resolv.conf should contain ipv6 nameserver"
# ipv4 cni
local mysubnet=$(random_rfc1918_subnet)
@@ -386,9 +373,7 @@ load helpers
is "$output" "$netname" "output of 'network create'"
run_podman run --rm --network $netname $IMAGE cat /etc/resolv.conf
- if grep -E "$ipv6_regex" <<< $output; then
- die "resolv.conf contains a ipv6 nameserver"
- fi
+ assert "$output" !~ "$ipv6_regex" "resolv.conf should not contain ipv6 nameserver"
run_podman network rm -t 0 -f $netname
@@ -400,10 +385,7 @@ load helpers
is "$output" "$netname" "output of 'network create'"
run_podman run --rm --network $netname $IMAGE cat /etc/resolv.conf
- # "is" does not like the ipv6 regex
- if ! grep -E "$ipv6_regex" <<< $output; then
- die "resolv.conf does not contain a ipv6 nameserver"
- fi
+ assert "$output" =~ "$ipv6_regex" "resolv.conf should contain ipv6 nameserver"
run_podman network rm -t 0 -f $netname
}
@@ -457,9 +439,8 @@ load helpers
# check that we cannot curl (timeout after 3 sec)
run curl --max-time 3 -s $SERVER/index.txt
- if [ "$status" -eq 0 ]; then
- die "curl did not fail, it should have timed out or failed with non zero exit code"
- fi
+ assert $status -ne 0 \
+ "curl did not fail, it should have timed out or failed with non zero exit code"
run_podman network connect $netname $cid
is "$output" "" "Output should be empty (no errors)"
@@ -471,13 +452,12 @@ load helpers
# check that we have a new ip and mac
# if the ip is still the same this whole test turns into a nop
run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}"
- if [[ "$output" == "$ip" ]]; then
- die "IP address did not change after podman network disconnect/connect"
- fi
+ assert "$output" != "$ip" \
+ "IP address did not change after podman network disconnect/connect"
+
run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}"
- if [[ "$output" == "$mac" ]]; then
- die "MAC address did not change after podman network disconnect/connect"
- fi
+ assert "$output" != "$mac" \
+ "MAC address did not change after podman network disconnect/connect"
# Disconnect/reconnect of a container *with no ports* should succeed quietly
run_podman network disconnect $netname $background_cid
@@ -553,9 +533,7 @@ load helpers
while kill -0 $pid; do
sleep 0.5
retries=$((retries - 1))
- if [[ $retries -eq 0 ]]; then
- die "Process $pid (container $cid) refused to die"
- fi
+ assert $retries -gt 0 "Process $pid (container $cid) refused to die"
done
# Wait for container to restart
@@ -564,16 +542,13 @@ load helpers
run_podman container inspect --format "{{.State.Pid}}" $cid
# pid is 0 as long as the container is not running
if [[ $output -ne 0 ]]; then
- if [[ $output == $pid ]]; then
- die "This should never happen! Restarted container has same PID ($output) as killed one!"
- fi
+ assert "$output" != "$pid" \
+ "This should never happen! Restarted container has same PID as killed one!"
break
fi
sleep 0.5
retries=$((retries - 1))
- if [[ $retries -eq 0 ]]; then
- die "Timed out waiting for container to restart"
- fi
+ assert $retries -gt 0 "Timed out waiting for container to restart"
done
# Verify http contents again: curl from localhost
diff --git a/test/system/520-checkpoint.bats b/test/system/520-checkpoint.bats
index 046dfd126..c16a8c35d 100644
--- a/test/system/520-checkpoint.bats
+++ b/test/system/520-checkpoint.bats
@@ -47,7 +47,8 @@ function teardown() {
# Checkpoint, and confirm via inspect
run_podman container checkpoint $cid
- is "$output" "$cid" "podman container checkpoint"
+ # FIXME: remove the `.*` prefix after fix packaged for https://github.com/checkpoint-restore/criu/pull/1706
+ is "$output" ".*$cid" "podman container checkpoint"
run_podman container inspect \
--format '{{.State.Status}}:{{.State.Running}}:{{.State.Paused}}:{{.State.Checkpointed}}' $cid
@@ -79,9 +80,8 @@ function teardown() {
# Get full logs, and make sure something changed
run_podman logs $cid
local nlines_after="${#lines[*]}"
- if [[ $nlines_after -eq $nlines_before ]]; then
- die "Container failed to output new lines after first restore"
- fi
+ assert $nlines_after -gt $nlines_before \
+ "Container failed to output new lines after first restore"
# Same thing again: test for https://github.com/containers/crun/issues/756
# in which, after second checkpoint/restore, we lose logs
@@ -95,9 +95,8 @@ function teardown() {
sleep 0.3
run_podman container logs $cid
nlines_after="${#lines[*]}"
- if [[ $nlines_after -eq $nlines_before ]]; then
- die "stdout went away after second restore (crun issue 756)"
- fi
+ assert $nlines_after -gt $nlines_before \
+ "stdout went away after second restore (crun issue 756)"
run_podman rm -t 0 -f $cid
}
@@ -159,9 +158,8 @@ function teardown() {
sleep .3
run curl --max-time 3 -s $server/mydate
local date_newroot="$output"
- if [[ $date_newroot = $date_oldroot ]]; then
- die "Restored container did not update the timestamp file"
- fi
+ assert "$date_newroot" != "$date_oldroot" \
+ "Restored container did not update the timestamp file"
run_podman exec $cid cat /myvol/cname
is "$output" "$cname" "volume transferred fine"
diff --git a/test/system/600-completion.bats b/test/system/600-completion.bats
index 9fdd42332..018e95e78 100644
--- a/test/system/600-completion.bats
+++ b/test/system/600-completion.bats
@@ -40,7 +40,7 @@ function check_shell_completion() {
# The line immediately after 'Usage:' gives us a 1-line synopsis
usage=$(echo "$full_help" | grep -A1 '^Usage:' | tail -1)
- [ -n "$usage" ] || die "podman $cmd: no Usage message found"
+ assert "$usage" != "" "podman $cmd: no Usage message found"
# If usage ends in '[command]', recurse into subcommands
if expr "$usage" : '.*\[command\]$' >/dev/null; then
@@ -74,7 +74,8 @@ function check_shell_completion() {
# If this fails there is most likely a problem with the cobra library
is "${lines[0]}" "--.*" \
"$* $cmd: flag(s) listed in suggestions"
- [ ${#lines[@]} -gt 2 ] || die "$* $cmd: No flag suggestions"
+ assert "${#lines[@]}" -gt 2 \
+ "$* $cmd: No flag suggestions"
_check_completion_end NoFileComp
fi
# continue the outer for args loop
@@ -149,7 +150,7 @@ function check_shell_completion() {
### FIXME how can we get the configured registries?
_check_completion_end NoFileComp
### FIXME this fails if no registries are configured
- [[ ${#lines[@]} -gt 2 ]] || die "$* $cmd: No REGISTRIES found in suggestions"
+ assert "${#lines[@]}" -gt 2 "$* $cmd: No REGISTRIES found in suggestions"
match=true
# resume
@@ -174,7 +175,7 @@ function check_shell_completion() {
_check_completion_end NoSpace
else
_check_completion_end Default
- [[ ${#lines[@]} -eq 2 ]] || die "$* $cmd: Suggestions are in the output"
+ assert "${#lines[@]}" -eq 2 "$* $cmd: Suggestions are in the output"
fi
;;
@@ -210,7 +211,7 @@ function check_shell_completion() {
i=0
length=$(( ${#lines[@]} - 2 ))
while [[ i -lt length ]]; do
- [[ "${lines[$i]:0:7}" == "[Debug]" ]] || die "Suggestions are in the output"
+ assert "${lines[$i]:0:7}" == "[Debug]" "Suggestions are in the output"
i=$(( i + 1 ))
done
fi
diff --git a/test/system/750-trust.bats b/test/system/750-trust.bats
index f06df35e7..0d04c33dc 100644
--- a/test/system/750-trust.bats
+++ b/test/system/750-trust.bats
@@ -37,8 +37,7 @@ load helpers
subset=$(jq -r '.[1] | .repo_name, .type' <<<"$output" | fmt)
is "$subset" "docker.io accept" "--json, docker.io should now be accept"
- run cat $policypath
- policy=$output
+ policy="$(< $policypath)"
run_podman image trust show --policypath=$policypath --raw
is "$output" "$policy" "output should show match content of policy.json"
}
diff --git a/test/system/helpers.bash b/test/system/helpers.bash
index 0d336592f..1a1dc0df9 100644
--- a/test/system/helpers.bash
+++ b/test/system/helpers.bash
@@ -483,7 +483,7 @@ function skip_if_root_ubuntu {
if is_ubuntu; then
if ! is_remote; then
if ! is_rootless; then
- skip "Cannot run this test on rootful ubuntu, usually due to user errors"
+ skip "Cannot run this test on rootfull ubuntu, usually due to user errors"
fi
fi
fi
@@ -500,19 +500,107 @@ function die() {
false
}
-
-########
-# is # Compare actual vs expected string; fail w/diagnostic if mismatch
-########
+############
+# assert # Compare actual vs expected string; fail if mismatch
+############
#
-# Compares given string against expectations, using 'expr' to allow patterns.
+# Compares string (default: $output) against the given string argument.
+# By default we do an exact-match comparison against $output, but there
+# are two different ways to invoke us, each with an optional description:
+#
+# assert "EXPECT" [DESCRIPTION]
+# assert "RESULT" "OP" "EXPECT" [DESCRIPTION]
+#
+# The first form (one or two arguments) does an exact-match comparison
+# of "$output" against "EXPECT". The second (three or four args) compares
+# the first parameter against EXPECT, using the given OPerator. If present,
+# DESCRIPTION will be displayed on test failure.
#
# Examples:
#
-# is "$actual" "$expected" "descriptive test name"
-# is "apple" "orange" "name of a test that will fail in most universes"
-# is "apple" "[a-z]\+" "this time it should pass"
+# assert "this is exactly what we expect"
+# assert "${lines[0]}" =~ "^abc" "first line begins with abc"
#
+function assert() {
+ local actual_string="$output"
+ local operator='=='
+ local expect_string="$1"
+ local testname="$2"
+
+ case "${#*}" in
+ 0) die "Internal error: 'assert' requires one or more arguments" ;;
+ 1|2) ;;
+ 3|4) actual_string="$1"
+ operator="$2"
+ expect_string="$3"
+ testname="$4"
+ ;;
+ *) die "Internal error: too many arguments to 'assert'" ;;
+ esac
+
+ # Comparisons.
+ # Special case: there is no !~ operator, so fake it via '! x =~ y'
+ local not=
+ local actual_op="$operator"
+ if [[ $operator == '!~' ]]; then
+ not='!'
+ actual_op='=~'
+ fi
+ if [[ $operator == '=' || $operator == '==' ]]; then
+ # Special case: we can't use '=' or '==' inside [[ ... ]] because
+ # the right-hand side is treated as a pattern... and '[xy]' will
+ # not compare literally. There seems to be no way to turn that off.
+ if [ "$actual_string" = "$expect_string" ]; then
+ return
+ fi
+ elif [[ $operator == '!=' ]]; then
+ # Same special case as above
+ if [ "$actual_string" != "$expect_string" ]; then
+ return
+ fi
+ else
+ if eval "[[ $not \$actual_string $actual_op \$expect_string ]]"; then
+ return
+ elif [ $? -gt 1 ]; then
+ die "Internal error: could not process 'actual' $operator 'expect'"
+ fi
+ fi
+
+ # Test has failed. Get a descriptive test name.
+ if [ -z "$testname" ]; then
+ testname="${MOST_RECENT_PODMAN_COMMAND:-[no test name given]}"
+ fi
+
+ # Display optimization: the typical case for 'expect' is an
+ # exact match ('='), but there are also '=~' or '!~' or '-ge'
+ # and the like. Omit the '=' but show the others; and always
+ # align subsequent output lines for ease of comparison.
+ local op=''
+ local ws=''
+ if [ "$operator" != '==' ]; then
+ op="$operator "
+ ws=$(printf "%*s" ${#op} "")
+ fi
+
+ # This is a multi-line message, which may in turn contain multi-line
+ # output, so let's format it ourself, readably
+ local actual_split
+ IFS=$'\n' read -rd '' -a actual_split <<<"$actual_string" || true
+ printf "#/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n" >&2
+ printf "#| FAIL: %s\n" "$testname" >&2
+ printf "#| expected: %s'%s'\n" "$op" "$expect_string" >&2
+ printf "#| actual: %s'%s'\n" "$ws" "${actual_split[0]}" >&2
+ local line
+ for line in "${actual_split[@]:1}"; do
+ printf "#| > %s'%s'\n" "$ws" "$line" >&2
+ done
+ printf "#\\^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" >&2
+ false
+}
+
+########
+# is # **DEPRECATED**; see assert() above
+########
function is() {
local actual="$1"
local expect="$2"
@@ -716,10 +804,9 @@ function remove_same_dev_warning() {
# return that list.
function _podman_commands() {
dprint "$@"
- run_podman help "$@" |
- awk '/^Available Commands:/{ok=1;next}/^Options:/{ok=0}ok { print $1 }' |
- grep .
- "$output"
+ # &>/dev/null prevents duplicate output
+ run_podman help "$@" &>/dev/null
+ awk '/^Available Commands:/{ok=1;next}/^Options:/{ok=0}ok { print $1 }' <<<"$output" | grep .
}
# END miscellaneous tools
diff --git a/test/upgrade/test-upgrade.bats b/test/upgrade/test-upgrade.bats
index 198d8a169..5efe05d49 100644
--- a/test/upgrade/test-upgrade.bats
+++ b/test/upgrade/test-upgrade.bats
@@ -146,6 +146,12 @@ EOF
# cause connectivity issues since cni and netavark should never be mixed.
mkdir -p /run/netns /run/cni /run/containers /var/lib/cni /etc/cni/net.d
+ # Containers-common around release 1-55 no-longer supplies this file
+ sconf=/etc/containers/storage.conf
+ v_sconf=
+ if [[ -e "$sconf" ]]; then
+ v_sconf="-v $sconf:$sconf"
+ fi
#
# Use new-podman to run the above script under old-podman.
@@ -165,7 +171,7 @@ EOF
--net=host \
--cgroupns=host \
--pid=host \
- -v /etc/containers/storage.conf:/etc/containers/storage.conf \
+ $v_sconf \
-v /dev/fuse:/dev/fuse \
-v /run/crun:/run/crun \
-v /run/netns:/run/netns:rshared \
diff --git a/test/utils/common_function_test.go b/test/utils/common_function_test.go
index 6323b44eb..a73d75490 100644
--- a/test/utils/common_function_test.go
+++ b/test/utils/common_function_test.go
@@ -110,9 +110,8 @@ var _ = Describe("Common functions test", func() {
Expect(err).To(BeNil(), "Failed to write JSON to file.")
read, err := os.Open("/tmp/testJSON")
- defer read.Close()
-
Expect(err).To(BeNil(), "Can not find the JSON file after we write it.")
+ defer read.Close()
bytes, _ := ioutil.ReadAll(read)
json.Unmarshal(bytes, compareData)
diff --git a/test/utils/utils.go b/test/utils/utils.go
index da56a3a2e..9695835e5 100644
--- a/test/utils/utils.go
+++ b/test/utils/utils.go
@@ -110,7 +110,7 @@ func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string
}
runCmd := append(wrapper, podmanBinary)
- if p.NetworkBackend == Netavark {
+ if !p.RemoteTest && p.NetworkBackend == Netavark {
runCmd = append(runCmd, []string{"--network-backend", "netavark"}...)
}
@@ -439,10 +439,10 @@ func tagOutputToMap(imagesOutput []string) map[string]map[string]bool {
// GetHostDistributionInfo returns a struct with its distribution Name and version
func GetHostDistributionInfo() HostOS {
f, err := os.Open(OSReleasePath)
- defer f.Close()
if err != nil {
return HostOS{}
}
+ defer f.Close()
l := bufio.NewScanner(f)
host := HostOS{}
diff --git a/test/version/main.go b/test/version/main.go
index 8f2904405..2a68aa5fc 100644
--- a/test/version/main.go
+++ b/test/version/main.go
@@ -7,5 +7,5 @@ import (
)
func main() {
- fmt.Printf(version.Version.String())
+ fmt.Print(version.Version.String())
}
diff --git a/utils/utils_supported.go b/utils/utils_supported.go
index ab2de2ce1..493ea61ce 100644
--- a/utils/utils_supported.go
+++ b/utils/utils_supported.go
@@ -6,6 +6,7 @@ package utils
import (
"bufio"
"bytes"
+ "context"
"fmt"
"io/ioutil"
"os"
@@ -32,7 +33,7 @@ func RunUnderSystemdScope(pid int, slice string, unitName string) error {
return err
}
} else {
- conn, err = systemdDbus.New()
+ conn, err = systemdDbus.NewWithContext(context.Background())
if err != nil {
return err
}
@@ -43,10 +44,10 @@ func RunUnderSystemdScope(pid int, slice string, unitName string) error {
properties = append(properties, newProp("Delegate", true))
properties = append(properties, newProp("DefaultDependencies", false))
ch := make(chan string)
- _, err = conn.StartTransientUnit(unitName, "replace", properties, ch)
+ _, err = conn.StartTransientUnitContext(context.Background(), unitName, "replace", properties, ch)
if err != nil {
// On errors check if the cgroup already exists, if it does move the process there
- if props, err := conn.GetUnitTypeProperties(unitName, "Scope"); err == nil {
+ if props, err := conn.GetUnitTypePropertiesContext(context.Background(), unitName, "Scope"); err == nil {
if cgroup, ok := props["ControlGroup"].(string); ok && cgroup != "" {
if err := moveUnderCgroup(cgroup, "", []uint32{uint32(pid)}); err == nil {
return nil
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index b28c527bc..319b8d153 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -95,6 +95,13 @@ type ContainersConfig struct {
// Annotation to add to all containers
Annotations []string `toml:"annotations,omitempty"`
+ // BaseHostsFile is the path to a hosts file, the entries from this file
+ // are added to the containers hosts file. As special value "image" is
+ // allowed which uses the /etc/hosts file from within the image and "none"
+ // which uses no base file at all. If it is empty we should default
+ // to /etc/hosts.
+ BaseHostsFile string `toml:"base_hosts_file,omitempty"`
+
// Default way to create a cgroup namespace for the container
CgroupNS string `toml:"cgroupns,omitempty"`
@@ -136,6 +143,9 @@ type ContainersConfig struct {
// EnvHost Pass all host environment variables into the container.
EnvHost bool `toml:"env_host,omitempty"`
+ // HostContainersInternalIP is used to set a specific host.containers.internal ip.
+ HostContainersInternalIP string `toml:"host_containers_internal_ip,omitempty"`
+
// HTTPProxy is the proxy environment variable list to apply to container process
HTTPProxy bool `toml:"http_proxy,omitempty"`
diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf
index f069c531d..429b254bc 100644
--- a/vendor/github.com/containers/common/pkg/config/containers.conf
+++ b/vendor/github.com/containers/common/pkg/config/containers.conf
@@ -26,6 +26,13 @@
#
#apparmor_profile = "container-default"
+# The hosts entries from the base hosts file are added to the containers hosts
+# file. This must be either an absolute path or as special values "image" which
+# uses the hosts file from the container image or "none" which means
+# no base hosts file is used. The default is "" which will use /etc/hosts.
+#
+#base_hosts_file = ""
+
# Default way to to create a cgroup namespace for the container
# Options are:
# `private` Create private Cgroup Namespace for the container.
@@ -114,6 +121,16 @@ default_sysctls = [
#
#env_host = false
+# Set the ip for the host.containers.internal entry in the containers /etc/hosts
+# file. This can be set to "none" to disable adding this entry. By default it
+# will automatically choose the host ip.
+#
+# NOTE: When using podman machine this entry will never be added to the containers
+# hosts file instead the gvproxy dns resolver will resolve this hostname. Therefore
+# it is not possible to disable the entry in this case.
+#
+#host_containers_internal_ip = ""
+
# Default proxy environment variables passed into the container.
# The environment variables passed in include:
# http_proxy, https_proxy, ftp_proxy, no_proxy, and the upper case versions of
@@ -464,9 +481,26 @@ default_sysctls = [
#network_cmd_path = ""
# Default options to pass to the slirp4netns binary.
-# For example "allow_host_loopback=true"
-#
-#network_cmd_options = ["enable_ipv6=true",]
+# Valid options values are:
+#
+# - allow_host_loopback=true|false: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`).
+# 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 a 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.
+#
+#network_cmd_options = []
# Whether to use chroot instead of pivot_root in the runtime
#
@@ -644,4 +678,3 @@ default_sysctls = [
# TOML does not provide a way to end a table other than a further table being
# defined, so every key hereafter will be part of [machine] and not the
# main config.
-
diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go
index 275f67cbf..62b348d6e 100644
--- a/vendor/github.com/containers/common/pkg/config/default.go
+++ b/vendor/github.com/containers/common/pkg/config/default.go
@@ -122,6 +122,8 @@ const (
CgroupfsCgroupsManager = "cgroupfs"
// DefaultApparmorProfile specifies the default apparmor profile for the container.
DefaultApparmorProfile = apparmor.Profile
+ // DefaultHostsFile is the default path to the hosts file
+ DefaultHostsFile = "/etc/hosts"
// SystemdCgroupsManager represents systemd native cgroup manager
SystemdCgroupsManager = "systemd"
// DefaultLogSizeMax is the default value for the maximum log size
@@ -189,6 +191,7 @@ func DefaultConfig() (*Config, error) {
Volumes: []string{},
Annotations: []string{},
ApparmorProfile: DefaultApparmorProfile,
+ BaseHostsFile: "",
CgroupNS: cgroupNS,
Cgroups: "enabled",
DefaultCapabilities: DefaultCapabilities,
@@ -299,9 +302,6 @@ func defaultConfigFromMemory() (*EngineConfig, error) {
c.ServiceTimeout = uint(5)
c.StopTimeout = uint(10)
c.ExitCommandDelay = uint(5 * 60)
- c.NetworkCmdOptions = []string{
- "enable_ipv6=true",
- }
c.Remote = isRemote()
c.OCIRuntimes = map[string][]string{
"crun": {
diff --git a/vendor/github.com/containers/common/pkg/secrets/shelldriver/shelldriver.go b/vendor/github.com/containers/common/pkg/secrets/shelldriver/shelldriver.go
index 846bd5c17..8eac200f7 100644
--- a/vendor/github.com/containers/common/pkg/secrets/shelldriver/shelldriver.go
+++ b/vendor/github.com/containers/common/pkg/secrets/shelldriver/shelldriver.go
@@ -3,12 +3,12 @@ package shelldriver
import (
"bytes"
"context"
+ "fmt"
"os"
"os/exec"
"sort"
"strings"
- "github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
)
@@ -27,22 +27,33 @@ var (
type driverConfig struct {
// DeleteCommand contains a shell command that deletes a secret.
// The secret id is provided as environment variable SECRET_ID
- DeleteCommand string `mapstructure:"delete"`
+ DeleteCommand string
// ListCommand contains a shell command that lists all secrets.
// The output is expected to be one id per line
- ListCommand string `mapstructure:"list"`
+ ListCommand string
// LookupCommand contains a shell command that retrieves a secret.
// The secret id is provided as environment variable SECRET_ID
- LookupCommand string `mapstructure:"lookup"`
+ LookupCommand string
// StoreCommand contains a shell command that stores a secret.
// The secret id is provided as environment variable SECRET_ID
// The secret value itself is provided over stdin
- StoreCommand string `mapstructure:"store"`
+ StoreCommand string
}
func (cfg *driverConfig) ParseOpts(opts map[string]string) error {
- if err := mapstructure.Decode(opts, cfg); err != nil {
- return err
+ for key, value := range opts {
+ switch key {
+ case "delete":
+ cfg.DeleteCommand = value
+ case "list":
+ cfg.ListCommand = value
+ case "lookup":
+ cfg.LookupCommand = value
+ case "store":
+ cfg.StoreCommand = value
+ default:
+ return fmt.Errorf("invalid shell driver option: %q", key)
+ }
}
if cfg.DeleteCommand == "" ||
cfg.ListCommand == "" ||
diff --git a/vendor/github.com/containers/image/v5/copy/copy.go b/vendor/github.com/containers/image/v5/copy/copy.go
index b616e566c..644f82615 100644
--- a/vendor/github.com/containers/image/v5/copy/copy.go
+++ b/vendor/github.com/containers/image/v5/copy/copy.go
@@ -5,7 +5,6 @@ import (
"context"
"fmt"
"io"
- "io/ioutil"
"os"
"reflect"
"strings"
@@ -199,7 +198,7 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef,
return nil, err
}
- reportWriter := ioutil.Discard
+ reportWriter := io.Discard
if options.ReportWriter != nil {
reportWriter = options.ReportWriter
@@ -232,7 +231,7 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef,
// createProgressBar() will print a single line instead.
progressOutput := reportWriter
if !isTTY(reportWriter) {
- progressOutput = ioutil.Discard
+ progressOutput = io.Discard
}
c := &copier{
@@ -1091,7 +1090,7 @@ func customPartialBlobDecorFunc(s decor.Statistics) string {
}
// createProgressBar creates a mpb.Bar in pool. Note that if the copier's reportWriter
-// is ioutil.Discard, the progress bar's output will be discarded
+// is io.Discard, the progress bar's output will be discarded
// NOTE: Every progress bar created within a progress pool must either successfully
// complete or be aborted, or pool.Wait() will hang. That is typically done
// using "defer bar.Abort(false)", which must happen BEFORE pool.Wait() is called.
@@ -1143,7 +1142,7 @@ func (c *copier) createProgressBar(pool *mpb.Progress, partial bool, info types.
),
)
}
- if c.progressOutput == ioutil.Discard {
+ if c.progressOutput == io.Discard {
c.Printf("Copying %s %s\n", kind, info.Digest)
}
return bar
@@ -1669,7 +1668,7 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr
// sent there if we are not already at EOF.
if getOriginalLayerCopyWriter != nil {
logrus.Debugf("Consuming rest of the original blob to satisfy getOriginalLayerCopyWriter")
- _, err := io.Copy(ioutil.Discard, originalLayerReader)
+ _, err := io.Copy(io.Discard, originalLayerReader)
if err != nil {
return types.BlobInfo{}, errors.Wrapf(err, "reading input blob %s", srcInfo.Digest)
}
diff --git a/vendor/github.com/containers/image/v5/directory/directory_dest.go b/vendor/github.com/containers/image/v5/directory/directory_dest.go
index ea20e7c5e..3b135e68e 100644
--- a/vendor/github.com/containers/image/v5/directory/directory_dest.go
+++ b/vendor/github.com/containers/image/v5/directory/directory_dest.go
@@ -3,7 +3,6 @@ package directory
import (
"context"
"io"
- "io/ioutil"
"os"
"path/filepath"
"runtime"
@@ -62,7 +61,7 @@ func newImageDestination(sys *types.SystemContext, ref dirReference) (types.Imag
return nil, errors.Wrapf(err, "checking if path exists %q", d.ref.versionPath())
}
if versionExists {
- contents, err := ioutil.ReadFile(d.ref.versionPath())
+ contents, err := os.ReadFile(d.ref.versionPath())
if err != nil {
return nil, err
}
@@ -86,7 +85,7 @@ func newImageDestination(sys *types.SystemContext, ref dirReference) (types.Imag
}
}
// create version file
- err = ioutil.WriteFile(d.ref.versionPath(), []byte(version), 0644)
+ err = os.WriteFile(d.ref.versionPath(), []byte(version), 0644)
if err != nil {
return nil, errors.Wrapf(err, "creating version file %q", d.ref.versionPath())
}
@@ -149,7 +148,7 @@ func (d *dirImageDestination) HasThreadSafePutBlob() bool {
// to any other readers for download using the supplied digest.
// If stream.Read() at any time, ESPECIALLY at end of input, returns an error, PutBlob MUST 1) fail, and 2) delete any data stored so far.
func (d *dirImageDestination) PutBlob(ctx context.Context, stream io.Reader, inputInfo types.BlobInfo, cache types.BlobInfoCache, isConfig bool) (types.BlobInfo, error) {
- blobFile, err := ioutil.TempFile(d.ref.path, "dir-put-blob")
+ blobFile, err := os.CreateTemp(d.ref.path, "dir-put-blob")
if err != nil {
return types.BlobInfo{}, err
}
@@ -232,7 +231,7 @@ func (d *dirImageDestination) TryReusingBlob(ctx context.Context, info types.Blo
// If the destination is in principle available, refuses this manifest type (e.g. it does not recognize the schema),
// but may accept a different manifest type, the returned error must be an ManifestTypeRejectedError.
func (d *dirImageDestination) PutManifest(ctx context.Context, manifest []byte, instanceDigest *digest.Digest) error {
- return ioutil.WriteFile(d.ref.manifestPath(instanceDigest), manifest, 0644)
+ return os.WriteFile(d.ref.manifestPath(instanceDigest), manifest, 0644)
}
// PutSignatures writes a set of signatures to the destination.
@@ -240,7 +239,7 @@ func (d *dirImageDestination) PutManifest(ctx context.Context, manifest []byte,
// (when the primary manifest is a manifest list); this should always be nil if the primary manifest is not a manifest list.
func (d *dirImageDestination) PutSignatures(ctx context.Context, signatures [][]byte, instanceDigest *digest.Digest) error {
for i, sig := range signatures {
- if err := ioutil.WriteFile(d.ref.signaturePath(i, instanceDigest), sig, 0644); err != nil {
+ if err := os.WriteFile(d.ref.signaturePath(i, instanceDigest), sig, 0644); err != nil {
return err
}
}
@@ -272,7 +271,7 @@ func pathExists(path string) (bool, error) {
// returns true if directory is empty
func isDirEmpty(path string) (bool, error) {
- files, err := ioutil.ReadDir(path)
+ files, err := os.ReadDir(path)
if err != nil {
return false, err
}
@@ -281,7 +280,7 @@ func isDirEmpty(path string) (bool, error) {
// deletes the contents of a directory
func removeDirContents(path string) error {
- files, err := ioutil.ReadDir(path)
+ files, err := os.ReadDir(path)
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/image/v5/directory/directory_src.go b/vendor/github.com/containers/image/v5/directory/directory_src.go
index ad9129d40..8b509112a 100644
--- a/vendor/github.com/containers/image/v5/directory/directory_src.go
+++ b/vendor/github.com/containers/image/v5/directory/directory_src.go
@@ -3,7 +3,6 @@ package directory
import (
"context"
"io"
- "io/ioutil"
"os"
"github.com/containers/image/v5/manifest"
@@ -37,7 +36,7 @@ func (s *dirImageSource) Close() error {
// If instanceDigest is not nil, it contains a digest of the specific manifest instance to retrieve (when the primary manifest is a manifest list);
// this never happens if the primary manifest is not a manifest list (e.g. if the source never returns manifest lists).
func (s *dirImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) {
- m, err := ioutil.ReadFile(s.ref.manifestPath(instanceDigest))
+ m, err := os.ReadFile(s.ref.manifestPath(instanceDigest))
if err != nil {
return nil, "", err
}
@@ -71,7 +70,7 @@ func (s *dirImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache
func (s *dirImageSource) GetSignatures(ctx context.Context, instanceDigest *digest.Digest) ([][]byte, error) {
signatures := [][]byte{}
for i := 0; ; i++ {
- signature, err := ioutil.ReadFile(s.ref.signaturePath(i, instanceDigest))
+ signature, err := os.ReadFile(s.ref.signaturePath(i, instanceDigest))
if err != nil {
if os.IsNotExist(err) {
break
diff --git a/vendor/github.com/containers/image/v5/docker/docker_client.go b/vendor/github.com/containers/image/v5/docker/docker_client.go
index 9837235d8..d984db718 100644
--- a/vendor/github.com/containers/image/v5/docker/docker_client.go
+++ b/vendor/github.com/containers/image/v5/docker/docker_client.go
@@ -7,7 +7,6 @@ import (
"encoding/json"
"fmt"
"io"
- "io/ioutil"
"net/http"
"net/url"
"os"
@@ -654,7 +653,7 @@ func (c *dockerClient) getBearerTokenOAuth2(ctx context.Context, challenge chall
params.Add("refresh_token", c.auth.IdentityToken)
params.Add("client_id", "containers/image")
- authReq.Body = ioutil.NopCloser(bytes.NewBufferString(params.Encode()))
+ authReq.Body = io.NopCloser(bytes.NewBufferString(params.Encode()))
authReq.Header.Add("User-Agent", c.userAgent)
authReq.Header.Add("Content-Type", "application/x-www-form-urlencoded")
logrus.Debugf("%s %s", authReq.Method, authReq.URL.Redacted())
diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go
index e3275aa45..d02100cf8 100644
--- a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go
+++ b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go
@@ -7,7 +7,6 @@ import (
"encoding/json"
"fmt"
"io"
- "io/ioutil"
"net/http"
"net/url"
"os"
@@ -592,7 +591,7 @@ func (d *dockerImageDestination) putOneSignature(url *url.URL, signature []byte)
if err != nil {
return err
}
- err = ioutil.WriteFile(url.Path, signature, 0644)
+ err = os.WriteFile(url.Path, signature, 0644)
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_src.go b/vendor/github.com/containers/image/v5/docker/docker_image_src.go
index c08e5538a..c8e176f90 100644
--- a/vendor/github.com/containers/image/v5/docker/docker_image_src.go
+++ b/vendor/github.com/containers/image/v5/docker/docker_image_src.go
@@ -4,7 +4,6 @@ import (
"context"
"fmt"
"io"
- "io/ioutil"
"mime"
"mime/multipart"
"net/http"
@@ -308,7 +307,7 @@ func splitHTTP200ResponseToPartial(streams chan io.ReadCloser, errs chan error,
break
}
toSkip := c.Offset - currentOffset
- if _, err := io.Copy(ioutil.Discard, io.LimitReader(body, int64(toSkip))); err != nil {
+ if _, err := io.Copy(io.Discard, io.LimitReader(body, int64(toSkip))); err != nil {
errs <- err
break
}
@@ -316,7 +315,7 @@ func splitHTTP200ResponseToPartial(streams chan io.ReadCloser, errs chan error,
}
s := signalCloseReader{
closed: make(chan interface{}),
- stream: ioutil.NopCloser(io.LimitReader(body, int64(c.Length))),
+ stream: io.NopCloser(io.LimitReader(body, int64(c.Length))),
consumeStream: true,
}
streams <- s
@@ -515,7 +514,7 @@ func (s *dockerImageSource) getOneSignature(ctx context.Context, url *url.URL) (
switch url.Scheme {
case "file":
logrus.Debugf("Reading %s", url.Path)
- sig, err := ioutil.ReadFile(url.Path)
+ sig, err := os.ReadFile(url.Path)
if err != nil {
if os.IsNotExist(err) {
return nil, true, nil
@@ -765,7 +764,7 @@ func (s signalCloseReader) Read(p []byte) (int, error) {
func (s signalCloseReader) Close() error {
defer close(s.closed)
if s.consumeStream {
- if _, err := io.Copy(ioutil.Discard, s.stream); err != nil {
+ if _, err := io.Copy(io.Discard, s.stream); err != nil {
s.stream.Close()
return err
}
diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/reader.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/reader.go
index 6164ceb66..c77c002d1 100644
--- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/reader.go
+++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/reader.go
@@ -4,7 +4,6 @@ import (
"archive/tar"
"encoding/json"
"io"
- "io/ioutil"
"os"
"path"
@@ -53,7 +52,7 @@ func NewReaderFromFile(sys *types.SystemContext, path string) (*Reader, error) {
// The caller should call .Close() on the returned archive when done.
func NewReaderFromStream(sys *types.SystemContext, inputStream io.Reader) (*Reader, error) {
// Save inputStream to a temporary file
- tarCopyFile, err := ioutil.TempFile(tmpdir.TemporaryDirectoryForBigFiles(sys), "docker-tar")
+ tarCopyFile, err := os.CreateTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "docker-tar")
if err != nil {
return nil, errors.Wrap(err, "creating temporary file")
}
diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go
index b8d84d245..8e9be17c1 100644
--- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go
+++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go
@@ -6,7 +6,6 @@ import (
"context"
"encoding/json"
"io"
- "io/ioutil"
"os"
"path"
"sync"
@@ -170,7 +169,7 @@ func (s *Source) prepareLayerData(tarManifest *ManifestItem, parsedConfig *manif
uncompressedSize := h.Size
if isCompressed {
- uncompressedSize, err = io.Copy(ioutil.Discard, uncompressedStream)
+ uncompressedSize, err = io.Copy(io.Discard, uncompressedStream)
if err != nil {
return nil, errors.Wrapf(err, "reading %s to find its size", layerPath)
}
@@ -263,7 +262,7 @@ func (s *Source) GetBlob(ctx context.Context, info types.BlobInfo, cache types.B
}
if info.Digest == s.configDigest { // FIXME? Implement a more general algorithm matching instead of assuming sha256.
- return ioutil.NopCloser(bytes.NewReader(s.configBytes)), int64(len(s.configBytes)), nil
+ return io.NopCloser(bytes.NewReader(s.configBytes)), int64(len(s.configBytes)), nil
}
if li, ok := s.knownLayers[info.Digest]; ok { // diffID is a digest of the uncompressed tarball,
diff --git a/vendor/github.com/containers/image/v5/docker/lookaside.go b/vendor/github.com/containers/image/v5/docker/lookaside.go
index 22d84931c..d0a3f1be0 100644
--- a/vendor/github.com/containers/image/v5/docker/lookaside.go
+++ b/vendor/github.com/containers/image/v5/docker/lookaside.go
@@ -2,7 +2,6 @@ package docker
import (
"fmt"
- "io/ioutil"
"net/url"
"os"
"path"
@@ -146,7 +145,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/vendor/github.com/containers/image/v5/internal/iolimits/iolimits.go b/vendor/github.com/containers/image/v5/internal/iolimits/iolimits.go
index 3fed1995c..49fa410e9 100644
--- a/vendor/github.com/containers/image/v5/internal/iolimits/iolimits.go
+++ b/vendor/github.com/containers/image/v5/internal/iolimits/iolimits.go
@@ -2,7 +2,6 @@ package iolimits
import (
"io"
- "io/ioutil"
"github.com/pkg/errors"
)
@@ -47,7 +46,7 @@ const (
func ReadAtMost(reader io.Reader, limit int) ([]byte, error) {
limitedReader := io.LimitReader(reader, int64(limit+1))
- res, err := ioutil.ReadAll(limitedReader)
+ res, err := io.ReadAll(limitedReader)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/v5/internal/streamdigest/stream_digest.go b/vendor/github.com/containers/image/v5/internal/streamdigest/stream_digest.go
index 306220585..84bb656ac 100644
--- a/vendor/github.com/containers/image/v5/internal/streamdigest/stream_digest.go
+++ b/vendor/github.com/containers/image/v5/internal/streamdigest/stream_digest.go
@@ -3,7 +3,6 @@ package streamdigest
import (
"fmt"
"io"
- "io/ioutil"
"os"
"github.com/containers/image/v5/internal/putblobdigest"
@@ -16,7 +15,7 @@ import (
// It is the caller's responsibility to call the cleanup function, which closes and removes the temporary file.
// If an error occurs, inputInfo is not modified.
func ComputeBlobInfo(sys *types.SystemContext, stream io.Reader, inputInfo *types.BlobInfo) (io.Reader, func(), error) {
- diskBlob, err := ioutil.TempFile(tmpdir.TemporaryDirectoryForBigFiles(sys), "stream-blob")
+ diskBlob, err := os.CreateTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "stream-blob")
if err != nil {
return nil, nil, fmt.Errorf("creating temporary on-disk layer: %w", err)
}
diff --git a/vendor/github.com/containers/image/v5/oci/archive/oci_transport.go b/vendor/github.com/containers/image/v5/oci/archive/oci_transport.go
index 54d325d34..4fa912765 100644
--- a/vendor/github.com/containers/image/v5/oci/archive/oci_transport.go
+++ b/vendor/github.com/containers/image/v5/oci/archive/oci_transport.go
@@ -3,7 +3,6 @@ package archive
import (
"context"
"fmt"
- "io/ioutil"
"os"
"strings"
@@ -161,7 +160,7 @@ func (t *tempDirOCIRef) deleteTempDir() error {
// createOCIRef creates the oci reference of the image
// If SystemContext.BigFilesTemporaryDir not "", overrides the temporary directory to use for storing big files
func createOCIRef(sys *types.SystemContext, image string) (tempDirOCIRef, error) {
- dir, err := ioutil.TempDir(tmpdir.TemporaryDirectoryForBigFiles(sys), "oci")
+ dir, err := os.MkdirTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "oci")
if err != nil {
return tempDirOCIRef{}, errors.Wrapf(err, "creating temp directory")
}
diff --git a/vendor/github.com/containers/image/v5/oci/layout/oci_dest.go b/vendor/github.com/containers/image/v5/oci/layout/oci_dest.go
index c8156cc3a..77e8fd876 100644
--- a/vendor/github.com/containers/image/v5/oci/layout/oci_dest.go
+++ b/vendor/github.com/containers/image/v5/oci/layout/oci_dest.go
@@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"io"
- "io/ioutil"
"os"
"path/filepath"
"runtime"
@@ -124,7 +123,7 @@ func (d *ociImageDestination) HasThreadSafePutBlob() bool {
// to any other readers for download using the supplied digest.
// If stream.Read() at any time, ESPECIALLY at end of input, returns an error, PutBlob MUST 1) fail, and 2) delete any data stored so far.
func (d *ociImageDestination) PutBlob(ctx context.Context, stream io.Reader, inputInfo types.BlobInfo, cache types.BlobInfoCache, isConfig bool) (types.BlobInfo, error) {
- blobFile, err := ioutil.TempFile(d.ref.dir, "oci-put-blob")
+ blobFile, err := os.CreateTemp(d.ref.dir, "oci-put-blob")
if err != nil {
return types.BlobInfo{}, err
}
@@ -238,7 +237,7 @@ func (d *ociImageDestination) PutManifest(ctx context.Context, m []byte, instanc
if err := ensureParentDirectoryExists(blobPath); err != nil {
return err
}
- if err := ioutil.WriteFile(blobPath, m, 0644); err != nil {
+ if err := os.WriteFile(blobPath, m, 0644); err != nil {
return err
}
@@ -309,14 +308,14 @@ func (d *ociImageDestination) PutSignatures(ctx context.Context, signatures [][]
// - Uploaded data MAY be visible to others before Commit() is called
// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed)
func (d *ociImageDestination) Commit(context.Context, types.UnparsedImage) error {
- if err := ioutil.WriteFile(d.ref.ociLayoutPath(), []byte(`{"imageLayoutVersion": "1.0.0"}`), 0644); err != nil {
+ if err := os.WriteFile(d.ref.ociLayoutPath(), []byte(`{"imageLayoutVersion": "1.0.0"}`), 0644); err != nil {
return err
}
indexJSON, err := json.Marshal(d.index)
if err != nil {
return err
}
- return ioutil.WriteFile(d.ref.indexPath(), indexJSON, 0644)
+ return os.WriteFile(d.ref.indexPath(), indexJSON, 0644)
}
func ensureDirectoryExists(path string) error {
diff --git a/vendor/github.com/containers/image/v5/oci/layout/oci_src.go b/vendor/github.com/containers/image/v5/oci/layout/oci_src.go
index 9d8ab689b..8973f461c 100644
--- a/vendor/github.com/containers/image/v5/oci/layout/oci_src.go
+++ b/vendor/github.com/containers/image/v5/oci/layout/oci_src.go
@@ -3,7 +3,6 @@ package layout
import (
"context"
"io"
- "io/ioutil"
"net/http"
"net/url"
"os"
@@ -93,7 +92,7 @@ func (s *ociImageSource) GetManifest(ctx context.Context, instanceDigest *digest
return nil, "", err
}
- m, err := ioutil.ReadFile(manifestPath)
+ m, err := os.ReadFile(manifestPath)
if err != nil {
return nil, "", err
}
diff --git a/vendor/github.com/containers/image/v5/openshift/openshift-copies.go b/vendor/github.com/containers/image/v5/openshift/openshift-copies.go
index 4ffbced6b..a6473ae68 100644
--- a/vendor/github.com/containers/image/v5/openshift/openshift-copies.go
+++ b/vendor/github.com/containers/image/v5/openshift/openshift-copies.go
@@ -5,7 +5,6 @@ import (
"crypto/x509"
"encoding/json"
"fmt"
- "io/ioutil"
"net"
"net/http"
"net/url"
@@ -625,7 +624,7 @@ func (rules *clientConfigLoadingRules) Load() (*clientcmdConfig, error) {
// loadFromFile is a modified copy of k8s.io/kubernetes/pkg/client/unversioned/clientcmd.LoadFromFile
// LoadFromFile takes a filename and deserializes the contents into Config object
func loadFromFile(filename string) (*clientcmdConfig, error) {
- kubeconfigBytes, err := ioutil.ReadFile(filename)
+ kubeconfigBytes, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
@@ -1013,7 +1012,7 @@ func dataFromSliceOrFile(data []byte, file string) ([]byte, error) {
return data, nil
}
if len(file) > 0 {
- fileData, err := ioutil.ReadFile(file)
+ fileData, err := os.ReadFile(file)
if err != nil {
return []byte{}, err
}
diff --git a/vendor/github.com/containers/image/v5/ostree/ostree_dest.go b/vendor/github.com/containers/image/v5/ostree/ostree_dest.go
index 3eb2a2cba..011118fa5 100644
--- a/vendor/github.com/containers/image/v5/ostree/ostree_dest.go
+++ b/vendor/github.com/containers/image/v5/ostree/ostree_dest.go
@@ -10,7 +10,6 @@ import (
"encoding/json"
"fmt"
"io"
- "io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -148,7 +147,7 @@ func (d *ostreeImageDestination) HasThreadSafePutBlob() bool {
// to any other readers for download using the supplied digest.
// If stream.Read() at any time, ESPECIALLY at end of input, returns an error, PutBlob MUST 1) fail, and 2) delete any data stored so far.
func (d *ostreeImageDestination) PutBlob(ctx context.Context, stream io.Reader, inputInfo types.BlobInfo, cache types.BlobInfoCache, isConfig bool) (types.BlobInfo, error) {
- tmpDir, err := ioutil.TempDir(d.tmpDirPath, "blob")
+ tmpDir, err := os.MkdirTemp(d.tmpDirPath, "blob")
if err != nil {
return types.BlobInfo{}, err
}
@@ -180,20 +179,24 @@ func (d *ostreeImageDestination) PutBlob(ctx context.Context, stream io.Reader,
}
func fixFiles(selinuxHnd *C.struct_selabel_handle, root string, dir string, usermode bool) error {
- entries, err := ioutil.ReadDir(dir)
+ entries, err := os.ReadDir(dir)
if err != nil {
return err
}
- for _, info := range entries {
- fullpath := filepath.Join(dir, info.Name())
- if info.Mode()&(os.ModeNamedPipe|os.ModeSocket|os.ModeDevice) != 0 {
+ for _, entry := range entries {
+ fullpath := filepath.Join(dir, entry.Name())
+ if entry.Type()&(os.ModeNamedPipe|os.ModeSocket|os.ModeDevice) != 0 {
if err := os.Remove(fullpath); err != nil {
return err
}
continue
}
+ info, err := entry.Info()
+ if err != nil {
+ return err
+ }
if selinuxHnd != nil {
relPath, err := filepath.Rel(root, fullpath)
if err != nil {
@@ -223,7 +226,7 @@ func fixFiles(selinuxHnd *C.struct_selabel_handle, root string, dir string, user
}
}
- if info.IsDir() {
+ if entry.IsDir() {
if usermode {
if err := os.Chmod(fullpath, info.Mode()|0700); err != nil {
return err
@@ -233,7 +236,7 @@ func fixFiles(selinuxHnd *C.struct_selabel_handle, root string, dir string, user
if err != nil {
return err
}
- } else if usermode && (info.Mode().IsRegular()) {
+ } else if usermode && (entry.Type().IsRegular()) {
if err := os.Chmod(fullpath, info.Mode()|0600); err != nil {
return err
}
@@ -405,7 +408,7 @@ func (d *ostreeImageDestination) PutManifest(ctx context.Context, manifestBlob [
}
d.digest = digest
- return ioutil.WriteFile(manifestPath, manifestBlob, 0644)
+ return os.WriteFile(manifestPath, manifestBlob, 0644)
}
// PutSignatures writes signatures to the destination.
@@ -423,7 +426,7 @@ func (d *ostreeImageDestination) PutSignatures(ctx context.Context, signatures [
for i, sig := range signatures {
signaturePath := filepath.Join(d.tmpDirPath, d.ref.signaturePath(i))
- if err := ioutil.WriteFile(signaturePath, sig, 0644); err != nil {
+ if err := os.WriteFile(signaturePath, sig, 0644); err != nil {
return err
}
}
diff --git a/vendor/github.com/containers/image/v5/ostree/ostree_src.go b/vendor/github.com/containers/image/v5/ostree/ostree_src.go
index d30c764a6..1e1f2be03 100644
--- a/vendor/github.com/containers/image/v5/ostree/ostree_src.go
+++ b/vendor/github.com/containers/image/v5/ostree/ostree_src.go
@@ -9,7 +9,6 @@ import (
"encoding/base64"
"fmt"
"io"
- "io/ioutil"
"strconv"
"strings"
"unsafe"
@@ -369,7 +368,7 @@ func (s *ostreeImageSource) GetSignatures(ctx context.Context, instanceDigest *d
}
defer sigReader.Close()
- sig, err := ioutil.ReadAll(sigReader)
+ sig, err := os.ReadAll(sigReader)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/v5/pkg/blobcache/blobcache.go b/vendor/github.com/containers/image/v5/pkg/blobcache/blobcache.go
index b67a83f33..8b22733ac 100644
--- a/vendor/github.com/containers/image/v5/pkg/blobcache/blobcache.go
+++ b/vendor/github.com/containers/image/v5/pkg/blobcache/blobcache.go
@@ -4,7 +4,6 @@ import (
"bytes"
"context"
"io"
- "io/ioutil"
"os"
"path/filepath"
"sync"
@@ -196,7 +195,7 @@ func (s *blobCacheSource) Close() error {
func (s *blobCacheSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) {
if instanceDigest != nil {
filename := filepath.Join(s.reference.directory, makeFilename(*instanceDigest, false))
- manifestBytes, err := ioutil.ReadFile(filename)
+ manifestBytes, err := os.ReadFile(filename)
if err == nil {
s.cacheHits++
return manifestBytes, manifest.GuessMIMEType(manifestBytes), nil
@@ -280,10 +279,10 @@ func (s *blobCacheSource) LayerInfosForCopy(ctx context.Context, instanceDigest
switch s.reference.compress {
case types.Compress:
alternate = blobFile + compressedNote
- replaceDigest, err = ioutil.ReadFile(alternate)
+ replaceDigest, err = os.ReadFile(alternate)
case types.Decompress:
alternate = blobFile + decompressedNote
- replaceDigest, err = ioutil.ReadFile(alternate)
+ replaceDigest, err = os.ReadFile(alternate)
}
if err == nil && digest.Digest(replaceDigest).Validate() == nil {
alternate = filepath.Join(filepath.Dir(alternate), makeFilename(digest.Digest(replaceDigest), false))
@@ -373,7 +372,7 @@ func saveStream(wg *sync.WaitGroup, decompressReader io.ReadCloser, tempFile *os
_, err3 = io.Copy(io.MultiWriter(tempFile, digester.Hash()), decompressed)
} else {
// Drain the pipe to keep from stalling the PutBlob() thread.
- if _, err := io.Copy(ioutil.Discard, decompressReader); err != nil {
+ if _, err := io.Copy(io.Discard, decompressReader); err != nil {
logrus.Debugf("error draining the pipe: %v", err)
}
}
@@ -423,7 +422,7 @@ func (d *blobCacheDestination) PutBlob(ctx context.Context, stream io.Reader, in
compression := archive.Uncompressed
if inputInfo.Digest != "" {
filename := filepath.Join(d.reference.directory, makeFilename(inputInfo.Digest, isConfig))
- tempfile, err = ioutil.TempFile(d.reference.directory, makeFilename(inputInfo.Digest, isConfig))
+ tempfile, err = os.CreateTemp(d.reference.directory, makeFilename(inputInfo.Digest, isConfig))
if err == nil {
stream = io.TeeReader(stream, tempfile)
defer func() {
@@ -457,7 +456,7 @@ func (d *blobCacheDestination) PutBlob(ctx context.Context, stream io.Reader, in
if compression == archive.Gzip {
// The stream is compressed, so create a file which we'll
// use to store a decompressed copy.
- decompressedTemp, err2 := ioutil.TempFile(d.reference.directory, makeFilename(inputInfo.Digest, isConfig))
+ decompressedTemp, err2 := os.CreateTemp(d.reference.directory, makeFilename(inputInfo.Digest, isConfig))
if err2 != nil {
logrus.Debugf("error while creating a temporary file under %q to hold decompressed blob %q: %v", d.reference.directory, inputInfo.Digest.String(), err2)
decompressedTemp.Close()
diff --git a/vendor/github.com/containers/image/v5/pkg/compression/compression.go b/vendor/github.com/containers/image/v5/pkg/compression/compression.go
index c28e81792..34c90dd77 100644
--- a/vendor/github.com/containers/image/v5/pkg/compression/compression.go
+++ b/vendor/github.com/containers/image/v5/pkg/compression/compression.go
@@ -5,7 +5,6 @@ import (
"compress/bzip2"
"fmt"
"io"
- "io/ioutil"
"github.com/containers/image/v5/pkg/compression/internal"
"github.com/containers/image/v5/pkg/compression/types"
@@ -65,7 +64,7 @@ func GzipDecompressor(r io.Reader) (io.ReadCloser, error) {
// Bzip2Decompressor is a DecompressorFunc for the bzip2 compression algorithm.
func Bzip2Decompressor(r io.Reader) (io.ReadCloser, error) {
- return ioutil.NopCloser(bzip2.NewReader(r)), nil
+ return io.NopCloser(bzip2.NewReader(r)), nil
}
// XzDecompressor is a DecompressorFunc for the xz compression algorithm.
@@ -74,7 +73,7 @@ func XzDecompressor(r io.Reader) (io.ReadCloser, error) {
if err != nil {
return nil, err
}
- return ioutil.NopCloser(r), nil
+ return io.NopCloser(r), nil
}
// gzipCompressor is a CompressorFunc for the gzip compression algorithm.
@@ -161,7 +160,7 @@ func AutoDecompress(stream io.Reader) (io.ReadCloser, bool, error) {
return nil, false, errors.Wrapf(err, "initializing decompression")
}
} else {
- res = ioutil.NopCloser(stream)
+ res = io.NopCloser(stream)
}
return res, decompressor != nil, nil
}
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 52734bead..d0bdd08e9 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
@@ -4,7 +4,6 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
- "io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -544,7 +543,7 @@ func getPathToAuthWithOS(sys *types.SystemContext, goOS string) (string, bool, e
func readJSONFile(path string, legacyFormat bool) (dockerConfigFile, error) {
var auths dockerConfigFile
- raw, err := ioutil.ReadFile(path)
+ raw, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
auths.AuthConfigs = map[string]dockerAuthConfig{}
diff --git a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go
index c5df241b7..c1753c845 100644
--- a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go
+++ b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go
@@ -2,6 +2,7 @@ package sysregistriesv2
import (
"fmt"
+ "io/fs"
"os"
"path/filepath"
"reflect"
@@ -643,17 +644,17 @@ func dropInConfigs(wrapper configWrapper) ([]string, error) {
dirPaths = append(dirPaths, wrapper.userConfigDirPath)
}
for _, dirPath := range dirPaths {
- err := filepath.Walk(dirPath,
+ err := filepath.WalkDir(dirPath,
// WalkFunc to read additional configs
- func(path string, info os.FileInfo, err error) error {
+ func(path string, d fs.DirEntry, err error) error {
switch {
case err != nil:
// return error (could be a permission problem)
return err
- case info == nil:
+ case d == nil:
// this should only happen when err != nil but let's be sure
return nil
- case info.IsDir():
+ case d.IsDir():
if path != dirPath {
// make sure to not recurse into sub-directories
return filepath.SkipDir
diff --git a/vendor/github.com/containers/image/v5/pkg/tlsclientconfig/tlsclientconfig.go b/vendor/github.com/containers/image/v5/pkg/tlsclientconfig/tlsclientconfig.go
index 7e2142b1f..c766417d0 100644
--- a/vendor/github.com/containers/image/v5/pkg/tlsclientconfig/tlsclientconfig.go
+++ b/vendor/github.com/containers/image/v5/pkg/tlsclientconfig/tlsclientconfig.go
@@ -2,7 +2,6 @@ package tlsclientconfig
import (
"crypto/tls"
- "io/ioutil"
"net"
"net/http"
"os"
@@ -19,7 +18,7 @@ import (
// SetupCertificates opens all .crt, .cert, and .key files in dir and appends / loads certs and key pairs as appropriate to tlsc
func SetupCertificates(dir string, tlsc *tls.Config) error {
logrus.Debugf("Looking for TLS certificates and private keys in %s", dir)
- fs, err := ioutil.ReadDir(dir)
+ fs, err := os.ReadDir(dir)
if err != nil {
if os.IsNotExist(err) {
return nil
@@ -35,7 +34,7 @@ func SetupCertificates(dir string, tlsc *tls.Config) error {
fullPath := filepath.Join(dir, f.Name())
if strings.HasSuffix(f.Name(), ".crt") {
logrus.Debugf(" crt: %s", fullPath)
- data, err := ioutil.ReadFile(fullPath)
+ data, err := os.ReadFile(fullPath)
if err != nil {
if os.IsNotExist(err) {
// Dangling symbolic link?
@@ -81,7 +80,7 @@ func SetupCertificates(dir string, tlsc *tls.Config) error {
return nil
}
-func hasFile(files []os.FileInfo, name string) bool {
+func hasFile(files []os.DirEntry, name string) bool {
for _, f := range files {
if f.Name() == name {
return true
diff --git a/vendor/github.com/containers/image/v5/sif/load.go b/vendor/github.com/containers/image/v5/sif/load.go
index ba6d875ba..70758ad43 100644
--- a/vendor/github.com/containers/image/v5/sif/load.go
+++ b/vendor/github.com/containers/image/v5/sif/load.go
@@ -5,7 +5,6 @@ import (
"context"
"fmt"
"io"
- "io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -103,7 +102,7 @@ func writeInjectedScript(extractedRootPath string, injectedScript []byte) error
if err := os.MkdirAll(parentDirPath, 0755); err != nil {
return fmt.Errorf("creating %s: %w", parentDirPath, err)
}
- if err := ioutil.WriteFile(filePath, injectedScript, 0755); err != nil {
+ if err := os.WriteFile(filePath, injectedScript, 0755); err != nil {
return fmt.Errorf("writing %s to %s: %w", injectedScriptTargetPath, filePath, err)
}
return nil
@@ -121,7 +120,7 @@ func createTarFromSIFInputs(ctx context.Context, tarPath, squashFSPath string, i
conversionCommand := fmt.Sprintf("unsquashfs -d %s -f %s && tar --acls --xattrs -C %s -cpf %s ./",
extractedRootPath, squashFSPath, extractedRootPath, tarPath)
script := "#!/bin/sh\n" + conversionCommand + "\n"
- if err := ioutil.WriteFile(scriptPath, []byte(script), 0755); err != nil {
+ if err := os.WriteFile(scriptPath, []byte(script), 0755); err != nil {
return err
}
defer os.Remove(scriptPath)
@@ -149,7 +148,7 @@ func createTarFromSIFInputs(ctx context.Context, tarPath, squashFSPath string, i
// at start, and is exclusively used by the current process (i.e. it is safe
// to use hard-coded relative paths within it).
func convertSIFToElements(ctx context.Context, sifImage *sif.FileImage, tempDir string) (string, []string, error) {
- // We could allocate unique names for all of these using ioutil.Temp*, but tempDir is exclusive,
+ // We could allocate unique names for all of these using os.{CreateTemp,MkdirTemp}, but tempDir is exclusive,
// so we can just hard-code a set of unique values here.
// We create and/or manage cleanup of these two paths.
squashFSPath := filepath.Join(tempDir, "rootfs.squashfs")
diff --git a/vendor/github.com/containers/image/v5/sif/src.go b/vendor/github.com/containers/image/v5/sif/src.go
index ba95a469f..ccf125966 100644
--- a/vendor/github.com/containers/image/v5/sif/src.go
+++ b/vendor/github.com/containers/image/v5/sif/src.go
@@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"io"
- "io/ioutil"
"os"
"github.com/containers/image/v5/internal/tmpdir"
@@ -65,7 +64,7 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref sifRefere
_ = sifImg.UnloadContainer()
}()
- workDir, err := ioutil.TempDir(tmpdir.TemporaryDirectoryForBigFiles(sys), "sif")
+ workDir, err := os.MkdirTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "sif")
if err != nil {
return nil, fmt.Errorf("creating temp directory: %w", err)
}
@@ -170,7 +169,7 @@ func (s *sifImageSource) HasThreadSafeGetBlob() bool {
func (s *sifImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) {
switch info.Digest {
case s.configDigest:
- return ioutil.NopCloser(bytes.NewBuffer(s.config)), int64(len(s.config)), nil
+ return io.NopCloser(bytes.NewBuffer(s.config)), int64(len(s.config)), nil
case s.layerDigest:
reader, err := os.Open(s.layerFile)
if err != nil {
diff --git a/vendor/github.com/containers/image/v5/signature/mechanism.go b/vendor/github.com/containers/image/v5/signature/mechanism.go
index 961246147..249b5a1fe 100644
--- a/vendor/github.com/containers/image/v5/signature/mechanism.go
+++ b/vendor/github.com/containers/image/v5/signature/mechanism.go
@@ -6,7 +6,7 @@ import (
"bytes"
"errors"
"fmt"
- "io/ioutil"
+ "io"
"strings"
// This code is used only to parse the data in an explicitly-untrusted
@@ -82,7 +82,7 @@ func gpgUntrustedSignatureContents(untrustedSignature []byte) (untrustedContents
if !md.IsSigned {
return nil, "", errors.New("The input is not a signature")
}
- content, err := ioutil.ReadAll(md.UnverifiedBody)
+ content, err := io.ReadAll(md.UnverifiedBody)
if err != nil {
// Coverage: An error during reading the body can happen only if
// 1) the message is encrypted, which is not our case (and we don’t give ReadMessage the key
diff --git a/vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go b/vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go
index c166fb32d..4c7968417 100644
--- a/vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go
+++ b/vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go
@@ -7,7 +7,6 @@ import (
"bytes"
"errors"
"fmt"
- "io/ioutil"
"os"
"github.com/proglottis/gpgme"
@@ -37,7 +36,7 @@ func newGPGSigningMechanismInDirectory(optionalDir string) (signingMechanismWith
// of these keys.
// The caller must call .Close() on the returned SigningMechanism.
func newEphemeralGPGSigningMechanism(blob []byte) (signingMechanismWithPassphrase, []string, error) {
- dir, err := ioutil.TempDir("", "containers-ephemeral-gpg-")
+ dir, err := os.MkdirTemp("", "containers-ephemeral-gpg-")
if err != nil {
return nil, nil, err
}
diff --git a/vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go b/vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go
index ef4e70e7f..63cb7788b 100644
--- a/vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go
+++ b/vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go
@@ -7,7 +7,7 @@ import (
"bytes"
"errors"
"fmt"
- "io/ioutil"
+ "io"
"os"
"path"
"strings"
@@ -44,7 +44,7 @@ func newGPGSigningMechanismInDirectory(optionalDir string) (signingMechanismWith
}
}
- pubring, err := ioutil.ReadFile(path.Join(gpgHome, "pubring.gpg"))
+ pubring, err := os.ReadFile(path.Join(gpgHome, "pubring.gpg"))
if err != nil {
if !os.IsNotExist(err) {
return nil, err
@@ -130,7 +130,7 @@ func (m *openpgpSigningMechanism) Verify(unverifiedSignature []byte) (contents [
if !md.IsSigned {
return nil, "", errors.New("not signed")
}
- content, err := ioutil.ReadAll(md.UnverifiedBody)
+ content, err := io.ReadAll(md.UnverifiedBody)
if err != nil {
// Coverage: md.UnverifiedBody.Read only fails if the body is encrypted
// (and possibly also signed, but it _must_ be encrypted) and the signing
diff --git a/vendor/github.com/containers/image/v5/signature/policy_config.go b/vendor/github.com/containers/image/v5/signature/policy_config.go
index 82fbb68cb..bb91cae8c 100644
--- a/vendor/github.com/containers/image/v5/signature/policy_config.go
+++ b/vendor/github.com/containers/image/v5/signature/policy_config.go
@@ -16,7 +16,6 @@ package signature
import (
"encoding/json"
"fmt"
- "io/ioutil"
"os"
"path/filepath"
"regexp"
@@ -80,7 +79,7 @@ func defaultPolicyPathWithHomeDir(sys *types.SystemContext, homeDir string) stri
// NewPolicyFromFile returns a policy configured in the specified file.
func NewPolicyFromFile(fileName string) (*Policy, error) {
- contents, err := ioutil.ReadFile(fileName)
+ contents, err := os.ReadFile(fileName)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/v5/signature/policy_eval_signedby.go b/vendor/github.com/containers/image/v5/signature/policy_eval_signedby.go
index 26cca4759..65e825973 100644
--- a/vendor/github.com/containers/image/v5/signature/policy_eval_signedby.go
+++ b/vendor/github.com/containers/image/v5/signature/policy_eval_signedby.go
@@ -5,7 +5,7 @@ package signature
import (
"context"
"fmt"
- "io/ioutil"
+ "os"
"strings"
"github.com/containers/image/v5/manifest"
@@ -33,7 +33,7 @@ func (pr *prSignedBy) isSignatureAuthorAccepted(ctx context.Context, image types
if pr.KeyData != nil {
data = pr.KeyData
} else {
- d, err := ioutil.ReadFile(pr.KeyPath)
+ d, err := os.ReadFile(pr.KeyPath)
if err != nil {
return sarRejected, nil, err
}
diff --git a/vendor/github.com/containers/image/v5/storage/storage_image.go b/vendor/github.com/containers/image/v5/storage/storage_image.go
index 08ae042ac..8071e3b32 100644
--- a/vendor/github.com/containers/image/v5/storage/storage_image.go
+++ b/vendor/github.com/containers/image/v5/storage/storage_image.go
@@ -10,7 +10,6 @@ import (
stderrors "errors"
"fmt"
"io"
- "io/ioutil"
"os"
"path/filepath"
"sync"
@@ -155,7 +154,7 @@ func (s *storageImageSource) HasThreadSafeGetBlob() bool {
// May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location.
func (s *storageImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (rc io.ReadCloser, n int64, err error) {
if info.Digest == image.GzippedEmptyLayerDigest {
- return ioutil.NopCloser(bytes.NewReader(image.GzippedEmptyLayer)), int64(len(image.GzippedEmptyLayer)), nil
+ return io.NopCloser(bytes.NewReader(image.GzippedEmptyLayer)), int64(len(image.GzippedEmptyLayer)), nil
}
// NOTE: the blob is first written to a temporary file and subsequently
@@ -167,7 +166,7 @@ func (s *storageImageSource) GetBlob(ctx context.Context, info types.BlobInfo, c
}
defer rc.Close()
- tmpFile, err := ioutil.TempFile(tmpdir.TemporaryDirectoryForBigFiles(s.systemContext), "")
+ tmpFile, err := os.CreateTemp(tmpdir.TemporaryDirectoryForBigFiles(s.systemContext), "")
if err != nil {
return nil, 0, err
}
@@ -210,7 +209,7 @@ func (s *storageImageSource) getBlobAndLayerID(info types.BlobInfo) (rc io.ReadC
}
r := bytes.NewReader(b)
logrus.Debugf("exporting opaque data as blob %q", info.Digest.String())
- return ioutil.NopCloser(r), int64(r.Len()), "", nil
+ return io.NopCloser(r), int64(r.Len()), "", nil
}
// Step through the list of matching layers. Tests may want to verify that if we have multiple layers
// which claim to have the same contents, that we actually do have multiple layers, otherwise we could
@@ -395,7 +394,7 @@ func (s *storageImageSource) GetSignatures(ctx context.Context, instanceDigest *
// newImageDestination sets us up to write a new image, caching blobs in a temporary directory until
// it's time to Commit() the image
func newImageDestination(sys *types.SystemContext, imageRef storageReference) (*storageImageDestination, error) {
- directory, err := ioutil.TempDir(tmpdir.TemporaryDirectoryForBigFiles(sys), "storage")
+ directory, err := os.MkdirTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "storage")
if err != nil {
return nil, errors.Wrapf(err, "creating a temporary directory")
}
@@ -791,7 +790,7 @@ func (s *storageImageDestination) getConfigBlob(info types.BlobInfo) ([]byte, er
}
// Assume it's a file, since we're only calling this from a place that expects to read files.
if filename, ok := s.filenames[info.Digest]; ok {
- contents, err2 := ioutil.ReadFile(filename)
+ contents, err2 := os.ReadFile(filename)
if err2 != nil {
return nil, errors.Wrapf(err2, `reading blob from file %q`, filename)
}
@@ -1136,7 +1135,7 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
delete(dataBlobs, layerBlob.Digest)
}
for blob := range dataBlobs {
- v, err := ioutil.ReadFile(s.filenames[blob])
+ v, err := os.ReadFile(s.filenames[blob])
if err != nil {
return errors.Wrapf(err, "copying non-layer blob %q to image", blob)
}
diff --git a/vendor/github.com/containers/image/v5/tarball/tarball_src.go b/vendor/github.com/containers/image/v5/tarball/tarball_src.go
index 694ad17bd..aedfdf5de 100644
--- a/vendor/github.com/containers/image/v5/tarball/tarball_src.go
+++ b/vendor/github.com/containers/image/v5/tarball/tarball_src.go
@@ -6,7 +6,6 @@ import (
"encoding/json"
"fmt"
"io"
- "io/ioutil"
"os"
"runtime"
"strings"
@@ -87,7 +86,7 @@ func (r *tarballReference) NewImageSource(ctx context.Context, sys *types.System
uncompressed = nil
}
// TODO: This can take quite some time, and should ideally be cancellable using ctx.Done().
- n, err := io.Copy(ioutil.Discard, reader)
+ n, err := io.Copy(io.Discard, reader)
if err != nil {
return nil, fmt.Errorf("error reading %q: %v", filename, err)
}
@@ -217,14 +216,14 @@ func (is *tarballImageSource) HasThreadSafeGetBlob() bool {
func (is *tarballImageSource) GetBlob(ctx context.Context, blobinfo types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) {
// We should only be asked about things in the manifest. Maybe the configuration blob.
if blobinfo.Digest == is.configID {
- return ioutil.NopCloser(bytes.NewBuffer(is.config)), is.configSize, nil
+ return io.NopCloser(bytes.NewBuffer(is.config)), is.configSize, nil
}
// Maybe one of the layer blobs.
for i := range is.blobIDs {
if blobinfo.Digest == is.blobIDs[i] {
// We want to read that layer: open the file or memory block and hand it back.
if is.filenames[i] == "-" {
- return ioutil.NopCloser(bytes.NewBuffer(is.reference.stdin)), int64(len(is.reference.stdin)), nil
+ return io.NopCloser(bytes.NewBuffer(is.reference.stdin)), int64(len(is.reference.stdin)), nil
}
reader, err := os.Open(is.filenames[i])
if err != nil {
diff --git a/vendor/github.com/containers/image/v5/tarball/tarball_transport.go b/vendor/github.com/containers/image/v5/tarball/tarball_transport.go
index d407c657f..63d835530 100644
--- a/vendor/github.com/containers/image/v5/tarball/tarball_transport.go
+++ b/vendor/github.com/containers/image/v5/tarball/tarball_transport.go
@@ -3,7 +3,7 @@ package tarball
import (
"errors"
"fmt"
- "io/ioutil"
+ "io"
"os"
"strings"
@@ -36,7 +36,7 @@ func (t *tarballTransport) ParseReference(reference string) (types.ImageReferenc
filenames := strings.Split(reference, separator)
for _, filename := range filenames {
if filename == "-" {
- stdin, err = ioutil.ReadAll(os.Stdin)
+ stdin, err = io.ReadAll(os.Stdin)
if err != nil {
return nil, fmt.Errorf("error buffering stdin: %v", err)
}
diff --git a/vendor/github.com/containers/storage/Makefile b/vendor/github.com/containers/storage/Makefile
index d7ca0c1c4..2c1e4a185 100644
--- a/vendor/github.com/containers/storage/Makefile
+++ b/vendor/github.com/containers/storage/Makefile
@@ -69,44 +69,44 @@ local-cross: ## cross build the binaries for arm, darwin, and\nfreebsd
done
cross: ## cross build the binaries for arm, darwin, and\nfreebsd using VMs
- $(RUNINVM) make local-$@
+ $(RUNINVM) $(MAKE) local-$@
docs: install.tools ## build the docs on the host
$(MAKE) -C docs docs
gccgo: ## build using gccgo using VMs
- $(RUNINVM) make local-$@
+ $(RUNINVM) $(MAKE) local-$@
test: local-binary ## build the binaries and run the tests using VMs
- $(RUNINVM) make local-binary local-cross local-test-unit local-test-integration
+ $(RUNINVM) $(MAKE) local-binary local-cross local-test-unit local-test-integration
local-test-unit: local-binary ## run the unit tests on the host (requires\nsuperuser privileges)
@$(GO) test $(MOD_VENDOR) $(BUILDFLAGS) $(TESTFLAGS) $(shell $(GO) list ./... | grep -v ^$(PACKAGE)/vendor)
test-unit: local-binary ## run the unit tests using VMs
- $(RUNINVM) make local-$@
+ $(RUNINVM) $(MAKE) local-$@
local-test-integration: local-binary ## run the integration tests on the host (requires\nsuperuser privileges)
@cd tests; ./test_runner.bash
test-integration: local-binary ## run the integration tests using VMs
- $(RUNINVM) make local-$@
+ $(RUNINVM) $(MAKE) local-$@
local-validate: ## validate DCO and gofmt on the host
@./hack/git-validation.sh
@./hack/gofmt.sh
validate: ## validate DCO, gofmt, ./pkg/ isolation, golint,\ngo vet and vendor using VMs
- $(RUNINVM) make local-$@
+ $(RUNINVM) $(MAKE) local-$@
install.tools:
- make -C tests/tools
+ $(MAKE) -C tests/tools
$(FFJSON):
- make -C tests/tools
+ $(MAKE) -C tests/tools
install.docs: docs
- make -C docs install
+ $(MAKE) -C docs install
install: install.docs
diff --git a/vendor/github.com/containers/storage/drivers/driver_freebsd.go b/vendor/github.com/containers/storage/drivers/driver_freebsd.go
index e1320ee07..79a591288 100644
--- a/vendor/github.com/containers/storage/drivers/driver_freebsd.go
+++ b/vendor/github.com/containers/storage/drivers/driver_freebsd.go
@@ -1,16 +1,45 @@
package graphdriver
import (
+ "fmt"
"golang.org/x/sys/unix"
+
+ "github.com/containers/storage/pkg/mount"
+)
+
+const (
+ // FsMagicZfs filesystem id for Zfs
+ FsMagicZfs = FsMagic(0x2fc12fc1)
)
var (
// Slice of drivers that should be used in an order
priority = []string{
"zfs",
+ "vfs",
+ }
+
+ // FsNames maps filesystem id to name of the filesystem.
+ FsNames = map[FsMagic]string{
+ FsMagicZfs: "zfs",
}
)
+// NewDefaultChecker returns a check that parses /proc/mountinfo to check
+// if the specified path is mounted.
+// No-op on FreeBSD.
+func NewDefaultChecker() Checker {
+ return &defaultChecker{}
+}
+
+type defaultChecker struct {
+}
+
+func (c *defaultChecker) IsMounted(path string) bool {
+ m, _ := mount.Mounted(path)
+ return m
+}
+
// Mounted checks if the given path is mounted as the fs type
func Mounted(fsType FsMagic, mountPath string) (bool, error) {
var buf unix.Statfs_t
diff --git a/vendor/github.com/containers/storage/drivers/register/register_zfs.go b/vendor/github.com/containers/storage/drivers/register/register_zfs.go
index c748468e5..4623e7f46 100644
--- a/vendor/github.com/containers/storage/drivers/register/register_zfs.go
+++ b/vendor/github.com/containers/storage/drivers/register/register_zfs.go
@@ -1,4 +1,4 @@
-// +build !exclude_graphdriver_zfs,linux !exclude_graphdriver_zfs,freebsd, solaris
+// +build !exclude_graphdriver_zfs,linux !exclude_graphdriver_zfs,freebsd solaris
package register
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs.go b/vendor/github.com/containers/storage/drivers/zfs/zfs.go
index e034bf152..f29dc8f85 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs.go
@@ -344,7 +344,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) error {
return errors.Wrap(err, "error creating zfs mount")
}
defer func() {
- if err := unix.Unmount(mountpoint, unix.MNT_DETACH); err != nil {
+ if err := detachUnmount(mountpoint); err != nil {
logrus.Warnf("Failed to unmount %s mount %s: %v", id, mountpoint, err)
}
}()
@@ -483,7 +483,7 @@ func (d *Driver) Put(id string) error {
logger.Debugf(`unmount("%s")`, mountpoint)
- if err := unix.Unmount(mountpoint, unix.MNT_DETACH); err != nil {
+ if err := detachUnmount(mountpoint); err != nil {
logger.Warnf("Failed to unmount %s mount %s: %v", id, mountpoint, err)
}
if err := unix.Rmdir(mountpoint); err != nil && !os.IsNotExist(err) {
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go b/vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go
index bf6905159..fd98ad305 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go
@@ -37,3 +37,8 @@ func getMountpoint(id string) string {
return id[:maxlen]
}
+
+func detachUnmount(mountpoint string) error {
+ // FreeBSD doesn't have an equivalent to MNT_DETACH
+ return unix.Unmount(mountpoint, 0)
+}
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go b/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go
index edcb1da36..44c68f394 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go
@@ -4,6 +4,7 @@ import (
graphdriver "github.com/containers/storage/drivers"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
+ "golang.org/x/sys/unix"
)
func checkRootdirFs(rootDir string) error {
@@ -27,3 +28,7 @@ func checkRootdirFs(rootDir string) error {
func getMountpoint(id string) string {
return id
}
+
+func detachUnmount(mountpoint string) error {
+ return unix.Unmount(mountpoint, unix.MNT_DETACH)
+}
diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go
index 5e9930ea7..34d27ffa3 100644
--- a/vendor/github.com/containers/storage/layers.go
+++ b/vendor/github.com/containers/storage/layers.go
@@ -683,7 +683,7 @@ func (r *layerStore) PutAdditionalLayer(id string, parentLayer *Layer, names []s
r.bycompressedsum[layer.CompressedDigest] = append(r.bycompressedsum[layer.CompressedDigest], layer.ID)
}
if layer.UncompressedDigest != "" {
- r.byuncompressedsum[layer.CompressedDigest] = append(r.byuncompressedsum[layer.CompressedDigest], layer.ID)
+ r.byuncompressedsum[layer.UncompressedDigest] = append(r.byuncompressedsum[layer.UncompressedDigest], layer.ID)
}
if err := r.Save(); err != nil {
r.driver.Remove(id)
@@ -866,6 +866,14 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
return nil, -1, err
}
delete(layer.Flags, incompleteFlag)
+ } else {
+ // applyDiffWithOptions in the `diff != nil` case handles this bit for us
+ if layer.CompressedDigest != "" {
+ r.bycompressedsum[layer.CompressedDigest] = append(r.bycompressedsum[layer.CompressedDigest], layer.ID)
+ }
+ if layer.UncompressedDigest != "" {
+ r.byuncompressedsum[layer.UncompressedDigest] = append(r.byuncompressedsum[layer.UncompressedDigest], layer.ID)
+ }
}
err = r.Save()
if err != nil {
diff --git a/vendor/github.com/containers/storage/storage.conf-freebsd b/vendor/github.com/containers/storage/storage.conf-freebsd
new file mode 100644
index 000000000..cc655c62e
--- /dev/null
+++ b/vendor/github.com/containers/storage/storage.conf-freebsd
@@ -0,0 +1,205 @@
+# This file is is the configuration file for all tools
+# that use the containers/storage library. The storage.conf file
+# overrides all other storage.conf files. Container engines using the
+# container/storage library do not inherit fields from other storage.conf
+# files.
+#
+# Note: The storage.conf file overrides other storage.conf files based on this precedence:
+# /usr/containers/storage.conf
+# /etc/containers/storage.conf
+# $HOME/.config/containers/storage.conf
+# $XDG_CONFIG_HOME/containers/storage.conf (If XDG_CONFIG_HOME is set)
+# See man 5 containers-storage.conf for more information
+# The "container storage" table contains all of the server options.
+[storage]
+
+# Default Storage Driver, Must be set for proper operation.
+driver = "zfs"
+
+# Temporary storage location
+runroot = "/var/run/containers/storage"
+
+# Primary Read/Write location of container storage
+graphroot = "/var/db/containers/storage"
+
+
+# Storage path for rootless users
+#
+# rootless_storage_path = "$HOME/.local/share/containers/storage"
+
+[storage.options]
+# Storage options to be passed to underlying storage drivers
+
+# AdditionalImageStores is used to pass paths to additional Read/Only image stores
+# Must be comma separated list.
+additionalimagestores = [
+]
+
+# 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 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.
+#
+# remap-uids = 0:1668442479:65536
+# remap-gids = 0:1668442479:65536
+
+# Remap-User/Group is a user name which can be used to look up one or more UID/GID
+# ranges in the /etc/subuid or /etc/subgid file. Mappings are set up starting
+# with an in-container ID of 0 and then a host-level ID taken from the lowest
+# range that matches the specified name, and using the length of that range.
+# Additional ranges are then assigned, using the ranges which specify the
+# lowest host-level IDs first, to the lowest not-yet-mapped in-container ID,
+# until all of the entries have been used for maps.
+#
+# remap-user = "containers"
+# remap-group = "containers"
+
+# Root-auto-userns-user is a user name which can be used to look up one or more UID/GID
+# ranges in the /etc/subuid and /etc/subgid file. These ranges will be partitioned
+# to containers configured to create automatically a user namespace. Containers
+# configured to automatically create a user namespace can still overlap with containers
+# having an explicit mapping set.
+# This setting is ignored when running as rootless.
+# root-auto-userns-user = "storage"
+#
+# Auto-userns-min-size is the minimum size for a user namespace created automatically.
+# auto-userns-min-size=1024
+#
+# Auto-userns-max-size is the minimum size for a user namespace created automatically.
+# auto-userns-max-size=65536
+
+[storage.options.overlay]
+# ignore_chown_errors can be set to allow a non privileged user running with
+# a single UID within a user namespace to run containers. The user can pull
+# and use any image even those with multiple uids. Note multiple UIDs will be
+# squashed down to the default uid in the container. These images will have no
+# separation between the users in the container. Only supported for the overlay
+# and vfs drivers.
+#ignore_chown_errors = "false"
+
+# Inodes is used to set a maximum inodes of the container image.
+# inodes = ""
+
+# Path to an helper program to use for mounting the file system instead of mounting it
+# directly.
+#mount_program = "/usr/bin/fuse-overlayfs"
+
+# mountopt specifies comma separated list of extra mount options
+mountopt = "nodev"
+
+# Set to skip a PRIVATE bind mount on the storage home directory.
+# skip_mount_home = "false"
+
+# Size is used to set a maximum size of the container image.
+# size = ""
+
+# ForceMask specifies the permissions mask that is used for new files and
+# directories.
+#
+# The values "shared" and "private" are accepted.
+# Octal permission masks are also accepted.
+#
+# "": No value specified.
+# All files/directories, get set with the permissions identified within the
+# image.
+# "private": it is equivalent to 0700.
+# All files/directories get set with 0700 permissions. The owner has rwx
+# access to the files. No other users on the system can access the files.
+# This setting could be used with networked based homedirs.
+# "shared": it is equivalent to 0755.
+# The owner has rwx access to the files and everyone else can read, access
+# and execute them. This setting is useful for sharing containers storage
+# with other users. For instance have a storage owned by root but shared
+# to rootless users as an additional store.
+# NOTE: All files within the image are made readable and executable by any
+# user on the system. Even /etc/shadow within your image is now readable by
+# any user.
+#
+# OCTAL: Users can experiment with other OCTAL Permissions.
+#
+# Note: The force_mask Flag is an experimental feature, it could change in the
+# future. When "force_mask" is set the original permission mask is stored in
+# the "user.containers.override_stat" xattr and the "mount_program" option must
+# be specified. Mount programs like "/usr/bin/fuse-overlayfs" present the
+# extended attribute permissions to processes within containers rather then the
+# "force_mask" permissions.
+#
+# force_mask = ""
+
+[storage.options.thinpool]
+# Storage Options for thinpool
+
+# autoextend_percent determines the amount by which pool needs to be
+# grown. This is specified in terms of % of pool size. So a value of 20 means
+# that when threshold is hit, pool will be grown by 20% of existing
+# pool size.
+# autoextend_percent = "20"
+
+# autoextend_threshold determines the pool extension threshold in terms
+# of percentage of pool size. For example, if threshold is 60, that means when
+# pool is 60% full, threshold has been hit.
+# autoextend_threshold = "80"
+
+# basesize specifies the size to use when creating the base device, which
+# limits the size of images and containers.
+# basesize = "10G"
+
+# blocksize specifies a custom blocksize to use for the thin pool.
+# blocksize="64k"
+
+# directlvm_device specifies a custom block storage device to use for the
+# thin pool. Required if you setup devicemapper.
+# directlvm_device = ""
+
+# directlvm_device_force wipes device even if device already has a filesystem.
+# directlvm_device_force = "True"
+
+# fs specifies the filesystem type to use for the base device.
+# fs="xfs"
+
+# log_level sets the log level of devicemapper.
+# 0: LogLevelSuppress 0 (Default)
+# 2: LogLevelFatal
+# 3: LogLevelErr
+# 4: LogLevelWarn
+# 5: LogLevelNotice
+# 6: LogLevelInfo
+# 7: LogLevelDebug
+# log_level = "7"
+
+# min_free_space specifies the min free space percent in a thin pool require for
+# new device creation to succeed. Valid values are from 0% - 99%.
+# Value 0% disables
+# min_free_space = "10%"
+
+# mkfsarg specifies extra mkfs arguments to be used when creating the base
+# device.
+# mkfsarg = ""
+
+# metadata_size is used to set the `pvcreate --metadatasize` options when
+# creating thin devices. Default is 128k
+# metadata_size = ""
+
+# Size is used to set a maximum size of the container image.
+# size = ""
+
+# use_deferred_removal marks devicemapper block device for deferred removal.
+# If the thinpool is in use when the driver attempts to remove it, the driver
+# tells the kernel to remove it as soon as possible. Note this does not free
+# up the disk space, use deferred deletion to fully remove the thinpool.
+# use_deferred_removal = "True"
+
+# use_deferred_deletion marks thinpool device for deferred deletion.
+# If the device is busy when the driver attempts to delete it, the driver
+# will attempt to delete device every 30 seconds until successful.
+# If the program using the driver exits, the driver will continue attempting
+# to cleanup the next time the driver is used. Deferred deletion permanently
+# deletes the device and all data stored in device will be lost.
+# use_deferred_deletion = "True"
+
+# xfs_nospace_max_retries specifies the maximum number of retries XFS should
+# attempt to complete IO when ENOSPC (no space) error is returned by
+# underlying storage device.
+# xfs_nospace_max_retries = "0"
diff --git a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
deleted file mode 100644
index 38a099162..000000000
--- a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
+++ /dev/null
@@ -1,83 +0,0 @@
-## 1.4.3
-
-* Fix cases where `json.Number` didn't decode properly [GH-261]
-
-## 1.4.2
-
-* Custom name matchers to support any sort of casing, formatting, etc. for
- field names. [GH-250]
-* Fix possible panic in ComposeDecodeHookFunc [GH-251]
-
-## 1.4.1
-
-* Fix regression where `*time.Time` value would be set to empty and not be sent
- to decode hooks properly [GH-232]
-
-## 1.4.0
-
-* A new decode hook type `DecodeHookFuncValue` has been added that has
- access to the full values. [GH-183]
-* Squash is now supported with embedded fields that are struct pointers [GH-205]
-* Empty strings will convert to 0 for all numeric types when weakly decoding [GH-206]
-
-## 1.3.3
-
-* Decoding maps from maps creates a settable value for decode hooks [GH-203]
-
-## 1.3.2
-
-* Decode into interface type with a struct value is supported [GH-187]
-
-## 1.3.1
-
-* Squash should only squash embedded structs. [GH-194]
-
-## 1.3.0
-
-* Added `",omitempty"` support. This will ignore zero values in the source
- structure when encoding. [GH-145]
-
-## 1.2.3
-
-* Fix duplicate entries in Keys list with pointer values. [GH-185]
-
-## 1.2.2
-
-* Do not add unsettable (unexported) values to the unused metadata key
- or "remain" value. [GH-150]
-
-## 1.2.1
-
-* Go modules checksum mismatch fix
-
-## 1.2.0
-
-* Added support to capture unused values in a field using the `",remain"` value
- in the mapstructure tag. There is an example to showcase usage.
-* Added `DecoderConfig` option to always squash embedded structs
-* `json.Number` can decode into `uint` types
-* Empty slices are preserved and not replaced with nil slices
-* Fix panic that can occur in when decoding a map into a nil slice of structs
-* Improved package documentation for godoc
-
-## 1.1.2
-
-* Fix error when decode hook decodes interface implementation into interface
- type. [GH-140]
-
-## 1.1.1
-
-* Fix panic that can happen in `decodePtr`
-
-## 1.1.0
-
-* Added `StringToIPHookFunc` to convert `string` to `net.IP` and `net.IPNet` [GH-133]
-* Support struct to struct decoding [GH-137]
-* If source map value is nil, then destination map value is nil (instead of empty)
-* If source slice value is nil, then destination slice value is nil (instead of empty)
-* If source pointer is nil, then destination pointer is set to nil (instead of
- allocated zero value of type)
-
-## 1.0.0
-
-* Initial tagged stable release.
diff --git a/vendor/github.com/mitchellh/mapstructure/LICENSE b/vendor/github.com/mitchellh/mapstructure/LICENSE
deleted file mode 100644
index f9c841a51..000000000
--- a/vendor/github.com/mitchellh/mapstructure/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 Mitchell Hashimoto
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/vendor/github.com/mitchellh/mapstructure/README.md b/vendor/github.com/mitchellh/mapstructure/README.md
deleted file mode 100644
index 0018dc7d9..000000000
--- a/vendor/github.com/mitchellh/mapstructure/README.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# mapstructure [![Godoc](https://godoc.org/github.com/mitchellh/mapstructure?status.svg)](https://godoc.org/github.com/mitchellh/mapstructure)
-
-mapstructure is a Go library for decoding generic map values to structures
-and vice versa, while providing helpful error handling.
-
-This library is most useful when decoding values from some data stream (JSON,
-Gob, etc.) where you don't _quite_ know the structure of the underlying data
-until you read a part of it. You can therefore read a `map[string]interface{}`
-and use this library to decode it into the proper underlying native Go
-structure.
-
-## Installation
-
-Standard `go get`:
-
-```
-$ go get github.com/mitchellh/mapstructure
-```
-
-## Usage & Example
-
-For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/mapstructure).
-
-The `Decode` function has examples associated with it there.
-
-## But Why?!
-
-Go offers fantastic standard libraries for decoding formats such as JSON.
-The standard method is to have a struct pre-created, and populate that struct
-from the bytes of the encoded format. This is great, but the problem is if
-you have configuration or an encoding that changes slightly depending on
-specific fields. For example, consider this JSON:
-
-```json
-{
- "type": "person",
- "name": "Mitchell"
-}
-```
-
-Perhaps we can't populate a specific structure without first reading
-the "type" field from the JSON. We could always do two passes over the
-decoding of the JSON (reading the "type" first, and the rest later).
-However, it is much simpler to just decode this into a `map[string]interface{}`
-structure, read the "type" key, then use something like this library
-to decode it into the proper structure.
diff --git a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go
deleted file mode 100644
index 4d4bbc733..000000000
--- a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go
+++ /dev/null
@@ -1,257 +0,0 @@
-package mapstructure
-
-import (
- "encoding"
- "errors"
- "fmt"
- "net"
- "reflect"
- "strconv"
- "strings"
- "time"
-)
-
-// typedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns
-// it into the proper DecodeHookFunc type, such as DecodeHookFuncType.
-func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc {
- // Create variables here so we can reference them with the reflect pkg
- var f1 DecodeHookFuncType
- var f2 DecodeHookFuncKind
- var f3 DecodeHookFuncValue
-
- // Fill in the variables into this interface and the rest is done
- // automatically using the reflect package.
- potential := []interface{}{f1, f2, f3}
-
- v := reflect.ValueOf(h)
- vt := v.Type()
- for _, raw := range potential {
- pt := reflect.ValueOf(raw).Type()
- if vt.ConvertibleTo(pt) {
- return v.Convert(pt).Interface()
- }
- }
-
- return nil
-}
-
-// DecodeHookExec executes the given decode hook. This should be used
-// since it'll naturally degrade to the older backwards compatible DecodeHookFunc
-// that took reflect.Kind instead of reflect.Type.
-func DecodeHookExec(
- raw DecodeHookFunc,
- from reflect.Value, to reflect.Value) (interface{}, error) {
-
- switch f := typedDecodeHook(raw).(type) {
- case DecodeHookFuncType:
- return f(from.Type(), to.Type(), from.Interface())
- case DecodeHookFuncKind:
- return f(from.Kind(), to.Kind(), from.Interface())
- case DecodeHookFuncValue:
- return f(from, to)
- default:
- return nil, errors.New("invalid decode hook signature")
- }
-}
-
-// ComposeDecodeHookFunc creates a single DecodeHookFunc that
-// automatically composes multiple DecodeHookFuncs.
-//
-// The composed funcs are called in order, with the result of the
-// previous transformation.
-func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {
- return func(f reflect.Value, t reflect.Value) (interface{}, error) {
- var err error
- data := f.Interface()
-
- newFrom := f
- for _, f1 := range fs {
- data, err = DecodeHookExec(f1, newFrom, t)
- if err != nil {
- return nil, err
- }
- newFrom = reflect.ValueOf(data)
- }
-
- return data, nil
- }
-}
-
-// StringToSliceHookFunc returns a DecodeHookFunc that converts
-// string to []string by splitting on the given sep.
-func StringToSliceHookFunc(sep string) DecodeHookFunc {
- return func(
- f reflect.Kind,
- t reflect.Kind,
- data interface{}) (interface{}, error) {
- if f != reflect.String || t != reflect.Slice {
- return data, nil
- }
-
- raw := data.(string)
- if raw == "" {
- return []string{}, nil
- }
-
- return strings.Split(raw, sep), nil
- }
-}
-
-// StringToTimeDurationHookFunc returns a DecodeHookFunc that converts
-// strings to time.Duration.
-func StringToTimeDurationHookFunc() DecodeHookFunc {
- return func(
- f reflect.Type,
- t reflect.Type,
- data interface{}) (interface{}, error) {
- if f.Kind() != reflect.String {
- return data, nil
- }
- if t != reflect.TypeOf(time.Duration(5)) {
- return data, nil
- }
-
- // Convert it by parsing
- return time.ParseDuration(data.(string))
- }
-}
-
-// StringToIPHookFunc returns a DecodeHookFunc that converts
-// strings to net.IP
-func StringToIPHookFunc() DecodeHookFunc {
- return func(
- f reflect.Type,
- t reflect.Type,
- data interface{}) (interface{}, error) {
- if f.Kind() != reflect.String {
- return data, nil
- }
- if t != reflect.TypeOf(net.IP{}) {
- return data, nil
- }
-
- // Convert it by parsing
- ip := net.ParseIP(data.(string))
- if ip == nil {
- return net.IP{}, fmt.Errorf("failed parsing ip %v", data)
- }
-
- return ip, nil
- }
-}
-
-// StringToIPNetHookFunc returns a DecodeHookFunc that converts
-// strings to net.IPNet
-func StringToIPNetHookFunc() DecodeHookFunc {
- return func(
- f reflect.Type,
- t reflect.Type,
- data interface{}) (interface{}, error) {
- if f.Kind() != reflect.String {
- return data, nil
- }
- if t != reflect.TypeOf(net.IPNet{}) {
- return data, nil
- }
-
- // Convert it by parsing
- _, net, err := net.ParseCIDR(data.(string))
- return net, err
- }
-}
-
-// StringToTimeHookFunc returns a DecodeHookFunc that converts
-// strings to time.Time.
-func StringToTimeHookFunc(layout string) DecodeHookFunc {
- return func(
- f reflect.Type,
- t reflect.Type,
- data interface{}) (interface{}, error) {
- if f.Kind() != reflect.String {
- return data, nil
- }
- if t != reflect.TypeOf(time.Time{}) {
- return data, nil
- }
-
- // Convert it by parsing
- return time.Parse(layout, data.(string))
- }
-}
-
-// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to
-// the decoder.
-//
-// Note that this is significantly different from the WeaklyTypedInput option
-// of the DecoderConfig.
-func WeaklyTypedHook(
- f reflect.Kind,
- t reflect.Kind,
- data interface{}) (interface{}, error) {
- dataVal := reflect.ValueOf(data)
- switch t {
- case reflect.String:
- switch f {
- case reflect.Bool:
- if dataVal.Bool() {
- return "1", nil
- }
- return "0", nil
- case reflect.Float32:
- return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil
- case reflect.Int:
- return strconv.FormatInt(dataVal.Int(), 10), nil
- case reflect.Slice:
- dataType := dataVal.Type()
- elemKind := dataType.Elem().Kind()
- if elemKind == reflect.Uint8 {
- return string(dataVal.Interface().([]uint8)), nil
- }
- case reflect.Uint:
- return strconv.FormatUint(dataVal.Uint(), 10), nil
- }
- }
-
- return data, nil
-}
-
-func RecursiveStructToMapHookFunc() DecodeHookFunc {
- return func(f reflect.Value, t reflect.Value) (interface{}, error) {
- if f.Kind() != reflect.Struct {
- return f.Interface(), nil
- }
-
- var i interface{} = struct{}{}
- if t.Type() != reflect.TypeOf(&i).Elem() {
- return f.Interface(), nil
- }
-
- m := make(map[string]interface{})
- t.Set(reflect.ValueOf(m))
-
- return f.Interface(), nil
- }
-}
-
-// TextUnmarshallerHookFunc returns a DecodeHookFunc that applies
-// strings to the UnmarshalText function, when the target type
-// implements the encoding.TextUnmarshaler interface
-func TextUnmarshallerHookFunc() DecodeHookFuncType {
- return func(
- f reflect.Type,
- t reflect.Type,
- data interface{}) (interface{}, error) {
- if f.Kind() != reflect.String {
- return data, nil
- }
- result := reflect.New(t).Interface()
- unmarshaller, ok := result.(encoding.TextUnmarshaler)
- if !ok {
- return data, nil
- }
- if err := unmarshaller.UnmarshalText([]byte(data.(string))); err != nil {
- return nil, err
- }
- return result, nil
- }
-}
diff --git a/vendor/github.com/mitchellh/mapstructure/error.go b/vendor/github.com/mitchellh/mapstructure/error.go
deleted file mode 100644
index 47a99e5af..000000000
--- a/vendor/github.com/mitchellh/mapstructure/error.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package mapstructure
-
-import (
- "errors"
- "fmt"
- "sort"
- "strings"
-)
-
-// Error implements the error interface and can represents multiple
-// errors that occur in the course of a single decode.
-type Error struct {
- Errors []string
-}
-
-func (e *Error) Error() string {
- points := make([]string, len(e.Errors))
- for i, err := range e.Errors {
- points[i] = fmt.Sprintf("* %s", err)
- }
-
- sort.Strings(points)
- return fmt.Sprintf(
- "%d error(s) decoding:\n\n%s",
- len(e.Errors), strings.Join(points, "\n"))
-}
-
-// WrappedErrors implements the errwrap.Wrapper interface to make this
-// return value more useful with the errwrap and go-multierror libraries.
-func (e *Error) WrappedErrors() []error {
- if e == nil {
- return nil
- }
-
- result := make([]error, len(e.Errors))
- for i, e := range e.Errors {
- result[i] = errors.New(e)
- }
-
- return result
-}
-
-func appendErrors(errors []string, err error) []string {
- switch e := err.(type) {
- case *Error:
- return append(errors, e.Errors...)
- default:
- return append(errors, e.Error())
- }
-}
diff --git a/vendor/github.com/mitchellh/mapstructure/go.mod b/vendor/github.com/mitchellh/mapstructure/go.mod
deleted file mode 100644
index a03ae9730..000000000
--- a/vendor/github.com/mitchellh/mapstructure/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module github.com/mitchellh/mapstructure
-
-go 1.14
diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go
deleted file mode 100644
index 6b81b0067..000000000
--- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go
+++ /dev/null
@@ -1,1467 +0,0 @@
-// Package mapstructure exposes functionality to convert one arbitrary
-// Go type into another, typically to convert a map[string]interface{}
-// into a native Go structure.
-//
-// The Go structure can be arbitrarily complex, containing slices,
-// other structs, etc. and the decoder will properly decode nested
-// maps and so on into the proper structures in the native Go struct.
-// See the examples to see what the decoder is capable of.
-//
-// The simplest function to start with is Decode.
-//
-// Field Tags
-//
-// When decoding to a struct, mapstructure will use the field name by
-// default to perform the mapping. For example, if a struct has a field
-// "Username" then mapstructure will look for a key in the source value
-// of "username" (case insensitive).
-//
-// type User struct {
-// Username string
-// }
-//
-// You can change the behavior of mapstructure by using struct tags.
-// The default struct tag that mapstructure looks for is "mapstructure"
-// but you can customize it using DecoderConfig.
-//
-// Renaming Fields
-//
-// To rename the key that mapstructure looks for, use the "mapstructure"
-// tag and set a value directly. For example, to change the "username" example
-// above to "user":
-//
-// type User struct {
-// Username string `mapstructure:"user"`
-// }
-//
-// Embedded Structs and Squashing
-//
-// Embedded structs are treated as if they're another field with that name.
-// By default, the two structs below are equivalent when decoding with
-// mapstructure:
-//
-// type Person struct {
-// Name string
-// }
-//
-// type Friend struct {
-// Person
-// }
-//
-// type Friend struct {
-// Person Person
-// }
-//
-// This would require an input that looks like below:
-//
-// map[string]interface{}{
-// "person": map[string]interface{}{"name": "alice"},
-// }
-//
-// If your "person" value is NOT nested, then you can append ",squash" to
-// your tag value and mapstructure will treat it as if the embedded struct
-// were part of the struct directly. Example:
-//
-// type Friend struct {
-// Person `mapstructure:",squash"`
-// }
-//
-// Now the following input would be accepted:
-//
-// map[string]interface{}{
-// "name": "alice",
-// }
-//
-// When decoding from a struct to a map, the squash tag squashes the struct
-// fields into a single map. Using the example structs from above:
-//
-// Friend{Person: Person{Name: "alice"}}
-//
-// Will be decoded into a map:
-//
-// map[string]interface{}{
-// "name": "alice",
-// }
-//
-// DecoderConfig has a field that changes the behavior of mapstructure
-// to always squash embedded structs.
-//
-// Remainder Values
-//
-// If there are any unmapped keys in the source value, mapstructure by
-// default will silently ignore them. You can error by setting ErrorUnused
-// in DecoderConfig. If you're using Metadata you can also maintain a slice
-// of the unused keys.
-//
-// You can also use the ",remain" suffix on your tag to collect all unused
-// values in a map. The field with this tag MUST be a map type and should
-// probably be a "map[string]interface{}" or "map[interface{}]interface{}".
-// See example below:
-//
-// type Friend struct {
-// Name string
-// Other map[string]interface{} `mapstructure:",remain"`
-// }
-//
-// Given the input below, Other would be populated with the other
-// values that weren't used (everything but "name"):
-//
-// map[string]interface{}{
-// "name": "bob",
-// "address": "123 Maple St.",
-// }
-//
-// Omit Empty Values
-//
-// When decoding from a struct to any other value, you may use the
-// ",omitempty" suffix on your tag to omit that value if it equates to
-// the zero value. The zero value of all types is specified in the Go
-// specification.
-//
-// For example, the zero type of a numeric type is zero ("0"). If the struct
-// field value is zero and a numeric type, the field is empty, and it won't
-// be encoded into the destination type.
-//
-// type Source {
-// Age int `mapstructure:",omitempty"`
-// }
-//
-// Unexported fields
-//
-// Since unexported (private) struct fields cannot be set outside the package
-// where they are defined, the decoder will simply skip them.
-//
-// For this output type definition:
-//
-// type Exported struct {
-// private string // this unexported field will be skipped
-// Public string
-// }
-//
-// Using this map as input:
-//
-// map[string]interface{}{
-// "private": "I will be ignored",
-// "Public": "I made it through!",
-// }
-//
-// The following struct will be decoded:
-//
-// type Exported struct {
-// private: "" // field is left with an empty string (zero value)
-// Public: "I made it through!"
-// }
-//
-// Other Configuration
-//
-// mapstructure is highly configurable. See the DecoderConfig struct
-// for other features and options that are supported.
-package mapstructure
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "reflect"
- "sort"
- "strconv"
- "strings"
-)
-
-// DecodeHookFunc is the callback function that can be used for
-// data transformations. See "DecodeHook" in the DecoderConfig
-// struct.
-//
-// The type must be one of DecodeHookFuncType, DecodeHookFuncKind, or
-// DecodeHookFuncValue.
-// Values are a superset of Types (Values can return types), and Types are a
-// superset of Kinds (Types can return Kinds) and are generally a richer thing
-// to use, but Kinds are simpler if you only need those.
-//
-// The reason DecodeHookFunc is multi-typed is for backwards compatibility:
-// we started with Kinds and then realized Types were the better solution,
-// but have a promise to not break backwards compat so we now support
-// both.
-type DecodeHookFunc interface{}
-
-// DecodeHookFuncType is a DecodeHookFunc which has complete information about
-// the source and target types.
-type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error)
-
-// DecodeHookFuncKind is a DecodeHookFunc which knows only the Kinds of the
-// source and target types.
-type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error)
-
-// DecodeHookFuncValue is a DecodeHookFunc which has complete access to both the source and target
-// values.
-type DecodeHookFuncValue func(from reflect.Value, to reflect.Value) (interface{}, error)
-
-// DecoderConfig is the configuration that is used to create a new decoder
-// and allows customization of various aspects of decoding.
-type DecoderConfig struct {
- // DecodeHook, if set, will be called before any decoding and any
- // type conversion (if WeaklyTypedInput is on). This lets you modify
- // the values before they're set down onto the resulting struct. The
- // DecodeHook is called for every map and value in the input. This means
- // that if a struct has embedded fields with squash tags the decode hook
- // is called only once with all of the input data, not once for each
- // embedded struct.
- //
- // If an error is returned, the entire decode will fail with that error.
- DecodeHook DecodeHookFunc
-
- // If ErrorUnused is true, then it is an error for there to exist
- // keys in the original map that were unused in the decoding process
- // (extra keys).
- ErrorUnused bool
-
- // ZeroFields, if set to true, will zero fields before writing them.
- // For example, a map will be emptied before decoded values are put in
- // it. If this is false, a map will be merged.
- ZeroFields bool
-
- // If WeaklyTypedInput is true, the decoder will make the following
- // "weak" conversions:
- //
- // - bools to string (true = "1", false = "0")
- // - numbers to string (base 10)
- // - bools to int/uint (true = 1, false = 0)
- // - strings to int/uint (base implied by prefix)
- // - int to bool (true if value != 0)
- // - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F,
- // FALSE, false, False. Anything else is an error)
- // - empty array = empty map and vice versa
- // - negative numbers to overflowed uint values (base 10)
- // - slice of maps to a merged map
- // - single values are converted to slices if required. Each
- // element is weakly decoded. For example: "4" can become []int{4}
- // if the target type is an int slice.
- //
- WeaklyTypedInput bool
-
- // Squash will squash embedded structs. A squash tag may also be
- // added to an individual struct field using a tag. For example:
- //
- // type Parent struct {
- // Child `mapstructure:",squash"`
- // }
- Squash bool
-
- // Metadata is the struct that will contain extra metadata about
- // the decoding. If this is nil, then no metadata will be tracked.
- Metadata *Metadata
-
- // Result is a pointer to the struct that will contain the decoded
- // value.
- Result interface{}
-
- // The tag name that mapstructure reads for field names. This
- // defaults to "mapstructure"
- TagName string
-
- // MatchName is the function used to match the map key to the struct
- // field name or tag. Defaults to `strings.EqualFold`. This can be used
- // to implement case-sensitive tag values, support snake casing, etc.
- MatchName func(mapKey, fieldName string) bool
-}
-
-// A Decoder takes a raw interface value and turns it into structured
-// data, keeping track of rich error information along the way in case
-// anything goes wrong. Unlike the basic top-level Decode method, you can
-// more finely control how the Decoder behaves using the DecoderConfig
-// structure. The top-level Decode method is just a convenience that sets
-// up the most basic Decoder.
-type Decoder struct {
- config *DecoderConfig
-}
-
-// Metadata contains information about decoding a structure that
-// is tedious or difficult to get otherwise.
-type Metadata struct {
- // Keys are the keys of the structure which were successfully decoded
- Keys []string
-
- // Unused is a slice of keys that were found in the raw value but
- // weren't decoded since there was no matching field in the result interface
- Unused []string
-}
-
-// Decode takes an input structure and uses reflection to translate it to
-// the output structure. output must be a pointer to a map or struct.
-func Decode(input interface{}, output interface{}) error {
- config := &DecoderConfig{
- Metadata: nil,
- Result: output,
- }
-
- decoder, err := NewDecoder(config)
- if err != nil {
- return err
- }
-
- return decoder.Decode(input)
-}
-
-// WeakDecode is the same as Decode but is shorthand to enable
-// WeaklyTypedInput. See DecoderConfig for more info.
-func WeakDecode(input, output interface{}) error {
- config := &DecoderConfig{
- Metadata: nil,
- Result: output,
- WeaklyTypedInput: true,
- }
-
- decoder, err := NewDecoder(config)
- if err != nil {
- return err
- }
-
- return decoder.Decode(input)
-}
-
-// DecodeMetadata is the same as Decode, but is shorthand to
-// enable metadata collection. See DecoderConfig for more info.
-func DecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error {
- config := &DecoderConfig{
- Metadata: metadata,
- Result: output,
- }
-
- decoder, err := NewDecoder(config)
- if err != nil {
- return err
- }
-
- return decoder.Decode(input)
-}
-
-// WeakDecodeMetadata is the same as Decode, but is shorthand to
-// enable both WeaklyTypedInput and metadata collection. See
-// DecoderConfig for more info.
-func WeakDecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error {
- config := &DecoderConfig{
- Metadata: metadata,
- Result: output,
- WeaklyTypedInput: true,
- }
-
- decoder, err := NewDecoder(config)
- if err != nil {
- return err
- }
-
- return decoder.Decode(input)
-}
-
-// NewDecoder returns a new decoder for the given configuration. Once
-// a decoder has been returned, the same configuration must not be used
-// again.
-func NewDecoder(config *DecoderConfig) (*Decoder, error) {
- val := reflect.ValueOf(config.Result)
- if val.Kind() != reflect.Ptr {
- return nil, errors.New("result must be a pointer")
- }
-
- val = val.Elem()
- if !val.CanAddr() {
- return nil, errors.New("result must be addressable (a pointer)")
- }
-
- if config.Metadata != nil {
- if config.Metadata.Keys == nil {
- config.Metadata.Keys = make([]string, 0)
- }
-
- if config.Metadata.Unused == nil {
- config.Metadata.Unused = make([]string, 0)
- }
- }
-
- if config.TagName == "" {
- config.TagName = "mapstructure"
- }
-
- if config.MatchName == nil {
- config.MatchName = strings.EqualFold
- }
-
- result := &Decoder{
- config: config,
- }
-
- return result, nil
-}
-
-// Decode decodes the given raw interface to the target pointer specified
-// by the configuration.
-func (d *Decoder) Decode(input interface{}) error {
- return d.decode("", input, reflect.ValueOf(d.config.Result).Elem())
-}
-
-// Decodes an unknown data type into a specific reflection value.
-func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error {
- var inputVal reflect.Value
- if input != nil {
- inputVal = reflect.ValueOf(input)
-
- // We need to check here if input is a typed nil. Typed nils won't
- // match the "input == nil" below so we check that here.
- if inputVal.Kind() == reflect.Ptr && inputVal.IsNil() {
- input = nil
- }
- }
-
- if input == nil {
- // If the data is nil, then we don't set anything, unless ZeroFields is set
- // to true.
- if d.config.ZeroFields {
- outVal.Set(reflect.Zero(outVal.Type()))
-
- if d.config.Metadata != nil && name != "" {
- d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
- }
- }
- return nil
- }
-
- if !inputVal.IsValid() {
- // If the input value is invalid, then we just set the value
- // to be the zero value.
- outVal.Set(reflect.Zero(outVal.Type()))
- if d.config.Metadata != nil && name != "" {
- d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
- }
- return nil
- }
-
- if d.config.DecodeHook != nil {
- // We have a DecodeHook, so let's pre-process the input.
- var err error
- input, err = DecodeHookExec(d.config.DecodeHook, inputVal, outVal)
- if err != nil {
- return fmt.Errorf("error decoding '%s': %s", name, err)
- }
- }
-
- var err error
- outputKind := getKind(outVal)
- addMetaKey := true
- switch outputKind {
- case reflect.Bool:
- err = d.decodeBool(name, input, outVal)
- case reflect.Interface:
- err = d.decodeBasic(name, input, outVal)
- case reflect.String:
- err = d.decodeString(name, input, outVal)
- case reflect.Int:
- err = d.decodeInt(name, input, outVal)
- case reflect.Uint:
- err = d.decodeUint(name, input, outVal)
- case reflect.Float32:
- err = d.decodeFloat(name, input, outVal)
- case reflect.Struct:
- err = d.decodeStruct(name, input, outVal)
- case reflect.Map:
- err = d.decodeMap(name, input, outVal)
- case reflect.Ptr:
- addMetaKey, err = d.decodePtr(name, input, outVal)
- case reflect.Slice:
- err = d.decodeSlice(name, input, outVal)
- case reflect.Array:
- err = d.decodeArray(name, input, outVal)
- case reflect.Func:
- err = d.decodeFunc(name, input, outVal)
- default:
- // If we reached this point then we weren't able to decode it
- return fmt.Errorf("%s: unsupported type: %s", name, outputKind)
- }
-
- // If we reached here, then we successfully decoded SOMETHING, so
- // mark the key as used if we're tracking metainput.
- if addMetaKey && d.config.Metadata != nil && name != "" {
- d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
- }
-
- return err
-}
-
-// This decodes a basic type (bool, int, string, etc.) and sets the
-// value to "data" of that type.
-func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
- if val.IsValid() && val.Elem().IsValid() {
- elem := val.Elem()
-
- // If we can't address this element, then its not writable. Instead,
- // we make a copy of the value (which is a pointer and therefore
- // writable), decode into that, and replace the whole value.
- copied := false
- if !elem.CanAddr() {
- copied = true
-
- // Make *T
- copy := reflect.New(elem.Type())
-
- // *T = elem
- copy.Elem().Set(elem)
-
- // Set elem so we decode into it
- elem = copy
- }
-
- // Decode. If we have an error then return. We also return right
- // away if we're not a copy because that means we decoded directly.
- if err := d.decode(name, data, elem); err != nil || !copied {
- return err
- }
-
- // If we're a copy, we need to set te final result
- val.Set(elem.Elem())
- return nil
- }
-
- dataVal := reflect.ValueOf(data)
-
- // If the input data is a pointer, and the assigned type is the dereference
- // of that exact pointer, then indirect it so that we can assign it.
- // Example: *string to string
- if dataVal.Kind() == reflect.Ptr && dataVal.Type().Elem() == val.Type() {
- dataVal = reflect.Indirect(dataVal)
- }
-
- if !dataVal.IsValid() {
- dataVal = reflect.Zero(val.Type())
- }
-
- dataValType := dataVal.Type()
- if !dataValType.AssignableTo(val.Type()) {
- return fmt.Errorf(
- "'%s' expected type '%s', got '%s'",
- name, val.Type(), dataValType)
- }
-
- val.Set(dataVal)
- return nil
-}
-
-func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataKind := getKind(dataVal)
-
- converted := true
- switch {
- case dataKind == reflect.String:
- val.SetString(dataVal.String())
- case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
- if dataVal.Bool() {
- val.SetString("1")
- } else {
- val.SetString("0")
- }
- case dataKind == reflect.Int && d.config.WeaklyTypedInput:
- val.SetString(strconv.FormatInt(dataVal.Int(), 10))
- case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
- val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
- case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
- val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))
- case dataKind == reflect.Slice && d.config.WeaklyTypedInput,
- dataKind == reflect.Array && d.config.WeaklyTypedInput:
- dataType := dataVal.Type()
- elemKind := dataType.Elem().Kind()
- switch elemKind {
- case reflect.Uint8:
- var uints []uint8
- if dataKind == reflect.Array {
- uints = make([]uint8, dataVal.Len(), dataVal.Len())
- for i := range uints {
- uints[i] = dataVal.Index(i).Interface().(uint8)
- }
- } else {
- uints = dataVal.Interface().([]uint8)
- }
- val.SetString(string(uints))
- default:
- converted = false
- }
- default:
- converted = false
- }
-
- if !converted {
- return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
- }
-
- return nil
-}
-
-func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataKind := getKind(dataVal)
- dataType := dataVal.Type()
-
- switch {
- case dataKind == reflect.Int:
- val.SetInt(dataVal.Int())
- case dataKind == reflect.Uint:
- val.SetInt(int64(dataVal.Uint()))
- case dataKind == reflect.Float32:
- val.SetInt(int64(dataVal.Float()))
- case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
- if dataVal.Bool() {
- val.SetInt(1)
- } else {
- val.SetInt(0)
- }
- case dataKind == reflect.String && d.config.WeaklyTypedInput:
- str := dataVal.String()
- if str == "" {
- str = "0"
- }
-
- i, err := strconv.ParseInt(str, 0, val.Type().Bits())
- if err == nil {
- val.SetInt(i)
- } else {
- return fmt.Errorf("cannot parse '%s' as int: %s", name, err)
- }
- case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
- jn := data.(json.Number)
- i, err := jn.Int64()
- if err != nil {
- return fmt.Errorf(
- "error decoding json.Number into %s: %s", name, err)
- }
- val.SetInt(i)
- default:
- return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
- }
-
- return nil
-}
-
-func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataKind := getKind(dataVal)
- dataType := dataVal.Type()
-
- switch {
- case dataKind == reflect.Int:
- i := dataVal.Int()
- if i < 0 && !d.config.WeaklyTypedInput {
- return fmt.Errorf("cannot parse '%s', %d overflows uint",
- name, i)
- }
- val.SetUint(uint64(i))
- case dataKind == reflect.Uint:
- val.SetUint(dataVal.Uint())
- case dataKind == reflect.Float32:
- f := dataVal.Float()
- if f < 0 && !d.config.WeaklyTypedInput {
- return fmt.Errorf("cannot parse '%s', %f overflows uint",
- name, f)
- }
- val.SetUint(uint64(f))
- case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
- if dataVal.Bool() {
- val.SetUint(1)
- } else {
- val.SetUint(0)
- }
- case dataKind == reflect.String && d.config.WeaklyTypedInput:
- str := dataVal.String()
- if str == "" {
- str = "0"
- }
-
- i, err := strconv.ParseUint(str, 0, val.Type().Bits())
- if err == nil {
- val.SetUint(i)
- } else {
- return fmt.Errorf("cannot parse '%s' as uint: %s", name, err)
- }
- case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
- jn := data.(json.Number)
- i, err := strconv.ParseUint(string(jn), 0, 64)
- if err != nil {
- return fmt.Errorf(
- "error decoding json.Number into %s: %s", name, err)
- }
- val.SetUint(i)
- default:
- return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
- }
-
- return nil
-}
-
-func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataKind := getKind(dataVal)
-
- switch {
- case dataKind == reflect.Bool:
- val.SetBool(dataVal.Bool())
- case dataKind == reflect.Int && d.config.WeaklyTypedInput:
- val.SetBool(dataVal.Int() != 0)
- case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
- val.SetBool(dataVal.Uint() != 0)
- case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
- val.SetBool(dataVal.Float() != 0)
- case dataKind == reflect.String && d.config.WeaklyTypedInput:
- b, err := strconv.ParseBool(dataVal.String())
- if err == nil {
- val.SetBool(b)
- } else if dataVal.String() == "" {
- val.SetBool(false)
- } else {
- return fmt.Errorf("cannot parse '%s' as bool: %s", name, err)
- }
- default:
- return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
- }
-
- return nil
-}
-
-func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataKind := getKind(dataVal)
- dataType := dataVal.Type()
-
- switch {
- case dataKind == reflect.Int:
- val.SetFloat(float64(dataVal.Int()))
- case dataKind == reflect.Uint:
- val.SetFloat(float64(dataVal.Uint()))
- case dataKind == reflect.Float32:
- val.SetFloat(dataVal.Float())
- case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
- if dataVal.Bool() {
- val.SetFloat(1)
- } else {
- val.SetFloat(0)
- }
- case dataKind == reflect.String && d.config.WeaklyTypedInput:
- str := dataVal.String()
- if str == "" {
- str = "0"
- }
-
- f, err := strconv.ParseFloat(str, val.Type().Bits())
- if err == nil {
- val.SetFloat(f)
- } else {
- return fmt.Errorf("cannot parse '%s' as float: %s", name, err)
- }
- case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
- jn := data.(json.Number)
- i, err := jn.Float64()
- if err != nil {
- return fmt.Errorf(
- "error decoding json.Number into %s: %s", name, err)
- }
- val.SetFloat(i)
- default:
- return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
- }
-
- return nil
-}
-
-func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {
- valType := val.Type()
- valKeyType := valType.Key()
- valElemType := valType.Elem()
-
- // By default we overwrite keys in the current map
- valMap := val
-
- // If the map is nil or we're purposely zeroing fields, make a new map
- if valMap.IsNil() || d.config.ZeroFields {
- // Make a new map to hold our result
- mapType := reflect.MapOf(valKeyType, valElemType)
- valMap = reflect.MakeMap(mapType)
- }
-
- // Check input type and based on the input type jump to the proper func
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- switch dataVal.Kind() {
- case reflect.Map:
- return d.decodeMapFromMap(name, dataVal, val, valMap)
-
- case reflect.Struct:
- return d.decodeMapFromStruct(name, dataVal, val, valMap)
-
- case reflect.Array, reflect.Slice:
- if d.config.WeaklyTypedInput {
- return d.decodeMapFromSlice(name, dataVal, val, valMap)
- }
-
- fallthrough
-
- default:
- return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
- }
-}
-
-func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
- // Special case for BC reasons (covered by tests)
- if dataVal.Len() == 0 {
- val.Set(valMap)
- return nil
- }
-
- for i := 0; i < dataVal.Len(); i++ {
- err := d.decode(
- name+"["+strconv.Itoa(i)+"]",
- dataVal.Index(i).Interface(), val)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
- valType := val.Type()
- valKeyType := valType.Key()
- valElemType := valType.Elem()
-
- // Accumulate errors
- errors := make([]string, 0)
-
- // If the input data is empty, then we just match what the input data is.
- if dataVal.Len() == 0 {
- if dataVal.IsNil() {
- if !val.IsNil() {
- val.Set(dataVal)
- }
- } else {
- // Set to empty allocated value
- val.Set(valMap)
- }
-
- return nil
- }
-
- for _, k := range dataVal.MapKeys() {
- fieldName := name + "[" + k.String() + "]"
-
- // First decode the key into the proper type
- currentKey := reflect.Indirect(reflect.New(valKeyType))
- if err := d.decode(fieldName, k.Interface(), currentKey); err != nil {
- errors = appendErrors(errors, err)
- continue
- }
-
- // Next decode the data into the proper type
- v := dataVal.MapIndex(k).Interface()
- currentVal := reflect.Indirect(reflect.New(valElemType))
- if err := d.decode(fieldName, v, currentVal); err != nil {
- errors = appendErrors(errors, err)
- continue
- }
-
- valMap.SetMapIndex(currentKey, currentVal)
- }
-
- // Set the built up map to the value
- val.Set(valMap)
-
- // If we had errors, return those
- if len(errors) > 0 {
- return &Error{errors}
- }
-
- return nil
-}
-
-func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {
- typ := dataVal.Type()
- for i := 0; i < typ.NumField(); i++ {
- // Get the StructField first since this is a cheap operation. If the
- // field is unexported, then ignore it.
- f := typ.Field(i)
- if f.PkgPath != "" {
- continue
- }
-
- // Next get the actual value of this field and verify it is assignable
- // to the map value.
- v := dataVal.Field(i)
- if !v.Type().AssignableTo(valMap.Type().Elem()) {
- return fmt.Errorf("cannot assign type '%s' to map value field of type '%s'", v.Type(), valMap.Type().Elem())
- }
-
- tagValue := f.Tag.Get(d.config.TagName)
- keyName := f.Name
-
- // If Squash is set in the config, we squash the field down.
- squash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous
-
- // Determine the name of the key in the map
- if index := strings.Index(tagValue, ","); index != -1 {
- if tagValue[:index] == "-" {
- continue
- }
- // If "omitempty" is specified in the tag, it ignores empty values.
- if strings.Index(tagValue[index+1:], "omitempty") != -1 && isEmptyValue(v) {
- continue
- }
-
- // If "squash" is specified in the tag, we squash the field down.
- squash = !squash && strings.Index(tagValue[index+1:], "squash") != -1
- if squash {
- // When squashing, the embedded type can be a pointer to a struct.
- if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct {
- v = v.Elem()
- }
-
- // The final type must be a struct
- if v.Kind() != reflect.Struct {
- return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
- }
- }
- keyName = tagValue[:index]
- } else if len(tagValue) > 0 {
- if tagValue == "-" {
- continue
- }
- keyName = tagValue
- }
-
- switch v.Kind() {
- // this is an embedded struct, so handle it differently
- case reflect.Struct:
- x := reflect.New(v.Type())
- x.Elem().Set(v)
-
- vType := valMap.Type()
- vKeyType := vType.Key()
- vElemType := vType.Elem()
- mType := reflect.MapOf(vKeyType, vElemType)
- vMap := reflect.MakeMap(mType)
-
- // Creating a pointer to a map so that other methods can completely
- // overwrite the map if need be (looking at you decodeMapFromMap). The
- // indirection allows the underlying map to be settable (CanSet() == true)
- // where as reflect.MakeMap returns an unsettable map.
- addrVal := reflect.New(vMap.Type())
- reflect.Indirect(addrVal).Set(vMap)
-
- err := d.decode(keyName, x.Interface(), reflect.Indirect(addrVal))
- if err != nil {
- return err
- }
-
- // the underlying map may have been completely overwritten so pull
- // it indirectly out of the enclosing value.
- vMap = reflect.Indirect(addrVal)
-
- if squash {
- for _, k := range vMap.MapKeys() {
- valMap.SetMapIndex(k, vMap.MapIndex(k))
- }
- } else {
- valMap.SetMapIndex(reflect.ValueOf(keyName), vMap)
- }
-
- default:
- valMap.SetMapIndex(reflect.ValueOf(keyName), v)
- }
- }
-
- if val.CanAddr() {
- val.Set(valMap)
- }
-
- return nil
-}
-
-func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) (bool, error) {
- // If the input data is nil, then we want to just set the output
- // pointer to be nil as well.
- isNil := data == nil
- if !isNil {
- switch v := reflect.Indirect(reflect.ValueOf(data)); v.Kind() {
- case reflect.Chan,
- reflect.Func,
- reflect.Interface,
- reflect.Map,
- reflect.Ptr,
- reflect.Slice:
- isNil = v.IsNil()
- }
- }
- if isNil {
- if !val.IsNil() && val.CanSet() {
- nilValue := reflect.New(val.Type()).Elem()
- val.Set(nilValue)
- }
-
- return true, nil
- }
-
- // Create an element of the concrete (non pointer) type and decode
- // into that. Then set the value of the pointer to this type.
- valType := val.Type()
- valElemType := valType.Elem()
- if val.CanSet() {
- realVal := val
- if realVal.IsNil() || d.config.ZeroFields {
- realVal = reflect.New(valElemType)
- }
-
- if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
- return false, err
- }
-
- val.Set(realVal)
- } else {
- if err := d.decode(name, data, reflect.Indirect(val)); err != nil {
- return false, err
- }
- }
- return false, nil
-}
-
-func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {
- // Create an element of the concrete (non pointer) type and decode
- // into that. Then set the value of the pointer to this type.
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- if val.Type() != dataVal.Type() {
- return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
- }
- val.Set(dataVal)
- return nil
-}
-
-func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataValKind := dataVal.Kind()
- valType := val.Type()
- valElemType := valType.Elem()
- sliceType := reflect.SliceOf(valElemType)
-
- // If we have a non array/slice type then we first attempt to convert.
- if dataValKind != reflect.Array && dataValKind != reflect.Slice {
- if d.config.WeaklyTypedInput {
- switch {
- // Slice and array we use the normal logic
- case dataValKind == reflect.Slice, dataValKind == reflect.Array:
- break
-
- // Empty maps turn into empty slices
- case dataValKind == reflect.Map:
- if dataVal.Len() == 0 {
- val.Set(reflect.MakeSlice(sliceType, 0, 0))
- return nil
- }
- // Create slice of maps of other sizes
- return d.decodeSlice(name, []interface{}{data}, val)
-
- case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8:
- return d.decodeSlice(name, []byte(dataVal.String()), val)
-
- // All other types we try to convert to the slice type
- // and "lift" it into it. i.e. a string becomes a string slice.
- default:
- // Just re-try this function with data as a slice.
- return d.decodeSlice(name, []interface{}{data}, val)
- }
- }
-
- return fmt.Errorf(
- "'%s': source data must be an array or slice, got %s", name, dataValKind)
- }
-
- // If the input value is nil, then don't allocate since empty != nil
- if dataVal.IsNil() {
- return nil
- }
-
- valSlice := val
- if valSlice.IsNil() || d.config.ZeroFields {
- // Make a new slice to hold our result, same size as the original data.
- valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
- }
-
- // Accumulate any errors
- errors := make([]string, 0)
-
- for i := 0; i < dataVal.Len(); i++ {
- currentData := dataVal.Index(i).Interface()
- for valSlice.Len() <= i {
- valSlice = reflect.Append(valSlice, reflect.Zero(valElemType))
- }
- currentField := valSlice.Index(i)
-
- fieldName := name + "[" + strconv.Itoa(i) + "]"
- if err := d.decode(fieldName, currentData, currentField); err != nil {
- errors = appendErrors(errors, err)
- }
- }
-
- // Finally, set the value to the slice we built up
- val.Set(valSlice)
-
- // If there were errors, we return those
- if len(errors) > 0 {
- return &Error{errors}
- }
-
- return nil
-}
-
-func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
- dataValKind := dataVal.Kind()
- valType := val.Type()
- valElemType := valType.Elem()
- arrayType := reflect.ArrayOf(valType.Len(), valElemType)
-
- valArray := val
-
- if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields {
- // Check input type
- if dataValKind != reflect.Array && dataValKind != reflect.Slice {
- if d.config.WeaklyTypedInput {
- switch {
- // Empty maps turn into empty arrays
- case dataValKind == reflect.Map:
- if dataVal.Len() == 0 {
- val.Set(reflect.Zero(arrayType))
- return nil
- }
-
- // All other types we try to convert to the array type
- // and "lift" it into it. i.e. a string becomes a string array.
- default:
- // Just re-try this function with data as a slice.
- return d.decodeArray(name, []interface{}{data}, val)
- }
- }
-
- return fmt.Errorf(
- "'%s': source data must be an array or slice, got %s", name, dataValKind)
-
- }
- if dataVal.Len() > arrayType.Len() {
- return fmt.Errorf(
- "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len())
-
- }
-
- // Make a new array to hold our result, same size as the original data.
- valArray = reflect.New(arrayType).Elem()
- }
-
- // Accumulate any errors
- errors := make([]string, 0)
-
- for i := 0; i < dataVal.Len(); i++ {
- currentData := dataVal.Index(i).Interface()
- currentField := valArray.Index(i)
-
- fieldName := name + "[" + strconv.Itoa(i) + "]"
- if err := d.decode(fieldName, currentData, currentField); err != nil {
- errors = appendErrors(errors, err)
- }
- }
-
- // Finally, set the value to the array we built up
- val.Set(valArray)
-
- // If there were errors, we return those
- if len(errors) > 0 {
- return &Error{errors}
- }
-
- return nil
-}
-
-func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {
- dataVal := reflect.Indirect(reflect.ValueOf(data))
-
- // If the type of the value to write to and the data match directly,
- // then we just set it directly instead of recursing into the structure.
- if dataVal.Type() == val.Type() {
- val.Set(dataVal)
- return nil
- }
-
- dataValKind := dataVal.Kind()
- switch dataValKind {
- case reflect.Map:
- return d.decodeStructFromMap(name, dataVal, val)
-
- case reflect.Struct:
- // Not the most efficient way to do this but we can optimize later if
- // we want to. To convert from struct to struct we go to map first
- // as an intermediary.
-
- // Make a new map to hold our result
- mapType := reflect.TypeOf((map[string]interface{})(nil))
- mval := reflect.MakeMap(mapType)
-
- // Creating a pointer to a map so that other methods can completely
- // overwrite the map if need be (looking at you decodeMapFromMap). The
- // indirection allows the underlying map to be settable (CanSet() == true)
- // where as reflect.MakeMap returns an unsettable map.
- addrVal := reflect.New(mval.Type())
-
- reflect.Indirect(addrVal).Set(mval)
- if err := d.decodeMapFromStruct(name, dataVal, reflect.Indirect(addrVal), mval); err != nil {
- return err
- }
-
- result := d.decodeStructFromMap(name, reflect.Indirect(addrVal), val)
- return result
-
- default:
- return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
- }
-}
-
-func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error {
- dataValType := dataVal.Type()
- if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface {
- return fmt.Errorf(
- "'%s' needs a map with string keys, has '%s' keys",
- name, dataValType.Key().Kind())
- }
-
- dataValKeys := make(map[reflect.Value]struct{})
- dataValKeysUnused := make(map[interface{}]struct{})
- for _, dataValKey := range dataVal.MapKeys() {
- dataValKeys[dataValKey] = struct{}{}
- dataValKeysUnused[dataValKey.Interface()] = struct{}{}
- }
-
- errors := make([]string, 0)
-
- // This slice will keep track of all the structs we'll be decoding.
- // There can be more than one struct if there are embedded structs
- // that are squashed.
- structs := make([]reflect.Value, 1, 5)
- structs[0] = val
-
- // Compile the list of all the fields that we're going to be decoding
- // from all the structs.
- type field struct {
- field reflect.StructField
- val reflect.Value
- }
-
- // remainField is set to a valid field set with the "remain" tag if
- // we are keeping track of remaining values.
- var remainField *field
-
- fields := []field{}
- for len(structs) > 0 {
- structVal := structs[0]
- structs = structs[1:]
-
- structType := structVal.Type()
-
- for i := 0; i < structType.NumField(); i++ {
- fieldType := structType.Field(i)
- fieldVal := structVal.Field(i)
- if fieldVal.Kind() == reflect.Ptr && fieldVal.Elem().Kind() == reflect.Struct {
- // Handle embedded struct pointers as embedded structs.
- fieldVal = fieldVal.Elem()
- }
-
- // If "squash" is specified in the tag, we squash the field down.
- squash := d.config.Squash && fieldVal.Kind() == reflect.Struct && fieldType.Anonymous
- remain := false
-
- // We always parse the tags cause we're looking for other tags too
- tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
- for _, tag := range tagParts[1:] {
- if tag == "squash" {
- squash = true
- break
- }
-
- if tag == "remain" {
- remain = true
- break
- }
- }
-
- if squash {
- if fieldVal.Kind() != reflect.Struct {
- errors = appendErrors(errors,
- fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldVal.Kind()))
- } else {
- structs = append(structs, fieldVal)
- }
- continue
- }
-
- // Build our field
- if remain {
- remainField = &field{fieldType, fieldVal}
- } else {
- // Normal struct field, store it away
- fields = append(fields, field{fieldType, fieldVal})
- }
- }
- }
-
- // for fieldType, field := range fields {
- for _, f := range fields {
- field, fieldValue := f.field, f.val
- fieldName := field.Name
-
- tagValue := field.Tag.Get(d.config.TagName)
- tagValue = strings.SplitN(tagValue, ",", 2)[0]
- if tagValue != "" {
- fieldName = tagValue
- }
-
- rawMapKey := reflect.ValueOf(fieldName)
- rawMapVal := dataVal.MapIndex(rawMapKey)
- if !rawMapVal.IsValid() {
- // Do a slower search by iterating over each key and
- // doing case-insensitive search.
- for dataValKey := range dataValKeys {
- mK, ok := dataValKey.Interface().(string)
- if !ok {
- // Not a string key
- continue
- }
-
- if d.config.MatchName(mK, fieldName) {
- rawMapKey = dataValKey
- rawMapVal = dataVal.MapIndex(dataValKey)
- break
- }
- }
-
- if !rawMapVal.IsValid() {
- // There was no matching key in the map for the value in
- // the struct. Just ignore.
- continue
- }
- }
-
- if !fieldValue.IsValid() {
- // This should never happen
- panic("field is not valid")
- }
-
- // If we can't set the field, then it is unexported or something,
- // and we just continue onwards.
- if !fieldValue.CanSet() {
- continue
- }
-
- // Delete the key we're using from the unused map so we stop tracking
- delete(dataValKeysUnused, rawMapKey.Interface())
-
- // If the name is empty string, then we're at the root, and we
- // don't dot-join the fields.
- if name != "" {
- fieldName = name + "." + fieldName
- }
-
- if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil {
- errors = appendErrors(errors, err)
- }
- }
-
- // If we have a "remain"-tagged field and we have unused keys then
- // we put the unused keys directly into the remain field.
- if remainField != nil && len(dataValKeysUnused) > 0 {
- // Build a map of only the unused values
- remain := map[interface{}]interface{}{}
- for key := range dataValKeysUnused {
- remain[key] = dataVal.MapIndex(reflect.ValueOf(key)).Interface()
- }
-
- // Decode it as-if we were just decoding this map onto our map.
- if err := d.decodeMap(name, remain, remainField.val); err != nil {
- errors = appendErrors(errors, err)
- }
-
- // Set the map to nil so we have none so that the next check will
- // not error (ErrorUnused)
- dataValKeysUnused = nil
- }
-
- if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
- keys := make([]string, 0, len(dataValKeysUnused))
- for rawKey := range dataValKeysUnused {
- keys = append(keys, rawKey.(string))
- }
- sort.Strings(keys)
-
- err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", "))
- errors = appendErrors(errors, err)
- }
-
- if len(errors) > 0 {
- return &Error{errors}
- }
-
- // Add the unused keys to the list of unused keys if we're tracking metadata
- if d.config.Metadata != nil {
- for rawKey := range dataValKeysUnused {
- key := rawKey.(string)
- if name != "" {
- key = name + "." + key
- }
-
- d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
- }
- }
-
- return nil
-}
-
-func isEmptyValue(v reflect.Value) bool {
- switch getKind(v) {
- case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
- return v.Len() == 0
- case reflect.Bool:
- return !v.Bool()
- 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 v.Float() == 0
- case reflect.Interface, reflect.Ptr:
- return v.IsNil()
- }
- return false
-}
-
-func getKind(val reflect.Value) reflect.Kind {
- kind := val.Kind()
-
- switch {
- case kind >= reflect.Int && kind <= reflect.Int64:
- return reflect.Int
- case kind >= reflect.Uint && kind <= reflect.Uint64:
- return reflect.Uint
- case kind >= reflect.Float32 && kind <= reflect.Float64:
- return reflect.Float32
- default:
- return kind
- }
-}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
deleted file mode 100644
index a4d1919a9..000000000
--- a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2011 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 terminal provides support functions for dealing with terminals, as
-// commonly found on UNIX systems.
-//
-// Deprecated: this package moved to golang.org/x/term.
-package terminal
-
-import (
- "io"
-
- "golang.org/x/term"
-)
-
-// EscapeCodes contains escape sequences that can be written to the terminal in
-// order to achieve different styles of text.
-type EscapeCodes = term.EscapeCodes
-
-// Terminal contains the state for running a VT100 terminal that is capable of
-// reading lines of input.
-type Terminal = term.Terminal
-
-// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
-// a local terminal, that terminal must first have been put into raw mode.
-// prompt is a string that is written at the start of each input line (i.e.
-// "> ").
-func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
- return term.NewTerminal(c, prompt)
-}
-
-// ErrPasteIndicator may be returned from ReadLine as the error, in addition
-// to valid line data. It indicates that bracketed paste mode is enabled and
-// that the returned line consists only of pasted data. Programs may wish to
-// interpret pasted data more literally than typed data.
-var ErrPasteIndicator = term.ErrPasteIndicator
-
-// State contains the state of a terminal.
-type State = term.State
-
-// IsTerminal returns whether the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
- return term.IsTerminal(fd)
-}
-
-// ReadPassword reads a line of input from a terminal without local echo. This
-// is commonly used for inputting passwords and other sensitive data. The slice
-// returned does not include the \n.
-func ReadPassword(fd int) ([]byte, error) {
- return term.ReadPassword(fd)
-}
-
-// MakeRaw puts the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd int) (*State, error) {
- return term.MakeRaw(fd)
-}
-
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func Restore(fd int, oldState *State) error {
- return term.Restore(fd, oldState)
-}
-
-// GetState returns the current state of a terminal which may be useful to
-// restore the terminal after a signal.
-func GetState(fd int) (*State, error) {
- return term.GetState(fd)
-}
-
-// GetSize returns the dimensions of the given terminal.
-func GetSize(fd int) (width, height int, err error) {
- return term.GetSize(fd)
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 8150ab970..ca4f53bf6 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -109,7 +109,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.47.5-0.20220421072908-49f1a40067b2
+# github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb
## explicit
github.com/containers/common/libimage
github.com/containers/common/libimage/manifests
@@ -153,7 +153,7 @@ github.com/containers/common/version
# github.com/containers/conmon v2.0.20+incompatible
## explicit
github.com/containers/conmon/runner/config
-# github.com/containers/image/v5 v5.21.1-0.20220405081457-d1b64686e1d0
+# github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c
## explicit
github.com/containers/image/v5/copy
github.com/containers/image/v5/directory
@@ -233,7 +233,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.39.1-0.20220414183333-eea4e0f5f1f9
+# github.com/containers/storage v1.39.1-0.20220421071128-4899f8265d63
## explicit
github.com/containers/storage
github.com/containers/storage/drivers
@@ -475,8 +475,6 @@ github.com/matttproud/golang_protobuf_extensions/pbutil
github.com/miekg/pkcs11
# github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
github.com/mistifyio/go-zfs
-# github.com/mitchellh/mapstructure v1.4.3
-github.com/mitchellh/mapstructure
# github.com/moby/sys/mount v0.2.0
github.com/moby/sys/mount
# github.com/moby/sys/mountinfo v0.6.1
@@ -645,7 +643,7 @@ github.com/stefanberger/go-pkcs11uri
## explicit
github.com/stretchr/testify/assert
github.com/stretchr/testify/require
-# github.com/sylabs/sif/v2 v2.4.2
+# github.com/sylabs/sif/v2 v2.6.0
github.com/sylabs/sif/v2/pkg/sif
# github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
## explicit
@@ -720,7 +718,6 @@ 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/crypto/ssh/terminal
# golang.org/x/net v0.0.0-20220225172249-27dd8689420f
golang.org/x/net/context
golang.org/x/net/html
@@ -746,6 +743,7 @@ golang.org/x/sys/unix
golang.org/x/sys/windows
golang.org/x/sys/windows/registry
# golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
+## explicit
golang.org/x/term
# golang.org/x/text v0.3.7
## explicit