diff options
24 files changed, 401 insertions, 126 deletions
@@ -17,7 +17,7 @@ require ( github.com/containers/image/v5 v5.17.1-0.20211207161909-6f3c8453e1a7 github.com/containers/ocicrypt v1.1.2 github.com/containers/psgo v1.7.1 - github.com/containers/storage v1.37.1-0.20211130181259-1a158c89a518 + github.com/containers/storage v1.37.1-0.20211213220314-73a749e4fec5 github.com/coreos/go-systemd/v22 v22.3.2 github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3 github.com/cyphar/filepath-securejoin v0.2.3 @@ -308,8 +308,8 @@ github.com/containers/storage v1.35.0/go.mod h1:qzYhasQP2/V9D9XdO+vRwkHBhsBO0ozn github.com/containers/storage v1.36.0/go.mod h1:vbd3SKVQNHdmU5qQI6hTEcKPxnZkGqydG4f6uwrI5a8= github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4= github.com/containers/storage v1.37.1-0.20211119174841-bf170b3ddac0/go.mod h1:XjCNlt5JUUmRuTJXhFxHb9hHGPho7DNg3o4N/14prdQ= -github.com/containers/storage v1.37.1-0.20211130181259-1a158c89a518 h1:p44O35V8XCefRxOxU1aY6eT9XNMxkWA1drtJpsl211c= -github.com/containers/storage v1.37.1-0.20211130181259-1a158c89a518/go.mod h1:T5DX08T/eKKRs0WGDhC/ztngMSth6YuHq15eF8C/Y5A= +github.com/containers/storage v1.37.1-0.20211213220314-73a749e4fec5 h1:DOpYQGCHIJfrErey3FyondnZGfZrbfGpHAN6nQssE1o= +github.com/containers/storage v1.37.1-0.20211213220314-73a749e4fec5/go.mod h1:5qRpx96WJRTCQCsArfrWjUh398JSNCaTJG6RbOhMlqY= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= diff --git a/hack/libsubid_tag.sh b/hack/libsubid_tag.sh index ab6af9e30..31412b3e6 100755 --- a/hack/libsubid_tag.sh +++ b/hack/libsubid_tag.sh @@ -7,9 +7,19 @@ mkdir -p "$tmpdir" trap 'rm -fr "$tmpdir"' EXIT cc -o "$tmpdir"/libsubid_tag -l subid -x c - > /dev/null 2> /dev/null << EOF #include <shadow/subid.h> +#include <stdio.h> +#include <stdlib.h> + +const char *Prog = "test"; +FILE *shadow_logfd = NULL; + int main() { struct subid_range *ranges = NULL; +#if SUBID_ABI_MAJOR >= 4 + subid_get_uid_ranges("root", &ranges); +#else get_subuid_ranges("root", &ranges); +#endif free(ranges); return 0; } diff --git a/libpod/container.go b/libpod/container.go index 1270f2112..c746f97c7 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -213,6 +213,15 @@ type ContainerState struct { // containerPlatformState holds platform-specific container state. containerPlatformState + + // Following checkpoint/restore related information is displayed + // if the container has been checkpointed or restored. + CheckpointedTime time.Time `json:"checkpointedTime,omitempty"` + RestoredTime time.Time `json:"restoredTime,omitempty"` + CheckpointLog string `json:"checkpointLog,omitempty"` + CheckpointPath string `json:"checkpointPath,omitempty"` + RestoreLog string `json:"restoreLog,omitempty"` + Restored bool `json:"restored,omitempty"` } // ContainerNamedVolume is a named volume that will be mounted into the diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 83b643266..439328ea8 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -113,20 +113,26 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver Path: path, Args: args, State: &define.InspectContainerState{ - OciVersion: ctrSpec.Version, - Status: runtimeInfo.State.String(), - Running: runtimeInfo.State == define.ContainerStateRunning, - Paused: runtimeInfo.State == define.ContainerStatePaused, - OOMKilled: runtimeInfo.OOMKilled, - Dead: runtimeInfo.State.String() == "bad state", - Pid: runtimeInfo.PID, - ConmonPid: runtimeInfo.ConmonPID, - ExitCode: runtimeInfo.ExitCode, - Error: "", // can't get yet - StartedAt: runtimeInfo.StartedTime, - FinishedAt: runtimeInfo.FinishedTime, - Checkpointed: runtimeInfo.Checkpointed, - CgroupPath: cgroupPath, + OciVersion: ctrSpec.Version, + Status: runtimeInfo.State.String(), + Running: runtimeInfo.State == define.ContainerStateRunning, + Paused: runtimeInfo.State == define.ContainerStatePaused, + OOMKilled: runtimeInfo.OOMKilled, + Dead: runtimeInfo.State.String() == "bad state", + Pid: runtimeInfo.PID, + ConmonPid: runtimeInfo.ConmonPID, + ExitCode: runtimeInfo.ExitCode, + Error: "", // can't get yet + StartedAt: runtimeInfo.StartedTime, + FinishedAt: runtimeInfo.FinishedTime, + Checkpointed: runtimeInfo.Checkpointed, + CgroupPath: cgroupPath, + RestoredAt: runtimeInfo.RestoredTime, + CheckpointedAt: runtimeInfo.CheckpointedTime, + Restored: runtimeInfo.Restored, + CheckpointPath: runtimeInfo.CheckpointPath, + CheckpointLog: runtimeInfo.CheckpointLog, + RestoreLog: runtimeInfo.RestoreLog, }, Image: config.RootfsImageID, ImageName: config.RootfsImageName, diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 7df82eb18..7ae9daefa 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -634,6 +634,12 @@ func resetState(state *ContainerState) { state.RestartPolicyMatch = false state.RestartCount = 0 state.Checkpointed = false + state.Restored = false + state.CheckpointedTime = time.Time{} + state.RestoredTime = time.Time{} + state.CheckpointPath = "" + state.CheckpointLog = "" + state.RestoreLog = "" } // Refresh refreshes the container's state after a restart. @@ -1111,6 +1117,12 @@ func (c *Container) init(ctx context.Context, retainRetries bool) error { } c.state.Checkpointed = false + c.state.Restored = false + c.state.CheckpointedTime = time.Time{} + c.state.RestoredTime = time.Time{} + c.state.CheckpointPath = "" + c.state.CheckpointLog = "" + c.state.RestoreLog = "" c.state.ExitCode = 0 c.state.Exited = false c.state.State = define.ContainerStateCreated diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index f4b629a83..9e6ae9f02 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -1134,6 +1134,10 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO return nil, 0, err } + // Setting CheckpointLog early in case there is a failure. + c.state.CheckpointLog = path.Join(c.bundlePath(), "dump.log") + c.state.CheckpointPath = c.CheckpointPath() + runtimeCheckpointDuration, err := c.ociRuntime.CheckpointContainer(c, options) if err != nil { return nil, 0, err @@ -1169,6 +1173,9 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO if !options.KeepRunning && !options.PreCheckPoint { c.state.State = define.ContainerStateStopped c.state.Checkpointed = true + c.state.CheckpointedTime = time.Now() + c.state.Restored = false + c.state.RestoredTime = time.Time{} // Cleanup Storage and Network if err := c.cleanup(ctx); err != nil { @@ -1216,6 +1223,8 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO logrus.Debugf("Unable to remove file %s", file) } } + // The file has been deleted. Do not mention it. + c.state.CheckpointLog = "" } c.state.FinishedTime = time.Now() @@ -1293,6 +1302,10 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti return nil, 0, err } + // Setting RestoreLog early in case there is a failure. + c.state.RestoreLog = path.Join(c.bundlePath(), "restore.log") + c.state.CheckpointPath = c.CheckpointPath() + // Read network configuration from checkpoint var netStatus map[string]types.StatusBlock _, err := metadata.ReadJSONFile(&netStatus, c.bundlePath(), metadata.NetworkStatusFile) @@ -1559,6 +1572,9 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti c.state.State = define.ContainerStateRunning c.state.Checkpointed = false + c.state.Restored = true + c.state.CheckpointedTime = time.Time{} + c.state.RestoredTime = time.Now() if !options.Keep { // Delete all checkpoint related files. At this point, in theory, all files @@ -1569,6 +1585,7 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti if err != nil { logrus.Debugf("Non-fatal: removal of checkpoint directory (%s) failed: %v", c.CheckpointPath(), err) } + c.state.CheckpointPath = "" err = os.RemoveAll(c.PreCheckPointPath()) if err != nil { logrus.Debugf("Non-fatal: removal of pre-checkpoint directory (%s) failed: %v", c.PreCheckPointPath(), err) @@ -1589,6 +1606,8 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti logrus.Debugf("Non-fatal: removal of checkpoint file (%s) failed: %v", file, err) } } + c.state.CheckpointLog = "" + c.state.RestoreLog = "" } return criuStatistics, runtimeRestoreDuration, c.save() diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go index 677b39218..a4d9bcf4f 100644 --- a/libpod/define/container_inspect.go +++ b/libpod/define/container_inspect.go @@ -189,22 +189,28 @@ type InspectMount struct { // Docker, but here we see more fields that are unused (nonsensical in the // context of Libpod). type InspectContainerState struct { - OciVersion string `json:"OciVersion"` - Status string `json:"Status"` - Running bool `json:"Running"` - Paused bool `json:"Paused"` - Restarting bool `json:"Restarting"` // TODO - OOMKilled bool `json:"OOMKilled"` - Dead bool `json:"Dead"` - Pid int `json:"Pid"` - ConmonPid int `json:"ConmonPid,omitempty"` - ExitCode int32 `json:"ExitCode"` - Error string `json:"Error"` // TODO - StartedAt time.Time `json:"StartedAt"` - FinishedAt time.Time `json:"FinishedAt"` - Health HealthCheckResults `json:"Health,omitempty"` - Checkpointed bool `json:"Checkpointed,omitempty"` - CgroupPath string `json:"CgroupPath,omitempty"` + OciVersion string `json:"OciVersion"` + Status string `json:"Status"` + Running bool `json:"Running"` + Paused bool `json:"Paused"` + Restarting bool `json:"Restarting"` // TODO + OOMKilled bool `json:"OOMKilled"` + Dead bool `json:"Dead"` + Pid int `json:"Pid"` + ConmonPid int `json:"ConmonPid,omitempty"` + ExitCode int32 `json:"ExitCode"` + Error string `json:"Error"` // TODO + StartedAt time.Time `json:"StartedAt"` + FinishedAt time.Time `json:"FinishedAt"` + Health HealthCheckResults `json:"Health,omitempty"` + Checkpointed bool `json:"Checkpointed,omitempty"` + CgroupPath string `json:"CgroupPath,omitempty"` + CheckpointedAt time.Time `json:"CheckpointedAt,omitempty"` + RestoredAt time.Time `json:"RestoredAt,omitempty"` + CheckpointLog string `json:"CheckpointLog,omitempty"` + CheckpointPath string `json:"CheckpointPath,omitempty"` + RestoreLog string `json:"RestoreLog,omitempty"` + Restored bool `json:"Restored,omitempty"` } // Healthcheck returns the HealthCheckResults. This is used for old podman compat diff --git a/libpod/kube.go b/libpod/kube.go index 4e61b5377..d667616d0 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -747,7 +747,7 @@ func libpodEnvVarsToKubeEnvVars(envs []string, imageEnvs []string) ([]v1.EnvVar, defaultEnv := env.DefaultEnvVariables() envVars := make([]v1.EnvVar, 0, len(envs)) imageMap := make(map[string]string, len(imageEnvs)) - for _, ie := range envs { + for _, ie := range imageEnvs { split := strings.SplitN(ie, "=", 2) imageMap[split[0]] = split[1] } diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index 52ac0d4d7..bf0fc4585 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -36,10 +36,21 @@ func (r *Runtime) RemoveContainersForImageCallback(ctx context.Context) libimage return err } for _, ctr := range ctrs { - if ctr.config.RootfsImageID == imageID { - var timeout *uint + if ctr.config.RootfsImageID != imageID { + continue + } + var timeout *uint + if ctr.config.IsInfra { + pod, err := r.state.Pod(ctr.config.Pod) + if err != nil { + return errors.Wrapf(err, "container %s is in pod %s, but pod cannot be retrieved", ctr.ID(), pod.ID()) + } + if err := r.removePod(ctx, pod, true, true, timeout); err != nil { + return errors.Wrapf(err, "removing image %s: container %s using image could not be removed", imageID, ctr.ID()) + } + } else { if err := r.removeContainer(ctx, ctr, true, false, false, timeout); err != nil { - return errors.Wrapf(err, "error removing image %s: container %s using image could not be removed", imageID, ctr.ID()) + return errors.Wrapf(err, "removing image %s: container %s using image could not be removed", imageID, ctr.ID()) } } } diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index 3e81d5c14..92725adc7 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -145,8 +145,8 @@ func tryMappingTool(uid bool, pid int, hostID int, mappings []idtools.IDMap) err } if output, err := cmd.CombinedOutput(); err != nil { - logrus.Debugf("error from %s: %s", tool, output) - return errors.Wrapf(err, "cannot setup namespace using %s", tool) + logrus.Errorf("error running `%s`: %s", strings.Join(args, " "), output) + return errors.Wrapf(err, "cannot setup namespace using %q", path) } return nil } diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index 064c82621..8103a0f6b 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -91,25 +91,97 @@ var _ = Describe("Podman checkpoint", func() { Expect(session).Should(Exit(0)) cid := session.OutputToString() - result := podmanTest.Podman([]string{"container", "checkpoint", cid}) + // Check if none of the checkpoint/restore specific information is displayed + // for newly started containers. + inspect := podmanTest.Podman([]string{"inspect", cid}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + inspectOut := inspect.InspectContainerToJSON() + Expect(inspectOut[0].State.Checkpointed).To(BeFalse(), ".State.Checkpointed") + Expect(inspectOut[0].State.Restored).To(BeFalse(), ".State.Restored") + Expect(inspectOut[0].State.CheckpointPath).To(Equal("")) + Expect(inspectOut[0].State.CheckpointLog).To(Equal("")) + Expect(inspectOut[0].State.RestoreLog).To(Equal("")) + + result := podmanTest.Podman([]string{ + "container", + "checkpoint", + "--keep", + cid, + }) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) - inspect := podmanTest.Podman([]string{"inspect", cid}) + // For a checkpointed container we expect the checkpoint related information + // to be populated. + inspect = podmanTest.Podman([]string{"inspect", cid}) inspect.WaitWithDefaultTimeout() Expect(inspect).Should(Exit(0)) - inspectOut := inspect.InspectContainerToJSON() + inspectOut = inspect.InspectContainerToJSON() Expect(inspectOut[0].State.Checkpointed).To(BeTrue(), ".State.Checkpointed") + Expect(inspectOut[0].State.Restored).To(BeFalse(), ".State.Restored") + Expect(inspectOut[0].State.CheckpointPath).To(ContainSubstring("userdata/checkpoint")) + Expect(inspectOut[0].State.CheckpointLog).To(ContainSubstring("userdata/dump.log")) + Expect(inspectOut[0].State.RestoreLog).To(Equal("")) - result = podmanTest.Podman([]string{"container", "restore", cid}) + result = podmanTest.Podman([]string{ + "container", + "restore", + "--keep", + cid, + }) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) + + inspect = podmanTest.Podman([]string{"inspect", cid}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + inspectOut = inspect.InspectContainerToJSON() + Expect(inspectOut[0].State.Restored).To(BeTrue(), ".State.Restored") + Expect(inspectOut[0].State.Checkpointed).To(BeFalse(), ".State.Checkpointed") + Expect(inspectOut[0].State.CheckpointPath).To(ContainSubstring("userdata/checkpoint")) + Expect(inspectOut[0].State.CheckpointLog).To(ContainSubstring("userdata/dump.log")) + Expect(inspectOut[0].State.RestoreLog).To(ContainSubstring("userdata/restore.log")) + + result = podmanTest.Podman([]string{ + "container", + "stop", + "--timeout", + "0", + cid, + }) + result.WaitWithDefaultTimeout() + + Expect(result).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + + result = podmanTest.Podman([]string{ + "container", + "start", + cid, + }) + result.WaitWithDefaultTimeout() + + Expect(result).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + + // Stopping and starting the container should remove all checkpoint + // related information from inspect again. + inspect = podmanTest.Podman([]string{"inspect", cid}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + inspectOut = inspect.InspectContainerToJSON() + Expect(inspectOut[0].State.Checkpointed).To(BeFalse(), ".State.Checkpointed") + Expect(inspectOut[0].State.Restored).To(BeFalse(), ".State.Restored") + Expect(inspectOut[0].State.CheckpointPath).To(Equal("")) + Expect(inspectOut[0].State.CheckpointLog).To(Equal("")) + Expect(inspectOut[0].State.RestoreLog).To(Equal("")) }) It("podman checkpoint a running container by name", func() { diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go index cfa264de2..16f2c4272 100644 --- a/test/e2e/generate_kube_test.go +++ b/test/e2e/generate_kube_test.go @@ -1100,4 +1100,28 @@ USER test1` Expect(pod.GetAnnotations()).To(HaveKeyWithValue("io.containers.autoupdate.authfile/"+ctr, "/some/authfile.json")) } }) + + It("podman generate kube can export env variables correctly", func() { + // Fixes https://github.com/containers/podman/issues/12647 + // PR https://github.com/containers/podman/pull/12648 + + ctrName := "gen-kube-env-ctr" + podName := "gen-kube-env" + session1 := podmanTest.Podman([]string{"run", "-d", "--pod", "new:" + podName, "--name", ctrName, + "-e", "FOO=bar", + "-e", "HELLO=WORLD", + "alpine", "top"}) + session1.WaitWithDefaultTimeout() + Expect(session1).Should(Exit(0)) + + kube := podmanTest.Podman([]string{"generate", "kube", podName}) + kube.WaitWithDefaultTimeout() + Expect(kube).Should(Exit(0)) + + pod := new(v1.Pod) + err := yaml.Unmarshal(kube.Out.Contents(), pod) + Expect(err).To(BeNil()) + + Expect(pod.Spec.Containers[0].Env).To(HaveLen(2)) + }) }) diff --git a/test/system/010-images.bats b/test/system/010-images.bats index 9de31f96c..201418620 100644 --- a/test/system/010-images.bats +++ b/test/system/010-images.bats @@ -240,4 +240,64 @@ Labels.created_at | 20[0-9-]\\\+T[0-9:]\\\+Z run_podman rmi test:1.0 } + +@test "podman images - rmi -af removes all containers and pods" { + pname=$(random_string) + run_podman create --pod new:$pname $IMAGE + + run_podman inspect --format '{{.ID}}' $IMAGE + imageID=$output + + run_podman version --format "{{.Server.Version}}-{{.Server.Built}}" + pauseImage=localhost/podman-pause:$output + run_podman inspect --format '{{.ID}}' $pauseImage + pauseID=$output + + run_podman 2 rmi -a + is "$output" "Error: 2 errors occurred: +.** Image used by .*: image is in use by a container +.** Image used by .*: image is in use by a container" + + run_podman rmi -af + is "$output" "Untagged: $IMAGE +Untagged: $pauseImage +Deleted: $imageID +Deleted: $pauseID" "infra images gets removed as well" + + run_podman images --noheading + is "$output" "" + run_podman ps --all --noheading + is "$output" "" + run_podman pod ps --noheading + is "$output" "" + + run_podman create --pod new:$pname $IMAGE +} + +@test "podman images - rmi -f can remove infra images" { + pname=$(random_string) + run_podman create --pod new:$pname $IMAGE + + run_podman version --format "{{.Server.Version}}-{{.Server.Built}}" + pauseImage=localhost/podman-pause:$output + run_podman inspect --format '{{.ID}}' $pauseImage + pauseID=$output + + run_podman 2 rmi $pauseImage + is "$output" "Error: Image used by .* image is in use by a container" + + run_podman rmi -f $pauseImage + is "$output" "Untagged: $pauseImage +Deleted: $pauseID" + + # Force-removing the infra container removes the pod and all its containers. + run_podman ps --all --noheading + is "$output" "" + run_podman pod ps --noheading + is "$output" "" + + # Other images are still present. + run_podman image exists $IMAGE +} + # vim: filetype=sh diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod index 57b634f17..96ca1f0b2 100644 --- a/vendor/github.com/containers/storage/go.mod +++ b/vendor/github.com/containers/storage/go.mod @@ -18,7 +18,7 @@ require ( github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible github.com/moby/sys/mountinfo v0.5.0 github.com/opencontainers/go-digest v1.0.0 - github.com/opencontainers/runc v1.0.2 + github.com/opencontainers/runc v1.0.3 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 github.com/opencontainers/selinux v1.10.0 github.com/pkg/errors v0.9.1 diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum index 94d46b21a..c7262fe7a 100644 --- a/vendor/github.com/containers/storage/go.sum +++ b/vendor/github.com/containers/storage/go.sum @@ -514,8 +514,9 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= -github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg= github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/runc v1.0.3 h1:1hbqejyQWCJBvtKAfdO0b1FmaEf2z/bxnjqbARass5k= +github.com/opencontainers/runc v1.0.3/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go index fbf6ad362..e2357c540 100644 --- a/vendor/github.com/containers/storage/layers.go +++ b/vendor/github.com/containers/storage/layers.go @@ -23,6 +23,7 @@ import ( "github.com/containers/storage/pkg/system" "github.com/containers/storage/pkg/tarlog" "github.com/containers/storage/pkg/truncindex" + multierror "github.com/hashicorp/go-multierror" "github.com/klauspost/pgzip" digest "github.com/opencontainers/go-digest" "github.com/opencontainers/selinux/go-selinux/label" @@ -1463,34 +1464,48 @@ func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser, } return maybeCompressReadCloser(diff) } - defer tsfile.Close() decompressor, err := pgzip.NewReader(tsfile) if err != nil { - return nil, err - } - defer decompressor.Close() - - tsbytes, err := ioutil.ReadAll(decompressor) - if err != nil { + if e := tsfile.Close(); e != nil { + logrus.Debug(e) + } return nil, err } - metadata = storage.NewJSONUnpacker(bytes.NewBuffer(tsbytes)) + metadata = storage.NewJSONUnpacker(decompressor) fgetter, err := r.newFileGetter(to) if err != nil { - return nil, err + errs := multierror.Append(nil, errors.Wrapf(err, "creating file-getter")) + if err := decompressor.Close(); err != nil { + errs = multierror.Append(errs, errors.Wrapf(err, "closing decompressor")) + } + if err := tsfile.Close(); err != nil { + errs = multierror.Append(errs, errors.Wrapf(err, "closing tarstream headers")) + } + return nil, errs.ErrorOrNil() } tarstream := asm.NewOutputTarStream(fgetter, metadata) rc := ioutils.NewReadCloserWrapper(tarstream, func() error { - err1 := tarstream.Close() - err2 := fgetter.Close() - if err2 == nil { - return err1 + var errs *multierror.Error + if err := decompressor.Close(); err != nil { + errs = multierror.Append(errs, errors.Wrapf(err, "closing decompressor")) + } + if err := tsfile.Close(); err != nil { + errs = multierror.Append(errs, errors.Wrapf(err, "closing tarstream headers")) + } + if err := tarstream.Close(); err != nil { + errs = multierror.Append(errs, errors.Wrapf(err, "closing reconstructed tarstream")) + } + if err := fgetter.Close(); err != nil { + errs = multierror.Append(errs, errors.Wrapf(err, "closing file-getter")) + } + if errs != nil { + return errs.ErrorOrNil() } - return err2 + return nil }) return maybeCompressReadCloser(rc) } diff --git a/vendor/github.com/containers/storage/pkg/homedir/homedir.go b/vendor/github.com/containers/storage/pkg/homedir/homedir.go new file mode 100644 index 000000000..85c5e76c8 --- /dev/null +++ b/vendor/github.com/containers/storage/pkg/homedir/homedir.go @@ -0,0 +1,52 @@ +package homedir + +import ( + "errors" + "os" + "path/filepath" +) + +// GetConfigHome returns XDG_CONFIG_HOME. +// GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set. +// +// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html +func GetConfigHome() (string, error) { + if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" { + return xdgConfigHome, nil + } + home := Get() + if home == "" { + return "", errors.New("could not get either XDG_CONFIG_HOME or HOME") + } + return filepath.Join(home, ".config"), nil +} + +// GetDataHome returns XDG_DATA_HOME. +// GetDataHome returns $HOME/.local/share and nil error if XDG_DATA_HOME is not set. +// +// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html +func GetDataHome() (string, error) { + if xdgDataHome := os.Getenv("XDG_DATA_HOME"); xdgDataHome != "" { + return xdgDataHome, nil + } + home := Get() + if home == "" { + return "", errors.New("could not get either XDG_DATA_HOME or HOME") + } + return filepath.Join(home, ".local", "share"), nil +} + +// GetCacheHome returns XDG_CACHE_HOME. +// GetCacheHome returns $HOME/.cache and nil error if XDG_CACHE_HOME is not set. +// +// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html +func GetCacheHome() (string, error) { + if xdgCacheHome := os.Getenv("XDG_CACHE_HOME"); xdgCacheHome != "" { + return xdgCacheHome, nil + } + home := Get() + if home == "" { + return "", errors.New("could not get either XDG_CACHE_HOME or HOME") + } + return filepath.Join(home, ".cache"), nil +} diff --git a/vendor/github.com/containers/storage/pkg/homedir/homedir_others.go b/vendor/github.com/containers/storage/pkg/homedir/homedir_others.go index 06b53854b..027db259c 100644 --- a/vendor/github.com/containers/storage/pkg/homedir/homedir_others.go +++ b/vendor/github.com/containers/storage/pkg/homedir/homedir_others.go @@ -18,18 +18,3 @@ func GetRuntimeDir() (string, error) { func StickRuntimeDirContents(files []string) ([]string, error) { return nil, errors.New("homedir.StickRuntimeDirContents() is not supported on this system") } - -// GetDataHome is unsupported on non-linux system. -func GetDataHome() (string, error) { - return "", errors.New("homedir.GetDataHome() is not supported on this system") -} - -// GetConfigHome is unsupported on non-linux system. -func GetConfigHome() (string, error) { - return "", errors.New("homedir.GetConfigHome() is not supported on this system") -} - -// GetCacheHome is unsupported on non-linux system. -func GetCacheHome() (string, error) { - return "", errors.New("homedir.GetCacheHome() is not supported on this system") -} diff --git a/vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go b/vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go index 2475e351b..33177bdf3 100644 --- a/vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go +++ b/vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go @@ -93,48 +93,3 @@ func stick(f string) error { m |= os.ModeSticky return os.Chmod(f, m) } - -// GetDataHome returns XDG_DATA_HOME. -// GetDataHome returns $HOME/.local/share and nil error if XDG_DATA_HOME is not set. -// -// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html -func GetDataHome() (string, error) { - if xdgDataHome := os.Getenv("XDG_DATA_HOME"); xdgDataHome != "" { - return xdgDataHome, nil - } - home := Get() - if home == "" { - return "", errors.New("could not get either XDG_DATA_HOME or HOME") - } - return filepath.Join(home, ".local", "share"), nil -} - -// GetConfigHome returns XDG_CONFIG_HOME. -// GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set. -// -// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html -func GetConfigHome() (string, error) { - if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" { - return xdgConfigHome, nil - } - home := Get() - if home == "" { - return "", errors.New("could not get either XDG_CONFIG_HOME or HOME") - } - return filepath.Join(home, ".config"), nil -} - -// GetCacheHome returns XDG_CACHE_HOME. -// GetCacheHome returns $HOME/.cache and nil error if XDG_CACHE_HOME is not set. -// -// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html -func GetCacheHome() (string, error) { - if xdgCacheHome := os.Getenv("XDG_CACHE_HOME"); xdgCacheHome != "" { - return xdgCacheHome, nil - } - home := Get() - if home == "" { - return "", errors.New("could not get either XDG_CACHE_HOME or HOME") - } - return filepath.Join(home, ".cache"), nil -} diff --git a/vendor/github.com/containers/storage/pkg/homedir/homedir_windows.go b/vendor/github.com/containers/storage/pkg/homedir/homedir_windows.go index 4f2615ed3..af65f2c03 100644 --- a/vendor/github.com/containers/storage/pkg/homedir/homedir_windows.go +++ b/vendor/github.com/containers/storage/pkg/homedir/homedir_windows.go @@ -17,7 +17,12 @@ func Key() string { // environment variables depending on the target operating system. // Returned path should be used with "path/filepath" to form new paths. func Get() string { - return os.Getenv(Key()) + home := os.Getenv(Key()) + if home != "" { + return home + } + home, _ = os.UserHomeDir() + return home } // GetShortcutString returns the string that is shortcut to user's home directory diff --git a/vendor/github.com/containers/storage/pkg/idtools/idtools_supported.go b/vendor/github.com/containers/storage/pkg/idtools/idtools_supported.go index db50a62e4..e444a1bcc 100644 --- a/vendor/github.com/containers/storage/pkg/idtools/idtools_supported.go +++ b/vendor/github.com/containers/storage/pkg/idtools/idtools_supported.go @@ -17,6 +17,12 @@ struct subid_range get_range(struct subid_range *ranges, int i) { return ranges[i]; } + +#if !defined(SUBID_ABI_MAJOR) || (SUBID_ABI_MAJOR < 4) +# define subid_get_uid_ranges get_subuid_ranges +# define subid_get_gid_ranges get_subgid_ranges +#endif + */ import "C" @@ -32,9 +38,9 @@ func readSubid(username string, isUser bool) (ranges, error) { var nRanges C.int var cRanges *C.struct_subid_range if isUser { - nRanges = C.get_subuid_ranges(cUsername, &cRanges) + nRanges = C.subid_get_uid_ranges(cUsername, &cRanges) } else { - nRanges = C.get_subgid_ranges(cUsername, &cRanges) + nRanges = C.subid_get_gid_ranges(cUsername, &cRanges) } if nRanges < 0 { return nil, errors.New("cannot read subids") diff --git a/vendor/github.com/containers/storage/types/options.go b/vendor/github.com/containers/storage/types/options.go index fe4274efd..7586cd5ae 100644 --- a/vendor/github.com/containers/storage/types/options.go +++ b/vendor/github.com/containers/storage/types/options.go @@ -27,6 +27,13 @@ type tomlConfig struct { } `toml:"storage"` } +const ( + // these are default path for run and graph root for rootful users + // for rootless path is constructed via getRootlessStorageOpts + defaultRunRoot string = "/run/containers/storage" + defaultGraphRoot string = "/var/lib/containers/storage" +) + // defaultConfigFile path to the system wide storage.conf file var ( defaultConfigFile = "/usr/share/containers/storage.conf" @@ -36,9 +43,14 @@ var ( defaultStoreOptions StoreOptions ) +const ( + overlayDriver = "overlay" + overlay2 = "overlay2" +) + func init() { - defaultStoreOptions.RunRoot = "/run/containers/storage" - defaultStoreOptions.GraphRoot = "/var/lib/containers/storage" + defaultStoreOptions.RunRoot = defaultRunRoot + defaultStoreOptions.GraphRoot = defaultGraphRoot defaultStoreOptions.GraphDriverName = "" if _, err := os.Stat(defaultOverrideConfigFile); err == nil { @@ -53,6 +65,13 @@ func init() { } ReloadConfigurationFileIfNeeded(defaultConfigFile, &defaultStoreOptions) } + // reload could set values to empty for run and graph root if config does not contains anything + if defaultStoreOptions.RunRoot == "" { + defaultStoreOptions.RunRoot = defaultRunRoot + } + if defaultStoreOptions.GraphRoot == "" { + defaultStoreOptions.GraphRoot = defaultGraphRoot + } } // defaultStoreOptionsIsolated is an internal implementation detail of DefaultStoreOptions to allow testing. @@ -180,7 +199,6 @@ func isRootlessDriver(driver string) bool { // getRootlessStorageOpts returns the storage opts for containers running as non root func getRootlessStorageOpts(rootlessUID int, systemOpts StoreOptions) (StoreOptions, error) { var opts StoreOptions - const overlayDriver = "overlay" dataDir, rootlessRuntime, err := getRootlessDirInfo(rootlessUID) if err != nil { @@ -202,6 +220,11 @@ func getRootlessStorageOpts(rootlessUID int, systemOpts StoreOptions) (StoreOpti if driver := os.Getenv("STORAGE_DRIVER"); driver != "" { opts.GraphDriverName = driver } + if opts.GraphDriverName == overlay2 { + logrus.Warnf("Switching default driver from overlay2 to the equivalent overlay driver.") + opts.GraphDriverName = overlayDriver + } + if opts.GraphDriverName == "" || opts.GraphDriverName == overlayDriver { supported, err := overlay.SupportsNativeOverlay(opts.GraphRoot, rootlessRuntime) if err != nil { @@ -307,6 +330,10 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) { config.Storage.Driver = os.Getenv("STORAGE_DRIVER") storeOptions.GraphDriverName = config.Storage.Driver } + if storeOptions.GraphDriverName == overlay2 { + logrus.Warnf("Switching default driver from overlay2 to the equivalent overlay driver.") + storeOptions.GraphDriverName = overlayDriver + } if storeOptions.GraphDriverName == "" { logrus.Errorf("The storage 'driver' option must be set in %s, guarantee proper operation.", configFile) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 02c8315fa..5302a7e50 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -220,7 +220,7 @@ github.com/containers/psgo/internal/dev github.com/containers/psgo/internal/host github.com/containers/psgo/internal/proc github.com/containers/psgo/internal/process -# github.com/containers/storage v1.37.1-0.20211130181259-1a158c89a518 +# github.com/containers/storage v1.37.1-0.20211213220314-73a749e4fec5 ## explicit github.com/containers/storage github.com/containers/storage/drivers |