diff options
-rw-r--r-- | cmd/podman/containers/restore.go | 8 | ||||
-rw-r--r-- | cmd/podman/root.go | 14 | ||||
-rw-r--r-- | go.mod | 2 | ||||
-rw-r--r-- | go.sum | 4 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/containers.go | 143 | ||||
-rw-r--r-- | pkg/bindings/containers/checkpoint.go | 49 | ||||
-rw-r--r-- | pkg/bindings/containers/types.go | 7 | ||||
-rw-r--r-- | pkg/bindings/containers/types_checkpoint_options.go | 15 | ||||
-rw-r--r-- | pkg/bindings/containers/types_restore_options.go | 45 | ||||
-rw-r--r-- | pkg/checkpoint/checkpoint_restore.go | 8 | ||||
-rw-r--r-- | pkg/domain/entities/containers.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 32 | ||||
-rw-r--r-- | test/e2e/checkpoint_test.go | 92 | ||||
-rw-r--r-- | utils/utils.go | 12 | ||||
-rw-r--r-- | utils/utils_supported.go | 9 | ||||
-rw-r--r-- | vendor/github.com/containers/common/libimage/manifests/manifests.go | 3 | ||||
-rw-r--r-- | vendor/github.com/containers/common/pkg/config/config.go | 33 | ||||
-rw-r--r-- | vendor/github.com/containers/common/pkg/parse/parse.go | 1 | ||||
-rw-r--r-- | vendor/modules.txt | 2 |
19 files changed, 319 insertions, 162 deletions
diff --git a/cmd/podman/containers/restore.go b/cmd/podman/containers/restore.go index 217adc887..4ac14001a 100644 --- a/cmd/podman/containers/restore.go +++ b/cmd/podman/containers/restore.go @@ -12,7 +12,6 @@ import ( "github.com/containers/podman/v3/cmd/podman/validate" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/rootless" - "github.com/containers/podman/v3/pkg/specgenutil" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -120,12 +119,7 @@ func restore(cmd *cobra.Command, args []string) error { if err != nil { return err } - if len(inputPorts) > 0 { - restoreOptions.PublishPorts, err = specgenutil.CreatePortBindings(inputPorts) - if err != nil { - return err - } - } + restoreOptions.PublishPorts = inputPorts argLen := len(args) if restoreOptions.Import != "" { diff --git a/cmd/podman/root.go b/cmd/podman/root.go index 418a70e1e..9e4c8d24d 100644 --- a/cmd/podman/root.go +++ b/cmd/podman/root.go @@ -163,20 +163,6 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { return err } - for _, env := range cfg.Engine.Env { - splitEnv := strings.SplitN(env, "=", 2) - if len(splitEnv) != 2 { - return fmt.Errorf("invalid environment variable for engine %s, valid configuration is KEY=value pair", env) - } - // skip if the env is already defined - if _, ok := os.LookupEnv(splitEnv[0]); ok { - logrus.Debugf("environment variable %s is already defined, skip the settings from containers.conf", splitEnv[0]) - continue - } - if err := os.Setenv(splitEnv[0], splitEnv[1]); err != nil { - return err - } - } // Hard code TMPDIR functions to use /var/tmp, if user did not override if _, ok := os.LookupEnv("TMPDIR"); !ok { if tmpdir, err := cfg.ImageCopyTmpDir(); err != nil { @@ -12,7 +12,7 @@ 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.20211110143743-73e7b462c358 + github.com/containers/common v0.46.1-0.20211115170340-7ae7bd1c3f8e github.com/containers/conmon v2.0.20+incompatible github.com/containers/image/v5 v5.16.1 github.com/containers/ocicrypt v1.1.2 @@ -258,8 +258,8 @@ 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.20211110143743-73e7b462c358 h1:dK2AgGBdWspdQNw28Wc4peY25QeyYV4H9ViQaFaQ9XQ= -github.com/containers/common v0.46.1-0.20211110143743-73e7b462c358/go.mod h1:bu8gizEkgAz6gXHvUw2cMtI5ErxB+fn/hv49RWk5N1A= +github.com/containers/common v0.46.1-0.20211115170340-7ae7bd1c3f8e h1:YSuo3zGivcgQhRV1TOJ6zW3VjyjoU7BJMRyh71v/Zdc= +github.com/containers/common v0.46.1-0.20211115170340-7ae7bd1c3f8e/go.mod h1:bu8gizEkgAz6gXHvUw2cMtI5ErxB+fn/hv49RWk5N1A= 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= diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go index 3aeebc334..b0cec2b1f 100644 --- a/pkg/api/handlers/libpod/containers.go +++ b/pkg/api/handlers/libpod/containers.go @@ -1,9 +1,11 @@ package libpod import ( + "fmt" "io/ioutil" "net/http" "os" + "strings" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" @@ -206,7 +208,9 @@ func ShowMountedContainers(w http.ResponseWriter, r *http.Request) { } func Checkpoint(w http.ResponseWriter, r *http.Request) { - var targetFile string + runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) + containerEngine := abi.ContainerEngine{Libpod: runtime} + decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) query := struct { Keep bool `schema:"keep"` @@ -224,66 +228,68 @@ func Checkpoint(w http.ResponseWriter, r *http.Request) { errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) return } + name := utils.GetName(r) - runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) - ctr, err := runtime.LookupContainer(name) - if err != nil { + if _, err := runtime.LookupContainer(name); err != nil { utils.ContainerNotFound(w, name, err) return } + names := []string{name} + + options := entities.CheckpointOptions{ + Keep: query.Keep, + LeaveRunning: query.LeaveRunning, + TCPEstablished: query.TCPEstablished, + IgnoreRootFS: query.IgnoreRootFS, + PrintStats: query.PrintStats, + } + if query.Export { - tmpFile, err := ioutil.TempFile("", "checkpoint") + f, err := ioutil.TempFile("", "checkpoint") if err != nil { utils.InternalServerError(w, err) return } - defer os.Remove(tmpFile.Name()) - if err := tmpFile.Close(); err != nil { + defer os.Remove(f.Name()) + if err := f.Close(); err != nil { utils.InternalServerError(w, err) return } - targetFile = tmpFile.Name() - } - options := libpod.ContainerCheckpointOptions{ - Keep: query.Keep, - KeepRunning: query.LeaveRunning, - TCPEstablished: query.TCPEstablished, - IgnoreRootfs: query.IgnoreRootFS, - PrintStats: query.PrintStats, - } - if query.Export { - options.TargetFile = targetFile + options.Export = f.Name() } - criuStatistics, runtimeCheckpointDuration, err := ctr.Checkpoint(r.Context(), options) + + reports, err := containerEngine.ContainerCheckpoint(r.Context(), names, options) if err != nil { utils.InternalServerError(w, err) return } - if query.Export { - f, err := os.Open(targetFile) - if err != nil { - utils.InternalServerError(w, err) + + if !query.Export { + if len(reports) != 1 { + utils.InternalServerError(w, fmt.Errorf("expected 1 restore report but got %d", len(reports))) return } - defer f.Close() - utils.WriteResponse(w, http.StatusOK, f) + if reports[0].Err != nil { + utils.InternalServerError(w, reports[0].Err) + return + } + utils.WriteResponse(w, http.StatusOK, reports[0]) + return + } + + f, err := os.Open(options.Export) + if err != nil { + utils.InternalServerError(w, err) return } - utils.WriteResponse( - w, - http.StatusOK, - entities.CheckpointReport{ - Id: ctr.ID(), - RuntimeDuration: runtimeCheckpointDuration, - CRIUStatistics: criuStatistics, - }, - ) + defer f.Close() + utils.WriteResponse(w, http.StatusOK, f) } func Restore(w http.ResponseWriter, r *http.Request) { - var ( - targetFile string - ) + runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) + containerEngine := abi.ContainerEngine{Libpod: runtime} + decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) query := struct { Keep bool `schema:"keep"` @@ -295,6 +301,7 @@ func Restore(w http.ResponseWriter, r *http.Request) { IgnoreStaticIP bool `schema:"ignoreStaticIP"` IgnoreStaticMAC bool `schema:"ignoreStaticMAC"` PrintStats bool `schema:"printStats"` + PublishPorts string `schema:"publishPorts"` }{ // override any golang type defaults } @@ -303,53 +310,55 @@ func Restore(w http.ResponseWriter, r *http.Request) { errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) return } - name := utils.GetName(r) - runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) - ctr, err := runtime.LookupContainer(name) - if err != nil { - utils.ContainerNotFound(w, name, err) - return + + options := entities.RestoreOptions{ + Name: query.Name, + Keep: query.Keep, + TCPEstablished: query.TCPEstablished, + IgnoreRootFS: query.IgnoreRootFS, + IgnoreVolumes: query.IgnoreVolumes, + IgnoreStaticIP: query.IgnoreStaticIP, + IgnoreStaticMAC: query.IgnoreStaticMAC, + PrintStats: query.PrintStats, + PublishPorts: strings.Fields(query.PublishPorts), } + + var names []string if query.Import { t, err := ioutil.TempFile("", "restore") if err != nil { utils.InternalServerError(w, err) return } - defer t.Close() + defer os.Remove(t.Name()) if err := compat.SaveFromBody(t, r); err != nil { utils.InternalServerError(w, err) return } - targetFile = t.Name() + options.Import = t.Name() + } else { + name := utils.GetName(r) + if _, err := runtime.LookupContainer(name); err != nil { + utils.ContainerNotFound(w, name, err) + return + } + names = []string{name} } - options := libpod.ContainerCheckpointOptions{ - Keep: query.Keep, - TCPEstablished: query.TCPEstablished, - IgnoreRootfs: query.IgnoreRootFS, - IgnoreStaticIP: query.IgnoreStaticIP, - IgnoreStaticMAC: query.IgnoreStaticMAC, - PrintStats: query.PrintStats, - } - if query.Import { - options.TargetFile = targetFile - options.Name = query.Name - } - criuStatistics, runtimeRestoreDuration, err := ctr.Restore(r.Context(), options) + reports, err := containerEngine.ContainerRestore(r.Context(), names, options) if err != nil { utils.InternalServerError(w, err) return } - utils.WriteResponse( - w, - http.StatusOK, - entities.RestoreReport{ - Id: ctr.ID(), - RuntimeDuration: runtimeRestoreDuration, - CRIUStatistics: criuStatistics, - }, - ) + if len(reports) != 1 { + utils.InternalServerError(w, fmt.Errorf("expected 1 restore report but got %d", len(reports))) + return + } + if reports[0].Err != nil { + utils.InternalServerError(w, reports[0].Err) + return + } + utils.WriteResponse(w, http.StatusOK, reports[0]) } func InitContainer(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/bindings/containers/checkpoint.go b/pkg/bindings/containers/checkpoint.go index 2ad2c6931..7b4ec093d 100644 --- a/pkg/bindings/containers/checkpoint.go +++ b/pkg/bindings/containers/checkpoint.go @@ -2,7 +2,9 @@ package containers import ( "context" + "io" "net/http" + "os" "github.com/containers/podman/v3/pkg/bindings" "github.com/containers/podman/v3/pkg/domain/entities" @@ -23,13 +25,34 @@ func Checkpoint(ctx context.Context, nameOrID string, options *CheckpointOptions if err != nil { return nil, err } + + // "export" is a bool for the server so override it in the parameters + // if set. + export := false + if options.Export != nil && *options.Export != "" { + export = true + params.Set("export", "true") + } response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/checkpoint", params, nil, nameOrID) if err != nil { return nil, err } defer response.Body.Close() - return &report, response.Process(&report) + if !export { + return &report, response.Process(&report) + } + + f, err := os.OpenFile(*options.Export, os.O_RDWR|os.O_CREATE, 0600) + if err != nil { + return nil, err + } + defer f.Close() + if _, err := io.Copy(f, response.Body); err != nil { + return nil, err + } + + return &entities.CheckpointReport{}, nil } // Restore restores a checkpointed container to running. The container is identified by the nameOrID option. All @@ -47,12 +70,26 @@ func Restore(ctx context.Context, nameOrID string, options *RestoreOptions) (*en if err != nil { return nil, err } - // The import key is a reserved golang term - params.Del("ImportArchive") - if i := options.GetImportAchive(); options.Changed("ImportArchive") { - params.Set("import", i) + + for _, p := range options.PublishPorts { + params.Add("publishPorts", p) + } + + params.Del("ImportArchive") // The import key is a reserved golang term + + // Open the to-be-imported archive if needed. + var r io.Reader + if i := options.GetImportAchive(); i != "" { + params.Set("import", "true") + r, err = os.Open(i) + if err != nil { + return nil, err + } + // Hard-code the name since it will be ignored in any case. + nameOrID = "import" } - response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/restore", params, nil, nameOrID) + + response, err := conn.DoRequest(ctx, r, http.MethodPost, "/containers/%s/restore", params, nil, nameOrID) if err != nil { return nil, err } diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go index 3a7d5a4c7..4bbb4a62b 100644 --- a/pkg/bindings/containers/types.go +++ b/pkg/bindings/containers/types.go @@ -50,12 +50,14 @@ type CheckpointOptions struct { Keep *bool LeaveRunning *bool TCPEstablished *bool + PrintStats *bool } //go:generate go run ../generator/generator.go RestoreOptions // RestoreOptions are optional options for restoring containers type RestoreOptions struct { IgnoreRootfs *bool + IgnoreVolumes *bool IgnoreStaticIP *bool IgnoreStaticMAC *bool ImportAchive *string @@ -63,6 +65,8 @@ type RestoreOptions struct { Name *string TCPEstablished *bool Pod *string + PrintStats *bool + PublishPorts []string } //go:generate go run ../generator/generator.go CreateOptions @@ -86,7 +90,8 @@ type ExecInspectOptions struct{} //go:generate go run ../generator/generator.go ExecStartOptions // ExecStartOptions are optional options for starting // exec sessions -type ExecStartOptions struct{} +type ExecStartOptions struct { +} //go:generate go run ../generator/generator.go HealthCheckOptions // HealthCheckOptions are optional options for checking diff --git a/pkg/bindings/containers/types_checkpoint_options.go b/pkg/bindings/containers/types_checkpoint_options.go index 7b28c4045..b606922e0 100644 --- a/pkg/bindings/containers/types_checkpoint_options.go +++ b/pkg/bindings/containers/types_checkpoint_options.go @@ -91,3 +91,18 @@ func (o *CheckpointOptions) GetTCPEstablished() bool { } return *o.TCPEstablished } + +// WithPrintStats set field PrintStats to given value +func (o *CheckpointOptions) WithPrintStats(value bool) *CheckpointOptions { + o.PrintStats = &value + return o +} + +// GetPrintStats returns value of field PrintStats +func (o *CheckpointOptions) GetPrintStats() bool { + if o.PrintStats == nil { + var z bool + return z + } + return *o.PrintStats +} diff --git a/pkg/bindings/containers/types_restore_options.go b/pkg/bindings/containers/types_restore_options.go index 6eea108f4..8817b834b 100644 --- a/pkg/bindings/containers/types_restore_options.go +++ b/pkg/bindings/containers/types_restore_options.go @@ -32,6 +32,21 @@ func (o *RestoreOptions) GetIgnoreRootfs() bool { return *o.IgnoreRootfs } +// WithIgnoreVolumes set field IgnoreVolumes to given value +func (o *RestoreOptions) WithIgnoreVolumes(value bool) *RestoreOptions { + o.IgnoreVolumes = &value + return o +} + +// GetIgnoreVolumes returns value of field IgnoreVolumes +func (o *RestoreOptions) GetIgnoreVolumes() bool { + if o.IgnoreVolumes == nil { + var z bool + return z + } + return *o.IgnoreVolumes +} + // WithIgnoreStaticIP set field IgnoreStaticIP to given value func (o *RestoreOptions) WithIgnoreStaticIP(value bool) *RestoreOptions { o.IgnoreStaticIP = &value @@ -136,3 +151,33 @@ func (o *RestoreOptions) GetPod() string { } return *o.Pod } + +// WithPrintStats set field PrintStats to given value +func (o *RestoreOptions) WithPrintStats(value bool) *RestoreOptions { + o.PrintStats = &value + return o +} + +// GetPrintStats returns value of field PrintStats +func (o *RestoreOptions) GetPrintStats() bool { + if o.PrintStats == nil { + var z bool + return z + } + return *o.PrintStats +} + +// WithPublishPorts set field PublishPorts to given value +func (o *RestoreOptions) WithPublishPorts(value []string) *RestoreOptions { + o.PublishPorts = value + return o +} + +// GetPublishPorts returns value of field PublishPorts +func (o *RestoreOptions) GetPublishPorts() []string { + if o.PublishPorts == nil { + var z []string + return z + } + return o.PublishPorts +} diff --git a/pkg/checkpoint/checkpoint_restore.go b/pkg/checkpoint/checkpoint_restore.go index da82c9745..3a300daaf 100644 --- a/pkg/checkpoint/checkpoint_restore.go +++ b/pkg/checkpoint/checkpoint_restore.go @@ -16,6 +16,7 @@ import ( "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/errorhandling" "github.com/containers/podman/v3/pkg/specgen/generate" + "github.com/containers/podman/v3/pkg/specgenutil" "github.com/containers/storage/pkg/archive" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -195,7 +196,12 @@ func CRImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, restoreOpt } if len(restoreOptions.PublishPorts) > 0 { - ports, err := generate.ParsePortMapping(restoreOptions.PublishPorts, nil) + pubPorts, err := specgenutil.CreatePortBindings(restoreOptions.PublishPorts) + if err != nil { + return nil, err + } + + ports, err := generate.ParsePortMapping(pubPorts, nil) if err != nil { return nil, err } diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index 8b7cd62d9..1a4019bb1 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -212,7 +212,7 @@ type RestoreOptions struct { Name string TCPEstablished bool ImportPrevious string - PublishPorts []nettypes.PortMapping + PublishPorts []string Pod string PrintStats bool } diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 5b5a1912c..152e3c302 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -302,6 +302,14 @@ func (ic *ContainerEngine) ContainerExport(ctx context.Context, nameOrID string, } func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds []string, opts entities.CheckpointOptions) ([]*entities.CheckpointReport, error) { + options := new(containers.CheckpointOptions) + options.WithIgnoreRootfs(opts.IgnoreRootFS) + options.WithKeep(opts.Keep) + options.WithExport(opts.Export) + options.WithTCPEstablished(opts.TCPEstablished) + options.WithPrintStats(opts.PrintStats) + options.WithLeaveRunning(opts.LeaveRunning) + var ( err error ctrs = []entities.ListContainer{} @@ -325,19 +333,36 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [ } } reports := make([]*entities.CheckpointReport, 0, len(ctrs)) - options := new(containers.CheckpointOptions).WithExport(opts.Export).WithIgnoreRootfs(opts.IgnoreRootFS).WithKeep(opts.Keep) - options.WithLeaveRunning(opts.LeaveRunning).WithTCPEstablished(opts.TCPEstablished) for _, c := range ctrs { report, err := containers.Checkpoint(ic.ClientCtx, c.ID, options) if err != nil { reports = append(reports, &entities.CheckpointReport{Id: c.ID, Err: err}) + } else { + reports = append(reports, report) } - reports = append(reports, report) } return reports, nil } func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []string, opts entities.RestoreOptions) ([]*entities.RestoreReport, error) { + options := new(containers.RestoreOptions) + options.WithIgnoreRootfs(opts.IgnoreRootFS) + options.WithIgnoreVolumes(opts.IgnoreVolumes) + options.WithIgnoreStaticIP(opts.IgnoreStaticIP) + options.WithIgnoreStaticMAC(opts.IgnoreStaticMAC) + options.WithKeep(opts.Keep) + options.WithName(opts.Name) + options.WithTCPEstablished(opts.TCPEstablished) + options.WithPod(opts.Pod) + options.WithPrintStats(opts.PrintStats) + options.WithPublishPorts(opts.PublishPorts) + + if opts.Import != "" { + options.WithImportAchive(opts.Import) + report, err := containers.Restore(ic.ClientCtx, "", options) + return []*entities.RestoreReport{report}, err + } + var ( err error ctrs = []entities.ListContainer{} @@ -360,7 +385,6 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st } } reports := make([]*entities.RestoreReport, 0, len(ctrs)) - options := new(containers.RestoreOptions) for _, c := range ctrs { report, err := containers.Restore(ic.ClientCtx, c.ID, options) if err != nil { diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index 6b294802d..37935fd38 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -35,7 +35,6 @@ var _ = Describe("Podman checkpoint", func() { ) BeforeEach(func() { - SkipIfRemote("checkpoint not supported in remote mode") SkipIfRootless("checkpoint not supported in rootless mode") tempdir, err = CreateTempDirInTempDir() if err != nil { @@ -183,7 +182,7 @@ var _ = Describe("Podman checkpoint", func() { session2.WaitWithDefaultTimeout() Expect(session2).Should(Exit(0)) - result := podmanTest.Podman([]string{"container", "checkpoint", "-l"}) + result := podmanTest.Podman([]string{"container", "checkpoint", "second"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) @@ -195,7 +194,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(ps.LineInOutputContains(session1.OutputToString())).To(BeTrue()) Expect(ps.LineInOutputContains(session2.OutputToString())).To(BeFalse()) - result = podmanTest.Podman([]string{"container", "restore", "-l"}) + result = podmanTest.Podman([]string{"container", "restore", "second"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) @@ -258,7 +257,7 @@ var _ = Describe("Podman checkpoint", func() { Fail("Container failed to get ready") } - IP := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.IPAddress}}"}) + IP := podmanTest.Podman([]string{"inspect", cid, "--format={{.NetworkSettings.IPAddress}}"}) IP.WaitWithDefaultTimeout() Expect(IP).Should(Exit(0)) @@ -267,7 +266,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(err).To(BeNil()) // This should fail as the container has established TCP connections - result := podmanTest.Podman([]string{"container", "checkpoint", "-l"}) + result := podmanTest.Podman([]string{"container", "checkpoint", cid}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(125)) @@ -275,7 +274,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) // Now it should work thanks to "--tcp-established" - result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "--tcp-established"}) + result = podmanTest.Podman([]string{"container", "checkpoint", cid, "--tcp-established"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) @@ -283,7 +282,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) // Restore should fail as the checkpoint image contains established TCP connections - result = podmanTest.Podman([]string{"container", "restore", "-l"}) + result = podmanTest.Podman([]string{"container", "restore", cid}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(125)) @@ -291,7 +290,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) // Now it should work thanks to "--tcp-established" - result = podmanTest.Podman([]string{"container", "restore", "-l", "--tcp-established"}) + result = podmanTest.Podman([]string{"container", "restore", cid, "--tcp-established"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) @@ -350,11 +349,11 @@ var _ = Describe("Podman checkpoint", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - IPBefore := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.IPAddress}}"}) + IPBefore := podmanTest.Podman([]string{"inspect", "test_name", "--format={{.NetworkSettings.IPAddress}}"}) IPBefore.WaitWithDefaultTimeout() Expect(IPBefore).Should(Exit(0)) - MACBefore := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.MacAddress}}"}) + MACBefore := podmanTest.Podman([]string{"inspect", "test_name", "--format={{.NetworkSettings.MacAddress}}"}) MACBefore.WaitWithDefaultTimeout() Expect(MACBefore).Should(Exit(0)) @@ -368,11 +367,11 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "restore", "test_name"}) result.WaitWithDefaultTimeout() - IPAfter := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.IPAddress}}"}) + IPAfter := podmanTest.Podman([]string{"inspect", "test_name", "--format={{.NetworkSettings.IPAddress}}"}) IPAfter.WaitWithDefaultTimeout() Expect(IPAfter).Should(Exit(0)) - MACAfter := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.MacAddress}}"}) + MACAfter := podmanTest.Podman([]string{"inspect", "test_name", "--format={{.NetworkSettings.MacAddress}}"}) MACAfter.WaitWithDefaultTimeout() Expect(MACAfter).Should(Exit(0)) @@ -403,7 +402,7 @@ var _ = Describe("Podman checkpoint", func() { cid := session.OutputToString() fileName := "/tmp/checkpoint-" + cid + ".tar.gz" - result := podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) + result := podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) result.WaitWithDefaultTimeout() // As the container has been started with '--rm' it will be completely @@ -455,7 +454,7 @@ var _ = Describe("Podman checkpoint", func() { fileName := "/tmp/checkpoint-" + cid + ".tar" // Checkpoint with the default algorithm - result := podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) + result := podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) result.WaitWithDefaultTimeout() // As the container has been started with '--rm' it will be completely @@ -473,7 +472,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) // Checkpoint with the zstd algorithm - result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName, "--compress", "zstd"}) + result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName, "--compress", "zstd"}) result.WaitWithDefaultTimeout() // As the container has been started with '--rm' it will be completely @@ -491,7 +490,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) // Checkpoint with the none algorithm - result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName, "-c", "none"}) + result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName, "-c", "none"}) result.WaitWithDefaultTimeout() // As the container has been started with '--rm' it will be completely @@ -509,7 +508,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) // Checkpoint with the gzip algorithm - result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName, "-c", "gzip"}) + result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName, "-c", "gzip"}) result.WaitWithDefaultTimeout() // As the container has been started with '--rm' it will be completely @@ -527,7 +526,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) // Checkpoint with the non-existing algorithm - result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName, "-c", "non-existing"}) + result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName, "-c", "non-existing"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(125)) @@ -555,15 +554,15 @@ var _ = Describe("Podman checkpoint", func() { fileName := "/tmp/checkpoint-" + cid + ".tar.gz" // Change the container's root file-system - result := podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) + result := podmanTest.Podman([]string{"exec", cid, "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) - result = podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "rm /etc/motd"}) + result = podmanTest.Podman([]string{"exec", cid, "/bin/sh", "-c", "rm /etc/motd"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) - result = podmanTest.Podman([]string{"diff", "-l"}) + result = podmanTest.Podman([]string{"diff", cid}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring("C /etc")) @@ -572,7 +571,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(len(result.OutputToStringArray())).To(Equal(3)) // Checkpoint the container - result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) + result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) @@ -589,12 +588,12 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) // Verify the changes to the container's root file-system - result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) + result = podmanTest.Podman([]string{"exec", cid, "cat", "/test.output"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring("test" + cid + "test")) - result = podmanTest.Podman([]string{"diff", "-l"}) + result = podmanTest.Podman([]string{"diff", cid}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring("C /etc")) @@ -616,12 +615,12 @@ var _ = Describe("Podman checkpoint", func() { fileName := "/tmp/checkpoint-" + cid + ".tar.gz" // Change the container's root file-system - result := podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) + result := podmanTest.Podman([]string{"exec", cid, "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) // Checkpoint the container - result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) + result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) @@ -638,7 +637,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) // Verify the changes to the container's root file-system - result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) + result = podmanTest.Podman([]string{"exec", cid, "cat", "/test.output"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(1)) Expect(result.ErrorToString()).To(ContainSubstring("cat: can't open '/test.output': No such file or directory")) @@ -657,12 +656,12 @@ var _ = Describe("Podman checkpoint", func() { fileName := "/tmp/checkpoint-" + cid + ".tar.gz" // Change the container's root file-system - result := podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) + result := podmanTest.Podman([]string{"exec", cid, "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) // Checkpoint the container - result = podmanTest.Podman([]string{"container", "checkpoint", "--ignore-rootfs", "-l", "-e", fileName}) + result = podmanTest.Podman([]string{"container", "checkpoint", "--ignore-rootfs", cid, "-e", fileName}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) @@ -679,7 +678,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) // Verify the changes to the container's root file-system - result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) + result = podmanTest.Podman([]string{"exec", cid, "cat", "/test.output"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(1)) Expect(result.ErrorToString()).To(ContainSubstring("cat: can't open '/test.output': No such file or directory")) @@ -699,7 +698,7 @@ var _ = Describe("Podman checkpoint", func() { fileName := "/tmp/checkpoint-" + cid + ".tar.gz" // Checkpoint the container - result := podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) + result := podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) @@ -716,11 +715,11 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) // Exec in the container - result = podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo " + cid + " > /test.output"}) + result = podmanTest.Podman([]string{"exec", cid, "/bin/sh", "-c", "echo " + cid + " > /test.output"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) - result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) + result = podmanTest.Podman([]string{"exec", cid, "cat", "/test.output"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(cid)) @@ -738,7 +737,7 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) // Checkpoint the container - this should fail as it was started with --rm - result := podmanTest.Podman([]string{"container", "checkpoint", "-l"}) + result := podmanTest.Podman([]string{"container", "checkpoint", cid}) result.WaitWithDefaultTimeout() Expect(result).To(ExitWithError()) Expect(result.ErrorToString()).To(ContainSubstring("cannot checkpoint containers that have been started with '--rm'")) @@ -746,7 +745,7 @@ var _ = Describe("Podman checkpoint", func() { // Checkpointing with --export should still work fileName := "/tmp/checkpoint-" + cid + ".tar.gz" - result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) + result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) result.WaitWithDefaultTimeout() // As the container has been started with '--rm' it will be completely @@ -796,21 +795,21 @@ var _ = Describe("Podman checkpoint", func() { // Add file in volume0 result := podmanTest.Podman([]string{ - "exec", "-l", "/bin/sh", "-c", "echo " + cid + " > /volume0/test.output", + "exec", cid, "/bin/sh", "-c", "echo " + cid + " > /volume0/test.output", }) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) // Add file in volume1 result = podmanTest.Podman([]string{ - "exec", "-l", "/bin/sh", "-c", "echo " + cid + " > /volume1/test.output", + "exec", cid, "/bin/sh", "-c", "echo " + cid + " > /volume1/test.output", }) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) // Add file in volume2 result = podmanTest.Podman([]string{ - "exec", "-l", "/bin/sh", "-c", "echo " + cid + " > /volume2/test.output", + "exec", cid, "/bin/sh", "-c", "echo " + cid + " > /volume2/test.output", }) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) @@ -818,7 +817,7 @@ var _ = Describe("Podman checkpoint", func() { checkpointFileName := "/tmp/checkpoint-" + cid + ".tar.gz" // Checkpoint the container - result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", checkpointFileName}) + result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", checkpointFileName}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) @@ -846,19 +845,19 @@ var _ = Describe("Podman checkpoint", func() { Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) // Validate volume0 content - result = podmanTest.Podman([]string{"exec", "-l", "cat", "/volume0/test.output"}) + result = podmanTest.Podman([]string{"exec", cid, "cat", "/volume0/test.output"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(cid)) // Validate volume1 content - result = podmanTest.Podman([]string{"exec", "-l", "cat", "/volume1/test.output"}) + result = podmanTest.Podman([]string{"exec", cid, "cat", "/volume1/test.output"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(cid)) // Validate volume2 content - result = podmanTest.Podman([]string{"exec", "-l", "cat", "/volume2/test.output"}) + result = podmanTest.Podman([]string{"exec", cid, "cat", "/volume2/test.output"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) Expect(result.OutputToString()).To(ContainSubstring(cid)) @@ -962,7 +961,7 @@ var _ = Describe("Podman checkpoint", func() { conn.Close() // Checkpoint the container - result := podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) + result := podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) result.WaitWithDefaultTimeout() // As the container has been started with '--rm' it will be completely @@ -984,6 +983,7 @@ var _ = Describe("Podman checkpoint", func() { // Open a network connection to the redis server via initial port mapping // This should fail conn, err = net.DialTimeout("tcp4", fmt.Sprintf("localhost:%d", randomPort), time.Duration(3)*time.Second) + Expect(err).ToNot(BeNil()) Expect(err.Error()).To(ContainSubstring("connection refused")) // Open a network connection to the redis server via new port mapping fmt.Fprintf(os.Stderr, "Trying to reconnect to redis server at localhost:%d", newRandomPort) @@ -1023,7 +1023,7 @@ var _ = Describe("Podman checkpoint", func() { Skip("CRIU is missing or too old.") } if !crutils.CRRuntimeSupportsPodCheckpointRestore(podmanTest.OCIRuntime) { - Skip("runtime does not support pod restore") + Skip("runtime does not support pod restore: " + podmanTest.OCIRuntime) } // Create a pod session := podmanTest.Podman([]string{ @@ -1170,7 +1170,7 @@ var _ = Describe("Podman checkpoint", func() { cid := session.OutputToString() fileName := "/tmp/checkpoint-" + cid + ".tar.gz" - result := podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) + result := podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) result.WaitWithDefaultTimeout() // As the container has been started with '--rm' it will be completely @@ -1212,7 +1212,7 @@ var _ = Describe("Podman checkpoint", func() { result := podmanTest.Podman([]string{ "container", "checkpoint", - "-l", "-e", + cid, "-e", fileName, }) result.WaitWithDefaultTimeout() diff --git a/utils/utils.go b/utils/utils.go index 109ae088b..f2e7beef9 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "io/ioutil" + "math/rand" "os" "os/exec" "strconv" @@ -203,7 +204,16 @@ func moveProcessToScope(pidPath, slice, scope string) error { // MovePauseProcessToScope moves the pause process used for rootless mode to keep the namespaces alive to // a separate scope. func MovePauseProcessToScope(pausePidPath string) { - err := moveProcessToScope(pausePidPath, "user.slice", "podman-pause.scope") + var err error + + for i := 0; i < 3; i++ { + r := rand.Int() + err = moveProcessToScope(pausePidPath, "user.slice", fmt.Sprintf("podman-pause-%d.scope", r)) + if err == nil { + return + } + } + if err != nil { unified, err2 := cgroups.IsCgroup2UnifiedMode() if err2 != nil { diff --git a/utils/utils_supported.go b/utils/utils_supported.go index 1404e3194..0f0c9a9ba 100644 --- a/utils/utils_supported.go +++ b/utils/utils_supported.go @@ -44,15 +44,6 @@ func RunUnderSystemdScope(pid int, slice string, unitName string) error { ch := make(chan string) _, err = conn.StartTransientUnit(unitName, "replace", properties, ch) if err != nil { - // On errors check if the cgroup already exists, if it does move the process there - if props, err := conn.GetUnitTypeProperties(unitName, "Scope"); err == nil { - if cgroup, ok := props["ControlGroup"].(string); ok && cgroup != "" { - if err := moveUnderCgroup(cgroup, "", []uint32{uint32(pid)}); err == nil { - return nil - } - // On errors return the original error message we got from StartTransientUnit. - } - } return err } diff --git a/vendor/github.com/containers/common/libimage/manifests/manifests.go b/vendor/github.com/containers/common/libimage/manifests/manifests.go index 8d1abfba9..45223cc2f 100644 --- a/vendor/github.com/containers/common/libimage/manifests/manifests.go +++ b/vendor/github.com/containers/common/libimage/manifests/manifests.go @@ -353,9 +353,12 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag } if instanceInfo.OS == "" { instanceInfo.OS = config.OS + instanceInfo.OSVersion = config.OSVersion + instanceInfo.OSFeatures = config.OSFeatures } if instanceInfo.Architecture == "" { instanceInfo.Architecture = config.Architecture + instanceInfo.Variant = config.Variant } } manifestBytes, manifestType, err := src.GetManifest(ctx, instanceInfo.instanceDigest) diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go index 2eda0290a..1a5370a39 100644 --- a/vendor/github.com/containers/common/pkg/config/config.go +++ b/vendor/github.com/containers/common/pkg/config/config.go @@ -563,6 +563,10 @@ func NewConfig(userConfigPath string) (*Config, error) { return nil, err } + if err := config.setupEnv(); err != nil { + return nil, err + } + return config, nil } @@ -1146,7 +1150,14 @@ func (c *Config) ActiveDestination() (uri, identity string, err error) { // FindHelperBinary will search the given binary name in the configured directories. // If searchPATH is set to true it will also search in $PATH. func (c *Config) FindHelperBinary(name string, searchPATH bool) (string, error) { - for _, path := range c.Engine.HelperBinariesDir { + dir_list := c.Engine.HelperBinariesDir + + // If set, search this directory first. This is used in testing. + if dir, found := os.LookupEnv("CONTAINERS_HELPER_BINARY_DIR"); found { + dir_list = append([]string{dir}, dir_list...) + } + + for _, path := range dir_list { fullpath := filepath.Join(path, name) if fi, err := os.Stat(fullpath); err == nil && fi.Mode().IsRegular() { return fullpath, nil @@ -1180,3 +1191,23 @@ func (c *Config) ImageCopyTmpDir() (string, error) { return "", errors.Errorf("invalid image_copy_tmp_dir value %q (relative paths are not accepted)", c.Engine.ImageCopyTmpDir) } + +// setupEnv sets the environment variables for the engine +func (c *Config) setupEnv() error { + for _, env := range c.Engine.Env { + splitEnv := strings.SplitN(env, "=", 2) + if len(splitEnv) != 2 { + logrus.Warnf("invalid environment variable for engine %s, valid configuration is KEY=value pair", env) + continue + } + // skip if the env is already defined + if _, ok := os.LookupEnv(splitEnv[0]); ok { + logrus.Debugf("environment variable %s is already defined, skip the settings from containers.conf", splitEnv[0]) + continue + } + if err := os.Setenv(splitEnv[0], splitEnv[1]); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/containers/common/pkg/parse/parse.go b/vendor/github.com/containers/common/pkg/parse/parse.go index 02e670c50..fda129c83 100644 --- a/vendor/github.com/containers/common/pkg/parse/parse.go +++ b/vendor/github.com/containers/common/pkg/parse/parse.go @@ -66,6 +66,7 @@ func ValidateVolumeOpts(options []string) ([]string, error) { // are intended to be always safe to use, even not on OS // X). continue + case "idmap": default: return nil, errors.Errorf("invalid option type %q", opt) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 9b6bd34bf..916cf41ae 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -97,7 +97,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.20211110143743-73e7b462c358 +# github.com/containers/common v0.46.1-0.20211115170340-7ae7bd1c3f8e github.com/containers/common/libimage github.com/containers/common/libimage/manifests github.com/containers/common/pkg/apparmor |