aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml10
-rw-r--r--cmd/podman/containers/create.go5
-rw-r--r--cmd/podman/containers/rm.go3
-rw-r--r--cmd/podman/images/scp.go13
-rw-r--r--cmd/podman/machine/list.go29
-rw-r--r--cmd/podman/machine/start.go2
-rw-r--r--cmd/podman/pods/create.go10
-rw-r--r--cmd/podman/root.go9
-rw-r--r--cmd/podman/utils/error.go2
-rw-r--r--cmd/winpath/main.go4
-rwxr-xr-xcontrib/cirrus/setup_environment.sh6
-rw-r--r--docs/source/markdown/podman-machine-list.1.md42
-rw-r--r--docs/source/markdown/podman-rm.1.md9
-rw-r--r--docs/source/markdown/podman.1.md5
-rw-r--r--go.mod10
-rw-r--r--go.sum33
-rw-r--r--libpod/container_internal_linux.go51
-rw-r--r--libpod/kube.go2
-rw-r--r--libpod/options.go65
-rw-r--r--libpod/runtime.go7
-rw-r--r--libpod/runtime_ctr.go33
-rw-r--r--pkg/api/handlers/compat/containers.go13
-rw-r--r--pkg/api/handlers/compat/images_build.go2
-rw-r--r--pkg/api/handlers/libpod/pods.go12
-rw-r--r--pkg/api/handlers/swagger/swagger.go7
-rw-r--r--pkg/api/handlers/types.go11
-rw-r--r--pkg/api/server/register_containers.go17
-rw-r--r--pkg/bindings/containers/containers.go11
-rw-r--r--pkg/bindings/containers/types.go1
-rw-r--r--pkg/bindings/containers/types_remove_options.go15
-rw-r--r--pkg/bindings/test/containers_test.go47
-rw-r--r--pkg/domain/entities/containers.go6
-rw-r--r--pkg/domain/entities/engine.go1
-rw-r--r--pkg/domain/entities/engine_container.go2
-rw-r--r--pkg/domain/entities/events.go2
-rw-r--r--pkg/domain/entities/reports/containers.go28
-rw-r--r--pkg/domain/infra/abi/containers.go37
-rw-r--r--pkg/domain/infra/abi/images.go50
-rw-r--r--pkg/domain/infra/tunnel/containers.go90
-rw-r--r--pkg/machine/config.go30
-rw-r--r--pkg/machine/ignition.go127
-rw-r--r--pkg/machine/qemu/machine.go125
-rw-r--r--pkg/specgen/generate/container.go12
-rw-r--r--pkg/specgen/generate/kube/kube.go5
-rw-r--r--pkg/specgen/generate/ports.go2
-rw-r--r--pkg/specgen/podspecgen.go2
-rw-r--r--pkg/specgen/specgen.go2
-rw-r--r--test/apiv2/12-imagesMore.at2
-rw-r--r--test/apiv2/20-containers.at8
-rw-r--r--test/apiv2/22-stop.at4
-rw-r--r--test/apiv2/25-containersMore.at4
-rw-r--r--test/apiv2/python/rest_api/test_v2_0_0_container.py2
-rwxr-xr-xtest/buildah-bud/apply-podman-deltas10
-rw-r--r--test/e2e/containers_conf_test.go32
-rw-r--r--test/e2e/events_test.go2
-rw-r--r--test/e2e/play_kube_test.go10
-rw-r--r--test/e2e/pull_test.go8
-rw-r--r--test/system/001-basic.bats2
-rw-r--r--test/system/010-images.bats4
-rw-r--r--test/system/030-run.bats15
-rw-r--r--test/system/035-logs.bats8
-rw-r--r--test/system/050-stop.bats5
-rw-r--r--test/system/055-rm.bats12
-rw-r--r--test/system/080-pause.bats3
-rw-r--r--test/system/090-events.bats13
-rw-r--r--test/system/170-run-userns.bats16
-rw-r--r--test/system/200-pod.bats11
-rw-r--r--test/system/250-systemd.bats5
-rw-r--r--test/system/500-networking.bats6
-rw-r--r--vendor/github.com/BurntSushi/toml/README.md41
-rw-r--r--vendor/github.com/BurntSushi/toml/decode.go133
-rw-r--r--vendor/github.com/BurntSushi/toml/decode_go116.go1
-rw-r--r--vendor/github.com/BurntSushi/toml/deprecated.go24
-rw-r--r--vendor/github.com/BurntSushi/toml/encode.go146
-rw-r--r--vendor/github.com/BurntSushi/toml/error.go229
-rw-r--r--vendor/github.com/BurntSushi/toml/go.sum0
-rw-r--r--vendor/github.com/BurntSushi/toml/lex.go352
-rw-r--r--vendor/github.com/BurntSushi/toml/meta.go (renamed from vendor/github.com/BurntSushi/toml/decode_meta.go)105
-rw-r--r--vendor/github.com/BurntSushi/toml/parse.go174
-rw-r--r--vendor/github.com/BurntSushi/toml/type_fields.go4
-rw-r--r--vendor/github.com/BurntSushi/toml/type_toml.go (renamed from vendor/github.com/BurntSushi/toml/type_check.go)2
-rw-r--r--vendor/github.com/containers/common/libimage/copier.go10
-rw-r--r--vendor/github.com/containers/common/libimage/filters.go196
-rw-r--r--vendor/github.com/containers/common/libimage/load.go22
-rw-r--r--vendor/github.com/containers/common/libimage/normalize.go38
-rw-r--r--vendor/github.com/containers/common/libimage/pull.go100
-rw-r--r--vendor/github.com/containers/common/libimage/runtime.go32
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/cgroups.go49
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go39
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/cgroups_unsupported.go8
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/memory.go24
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/pids.go3
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go15
-rw-r--r--vendor/github.com/containers/common/pkg/config/default.go4
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/errno_list.go2
-rw-r--r--vendor/github.com/containers/common/pkg/util/util.go24
-rw-r--r--vendor/github.com/containers/common/pkg/util/util_supported.go (renamed from vendor/github.com/containers/common/pkg/config/util_supported.go)6
-rw-r--r--vendor/github.com/containers/common/pkg/util/util_windows.go (renamed from vendor/github.com/containers/common/pkg/config/util_windows.go)4
-rw-r--r--vendor/github.com/containers/image/v5/copy/copy.go30
-rw-r--r--vendor/github.com/containers/image/v5/docker/docker_client.go2
-rw-r--r--vendor/github.com/containers/image/v5/pkg/docker/config/config.go10
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/README.md12
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar.go4
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar_filler.go25
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar_filler_nop.go14
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar_option.go23
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/container_option.go11
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/merge.go3
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/on_abort.go3
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go3
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/on_condition.go27
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/go.mod2
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/go.sum4
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/internal/predicate.go6
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/progress.go18
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/proxyreader.go4
-rw-r--r--vendor/golang.org/x/sys/plan9/syscall_plan9.go6
-rw-r--r--vendor/golang.org/x/sys/unix/mkerrors.sh2
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_aix.go6
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_darwin.go6
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_dragonfly.go10
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_freebsd.go6
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_linux.go6
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_netbsd.go14
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_openbsd.go6
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_solaris.go12
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_zos_s390x.go6
-rw-r--r--vendor/golang.org/x/sys/unix/zerrors_linux.go7
-rw-r--r--vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go12
-rw-r--r--vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go12
-rw-r--r--vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go12
-rw-r--r--vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go12
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux.go41
-rw-r--r--vendor/golang.org/x/sys/windows/exec_windows.go37
-rw-r--r--vendor/golang.org/x/sys/windows/types_windows.go4
-rw-r--r--vendor/modules.txt15
136 files changed, 2229 insertions, 1180 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 3dfbff11b..c33ed9c0c 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -29,7 +29,7 @@ env:
UBUNTU_NAME: "ubuntu-2110"
# Google-cloud VM Images
- IMAGE_SUFFIX: "c6015869890330624"
+ IMAGE_SUFFIX: "c6454758209748992"
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}"
UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX}"
@@ -612,10 +612,10 @@ rootless_gitlab_test_task:
alias: rootless_gitlab_test
skip: *tags
only_if: *not_docs
- # Test temporarily ignored due to failure on/around 7-10th Dec. 2021
- # Appears related to https://gitlab.com/gitlab-org/gitlab-runner/-/issues/28732
- # Log: https://cirrus-ci.com/task/5708221852680192?logs=setup#L433
- allow_failures: $CI == $CI
+ # Community-maintained downstream test may fail unexpectedly.
+ # Ref. repository: https://gitlab.com/gitlab-org/gitlab-runner
+ # If necessary, uncomment the next line and file issue(s) with details.
+ # allow_failures: $CI == $CI
depends_on:
- rootless_integration_test
gce_instance: *standardvm
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 9610c29dc..694b97fe5 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -388,10 +388,7 @@ func createPodIfNecessary(cmd *cobra.Command, s *specgen.SpecGenerator, netOpts
if err != nil {
return nil, err
}
- imageName := config.DefaultInfraImage
- podGen.InfraImage = imageName
- podGen.InfraContainerSpec = specgen.NewSpecGenerator(imageName, false)
- podGen.InfraContainerSpec.RawImageName = imageName
+ podGen.InfraContainerSpec = specgen.NewSpecGenerator("", false)
podGen.InfraContainerSpec.NetworkOptions = podGen.NetworkOptions
err = specgenutil.FillOutSpecGen(podGen.InfraContainerSpec, &infraOpts, []string{})
if err != nil {
diff --git a/cmd/podman/containers/rm.go b/cmd/podman/containers/rm.go
index 70cb76693..cede0ba14 100644
--- a/cmd/podman/containers/rm.go
+++ b/cmd/podman/containers/rm.go
@@ -61,7 +61,8 @@ func rmFlags(cmd *cobra.Command) {
flags.BoolVarP(&rmOptions.All, "all", "a", false, "Remove all containers")
flags.BoolVarP(&rmOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing")
- flags.BoolVarP(&rmOptions.Force, "force", "f", false, "Force removal of a running or unusable container. The default is false")
+ flags.BoolVarP(&rmOptions.Force, "force", "f", false, "Force removal of a running or unusable container")
+ flags.BoolVar(&rmOptions.Depend, "depend", false, "Remove container and all containers that depend on the selected container")
timeFlagName := "time"
flags.UintVarP(&stopTimeout, timeFlagName, "t", containerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
_ = cmd.RegisterFlagCompletionFunc(timeFlagName, completion.AutocompleteNone)
diff --git a/cmd/podman/images/scp.go b/cmd/podman/images/scp.go
index f02a3c15e..fb20d9417 100644
--- a/cmd/podman/images/scp.go
+++ b/cmd/podman/images/scp.go
@@ -46,6 +46,7 @@ var (
var (
parentFlags []string
+ quiet bool
source entities.ImageScpOptions
dest entities.ImageScpOptions
sshInfo entities.ImageScpConnections
@@ -61,7 +62,7 @@ func init() {
func scpFlags(cmd *cobra.Command) {
flags := cmd.Flags()
- flags.BoolVarP(&source.Quiet, "quiet", "q", false, "Suppress the output")
+ flags.BoolVarP(&quiet, "quiet", "q", false, "Suppress the output")
}
func scp(cmd *cobra.Command, args []string) (finalErr error) {
@@ -139,6 +140,7 @@ func scp(cmd *cobra.Command, args []string) (finalErr error) {
}
}
+ source.Quiet = quiet
source.File = f.Name() // after parsing the arguments, set the file for the save/load
dest.File = source.File
if err = os.Remove(source.File); err != nil { // remove the file and simply use its name so podman creates the file upon save. avoids umask errors
@@ -203,15 +205,6 @@ func scp(cmd *cobra.Command, args []string) (finalErr error) {
}
}
- src, err := json.MarshalIndent(source, "", " ")
- if err != nil {
- return err
- }
- dst, err := json.MarshalIndent(dest, "", " ")
- if err != nil {
- return err
- }
- fmt.Printf("SOURCE: %s\nDEST: %s\n", string(src), string(dst))
return nil
}
diff --git a/cmd/podman/machine/list.go b/cmd/podman/machine/list.go
index 858d87401..3d8def0db 100644
--- a/cmd/podman/machine/list.go
+++ b/cmd/podman/machine/list.go
@@ -32,6 +32,7 @@ var (
Args: validate.NoArgs,
ValidArgsFunction: completion.AutocompleteNone,
Example: `podman machine list,
+ podman machine list --format json
podman machine ls`,
}
listFlag = listFlagType{}
@@ -43,16 +44,19 @@ type listFlagType struct {
}
type machineReporter struct {
- Name string
- Default bool
- Created string
- Running bool
- LastUp string
- Stream string
- VMType string
- CPUs uint64
- Memory string
- DiskSize string
+ Name string
+ Default bool
+ Created string
+ Running bool
+ LastUp string
+ Stream string
+ VMType string
+ CPUs uint64
+ Memory string
+ DiskSize string
+ Port int
+ RemoteUsername string
+ IdentityPath string
}
func init() {
@@ -96,7 +100,7 @@ func list(cmd *cobra.Command, args []string) error {
return err
}
- b, err := json.Marshal(machineReporter)
+ b, err := json.MarshalIndent(machineReporter, "", " ")
if err != nil {
return err
}
@@ -189,6 +193,9 @@ func toMachineFormat(vms []*machine.ListResponse) ([]*machineReporter, error) {
response.CPUs = vm.CPUs
response.Memory = strUint(vm.Memory)
response.DiskSize = strUint(vm.DiskSize)
+ response.Port = vm.Port
+ response.RemoteUsername = vm.RemoteUsername
+ response.IdentityPath = vm.IdentityPath
machineResponses = append(machineResponses, response)
}
diff --git a/cmd/podman/machine/start.go b/cmd/podman/machine/start.go
index 9c9c24f64..a3770d61a 100644
--- a/cmd/podman/machine/start.go
+++ b/cmd/podman/machine/start.go
@@ -60,9 +60,9 @@ func start(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
+ fmt.Printf("Starting machine %q\n", vmName)
if err := vm.Start(vmName, machine.StartOptions{}); err != nil {
return err
}
- fmt.Printf("Machine %q started successfully\n", vmName)
return nil
}
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index f844812c2..6a28f7a79 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -71,7 +71,11 @@ func init() {
_ = createCommand.RegisterFlagCompletionFunc(nameFlagName, completion.AutocompleteNone)
infraImageFlagName := "infra-image"
- flags.StringVar(&infraImage, infraImageFlagName, containerConfig.Engine.InfraImage, "The image of the infra container to associate with the pod")
+ var defInfraImage string
+ if !registry.IsRemote() {
+ defInfraImage = containerConfig.Engine.InfraImage
+ }
+ flags.StringVar(&infraImage, infraImageFlagName, defInfraImage, "The image of the infra container to associate with the pod")
_ = createCommand.RegisterFlagCompletionFunc(infraImageFlagName, common.AutocompleteImages)
podIDFileFlagName := "pod-id-file"
@@ -109,7 +113,9 @@ func create(cmd *cobra.Command, args []string) error {
return errors.Wrapf(err, "unable to process labels")
}
- imageName = infraImage
+ if cmd.Flag("infra-image").Changed {
+ imageName = infraImage
+ }
img := imageName
if !createOptions.Infra {
if cmd.Flag("no-hosts").Changed {
diff --git a/cmd/podman/root.go b/cmd/podman/root.go
index bccc559ce..1de937ca5 100644
--- a/cmd/podman/root.go
+++ b/cmd/podman/root.go
@@ -114,6 +114,10 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error {
}
cfg := registry.PodmanConfig()
+ if cfg.NoOut {
+ null, _ := os.Open(os.DevNull)
+ os.Stdout = null
+ }
// Currently it is only possible to restore a container with the same runtime
// as used for checkpointing. It should be possible to make crun and runc
@@ -137,7 +141,7 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error {
runtimeFlag := cmd.Root().Flags().Lookup("runtime")
if runtimeFlag == nil {
return errors.Errorf(
- "Unexcpected error setting runtime to '%s' for restore",
+ "setting runtime to '%s' for restore",
*runtime,
)
}
@@ -217,7 +221,7 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error {
context := cmd.Root().LocalFlags().Lookup("context")
if context.Value.String() != "default" {
- return errors.New("Podman does not support swarm, the only --context value allowed is \"default\"")
+ return errors.New("podman does not support swarm, the only --context value allowed is \"default\"")
}
if !registry.IsRemote() {
if cmd.Flag("cpu-profile").Changed {
@@ -343,6 +347,7 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) {
lFlags.StringVar(&opts.Identity, identityFlagName, ident, "path to SSH identity file, (CONTAINER_SSHKEY)")
_ = cmd.RegisterFlagCompletionFunc(identityFlagName, completion.AutocompleteDefault)
+ lFlags.BoolVar(&opts.NoOut, "noout", false, "do not output to stdout")
lFlags.BoolVarP(&opts.Remote, "remote", "r", registry.IsRemote(), "Access remote Podman service")
pFlags := cmd.PersistentFlags()
if registry.IsRemote() {
diff --git a/cmd/podman/utils/error.go b/cmd/podman/utils/error.go
index aab1da675..b3b54876f 100644
--- a/cmd/podman/utils/error.go
+++ b/cmd/podman/utils/error.go
@@ -27,7 +27,7 @@ func (o OutputErrors) PrintErrors() (lastError error) {
instead returns a message and we cast it to a new error.
Following function performs parsing on build error and returns
- exit status which was exepected for this current build
+ exit status which was expected for this current build
*/
func ExitCodeFromBuildError(errorMsg string) (int, error) {
if strings.Contains(errorMsg, "exit status") {
diff --git a/cmd/winpath/main.go b/cmd/winpath/main.go
index 494d1cf3c..6fbe72837 100644
--- a/cmd/winpath/main.go
+++ b/cmd/winpath/main.go
@@ -114,7 +114,7 @@ func addPathToRegistry(dir string) error {
return err
}
-// Removes all occurences of a directory path from the Windows path stored in the registry
+// Removes all occurrences of a directory path from the Windows path stored in the registry
func removePathFromRegistry(path string) error {
k, err := registry.OpenKey(registry.CURRENT_USER, Environment, registry.READ|registry.WRITE)
if err != nil {
@@ -155,7 +155,7 @@ func removePathFromRegistry(path string) error {
return err
}
-// Sends a notification message to all top level windows informing them the environmental setings have changed.
+// Sends a notification message to all top level windows informing them the environmental settings have changed.
// Applications such as the Windows command prompt and powershell will know to stop caching stale values on
// subsequent restarts. Since applications block the sender when receiving a message, we set a 3 second timeout
func broadcastEnvironmentChange() {
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index ee80a209c..8f535c7e7 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -118,12 +118,6 @@ fi
case "$OS_RELEASE_ID" in
ubuntu) ;;
fedora)
- # Force a crun version that has this fix: https://github.com/containers/crun/pull/819
- # FIXME: Remove once a fixed crun made its way into Fedora
- if test "$OS_RELEASE_VER" == "35"; then
- yum upgrade -y crun
- fi
-
if ((CONTAINER==0)); then
# All SELinux distros need this for systemd-in-a-container
msg "Enabling container_manage_cgroup"
diff --git a/docs/source/markdown/podman-machine-list.1.md b/docs/source/markdown/podman-machine-list.1.md
index accdd760c..d68b8b1ca 100644
--- a/docs/source/markdown/podman-machine-list.1.md
+++ b/docs/source/markdown/podman-machine-list.1.md
@@ -20,16 +20,26 @@ tied to the Linux kernel.
#### **--format**=*format*
-Format list output using a Go template.
-
+Change the default output format. This can be of a supported type like 'json'
+or a Go template.
Valid placeholders for the Go template are listed below:
| **Placeholder** | **Description** |
| --------------- | ------------------------------- |
-| .Name | VM name |
+| .CPUs | Number of CPUs |
| .Created | Time since VM creation |
+| .Default | Is default machine |
+| .DiskSize | Disk size of machine |
+| .LastUp | Time machine was last up |
| .LastUp | Time since the VM was last run |
-| .VMType | VM type |
+| .Memory | Allocated memeory for machine |
+| .Name | VM name |
+| .Running | Is machine running |
+| .Stream | Stream name |
+| .VMType | VM type |
+| .Port | SSH Port to use to connect to VM|
+| .RemoteUsername | VM Username for rootless Podman |
+| .IdentityPath | Path to ssh identify file |
#### **--help**
@@ -43,8 +53,28 @@ Omit the table headings from the listing of pods.
```
$ podman machine list
-
-$ podman machine ls --format {{.Name}}\t{{.VMType}}\t{{.Created}}\t{{.LastUp}}\n
+NAME VM TYPE CREATED LAST UP CPUS MEMORY DISK SIZE
+podman-machine-default qemu 2 weeks ago 2 weeks ago 1 2.147GB 10.74GB
+
+$ podman machine ls --format "table {{.Name}}\t{{.VMType}}\t{{.Created}}\t{{.LastUp}}"
+NAME VM TYPE CREATED LAST UP
+podman-machine-default qemu 2 weeks ago 2 weeks ago
+
+$ podman machine ls --format json
+[
+ {
+ "Name": "podman-machine-default",
+ "Default": false,
+ "Created": "2021-12-27T10:36:14.373347492-05:00",
+ "Running": false,
+ "LastUp": "2021-12-27T11:22:50.17333371-05:00",
+ "Stream": "default",
+ "VMType": "qemu",
+ "CPUs": 1,
+ "Memory": "2147483648",
+ "DiskSize": "10737418240"
+ }
+]
```
## SEE ALSO
diff --git a/docs/source/markdown/podman-rm.1.md b/docs/source/markdown/podman-rm.1.md
index c599c8687..f3807d2f7 100644
--- a/docs/source/markdown/podman-rm.1.md
+++ b/docs/source/markdown/podman-rm.1.md
@@ -18,6 +18,10 @@ Running or unusable containers will not be removed without the **-f** option.
Remove all containers. Can be used in conjunction with **-f** as well.
+#### **--depend**
+
+Remove selected container and recursively remove all containers that depend on it.
+
#### **--cidfile**
Read container ID from the specified file and remove the container. Can be specified multiple times.
@@ -56,6 +60,11 @@ Remove a container by its name *mywebserver*
$ podman rm mywebserver
```
+Remove a *mywebserver* container and all of the containers that depend on it
+```
+$ podman rm --depend mywebserver
+```
+
Remove several containers by name and container id.
```
$ podman rm mywebserver myflaskserver 860a4b23
diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/podman.1.md
index daa8212c5..9f85ebda3 100644
--- a/docs/source/markdown/podman.1.md
+++ b/docs/source/markdown/podman.1.md
@@ -92,6 +92,11 @@ When namespace is set, created containers and pods will join the given namespace
#### **--network-cmd-path**=*path*
Path to the command binary to use for setting up a network. It is currently only used for setting up a slirp4netns network. If "" is used then the binary is looked up using the $PATH environment variable.
+#### **--noout**
+
+Redirect stdout to /dev/null. This command will prevent all stdout from the Podman command. The **--noout** option will not block stderr or stdout from containers.
+
+
#### **--remote**, **-r**
When true, access to the Podman service will be remote. Defaults to false.
Settings can be modified in the containers.conf file. If the CONTAINER_HOST
diff --git a/go.mod b/go.mod
index a432c2d5e..1051aa555 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/containers/podman/v3
go 1.16
require (
- github.com/BurntSushi/toml v0.4.1
+ github.com/BurntSushi/toml v1.0.0
github.com/blang/semver v3.5.1+incompatible
github.com/buger/goterm v0.0.0-20181115115552-c206103e1f37
github.com/checkpoint-restore/checkpointctl v0.0.0-20211204171957-54b4ebfdb681
@@ -12,9 +12,9 @@ require (
github.com/containernetworking/cni v1.0.1
github.com/containernetworking/plugins v1.0.1
github.com/containers/buildah v1.23.1
- github.com/containers/common v0.46.1-0.20211209220542-24f363480347
+ github.com/containers/common v0.46.1-0.20220112112017-31e8cc4aeeab
github.com/containers/conmon v2.0.20+incompatible
- github.com/containers/image/v5 v5.17.1-0.20211207161909-6f3c8453e1a7
+ github.com/containers/image/v5 v5.17.1-0.20220106205022-73f80d60f0e1
github.com/containers/ocicrypt v1.1.2
github.com/containers/psgo v1.7.1
github.com/containers/storage v1.37.1-0.20211213220314-73a749e4fec5
@@ -46,7 +46,7 @@ require (
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.17.0
github.com/opencontainers/go-digest v1.0.0
- github.com/opencontainers/image-spec v1.0.2-0.20211123152302-43a7dee1ec31
+ github.com/opencontainers/image-spec v1.0.3-0.20211202193544-a5463b7f9c84
github.com/opencontainers/runc v1.0.3
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
github.com/opencontainers/runtime-tools v0.9.1-0.20211020193359-09d837bf40a7
@@ -66,7 +66,7 @@ require (
go.etcd.io/bbolt v1.3.6
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
- golang.org/x/sys v0.0.0-20211205182925-97ca703d548d
+ golang.org/x/sys v0.0.0-20211214234402-4825e8c3871d
golang.org/x/text v0.3.7
google.golang.org/protobuf v1.27.1
gopkg.in/fsnotify.v1 v1.4.7 // indirect
diff --git a/go.sum b/go.sum
index cc0c9e0e0..acfdd6c21 100644
--- a/go.sum
+++ b/go.sum
@@ -65,8 +65,9 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
+github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
@@ -221,8 +222,8 @@ github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoT
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
github.com/containerd/containerd v1.5.5/go.mod h1:oSTh0QpT1w6jYcGmbiSbxv9OSQYaa88mPyWIuU79zyo=
github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
-github.com/containerd/containerd v1.5.8 h1:NmkCC1/QxyZFBny8JogwLpOy2f+VEbO/f6bV2Mqtwuw=
-github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s=
+github.com/containerd/containerd v1.5.9 h1:rs6Xg1gtIxaeyG+Smsb/0xaSDu1VgFhOCKBXxMxbsF4=
+github.com/containerd/containerd v1.5.9/go.mod h1:fvQqCfadDGga5HZyn3j4+dx56qj2I9YwBrlSdalvJYQ=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
@@ -283,14 +284,13 @@ github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNB
github.com/containers/buildah v1.23.1 h1:Tpc9DsRuU+0Oofewpxb6OJVNQjCu7yloN/obUqzfDTY=
github.com/containers/buildah v1.23.1/go.mod h1:4WnrN0yrA7ab0ppgunixu2WM1rlD2rG8QLJAKbEkZlQ=
github.com/containers/common v0.44.2/go.mod h1:7sdP4vmI5Bm6FPFxb3lvAh1Iktb6tiO1MzjUzhxdoGo=
-github.com/containers/common v0.46.1-0.20211209220542-24f363480347 h1:6CS7RroQLJu/SgUJXGZ3bOs2vnh9rxEnxczDcGjStBw=
-github.com/containers/common v0.46.1-0.20211209220542-24f363480347/go.mod h1:SoHWZESBD7dbqIOkvKrIg5D8EuVIQgL6vkOvv0Yebws=
+github.com/containers/common v0.46.1-0.20220112112017-31e8cc4aeeab h1:Pf1kwI8sZPiPMuen619noeltwtB2cIFC1iY42fE87AY=
+github.com/containers/common v0.46.1-0.20220112112017-31e8cc4aeeab/go.mod h1:hXUU9gtA8V9dSLHhizp/k/s0ZXBzrnUSScUfrsw8z2Y=
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.16.0/go.mod h1:XgTpfAPLRGOd1XYyCU5cISFr777bLmOerCSpt/v7+Q4=
-github.com/containers/image/v5 v5.17.1-0.20211201214147-603ec1341d58/go.mod h1:iUA6fv9NnqIhEaP3+dqo22nKMNkSWCj8d5o8Dju0j1Q=
-github.com/containers/image/v5 v5.17.1-0.20211207161909-6f3c8453e1a7 h1:iDxYJ+bqh626ui+jdSd17Bg7mCfqOJrLngnDCodxCY0=
-github.com/containers/image/v5 v5.17.1-0.20211207161909-6f3c8453e1a7/go.mod h1:WbE0J9s8mDldjRSP1S07tgVX1R7rZGnvU70bYZq0aBg=
+github.com/containers/image/v5 v5.17.1-0.20220106205022-73f80d60f0e1 h1:IIxEBQaYuj6w15h2q6mc8gB4MF6oSeDnOaq3pbVk3mg=
+github.com/containers/image/v5 v5.17.1-0.20220106205022-73f80d60f0e1/go.mod h1:daAiRXgcGIf/7eD7B2EkuHHw084/8M8Kh35rzOu56y0=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
@@ -362,7 +362,6 @@ github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BU
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.8+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v20.10.11+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.12+incompatible h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U=
github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
@@ -818,8 +817,9 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
-github.com/opencontainers/image-spec v1.0.2-0.20211123152302-43a7dee1ec31 h1:Wh4aR2I6JFwySre9m3iHJYuMnvUFE/HT6qAXozRWi/E=
-github.com/opencontainers/image-spec v1.0.2-0.20211123152302-43a7dee1ec31/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
+github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
+github.com/opencontainers/image-spec v1.0.3-0.20211202193544-a5463b7f9c84 h1:g47eG1u/gw0JB7mZ88TcHKCmsy7sWUNZD8ZS9Jhi0O8=
+github.com/opencontainers/image-spec v1.0.3-0.20211202193544-a5463b7f9c84/go.mod h1:Qnt1q4cjDNQI9bT832ziho5Iw2BhK8o1KwLOwW56VP4=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
@@ -913,6 +913,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rootless-containers/rootlesskit v0.14.6 h1:5kvJK6eeUtWZz1mYegu5S7DHOahq93K+jbc/mz+hbFQ=
github.com/rootless-containers/rootlesskit v0.14.6/go.mod h1:uHPTRoPO6ZdOl2q99ZKOK14PJAwepfNKh6hV57AOZYQ=
+github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
@@ -1010,9 +1011,8 @@ github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaW
github.com/vbauerster/mpb/v6 v6.0.4 h1:h6J5zM/2wimP5Hj00unQuV8qbo5EPcj6wbkCqgj7KcY=
github.com/vbauerster/mpb/v6 v6.0.4/go.mod h1:a/+JT57gqh6Du0Ay5jSR+uBMfXGdlR7VQlGP52fJxLM=
github.com/vbauerster/mpb/v7 v7.1.3/go.mod h1:X5GlohZw2fIpypMXWaKart+HGSAjpz49skxkDk+ZL7c=
-github.com/vbauerster/mpb/v7 v7.1.5/go.mod h1:4M8+qAoQqV60WDNktBM5k05i1iTrXE7rjKOHEVkVlec=
-github.com/vbauerster/mpb/v7 v7.2.0 h1:WfCkVMNQfDZy8ZZ2r7YFXP7bi5+mnCiSecakBDYGW+E=
-github.com/vbauerster/mpb/v7 v7.2.0/go.mod h1:WxlpgTrbnxiIjm5xn7IGYOopqP57hs0MhzBoGFC5ek4=
+github.com/vbauerster/mpb/v7 v7.3.0 h1:WwRtHHT26gjVln0yJypDEEpTWyX9sk4QcUxM6tQjdEc=
+github.com/vbauerster/mpb/v7 v7.3.0/go.mod h1:KERDXx9bfuStUwTH2FbsrJhJhVu1q+xmjjoCZMZrin4=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
@@ -1327,15 +1327,14 @@ golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211214234402-4825e8c3871d h1:1oIt9o40TWWI9FUaveVpUvBe13FNqBNVXy3ue2fcfkw=
+golang.org/x/sys v0.0.0-20211214234402-4825e8c3871d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 7745646b6..28d961e4b 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -2221,33 +2221,50 @@ func (c *Container) getHosts() string {
depCtr = c
}
+ // getLocalIP returns the non loopback local IP of the host
+ getLocalIP := func() string {
+ addrs, err := net.InterfaceAddrs()
+ if err != nil {
+ return ""
+ }
+ for _, address := range addrs {
+ // check the address type and if it is not a loopback the display it
+ if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
+ if ipnet.IP.To4() != nil {
+ return ipnet.IP.String()
+ }
+ }
+ }
+ return ""
+ }
+
if depCtr != nil {
- for _, status := range depCtr.getNetworkStatus() {
+ host := ""
+ outer:
+ for net, status := range depCtr.getNetworkStatus() {
+ network, err := c.runtime.network.NetworkInspect(net)
+ // only add the host entry for bridge networks
+ // ip/macvlan gateway is normally not on the host
+ if err != nil || network.Driver != types.BridgeNetworkDriver {
+ continue
+ }
for _, netInt := range status.Interfaces {
for _, netAddress := range netInt.Subnets {
if netAddress.Gateway != nil {
- hosts += fmt.Sprintf("%s host.containers.internal\n", netAddress.Gateway.String())
+ host = fmt.Sprintf("%s host.containers.internal\n", netAddress.Gateway.String())
+ break outer
}
}
}
}
- } else if c.config.NetMode.IsSlirp4netns() {
- // getLocalIP returns the non loopback local IP of the host
- getLocalIP := func() string {
- addrs, err := net.InterfaceAddrs()
- if err != nil {
- return ""
- }
- for _, address := range addrs {
- // check the address type and if it is not a loopback the display it
- if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
- if ipnet.IP.To4() != nil {
- return ipnet.IP.String()
- }
- }
+ // if no bridge gw was found try to use a local ip
+ if host == "" {
+ if ip := getLocalIP(); ip != "" {
+ host = fmt.Sprintf("%s\t%s\n", ip, "host.containers.internal")
}
- return ""
}
+ hosts += host
+ } else if c.config.NetMode.IsSlirp4netns() {
if ip := getLocalIP(); ip != "" {
hosts += fmt.Sprintf("%s\t%s\n", ip, "host.containers.internal")
}
diff --git a/libpod/kube.go b/libpod/kube.go
index d667616d0..f465fc776 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -595,7 +595,7 @@ func containerToV1Container(ctx context.Context, c *Container) (v1.Container, []
// pause one and make sure it's in the storage by pulling it down if
// missing.
if image == "" && c.IsInfra() {
- image = config.DefaultInfraImage
+ image = c.runtime.config.Engine.InfraImage
if _, err := c.runtime.libimageRuntime.Pull(ctx, image, config.PullPolicyMissing, nil); err != nil {
return kubeContainer, nil, nil, nil, err
}
diff --git a/libpod/options.go b/libpod/options.go
index 6edb9972b..630fe809d 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -115,19 +115,6 @@ func WithStorageConfig(config storage.StoreOptions) RuntimeOption {
}
}
-// WithDefaultTransport sets the default transport for retrieving images.
-func WithDefaultTransport(defaultTransport string) RuntimeOption {
- return func(rt *Runtime) error {
- if rt.valid {
- return define.ErrRuntimeFinalized
- }
-
- rt.config.Engine.ImageDefaultTransport = defaultTransport
-
- return nil
- }
-}
-
// WithSignaturePolicy specifies the path of a file which decides how trust is
// managed for images we've pulled.
// If this is not specified, the system default configuration will be used
@@ -144,26 +131,6 @@ func WithSignaturePolicy(path string) RuntimeOption {
}
}
-// WithStateType sets the backing state implementation for libpod.
-// Please note that information is not portable between backing states.
-// As such, if this differs between two libpods running on the same system,
-// they will not share containers, and unspecified behavior may occur.
-func WithStateType(storeType config.RuntimeStateStore) RuntimeOption {
- return func(rt *Runtime) error {
- if rt.valid {
- return define.ErrRuntimeFinalized
- }
-
- if storeType == config.InvalidStateStore {
- return errors.Wrapf(define.ErrInvalidArg, "must provide a valid state store type")
- }
-
- rt.config.Engine.StateType = storeType
-
- return nil
- }
-}
-
// WithOCIRuntime specifies an OCI runtime to use for running containers.
func WithOCIRuntime(runtime string) RuntimeOption {
return func(rt *Runtime) error {
@@ -452,23 +419,6 @@ func WithVolumePath(volPath string) RuntimeOption {
}
}
-// WithDefaultInfraImage sets the infra image for libpod.
-// An infra image is used for inter-container kernel
-// namespace sharing within a pod. Typically, an infra
-// container is lightweight and is there to reap
-// zombie processes within its pid namespace.
-func WithDefaultInfraImage(img string) RuntimeOption {
- return func(rt *Runtime) error {
- if rt.valid {
- return define.ErrRuntimeFinalized
- }
-
- rt.config.Engine.InfraImage = img
-
- return nil
- }
-}
-
// WithDefaultInfraCommand sets the command to
// run on pause container start up.
func WithDefaultInfraCommand(cmd string) RuntimeOption {
@@ -483,19 +433,6 @@ func WithDefaultInfraCommand(cmd string) RuntimeOption {
}
}
-// WithDefaultInfraName sets the infra container name for a single pod.
-func WithDefaultInfraName(name string) RuntimeOption {
- return func(rt *Runtime) error {
- if rt.valid {
- return define.ErrRuntimeFinalized
- }
-
- rt.config.Engine.InfraImage = name
-
- return nil
- }
-}
-
// WithRenumber instructs libpod to perform a lock renumbering while
// initializing. This will handle migrations from early versions of libpod with
// file locks to newer versions with SHM locking, as well as changes in the
@@ -563,8 +500,6 @@ func WithEventsLogger(logger string) RuntimeOption {
}
rt.config.Engine.EventsLogger = logger
- rt.config.Engine.EventsLogFilePath = filepath.Join(rt.config.Engine.TmpDir, "events", "events.log")
-
return nil
}
}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 9794b3605..90cd8ffe0 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -170,7 +170,6 @@ func NewRuntime(ctx context.Context, options ...RuntimeOption) (*Runtime, error)
if err != nil {
return nil, err
}
- conf.CheckCgroupsAndAdjustConfig()
return newRuntimeFromConfig(ctx, conf, options...)
}
@@ -228,6 +227,8 @@ func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...R
return nil, err
}
+ runtime.config.CheckCgroupsAndAdjustConfig()
+
return runtime, nil
}
@@ -1113,7 +1114,9 @@ func (r *Runtime) mergeDBConfig(dbConfig *DBConfig) {
logrus.Debugf("Overriding tmp dir %q with %q from database", c.TmpDir, dbConfig.LibpodTmp)
}
c.TmpDir = dbConfig.LibpodTmp
- c.EventsLogFilePath = filepath.Join(dbConfig.LibpodTmp, "events", "events.log")
+ if c.EventsLogFilePath == "" {
+ c.EventsLogFilePath = filepath.Join(dbConfig.LibpodTmp, "events", "events.log")
+ }
}
if !r.storageSet.VolumePathSet && dbConfig.VolumePath != "" {
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 59a1fd153..53ccb9139 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -429,7 +429,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
}()
ctr.config.SecretsPath = filepath.Join(ctr.config.StaticDir, "secrets")
- err = os.MkdirAll(ctr.config.SecretsPath, 0644)
+ err = os.MkdirAll(ctr.config.SecretsPath, 0755)
if err != nil {
return nil, err
}
@@ -915,6 +915,37 @@ func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVol
return id, cleanupErr
}
+// RemoveDepend removes all dependencies for a container
+func (r *Runtime) RemoveDepend(ctx context.Context, rmCtr *Container, force bool, removeVolume bool, timeout *uint) ([]*reports.RmReport, error) {
+ rmReports := make([]*reports.RmReport, 0)
+ deps, err := r.state.ContainerInUse(rmCtr)
+ if err != nil {
+ if err == define.ErrCtrRemoved {
+ return rmReports, nil
+ }
+ return rmReports, err
+ }
+ for _, cid := range deps {
+ ctr, err := r.state.Container(cid)
+ if err != nil {
+ if err == define.ErrNoSuchCtr {
+ continue
+ }
+ return rmReports, err
+ }
+
+ reports, err := r.RemoveDepend(ctx, ctr, force, removeVolume, timeout)
+ if err != nil {
+ return rmReports, err
+ }
+ rmReports = append(rmReports, reports...)
+ }
+ report := reports.RmReport{Id: rmCtr.ID()}
+ report.Err = r.removeContainer(ctx, rmCtr, force, removeVolume, false, timeout)
+
+ return append(rmReports, &report), nil
+}
+
// GetContainer retrieves a container by its ID
func (r *Runtime) GetContainer(id string) (*Container, error) {
r.lock.RLock()
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index ad341c3ab..4539199d3 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -36,6 +36,7 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
query := struct {
Force bool `schema:"force"`
Ignore bool `schema:"ignore"`
+ Depend bool `schema:"depend"`
Link bool `schema:"link"`
Timeout *uint `schema:"timeout"`
DockerVolumes bool `schema:"v"`
@@ -57,6 +58,7 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
if utils.IsLibpodRequest(r) {
options.Volumes = query.LibpodVolumes
options.Timeout = query.Timeout
+ options.Depend = query.Depend
} else {
if query.Link {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
@@ -71,7 +73,7 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
// code.
containerEngine := abi.ContainerEngine{Libpod: runtime}
name := utils.GetName(r)
- report, err := containerEngine.ContainerRm(r.Context(), []string{name}, options)
+ reports, err := containerEngine.ContainerRm(r.Context(), []string{name}, options)
if err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr {
utils.ContainerNotFound(w, name, err)
@@ -81,8 +83,8 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
- if len(report) > 0 && report[0].Err != nil {
- err = report[0].Err
+ if len(reports) > 0 && reports[0].Err != nil {
+ err = reports[0].Err
if errors.Cause(err) == define.ErrNoSuchCtr {
utils.ContainerNotFound(w, name, err)
return
@@ -90,7 +92,10 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
-
+ if utils.IsLibpodRequest(r) {
+ utils.WriteResponse(w, http.StatusOK, reports)
+ return
+ }
utils.WriteResponse(w, http.StatusNoContent, nil)
}
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index 0fcac5330..2d296b5ce 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -138,7 +138,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
// if layers field not set assume its not from a valid podman-client
// could be a docker client, set `layers=true` since that is the default
- // expected behviour
+ // expected behaviour
if !utils.IsLibpodRequest(r) {
if _, found := r.URL.Query()["layers"]; !found {
query.Layers = true
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go
index 1b29831b4..43b39060b 100644
--- a/pkg/api/handlers/libpod/pods.go
+++ b/pkg/api/handlers/libpod/pods.go
@@ -7,7 +7,6 @@ import (
"strings"
"time"
- "github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/api/handlers"
@@ -62,15 +61,8 @@ func PodCreate(w http.ResponseWriter, r *http.Request) {
psg.InfraContainerSpec.Name = psg.InfraName
psg.InfraContainerSpec.ConmonPidFile = psg.InfraConmonPidFile
psg.InfraContainerSpec.ContainerCreateCommand = psg.InfraCommand
- imageName := psg.InfraImage
- rawImageName := psg.InfraImage
- if imageName == "" {
- imageName = config.DefaultInfraImage
- rawImageName = config.DefaultInfraImage
- }
- psg.InfraImage = imageName
- psg.InfraContainerSpec.Image = imageName
- psg.InfraContainerSpec.RawImageName = rawImageName
+ psg.InfraContainerSpec.Image = psg.InfraImage
+ psg.InfraContainerSpec.RawImageName = psg.InfraImage
}
podSpecComplete := entities.PodSpec{PodSpecGen: psg}
pod, err := generate.MakePod(&podSpecComplete, runtime)
diff --git a/pkg/api/handlers/swagger/swagger.go b/pkg/api/handlers/swagger/swagger.go
index 9844839b7..7868ff206 100644
--- a/pkg/api/handlers/swagger/swagger.go
+++ b/pkg/api/handlers/swagger/swagger.go
@@ -111,6 +111,13 @@ type swagLibpodInspectImageResponse struct {
}
}
+// Rm containers
+// swagger:response DocsLibpodContainerRmReport
+type swagLibpodContainerRmReport struct {
+ // in: body
+ Body []handlers.LibpodContainersRmReport
+}
+
// Prune containers
// swagger:response DocsContainerPruneReport
type swagContainerPruneReport struct {
diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go
index f850db3d8..588758b2c 100644
--- a/pkg/api/handlers/types.go
+++ b/pkg/api/handlers/types.go
@@ -53,6 +53,17 @@ type LibpodContainersPruneReport struct {
PruneError string `json:"Err,omitempty"`
}
+type LibpodContainersRmReport struct {
+ ID string `json:"Id"`
+ // Error which occurred during Rm operation (if any).
+ // This field is optional and may be omitted if no error occurred.
+ //
+ // Extensions:
+ // x-omitempty: true
+ // x-nullable: true
+ RmError string `json:"Err,omitempty"`
+}
+
type Info struct {
docker.Info
BuildahVersion string
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index 601e1251b..4d19c04d4 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -817,9 +817,22 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// required: true
// description: the name or ID of the container
// - in: query
+ // name: depend
+ // type: boolean
+ // description: additionally remove containers that depend on the container to be removed
+ // - in: query
// name: force
// type: boolean
- // description: need something
+ // description: force stop container if running
+ // - in: query
+ // name: ignore
+ // type: boolean
+ // description: ignore errors when the container to be removed does not existxo
+ // - in: query
+ // name: timeout
+ // type: integer
+ // default: 10
+ // description: number of seconds to wait before killing container when force removing
// - in: query
// name: v
// type: boolean
@@ -827,6 +840,8 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// produces:
// - application/json
// responses:
+ // 200:
+ // $ref: "#/responses/DocsLibpodContainerRmReport"
// 204:
// description: no error
// 400:
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index 14a173025..0148e62cb 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -78,25 +78,26 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*reports.PruneReport,
// The volumes bool dictates that a container's volumes should also be removed.
// The All option indicates that all containers should be removed
// The Ignore option indicates that if a container did not exist, ignore the error
-func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) error {
+func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) ([]*reports.RmReport, error) {
if options == nil {
options = new(RemoveOptions)
}
+ var reports []*reports.RmReport
conn, err := bindings.GetClient(ctx)
if err != nil {
- return err
+ return reports, err
}
params, err := options.ToParams()
if err != nil {
- return err
+ return reports, err
}
response, err := conn.DoRequest(ctx, nil, http.MethodDelete, "/containers/%s", params, nil, nameOrID)
if err != nil {
- return err
+ return reports, err
}
defer response.Body.Close()
- return response.Process(nil)
+ return reports, response.Process(&reports)
}
// Inspect returns low level information about a Container. The nameOrID can be a container name
diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go
index 81a53a549..db3eb3e1b 100644
--- a/pkg/bindings/containers/types.go
+++ b/pkg/bindings/containers/types.go
@@ -138,6 +138,7 @@ type PruneOptions struct {
//go:generate go run ../generator/generator.go RemoveOptions
// RemoveOptions are optional options for removing containers
type RemoveOptions struct {
+ Depend *bool
Ignore *bool
Force *bool
Volumes *bool
diff --git a/pkg/bindings/containers/types_remove_options.go b/pkg/bindings/containers/types_remove_options.go
index 1e52e819d..7fa198d2f 100644
--- a/pkg/bindings/containers/types_remove_options.go
+++ b/pkg/bindings/containers/types_remove_options.go
@@ -17,6 +17,21 @@ func (o *RemoveOptions) ToParams() (url.Values, error) {
return util.ToParams(o)
}
+// WithDepend set field Depend to given value
+func (o *RemoveOptions) WithDepend(value bool) *RemoveOptions {
+ o.Depend = &value
+ return o
+}
+
+// GetDepend returns value of field Depend
+func (o *RemoveOptions) GetDepend() bool {
+ if o.Depend == nil {
+ var z bool
+ return z
+ }
+ return *o.Depend
+}
+
// WithIgnore set field Ignore to given value
func (o *RemoveOptions) WithIgnore(value bool) *RemoveOptions {
o.Ignore = &value
diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go
index b6c06756b..cab032a40 100644
--- a/pkg/bindings/test/containers_test.go
+++ b/pkg/bindings/test/containers_test.go
@@ -175,7 +175,7 @@ var _ = Describe("Podman containers ", func() {
Expect(err).To(BeNil())
err = containers.Pause(bt.conn, cid, nil)
Expect(err).To(BeNil())
- err = containers.Remove(bt.conn, cid, nil)
+ _, err = containers.Remove(bt.conn, cid, nil)
Expect(err).ToNot(BeNil())
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
@@ -188,8 +188,10 @@ var _ = Describe("Podman containers ", func() {
Expect(err).To(BeNil())
err = containers.Pause(bt.conn, cid, nil)
Expect(err).To(BeNil())
- err = containers.Remove(bt.conn, cid, new(containers.RemoveOptions).WithForce(true))
+ rmResponse, err := containers.Remove(bt.conn, cid, new(containers.RemoveOptions).WithForce(true))
Expect(err).To(BeNil())
+ Expect(len(reports.RmReportsErrs(rmResponse))).To(Equal(0))
+ Expect(len(reports.RmReportsIds(rmResponse))).To(Equal(1))
})
It("podman stop a paused container by name", func() {
@@ -669,7 +671,8 @@ var _ = Describe("Podman containers ", func() {
})
It("podman remove bogus container", func() {
- err = containers.Remove(bt.conn, "foobar", nil)
+ _, err := containers.Remove(bt.conn, "foobar", nil)
+ Expect(err).ToNot(BeNil())
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusNotFound))
})
@@ -679,7 +682,7 @@ var _ = Describe("Podman containers ", func() {
_, err := bt.RunTopContainer(&name, nil)
Expect(err).To(BeNil())
// Removing running container should fail
- err = containers.Remove(bt.conn, name, nil)
+ _, err = containers.Remove(bt.conn, name, nil)
Expect(err).ToNot(BeNil())
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
@@ -690,7 +693,7 @@ var _ = Describe("Podman containers ", func() {
cid, err := bt.RunTopContainer(&name, nil)
Expect(err).To(BeNil())
// Removing running container should fail
- err = containers.Remove(bt.conn, cid, nil)
+ _, err = containers.Remove(bt.conn, cid, nil)
Expect(err).ToNot(BeNil())
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
@@ -700,22 +703,22 @@ var _ = Describe("Podman containers ", func() {
var name = "top"
_, err := bt.RunTopContainer(&name, nil)
Expect(err).To(BeNil())
- // Removing running container should fail
- err = containers.Remove(bt.conn, name, new(containers.RemoveOptions).WithForce(true))
+ // Removing running container should succeed
+ rmResponse, err := containers.Remove(bt.conn, name, new(containers.RemoveOptions).WithForce(true))
Expect(err).To(BeNil())
- //code, _ := bindings.CheckResponseCode(err)
- //Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
+ Expect(len(reports.RmReportsErrs(rmResponse))).To(Equal(0))
+ Expect(len(reports.RmReportsIds(rmResponse))).To(Equal(1))
})
It("podman forcibly remove running container by ID", func() {
var name = "top"
cid, err := bt.RunTopContainer(&name, nil)
Expect(err).To(BeNil())
- // Removing running container should fail
- err = containers.Remove(bt.conn, cid, new(containers.RemoveOptions).WithForce(true))
+ // Forcably Removing running container should succeed
+ rmResponse, err := containers.Remove(bt.conn, cid, new(containers.RemoveOptions).WithForce(true))
Expect(err).To(BeNil())
- //code, _ := bindings.CheckResponseCode(err)
- //Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
+ Expect(len(reports.RmReportsErrs(rmResponse))).To(Equal(0))
+ Expect(len(reports.RmReportsIds(rmResponse))).To(Equal(1))
})
It("podman remove running container and volume by name", func() {
@@ -723,7 +726,7 @@ var _ = Describe("Podman containers ", func() {
_, err := bt.RunTopContainer(&name, nil)
Expect(err).To(BeNil())
// Removing running container should fail
- err = containers.Remove(bt.conn, name, new(containers.RemoveOptions).WithVolumes(true))
+ _, err = containers.Remove(bt.conn, name, new(containers.RemoveOptions).WithVolumes(true))
Expect(err).ToNot(BeNil())
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
@@ -734,7 +737,7 @@ var _ = Describe("Podman containers ", func() {
cid, err := bt.RunTopContainer(&name, nil)
Expect(err).To(BeNil())
// Removing running container should fail
- err = containers.Remove(bt.conn, cid, new(containers.RemoveOptions).WithVolumes(true))
+ _, err = containers.Remove(bt.conn, cid, new(containers.RemoveOptions).WithVolumes(true))
Expect(err).ToNot(BeNil())
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
@@ -744,11 +747,11 @@ var _ = Describe("Podman containers ", func() {
var name = "top"
_, err := bt.RunTopContainer(&name, nil)
Expect(err).To(BeNil())
- // Removing running container should fail
- err = containers.Remove(bt.conn, name, new(containers.RemoveOptions).WithVolumes(true).WithForce(true))
+ // Forcibly Removing running container should succeed
+ rmResponse, err := containers.Remove(bt.conn, name, new(containers.RemoveOptions).WithVolumes(true).WithForce(true))
Expect(err).To(BeNil())
- //code, _ := bindings.CheckResponseCode(err)
- //Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
+ Expect(len(reports.RmReportsErrs(rmResponse))).To(Equal(0))
+ Expect(len(reports.RmReportsIds(rmResponse))).To(Equal(1))
})
It("podman forcibly remove running container and volume by ID", func() {
@@ -756,10 +759,10 @@ var _ = Describe("Podman containers ", func() {
cid, err := bt.RunTopContainer(&name, nil)
Expect(err).To(BeNil())
// Removing running container should fail
- err = containers.Remove(bt.conn, cid, new(containers.RemoveOptions).WithForce(true).WithVolumes(true))
+ rmResponse, err := containers.Remove(bt.conn, cid, new(containers.RemoveOptions).WithForce(true).WithVolumes(true))
Expect(err).To(BeNil())
- //code, _ := bindings.CheckResponseCode(err)
- //Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
+ Expect(len(reports.RmReportsErrs(rmResponse))).To(Equal(0))
+ Expect(len(reports.RmReportsIds(rmResponse))).To(Equal(1))
})
It("List containers with filters", func() {
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index ae441b7f3..e3f8f1b7c 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -129,6 +129,7 @@ type RestartReport struct {
type RmOptions struct {
All bool
+ Depend bool
Force bool
Ignore bool
Latest bool
@@ -136,11 +137,6 @@ type RmOptions struct {
Volumes bool
}
-type RmReport struct {
- Err error
- Id string //nolint
-}
-
type ContainerInspectReport struct {
*define.InspectContainerData
}
diff --git a/pkg/domain/entities/engine.go b/pkg/domain/entities/engine.go
index a8023f7cf..055af7ff9 100644
--- a/pkg/domain/entities/engine.go
+++ b/pkg/domain/entities/engine.go
@@ -40,6 +40,7 @@ type PodmanConfig struct {
Identity string // ssh identity for connecting to server
MaxWorks int // maximum number of parallel threads
MemoryProfile string // Hidden: Should memory profile be taken
+ NoOut bool // Don't output to stdout
RegistriesConf string // allows for specifying a custom registries.conf
Remote bool // Connection to Podman API Service will use RESTful API
RuntimePath string // --runtime flag will set Engine.RuntimePath
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 383e42098..7ce4dd0f6 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -40,7 +40,7 @@ type ContainerEngine interface {
ContainerRename(ctr context.Context, nameOrID string, options ContainerRenameOptions) error
ContainerRestart(ctx context.Context, namesOrIds []string, options RestartOptions) ([]*RestartReport, error)
ContainerRestore(ctx context.Context, namesOrIds []string, options RestoreOptions) ([]*RestoreReport, error)
- ContainerRm(ctx context.Context, namesOrIds []string, options RmOptions) ([]*RmReport, error)
+ ContainerRm(ctx context.Context, namesOrIds []string, options RmOptions) ([]*reports.RmReport, error)
ContainerRun(ctx context.Context, opts ContainerRunOptions) (*ContainerRunReport, error)
ContainerRunlabel(ctx context.Context, label string, image string, args []string, opts ContainerRunlabelOptions) error
ContainerStart(ctx context.Context, namesOrIds []string, options ContainerStartOptions) ([]*ContainerStartReport, error)
diff --git a/pkg/domain/entities/events.go b/pkg/domain/entities/events.go
index 73a375b94..fa815d7b9 100644
--- a/pkg/domain/entities/events.go
+++ b/pkg/domain/entities/events.go
@@ -42,7 +42,7 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
Image: image,
Name: name,
Status: status,
- Time: time.Unix(e.Time, e.TimeNano),
+ Time: time.Unix(0, e.TimeNano),
Type: t,
Details: libpodEvents.Details{
Attributes: details,
diff --git a/pkg/domain/entities/reports/containers.go b/pkg/domain/entities/reports/containers.go
new file mode 100644
index 000000000..54bcd092b
--- /dev/null
+++ b/pkg/domain/entities/reports/containers.go
@@ -0,0 +1,28 @@
+package reports
+
+type RmReport struct {
+ Id string `json:"Id"` //nolint
+ Err error `json:"Err,omitempty"`
+}
+
+func RmReportsIds(r []*RmReport) []string {
+ ids := make([]string, 0, len(r))
+ for _, v := range r {
+ if v == nil || v.Id == "" {
+ continue
+ }
+ ids = append(ids, v.Id)
+ }
+ return ids
+}
+
+func RmReportsErrs(r []*RmReport) []error {
+ errs := make([]error, 0, len(r))
+ for _, v := range r {
+ if v == nil || v.Err == nil {
+ continue
+ }
+ errs = append(errs, v.Err)
+ }
+ return errs
+}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index bf4dcff62..a4522698e 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -301,27 +301,27 @@ func (ic *ContainerEngine) removeContainer(ctx context.Context, ctr *libpod.Cont
return err
}
-func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, options entities.RmOptions) ([]*entities.RmReport, error) {
- reports := []*entities.RmReport{}
+func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, options entities.RmOptions) ([]*reports.RmReport, error) {
+ rmReports := []*reports.RmReport{}
names := namesOrIds
// Attempt to remove named containers directly from storage, if container is defined in libpod
// this will fail and code will fall through to removing the container from libpod.`
tmpNames := []string{}
for _, ctr := range names {
- report := entities.RmReport{Id: ctr}
+ report := reports.RmReport{Id: ctr}
report.Err = ic.Libpod.RemoveStorageContainer(ctr, options.Force)
switch errors.Cause(report.Err) {
case nil:
// remove container names that we successfully deleted
- reports = append(reports, &report)
+ rmReports = append(rmReports, &report)
case define.ErrNoSuchCtr, define.ErrCtrExists:
// There is still a potential this is a libpod container
tmpNames = append(tmpNames, ctr)
default:
if _, err := ic.Libpod.LookupContainer(ctr); errors.Cause(err) == define.ErrNoSuchCtr {
// remove container failed, but not a libpod container
- reports = append(reports, &report)
+ rmReports = append(rmReports, &report)
continue
}
// attempt to remove as a libpod container
@@ -340,23 +340,34 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
for _, ctr := range names {
logrus.Debugf("Evicting container %q", ctr)
- report := entities.RmReport{Id: ctr}
+ report := reports.RmReport{Id: ctr}
_, err := ic.Libpod.EvictContainer(ctx, ctr, options.Volumes)
if err != nil {
if options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr {
logrus.Debugf("Ignoring error (--allow-missing): %v", err)
- reports = append(reports, &report)
+ rmReports = append(rmReports, &report)
continue
}
report.Err = err
- reports = append(reports, &report)
+ rmReports = append(rmReports, &report)
continue
}
- reports = append(reports, &report)
+ rmReports = append(rmReports, &report)
}
- return reports, nil
+ return rmReports, nil
}
+ if !options.All && options.Depend {
+ // Add additional containers based on dependencies to container map
+ for _, ctr := range ctrs {
+ reports, err := ic.Libpod.RemoveDepend(ctx, ctr, options.Force, options.Volumes, options.Timeout)
+ if err != nil {
+ return rmReports, err
+ }
+ rmReports = append(rmReports, reports...)
+ }
+ return rmReports, nil
+ }
errMap, err := parallelctr.ContainerOp(ctx, ctrs, func(c *libpod.Container) error {
return ic.removeContainer(ctx, c, options)
})
@@ -364,12 +375,12 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
return nil, err
}
for ctr, err := range errMap {
- report := new(entities.RmReport)
+ report := new(reports.RmReport)
report.Id = ctr.ID()
report.Err = err
- reports = append(reports, report)
+ rmReports = append(rmReports, report)
}
- return reports, nil
+ return rmReports, nil
}
func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, []error, error) {
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 84c83ea8e..592e0f4e3 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -745,11 +745,17 @@ func putSignature(manifestBlob []byte, mech signature.SigningMechanism, sigStore
// TransferRootless creates new podman processes using exec.Command and sudo, transferring images between the given source and destination users
func transferRootless(source entities.ImageScpOptions, dest entities.ImageScpOptions, podman string, parentFlags []string) error {
var cmdSave *exec.Cmd
- saveCommand := parentFlags
- saveCommand = append(saveCommand, []string{"save", "--output", source.File, source.Image}...)
+ saveCommand, loadCommand := parentFlags, parentFlags
+ saveCommand = append(saveCommand, []string{"save"}...)
+ loadCommand = append(loadCommand, []string{"load"}...)
+ if source.Quiet {
+ saveCommand = append(saveCommand, "-q")
+ loadCommand = append(loadCommand, "-q")
+ }
+
+ saveCommand = append(saveCommand, []string{"--output", source.File, source.Image}...)
- loadCommand := parentFlags
- loadCommand = append(loadCommand, []string{"load", "--input", dest.File}...)
+ loadCommand = append(loadCommand, []string{"--input", dest.File}...)
if source.User == "root" {
cmdSave = exec.Command("sudo", podman)
@@ -757,7 +763,7 @@ func transferRootless(source entities.ImageScpOptions, dest entities.ImageScpOpt
cmdSave = exec.Command(podman)
}
cmdSave = utils.CreateSCPCommand(cmdSave, saveCommand)
- logrus.Debug("Executing save command")
+ logrus.Debugf("Executing save command: %q", cmdSave)
err := cmdSave.Run()
if err != nil {
return err
@@ -770,20 +776,22 @@ func transferRootless(source entities.ImageScpOptions, dest entities.ImageScpOpt
cmdLoad = exec.Command(podman)
}
cmdLoad = utils.CreateSCPCommand(cmdLoad, loadCommand)
- logrus.Debug("Executing load command")
- err = cmdLoad.Run()
- if err != nil {
- return err
- }
- return nil
+ logrus.Debugf("Executing load command: %q", cmdLoad)
+ return cmdLoad.Run()
}
-// TransferRootless creates new podman processes using exec.Command and su/machinectl, transferring images between the given source and destination users
+// TransferRootful creates new podman processes using exec.Command and su/machinectl, transferring images between the given source and destination users
func transferRootful(source entities.ImageScpOptions, dest entities.ImageScpOptions, podman string, parentFlags []string) error {
basicCommand := []string{podman}
basicCommand = append(basicCommand, parentFlags...)
- saveCommand := append(basicCommand, []string{"save", "--output", source.File, source.Image}...)
- loadCommand := append(basicCommand, []string{"load", "--input", dest.File}...)
+ saveCommand := append(basicCommand, "save")
+ loadCommand := append(basicCommand, "load")
+ if source.Quiet {
+ saveCommand = append(saveCommand, "-q")
+ loadCommand = append(loadCommand, "-q")
+ }
+ saveCommand = append(saveCommand, []string{"--output", source.File, source.Image}...)
+ loadCommand = append(loadCommand, []string{"--input", dest.File}...)
save := []string{strings.Join(saveCommand, " ")}
load := []string{strings.Join(loadCommand, " ")}
@@ -846,18 +854,18 @@ func lookupUser(u string) (*user.User, error) {
func execSu(execUser *user.User, command []string) error {
cmd := exec.Command("su", "-l", execUser.Username, "--command")
cmd = utils.CreateSCPCommand(cmd, command)
- logrus.Debug("Executing command su")
+ logrus.Debugf("Executing via su: %q", cmd)
return cmd.Run()
}
func execMachine(execUser *user.User, command []string, machinectl string) error {
- var cmd *exec.Cmd
+ verb := machinectl
+ args := []string{"shell", "-q", execUser.Username + "@.host"}
if execUser.Uid == "0" {
- cmd = exec.Command("sudo", machinectl, "shell", "-q", execUser.Username+"@.host")
- } else {
- cmd = exec.Command(machinectl, "shell", "-q", execUser.Username+"@.host")
+ args = append([]string{verb}, args...)
+ verb = "sudo"
}
- cmd = utils.CreateSCPCommand(cmd, command)
- logrus.Debug("Executing command machinectl")
+ cmd := utils.CreateSCPCommand(exec.Command(verb, args...), command)
+ logrus.Debugf("Executing via machinectl: %q", cmd)
return cmd.Run()
}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 2127f8749..4f72eab96 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -182,9 +182,9 @@ func (ic *ContainerEngine) ContainerRestart(ctx context.Context, namesOrIds []st
return reports, nil
}
-func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, opts entities.RmOptions) ([]*entities.RmReport, error) {
+func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, opts entities.RmOptions) ([]*reports.RmReport, error) {
// TODO there is no endpoint for container eviction. Need to discuss
- options := new(containers.RemoveOptions).WithForce(opts.Force).WithVolumes(opts.Volumes).WithIgnore(opts.Ignore)
+ options := new(containers.RemoveOptions).WithForce(opts.Force).WithVolumes(opts.Volumes).WithIgnore(opts.Ignore).WithDepend(opts.Depend)
if opts.Timeout != nil {
options = options.WithTimeout(*opts.Timeout)
}
@@ -193,25 +193,31 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
if err != nil {
return nil, err
}
- reports := make([]*entities.RmReport, 0, len(ctrs))
+ rmReports := make([]*reports.RmReport, 0, len(ctrs))
for _, c := range ctrs {
- reports = append(reports, &entities.RmReport{
- Id: c.ID,
- Err: containers.Remove(ic.ClientCtx, c.ID, options),
- })
+ report, err := containers.Remove(ic.ClientCtx, c.ID, options)
+ if err != nil {
+ return rmReports, err
+ }
+ rmReports = append(rmReports, report...)
}
- return reports, nil
+ return rmReports, nil
}
- reports := make([]*entities.RmReport, 0, len(namesOrIds))
+ rmReports := make([]*reports.RmReport, 0, len(namesOrIds))
for _, name := range namesOrIds {
- reports = append(reports, &entities.RmReport{
- Id: name,
- Err: containers.Remove(ic.ClientCtx, name, options),
- })
+ report, err := containers.Remove(ic.ClientCtx, name, options)
+ if err != nil {
+ rmReports = append(rmReports, &reports.RmReport{
+ Id: name,
+ Err: err,
+ })
+ continue
+ }
+ rmReports = append(rmReports, report...)
}
- return reports, nil
+ return rmReports, nil
}
func (ic *ContainerEngine) ContainerPrune(ctx context.Context, opts entities.ContainerPruneOptions) ([]*reports.PruneReport, error) {
@@ -552,6 +558,27 @@ func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input,
return <-attachErr
}
+func logIfRmError(id string, err error, reports []*reports.RmReport) {
+ logError := func(id string, err error) {
+ if errorhandling.Contains(err, define.ErrNoSuchCtr) ||
+ errorhandling.Contains(err, define.ErrCtrRemoved) ||
+ errorhandling.Contains(err, types.ErrLayerUnknown) {
+ logrus.Debugf("Container %s does not exist: %v", id, err)
+ } else {
+ logrus.Errorf("Removing container %s: %v", id, err)
+ }
+ }
+ if err != nil {
+ logError(id, err)
+ } else {
+ for _, report := range reports {
+ if report.Err != nil {
+ logError(report.Id, report.Err)
+ }
+ }
+ }
+}
+
func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) {
reports := []*entities.ContainerStartReport{}
var exitCode = define.ExecErrorCodeGeneric
@@ -590,14 +617,8 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
}
removeOptions := new(containers.RemoveOptions).WithVolumes(true).WithForce(false)
removeContainer := func(id string) {
- if err := containers.Remove(ic.ClientCtx, id, removeOptions); err != nil {
- if errorhandling.Contains(err, define.ErrNoSuchCtr) ||
- errorhandling.Contains(err, define.ErrCtrRemoved) {
- logrus.Debugf("Container %s does not exist: %v", id, err)
- } else {
- logrus.Errorf("Removing container %s: %v", id, err)
- }
- }
+ reports, err := containers.Remove(ic.ClientCtx, id, removeOptions)
+ logIfRmError(id, err, reports)
}
// There can only be one container if attach was used
@@ -674,15 +695,8 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
if err != nil {
if ctr.AutoRemove {
rmOptions := new(containers.RemoveOptions).WithForce(false).WithVolumes(true)
- if err := containers.Remove(ic.ClientCtx, ctr.ID, rmOptions); err != nil {
- if errorhandling.Contains(err, define.ErrNoSuchCtr) ||
- errorhandling.Contains(err, define.ErrCtrRemoved) ||
- errorhandling.Contains(err, types.ErrLayerUnknown) {
- logrus.Debugf("Container %s does not exist: %v", ctr.ID, err)
- } else {
- logrus.Errorf("Removing container %s: %v", ctr.ID, err)
- }
- }
+ reports, err := containers.Remove(ic.ClientCtx, ctr.ID, rmOptions)
+ logIfRmError(ctr.ID, err, reports)
}
report.Err = errors.Wrapf(err, "unable to start container %q", name)
report.ExitCode = define.ExitCode(err)
@@ -741,7 +755,8 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
report.ExitCode = define.ExitCode(err)
if opts.Rm {
- if rmErr := containers.Remove(ic.ClientCtx, con.ID, new(containers.RemoveOptions).WithForce(false).WithVolumes(true)); rmErr != nil {
+ reports, rmErr := containers.Remove(ic.ClientCtx, con.ID, new(containers.RemoveOptions).WithForce(false).WithVolumes(true))
+ if rmErr != nil || reports[0].Err != nil {
logrus.Debugf("unable to remove container %s after failing to start and attach to it", con.ID)
}
}
@@ -759,15 +774,8 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
}
if !shouldRestart {
- if err := containers.Remove(ic.ClientCtx, con.ID, new(containers.RemoveOptions).WithForce(false).WithVolumes(true)); err != nil {
- if errorhandling.Contains(err, define.ErrNoSuchCtr) ||
- errorhandling.Contains(err, define.ErrCtrRemoved) ||
- errorhandling.Contains(err, types.ErrLayerUnknown) {
- logrus.Debugf("Container %s does not exist: %v", con.ID, err)
- } else {
- logrus.Errorf("Removing container %s: %v", con.ID, err)
- }
- }
+ reports, err := containers.Remove(ic.ClientCtx, con.ID, new(containers.RemoveOptions).WithForce(false).WithVolumes(true))
+ logIfRmError(con.ID, err, reports)
}
}()
}
diff --git a/pkg/machine/config.go b/pkg/machine/config.go
index 33a352898..97237f5e5 100644
--- a/pkg/machine/config.go
+++ b/pkg/machine/config.go
@@ -29,6 +29,15 @@ type InitOptions struct {
ReExec bool
}
+type QemuMachineStatus = string
+
+const (
+ // Running indicates the qemu vm is running
+ Running QemuMachineStatus = "running"
+ // Stopped indicates the vm has stopped
+ Stopped QemuMachineStatus = "stopped"
+)
+
type Provider interface {
NewMachine(opts InitOptions) (VM, error)
LoadVMByName(name string) (VM, error)
@@ -66,15 +75,18 @@ type Download struct {
type ListOptions struct{}
type ListResponse struct {
- Name string
- CreatedAt time.Time
- LastUp time.Time
- Running bool
- Stream string
- VMType string
- CPUs uint64
- Memory uint64
- DiskSize uint64
+ Name string
+ CreatedAt time.Time
+ LastUp time.Time
+ Running bool
+ Stream string
+ VMType string
+ CPUs uint64
+ Memory uint64
+ DiskSize uint64
+ Port int
+ RemoteUsername string
+ IdentityPath string
}
type SSHOptions struct {
diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index 84d3be296..ac2cf71cf 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -10,6 +10,7 @@ import (
"os"
"path/filepath"
+ "github.com/containers/common/pkg/config"
"github.com/sirupsen/logrus"
)
@@ -340,6 +341,24 @@ machine_enabled=true
},
})
+ setProxyOpts := getProxyVariables()
+ if setProxyOpts != "" {
+ files = append(files, File{
+ Node: Node{
+ Group: getNodeGrp("root"),
+ Path: "/etc/profile.d/proxy-opts.sh",
+ User: getNodeUsr("root"),
+ },
+ FileEmbedded1: FileEmbedded1{
+ Append: nil,
+ Contents: Resource{
+ Source: encodeDataURLPtr(setProxyOpts),
+ },
+ Mode: intToPtr(0644),
+ },
+ })
+ }
+
setDockerHost := `export DOCKER_HOST="unix://$(podman info -f "{{.Host.RemoteSocket.Path}}")"
`
@@ -365,52 +384,110 @@ machine_enabled=true
return files
}
- certFiles := getCerts(filepath.Join(userHome, ".config/containers/certs.d"))
+ certFiles := getCerts(filepath.Join(userHome, ".config/containers/certs.d"), true)
files = append(files, certFiles...)
- certFiles = getCerts(filepath.Join(userHome, ".config/docker/certs.d"))
+ certFiles = getCerts(filepath.Join(userHome, ".config/docker/certs.d"), true)
files = append(files, certFiles...)
+ if sslCertFile, ok := os.LookupEnv("SSL_CERT_FILE"); ok {
+ if _, err := os.Stat(sslCertFile); err == nil {
+ certFiles = getCerts(sslCertFile, false)
+ files = append(files, certFiles...)
+
+ if len(certFiles) > 0 {
+ setSSLCertFile := fmt.Sprintf("export %s=%s", "SSL_CERT_FILE", filepath.Join("/etc/containers/certs.d", filepath.Base(sslCertFile)))
+ files = append(files, File{
+ Node: Node{
+ Group: getNodeGrp("root"),
+ Path: "/etc/profile.d/ssl_cert_file.sh",
+ User: getNodeUsr("root"),
+ },
+ FileEmbedded1: FileEmbedded1{
+ Append: nil,
+ Contents: Resource{
+ Source: encodeDataURLPtr(setSSLCertFile),
+ },
+ Mode: intToPtr(0644),
+ },
+ })
+ }
+ }
+ }
+
return files
}
-func getCerts(certsDir string) []File {
+func getCerts(certsDir string, isDir bool) []File {
var (
files []File
)
certs, err := ioutil.ReadDir(certsDir)
- if err == nil {
- for _, cert := range certs {
- b, err := ioutil.ReadFile(filepath.Join(certsDir, cert.Name()))
- if err != nil {
- logrus.Warnf("Unable to read cert file %s", err.Error())
- continue
- }
- files = append(files, File{
- Node: Node{
- Group: getNodeGrp("root"),
- Path: filepath.Join("/etc/containers/certs.d/", cert.Name()),
- User: getNodeUsr("root"),
- },
- FileEmbedded1: FileEmbedded1{
- Append: nil,
- Contents: Resource{
- Source: encodeDataURLPtr(string(b)),
+ if isDir {
+ if err == nil {
+ for _, cert := range certs {
+ b, err := ioutil.ReadFile(filepath.Join(certsDir, cert.Name()))
+ if err != nil {
+ logrus.Warnf("Unable to read cert file %s", err.Error())
+ continue
+ }
+ files = append(files, File{
+ Node: Node{
+ Group: getNodeGrp("root"),
+ Path: filepath.Join("/etc/containers/certs.d/", cert.Name()),
+ User: getNodeUsr("root"),
},
- Mode: intToPtr(0644),
- },
- })
+ FileEmbedded1: FileEmbedded1{
+ Append: nil,
+ Contents: Resource{
+ Source: encodeDataURLPtr(string(b)),
+ },
+ Mode: intToPtr(0644),
+ },
+ })
+ }
+ } else {
+ if !os.IsNotExist(err) {
+ logrus.Warnf("Unable to copy certs via ignition, error while reading certs from %s: %s", certsDir, err.Error())
+ }
}
} else {
- if !os.IsNotExist(err) {
- logrus.Warnf("Unable to copy certs via ignition, error while reading certs from %s: %s", certsDir, err.Error())
+ fileName := filepath.Base(certsDir)
+ b, err := ioutil.ReadFile(certsDir)
+ if err != nil {
+ logrus.Warnf("Unable to read cert file %s", err.Error())
+ return files
}
+ files = append(files, File{
+ Node: Node{
+ Group: getNodeGrp("root"),
+ Path: filepath.Join("/etc/containers/certs.d/", fileName),
+ User: getNodeUsr("root"),
+ },
+ FileEmbedded1: FileEmbedded1{
+ Append: nil,
+ Contents: Resource{
+ Source: encodeDataURLPtr(string(b)),
+ },
+ Mode: intToPtr(0644),
+ },
+ })
}
return files
}
+func getProxyVariables() string {
+ proxyOpts := ""
+ for _, variable := range config.ProxyEnv {
+ if value, ok := os.LookupEnv(variable); ok {
+ proxyOpts += fmt.Sprintf("\n export %s=%s", variable, value)
+ }
+ }
+ return proxyOpts
+}
+
func getLinks(usrName string) []Link {
return []Link{{
Node: Node{
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index f09107c71..560037542 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -386,8 +386,16 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
}
if len(v.Mounts) > 0 {
- for !v.isRunning() || !v.isListening() {
+ running, err := v.isRunning()
+ if err != nil {
+ return err
+ }
+ for running || !v.isListening() {
time.Sleep(100 * time.Millisecond)
+ running, err = v.isRunning()
+ if err != nil {
+ return err
+ }
}
}
for _, mount := range v.Mounts {
@@ -416,8 +424,48 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
return nil
}
+func (v *MachineVM) checkStatus(monitor *qmp.SocketMonitor) (machine.QemuMachineStatus, error) {
+ // this is the format returned from the monitor
+ // {"return": {"status": "running", "singlestep": false, "running": true}}
+
+ type statusDetails struct {
+ Status string `json:"status"`
+ Step bool `json:"singlestep"`
+ Running bool `json:"running"`
+ }
+ type statusResponse struct {
+ Response statusDetails `json:"return"`
+ }
+ var response statusResponse
+
+ checkCommand := struct {
+ Execute string `json:"execute"`
+ }{
+ Execute: "query-status",
+ }
+ input, err := json.Marshal(checkCommand)
+ if err != nil {
+ return "", err
+ }
+ b, err := monitor.Run(input)
+ if err != nil {
+ if errors.Cause(err) == os.ErrNotExist {
+ return machine.Stopped, nil
+ }
+ return "", err
+ }
+ if err := json.Unmarshal(b, &response); err != nil {
+ return "", err
+ }
+ if response.Response.Status == machine.Running {
+ return machine.Running, nil
+ }
+ return machine.Stopped, nil
+}
+
// Stop uses the qmp monitor to call a system_powerdown
func (v *MachineVM) Stop(name string, _ machine.StopOptions) error {
+ var disconnected bool
// check if the qmp socket is there. if not, qemu instance is gone
if _, err := os.Stat(v.QMPMonitor.Address); os.IsNotExist(err) {
// Right now it is NOT an error to stop a stopped machine
@@ -442,19 +490,22 @@ func (v *MachineVM) Stop(name string, _ machine.StopOptions) error {
return err
}
defer func() {
- if err := qmpMonitor.Disconnect(); err != nil {
- logrus.Error(err)
+ if !disconnected {
+ if err := qmpMonitor.Disconnect(); err != nil {
+ logrus.Error(err)
+ }
}
}()
+
if _, err = qmpMonitor.Run(input); err != nil {
return err
}
+
qemuSocketFile, pidFile, err := v.getSocketandPid()
if err != nil {
return err
}
if _, err := os.Stat(pidFile); os.IsNotExist(err) {
- logrus.Info(err)
return nil
}
pidString, err := ioutil.ReadFile(pidFile)
@@ -483,6 +534,24 @@ func (v *MachineVM) Stop(name string, _ machine.StopOptions) error {
return err
}
+ if err := qmpMonitor.Disconnect(); err != nil {
+ return nil
+ }
+
+ disconnected = true
+ waitInternal := 250 * time.Millisecond
+ for i := 0; i < 5; i++ {
+ running, err := v.isRunning()
+ if err != nil {
+ return err
+ }
+ if !running {
+ break
+ }
+ time.Sleep(waitInternal)
+ waitInternal = waitInternal * 2
+ }
+
return nil
}
@@ -519,7 +588,11 @@ func (v *MachineVM) Remove(name string, opts machine.RemoveOptions) (string, fun
)
// cannot remove a running vm
- if v.isRunning() {
+ running, err := v.isRunning()
+ if err != nil {
+ return "", nil, err
+ }
+ if running {
return "", nil, errors.Errorf("running vm %q cannot be destroyed", v.Name)
}
@@ -578,16 +651,33 @@ func (v *MachineVM) Remove(name string, opts machine.RemoveOptions) (string, fun
}, nil
}
-func (v *MachineVM) isRunning() bool {
+func (v *MachineVM) isRunning() (bool, error) {
// Check if qmp socket path exists
if _, err := os.Stat(v.QMPMonitor.Address); os.IsNotExist(err) {
- return false
+ return false, nil
}
// Check if we can dial it
- if _, err := qmp.NewSocketMonitor(v.QMPMonitor.Network, v.QMPMonitor.Address, v.QMPMonitor.Timeout); err != nil {
- return false
+ monitor, err := qmp.NewSocketMonitor(v.QMPMonitor.Network, v.QMPMonitor.Address, v.QMPMonitor.Timeout)
+ if err != nil {
+ return false, nil
}
- return true
+ if err := monitor.Connect(); err != nil {
+ return false, err
+ }
+ defer func() {
+ if err := monitor.Disconnect(); err != nil {
+ logrus.Error(err)
+ }
+ }()
+ // If there is a monitor, lets see if we can query state
+ state, err := v.checkStatus(monitor)
+ if err != nil {
+ return false, err
+ }
+ if state == machine.Running {
+ return true, nil
+ }
+ return false, nil
}
func (v *MachineVM) isListening() bool {
@@ -603,7 +693,11 @@ func (v *MachineVM) isListening() bool {
// SSH opens an interactive SSH session to the vm specified.
// Added ssh function to VM interface: pkg/machine/config/go : line 58
func (v *MachineVM) SSH(name string, opts machine.SSHOptions) error {
- if !v.isRunning() {
+ running, err := v.isRunning()
+ if err != nil {
+ return err
+ }
+ if !running {
return errors.Errorf("vm %q is not running.", v.Name)
}
@@ -696,6 +790,9 @@ func GetVMInfos() ([]*machine.ListResponse, error) {
listEntry.CPUs = vm.CPUs
listEntry.Memory = vm.Memory * units.MiB
listEntry.DiskSize = vm.DiskSize * units.GiB
+ listEntry.Port = vm.Port
+ listEntry.RemoteUsername = vm.RemoteUsername
+ listEntry.IdentityPath = vm.IdentityPath
fi, err := os.Stat(fullPath)
if err != nil {
return err
@@ -707,7 +804,11 @@ func GetVMInfos() ([]*machine.ListResponse, error) {
return err
}
listEntry.LastUp = fi.ModTime()
- if vm.isRunning() {
+ running, err := vm.isRunning()
+ if err != nil {
+ return err
+ }
+ if running {
listEntry.Running = true
}
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 5ec7c7b03..2c7b3c091 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -7,6 +7,7 @@ import (
"time"
"github.com/containers/common/libimage"
+ "github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
ann "github.com/containers/podman/v3/pkg/annotations"
@@ -126,16 +127,7 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
if s.EnvHost {
defaultEnvs = envLib.Join(defaultEnvs, osEnv)
} else if s.HTTPProxy {
- for _, envSpec := range []string{
- "http_proxy",
- "HTTP_PROXY",
- "https_proxy",
- "HTTPS_PROXY",
- "ftp_proxy",
- "FTP_PROXY",
- "no_proxy",
- "NO_PROXY",
- } {
+ for _, envSpec := range config.ProxyEnv {
if v, ok := osEnv[envSpec]; ok {
defaultEnvs[envSpec] = v
}
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index 6d9f598c9..b41ee8db0 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -291,7 +291,10 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
return nil, err
}
- envs[env.Name] = value
+ // Only set the env if the value is not ""
+ if value != "" {
+ envs[env.Name] = value
+ }
}
for _, envFrom := range opts.Container.EnvFrom {
cmEnvs, err := envVarsFrom(envFrom, opts)
diff --git a/pkg/specgen/generate/ports.go b/pkg/specgen/generate/ports.go
index b60cc1e98..34b43a62e 100644
--- a/pkg/specgen/generate/ports.go
+++ b/pkg/specgen/generate/ports.go
@@ -206,7 +206,7 @@ func ParsePortMapping(portMappings []types.PortMapping, exposePorts map[uint16][
}
// we do no longer need the original port mappings
- // set it to 0 length so we can resuse it to populate
+ // set it to 0 length so we can reuse it to populate
// the slice again while keeping the underlying capacity
portMappings = portMappings[:0]
diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go
index a18364882..31f96b933 100644
--- a/pkg/specgen/podspecgen.go
+++ b/pkg/specgen/podspecgen.go
@@ -97,7 +97,7 @@ type PodNetworkConfig struct {
// Map of networks names ot ids the container should join to.
// You can request additional settings for each network, you can
// set network aliases, static ips, static mac address and the
- // network interface name for this container on the specifc network.
+ // network interface name for this container on the specific network.
// If the map is empty and the bridge network mode is set the container
// will be joined to the default network.
Networks map[string]types.PerNetworkOptions
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index 5989456c9..6c1011a78 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -426,7 +426,7 @@ type ContainerNetworkConfig struct {
// Map of networks names ot ids the container should join to.
// You can request additional settings for each network, you can
// set network aliases, static ips, static mac address and the
- // network interface name for this container on the specifc network.
+ // network interface name for this container on the specific network.
// If the map is empty and the bridge network mode is set the container
// will be joined to the default network.
Networks map[string]nettypes.PerNetworkOptions
diff --git a/test/apiv2/12-imagesMore.at b/test/apiv2/12-imagesMore.at
index 3a5d5c096..96eba1db5 100644
--- a/test/apiv2/12-imagesMore.at
+++ b/test/apiv2/12-imagesMore.at
@@ -53,7 +53,7 @@ t GET libpod/images/$IMAGE/json 200 \
.RepoTags[-1]=$IMAGE
# Remove the registry container
-t DELETE libpod/containers/registry?force=true 204
+t DELETE libpod/containers/registry?force=true 200
# Remove images
t DELETE libpod/images/$IMAGE 200 \
diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at
index 554a905d4..936597f72 100644
--- a/test/apiv2/20-containers.at
+++ b/test/apiv2/20-containers.at
@@ -85,7 +85,7 @@ else
fi
fi
-t DELETE libpod/containers/$cid 204
+t DELETE libpod/containers/$cid 200 .[0].Id=$cid
# Issue #6799: it should be possible to start a container, even w/o args.
t POST libpod/containers/create?name=test_noargs Image=${IMAGE} 201 \
@@ -100,7 +100,7 @@ t GET libpod/containers/${cid}/json 200 \
.State.Status~\\\(exited\\\|stopped\\\) \
.State.Running=false \
.State.ExitCode=0
-t DELETE libpod/containers/$cid 204
+t DELETE libpod/containers/$cid 200 .[0].Id=$cid
CNAME=myfoo
podman run -d --name $CNAME $IMAGE top
@@ -190,8 +190,8 @@ t GET containers/myctr/json 200 \
t DELETE images/localhost/newrepo:latest?force=true 200
t DELETE images/localhost/newrepo:v1?force=true 200
t DELETE images/localhost/newrepo:v2?force=true 200
-t DELETE libpod/containers/$cid?force=true 204
-t DELETE libpod/containers/myctr 204
+t DELETE libpod/containers/$cid?force=true 200 .[0].Id=$cid
+t DELETE libpod/containers/myctr 200
t DELETE libpod/containers/bogus 404
diff --git a/test/apiv2/22-stop.at b/test/apiv2/22-stop.at
index 91bc9937d..bde534b72 100644
--- a/test/apiv2/22-stop.at
+++ b/test/apiv2/22-stop.at
@@ -11,7 +11,7 @@ podman run -dt --name mytop $IMAGE top &>/dev/null
t GET libpod/containers/mytop/json 200 .State.Status=running
t POST libpod/containers/mytop/stop 204
t GET libpod/containers/mytop/json 200 .State.Status~\\\(exited\\\|stopped\\\)
-t DELETE libpod/containers/mytop 204
+t DELETE libpod/containers/mytop 200
# stop, by ID
# Remember that podman() hides all output; we need to get our CID via inspect
@@ -21,4 +21,4 @@ t GET libpod/containers/mytop/json 200 .State.Status=running
cid=$(jq -r .Id <<<"$output")
t POST libpod/containers/$cid/stop 204
t GET libpod/containers/mytop/json 200 .State.Status~\\\(exited\\\|stopped\\\)
-t DELETE libpod/containers/mytop 204
+t DELETE libpod/containers/mytop 200
diff --git a/test/apiv2/25-containersMore.at b/test/apiv2/25-containersMore.at
index 0a049d869..c9fda8c6f 100644
--- a/test/apiv2/25-containersMore.at
+++ b/test/apiv2/25-containersMore.at
@@ -51,7 +51,7 @@ like "$output" ".*merged" "Check container mount"
# Unmount the container
t POST libpod/containers/foo/unmount 204
-t DELETE libpod/containers/foo?force=true 204
+t DELETE libpod/containers/foo?force=true 200
podman run $IMAGE true
@@ -79,7 +79,7 @@ like "$output" ".*metadata:.*" "Check generated kube yaml(service=true) - metada
like "$output" ".*spec:.*" "Check generated kube yaml(service=true) - spec"
like "$output" ".*kind:\\sService.*" "Check generated kube yaml(service=true) - kind: Service"
-t DELETE libpod/containers/$cid 204
+t DELETE libpod/containers/$cid 200 .[0].Id=$cid
# Create 3 stopped containers to test containers prune
podman run $IMAGE true
diff --git a/test/apiv2/python/rest_api/test_v2_0_0_container.py b/test/apiv2/python/rest_api/test_v2_0_0_container.py
index 101044bbb..1b4597cf8 100644
--- a/test/apiv2/python/rest_api/test_v2_0_0_container.py
+++ b/test/apiv2/python/rest_api/test_v2_0_0_container.py
@@ -99,7 +99,7 @@ class ContainerTestCase(APITestCase):
def test_delete(self):
r = requests.delete(self.uri(self.resolve_container("/containers/{}?force=true")))
- self.assertEqual(r.status_code, 204, r.text)
+ self.assertEqual(r.status_code, 200, r.text)
def test_stop(self):
r = requests.post(self.uri(self.resolve_container("/containers/{}/start")))
diff --git a/test/buildah-bud/apply-podman-deltas b/test/buildah-bud/apply-podman-deltas
index 44a33b0b8..e42c8aa52 100755
--- a/test/buildah-bud/apply-podman-deltas
+++ b/test/buildah-bud/apply-podman-deltas
@@ -191,6 +191,16 @@ skip_if_remote "--stdin option will not be implemented in podman-remote" \
# BEGIN tests which are skipped due to actual podman-remote bugs.
###############################################################################
+# BEGIN emergency handling of github git-protocol shutdown
+#
+# Please remove this as soon as we vendor buildah with #3701
+
+skip "emergency workaround until buildah #3701 gets vendored in" \
+ "bud-git-context" \
+ "bud using gitrepo and branch"
+
+# END emergency handling of github git-protocol shutdown
+###############################################################################
# Done.
exit $RC
diff --git a/test/e2e/containers_conf_test.go b/test/e2e/containers_conf_test.go
index 2a6f177f2..838221dd5 100644
--- a/test/e2e/containers_conf_test.go
+++ b/test/e2e/containers_conf_test.go
@@ -452,4 +452,36 @@ var _ = Describe("Podman run", func() {
Expect(result).Should(Exit(0))
Expect(result.OutputToString()).To(ContainSubstring("(default 1234)"))
})
+
+ It("podman bad infra_image name in containers.conf", func() {
+ infra1 := "i.do/not/exist:image"
+ infra2 := "i.still.do/not/exist:image"
+ errorString := "initializing source docker://" + infra1
+ error2String := "initializing source docker://" + infra2
+ configPath := filepath.Join(podmanTest.TempDir, "containers.conf")
+ os.Setenv("CONTAINERS_CONF", configPath)
+
+ containersConf := []byte("[engine]\ninfra_image=\"" + infra1 + "\"")
+ err = ioutil.WriteFile(configPath, containersConf, os.ModePerm)
+ Expect(err).To(BeNil())
+
+ if IsRemote() {
+ podmanTest.RestartRemoteService()
+ }
+
+ result := podmanTest.Podman([]string{"pod", "create", "--infra-image", infra2})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring(error2String))
+
+ result = podmanTest.Podman([]string{"pod", "create"})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring(errorString))
+
+ result = podmanTest.Podman([]string{"create", "--pod", "new:pod1", ALPINE})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring(errorString))
+ })
})
diff --git a/test/e2e/events_test.go b/test/e2e/events_test.go
index 39f495460..3b5b8ac6c 100644
--- a/test/e2e/events_test.go
+++ b/test/e2e/events_test.go
@@ -62,6 +62,8 @@ var _ = Describe("Podman events", func() {
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
Expect(len(result.OutputToStringArray())).To(BeNumerically(">=", 1), "Number of events")
+ date := time.Now().Format("2006-01-02")
+ Expect(result.OutputToStringArray()).To(ContainElement(HavePrefix(date)), "event log has correct timestamp")
})
It("podman events with an event filter and container=cid", func() {
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index 1c7eb09a4..71bfd1e99 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -1659,7 +1659,7 @@ var _ = Describe("Podman play kube", func() {
inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ range .Config.Env }}[{{ . }}]{{end}}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(Exit(0))
- Expect(inspect.OutputToString()).To(ContainSubstring(`[FOO=]`))
+ Expect(inspect.OutputToString()).To(Not(ContainSubstring(`[FOO=]`)))
})
It("podman play kube test optional env value from missing configmap", func() {
@@ -1674,7 +1674,7 @@ var _ = Describe("Podman play kube", func() {
inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ range .Config.Env }}[{{ . }}]{{end}}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(Exit(0))
- Expect(inspect.OutputToString()).To(ContainSubstring(`[FOO=]`))
+ Expect(inspect.OutputToString()).To(Not(ContainSubstring(`[FOO=]`)))
})
It("podman play kube test get all key-value pairs from configmap as envs", func() {
@@ -1768,7 +1768,7 @@ var _ = Describe("Podman play kube", func() {
inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ range .Config.Env }}[{{ . }}]{{end}}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(Exit(0))
- Expect(inspect.OutputToString()).To(ContainSubstring(`[FOO=]`))
+ Expect(inspect.OutputToString()).To(Not(ContainSubstring(`[FOO=]`)))
})
It("podman play kube test optional env value from secret with missing key", func() {
@@ -1784,7 +1784,7 @@ var _ = Describe("Podman play kube", func() {
inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ range .Config.Env }}[{{ . }}]{{end}}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(Exit(0))
- Expect(inspect.OutputToString()).To(ContainSubstring(`[FOO=]`))
+ Expect(inspect.OutputToString()).To(Not(ContainSubstring(`[FOO=]`)))
})
It("podman play kube test get all key-value pairs from secret as envs", func() {
@@ -3212,7 +3212,7 @@ ENV OPENJ9_JAVA_OPTIONS=%q
inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ range .Config.Env }}[{{ . }}]{{end}}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(Exit(0))
- Expect(inspect.OutputToString()).To(ContainSubstring(`[FOO=]`))
+ Expect(inspect.OutputToString()).To(Not(ContainSubstring(`[FOO=]`)))
})
It("podman play kube uses all key-value pairs as envs", func() {
diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go
index f22acca6e..38afff9bd 100644
--- a/test/e2e/pull_test.go
+++ b/test/e2e/pull_test.go
@@ -354,13 +354,13 @@ var _ = Describe("Podman pull", func() {
session = podmanTest.Podman([]string{"rmi", "cirros"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- session = podmanTest.Podman([]string{"pull", imgPath})
+ session = podmanTest.Podman([]string{"run", imgPath, "ls"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- session = podmanTest.Podman([]string{"images"})
+ // Note that reference is not preserved in dir.
+ session = podmanTest.Podman([]string{"image", "exists", "cirros"})
session.WaitWithDefaultTimeout()
- Expect(session).Should(Exit(0))
- Expect(session.LineInOutputContainsTag(filepath.Join("localhost", dirpath), "latest")).To(BeTrue())
+ Expect(session).Should(Exit(1))
})
It("podman pull from local OCI directory", func() {
diff --git a/test/system/001-basic.bats b/test/system/001-basic.bats
index 23489c1b5..9b0a71285 100644
--- a/test/system/001-basic.bats
+++ b/test/system/001-basic.bats
@@ -41,7 +41,7 @@ function setup() {
# This one must fail
run_podman 125 --context=swarm version
is "$output" \
- "Error: Podman does not support swarm, the only --context value allowed is \"default\"" \
+ "Error: podman does not support swarm, the only --context value allowed is \"default\"" \
"--context=default or fail"
}
diff --git a/test/system/010-images.bats b/test/system/010-images.bats
index 201418620..ebd71450f 100644
--- a/test/system/010-images.bats
+++ b/test/system/010-images.bats
@@ -272,6 +272,10 @@ Deleted: $pauseID" "infra images gets removed as well"
is "$output" ""
run_podman create --pod new:$pname $IMAGE
+ # Clean up
+ run_podman rm "${lines[-1]}"
+ run_podman pod rm -a
+ run_podman rmi $pauseImage
}
@test "podman images - rmi -f can remove infra images" {
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index feca5370b..afcda3d3c 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -509,6 +509,21 @@ json-file | f
rm -f $new_runtime
}
+@test "podman --noout run should print output" {
+ run_podman --noout run -d --name test $IMAGE echo hi
+ is "$output" "" "output should be empty"
+ run_podman wait test
+ run_podman --noout rm test
+ is "$output" "" "output should be empty"
+}
+
+@test "podman --noout create should print output" {
+ run_podman --noout create --name test $IMAGE echo hi
+ is "$output" "" "output should be empty"
+ run_podman --noout rm test
+ is "$output" "" "output should be empty"
+}
+
# Regression test for issue #8082
@test "podman run : look up correct image name" {
# Create a 2nd tag for the local image. Force to lower case, and apply it.
diff --git a/test/system/035-logs.bats b/test/system/035-logs.bats
index 3caf97a22..db50c8f8c 100644
--- a/test/system/035-logs.bats
+++ b/test/system/035-logs.bats
@@ -90,14 +90,16 @@ ${cid[0]} d" "Sequential output from logs"
}
function _log_test_restarted() {
- run_podman run --log-driver=$1 --name logtest $IMAGE sh -c 'start=0; if test -s log; then start=`tail -n 1 log`; fi; seq `expr $start + 1` `expr $start + 10` | tee -a log'
+ local driver=$1
+ local events_backend=$(_additional_events_backend $driver)
+ run_podman run --log-driver=$driver ${events_backend} --name logtest $IMAGE sh -c 'start=0; if test -s log; then start=`tail -n 1 log`; fi; seq `expr $start + 1` `expr $start + 10` | tee -a log'
# FIXME: #9597
# run/start is flaking for remote so let's wait for the container condition
# to stop wasting energy until the root cause gets fixed.
run_podman container wait --condition=exited logtest
- run_podman start -a logtest
+ run_podman ${events_backend} start -a logtest
logfile=$(mktemp -p ${PODMAN_TMPDIR} logfileXXXXXXXX)
- $PODMAN $_PODMAN_TEST_OPTS logs -f logtest > $logfile
+ $PODMAN $_PODMAN_TEST_OPTS ${events_backend} logs -f logtest > $logfile
expected=$(mktemp -p ${PODMAN_TMPDIR} expectedXXXXXXXX)
seq 1 20 > $expected
diff -u ${expected} ${logfile}
diff --git a/test/system/050-stop.bats b/test/system/050-stop.bats
index e049da518..7dd8f98e8 100644
--- a/test/system/050-stop.bats
+++ b/test/system/050-stop.bats
@@ -173,4 +173,9 @@ load helpers
is "$output" ".*StopSignal SIGTERM failed to stop container stopme in 1 seconds, resorting to SIGKILL" "stopping container should print warning"
}
+@test "podman stop --noout" {
+ run_podman run --rm --name stopme -d $IMAGE top
+ run_podman --noout stop -t 0 stopme
+ is "$output" "" "output should be empty"
+}
# vim: filetype=sh
diff --git a/test/system/055-rm.bats b/test/system/055-rm.bats
index 7fe81c084..69663fafa 100644
--- a/test/system/055-rm.bats
+++ b/test/system/055-rm.bats
@@ -58,6 +58,18 @@ load helpers
run_podman rm -af
}
+@test "podman rm --depend" {
+ run_podman create $IMAGE
+ dependCid=$output
+ run_podman create --net=container:$dependCid $IMAGE
+ cid=$output
+ run_podman 125 rm $dependCid
+ is "$output" "Error: container $dependCid has dependent containers which must be removed before it:.*" "Fail to remove because of dependencies"
+ run_podman rm --depend $dependCid
+ is "$output" ".*$cid" "Container should have been removed"
+ is "$output" ".*$dependCid" "Depend container should have been removed"
+}
+
# I'm sorry! This test takes 13 seconds. There's not much I can do about it,
# please know that I think it's justified: podman 1.5.0 had a strange bug
# in with exit status was not preserved on some code paths with 'rm -f'
diff --git a/test/system/080-pause.bats b/test/system/080-pause.bats
index 857c8bbf4..57f390a74 100644
--- a/test/system/080-pause.bats
+++ b/test/system/080-pause.bats
@@ -21,7 +21,8 @@ load helpers
# time to write a new post-restart time value. Pause by CID, unpause
# by name, just to exercise code paths. While paused, check 'ps'
# and 'inspect', then check again after restarting.
- run_podman pause $cid
+ run_podman --noout pause $cid
+ is "$output" "" "output should be empty"
run_podman inspect --format '{{.State.Status}}' $cid
is "$output" "paused" "podman inspect .State.Status"
sleep 3
diff --git a/test/system/090-events.bats b/test/system/090-events.bats
index 5af6a3793..a0b0380a2 100644
--- a/test/system/090-events.bats
+++ b/test/system/090-events.bats
@@ -116,3 +116,16 @@ function _events_disjunctive_filters() {
@test "events with disjunctive filters - default" {
_events_disjunctive_filters ""
}
+
+@test "events with events_logfile_path in containers.conf" {
+ skip_if_remote "remote does not support --events-backend"
+ events_file=$PODMAN_TMPDIR/events.log
+ containersconf=$PODMAN_TMPDIR/containers.conf
+ cat >$containersconf <<EOF
+[engine]
+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"
+}
diff --git a/test/system/170-run-userns.bats b/test/system/170-run-userns.bats
index a5be591ef..c020a73ab 100644
--- a/test/system/170-run-userns.bats
+++ b/test/system/170-run-userns.bats
@@ -78,3 +78,19 @@ EOF
# Then check that the main user is not mapped into the user namespace
CONTAINERS_CONF=$PODMAN_TMPDIR/userns_auto.conf run_podman 0 run --rm $IMAGE awk '{if($2 == "0"){exit 1}}' /proc/self/uid_map /proc/self/gid_map
}
+
+@test "podman userns=auto and secrets" {
+ ns_user="containers"
+ if is_rootless; then
+ ns_user=$(id -un)
+ fi
+ egrep -q "${ns_user}:" /etc/subuid || skip "no IDs allocated for user ${ns_user}"
+ test_name="test_$(random_string 12)"
+ secret_file=$PODMAN_TMPDIR/secret$(random_string 12)
+ secret_content=$(random_string)
+ echo ${secret_content} > ${secret_file}
+ run_podman secret create ${test_name} ${secret_file}
+ run_podman run --rm --secret=${test_name} --userns=auto:size=1000 $IMAGE cat /run/secrets/${test_name}
+ is ${output} ${secret_content} "Secrets should work with user namespace"
+ run_podman secret rm ${test_name}
+}
diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats
index 57d052ce2..4a3337e57 100644
--- a/test/system/200-pod.bats
+++ b/test/system/200-pod.bats
@@ -57,13 +57,14 @@ function teardown() {
fi
# Clean up
- run_podman pod rm -f -t 0 $podid
+ run_podman --noout pod rm -f -t 0 $podid
+ is "$output" "" "output should be empty"
}
@test "podman pod create - custom infra image" {
+ skip_if_remote "CONTAINERS_CONF only effects server side"
image="i.do/not/exist:image"
-
tmpdir=$PODMAN_TMPDIR/pod-test
run mkdir -p $tmpdir
containersconf=$tmpdir/containers.conf
@@ -77,6 +78,9 @@ EOF
CONTAINERS_CONF=$containersconf run_podman 125 pod create
is "$output" ".*initializing source docker://$image:.*"
+
+ CONTAINERS_CONF=$containersconf run_podman 125 create --pod new:test $IMAGE
+ is "$output" ".*initializing source docker://$image:.*"
}
@test "podman pod - communicating between pods" {
@@ -327,7 +331,8 @@ EOF
# Note that the internal pause image is built even when --infra-image is
# set to the K8s one.
- run_podman pod create --name $pod_name --infra-name "$infra_name" --infra-image "k8s.gcr.io/pause:3.5"
+ run_podman --noout pod create --name $pod_name --infra-name "$infra_name" --infra-image "k8s.gcr.io/pause:3.5"
+ is "$output" "" "output 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"
diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats
index c49727cc9..c47679904 100644
--- a/test/system/250-systemd.bats
+++ b/test/system/250-systemd.bats
@@ -276,4 +276,9 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
is "$output" ".*--template cannot be set" "Error message should be '--template requires --new'"
}
+@test "podman --cgroup=cgroupfs doesn't show systemd warning" {
+ DBUS_SESSION_BUS_ADDRESS= run_podman --log-level warning --cgroup-manager=cgroupfs info -f ''
+ is "$output" "" "output should be empty"
+}
+
# vim: filetype=sh
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index 2b5ad44dc..5a721c965 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -332,7 +332,8 @@ load helpers
is_rootless || skip "only meaningful for rootless"
local mynetname=testnet-$(random_string 10)
- run_podman network create $mynetname
+ run_podman --noout network create $mynetname
+ is "$output" "" "output should be empty"
# Test that rootless cni adds /usr/sbin to $PATH
# iptables is located under /usr/sbin and is needed for the CNI plugins.
@@ -340,7 +341,8 @@ load helpers
PATH=/usr/local/bin:/usr/bin run_podman run --rm --network $mynetname $IMAGE ip addr
is "$output" ".*eth0.*" "Interface eth0 not found in ip addr output"
- run_podman network rm -t 0 -f $mynetname
+ run_podman --noout network rm -t 0 -f $mynetname
+ is "$output" "" "output should be empty"
}
@test "podman ipv6 in /etc/resolv.conf" {
diff --git a/vendor/github.com/BurntSushi/toml/README.md b/vendor/github.com/BurntSushi/toml/README.md
index 64410cf75..cc13f8667 100644
--- a/vendor/github.com/BurntSushi/toml/README.md
+++ b/vendor/github.com/BurntSushi/toml/README.md
@@ -1,10 +1,6 @@
-## TOML parser and encoder for Go with reflection
-
TOML stands for Tom's Obvious, Minimal Language. This Go package provides a
reflection interface similar to Go's standard library `json` and `xml`
-packages. This package also supports the `encoding.TextUnmarshaler` and
-`encoding.TextMarshaler` interfaces so that you can define custom data
-representations. (There is an example of this below.)
+packages.
Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0).
@@ -16,26 +12,25 @@ v0.4.0`).
This library requires Go 1.13 or newer; install it with:
- $ go get github.com/BurntSushi/toml
+ % go get github.com/BurntSushi/toml@latest
It also comes with a TOML validator CLI tool:
- $ go get github.com/BurntSushi/toml/cmd/tomlv
- $ tomlv some-toml-file.toml
+ % go install github.com/BurntSushi/toml/cmd/tomlv@latest
+ % tomlv some-toml-file.toml
### Testing
+This package passes all tests in [toml-test] for both the decoder and the
+encoder.
-This package passes all tests in
-[toml-test](https://github.com/BurntSushi/toml-test) for both the decoder
-and the encoder.
+[toml-test]: https://github.com/BurntSushi/toml-test
### Examples
+This package works similar to how the Go standard library handles XML and JSON.
+Namely, data is loaded into Go values via reflection.
-This package works similarly to how the Go standard library handles XML and
-JSON. Namely, data is loaded into Go values via reflection.
-
-For the simplest example, consider some TOML file as just a list of keys
-and values:
+For the simplest example, consider some TOML file as just a list of keys and
+values:
```toml
Age = 25
@@ -61,9 +56,8 @@ And then decoded with:
```go
var conf Config
-if _, err := toml.Decode(tomlData, &conf); err != nil {
- // handle error
-}
+err := toml.Decode(tomlData, &conf)
+// handle error
```
You can also use struct tags if your struct field name doesn't map to a TOML
@@ -75,15 +69,14 @@ some_key_NAME = "wat"
```go
type TOML struct {
- ObscureKey string `toml:"some_key_NAME"`
+ ObscureKey string `toml:"some_key_NAME"`
}
```
Beware that like other most other decoders **only exported fields** are
considered when encoding and decoding; private fields are silently ignored.
-### Using the `encoding.TextUnmarshaler` interface
-
+### Using the `Marshaler` and `encoding.TextUnmarshaler` interfaces
Here's an example that automatically parses duration strings into
`time.Duration` values:
@@ -136,7 +129,6 @@ To target TOML specifically you can implement `UnmarshalTOML` TOML interface in
a similar way.
### More complex usage
-
Here's an example of how to load the example from the official spec page:
```toml
@@ -216,5 +208,4 @@ type clients struct {
Note that a case insensitive match will be tried if an exact match can't be
found.
-A working example of the above can be found in `_examples/example.{go,toml}`.
-
+A working example of the above can be found in `_example/example.{go,toml}`.
diff --git a/vendor/github.com/BurntSushi/toml/decode.go b/vendor/github.com/BurntSushi/toml/decode.go
index d3d3b8397..e24f0c5d5 100644
--- a/vendor/github.com/BurntSushi/toml/decode.go
+++ b/vendor/github.com/BurntSushi/toml/decode.go
@@ -9,7 +9,6 @@ import (
"os"
"reflect"
"strings"
- "time"
)
// Unmarshaler is the interface implemented by objects that can unmarshal a
@@ -40,6 +39,13 @@ type Primitive struct {
context Key
}
+// The significand precision for float32 and float64 is 24 and 53 bits; this is
+// the range a natural number can be stored in a float without loss of data.
+const (
+ maxSafeFloat32Int = 16777215 // 2^24-1
+ maxSafeFloat64Int = 9007199254740991 // 2^53-1
+)
+
// PrimitiveDecode is just like the other `Decode*` functions, except it
// decodes a TOML value that has already been parsed. Valid primitive values
// can *only* be obtained from values filled by the decoder functions,
@@ -100,18 +106,38 @@ func NewDecoder(r io.Reader) *Decoder {
return &Decoder{r: r}
}
+var (
+ unmarshalToml = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
+ unmarshalText = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+)
+
// Decode TOML data in to the pointer `v`.
func (dec *Decoder) Decode(v interface{}) (MetaData, error) {
rv := reflect.ValueOf(v)
if rv.Kind() != reflect.Ptr {
- return MetaData{}, e("Decode of non-pointer %s", reflect.TypeOf(v))
+ s := "%q"
+ if reflect.TypeOf(v) == nil {
+ s = "%v"
+ }
+
+ return MetaData{}, e("cannot decode to non-pointer "+s, reflect.TypeOf(v))
}
if rv.IsNil() {
- return MetaData{}, e("Decode of nil %s", reflect.TypeOf(v))
+ return MetaData{}, e("cannot decode to nil value of %q", reflect.TypeOf(v))
+ }
+
+ // Check if this is a supported type: struct, map, interface{}, or something
+ // that implements UnmarshalTOML or UnmarshalText.
+ rv = indirect(rv)
+ rt := rv.Type()
+ if rv.Kind() != reflect.Struct && rv.Kind() != reflect.Map &&
+ !(rv.Kind() == reflect.Interface && rv.NumMethod() == 0) &&
+ !rt.Implements(unmarshalToml) && !rt.Implements(unmarshalText) {
+ return MetaData{}, e("cannot decode to type %s", rt)
}
- // TODO: have parser should read from io.Reader? Or at the very least, make
- // it read from []byte rather than string
+ // TODO: parser should read from io.Reader? Or at the very least, make it
+ // read from []byte rather than string
data, err := ioutil.ReadAll(dec.r)
if err != nil {
return MetaData{}, err
@@ -121,11 +147,15 @@ func (dec *Decoder) Decode(v interface{}) (MetaData, error) {
if err != nil {
return MetaData{}, err
}
+
md := MetaData{
- p.mapping, p.types, p.ordered,
- make(map[string]bool, len(p.ordered)), nil,
+ mapping: p.mapping,
+ types: p.types,
+ keys: p.ordered,
+ decoded: make(map[string]struct{}, len(p.ordered)),
+ context: nil,
}
- return md, md.unify(p.mapping, indirect(rv))
+ return md, md.unify(p.mapping, rv)
}
// Decode the TOML data in to the pointer v.
@@ -218,9 +248,7 @@ func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
return e("unsupported type %s", rv.Type())
}
return md.unifyAnything(data, rv)
- case reflect.Float32:
- fallthrough
- case reflect.Float64:
+ case reflect.Float32, reflect.Float64:
return md.unifyFloat64(data, rv)
}
return e("unsupported type %s", rv.Kind())
@@ -254,17 +282,17 @@ func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error {
for _, i := range f.index {
subv = indirect(subv.Field(i))
}
+
if isUnifiable(subv) {
- md.decoded[md.context.add(key).String()] = true
+ md.decoded[md.context.add(key).String()] = struct{}{}
md.context = append(md.context, key)
- if err := md.unify(datum, subv); err != nil {
+ err := md.unify(datum, subv)
+ if err != nil {
return err
}
md.context = md.context[0 : len(md.context)-1]
} else if f.name != "" {
- // Bad user! No soup for you!
- return e("cannot write unexported field %s.%s",
- rv.Type().String(), f.name)
+ return e("cannot write unexported field %s.%s", rv.Type().String(), f.name)
}
}
}
@@ -283,22 +311,22 @@ func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error {
if tmap == nil {
return nil
}
- return badtype("map", mapping)
+ return md.badtype("map", mapping)
}
if rv.IsNil() {
rv.Set(reflect.MakeMap(rv.Type()))
}
for k, v := range tmap {
- md.decoded[md.context.add(k).String()] = true
+ md.decoded[md.context.add(k).String()] = struct{}{}
md.context = append(md.context, k)
- rvkey := indirect(reflect.New(rv.Type().Key()))
rvval := reflect.Indirect(reflect.New(rv.Type().Elem()))
if err := md.unify(v, rvval); err != nil {
return err
}
md.context = md.context[0 : len(md.context)-1]
+ rvkey := indirect(reflect.New(rv.Type().Key()))
rvkey.SetString(k)
rv.SetMapIndex(rvkey, rvval)
}
@@ -311,7 +339,7 @@ func (md *MetaData) unifyArray(data interface{}, rv reflect.Value) error {
if !datav.IsValid() {
return nil
}
- return badtype("slice", data)
+ return md.badtype("slice", data)
}
if l := datav.Len(); l != rv.Len() {
return e("expected array length %d; got TOML array of length %d", rv.Len(), l)
@@ -325,7 +353,7 @@ func (md *MetaData) unifySlice(data interface{}, rv reflect.Value) error {
if !datav.IsValid() {
return nil
}
- return badtype("slice", data)
+ return md.badtype("slice", data)
}
n := datav.Len()
if rv.IsNil() || rv.Cap() < n {
@@ -346,26 +374,21 @@ func (md *MetaData) unifySliceArray(data, rv reflect.Value) error {
return nil
}
-func (md *MetaData) unifyDatetime(data interface{}, rv reflect.Value) error {
- if _, ok := data.(time.Time); ok {
- rv.Set(reflect.ValueOf(data))
- return nil
- }
- return badtype("time.Time", data)
-}
-
func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error {
if s, ok := data.(string); ok {
rv.SetString(s)
return nil
}
- return badtype("string", data)
+ return md.badtype("string", data)
}
func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {
if num, ok := data.(float64); ok {
switch rv.Kind() {
case reflect.Float32:
+ if num < -math.MaxFloat32 || num > math.MaxFloat32 {
+ return e("value %f is out of range for float32", num)
+ }
fallthrough
case reflect.Float64:
rv.SetFloat(num)
@@ -374,7 +397,26 @@ func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {
}
return nil
}
- return badtype("float", data)
+
+ if num, ok := data.(int64); ok {
+ switch rv.Kind() {
+ case reflect.Float32:
+ if num < -maxSafeFloat32Int || num > maxSafeFloat32Int {
+ return e("value %d is out of range for float32", num)
+ }
+ fallthrough
+ case reflect.Float64:
+ if num < -maxSafeFloat64Int || num > maxSafeFloat64Int {
+ return e("value %d is out of range for float64", num)
+ }
+ rv.SetFloat(float64(num))
+ default:
+ panic("bug")
+ }
+ return nil
+ }
+
+ return md.badtype("float", data)
}
func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error {
@@ -421,7 +463,7 @@ func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error {
}
return nil
}
- return badtype("integer", data)
+ return md.badtype("integer", data)
}
func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error {
@@ -429,7 +471,7 @@ func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error {
rv.SetBool(b)
return nil
}
- return badtype("boolean", data)
+ return md.badtype("boolean", data)
}
func (md *MetaData) unifyAnything(data interface{}, rv reflect.Value) error {
@@ -440,6 +482,12 @@ func (md *MetaData) unifyAnything(data interface{}, rv reflect.Value) error {
func (md *MetaData) unifyText(data interface{}, v encoding.TextUnmarshaler) error {
var s string
switch sdata := data.(type) {
+ case Marshaler:
+ text, err := sdata.MarshalTOML()
+ if err != nil {
+ return err
+ }
+ s = string(text)
case TextMarshaler:
text, err := sdata.MarshalText()
if err != nil {
@@ -457,7 +505,7 @@ func (md *MetaData) unifyText(data interface{}, v encoding.TextUnmarshaler) erro
case float64:
s = fmt.Sprintf("%f", sdata)
default:
- return badtype("primitive (string-like)", data)
+ return md.badtype("primitive (string-like)", data)
}
if err := v.UnmarshalText([]byte(s)); err != nil {
return err
@@ -465,17 +513,22 @@ func (md *MetaData) unifyText(data interface{}, v encoding.TextUnmarshaler) erro
return nil
}
+func (md *MetaData) badtype(dst string, data interface{}) error {
+ return e("incompatible types: TOML key %q has type %T; destination has type %s", md.context, data, dst)
+}
+
// rvalue returns a reflect.Value of `v`. All pointers are resolved.
func rvalue(v interface{}) reflect.Value {
return indirect(reflect.ValueOf(v))
}
// indirect returns the value pointed to by a pointer.
-// Pointers are followed until the value is not a pointer.
-// New values are allocated for each nil pointer.
//
-// An exception to this rule is if the value satisfies an interface of
-// interest to us (like encoding.TextUnmarshaler).
+// Pointers are followed until the value is not a pointer. New values are
+// allocated for each nil pointer.
+//
+// An exception to this rule is if the value satisfies an interface of interest
+// to us (like encoding.TextUnmarshaler).
func indirect(v reflect.Value) reflect.Value {
if v.Kind() != reflect.Ptr {
if v.CanSet() {
@@ -505,7 +558,3 @@ func isUnifiable(rv reflect.Value) bool {
func e(format string, args ...interface{}) error {
return fmt.Errorf("toml: "+format, args...)
}
-
-func badtype(expected string, data interface{}) error {
- return e("cannot load TOML value of type %T into a Go %s", data, expected)
-}
diff --git a/vendor/github.com/BurntSushi/toml/decode_go116.go b/vendor/github.com/BurntSushi/toml/decode_go116.go
index 38aa75fdc..eddfb641b 100644
--- a/vendor/github.com/BurntSushi/toml/decode_go116.go
+++ b/vendor/github.com/BurntSushi/toml/decode_go116.go
@@ -1,3 +1,4 @@
+//go:build go1.16
// +build go1.16
package toml
diff --git a/vendor/github.com/BurntSushi/toml/deprecated.go b/vendor/github.com/BurntSushi/toml/deprecated.go
index db89eac1d..c6af3f239 100644
--- a/vendor/github.com/BurntSushi/toml/deprecated.go
+++ b/vendor/github.com/BurntSushi/toml/deprecated.go
@@ -5,29 +5,17 @@ import (
"io"
)
-// DEPRECATED!
-//
-// Use the identical encoding.TextMarshaler instead. It is defined here to
-// support Go 1.1 and older.
+// Deprecated: use encoding.TextMarshaler
type TextMarshaler encoding.TextMarshaler
-// DEPRECATED!
-//
-// Use the identical encoding.TextUnmarshaler instead. It is defined here to
-// support Go 1.1 and older.
+// Deprecated: use encoding.TextUnmarshaler
type TextUnmarshaler encoding.TextUnmarshaler
-// DEPRECATED!
-//
-// Use MetaData.PrimitiveDecode instead.
+// Deprecated: use MetaData.PrimitiveDecode.
func PrimitiveDecode(primValue Primitive, v interface{}) error {
- md := MetaData{decoded: make(map[string]bool)}
+ md := MetaData{decoded: make(map[string]struct{})}
return md.unify(primValue.undecoded, rvalue(v))
}
-// DEPRECATED!
-//
-// Use NewDecoder(reader).Decode(&v) instead.
-func DecodeReader(r io.Reader, v interface{}) (MetaData, error) {
- return NewDecoder(r).Decode(v)
-}
+// Deprecated: use NewDecoder(reader).Decode(&value).
+func DecodeReader(r io.Reader, v interface{}) (MetaData, error) { return NewDecoder(r).Decode(v) }
diff --git a/vendor/github.com/BurntSushi/toml/encode.go b/vendor/github.com/BurntSushi/toml/encode.go
index 10d88ac63..dee4e6d31 100644
--- a/vendor/github.com/BurntSushi/toml/encode.go
+++ b/vendor/github.com/BurntSushi/toml/encode.go
@@ -21,12 +21,11 @@ type tomlEncodeError struct{ error }
var (
errArrayNilElement = errors.New("toml: cannot encode array with nil element")
errNonString = errors.New("toml: cannot encode a map with non-string key type")
- errAnonNonStruct = errors.New("toml: cannot encode an anonymous field that is not a struct")
errNoKey = errors.New("toml: top-level values must be Go maps or structs")
errAnything = errors.New("") // used in testing
)
-var quotedReplacer = strings.NewReplacer(
+var dblQuotedReplacer = strings.NewReplacer(
"\"", "\\\"",
"\\", "\\\\",
"\x00", `\u0000`,
@@ -64,13 +63,22 @@ var quotedReplacer = strings.NewReplacer(
"\x7f", `\u007f`,
)
+// Marshaler is the interface implemented by types that can marshal themselves
+// into valid TOML.
+type Marshaler interface {
+ MarshalTOML() ([]byte, error)
+}
+
// Encoder encodes a Go to a TOML document.
//
// The mapping between Go values and TOML values should be precisely the same as
-// for the Decode* functions. Similarly, the TextMarshaler interface is
-// supported by encoding the resulting bytes as strings. If you want to write
-// arbitrary binary data then you will need to use something like base64 since
-// TOML does not have any binary types.
+// for the Decode* functions.
+//
+// The toml.Marshaler and encoder.TextMarshaler interfaces are supported to
+// encoding the value as custom TOML.
+//
+// If you want to write arbitrary binary data then you will need to use
+// something like base64 since TOML does not have any binary types.
//
// When encoding TOML hashes (Go maps or structs), keys without any sub-hashes
// are encoded first.
@@ -83,16 +91,14 @@ var quotedReplacer = strings.NewReplacer(
// structs. (e.g. [][]map[string]string is not allowed but []map[string]string
// is okay, as is []map[string][]string).
//
-// NOTE: Only exported keys are encoded due to the use of reflection. Unexported
+// NOTE: only exported keys are encoded due to the use of reflection. Unexported
// keys are silently discarded.
type Encoder struct {
- // The string to use for a single indentation level. The default is two
- // spaces.
+ // String to use for a single indentation level; default is two spaces.
Indent string
- // hasWritten is whether we have written any output to w yet.
- hasWritten bool
w *bufio.Writer
+ hasWritten bool // written any output to w yet?
}
// NewEncoder create a new Encoder.
@@ -130,12 +136,13 @@ func (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) {
}
func (enc *Encoder) encode(key Key, rv reflect.Value) {
- // Special case. Time needs to be in ISO8601 format.
- // Special case. If we can marshal the type to text, then we used that.
- // Basically, this prevents the encoder for handling these types as
- // generic structs (or whatever the underlying type of a TextMarshaler is).
+ // Special case: time needs to be in ISO8601 format.
+ //
+ // Special case: if we can marshal the type to text, then we used that. This
+ // prevents the encoder for handling these types as generic structs (or
+ // whatever the underlying type of a TextMarshaler is).
switch t := rv.Interface().(type) {
- case time.Time, encoding.TextMarshaler:
+ case time.Time, encoding.TextMarshaler, Marshaler:
enc.writeKeyValue(key, rv, false)
return
// TODO: #76 would make this superfluous after implemented.
@@ -200,13 +207,19 @@ func (enc *Encoder) eElement(rv reflect.Value) {
enc.wf(v.In(time.UTC).Format(format))
}
return
+ case Marshaler:
+ s, err := v.MarshalTOML()
+ if err != nil {
+ encPanic(err)
+ }
+ enc.writeQuoted(string(s))
+ return
case encoding.TextMarshaler:
- // Use text marshaler if it's available for this value.
- if s, err := v.MarshalText(); err != nil {
+ s, err := v.MarshalText()
+ if err != nil {
encPanic(err)
- } else {
- enc.writeQuoted(string(s))
}
+ enc.writeQuoted(string(s))
return
}
@@ -260,7 +273,7 @@ func floatAddDecimal(fstr string) string {
}
func (enc *Encoder) writeQuoted(s string) {
- enc.wf("\"%s\"", quotedReplacer.Replace(s))
+ enc.wf("\"%s\"", dblQuotedReplacer.Replace(s))
}
func (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) {
@@ -286,7 +299,7 @@ func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) {
continue
}
enc.newline()
- enc.wf("%s[[%s]]", enc.indentStr(key), key.maybeQuotedAll())
+ enc.wf("%s[[%s]]", enc.indentStr(key), key)
enc.newline()
enc.eMapOrStruct(key, trv, false)
}
@@ -299,7 +312,7 @@ func (enc *Encoder) eTable(key Key, rv reflect.Value) {
enc.newline()
}
if len(key) > 0 {
- enc.wf("%s[%s]", enc.indentStr(key), key.maybeQuotedAll())
+ enc.wf("%s[%s]", enc.indentStr(key), key)
enc.newline()
}
enc.eMapOrStruct(key, rv, false)
@@ -328,7 +341,7 @@ func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) {
var mapKeysDirect, mapKeysSub []string
for _, mapKey := range rv.MapKeys() {
k := mapKey.String()
- if typeIsHash(tomlTypeOfGo(rv.MapIndex(mapKey))) {
+ if typeIsTable(tomlTypeOfGo(rv.MapIndex(mapKey))) {
mapKeysSub = append(mapKeysSub, k)
} else {
mapKeysDirect = append(mapKeysDirect, k)
@@ -364,6 +377,8 @@ func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) {
}
}
+const is32Bit = (32 << (^uint(0) >> 63)) == 32
+
func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
// Write keys for fields directly under this key first, because if we write
// a field that creates a new table then all keys under it will be in that
@@ -408,10 +423,20 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
}
}
- if typeIsHash(tomlTypeOfGo(frv)) {
+ if typeIsTable(tomlTypeOfGo(frv)) {
fieldsSub = append(fieldsSub, append(start, f.Index...))
} else {
- fieldsDirect = append(fieldsDirect, append(start, f.Index...))
+ // Copy so it works correct on 32bit archs; not clear why this
+ // is needed. See #314, and https://www.reddit.com/r/golang/comments/pnx8v4
+ // This also works fine on 64bit, but 32bit archs are somewhat
+ // rare and this is a wee bit faster.
+ if is32Bit {
+ copyStart := make([]int, len(start))
+ copy(copyStart, start)
+ fieldsDirect = append(fieldsDirect, append(copyStart, f.Index...))
+ } else {
+ fieldsDirect = append(fieldsDirect, append(start, f.Index...))
+ }
}
}
}
@@ -462,13 +487,13 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
}
}
-// tomlTypeName returns the TOML type name of the Go value's type. It is
-// used to determine whether the types of array elements are mixed (which is
-// forbidden). If the Go value is nil, then it is illegal for it to be an array
-// element, and valueIsNil is returned as true.
-
-// Returns the TOML type of a Go value. The type may be `nil`, which means
-// no concrete TOML type could be found.
+// tomlTypeOfGo returns the TOML type name of the Go value's type.
+//
+// It is used to determine whether the types of array elements are mixed (which
+// is forbidden). If the Go value is nil, then it is illegal for it to be an
+// array element, and valueIsNil is returned as true.
+//
+// The type may be `nil`, which means no concrete TOML type could be found.
func tomlTypeOfGo(rv reflect.Value) tomlType {
if isNil(rv) || !rv.IsValid() {
return nil
@@ -495,32 +520,43 @@ func tomlTypeOfGo(rv reflect.Value) tomlType {
case reflect.Map:
return tomlHash
case reflect.Struct:
- switch rv.Interface().(type) {
- case time.Time:
+ if _, ok := rv.Interface().(time.Time); ok {
return tomlDatetime
- case encoding.TextMarshaler:
+ }
+ if isMarshaler(rv) {
return tomlString
- default:
- // Someone used a pointer receiver: we can make it work for pointer
- // values.
- if rv.CanAddr() {
- _, ok := rv.Addr().Interface().(encoding.TextMarshaler)
- if ok {
- return tomlString
- }
- }
- return tomlHash
}
+ return tomlHash
default:
- _, ok := rv.Interface().(encoding.TextMarshaler)
- if ok {
+ if isMarshaler(rv) {
return tomlString
}
+
encPanic(errors.New("unsupported type: " + rv.Kind().String()))
- panic("") // Need *some* return value
+ panic("unreachable")
}
}
+func isMarshaler(rv reflect.Value) bool {
+ switch rv.Interface().(type) {
+ case encoding.TextMarshaler:
+ return true
+ case Marshaler:
+ return true
+ }
+
+ // Someone used a pointer receiver: we can make it work for pointer values.
+ if rv.CanAddr() {
+ if _, ok := rv.Addr().Interface().(encoding.TextMarshaler); ok {
+ return true
+ }
+ if _, ok := rv.Addr().Interface().(Marshaler); ok {
+ return true
+ }
+ }
+ return false
+}
+
// tomlArrayType returns the element type of a TOML array. The type returned
// may be nil if it cannot be determined (e.g., a nil slice or a zero length
// slize). This function may also panic if it finds a type that cannot be
@@ -604,7 +640,14 @@ func (enc *Encoder) newline() {
//
// key = <any value>
//
-// If inline is true it won't add a newline at the end.
+// This is also used for "k = v" in inline tables; so something like this will
+// be written in three calls:
+//
+// ┌────────────────────┐
+// │ ┌───┐ ┌─────┐│
+// v v v v vv
+// key = {k = v, k2 = v2}
+//
func (enc *Encoder) writeKeyValue(key Key, val reflect.Value, inline bool) {
if len(key) == 0 {
encPanic(errNoKey)
@@ -617,7 +660,8 @@ func (enc *Encoder) writeKeyValue(key Key, val reflect.Value, inline bool) {
}
func (enc *Encoder) wf(format string, v ...interface{}) {
- if _, err := fmt.Fprintf(enc.w, format, v...); err != nil {
+ _, err := fmt.Fprintf(enc.w, format, v...)
+ if err != nil {
encPanic(err)
}
enc.hasWritten = true
diff --git a/vendor/github.com/BurntSushi/toml/error.go b/vendor/github.com/BurntSushi/toml/error.go
new file mode 100644
index 000000000..36edc4655
--- /dev/null
+++ b/vendor/github.com/BurntSushi/toml/error.go
@@ -0,0 +1,229 @@
+package toml
+
+import (
+ "fmt"
+ "strings"
+)
+
+// ParseError is returned when there is an error parsing the TOML syntax.
+//
+// For example invalid syntax, duplicate keys, etc.
+//
+// In addition to the error message itself, you can also print detailed location
+// information with context by using ErrorWithLocation():
+//
+// toml: error: Key 'fruit' was already created and cannot be used as an array.
+//
+// At line 4, column 2-7:
+//
+// 2 | fruit = []
+// 3 |
+// 4 | [[fruit]] # Not allowed
+// ^^^^^
+//
+// Furthermore, the ErrorWithUsage() can be used to print the above with some
+// more detailed usage guidance:
+//
+// toml: error: newlines not allowed within inline tables
+//
+// At line 1, column 18:
+//
+// 1 | x = [{ key = 42 #
+// ^
+//
+// Error help:
+//
+// Inline tables must always be on a single line:
+//
+// table = {key = 42, second = 43}
+//
+// It is invalid to split them over multiple lines like so:
+//
+// # INVALID
+// table = {
+// key = 42,
+// second = 43
+// }
+//
+// Use regular for this:
+//
+// [table]
+// key = 42
+// second = 43
+type ParseError struct {
+ Message string // Short technical message.
+ Usage string // Longer message with usage guidance; may be blank.
+ Position Position // Position of the error
+ LastKey string // Last parsed key, may be blank.
+ Line int // Line the error occurred. Deprecated: use Position.
+
+ err error
+ input string
+}
+
+// Position of an error.
+type Position struct {
+ Line int // Line number, starting at 1.
+ Start int // Start of error, as byte offset starting at 0.
+ Len int // Lenght in bytes.
+}
+
+func (pe ParseError) Error() string {
+ msg := pe.Message
+ if msg == "" { // Error from errorf()
+ msg = pe.err.Error()
+ }
+
+ if pe.LastKey == "" {
+ return fmt.Sprintf("toml: line %d: %s", pe.Position.Line, msg)
+ }
+ return fmt.Sprintf("toml: line %d (last key %q): %s",
+ pe.Position.Line, pe.LastKey, msg)
+}
+
+// ErrorWithUsage() returns the error with detailed location context.
+//
+// See the documentation on ParseError.
+func (pe ParseError) ErrorWithPosition() string {
+ if pe.input == "" { // Should never happen, but just in case.
+ return pe.Error()
+ }
+
+ var (
+ lines = strings.Split(pe.input, "\n")
+ col = pe.column(lines)
+ b = new(strings.Builder)
+ )
+
+ msg := pe.Message
+ if msg == "" {
+ msg = pe.err.Error()
+ }
+
+ // TODO: don't show control characters as literals? This may not show up
+ // well everywhere.
+
+ if pe.Position.Len == 1 {
+ fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d:\n\n",
+ msg, pe.Position.Line, col+1)
+ } else {
+ fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d-%d:\n\n",
+ msg, pe.Position.Line, col, col+pe.Position.Len)
+ }
+ if pe.Position.Line > 2 {
+ fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-2, lines[pe.Position.Line-3])
+ }
+ if pe.Position.Line > 1 {
+ fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-1, lines[pe.Position.Line-2])
+ }
+ fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line, lines[pe.Position.Line-1])
+ fmt.Fprintf(b, "% 10s%s%s\n", "", strings.Repeat(" ", col), strings.Repeat("^", pe.Position.Len))
+ return b.String()
+}
+
+// ErrorWithUsage() returns the error with detailed location context and usage
+// guidance.
+//
+// See the documentation on ParseError.
+func (pe ParseError) ErrorWithUsage() string {
+ m := pe.ErrorWithPosition()
+ if u, ok := pe.err.(interface{ Usage() string }); ok && u.Usage() != "" {
+ return m + "Error help:\n\n " +
+ strings.ReplaceAll(strings.TrimSpace(u.Usage()), "\n", "\n ") +
+ "\n"
+ }
+ return m
+}
+
+func (pe ParseError) column(lines []string) int {
+ var pos, col int
+ for i := range lines {
+ ll := len(lines[i]) + 1 // +1 for the removed newline
+ if pos+ll >= pe.Position.Start {
+ col = pe.Position.Start - pos
+ if col < 0 { // Should never happen, but just in case.
+ col = 0
+ }
+ break
+ }
+ pos += ll
+ }
+
+ return col
+}
+
+type (
+ errLexControl struct{ r rune }
+ errLexEscape struct{ r rune }
+ errLexUTF8 struct{ b byte }
+ errLexInvalidNum struct{ v string }
+ errLexInvalidDate struct{ v string }
+ errLexInlineTableNL struct{}
+ errLexStringNL struct{}
+)
+
+func (e errLexControl) Error() string {
+ return fmt.Sprintf("TOML files cannot contain control characters: '0x%02x'", e.r)
+}
+func (e errLexControl) Usage() string { return "" }
+
+func (e errLexEscape) Error() string { return fmt.Sprintf(`invalid escape in string '\%c'`, e.r) }
+func (e errLexEscape) Usage() string { return usageEscape }
+func (e errLexUTF8) Error() string { return fmt.Sprintf("invalid UTF-8 byte: 0x%02x", e.b) }
+func (e errLexUTF8) Usage() string { return "" }
+func (e errLexInvalidNum) Error() string { return fmt.Sprintf("invalid number: %q", e.v) }
+func (e errLexInvalidNum) Usage() string { return "" }
+func (e errLexInvalidDate) Error() string { return fmt.Sprintf("invalid date: %q", e.v) }
+func (e errLexInvalidDate) Usage() string { return "" }
+func (e errLexInlineTableNL) Error() string { return "newlines not allowed within inline tables" }
+func (e errLexInlineTableNL) Usage() string { return usageInlineNewline }
+func (e errLexStringNL) Error() string { return "strings cannot contain newlines" }
+func (e errLexStringNL) Usage() string { return usageStringNewline }
+
+const usageEscape = `
+A '\' inside a "-delimited string is interpreted as an escape character.
+
+The following escape sequences are supported:
+\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX
+
+To prevent a '\' from being recognized as an escape character, use either:
+
+- a ' or '''-delimited string; escape characters aren't processed in them; or
+- write two backslashes to get a single backslash: '\\'.
+
+If you're trying to add a Windows path (e.g. "C:\Users\martin") then using '/'
+instead of '\' will usually also work: "C:/Users/martin".
+`
+
+const usageInlineNewline = `
+Inline tables must always be on a single line:
+
+ table = {key = 42, second = 43}
+
+It is invalid to split them over multiple lines like so:
+
+ # INVALID
+ table = {
+ key = 42,
+ second = 43
+ }
+
+Use regular for this:
+
+ [table]
+ key = 42
+ second = 43
+`
+
+const usageStringNewline = `
+Strings must always be on a single line, and cannot span more than one line:
+
+ # INVALID
+ string = "Hello,
+ world!"
+
+Instead use """ or ''' to split strings over multiple lines:
+
+ string = """Hello,
+ world!"""
+`
diff --git a/vendor/github.com/BurntSushi/toml/go.sum b/vendor/github.com/BurntSushi/toml/go.sum
deleted file mode 100644
index e69de29bb..000000000
--- a/vendor/github.com/BurntSushi/toml/go.sum
+++ /dev/null
diff --git a/vendor/github.com/BurntSushi/toml/lex.go b/vendor/github.com/BurntSushi/toml/lex.go
index adc4eb5d5..63ef20f47 100644
--- a/vendor/github.com/BurntSushi/toml/lex.go
+++ b/vendor/github.com/BurntSushi/toml/lex.go
@@ -37,28 +37,14 @@ const (
itemInlineTableEnd
)
-const (
- eof = 0
- comma = ','
- tableStart = '['
- tableEnd = ']'
- arrayTableStart = '['
- arrayTableEnd = ']'
- tableSep = '.'
- keySep = '='
- arrayStart = '['
- arrayEnd = ']'
- commentStart = '#'
- stringStart = '"'
- stringEnd = '"'
- rawStringStart = '\''
- rawStringEnd = '\''
- inlineTableStart = '{'
- inlineTableEnd = '}'
-)
+const eof = 0
type stateFn func(lx *lexer) stateFn
+func (p Position) String() string {
+ return fmt.Sprintf("at line %d; start %d; length %d", p.Line, p.Start, p.Len)
+}
+
type lexer struct {
input string
start int
@@ -67,26 +53,26 @@ type lexer struct {
state stateFn
items chan item
- // Allow for backing up up to four runes.
- // This is necessary because TOML contains 3-rune tokens (""" and ''').
+ // Allow for backing up up to 4 runes. This is necessary because TOML
+ // contains 3-rune tokens (""" and ''').
prevWidths [4]int
- nprev int // how many of prevWidths are in use
- // If we emit an eof, we can still back up, but it is not OK to call
- // next again.
- atEOF bool
+ nprev int // how many of prevWidths are in use
+ atEOF bool // If we emit an eof, we can still back up, but it is not OK to call next again.
// A stack of state functions used to maintain context.
- // The idea is to reuse parts of the state machine in various places.
- // For example, values can appear at the top level or within arbitrarily
- // nested arrays. The last state on the stack is used after a value has
- // been lexed. Similarly for comments.
+ //
+ // The idea is to reuse parts of the state machine in various places. For
+ // example, values can appear at the top level or within arbitrarily nested
+ // arrays. The last state on the stack is used after a value has been lexed.
+ // Similarly for comments.
stack []stateFn
}
type item struct {
- typ itemType
- val string
- line int
+ typ itemType
+ val string
+ err error
+ pos Position
}
func (lx *lexer) nextItem() item {
@@ -96,7 +82,7 @@ func (lx *lexer) nextItem() item {
return item
default:
lx.state = lx.state(lx)
- //fmt.Printf(" STATE %-24s current: %-10q stack: %s\n", lx.state, lx.current(), lx.stack)
+ //fmt.Printf(" STATE %-24s current: %-10q stack: %s\n", lx.state, lx.current(), lx.stack)
}
}
}
@@ -105,9 +91,9 @@ func lex(input string) *lexer {
lx := &lexer{
input: input,
state: lexTop,
- line: 1,
items: make(chan item, 10),
stack: make([]stateFn, 0, 10),
+ line: 1,
}
return lx
}
@@ -129,13 +115,25 @@ func (lx *lexer) current() string {
return lx.input[lx.start:lx.pos]
}
+func (lx lexer) getPos() Position {
+ p := Position{
+ Line: lx.line,
+ Start: lx.start,
+ Len: lx.pos - lx.start,
+ }
+ if p.Len <= 0 {
+ p.Len = 1
+ }
+ return p
+}
+
func (lx *lexer) emit(typ itemType) {
- lx.items <- item{typ, lx.current(), lx.line}
+ lx.items <- item{typ: typ, pos: lx.getPos(), val: lx.current()}
lx.start = lx.pos
}
func (lx *lexer) emitTrim(typ itemType) {
- lx.items <- item{typ, strings.TrimSpace(lx.current()), lx.line}
+ lx.items <- item{typ: typ, pos: lx.getPos(), val: strings.TrimSpace(lx.current())}
lx.start = lx.pos
}
@@ -160,7 +158,13 @@ func (lx *lexer) next() (r rune) {
r, w := utf8.DecodeRuneInString(lx.input[lx.pos:])
if r == utf8.RuneError {
- lx.errorf("invalid UTF-8 byte at position %d (line %d): 0x%02x", lx.pos, lx.line, lx.input[lx.pos])
+ lx.error(errLexUTF8{lx.input[lx.pos]})
+ return utf8.RuneError
+ }
+
+ // Note: don't use peek() here, as this calls next().
+ if isControl(r) || (r == '\r' && (len(lx.input)-1 == lx.pos || lx.input[lx.pos+1] != '\n')) {
+ lx.errorControlChar(r)
return utf8.RuneError
}
@@ -188,6 +192,7 @@ func (lx *lexer) backup() {
lx.prevWidths[1] = lx.prevWidths[2]
lx.prevWidths[2] = lx.prevWidths[3]
lx.nprev--
+
lx.pos -= w
if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' {
lx.line--
@@ -223,18 +228,58 @@ func (lx *lexer) skip(pred func(rune) bool) {
}
}
-// errorf stops all lexing by emitting an error and returning `nil`.
+// error stops all lexing by emitting an error and returning `nil`.
+//
// Note that any value that is a character is escaped if it's a special
// character (newlines, tabs, etc.).
+func (lx *lexer) error(err error) stateFn {
+ if lx.atEOF {
+ return lx.errorPrevLine(err)
+ }
+ lx.items <- item{typ: itemError, pos: lx.getPos(), err: err}
+ return nil
+}
+
+// errorfPrevline is like error(), but sets the position to the last column of
+// the previous line.
+//
+// This is so that unexpected EOF or NL errors don't show on a new blank line.
+func (lx *lexer) errorPrevLine(err error) stateFn {
+ pos := lx.getPos()
+ pos.Line--
+ pos.Len = 1
+ pos.Start = lx.pos - 1
+ lx.items <- item{typ: itemError, pos: pos, err: err}
+ return nil
+}
+
+// errorPos is like error(), but allows explicitly setting the position.
+func (lx *lexer) errorPos(start, length int, err error) stateFn {
+ pos := lx.getPos()
+ pos.Start = start
+ pos.Len = length
+ lx.items <- item{typ: itemError, pos: pos, err: err}
+ return nil
+}
+
+// errorf is like error, and creates a new error.
func (lx *lexer) errorf(format string, values ...interface{}) stateFn {
- lx.items <- item{
- itemError,
- fmt.Sprintf(format, values...),
- lx.line,
+ if lx.atEOF {
+ pos := lx.getPos()
+ pos.Line--
+ pos.Len = 1
+ pos.Start = lx.pos - 1
+ lx.items <- item{typ: itemError, pos: pos, err: fmt.Errorf(format, values...)}
+ return nil
}
+ lx.items <- item{typ: itemError, pos: lx.getPos(), err: fmt.Errorf(format, values...)}
return nil
}
+func (lx *lexer) errorControlChar(cc rune) stateFn {
+ return lx.errorPos(lx.pos-1, 1, errLexControl{cc})
+}
+
// lexTop consumes elements at the top level of TOML data.
func lexTop(lx *lexer) stateFn {
r := lx.next()
@@ -242,10 +287,10 @@ func lexTop(lx *lexer) stateFn {
return lexSkip(lx, lexTop)
}
switch r {
- case commentStart:
+ case '#':
lx.push(lexTop)
return lexCommentStart
- case tableStart:
+ case '[':
return lexTableStart
case eof:
if lx.pos > lx.start {
@@ -268,7 +313,7 @@ func lexTop(lx *lexer) stateFn {
func lexTopEnd(lx *lexer) stateFn {
r := lx.next()
switch {
- case r == commentStart:
+ case r == '#':
// a comment will read to a newline for us.
lx.push(lexTop)
return lexCommentStart
@@ -292,7 +337,7 @@ func lexTopEnd(lx *lexer) stateFn {
// It also handles the case that this is an item in an array of tables.
// e.g., '[[name]]'.
func lexTableStart(lx *lexer) stateFn {
- if lx.peek() == arrayTableStart {
+ if lx.peek() == '[' {
lx.next()
lx.emit(itemArrayTableStart)
lx.push(lexArrayTableEnd)
@@ -309,10 +354,8 @@ func lexTableEnd(lx *lexer) stateFn {
}
func lexArrayTableEnd(lx *lexer) stateFn {
- if r := lx.next(); r != arrayTableEnd {
- return lx.errorf(
- "expected end of table array name delimiter %q, but got %q instead",
- arrayTableEnd, r)
+ if r := lx.next(); r != ']' {
+ return lx.errorf("expected end of table array name delimiter ']', but got %q instead", r)
}
lx.emit(itemArrayTableEnd)
return lexTopEnd
@@ -321,11 +364,11 @@ func lexArrayTableEnd(lx *lexer) stateFn {
func lexTableNameStart(lx *lexer) stateFn {
lx.skip(isWhitespace)
switch r := lx.peek(); {
- case r == tableEnd || r == eof:
+ case r == ']' || r == eof:
return lx.errorf("unexpected end of table name (table names cannot be empty)")
- case r == tableSep:
+ case r == '.':
return lx.errorf("unexpected table separator (table names cannot be empty)")
- case r == stringStart || r == rawStringStart:
+ case r == '"' || r == '\'':
lx.ignore()
lx.push(lexTableNameEnd)
return lexQuotedName
@@ -342,10 +385,10 @@ func lexTableNameEnd(lx *lexer) stateFn {
switch r := lx.next(); {
case isWhitespace(r):
return lexTableNameEnd
- case r == tableSep:
+ case r == '.':
lx.ignore()
return lexTableNameStart
- case r == tableEnd:
+ case r == ']':
return lx.pop()
default:
return lx.errorf("expected '.' or ']' to end table name, but got %q instead", r)
@@ -379,10 +422,10 @@ func lexQuotedName(lx *lexer) stateFn {
switch {
case isWhitespace(r):
return lexSkip(lx, lexValue)
- case r == stringStart:
+ case r == '"':
lx.ignore() // ignore the '"'
return lexString
- case r == rawStringStart:
+ case r == '\'':
lx.ignore() // ignore the "'"
return lexRawString
case r == eof:
@@ -400,7 +443,7 @@ func lexKeyStart(lx *lexer) stateFn {
return lx.errorf("unexpected '=': key name appears blank")
case r == '.':
return lx.errorf("unexpected '.': keys cannot start with a '.'")
- case r == stringStart || r == rawStringStart:
+ case r == '"' || r == '\'':
lx.ignore()
fallthrough
default: // Bare key
@@ -416,7 +459,7 @@ func lexKeyNameStart(lx *lexer) stateFn {
return lx.errorf("unexpected '='")
case r == '.':
return lx.errorf("unexpected '.'")
- case r == stringStart || r == rawStringStart:
+ case r == '"' || r == '\'':
lx.ignore()
lx.push(lexKeyEnd)
return lexQuotedName
@@ -434,7 +477,7 @@ func lexKeyEnd(lx *lexer) stateFn {
case isWhitespace(r):
return lexSkip(lx, lexKeyEnd)
case r == eof:
- return lx.errorf("unexpected EOF; expected key separator %q", keySep)
+ return lx.errorf("unexpected EOF; expected key separator '='")
case r == '.':
lx.ignore()
return lexKeyNameStart
@@ -461,17 +504,17 @@ func lexValue(lx *lexer) stateFn {
return lexNumberOrDateStart
}
switch r {
- case arrayStart:
+ case '[':
lx.ignore()
lx.emit(itemArray)
return lexArrayValue
- case inlineTableStart:
+ case '{':
lx.ignore()
lx.emit(itemInlineTableStart)
return lexInlineTableValue
- case stringStart:
- if lx.accept(stringStart) {
- if lx.accept(stringStart) {
+ case '"':
+ if lx.accept('"') {
+ if lx.accept('"') {
lx.ignore() // Ignore """
return lexMultilineString
}
@@ -479,9 +522,9 @@ func lexValue(lx *lexer) stateFn {
}
lx.ignore() // ignore the '"'
return lexString
- case rawStringStart:
- if lx.accept(rawStringStart) {
- if lx.accept(rawStringStart) {
+ case '\'':
+ if lx.accept('\'') {
+ if lx.accept('\'') {
lx.ignore() // Ignore """
return lexMultilineRawString
}
@@ -520,14 +563,12 @@ func lexArrayValue(lx *lexer) stateFn {
switch {
case isWhitespace(r) || isNL(r):
return lexSkip(lx, lexArrayValue)
- case r == commentStart:
+ case r == '#':
lx.push(lexArrayValue)
return lexCommentStart
- case r == comma:
+ case r == ',':
return lx.errorf("unexpected comma")
- case r == arrayEnd:
- // NOTE(caleb): The spec isn't clear about whether you can have
- // a trailing comma or not, so we'll allow it.
+ case r == ']':
return lexArrayEnd
}
@@ -540,22 +581,20 @@ func lexArrayValue(lx *lexer) stateFn {
// the next value (or the end of the array): it ignores whitespace and newlines
// and expects either a ',' or a ']'.
func lexArrayValueEnd(lx *lexer) stateFn {
- r := lx.next()
- switch {
+ switch r := lx.next(); {
case isWhitespace(r) || isNL(r):
return lexSkip(lx, lexArrayValueEnd)
- case r == commentStart:
+ case r == '#':
lx.push(lexArrayValueEnd)
return lexCommentStart
- case r == comma:
+ case r == ',':
lx.ignore()
return lexArrayValue // move on to the next value
- case r == arrayEnd:
+ case r == ']':
return lexArrayEnd
+ default:
+ return lx.errorf("expected a comma (',') or array terminator (']'), but got %s", runeOrEOF(r))
}
- return lx.errorf(
- "expected a comma or array terminator %q, but got %s instead",
- arrayEnd, runeOrEOF(r))
}
// lexArrayEnd finishes the lexing of an array.
@@ -574,13 +613,13 @@ func lexInlineTableValue(lx *lexer) stateFn {
case isWhitespace(r):
return lexSkip(lx, lexInlineTableValue)
case isNL(r):
- return lx.errorf("newlines not allowed within inline tables")
- case r == commentStart:
+ return lx.errorPrevLine(errLexInlineTableNL{})
+ case r == '#':
lx.push(lexInlineTableValue)
return lexCommentStart
- case r == comma:
+ case r == ',':
return lx.errorf("unexpected comma")
- case r == inlineTableEnd:
+ case r == '}':
return lexInlineTableEnd
}
lx.backup()
@@ -596,23 +635,21 @@ func lexInlineTableValueEnd(lx *lexer) stateFn {
case isWhitespace(r):
return lexSkip(lx, lexInlineTableValueEnd)
case isNL(r):
- return lx.errorf("newlines not allowed within inline tables")
- case r == commentStart:
+ return lx.errorPrevLine(errLexInlineTableNL{})
+ case r == '#':
lx.push(lexInlineTableValueEnd)
return lexCommentStart
- case r == comma:
+ case r == ',':
lx.ignore()
lx.skip(isWhitespace)
if lx.peek() == '}' {
return lx.errorf("trailing comma not allowed in inline tables")
}
return lexInlineTableValue
- case r == inlineTableEnd:
+ case r == '}':
return lexInlineTableEnd
default:
- return lx.errorf(
- "expected a comma or an inline table terminator %q, but got %s instead",
- inlineTableEnd, runeOrEOF(r))
+ return lx.errorf("expected a comma or an inline table terminator '}', but got %s instead", runeOrEOF(r))
}
}
@@ -638,14 +675,12 @@ func lexString(lx *lexer) stateFn {
switch {
case r == eof:
return lx.errorf(`unexpected EOF; expected '"'`)
- case isControl(r) || r == '\r':
- return lx.errorf("control characters are not allowed inside strings: '0x%02x'", r)
case isNL(r):
- return lx.errorf("strings cannot contain newlines")
+ return lx.errorPrevLine(errLexStringNL{})
case r == '\\':
lx.push(lexString)
return lexStringEscape
- case r == stringEnd:
+ case r == '"':
lx.backup()
lx.emit(itemString)
lx.next()
@@ -660,23 +695,20 @@ func lexString(lx *lexer) stateFn {
func lexMultilineString(lx *lexer) stateFn {
r := lx.next()
switch r {
+ default:
+ return lexMultilineString
case eof:
return lx.errorf(`unexpected EOF; expected '"""'`)
- case '\r':
- if lx.peek() != '\n' {
- return lx.errorf("control characters are not allowed inside strings: '0x%02x'", r)
- }
- return lexMultilineString
case '\\':
return lexMultilineStringEscape
- case stringEnd:
+ case '"':
/// Found " → try to read two more "".
- if lx.accept(stringEnd) {
- if lx.accept(stringEnd) {
+ if lx.accept('"') {
+ if lx.accept('"') {
/// Peek ahead: the string can contain " and "", including at the
/// end: """str"""""
/// 6 or more at the end, however, is an error.
- if lx.peek() == stringEnd {
+ if lx.peek() == '"' {
/// Check if we already lexed 5 's; if so we have 6 now, and
/// that's just too many man!
if strings.HasSuffix(lx.current(), `"""""`) {
@@ -699,12 +731,8 @@ func lexMultilineString(lx *lexer) stateFn {
}
lx.backup()
}
+ return lexMultilineString
}
-
- if isControl(r) {
- return lx.errorf("control characters are not allowed inside strings: '0x%02x'", r)
- }
- return lexMultilineString
}
// lexRawString consumes a raw string. Nothing can be escaped in such a string.
@@ -712,20 +740,19 @@ func lexMultilineString(lx *lexer) stateFn {
func lexRawString(lx *lexer) stateFn {
r := lx.next()
switch {
+ default:
+ return lexRawString
case r == eof:
return lx.errorf(`unexpected EOF; expected "'"`)
- case isControl(r) || r == '\r':
- return lx.errorf("control characters are not allowed inside strings: '0x%02x'", r)
case isNL(r):
- return lx.errorf("strings cannot contain newlines")
- case r == rawStringEnd:
+ return lx.errorPrevLine(errLexStringNL{})
+ case r == '\'':
lx.backup()
lx.emit(itemRawString)
lx.next()
lx.ignore()
return lx.pop()
}
- return lexRawString
}
// lexMultilineRawString consumes a raw string. Nothing can be escaped in such
@@ -734,21 +761,18 @@ func lexRawString(lx *lexer) stateFn {
func lexMultilineRawString(lx *lexer) stateFn {
r := lx.next()
switch r {
+ default:
+ return lexMultilineRawString
case eof:
return lx.errorf(`unexpected EOF; expected "'''"`)
- case '\r':
- if lx.peek() != '\n' {
- return lx.errorf("control characters are not allowed inside strings: '0x%02x'", r)
- }
- return lexMultilineRawString
- case rawStringEnd:
+ case '\'':
/// Found ' → try to read two more ''.
- if lx.accept(rawStringEnd) {
- if lx.accept(rawStringEnd) {
+ if lx.accept('\'') {
+ if lx.accept('\'') {
/// Peek ahead: the string can contain ' and '', including at the
/// end: '''str'''''
/// 6 or more at the end, however, is an error.
- if lx.peek() == rawStringEnd {
+ if lx.peek() == '\'' {
/// Check if we already lexed 5 's; if so we have 6 now, and
/// that's just too many man!
if strings.HasSuffix(lx.current(), "'''''") {
@@ -771,12 +795,8 @@ func lexMultilineRawString(lx *lexer) stateFn {
}
lx.backup()
}
+ return lexMultilineRawString
}
-
- if isControl(r) {
- return lx.errorf("control characters are not allowed inside strings: '0x%02x'", r)
- }
- return lexMultilineRawString
}
// lexMultilineStringEscape consumes an escaped character. It assumes that the
@@ -817,8 +837,7 @@ func lexStringEscape(lx *lexer) stateFn {
case 'U':
return lexLongUnicodeEscape
}
- return lx.errorf("invalid escape character %q; only the following escape characters are allowed: "+
- `\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX`, r)
+ return lx.error(errLexEscape{r})
}
func lexShortUnicodeEscape(lx *lexer) stateFn {
@@ -1108,8 +1127,6 @@ func lexComment(lx *lexer) stateFn {
lx.backup()
lx.emit(itemText)
return lx.pop()
- case isControl(r):
- return lx.errorf("control characters are not allowed inside comments: '0x%02x'", r)
default:
return lexComment
}
@@ -1121,52 +1138,6 @@ func lexSkip(lx *lexer, nextState stateFn) stateFn {
return nextState
}
-// isWhitespace returns true if `r` is a whitespace character according
-// to the spec.
-func isWhitespace(r rune) bool {
- return r == '\t' || r == ' '
-}
-
-func isNL(r rune) bool {
- return r == '\n' || r == '\r'
-}
-
-// Control characters except \n, \t
-func isControl(r rune) bool {
- switch r {
- case '\t', '\r', '\n':
- return false
- default:
- return (r >= 0x00 && r <= 0x1f) || r == 0x7f
- }
-}
-
-func isDigit(r rune) bool {
- return r >= '0' && r <= '9'
-}
-
-func isHexadecimal(r rune) bool {
- return (r >= '0' && r <= '9') ||
- (r >= 'a' && r <= 'f') ||
- (r >= 'A' && r <= 'F')
-}
-
-func isOctal(r rune) bool {
- return r >= '0' && r <= '7'
-}
-
-func isBinary(r rune) bool {
- return r == '0' || r == '1'
-}
-
-func isBareKeyChar(r rune) bool {
- return (r >= 'A' && r <= 'Z') ||
- (r >= 'a' && r <= 'z') ||
- (r >= '0' && r <= '9') ||
- r == '_' ||
- r == '-'
-}
-
func (s stateFn) String() string {
name := runtime.FuncForPC(reflect.ValueOf(s).Pointer()).Name()
if i := strings.LastIndexByte(name, '.'); i > -1 {
@@ -1223,3 +1194,26 @@ func (itype itemType) String() string {
func (item item) String() string {
return fmt.Sprintf("(%s, %s)", item.typ.String(), item.val)
}
+
+func isWhitespace(r rune) bool { return r == '\t' || r == ' ' }
+func isNL(r rune) bool { return r == '\n' || r == '\r' }
+func isControl(r rune) bool { // Control characters except \t, \r, \n
+ switch r {
+ case '\t', '\r', '\n':
+ return false
+ default:
+ return (r >= 0x00 && r <= 0x1f) || r == 0x7f
+ }
+}
+func isDigit(r rune) bool { return r >= '0' && r <= '9' }
+func isBinary(r rune) bool { return r == '0' || r == '1' }
+func isOctal(r rune) bool { return r >= '0' && r <= '7' }
+func isHexadecimal(r rune) bool {
+ return (r >= '0' && r <= '9') || (r >= 'a' && r <= 'f') || (r >= 'A' && r <= 'F')
+}
+func isBareKeyChar(r rune) bool {
+ return (r >= 'A' && r <= 'Z') ||
+ (r >= 'a' && r <= 'z') ||
+ (r >= '0' && r <= '9') ||
+ r == '_' || r == '-'
+}
diff --git a/vendor/github.com/BurntSushi/toml/decode_meta.go b/vendor/github.com/BurntSushi/toml/meta.go
index ad8899c6c..868619fb9 100644
--- a/vendor/github.com/BurntSushi/toml/decode_meta.go
+++ b/vendor/github.com/BurntSushi/toml/meta.go
@@ -1,34 +1,39 @@
package toml
-import "strings"
+import (
+ "strings"
+)
-// MetaData allows access to meta information about TOML data that may not be
-// inferable via reflection. In particular, whether a key has been defined and
-// the TOML type of a key.
+// MetaData allows access to meta information about TOML data that's not
+// accessible otherwise.
+//
+// It allows checking if a key is defined in the TOML data, whether any keys
+// were undecoded, and the TOML type of a key.
type MetaData struct {
+ context Key // Used only during decoding.
+
mapping map[string]interface{}
types map[string]tomlType
keys []Key
- decoded map[string]bool
- context Key // Used only during decoding.
+ decoded map[string]struct{}
}
// IsDefined reports if the key exists in the TOML data.
//
// The key should be specified hierarchically, for example to access the TOML
-// key "a.b.c" you would use:
+// key "a.b.c" you would use IsDefined("a", "b", "c"). Keys are case sensitive.
//
-// IsDefined("a", "b", "c")
-//
-// IsDefined will return false if an empty key given. Keys are case sensitive.
+// Returns false for an empty key.
func (md *MetaData) IsDefined(key ...string) bool {
if len(key) == 0 {
return false
}
- var hash map[string]interface{}
- var ok bool
- var hashOrVal interface{} = md.mapping
+ var (
+ hash map[string]interface{}
+ ok bool
+ hashOrVal interface{} = md.mapping
+ )
for _, k := range key {
if hash, ok = hashOrVal.(map[string]interface{}); !ok {
return false
@@ -45,51 +50,12 @@ func (md *MetaData) IsDefined(key ...string) bool {
// Type will return the empty string if given an empty key or a key that does
// not exist. Keys are case sensitive.
func (md *MetaData) Type(key ...string) string {
- fullkey := strings.Join(key, ".")
- if typ, ok := md.types[fullkey]; ok {
+ if typ, ok := md.types[Key(key).String()]; ok {
return typ.typeString()
}
return ""
}
-// Key represents any TOML key, including key groups. Use (MetaData).Keys to get
-// values of this type.
-type Key []string
-
-func (k Key) String() string { return strings.Join(k, ".") }
-
-func (k Key) maybeQuotedAll() string {
- var ss []string
- for i := range k {
- ss = append(ss, k.maybeQuoted(i))
- }
- return strings.Join(ss, ".")
-}
-
-func (k Key) maybeQuoted(i int) string {
- if k[i] == "" {
- return `""`
- }
- quote := false
- for _, c := range k[i] {
- if !isBareKeyChar(c) {
- quote = true
- break
- }
- }
- if quote {
- return `"` + quotedReplacer.Replace(k[i]) + `"`
- }
- return k[i]
-}
-
-func (k Key) add(piece string) Key {
- newKey := make(Key, len(k)+1)
- copy(newKey, k)
- newKey[len(k)] = piece
- return newKey
-}
-
// Keys returns a slice of every key in the TOML data, including key groups.
//
// Each key is itself a slice, where the first element is the top of the
@@ -115,9 +81,40 @@ func (md *MetaData) Keys() []Key {
func (md *MetaData) Undecoded() []Key {
undecoded := make([]Key, 0, len(md.keys))
for _, key := range md.keys {
- if !md.decoded[key.String()] {
+ if _, ok := md.decoded[key.String()]; !ok {
undecoded = append(undecoded, key)
}
}
return undecoded
}
+
+// Key represents any TOML key, including key groups. Use (MetaData).Keys to get
+// values of this type.
+type Key []string
+
+func (k Key) String() string {
+ ss := make([]string, len(k))
+ for i := range k {
+ ss[i] = k.maybeQuoted(i)
+ }
+ return strings.Join(ss, ".")
+}
+
+func (k Key) maybeQuoted(i int) string {
+ if k[i] == "" {
+ return `""`
+ }
+ for _, c := range k[i] {
+ if !isBareKeyChar(c) {
+ return `"` + dblQuotedReplacer.Replace(k[i]) + `"`
+ }
+ }
+ return k[i]
+}
+
+func (k Key) add(piece string) Key {
+ newKey := make(Key, len(k)+1)
+ copy(newKey, k)
+ newKey[len(k)] = piece
+ return newKey
+}
diff --git a/vendor/github.com/BurntSushi/toml/parse.go b/vendor/github.com/BurntSushi/toml/parse.go
index d9ae5db94..8269cca17 100644
--- a/vendor/github.com/BurntSushi/toml/parse.go
+++ b/vendor/github.com/BurntSushi/toml/parse.go
@@ -1,7 +1,6 @@
package toml
import (
- "errors"
"fmt"
"strconv"
"strings"
@@ -12,35 +11,23 @@ import (
)
type parser struct {
- mapping map[string]interface{}
- types map[string]tomlType
- lx *lexer
-
- ordered []Key // List of keys in the order that they appear in the TOML data.
- context Key // Full key for the current hash in scope.
- currentKey string // Base key name for everything except hashes.
- approxLine int // Rough approximation of line number
- implicits map[string]bool // Record implied keys (e.g. 'key.group.names').
-}
-
-// ParseError is used when a file can't be parsed: for example invalid integer
-// literals, duplicate keys, etc.
-type ParseError struct {
- Message string
- Line int
- LastKey string
-}
-
-func (pe ParseError) Error() string {
- return fmt.Sprintf("Near line %d (last key parsed '%s'): %s",
- pe.Line, pe.LastKey, pe.Message)
+ lx *lexer
+ context Key // Full key for the current hash in scope.
+ currentKey string // Base key name for everything except hashes.
+ pos Position // Current position in the TOML file.
+
+ ordered []Key // List of keys in the order that they appear in the TOML data.
+ mapping map[string]interface{} // Map keyname → key value.
+ types map[string]tomlType // Map keyname → TOML type.
+ implicits map[string]struct{} // Record implicit keys (e.g. "key.group.names").
}
func parse(data string) (p *parser, err error) {
defer func() {
if r := recover(); r != nil {
- var ok bool
- if err, ok = r.(ParseError); ok {
+ if pErr, ok := r.(ParseError); ok {
+ pErr.input = data
+ err = pErr
return
}
panic(r)
@@ -60,8 +47,13 @@ func parse(data string) (p *parser, err error) {
if len(data) < 6 {
ex = len(data)
}
- if strings.ContainsRune(data[:ex], 0) {
- return nil, errors.New("files cannot contain NULL bytes; probably using UTF-16; TOML files must be UTF-8")
+ if i := strings.IndexRune(data[:ex], 0); i > -1 {
+ return nil, ParseError{
+ Message: "files cannot contain NULL bytes; probably using UTF-16; TOML files must be UTF-8",
+ Position: Position{Line: 1, Start: i, Len: 1},
+ Line: 1,
+ input: data,
+ }
}
p = &parser{
@@ -69,7 +61,7 @@ func parse(data string) (p *parser, err error) {
types: make(map[string]tomlType),
lx: lex(data),
ordered: make([]Key, 0),
- implicits: make(map[string]bool),
+ implicits: make(map[string]struct{}),
}
for {
item := p.next()
@@ -82,12 +74,21 @@ func parse(data string) (p *parser, err error) {
return p, nil
}
+func (p *parser) panicItemf(it item, format string, v ...interface{}) {
+ panic(ParseError{
+ Message: fmt.Sprintf(format, v...),
+ Position: it.pos,
+ Line: it.pos.Len,
+ LastKey: p.current(),
+ })
+}
+
func (p *parser) panicf(format string, v ...interface{}) {
- msg := fmt.Sprintf(format, v...)
panic(ParseError{
- Message: msg,
- Line: p.approxLine,
- LastKey: p.current(),
+ Message: fmt.Sprintf(format, v...),
+ Position: p.pos,
+ Line: p.pos.Line,
+ LastKey: p.current(),
})
}
@@ -95,11 +96,26 @@ func (p *parser) next() item {
it := p.lx.nextItem()
//fmt.Printf("ITEM %-18s line %-3d │ %q\n", it.typ, it.line, it.val)
if it.typ == itemError {
- p.panicf("%s", it.val)
+ if it.err != nil {
+ panic(ParseError{
+ Position: it.pos,
+ Line: it.pos.Line,
+ LastKey: p.current(),
+ err: it.err,
+ })
+ }
+
+ p.panicItemf(it, "%s", it.val)
}
return it
}
+func (p *parser) nextPos() item {
+ it := p.next()
+ p.pos = it.pos
+ return it
+}
+
func (p *parser) bug(format string, v ...interface{}) {
panic(fmt.Sprintf("BUG: "+format+"\n\n", v...))
}
@@ -119,11 +135,9 @@ func (p *parser) assertEqual(expected, got itemType) {
func (p *parser) topLevel(item item) {
switch item.typ {
case itemCommentStart: // # ..
- p.approxLine = item.line
p.expect(itemText)
case itemTableStart: // [ .. ]
- name := p.next()
- p.approxLine = name.line
+ name := p.nextPos()
var key Key
for ; name.typ != itemTableEnd && name.typ != itemEOF; name = p.next() {
@@ -135,8 +149,7 @@ func (p *parser) topLevel(item item) {
p.setType("", tomlHash)
p.ordered = append(p.ordered, key)
case itemArrayTableStart: // [[ .. ]]
- name := p.next()
- p.approxLine = name.line
+ name := p.nextPos()
var key Key
for ; name.typ != itemArrayTableEnd && name.typ != itemEOF; name = p.next() {
@@ -150,8 +163,7 @@ func (p *parser) topLevel(item item) {
case itemKeyStart: // key = ..
outerContext := p.context
/// Read all the key parts (e.g. 'a' and 'b' in 'a.b')
- k := p.next()
- p.approxLine = k.line
+ k := p.nextPos()
var key Key
for ; k.typ != itemKeyEnd && k.typ != itemEOF; k = p.next() {
key = append(key, p.keyString(k))
@@ -206,9 +218,9 @@ var datetimeRepl = strings.NewReplacer(
func (p *parser) value(it item, parentIsArray bool) (interface{}, tomlType) {
switch it.typ {
case itemString:
- return p.replaceEscapes(it.val), p.typeOfPrimitive(it)
+ return p.replaceEscapes(it, it.val), p.typeOfPrimitive(it)
case itemMultilineString:
- return p.replaceEscapes(stripFirstNewline(stripEscapedNewlines(it.val))), p.typeOfPrimitive(it)
+ return p.replaceEscapes(it, stripFirstNewline(stripEscapedNewlines(it.val))), p.typeOfPrimitive(it)
case itemRawString:
return it.val, p.typeOfPrimitive(it)
case itemRawMultilineString:
@@ -240,10 +252,10 @@ func (p *parser) value(it item, parentIsArray bool) (interface{}, tomlType) {
func (p *parser) valueInteger(it item) (interface{}, tomlType) {
if !numUnderscoresOK(it.val) {
- p.panicf("Invalid integer %q: underscores must be surrounded by digits", it.val)
+ p.panicItemf(it, "Invalid integer %q: underscores must be surrounded by digits", it.val)
}
if numHasLeadingZero(it.val) {
- p.panicf("Invalid integer %q: cannot have leading zeroes", it.val)
+ p.panicItemf(it, "Invalid integer %q: cannot have leading zeroes", it.val)
}
num, err := strconv.ParseInt(it.val, 0, 64)
@@ -254,7 +266,7 @@ func (p *parser) valueInteger(it item) (interface{}, tomlType) {
// So mark the former as a bug but the latter as a legitimate user
// error.
if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {
- p.panicf("Integer '%s' is out of the range of 64-bit signed integers.", it.val)
+ p.panicItemf(it, "Integer '%s' is out of the range of 64-bit signed integers.", it.val)
} else {
p.bug("Expected integer value, but got '%s'.", it.val)
}
@@ -272,18 +284,18 @@ func (p *parser) valueFloat(it item) (interface{}, tomlType) {
})
for _, part := range parts {
if !numUnderscoresOK(part) {
- p.panicf("Invalid float %q: underscores must be surrounded by digits", it.val)
+ p.panicItemf(it, "Invalid float %q: underscores must be surrounded by digits", it.val)
}
}
if len(parts) > 0 && numHasLeadingZero(parts[0]) {
- p.panicf("Invalid float %q: cannot have leading zeroes", it.val)
+ p.panicItemf(it, "Invalid float %q: cannot have leading zeroes", it.val)
}
if !numPeriodsOK(it.val) {
// As a special case, numbers like '123.' or '1.e2',
// which are valid as far as Go/strconv are concerned,
// must be rejected because TOML says that a fractional
// part consists of '.' followed by 1+ digits.
- p.panicf("Invalid float %q: '.' must be followed by one or more digits", it.val)
+ p.panicItemf(it, "Invalid float %q: '.' must be followed by one or more digits", it.val)
}
val := strings.Replace(it.val, "_", "", -1)
if val == "+nan" || val == "-nan" { // Go doesn't support this, but TOML spec does.
@@ -292,9 +304,9 @@ func (p *parser) valueFloat(it item) (interface{}, tomlType) {
num, err := strconv.ParseFloat(val, 64)
if err != nil {
if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {
- p.panicf("Float '%s' is out of the range of 64-bit IEEE-754 floating-point numbers.", it.val)
+ p.panicItemf(it, "Float '%s' is out of the range of 64-bit IEEE-754 floating-point numbers.", it.val)
} else {
- p.panicf("Invalid float value: %q", it.val)
+ p.panicItemf(it, "Invalid float value: %q", it.val)
}
}
return num, p.typeOfPrimitive(it)
@@ -325,7 +337,7 @@ func (p *parser) valueDatetime(it item) (interface{}, tomlType) {
}
}
if !ok {
- p.panicf("Invalid TOML Datetime: %q.", it.val)
+ p.panicItemf(it, "Invalid TOML Datetime: %q.", it.val)
}
return t, p.typeOfPrimitive(it)
}
@@ -335,8 +347,12 @@ func (p *parser) valueArray(it item) (interface{}, tomlType) {
// p.setType(p.currentKey, typ)
var (
- array []interface{}
types []tomlType
+
+ // Initialize to a non-nil empty slice. This makes it consistent with
+ // how S = [] decodes into a non-nil slice inside something like struct
+ // { S []string }. See #338
+ array = []interface{}{}
)
for it = p.next(); it.typ != itemArrayEnd; it = p.next() {
if it.typ == itemCommentStart {
@@ -347,6 +363,12 @@ func (p *parser) valueArray(it item) (interface{}, tomlType) {
val, typ := p.value(it, true)
array = append(array, val)
types = append(types, typ)
+
+ // XXX: types isn't used here, we need it to record the accurate type
+ // information.
+ //
+ // Not entirely sure how to best store this; could use "key[0]",
+ // "key[1]" notation, or maybe store it on the Array type?
}
return array, tomlArray
}
@@ -373,8 +395,7 @@ func (p *parser) valueInlineTable(it item, parentIsArray bool) (interface{}, tom
}
/// Read all key parts.
- k := p.next()
- p.approxLine = k.line
+ k := p.nextPos()
var key Key
for ; k.typ != itemKeyEnd && k.typ != itemEOF; k = p.next() {
key = append(key, p.keyString(k))
@@ -408,7 +429,7 @@ func (p *parser) valueInlineTable(it item, parentIsArray bool) (interface{}, tom
// numHasLeadingZero checks if this number has leading zeroes, allowing for '0',
// +/- signs, and base prefixes.
func numHasLeadingZero(s string) bool {
- if len(s) > 1 && s[0] == '0' && isDigit(rune(s[1])) { // >1 to allow "0" and isDigit to allow 0x
+ if len(s) > 1 && s[0] == '0' && !(s[1] == 'b' || s[1] == 'o' || s[1] == 'x') { // Allow 0b, 0o, 0x
return true
}
if len(s) > 2 && (s[0] == '-' || s[0] == '+') && s[1] == '0' {
@@ -503,7 +524,7 @@ func (p *parser) addContext(key Key, array bool) {
if hash, ok := hashContext[k].([]map[string]interface{}); ok {
hashContext[k] = append(hash, make(map[string]interface{}))
} else {
- p.panicf("Key '%s' was already created and cannot be used as an array.", keyContext)
+ p.panicf("Key '%s' was already created and cannot be used as an array.", key)
}
} else {
p.setValue(key[len(key)-1], make(map[string]interface{}))
@@ -513,8 +534,8 @@ func (p *parser) addContext(key Key, array bool) {
// set calls setValue and setType.
func (p *parser) set(key string, val interface{}, typ tomlType) {
- p.setValue(p.currentKey, val)
- p.setType(p.currentKey, typ)
+ p.setValue(key, val)
+ p.setType(key, typ)
}
// setValue sets the given key to the given value in the current context.
@@ -573,27 +594,31 @@ func (p *parser) setValue(key string, value interface{}) {
hash[key] = value
}
-// setType sets the type of a particular value at a given key.
-// It should be called immediately AFTER setValue.
+// setType sets the type of a particular value at a given key. It should be
+// called immediately AFTER setValue.
//
// Note that if `key` is empty, then the type given will be applied to the
// current context (which is either a table or an array of tables).
func (p *parser) setType(key string, typ tomlType) {
keyContext := make(Key, 0, len(p.context)+1)
- for _, k := range p.context {
- keyContext = append(keyContext, k)
- }
+ keyContext = append(keyContext, p.context...)
if len(key) > 0 { // allow type setting for hashes
keyContext = append(keyContext, key)
}
+ // Special case to make empty keys ("" = 1) work.
+ // Without it it will set "" rather than `""`.
+ // TODO: why is this needed? And why is this only needed here?
+ if len(keyContext) == 0 {
+ keyContext = Key{""}
+ }
p.types[keyContext.String()] = typ
}
// Implicit keys need to be created when tables are implied in "a.b.c.d = 1" and
// "[a.b.c]" (the "a", "b", and "c" hashes are never created explicitly).
-func (p *parser) addImplicit(key Key) { p.implicits[key.String()] = true }
-func (p *parser) removeImplicit(key Key) { p.implicits[key.String()] = false }
-func (p *parser) isImplicit(key Key) bool { return p.implicits[key.String()] }
+func (p *parser) addImplicit(key Key) { p.implicits[key.String()] = struct{}{} }
+func (p *parser) removeImplicit(key Key) { delete(p.implicits, key.String()) }
+func (p *parser) isImplicit(key Key) bool { _, ok := p.implicits[key.String()]; return ok }
func (p *parser) isArray(key Key) bool { return p.types[key.String()] == tomlArray }
func (p *parser) addImplicitContext(key Key) {
p.addImplicit(key)
@@ -662,8 +687,8 @@ func stripEscapedNewlines(s string) string {
return strings.Join(split, "")
}
-func (p *parser) replaceEscapes(str string) string {
- var replaced []rune
+func (p *parser) replaceEscapes(it item, str string) string {
+ replaced := make([]rune, 0, len(str))
s := []byte(str)
r := 0
for r < len(s) {
@@ -683,7 +708,7 @@ func (p *parser) replaceEscapes(str string) string {
p.bug("Expected valid escape code after \\, but got %q.", s[r])
return ""
case ' ', '\t':
- p.panicf("invalid escape: '\\%c'", s[r])
+ p.panicItemf(it, "invalid escape: '\\%c'", s[r])
return ""
case 'b':
replaced = append(replaced, rune(0x0008))
@@ -710,14 +735,14 @@ func (p *parser) replaceEscapes(str string) string {
// At this point, we know we have a Unicode escape of the form
// `uXXXX` at [r, r+5). (Because the lexer guarantees this
// for us.)
- escaped := p.asciiEscapeToUnicode(s[r+1 : r+5])
+ escaped := p.asciiEscapeToUnicode(it, s[r+1:r+5])
replaced = append(replaced, escaped)
r += 5
case 'U':
// At this point, we know we have a Unicode escape of the form
// `uXXXX` at [r, r+9). (Because the lexer guarantees this
// for us.)
- escaped := p.asciiEscapeToUnicode(s[r+1 : r+9])
+ escaped := p.asciiEscapeToUnicode(it, s[r+1:r+9])
replaced = append(replaced, escaped)
r += 9
}
@@ -725,15 +750,14 @@ func (p *parser) replaceEscapes(str string) string {
return string(replaced)
}
-func (p *parser) asciiEscapeToUnicode(bs []byte) rune {
+func (p *parser) asciiEscapeToUnicode(it item, bs []byte) rune {
s := string(bs)
hex, err := strconv.ParseUint(strings.ToLower(s), 16, 32)
if err != nil {
- p.bug("Could not parse '%s' as a hexadecimal number, but the "+
- "lexer claims it's OK: %s", s, err)
+ p.bug("Could not parse '%s' as a hexadecimal number, but the lexer claims it's OK: %s", s, err)
}
if !utf8.ValidRune(rune(hex)) {
- p.panicf("Escaped character '\\u%s' is not valid UTF-8.", s)
+ p.panicItemf(it, "Escaped character '\\u%s' is not valid UTF-8.", s)
}
return rune(hex)
}
diff --git a/vendor/github.com/BurntSushi/toml/type_fields.go b/vendor/github.com/BurntSushi/toml/type_fields.go
index 608997c22..254ca82e5 100644
--- a/vendor/github.com/BurntSushi/toml/type_fields.go
+++ b/vendor/github.com/BurntSushi/toml/type_fields.go
@@ -70,8 +70,8 @@ func typeFields(t reflect.Type) []field {
next := []field{{typ: t}}
// Count of queued names for current level and the next.
- count := map[reflect.Type]int{}
- nextCount := map[reflect.Type]int{}
+ var count map[reflect.Type]int
+ var nextCount map[reflect.Type]int
// Types already visited at an earlier level.
visited := map[reflect.Type]bool{}
diff --git a/vendor/github.com/BurntSushi/toml/type_check.go b/vendor/github.com/BurntSushi/toml/type_toml.go
index d56aa80fa..4e90d7737 100644
--- a/vendor/github.com/BurntSushi/toml/type_check.go
+++ b/vendor/github.com/BurntSushi/toml/type_toml.go
@@ -16,7 +16,7 @@ func typeEqual(t1, t2 tomlType) bool {
return t1.typeString() == t2.typeString()
}
-func typeIsHash(t tomlType) bool {
+func typeIsTable(t tomlType) bool {
return typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash)
}
diff --git a/vendor/github.com/containers/common/libimage/copier.go b/vendor/github.com/containers/common/libimage/copier.go
index 4f5c7d0a1..459989579 100644
--- a/vendor/github.com/containers/common/libimage/copier.go
+++ b/vendor/github.com/containers/common/libimage/copier.go
@@ -218,15 +218,7 @@ func (r *Runtime) newCopier(options *CopyOptions) (*copier, error) {
c.systemContext.DockerArchiveAdditionalTags = options.dockerArchiveAdditionalTags
- if options.Architecture != "" {
- c.systemContext.ArchitectureChoice = options.Architecture
- }
- if options.OS != "" {
- c.systemContext.OSChoice = options.OS
- }
- if options.Variant != "" {
- c.systemContext.VariantChoice = options.Variant
- }
+ c.systemContext.OSChoice, c.systemContext.ArchitectureChoice, c.systemContext.VariantChoice = NormalizePlatform(options.OS, options.Architecture, options.Variant)
if options.SignaturePolicyPath != "" {
c.systemContext.SignaturePolicyPath = options.SignaturePolicyPath
diff --git a/vendor/github.com/containers/common/libimage/filters.go b/vendor/github.com/containers/common/libimage/filters.go
index dfa34dd44..063f07149 100644
--- a/vendor/github.com/containers/common/libimage/filters.go
+++ b/vendor/github.com/containers/common/libimage/filters.go
@@ -19,26 +19,53 @@ import (
// indicates that the image matches the criteria.
type filterFunc func(*Image) (bool, error)
+// Apply the specified filters. At least one filter of each key must apply.
+func (i *Image) applyFilters(filters map[string][]filterFunc) (bool, error) {
+ matches := false
+ for key := range filters { // and
+ matches = false
+ for _, filter := range filters[key] { // or
+ var err error
+ matches, err = filter(i)
+ if err != nil {
+ // Some images may have been corrupted in the
+ // meantime, so do an extra check and make the
+ // error non-fatal (see containers/podman/issues/12582).
+ if errCorrupted := i.isCorrupted(""); errCorrupted != nil {
+ logrus.Errorf(errCorrupted.Error())
+ return false, nil
+ }
+ return false, err
+ }
+ if matches {
+ break
+ }
+ }
+ if !matches {
+ return false, nil
+ }
+ }
+ return matches, nil
+}
+
// filterImages returns a slice of images which are passing all specified
// filters.
-func filterImages(images []*Image, filters []filterFunc) ([]*Image, error) {
- if len(filters) == 0 {
+func (r *Runtime) filterImages(ctx context.Context, images []*Image, options *ListImagesOptions) ([]*Image, error) {
+ if len(options.Filters) == 0 || len(images) == 0 {
return images, nil
}
+
+ filters, err := r.compileImageFilters(ctx, options)
+ if err != nil {
+ return nil, err
+ }
result := []*Image{}
for i := range images {
- include := true
- var err error
- for _, filter := range filters {
- include, err = filter(images[i])
- if err != nil {
- return nil, err
- }
- if !include {
- break
- }
+ match, err := images[i].applyFilters(filters)
+ if err != nil {
+ return nil, err
}
- if include {
+ if match {
result = append(result, images[i])
}
}
@@ -48,7 +75,7 @@ func filterImages(images []*Image, filters []filterFunc) ([]*Image, error) {
// compileImageFilters creates `filterFunc`s for the specified filters. The
// required format is `key=value` with the following supported keys:
// after, since, before, containers, dangling, id, label, readonly, reference, intermediate
-func (r *Runtime) compileImageFilters(ctx context.Context, options *ListImagesOptions) ([]filterFunc, error) {
+func (r *Runtime) compileImageFilters(ctx context.Context, options *ListImagesOptions) (map[string][]filterFunc, error) {
logrus.Tracef("Parsing image filters %s", options.Filters)
var tree *layerTree
@@ -63,12 +90,14 @@ func (r *Runtime) compileImageFilters(ctx context.Context, options *ListImagesOp
return tree, nil
}
- filterFuncs := []filterFunc{}
- for _, filter := range options.Filters {
+ filters := map[string][]filterFunc{}
+ duplicate := map[string]string{}
+ for _, f := range options.Filters {
var key, value string
- split := strings.SplitN(filter, "=", 2)
+ var filter filterFunc
+ split := strings.SplitN(f, "=", 2)
if len(split) != 2 {
- return nil, errors.Errorf("invalid image filter %q: must be in the format %q", filter, "filter=value")
+ return nil, errors.Errorf("invalid image filter %q: must be in the format %q", f, "filter=value")
}
key = split[0]
@@ -76,87 +105,148 @@ func (r *Runtime) compileImageFilters(ctx context.Context, options *ListImagesOp
switch key {
case "after", "since":
- img, _, err := r.LookupImage(value, nil)
+ img, err := r.time(key, value)
if err != nil {
- return nil, errors.Wrapf(err, "could not find local image for filter %q", filter)
+ return nil, err
}
- filterFuncs = append(filterFuncs, filterAfter(img.Created()))
+ key = "since"
+ filter = filterAfter(img.Created())
case "before":
- img, _, err := r.LookupImage(value, nil)
+ img, err := r.time(key, value)
if err != nil {
- return nil, errors.Wrapf(err, "could not find local image for filter %q", filter)
+ return nil, err
}
- filterFuncs = append(filterFuncs, filterBefore(img.Created()))
+ filter = filterBefore(img.Created())
case "containers":
- switch value {
- case "false", "true":
- case "external":
- if options.IsExternalContainerFunc == nil {
- return nil, fmt.Errorf("libimage error: external containers filter without callback")
- }
- default:
- return nil, fmt.Errorf("unsupported value %q for containers filter", value)
+ if err := r.containers(duplicate, key, value, options.IsExternalContainerFunc); err != nil {
+ return nil, err
}
- filterFuncs = append(filterFuncs, filterContainers(value, options.IsExternalContainerFunc))
+ filter = filterContainers(value, options.IsExternalContainerFunc)
case "dangling":
- dangling, err := strconv.ParseBool(value)
+ dangling, err := r.bool(duplicate, key, value)
if err != nil {
- return nil, errors.Wrapf(err, "non-boolean value %q for dangling filter", value)
+ return nil, err
}
t, err := getTree()
if err != nil {
return nil, err
}
- filterFuncs = append(filterFuncs, filterDangling(ctx, dangling, t))
+
+ filter = filterDangling(ctx, dangling, t)
case "id":
- filterFuncs = append(filterFuncs, filterID(value))
+ filter = filterID(value)
case "intermediate":
- intermediate, err := strconv.ParseBool(value)
+ intermediate, err := r.bool(duplicate, key, value)
if err != nil {
- return nil, errors.Wrapf(err, "non-boolean value %q for intermediate filter", value)
+ return nil, err
}
t, err := getTree()
if err != nil {
return nil, err
}
- filterFuncs = append(filterFuncs, filterIntermediate(ctx, intermediate, t))
+
+ filter = filterIntermediate(ctx, intermediate, t)
case "label":
- filterFuncs = append(filterFuncs, filterLabel(ctx, value))
+ filter = filterLabel(ctx, value)
case "readonly":
- readOnly, err := strconv.ParseBool(value)
+ readOnly, err := r.bool(duplicate, key, value)
if err != nil {
- return nil, errors.Wrapf(err, "non-boolean value %q for readonly filter", value)
+ return nil, err
}
- filterFuncs = append(filterFuncs, filterReadOnly(readOnly))
-
- case "reference":
- filterFuncs = append(filterFuncs, filterReferences(value))
+ filter = filterReadOnly(readOnly)
- case "until":
- ts, err := timetype.GetTimestamp(value, time.Now())
+ case "manifest":
+ manifest, err := r.bool(duplicate, key, value)
if err != nil {
return nil, err
}
- seconds, nanoseconds, err := timetype.ParseTimestamps(ts, 0)
+ filter = filterManifest(ctx, manifest)
+
+ case "reference":
+ filter = filterReferences(value)
+
+ case "until":
+ until, err := r.until(value)
if err != nil {
return nil, err
}
- until := time.Unix(seconds, nanoseconds)
- filterFuncs = append(filterFuncs, filterBefore(until))
+ filter = filterBefore(until)
default:
return nil, errors.Errorf("unsupported image filter %q", key)
}
+ filters[key] = append(filters[key], filter)
+ }
+
+ return filters, nil
+}
+
+func (r *Runtime) containers(duplicate map[string]string, key, value string, externalFunc IsExternalContainerFunc) error {
+ if exists, ok := duplicate[key]; ok && exists != value {
+ return errors.Errorf("specifying %q filter more than once with different values is not supported", key)
+ }
+ duplicate[key] = value
+ switch value {
+ case "false", "true":
+ case "external":
+ if externalFunc == nil {
+ return fmt.Errorf("libimage error: external containers filter without callback")
+ }
+ default:
+ return fmt.Errorf("unsupported value %q for containers filter", value)
+ }
+ return nil
+}
+
+func (r *Runtime) until(value string) (time.Time, error) {
+ var until time.Time
+ ts, err := timetype.GetTimestamp(value, time.Now())
+ if err != nil {
+ return until, err
}
+ seconds, nanoseconds, err := timetype.ParseTimestamps(ts, 0)
+ if err != nil {
+ return until, err
+ }
+ return time.Unix(seconds, nanoseconds), nil
+}
+
+func (r *Runtime) time(key, value string) (*Image, error) {
+ img, _, err := r.LookupImage(value, nil)
+ if err != nil {
+ return nil, errors.Wrapf(err, "could not find local image for filter filter %q=%q", key, value)
+ }
+ return img, nil
+}
+
+func (r *Runtime) bool(duplicate map[string]string, key, value string) (bool, error) {
+ if exists, ok := duplicate[key]; ok && exists != value {
+ return false, errors.Errorf("specifying %q filter more than once with different values is not supported", key)
+ }
+ duplicate[key] = value
+ set, err := strconv.ParseBool(value)
+ if err != nil {
+ return false, errors.Wrapf(err, "non-boolean value %q for %s filter", key, value)
+ }
+ return set, nil
+}
- return filterFuncs, nil
+// filterManifest filters whether or not the image is a manifest list
+func filterManifest(ctx context.Context, value bool) filterFunc {
+ return func(img *Image) (bool, error) {
+ isManifestList, err := img.IsManifestList(ctx)
+ if err != nil {
+ return false, err
+ }
+ return isManifestList == value, nil
+ }
}
// filterReferences creates a reference filter for matching the specified value.
diff --git a/vendor/github.com/containers/common/libimage/load.go b/vendor/github.com/containers/common/libimage/load.go
index 74a1870e0..4dfac7106 100644
--- a/vendor/github.com/containers/common/libimage/load.go
+++ b/vendor/github.com/containers/common/libimage/load.go
@@ -35,17 +35,6 @@ func (r *Runtime) Load(ctx context.Context, path string, options *LoadOptions) (
var loadErrors []error
for _, f := range []func() ([]string, string, error){
- // DOCKER-ARCHIVE - must be first (see containers/podman/issues/10809)
- func() ([]string, string, error) {
- logrus.Debugf("-> Attempting to load %q as a Docker archive", path)
- ref, err := dockerArchiveTransport.ParseReference(path)
- if err != nil {
- return nil, dockerArchiveTransport.Transport.Name(), err
- }
- images, err := r.loadMultiImageDockerArchive(ctx, ref, &options.CopyOptions)
- return images, dockerArchiveTransport.Transport.Name(), err
- },
-
// OCI
func() ([]string, string, error) {
logrus.Debugf("-> Attempting to load %q as an OCI directory", path)
@@ -68,6 +57,17 @@ func (r *Runtime) Load(ctx context.Context, path string, options *LoadOptions) (
return images, ociArchiveTransport.Transport.Name(), err
},
+ // DOCKER-ARCHIVE
+ func() ([]string, string, error) {
+ logrus.Debugf("-> Attempting to load %q as a Docker archive", path)
+ ref, err := dockerArchiveTransport.ParseReference(path)
+ if err != nil {
+ return nil, dockerArchiveTransport.Transport.Name(), err
+ }
+ images, err := r.loadMultiImageDockerArchive(ctx, ref, &options.CopyOptions)
+ return images, dockerArchiveTransport.Transport.Name(), err
+ },
+
// DIR
func() ([]string, string, error) {
logrus.Debugf("-> Attempting to load %q as a Docker dir", path)
diff --git a/vendor/github.com/containers/common/libimage/normalize.go b/vendor/github.com/containers/common/libimage/normalize.go
index bfea807c8..7ceb62830 100644
--- a/vendor/github.com/containers/common/libimage/normalize.go
+++ b/vendor/github.com/containers/common/libimage/normalize.go
@@ -1,13 +1,51 @@
package libimage
import (
+ "runtime"
"strings"
+ "github.com/containerd/containerd/platforms"
"github.com/containers/image/v5/docker/reference"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
+// NormalizePlatform normalizes (according to the OCI spec) the specified os,
+// arch and variant. If left empty, the individual item will not be normalized.
+func NormalizePlatform(rawOS, rawArch, rawVariant string) (os, arch, variant string) {
+ os, arch, variant = rawOS, rawArch, rawVariant
+ if os == "" {
+ os = runtime.GOOS
+ }
+ if arch == "" {
+ arch = runtime.GOARCH
+ }
+ rawPlatform := os + "/" + arch
+ if variant != "" {
+ rawPlatform += "/" + variant
+ }
+
+ normalizedPlatform, err := platforms.Parse(rawPlatform)
+ if err != nil {
+ logrus.Debugf("Error normalizing platform: %v", err)
+ return rawOS, rawArch, rawVariant
+ }
+ logrus.Debugf("Normalized platform %s to %s", rawPlatform, normalizedPlatform)
+ os = rawOS
+ if rawOS != "" {
+ os = normalizedPlatform.OS
+ }
+ arch = rawArch
+ if rawArch != "" {
+ arch = normalizedPlatform.Architecture
+ }
+ variant = rawVariant
+ if rawVariant != "" {
+ variant = normalizedPlatform.Variant
+ }
+ return os, arch, variant
+}
+
// NormalizeName normalizes the provided name according to the conventions by
// Podman and Buildah. If tag and digest are missing, the "latest" tag will be
// used. If it's a short name, it will be prefixed with "localhost/".
diff --git a/vendor/github.com/containers/common/libimage/pull.go b/vendor/github.com/containers/common/libimage/pull.go
index 59221d935..ff93b6ed8 100644
--- a/vendor/github.com/containers/common/libimage/pull.go
+++ b/vendor/github.com/containers/common/libimage/pull.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io"
+ "runtime"
"strings"
"time"
@@ -21,6 +22,7 @@ import (
"github.com/containers/image/v5/types"
"github.com/containers/storage"
digest "github.com/opencontainers/go-digest"
+ ociSpec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -169,6 +171,20 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP
return localImages, pullError
}
+// nameFromAnnotations returns a reference string to be used as an image name,
+// or an empty string. The annotations map may be nil.
+func nameFromAnnotations(annotations map[string]string) string {
+ if annotations == nil {
+ return ""
+ }
+ // buildkit/containerd are using a custom annotation see
+ // containers/podman/issues/12560.
+ if annotations["io.containerd.image.name"] != "" {
+ return annotations["io.containerd.image.name"]
+ }
+ return annotations[ociSpec.AnnotationRefName]
+}
+
// copyFromDefault is the default copier for a number of transports. Other
// transports require some specific dancing, sometimes Yoga.
func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference, options *CopyOptions) ([]string, error) {
@@ -201,15 +217,16 @@ func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference,
if err != nil {
return nil, err
}
- // if index.json has no reference name, compute the image ID instead
- if manifestDescriptor.Annotations == nil || manifestDescriptor.Annotations["org.opencontainers.image.ref.name"] == "" {
+ storageName = nameFromAnnotations(manifestDescriptor.Annotations)
+ switch len(storageName) {
+ case 0:
+ // If there's no reference name in the annotations, compute an ID.
storageName, err = getImageID(ctx, ref, nil)
if err != nil {
return nil, err
}
imageName = "sha256:" + storageName[1:]
- } else {
- storageName = manifestDescriptor.Annotations["org.opencontainers.image.ref.name"]
+ default:
named, err := NormalizeName(storageName)
if err != nil {
return nil, err
@@ -227,8 +244,14 @@ func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference,
imageName = named.String()
default:
- storageName = toLocalImageName(ref.StringWithinTransport())
- imageName = storageName
+ // Path-based transports (e.g., dir) may include invalid
+ // characters, so we should pessimistically generate an ID
+ // instead of looking at the StringWithinTransport().
+ storageName, err = getImageID(ctx, ref, nil)
+ if err != nil {
+ return nil, err
+ }
+ imageName = "sha256:" + storageName[1:]
}
// Create a storage reference.
@@ -424,12 +447,18 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str
// If there's already a local image "localhost/foo", then we should
// attempt pulling that instead of doing the full short-name dance.
//
- // NOTE: we must ignore the platform of a local image when doing
- // lookups here, even if arch/os/variant is set. Some images set an
- // incorrect or even invalid platform (see containers/podman/issues/10682).
- // Doing the lookup while ignoring the platform checks prevents
- // redundantly downloading the same image.
- localImage, resolvedImageName, err = r.LookupImage(imageName, nil)
+ // NOTE that we only do platform checks if the specified values differ
+ // from the local platform. Unfortunately, there are many images used
+ // in the wild which don't set the correct value(s) in the config
+ // causing various issues such as containers/podman/issues/10682.
+ lookupImageOptions := &LookupImageOptions{Variant: options.Variant}
+ if options.Architecture != runtime.GOARCH {
+ lookupImageOptions.Architecture = options.Architecture
+ }
+ if options.OS != runtime.GOOS {
+ lookupImageOptions.OS = options.OS
+ }
+ localImage, resolvedImageName, err = r.LookupImage(imageName, lookupImageOptions)
if err != nil && errors.Cause(err) != storage.ErrImageUnknown {
logrus.Errorf("Looking up %s in local storage: %v", imageName, err)
}
@@ -442,37 +471,18 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str
}
}
- customPlatform := false
- if len(options.Architecture)+len(options.OS)+len(options.Variant) > 0 {
- customPlatform = true
- // Unless the pull policy is "always", we must pessimistically assume
- // that the local image has an invalid architecture (see
- // containers/podman/issues/10682). Hence, whenever the user requests
- // a custom platform, set the pull policy to "always" to make sure
- // we're pulling down the image.
+ customPlatform := len(options.Architecture)+len(options.OS)+len(options.Variant) > 0
+ if customPlatform && pullPolicy != config.PullPolicyAlways && pullPolicy != config.PullPolicyNever {
+ // Unless the pull policy is always/never, we must
+ // pessimistically assume that the local image has an invalid
+ // architecture (see containers/podman/issues/10682). Hence,
+ // whenever the user requests a custom platform, set the pull
+ // policy to "newer" to make sure we're pulling down the
+ // correct image.
//
- // NOTE that this is will even override --pull={false,never}. This is
- // very likely a bug but a consistent one in Podman/Buildah and should
- // be addressed at a later point.
- if pullPolicy != config.PullPolicyAlways && pullPolicy != config.PullPolicyNever {
- switch {
- // User input clearly refer to a local image.
- case strings.HasPrefix(imageName, "localhost/"):
- logrus.Debugf("Enforcing pull policy to %q to support custom platform (arch: %q, os: %q, variant: %q)", "never", options.Architecture, options.OS, options.Variant)
- pullPolicy = config.PullPolicyNever
-
- // Image resolved to a local one, so let's still have a
- // look at the registries or aliases but use it
- // otherwise.
- case strings.HasPrefix(resolvedImageName, "localhost/"):
- logrus.Debugf("Enforcing pull policy to %q to support custom platform (arch: %q, os: %q, variant: %q)", "newer", options.Architecture, options.OS, options.Variant)
- pullPolicy = config.PullPolicyNewer
-
- default:
- logrus.Debugf("Enforcing pull policy to %q to support custom platform (arch: %q, os: %q, variant: %q)", "always", options.Architecture, options.OS, options.Variant)
- pullPolicy = config.PullPolicyAlways
- }
- }
+ // NOTE that this is will even override --pull={false,never}.
+ pullPolicy = config.PullPolicyNewer
+ logrus.Debugf("Enforcing pull policy to %q to pull custom platform (arch: %q, os: %q, variant: %q) - local image may mistakenly specify wrong platform", pullPolicy, options.Architecture, options.OS, options.Variant)
}
if pullPolicy == config.PullPolicyNever {
@@ -518,6 +528,12 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str
sys := r.systemContextCopy()
resolved, err := shortnames.Resolve(sys, imageName)
if err != nil {
+ // TODO: that is a too big of a hammer since we should only
+ // ignore errors that indicate that there's no alias and no
+ // USRs. Must be addressed in c/image first.
+ if localImage != nil && pullPolicy == config.PullPolicyNewer {
+ return []string{resolvedImageName}, nil
+ }
return nil, err
}
diff --git a/vendor/github.com/containers/common/libimage/runtime.go b/vendor/github.com/containers/common/libimage/runtime.go
index c0eee4212..86e7eee56 100644
--- a/vendor/github.com/containers/common/libimage/runtime.go
+++ b/vendor/github.com/containers/common/libimage/runtime.go
@@ -253,6 +253,8 @@ func (r *Runtime) LookupImage(name string, options *LookupImageOptions) (*Image,
if options.Variant == "" {
options.Variant = r.systemContext.VariantChoice
}
+ // Normalize platform to be OCI compatible (e.g., "aarch64" -> "arm64").
+ options.OS, options.Architecture, options.Variant = NormalizePlatform(options.OS, options.Architecture, options.Variant)
// First, check if we have an exact match in the storage. Maybe an ID
// or a fully-qualified image name.
@@ -404,9 +406,15 @@ func (r *Runtime) lookupImageInDigestsAndRepoTags(name string, options *LookupIm
digest := digested.Digest()
for _, image := range allImages {
for _, d := range image.Digests() {
- if d == digest {
- return image, name, nil
+ if d != digest {
+ continue
+ }
+ // Also make sure that the matching image fits all criteria (e.g., manifest list).
+ if _, err := r.lookupImageInLocalStorage(name, image.ID(), options); err != nil {
+ return nil, "", err
}
+ return image, name, nil
+
}
}
return nil, "", errors.Wrap(storage.ErrImageUnknown, name)
@@ -489,13 +497,16 @@ func (r *Runtime) imageReferenceMatchesContext(ref types.ImageReference, options
}
if options.Architecture != "" && options.Architecture != data.Architecture {
- return false, err
+ logrus.Debugf("architecture %q does not match architecture %q of image %s", options.Architecture, data.Architecture, ref)
+ return false, nil
}
if options.OS != "" && options.OS != data.Os {
- return false, err
+ logrus.Debugf("OS %q does not match OS %q of image %s", options.OS, data.Os, ref)
+ return false, nil
}
if options.Variant != "" && options.Variant != data.Variant {
- return false, err
+ logrus.Debugf("variant %q does not match variant %q of image %s", options.Variant, data.Variant, ref)
+ return false, nil
}
return true, nil
@@ -551,16 +562,7 @@ func (r *Runtime) ListImages(ctx context.Context, names []string, options *ListI
}
}
- var filters []filterFunc
- if len(options.Filters) > 0 {
- compiledFilters, err := r.compileImageFilters(ctx, options)
- if err != nil {
- return nil, err
- }
- filters = append(filters, compiledFilters...)
- }
-
- return filterImages(images, filters)
+ return r.filterImages(ctx, images, options)
}
// RemoveImagesOptions allow for customizing image removal.
diff --git a/vendor/github.com/containers/common/pkg/cgroups/cgroups.go b/vendor/github.com/containers/common/pkg/cgroups/cgroups.go
index d0bcd8bfd..0bf275f38 100644
--- a/vendor/github.com/containers/common/pkg/cgroups/cgroups.go
+++ b/vendor/github.com/containers/common/pkg/cgroups/cgroups.go
@@ -365,6 +365,29 @@ func readFileAsUint64(path string) (uint64, error) {
return ret, nil
}
+func readFileByKeyAsUint64(path, key string) (uint64, error) {
+ content, err := ioutil.ReadFile(path)
+ if err != nil {
+ return 0, err
+ }
+ for _, line := range strings.Split(string(content), "\n") {
+ fields := strings.SplitN(line, " ", 2)
+ if fields[0] == key {
+ v := cleanString(string(fields[1]))
+ if v == "max" {
+ return math.MaxUint64, nil
+ }
+ ret, err := strconv.ParseUint(v, 10, 64)
+ if err != nil {
+ return ret, errors.Wrapf(err, "parse %s from %s", v, path)
+ }
+ return ret, nil
+ }
+ }
+
+ return 0, fmt.Errorf("no key named %s from %s", key, path)
+}
+
// New creates a new cgroup control
func New(path string, resources *spec.LinuxResources) (*CgroupControl, error) {
cgroup2, err := IsCgroup2UnifiedMode()
@@ -509,32 +532,6 @@ func (c *CgroupControl) Delete() error {
return c.DeleteByPath(c.path)
}
-// rmDirRecursively delete recursively a cgroup directory.
-// It differs from os.RemoveAll as it doesn't attempt to unlink files.
-// On cgroupfs we are allowed only to rmdir empty directories.
-func rmDirRecursively(path string) error {
- if err := os.Remove(path); err == nil || os.IsNotExist(err) {
- return nil
- }
- entries, err := ioutil.ReadDir(path)
- if err != nil {
- return err
- }
- for _, i := range entries {
- if i.IsDir() {
- if err := rmDirRecursively(filepath.Join(path, i.Name())); err != nil {
- return err
- }
- }
- }
- if err := os.Remove(path); err != nil {
- if !os.IsNotExist(err) {
- return errors.Wrapf(err, "remove %s", path)
- }
- }
- return nil
-}
-
// DeleteByPathConn deletes the specified cgroup path using the specified
// dbus connection if needed.
func (c *CgroupControl) DeleteByPathConn(path string, conn *systemdDbus.Conn) error {
diff --git a/vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go b/vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go
index fe17db7f7..c1fe194b2 100644
--- a/vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go
+++ b/vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go
@@ -5,11 +5,13 @@ package cgroups
import (
"bufio"
"fmt"
+ "io/ioutil"
"os"
"path/filepath"
"strings"
"sync"
"syscall"
+ "time"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
@@ -88,3 +90,40 @@ func UserOwnsCurrentSystemdCgroup() (bool, error) {
}
return true, nil
}
+
+// rmDirRecursively delete recursively a cgroup directory.
+// It differs from os.RemoveAll as it doesn't attempt to unlink files.
+// On cgroupfs we are allowed only to rmdir empty directories.
+func rmDirRecursively(path string) error {
+ if err := os.Remove(path); err == nil || os.IsNotExist(err) {
+ return nil
+ }
+ entries, err := ioutil.ReadDir(path)
+ if err != nil {
+ return err
+ }
+ for _, i := range entries {
+ if i.IsDir() {
+ if err := rmDirRecursively(filepath.Join(path, i.Name())); err != nil {
+ return err
+ }
+ }
+ }
+
+ attempts := 0
+ for {
+ err := os.Remove(path)
+ if err == nil || os.IsNotExist(err) {
+ return nil
+ }
+ if errors.Is(err, unix.EBUSY) {
+ // attempt up to 5 seconds if the cgroup is busy
+ if attempts < 500 {
+ time.Sleep(time.Millisecond * 10)
+ attempts++
+ continue
+ }
+ }
+ return errors.Wrapf(err, "remove %s", path)
+ }
+}
diff --git a/vendor/github.com/containers/common/pkg/cgroups/cgroups_unsupported.go b/vendor/github.com/containers/common/pkg/cgroups/cgroups_unsupported.go
index cd140fbf3..95d424170 100644
--- a/vendor/github.com/containers/common/pkg/cgroups/cgroups_unsupported.go
+++ b/vendor/github.com/containers/common/pkg/cgroups/cgroups_unsupported.go
@@ -2,6 +2,10 @@
package cgroups
+import (
+ "os"
+)
+
// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
func IsCgroup2UnifiedMode() (bool, error) {
return false, nil
@@ -12,3 +16,7 @@ func IsCgroup2UnifiedMode() (bool, error) {
func UserOwnsCurrentSystemdCgroup() (bool, error) {
return false, nil
}
+
+func rmDirRecursively(path string) error {
+ return os.RemoveAll(path)
+}
diff --git a/vendor/github.com/containers/common/pkg/cgroups/memory.go b/vendor/github.com/containers/common/pkg/cgroups/memory.go
index b3991f7e3..10d65893c 100644
--- a/vendor/github.com/containers/common/pkg/cgroups/memory.go
+++ b/vendor/github.com/containers/common/pkg/cgroups/memory.go
@@ -7,8 +7,7 @@ import (
spec "github.com/opencontainers/runtime-spec/specs-go"
)
-type memHandler struct {
-}
+type memHandler struct{}
func getMemoryHandler() *memHandler {
return &memHandler{}
@@ -41,22 +40,23 @@ func (c *memHandler) Stat(ctr *CgroupControl, m *Metrics) error {
usage := MemoryUsage{}
var memoryRoot string
- filenames := map[string]string{}
+ var limitFilename string
if ctr.cgroup2 {
memoryRoot = filepath.Join(cgroupRoot, ctr.path)
- filenames["usage"] = "memory.current"
- filenames["limit"] = "memory.max"
+ limitFilename = "memory.max"
+ if usage.Usage, err = readFileByKeyAsUint64(filepath.Join(memoryRoot, "memory.stat"), "anon"); err != nil {
+ return err
+ }
} else {
memoryRoot = ctr.getCgroupv1Path(Memory)
- filenames["usage"] = "memory.usage_in_bytes"
- filenames["limit"] = "memory.limit_in_bytes"
+ limitFilename = "memory.limit_in_bytes"
+ if usage.Usage, err = readFileAsUint64(filepath.Join(memoryRoot, "memory.usage_in_bytes")); err != nil {
+ return err
+ }
}
- usage.Usage, err = readFileAsUint64(filepath.Join(memoryRoot, filenames["usage"]))
- if err != nil {
- return err
- }
- usage.Limit, err = readFileAsUint64(filepath.Join(memoryRoot, filenames["limit"]))
+
+ usage.Limit, err = readFileAsUint64(filepath.Join(memoryRoot, limitFilename))
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/common/pkg/cgroups/pids.go b/vendor/github.com/containers/common/pkg/cgroups/pids.go
index b2bfebe4d..58cb32b3b 100644
--- a/vendor/github.com/containers/common/pkg/cgroups/pids.go
+++ b/vendor/github.com/containers/common/pkg/cgroups/pids.go
@@ -34,6 +34,9 @@ func (c *pidHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error {
// Create the cgroup
func (c *pidHandler) Create(ctr *CgroupControl) (bool, error) {
+ if ctr.cgroup2 {
+ return false, nil
+ }
return ctr.createCgroupDirectory(Pids)
}
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index f419601e9..7f89b9252 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -48,6 +48,18 @@ const (
BoltDBStateStore RuntimeStateStore = iota
)
+// ProxyEnv is a list of Proxy Environment variables
+var ProxyEnv = []string{
+ "http_proxy",
+ "https_proxy",
+ "ftp_proxy",
+ "no_proxy",
+ "HTTP_PROXY",
+ "HTTPS_PROXY",
+ "FTP_PROXY",
+ "NO_PROXY",
+}
+
// Config contains configuration options for container tools
type Config struct {
// Containers specify settings that configure how containers will run ont the system
@@ -897,8 +909,7 @@ func (c *Config) GetDefaultEnvEx(envHost, httpProxy bool) []string {
if envHost {
env = append(env, os.Environ()...)
} else if httpProxy {
- proxy := []string{"http_proxy", "https_proxy", "ftp_proxy", "no_proxy", "HTTP_PROXY", "HTTPS_PROXY", "FTP_PROXY", "NO_PROXY"}
- for _, p := range proxy {
+ for _, p := range ProxyEnv {
if val, ok := os.LookupEnv(p); ok {
env = append(env, fmt.Sprintf("%s=%s", p, val))
}
diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go
index cd7fea4a1..561158b12 100644
--- a/vendor/github.com/containers/common/pkg/config/default.go
+++ b/vendor/github.com/containers/common/pkg/config/default.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/cgroupv2"
+ "github.com/containers/common/pkg/util"
"github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/unshare"
"github.com/containers/storage/types"
@@ -202,7 +203,6 @@ func DefaultConfig() (*Config, error) {
UserNSSize: DefaultUserNSSize,
},
Network: NetworkConfig{
- NetworkBackend: "cni",
DefaultNetwork: "podman",
DefaultSubnet: DefaultSubnet,
NetworkConfigDir: cniConfig,
@@ -371,7 +371,7 @@ func defaultTmpDir() (string, error) {
return "/run/libpod", nil
}
- runtimeDir, err := getRuntimeDir()
+ runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return "", err
}
diff --git a/vendor/github.com/containers/common/pkg/seccomp/errno_list.go b/vendor/github.com/containers/common/pkg/seccomp/errno_list.go
index 55b92ecc8..a1009012d 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/errno_list.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/errno_list.go
@@ -1,3 +1,5 @@
+// +build linux,seccomp
+
package seccomp
import (
diff --git a/vendor/github.com/containers/common/pkg/util/util.go b/vendor/github.com/containers/common/pkg/util/util.go
new file mode 100644
index 000000000..98890a686
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/util/util.go
@@ -0,0 +1,24 @@
+package util
+
+import "regexp"
+
+// StringInSlice determines if a string is in a string slice, returns bool
+func StringInSlice(s string, sl []string) bool {
+ for _, i := range sl {
+ if i == s {
+ return true
+ }
+ }
+ return false
+}
+
+// StringMatchRegexSlice determines if a given string matches one of the given regexes, returns bool
+func StringMatchRegexSlice(s string, re []string) bool {
+ for _, r := range re {
+ m, err := regexp.MatchString(r, s)
+ if err == nil && m {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/containers/common/pkg/config/util_supported.go b/vendor/github.com/containers/common/pkg/util/util_supported.go
index 33e4a9e8f..422e28742 100644
--- a/vendor/github.com/containers/common/pkg/config/util_supported.go
+++ b/vendor/github.com/containers/common/pkg/util/util_supported.go
@@ -1,6 +1,6 @@
// +build linux darwin
-package config
+package util
import (
"fmt"
@@ -19,8 +19,8 @@ var (
rootlessRuntimeDir string
)
-// getRuntimeDir returns the runtime directory
-func getRuntimeDir() (string, error) {
+// GetRuntimeDir returns the runtime directory
+func GetRuntimeDir() (string, error) {
var rootlessRuntimeDirError error
rootlessRuntimeDirOnce.Do(func() {
diff --git a/vendor/github.com/containers/common/pkg/config/util_windows.go b/vendor/github.com/containers/common/pkg/util/util_windows.go
index 995301f5d..2add712f1 100644
--- a/vendor/github.com/containers/common/pkg/config/util_windows.go
+++ b/vendor/github.com/containers/common/pkg/util/util_windows.go
@@ -1,12 +1,12 @@
// +build windows
-package config
+package util
import (
"github.com/pkg/errors"
)
// getRuntimeDir returns the runtime directory
-func getRuntimeDir() (string, error) {
+func GetRuntimeDir() (string, error) {
return "", errors.New("this function is not implemented for windows")
}
diff --git a/vendor/github.com/containers/image/v5/copy/copy.go b/vendor/github.com/containers/image/v5/copy/copy.go
index 8b785668f..383215182 100644
--- a/vendor/github.com/containers/image/v5/copy/copy.go
+++ b/vendor/github.com/containers/image/v5/copy/copy.go
@@ -1073,20 +1073,15 @@ func (c *copier) newProgressPool() *mpb.Progress {
return mpb.New(mpb.WithWidth(40), mpb.WithOutput(c.progressOutput))
}
-// customPartialBlobCounter provides a decorator function for the partial blobs retrieval progress bar
-func customPartialBlobCounter(filler interface{}, wcc ...decor.WC) decor.Decorator {
- producer := func(filler interface{}) decor.DecorFunc {
- return func(s decor.Statistics) string {
- if s.Total == 0 {
- pairFmt := "%.1f / %.1f (skipped: %.1f)"
- return fmt.Sprintf(pairFmt, decor.SizeB1024(s.Current), decor.SizeB1024(s.Total), decor.SizeB1024(s.Refill))
- }
- pairFmt := "%.1f / %.1f (skipped: %.1f = %.2f%%)"
- percentage := 100.0 * float64(s.Refill) / float64(s.Total)
- return fmt.Sprintf(pairFmt, decor.SizeB1024(s.Current), decor.SizeB1024(s.Total), decor.SizeB1024(s.Refill), percentage)
- }
- }
- return decor.Any(producer(filler), wcc...)
+// customPartialBlobDecorFunc implements mpb.DecorFunc for the partial blobs retrieval progress bar
+func customPartialBlobDecorFunc(s decor.Statistics) string {
+ if s.Total == 0 {
+ pairFmt := "%.1f / %.1f (skipped: %.1f)"
+ return fmt.Sprintf(pairFmt, decor.SizeB1024(s.Current), decor.SizeB1024(s.Total), decor.SizeB1024(s.Refill))
+ }
+ pairFmt := "%.1f / %.1f (skipped: %.1f = %.2f%%)"
+ percentage := 100.0 * float64(s.Refill) / float64(s.Total)
+ return fmt.Sprintf(pairFmt, decor.SizeB1024(s.Current), decor.SizeB1024(s.Total), decor.SizeB1024(s.Refill), percentage)
}
// createProgressBar creates a mpb.Bar in pool. Note that if the copier's reportWriter
@@ -1111,7 +1106,6 @@ func (c *copier) createProgressBar(pool *mpb.Progress, partial bool, info types.
// Use a normal progress bar when we know the size (i.e., size > 0).
// Otherwise, use a spinner to indicate that something's happening.
var bar *mpb.Bar
- sstyle := mpb.SpinnerStyle(".", "..", "...", "....", "").PositionLeft()
if info.Size > 0 {
if partial {
bar = pool.AddBar(info.Size,
@@ -1120,7 +1114,7 @@ func (c *copier) createProgressBar(pool *mpb.Progress, partial bool, info types.
decor.OnComplete(decor.Name(prefix), onComplete),
),
mpb.AppendDecorators(
- customPartialBlobCounter(sstyle.Build()),
+ decor.Any(customPartialBlobDecorFunc),
),
)
} else {
@@ -1135,8 +1129,8 @@ func (c *copier) createProgressBar(pool *mpb.Progress, partial bool, info types.
)
}
} else {
- bar = pool.Add(0,
- sstyle.Build(),
+ bar = pool.New(0,
+ mpb.SpinnerStyle(".", "..", "...", "....", "").PositionLeft(),
mpb.BarFillerClearOnComplete(),
mpb.PrependDecorators(
decor.OnComplete(decor.Name(prefix), onComplete),
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 3fe9a11d0..833323b42 100644
--- a/vendor/github.com/containers/image/v5/docker/docker_client.go
+++ b/vendor/github.com/containers/image/v5/docker/docker_client.go
@@ -711,7 +711,7 @@ func (c *dockerClient) getBearerToken(ctx context.Context, challenge challenge,
return nil, err
}
defer res.Body.Close()
- if err := httpResponseToError(res, "Requesting bear token"); err != nil {
+ if err := httpResponseToError(res, "Requesting bearer token"); err != nil {
return nil, err
}
tokenBlob, err := iolimits.ReadAtMost(res.Body, iolimits.MaxAuthTokenBodySize)
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 76362a66e..8fa530549 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
@@ -190,14 +190,12 @@ func GetAllCredentials(sys *types.SystemContext) (map[string]types.DockerAuthCon
for key := range allKeys {
authConf, err := GetCredentials(sys, key)
if err != nil {
- if credentials.IsErrCredentialsNotFoundMessage(err.Error()) {
- // Ignore if the credentials could not be found (anymore).
- continue
- }
// Note: we rely on the logging in `GetCredentials`.
return nil, err
}
- authConfigs[key] = authConf
+ if authConf != (types.DockerAuthConfig{}) {
+ authConfigs[key] = authConf
+ }
}
return authConfigs, nil
@@ -285,7 +283,7 @@ func getCredentialsWithHomeDir(sys *types.SystemContext, key, homeDir string) (t
return types.DockerAuthConfig{}, "", err
}
- if (authConfig.Username != "" && authConfig.Password != "") || authConfig.IdentityToken != "" {
+ if authConfig != (types.DockerAuthConfig{}) {
return authConfig, path.path, nil
}
}
diff --git a/vendor/github.com/vbauerster/mpb/v7/README.md b/vendor/github.com/vbauerster/mpb/v7/README.md
index ee1b21231..413f9e1db 100644
--- a/vendor/github.com/vbauerster/mpb/v7/README.md
+++ b/vendor/github.com/vbauerster/mpb/v7/README.md
@@ -36,10 +36,10 @@ func main() {
total := 100
name := "Single Bar:"
- // adding a single bar, which will inherit container's width
- bar := p.Add(int64(total),
- // progress bar filler with customized style
- mpb.NewBarFiller(mpb.BarStyle().Lbound("╢").Filler("▌").Tip("▌").Padding("░").Rbound("╟")),
+ // create a single bar, which will inherit container's width
+ bar := p.New(int64(total),
+ // BarFillerBuilder with custom style
+ mpb.BarStyle().Lbound("╢").Filler("▌").Tip("▌").Padding("░").Rbound("╟"),
mpb.PrependDecorators(
// display our name with one space on the right
decor.Name(name, decor.WC{W: len(name) + 1, C: decor.DidentRight}),
@@ -65,7 +65,7 @@ func main() {
```go
var wg sync.WaitGroup
- // passed &wg will be accounted at p.Wait() call
+ // passed wg will be accounted at p.Wait() call
p := mpb.New(mpb.WithWaitGroup(&wg))
total, numBars := 100, 3
wg.Add(numBars)
@@ -103,7 +103,7 @@ func main() {
}
}()
}
- // Waiting for passed &wg and for all bars to complete and flush
+ // wait for passed wg and for all bars to complete and flush
p.Wait()
```
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar.go b/vendor/github.com/vbauerster/mpb/v7/bar.go
index d07dc165c..35644a411 100644
--- a/vendor/github.com/vbauerster/mpb/v7/bar.go
+++ b/vendor/github.com/vbauerster/mpb/v7/bar.go
@@ -165,12 +165,12 @@ func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) {
}
// SetTotal sets total dynamically.
-// If total is less than or equal to zero it takes progress' current value.
+// If total is negative it takes progress' current value.
func (b *Bar) SetTotal(total int64, triggerComplete bool) {
select {
case b.operateState <- func(s *bState) {
s.triggerComplete = triggerComplete
- if total <= 0 {
+ if total < 0 {
s.total = s.current
} else {
s.total = total
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_filler.go b/vendor/github.com/vbauerster/mpb/v7/bar_filler.go
index a69087c47..81177fc2e 100644
--- a/vendor/github.com/vbauerster/mpb/v7/bar_filler.go
+++ b/vendor/github.com/vbauerster/mpb/v7/bar_filler.go
@@ -9,31 +9,42 @@ import (
// BarFiller interface.
// Bar (without decorators) renders itself by calling BarFiller's Fill method.
//
-// reqWidth is requested width, set by `func WithWidth(int) ContainerOption`.
+// reqWidth is requested width set by `func WithWidth(int) ContainerOption`.
// If not set, it defaults to terminal width.
//
-// Default implementations can be obtained via:
-//
-// func NewBarFiller(BarStyle()) BarFiller
-// func NewBarFiller(SpinnerStyle()) BarFiller
-//
type BarFiller interface {
Fill(w io.Writer, reqWidth int, stat decor.Statistics)
}
// BarFillerBuilder interface.
+// Default implementations are:
+//
+// BarStyle()
+// SpinnerStyle()
+// NopStyle()
+//
type BarFillerBuilder interface {
Build() BarFiller
}
-// BarFillerFunc is function type adapter to convert function into BarFiller.
+// BarFillerFunc is function type adapter to convert compatible function
+// into BarFiller interface.
type BarFillerFunc func(w io.Writer, reqWidth int, stat decor.Statistics)
func (f BarFillerFunc) Fill(w io.Writer, reqWidth int, stat decor.Statistics) {
f(w, reqWidth, stat)
}
+// BarFillerBuilderFunc is function type adapter to convert compatible
+// function into BarFillerBuilder interface.
+type BarFillerBuilderFunc func() BarFiller
+
+func (f BarFillerBuilderFunc) Build() BarFiller {
+ return f()
+}
+
// NewBarFiller constructs a BarFiller from provided BarFillerBuilder.
+// Deprecated. Prefer using `*Progress.New(...)` directly.
func NewBarFiller(b BarFillerBuilder) BarFiller {
return b.Build()
}
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_filler_nop.go b/vendor/github.com/vbauerster/mpb/v7/bar_filler_nop.go
new file mode 100644
index 000000000..1a7086fec
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/bar_filler_nop.go
@@ -0,0 +1,14 @@
+package mpb
+
+import (
+ "io"
+
+ "github.com/vbauerster/mpb/v7/decor"
+)
+
+// NopStyle provides BarFillerBuilder which builds NOP BarFiller.
+func NopStyle() BarFillerBuilder {
+ return BarFillerBuilderFunc(func() BarFiller {
+ return BarFillerFunc(func(io.Writer, int, decor.Statistics) {})
+ })
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_option.go b/vendor/github.com/vbauerster/mpb/v7/bar_option.go
index 46b7de0bf..660e7c487 100644
--- a/vendor/github.com/vbauerster/mpb/v7/bar_option.go
+++ b/vendor/github.com/vbauerster/mpb/v7/bar_option.go
@@ -5,12 +5,20 @@ import (
"io"
"github.com/vbauerster/mpb/v7/decor"
- "github.com/vbauerster/mpb/v7/internal"
)
// BarOption is a func option to alter default behavior of a bar.
type BarOption func(*bState)
+func skipNil(decorators []decor.Decorator) (filtered []decor.Decorator) {
+ for _, d := range decorators {
+ if d != nil {
+ filtered = append(filtered, d)
+ }
+ }
+ return
+}
+
func (s *bState) addDecorators(dest *[]decor.Decorator, decorators ...decor.Decorator) {
type mergeWrapper interface {
MergeUnwrap() []decor.Decorator
@@ -26,14 +34,14 @@ func (s *bState) addDecorators(dest *[]decor.Decorator, decorators ...decor.Deco
// AppendDecorators let you inject decorators to the bar's right side.
func AppendDecorators(decorators ...decor.Decorator) BarOption {
return func(s *bState) {
- s.addDecorators(&s.aDecorators, decorators...)
+ s.addDecorators(&s.aDecorators, skipNil(decorators)...)
}
}
// PrependDecorators let you inject decorators to the bar's left side.
func PrependDecorators(decorators ...decor.Decorator) BarOption {
return func(s *bState) {
- s.addDecorators(&s.pDecorators, decorators...)
+ s.addDecorators(&s.pDecorators, skipNil(decorators)...)
}
}
@@ -138,9 +146,12 @@ func BarNoPop() BarOption {
}
}
-// BarOptional will invoke provided option only when pick is true.
-func BarOptional(option BarOption, pick bool) BarOption {
- return BarOptOn(option, internal.Predicate(pick))
+// BarOptional will invoke provided option only when cond is true.
+func BarOptional(option BarOption, cond bool) BarOption {
+ if cond {
+ return option
+ }
+ return nil
}
// BarOptOn will invoke provided option only when higher order predicate
diff --git a/vendor/github.com/vbauerster/mpb/v7/container_option.go b/vendor/github.com/vbauerster/mpb/v7/container_option.go
index a858c3c51..e523a1759 100644
--- a/vendor/github.com/vbauerster/mpb/v7/container_option.go
+++ b/vendor/github.com/vbauerster/mpb/v7/container_option.go
@@ -5,8 +5,6 @@ import (
"io/ioutil"
"sync"
"time"
-
- "github.com/vbauerster/mpb/v7/internal"
)
// ContainerOption is a func option to alter default behavior of a bar
@@ -101,9 +99,12 @@ func PopCompletedMode() ContainerOption {
}
}
-// ContainerOptional will invoke provided option only when pick is true.
-func ContainerOptional(option ContainerOption, pick bool) ContainerOption {
- return ContainerOptOn(option, internal.Predicate(pick))
+// ContainerOptional will invoke provided option only when cond is true.
+func ContainerOptional(option ContainerOption, cond bool) ContainerOption {
+ if cond {
+ return option
+ }
+ return nil
}
// ContainerOptOn will invoke provided option only when higher order
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/merge.go b/vendor/github.com/vbauerster/mpb/v7/decor/merge.go
index e41406a64..847671155 100644
--- a/vendor/github.com/vbauerster/mpb/v7/decor/merge.go
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/merge.go
@@ -17,6 +17,9 @@ import (
// +----+--------+---------+--------+
//
func Merge(decorator Decorator, placeholders ...WC) Decorator {
+ if decorator == nil {
+ return nil
+ }
if _, ok := decorator.Sync(); !ok || len(placeholders) == 0 {
return decorator
}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/on_abort.go b/vendor/github.com/vbauerster/mpb/v7/decor/on_abort.go
index 7ece120a2..10ff67009 100644
--- a/vendor/github.com/vbauerster/mpb/v7/decor/on_abort.go
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/on_abort.go
@@ -9,6 +9,9 @@ package decor
// `message` message to display on abort event
//
func OnAbort(decorator Decorator, message string) Decorator {
+ if decorator == nil {
+ return nil
+ }
d := &onAbortWrapper{
Decorator: decorator,
msg: message,
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go b/vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go
index c7c9e4d31..2ada2b31b 100644
--- a/vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go
@@ -8,6 +8,9 @@ package decor
// `message` message to display on complete event
//
func OnComplete(decorator Decorator, message string) Decorator {
+ if decorator == nil {
+ return nil
+ }
d := &onCompleteWrapper{
Decorator: decorator,
msg: message,
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/on_condition.go b/vendor/github.com/vbauerster/mpb/v7/decor/on_condition.go
new file mode 100644
index 000000000..a9db0653a
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/on_condition.go
@@ -0,0 +1,27 @@
+package decor
+
+// OnPredicate returns decorator if predicate evaluates to true.
+//
+// `decorator` Decorator
+//
+// `predicate` func() bool
+//
+func OnPredicate(decorator Decorator, predicate func() bool) Decorator {
+ if predicate() {
+ return decorator
+ }
+ return nil
+}
+
+// OnCondition returns decorator if condition is true.
+//
+// `decorator` Decorator
+//
+// `cond` bool
+//
+func OnCondition(decorator Decorator, cond bool) Decorator {
+ if cond {
+ return decorator
+ }
+ return nil
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/go.mod b/vendor/github.com/vbauerster/mpb/v7/go.mod
index 32008c66c..19a6f8044 100644
--- a/vendor/github.com/vbauerster/mpb/v7/go.mod
+++ b/vendor/github.com/vbauerster/mpb/v7/go.mod
@@ -4,7 +4,7 @@ require (
github.com/VividCortex/ewma v1.2.0
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/mattn/go-runewidth v0.0.13
- golang.org/x/sys v0.0.0-20211124211545-fe61309f8881
+ golang.org/x/sys v0.0.0-20211214234402-4825e8c3871d
)
go 1.14
diff --git a/vendor/github.com/vbauerster/mpb/v7/go.sum b/vendor/github.com/vbauerster/mpb/v7/go.sum
index 6fed396bb..b4388d9ea 100644
--- a/vendor/github.com/vbauerster/mpb/v7/go.sum
+++ b/vendor/github.com/vbauerster/mpb/v7/go.sum
@@ -6,5 +6,5 @@ github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
-golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc=
-golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211214234402-4825e8c3871d h1:1oIt9o40TWWI9FUaveVpUvBe13FNqBNVXy3ue2fcfkw=
+golang.org/x/sys v0.0.0-20211214234402-4825e8c3871d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
diff --git a/vendor/github.com/vbauerster/mpb/v7/internal/predicate.go b/vendor/github.com/vbauerster/mpb/v7/internal/predicate.go
deleted file mode 100644
index 1e4dd24d9..000000000
--- a/vendor/github.com/vbauerster/mpb/v7/internal/predicate.go
+++ /dev/null
@@ -1,6 +0,0 @@
-package internal
-
-// Predicate helper for internal use.
-func Predicate(pick bool) func() bool {
- return func() bool { return pick }
-}
diff --git a/vendor/github.com/vbauerster/mpb/v7/progress.go b/vendor/github.com/vbauerster/mpb/v7/progress.go
index c60c65694..46485f719 100644
--- a/vendor/github.com/vbauerster/mpb/v7/progress.go
+++ b/vendor/github.com/vbauerster/mpb/v7/progress.go
@@ -99,17 +99,19 @@ func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress {
return p
}
-// AddBar creates a bar with default bar filler. Different filler can
-// be chosen and applied via `*Progress.Add(...) *Bar` method.
+// AddBar creates a bar with default bar filler.
func (p *Progress) AddBar(total int64, options ...BarOption) *Bar {
- return p.Add(total, NewBarFiller(BarStyle()), options...)
+ return p.New(total, BarStyle(), options...)
}
-// AddSpinner creates a bar with default spinner filler. Different
-// filler can be chosen and applied via `*Progress.Add(...) *Bar`
-// method.
+// AddSpinner creates a bar with default spinner filler.
func (p *Progress) AddSpinner(total int64, options ...BarOption) *Bar {
- return p.Add(total, NewBarFiller(SpinnerStyle()), options...)
+ return p.New(total, SpinnerStyle(), options...)
+}
+
+// New creates a bar with provided BarFillerBuilder.
+func (p *Progress) New(total int64, builder BarFillerBuilder, options ...BarOption) *Bar {
+ return p.Add(total, builder.Build(), options...)
}
// Add creates a bar which renders itself by provided filler.
@@ -117,7 +119,7 @@ func (p *Progress) AddSpinner(total int64, options ...BarOption) *Bar {
// Panics if *Progress instance is done, i.e. called after *Progress.Wait().
func (p *Progress) Add(total int64, filler BarFiller, options ...BarOption) *Bar {
if filler == nil {
- filler = BarFillerFunc(func(io.Writer, int, decor.Statistics) {})
+ filler = NopStyle().Build()
}
p.bwg.Add(1)
result := make(chan *Bar)
diff --git a/vendor/github.com/vbauerster/mpb/v7/proxyreader.go b/vendor/github.com/vbauerster/mpb/v7/proxyreader.go
index 2f20053bd..a16f5ec8a 100644
--- a/vendor/github.com/vbauerster/mpb/v7/proxyreader.go
+++ b/vendor/github.com/vbauerster/mpb/v7/proxyreader.go
@@ -15,7 +15,7 @@ func (x *proxyReader) Read(p []byte) (int, error) {
n, err := x.ReadCloser.Read(p)
x.bar.IncrBy(n)
if err == io.EOF {
- go x.bar.SetTotal(0, true)
+ go x.bar.SetTotal(-1, true)
}
return n, err
}
@@ -30,7 +30,7 @@ func (x *proxyWriterTo) WriteTo(w io.Writer) (int64, error) {
n, err := x.wt.WriteTo(w)
x.bar.IncrInt64(n)
if err == io.EOF {
- go x.bar.SetTotal(0, true)
+ go x.bar.SetTotal(-1, true)
}
return n, err
}
diff --git a/vendor/golang.org/x/sys/plan9/syscall_plan9.go b/vendor/golang.org/x/sys/plan9/syscall_plan9.go
index 84e147148..723b1f400 100644
--- a/vendor/golang.org/x/sys/plan9/syscall_plan9.go
+++ b/vendor/golang.org/x/sys/plan9/syscall_plan9.go
@@ -132,8 +132,10 @@ func Pipe(p []int) (err error) {
}
var pp [2]int32
err = pipe(&pp)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return
}
diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh
index 4945739ea..a47b035f9 100644
--- a/vendor/golang.org/x/sys/unix/mkerrors.sh
+++ b/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -261,6 +261,7 @@ struct ltchars {
#include <linux/vm_sockets.h>
#include <linux/wait.h>
#include <linux/watchdog.h>
+#include <linux/wireguard.h>
#include <mtd/ubi-user.h>
#include <mtd/mtd-user.h>
@@ -606,6 +607,7 @@ ccflags="$@"
$2 ~ /^MTD/ ||
$2 ~ /^OTP/ ||
$2 ~ /^MEM/ ||
+ $2 ~ /^WG/ ||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
$2 ~ /^__WCOREFLAG$/ {next}
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
diff --git a/vendor/golang.org/x/sys/unix/syscall_aix.go b/vendor/golang.org/x/sys/unix/syscall_aix.go
index 6192750ce..4f55c8d99 100644
--- a/vendor/golang.org/x/sys/unix/syscall_aix.go
+++ b/vendor/golang.org/x/sys/unix/syscall_aix.go
@@ -519,8 +519,10 @@ func Pipe(p []int) (err error) {
}
var pp [2]_C_int
err = pipe(&pp)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return
}
diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go
index 8826f4143..0eaab9131 100644
--- a/vendor/golang.org/x/sys/unix/syscall_darwin.go
+++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go
@@ -159,8 +159,10 @@ func Pipe(p []int) (err error) {
}
var x [2]int32
err = pipe(&x)
- p[0] = int(x[0])
- p[1] = int(x[1])
+ if err == nil {
+ p[0] = int(x[0])
+ p[1] = int(x[1])
+ }
return
}
diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
index 5af108a50..2e37c3167 100644
--- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
+++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
@@ -101,7 +101,10 @@ func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
- p[0], p[1], err = pipe()
+ r, w, err := pipe()
+ if err == nil {
+ p[0], p[1] = r, w
+ }
return
}
@@ -114,7 +117,10 @@ func Pipe2(p []int, flags int) (err error) {
var pp [2]_C_int
// pipe2 on dragonfly takes an fds array as an argument, but still
// returns the file descriptors.
- p[0], p[1], err = pipe2(&pp, flags)
+ r, w, err := pipe2(&pp, flags)
+ if err == nil {
+ p[0], p[1] = r, w
+ }
return err
}
diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go
index 18c392cf3..2f650ae66 100644
--- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go
@@ -110,8 +110,10 @@ func Pipe2(p []int, flags int) error {
}
var pp [2]_C_int
err := pipe2(&pp, flags)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return err
}
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index 4bc5baf77..f432b0684 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -131,8 +131,10 @@ func Pipe2(p []int, flags int) error {
}
var pp [2]_C_int
err := pipe2(&pp, flags)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return err
}
diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go
index 853d5f0f4..696fed496 100644
--- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go
@@ -110,14 +110,8 @@ func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
-//sysnb pipe() (fd1 int, fd2 int, err error)
-
func Pipe(p []int) (err error) {
- if len(p) != 2 {
- return EINVAL
- }
- p[0], p[1], err = pipe()
- return
+ return Pipe2(p, 0)
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
@@ -128,8 +122,10 @@ func Pipe2(p []int, flags int) error {
}
var pp [2]_C_int
err := pipe2(&pp, flags)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return err
}
diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/vendor/golang.org/x/sys/unix/syscall_openbsd.go
index 22b550385..11b1d419d 100644
--- a/vendor/golang.org/x/sys/unix/syscall_openbsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_openbsd.go
@@ -87,8 +87,10 @@ func Pipe2(p []int, flags int) error {
}
var pp [2]_C_int
err := pipe2(&pp, flags)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return err
}
diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go
index 8b88ac213..5c813921e 100644
--- a/vendor/golang.org/x/sys/unix/syscall_solaris.go
+++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go
@@ -66,8 +66,10 @@ func Pipe(p []int) (err error) {
if n != 0 {
return err
}
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return nil
}
@@ -79,8 +81,10 @@ func Pipe2(p []int, flags int) error {
}
var pp [2]_C_int
err := pipe2(&pp, flags)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return err
}
diff --git a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
index 5fb76a146..f8616f454 100644
--- a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
+++ b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
@@ -579,8 +579,10 @@ func Pipe(p []int) (err error) {
}
var pp [2]_C_int
err = pipe(&pp)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return
}
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go
index d175aae89..bcc45d108 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go
@@ -2826,6 +2826,13 @@ const (
WDIOS_TEMPPANIC = 0x4
WDIOS_UNKNOWN = -0x1
WEXITED = 0x4
+ WGALLOWEDIP_A_MAX = 0x3
+ WGDEVICE_A_MAX = 0x8
+ WGPEER_A_MAX = 0xa
+ WG_CMD_MAX = 0x1
+ WG_GENL_NAME = "wireguard"
+ WG_GENL_VERSION = 0x1
+ WG_KEY_LEN = 0x20
WIN_ACKMEDIACHANGE = 0xdb
WIN_CHECKPOWERMODE1 = 0xe5
WIN_CHECKPOWERMODE2 = 0x98
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
index 4726ab30a..51d0c0742 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
@@ -351,18 +351,6 @@ func Munlockall() (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func pipe() (fd1 int, fd2 int, err error) {
- r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
- fd1 = int(r0)
- fd2 = int(r1)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func pipe2(p *[2]_C_int, flags int) (err error) {
_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
index fe71456db..df2efb6db 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
@@ -351,18 +351,6 @@ func Munlockall() (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func pipe() (fd1 int, fd2 int, err error) {
- r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
- fd1 = int(r0)
- fd2 = int(r1)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func pipe2(p *[2]_C_int, flags int) (err error) {
_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
index 0b5b2f014..c8536c2c9 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
@@ -351,18 +351,6 @@ func Munlockall() (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func pipe() (fd1 int, fd2 int, err error) {
- r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
- fd1 = int(r0)
- fd2 = int(r1)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func pipe2(p *[2]_C_int, flags int) (err error) {
_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go
index bfca28648..8b981bfc2 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go
@@ -351,18 +351,6 @@ func Munlockall() (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func pipe() (fd1 int, fd2 int, err error) {
- r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
- fd1 = int(r0)
- fd2 = int(r1)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func pipe2(p *[2]_C_int, flags int) (err error) {
_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go
index 37b521436..e76b7f6f9 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go
@@ -867,6 +867,7 @@ const (
CTRL_CMD_NEWMCAST_GRP = 0x7
CTRL_CMD_DELMCAST_GRP = 0x8
CTRL_CMD_GETMCAST_GRP = 0x9
+ CTRL_CMD_GETPOLICY = 0xa
CTRL_ATTR_UNSPEC = 0x0
CTRL_ATTR_FAMILY_ID = 0x1
CTRL_ATTR_FAMILY_NAME = 0x2
@@ -875,12 +876,19 @@ const (
CTRL_ATTR_MAXATTR = 0x5
CTRL_ATTR_OPS = 0x6
CTRL_ATTR_MCAST_GROUPS = 0x7
+ CTRL_ATTR_POLICY = 0x8
+ CTRL_ATTR_OP_POLICY = 0x9
+ CTRL_ATTR_OP = 0xa
CTRL_ATTR_OP_UNSPEC = 0x0
CTRL_ATTR_OP_ID = 0x1
CTRL_ATTR_OP_FLAGS = 0x2
CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0
CTRL_ATTR_MCAST_GRP_NAME = 0x1
CTRL_ATTR_MCAST_GRP_ID = 0x2
+ CTRL_ATTR_POLICY_UNSPEC = 0x0
+ CTRL_ATTR_POLICY_DO = 0x1
+ CTRL_ATTR_POLICY_DUMP = 0x2
+ CTRL_ATTR_POLICY_DUMP_MAX = 0x2
)
const (
@@ -3968,3 +3976,36 @@ type MountAttr struct {
Propagation uint64
Userns_fd uint64
}
+
+const (
+ WG_CMD_GET_DEVICE = 0x0
+ WG_CMD_SET_DEVICE = 0x1
+ WGDEVICE_F_REPLACE_PEERS = 0x1
+ WGDEVICE_A_UNSPEC = 0x0
+ WGDEVICE_A_IFINDEX = 0x1
+ WGDEVICE_A_IFNAME = 0x2
+ WGDEVICE_A_PRIVATE_KEY = 0x3
+ WGDEVICE_A_PUBLIC_KEY = 0x4
+ WGDEVICE_A_FLAGS = 0x5
+ WGDEVICE_A_LISTEN_PORT = 0x6
+ WGDEVICE_A_FWMARK = 0x7
+ WGDEVICE_A_PEERS = 0x8
+ WGPEER_F_REMOVE_ME = 0x1
+ WGPEER_F_REPLACE_ALLOWEDIPS = 0x2
+ WGPEER_F_UPDATE_ONLY = 0x4
+ WGPEER_A_UNSPEC = 0x0
+ WGPEER_A_PUBLIC_KEY = 0x1
+ WGPEER_A_PRESHARED_KEY = 0x2
+ WGPEER_A_FLAGS = 0x3
+ WGPEER_A_ENDPOINT = 0x4
+ WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL = 0x5
+ WGPEER_A_LAST_HANDSHAKE_TIME = 0x6
+ WGPEER_A_RX_BYTES = 0x7
+ WGPEER_A_TX_BYTES = 0x8
+ WGPEER_A_ALLOWEDIPS = 0x9
+ WGPEER_A_PROTOCOL_VERSION = 0xa
+ WGALLOWEDIP_A_UNSPEC = 0x0
+ WGALLOWEDIP_A_FAMILY = 0x1
+ WGALLOWEDIP_A_IPADDR = 0x2
+ WGALLOWEDIP_A_CIDR_MASK = 0x3
+)
diff --git a/vendor/golang.org/x/sys/windows/exec_windows.go b/vendor/golang.org/x/sys/windows/exec_windows.go
index 7a11e83b7..855698bb2 100644
--- a/vendor/golang.org/x/sys/windows/exec_windows.go
+++ b/vendor/golang.org/x/sys/windows/exec_windows.go
@@ -9,8 +9,6 @@ package windows
import (
errorspkg "errors"
"unsafe"
-
- "golang.org/x/sys/internal/unsafeheader"
)
// EscapeArg rewrites command line argument s as prescribed
@@ -147,8 +145,12 @@ func NewProcThreadAttributeList(maxAttrCount uint32) (*ProcThreadAttributeListCo
}
return nil, err
}
+ alloc, err := LocalAlloc(LMEM_FIXED, uint32(size))
+ if err != nil {
+ return nil, err
+ }
// size is guaranteed to be ≥1 by InitializeProcThreadAttributeList.
- al := &ProcThreadAttributeListContainer{data: (*ProcThreadAttributeList)(unsafe.Pointer(&make([]byte, size)[0]))}
+ al := &ProcThreadAttributeListContainer{data: (*ProcThreadAttributeList)(unsafe.Pointer(alloc))}
err = initializeProcThreadAttributeList(al.data, maxAttrCount, 0, &size)
if err != nil {
return nil, err
@@ -157,36 +159,17 @@ func NewProcThreadAttributeList(maxAttrCount uint32) (*ProcThreadAttributeListCo
}
// Update modifies the ProcThreadAttributeList using UpdateProcThreadAttribute.
-// Note that the value passed to this function will be copied into memory
-// allocated by LocalAlloc, the contents of which should not contain any
-// Go-managed pointers, even if the passed value itself is a Go-managed
-// pointer.
func (al *ProcThreadAttributeListContainer) Update(attribute uintptr, value unsafe.Pointer, size uintptr) error {
- alloc, err := LocalAlloc(LMEM_FIXED, uint32(size))
- if err != nil {
- return err
- }
- var src, dst []byte
- hdr := (*unsafeheader.Slice)(unsafe.Pointer(&src))
- hdr.Data = value
- hdr.Cap = int(size)
- hdr.Len = int(size)
- hdr = (*unsafeheader.Slice)(unsafe.Pointer(&dst))
- hdr.Data = unsafe.Pointer(alloc)
- hdr.Cap = int(size)
- hdr.Len = int(size)
- copy(dst, src)
- al.heapAllocations = append(al.heapAllocations, alloc)
- return updateProcThreadAttribute(al.data, 0, attribute, unsafe.Pointer(alloc), size, nil, nil)
+ al.pointers = append(al.pointers, value)
+ return updateProcThreadAttribute(al.data, 0, attribute, value, size, nil, nil)
}
// Delete frees ProcThreadAttributeList's resources.
func (al *ProcThreadAttributeListContainer) Delete() {
deleteProcThreadAttributeList(al.data)
- for i := range al.heapAllocations {
- LocalFree(Handle(al.heapAllocations[i]))
- }
- al.heapAllocations = nil
+ LocalFree(Handle(unsafe.Pointer(al.data)))
+ al.data = nil
+ al.pointers = nil
}
// List returns the actual ProcThreadAttributeList to be passed to StartupInfoEx.
diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go
index 73087bf5e..655447e8f 100644
--- a/vendor/golang.org/x/sys/windows/types_windows.go
+++ b/vendor/golang.org/x/sys/windows/types_windows.go
@@ -938,8 +938,8 @@ type StartupInfoEx struct {
type ProcThreadAttributeList struct{}
type ProcThreadAttributeListContainer struct {
- data *ProcThreadAttributeList
- heapAllocations []uintptr
+ data *ProcThreadAttributeList
+ pointers []unsafe.Pointer
}
type ProcessInformation struct {
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 68f9e5a99..54d49db42 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1,7 +1,7 @@
# github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1
github.com/Azure/go-ansiterm
github.com/Azure/go-ansiterm/winterm
-# github.com/BurntSushi/toml v0.4.1
+# github.com/BurntSushi/toml v1.0.0
## explicit
github.com/BurntSushi/toml
github.com/BurntSushi/toml/internal
@@ -63,7 +63,7 @@ github.com/container-orchestrated-devices/container-device-interface/pkg
github.com/container-orchestrated-devices/container-device-interface/specs-go
# github.com/containerd/cgroups v1.0.1
github.com/containerd/cgroups/stats/v1
-# github.com/containerd/containerd v1.5.8
+# github.com/containerd/containerd v1.5.9
github.com/containerd/containerd/errdefs
github.com/containerd/containerd/log
github.com/containerd/containerd/pkg/userns
@@ -106,7 +106,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.46.1-0.20211209220542-24f363480347
+# github.com/containers/common v0.46.1-0.20220112112017-31e8cc4aeeab
## explicit
github.com/containers/common/libimage
github.com/containers/common/libimage/manifests
@@ -139,11 +139,12 @@ github.com/containers/common/pkg/supplemented
github.com/containers/common/pkg/sysinfo
github.com/containers/common/pkg/timetype
github.com/containers/common/pkg/umask
+github.com/containers/common/pkg/util
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.17.1-0.20211207161909-6f3c8453e1a7
+# github.com/containers/image/v5 v5.17.1-0.20220106205022-73f80d60f0e1
## explicit
github.com/containers/image/v5/copy
github.com/containers/image/v5/directory
@@ -546,7 +547,7 @@ github.com/onsi/gomega/types
# github.com/opencontainers/go-digest v1.0.0
## explicit
github.com/opencontainers/go-digest
-# github.com/opencontainers/image-spec v1.0.2-0.20211123152302-43a7dee1ec31
+# github.com/opencontainers/image-spec v1.0.3-0.20211202193544-a5463b7f9c84
## explicit
github.com/opencontainers/image-spec/specs-go
github.com/opencontainers/image-spec/specs-go/v1
@@ -668,7 +669,7 @@ github.com/vbauerster/mpb/v6
github.com/vbauerster/mpb/v6/cwriter
github.com/vbauerster/mpb/v6/decor
github.com/vbauerster/mpb/v6/internal
-# github.com/vbauerster/mpb/v7 v7.2.0
+# github.com/vbauerster/mpb/v7 v7.3.0
github.com/vbauerster/mpb/v7
github.com/vbauerster/mpb/v7/cwriter
github.com/vbauerster/mpb/v7/decor
@@ -736,7 +737,7 @@ golang.org/x/net/trace
## explicit
golang.org/x/sync/errgroup
golang.org/x/sync/semaphore
-# golang.org/x/sys v0.0.0-20211205182925-97ca703d548d
+# golang.org/x/sys v0.0.0-20211214234402-4825e8c3871d
## explicit
golang.org/x/sys/cpu
golang.org/x/sys/execabs