diff options
82 files changed, 733 insertions, 545 deletions
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go index 5dea49c8b..05bb9de13 100644 --- a/cmd/podman/common/create_opts.go +++ b/cmd/podman/common/create_opts.go @@ -293,66 +293,61 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig) (*Cont // like with start. We believe this is just a difference in podman/compat cliOpts := ContainerCLIOpts{ //Attach: nil, // dont need? - Authfile: "", - BlkIOWeight: strconv.Itoa(int(cc.HostConfig.BlkioWeight)), - BlkIOWeightDevice: nil, // TODO - CapAdd: append(capAdd, cc.HostConfig.CapAdd...), - CapDrop: append(cappDrop, cc.HostConfig.CapDrop...), - CGroupParent: cc.HostConfig.CgroupParent, - CIDFile: cc.HostConfig.ContainerIDFile, - CPUPeriod: uint64(cc.HostConfig.CPUPeriod), - CPUQuota: cc.HostConfig.CPUQuota, - CPURTPeriod: uint64(cc.HostConfig.CPURealtimePeriod), - CPURTRuntime: cc.HostConfig.CPURealtimeRuntime, - CPUShares: uint64(cc.HostConfig.CPUShares), + Authfile: "", + CapAdd: append(capAdd, cc.HostConfig.CapAdd...), + CapDrop: append(cappDrop, cc.HostConfig.CapDrop...), + CGroupParent: cc.HostConfig.CgroupParent, + CIDFile: cc.HostConfig.ContainerIDFile, + CPUPeriod: uint64(cc.HostConfig.CPUPeriod), + CPUQuota: cc.HostConfig.CPUQuota, + CPURTPeriod: uint64(cc.HostConfig.CPURealtimePeriod), + CPURTRuntime: cc.HostConfig.CPURealtimeRuntime, + CPUShares: uint64(cc.HostConfig.CPUShares), //CPUS: 0, // dont need? CPUSetCPUs: cc.HostConfig.CpusetCpus, CPUSetMems: cc.HostConfig.CpusetMems, //Detach: false, // dont need //DetachKeys: "", // dont need - Devices: devices, - DeviceCGroupRule: nil, - DeviceReadBPs: readBps, - DeviceReadIOPs: readIops, - DeviceWriteBPs: writeBps, - DeviceWriteIOPs: writeIops, - Entrypoint: &entrypoint, - Env: cc.Config.Env, - Expose: expose, - GroupAdd: cc.HostConfig.GroupAdd, - Hostname: cc.Config.Hostname, - ImageVolume: "bind", - Init: init, - Interactive: cc.Config.OpenStdin, - IPC: string(cc.HostConfig.IpcMode), - Label: stringMaptoArray(cc.Config.Labels), - LogDriver: cc.HostConfig.LogConfig.Type, - LogOptions: stringMaptoArray(cc.HostConfig.LogConfig.Config), - Memory: strconv.Itoa(int(cc.HostConfig.Memory)), - MemoryReservation: strconv.Itoa(int(cc.HostConfig.MemoryReservation)), - MemorySwap: strconv.Itoa(int(cc.HostConfig.MemorySwap)), - Name: cc.Name, - OOMScoreAdj: cc.HostConfig.OomScoreAdj, - OverrideArch: "", - OverrideOS: "", - OverrideVariant: "", - PID: string(cc.HostConfig.PidMode), - PIDsLimit: cc.HostConfig.PidsLimit, - Privileged: cc.HostConfig.Privileged, - PublishAll: cc.HostConfig.PublishAllPorts, - Quiet: false, - ReadOnly: cc.HostConfig.ReadonlyRootfs, - ReadOnlyTmpFS: true, // podman default - Rm: cc.HostConfig.AutoRemove, - SecurityOpt: cc.HostConfig.SecurityOpt, - ShmSize: strconv.Itoa(int(cc.HostConfig.ShmSize)), - StopSignal: cc.Config.StopSignal, - StoreageOpt: stringMaptoArray(cc.HostConfig.StorageOpt), - Sysctl: stringMaptoArray(cc.HostConfig.Sysctls), - Systemd: "true", // podman default - TmpFS: stringMaptoArray(cc.HostConfig.Tmpfs), - TTY: cc.Config.Tty, + Devices: devices, + DeviceCGroupRule: nil, + DeviceReadBPs: readBps, + DeviceReadIOPs: readIops, + DeviceWriteBPs: writeBps, + DeviceWriteIOPs: writeIops, + Entrypoint: &entrypoint, + Env: cc.Config.Env, + Expose: expose, + GroupAdd: cc.HostConfig.GroupAdd, + Hostname: cc.Config.Hostname, + ImageVolume: "bind", + Init: init, + Interactive: cc.Config.OpenStdin, + IPC: string(cc.HostConfig.IpcMode), + Label: stringMaptoArray(cc.Config.Labels), + LogDriver: cc.HostConfig.LogConfig.Type, + LogOptions: stringMaptoArray(cc.HostConfig.LogConfig.Config), + Name: cc.Name, + OOMScoreAdj: cc.HostConfig.OomScoreAdj, + OverrideArch: "", + OverrideOS: "", + OverrideVariant: "", + PID: string(cc.HostConfig.PidMode), + PIDsLimit: cc.HostConfig.PidsLimit, + Privileged: cc.HostConfig.Privileged, + PublishAll: cc.HostConfig.PublishAllPorts, + Quiet: false, + ReadOnly: cc.HostConfig.ReadonlyRootfs, + ReadOnlyTmpFS: true, // podman default + Rm: cc.HostConfig.AutoRemove, + SecurityOpt: cc.HostConfig.SecurityOpt, + StopSignal: cc.Config.StopSignal, + StoreageOpt: stringMaptoArray(cc.HostConfig.StorageOpt), + Sysctl: stringMaptoArray(cc.HostConfig.Sysctls), + Systemd: "true", // podman default + TmpFS: stringMaptoArray(cc.HostConfig.Tmpfs), + TTY: cc.Config.Tty, //Ulimit: cc.HostConfig.Ulimits, // ask dan, no documented format + Ulimit: []string{"nproc=4194304:4194304"}, User: cc.Config.User, UserNS: string(cc.HostConfig.UsernsMode), UTS: string(cc.HostConfig.UTSMode), @@ -363,10 +358,37 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig) (*Cont Net: &netInfo, } + if len(cc.HostConfig.BlkioWeightDevice) > 0 { + devices := make([]string, 0, len(cc.HostConfig.BlkioWeightDevice)) + for _, d := range cc.HostConfig.BlkioWeightDevice { + devices = append(devices, d.String()) + } + cliOpts.BlkIOWeightDevice = devices + } + if cc.HostConfig.BlkioWeight > 0 { + cliOpts.BlkIOWeight = strconv.Itoa(int(cc.HostConfig.BlkioWeight)) + } + + if cc.HostConfig.Memory > 0 { + cliOpts.Memory = strconv.Itoa(int(cc.HostConfig.Memory)) + } + + if cc.HostConfig.MemoryReservation > 0 { + cliOpts.MemoryReservation = strconv.Itoa(int(cc.HostConfig.MemoryReservation)) + } + + if cc.HostConfig.MemorySwap > 0 { + cliOpts.MemorySwap = strconv.Itoa(int(cc.HostConfig.MemorySwap)) + } + if cc.Config.StopTimeout != nil { cliOpts.StopTimeout = uint(*cc.Config.StopTimeout) } + if cc.HostConfig.ShmSize > 0 { + cliOpts.ShmSize = strconv.Itoa(int(cc.HostConfig.ShmSize)) + } + if cc.HostConfig.KernelMemory > 0 { cliOpts.KernelMemory = strconv.Itoa(int(cc.HostConfig.KernelMemory)) } diff --git a/docs/source/markdown/podman-build.1.md b/docs/source/markdown/podman-build.1.md index 821324f84..f1fddb2fc 100644 --- a/docs/source/markdown/podman-build.1.md +++ b/docs/source/markdown/podman-build.1.md @@ -111,17 +111,27 @@ network namespaces can be found. **--cpu-period**=*limit* -Limit the CPU CFS (Completely Fair Scheduler) period +Set the CPU period for the Completely Fair Scheduler (CFS), which is a +duration in microseconds. Once the container's CPU quota is used up, it will +not be scheduled to run until the current period ends. Defaults to 100000 +microseconds. -Limit the container's CPU usage. This flag tell the kernel to restrict the container's CPU usage to the period you specify. +On some systems, changing the CPU limits may not be allowed for non-root +users. For more details, see +https://github.com/containers/podman/blob/master/troubleshooting.md#26-running-containers-with-cpu-limits-fails-with-a-permissions-error **--cpu-quota**=*limit* -Limit the CPU CFS (Completely Fair Scheduler) quota +Limit the CPU Completely Fair Scheduler (CFS) quota. Limit the container's CPU usage. By default, containers run with the full -CPU resource. This flag tell the kernel to restrict the container's CPU usage -to the quota you specify. +CPU resource. The limit is a number in microseconds. If you provide a number, +the container will be allowed to use that much CPU time until the CPU period +ends (controllable via **--cpu-period**). + +On some systems, changing the CPU limits may not be allowed for non-root +users. For more details, see +https://github.com/containers/podman/blob/master/troubleshooting.md#26-running-containers-with-cpu-limits-fails-with-a-permissions-error **--cpu-shares**, **-c**=*shares* @@ -787,9 +797,9 @@ registries.conf is the configuration file which specifies which container regist ## Troubleshooting -If you are using a useradd command within a Containerfile with a large UID/GID, it will create a large sparse file `/var/log/lastlog`. This can cause the build to hang forever. Go language does not support sparse files correctly, which can lead to some huge files being created in your container image. +### lastlog sparse file -### Solution +If you are using a useradd command within a Containerfile with a large UID/GID, it will create a large sparse file `/var/log/lastlog`. This can cause the build to hang forever. Go language does not support sparse files correctly, which can lead to some huge files being created in your container image. If you are using `useradd` within your build script, you should pass the `--no-log-init or -l` option to the `useradd` command. This option tells useradd to stop creating the lastlog file. diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md index 1f229a3a0..c7e00f594 100644 --- a/docs/source/markdown/podman-create.1.md +++ b/docs/source/markdown/podman-create.1.md @@ -103,17 +103,27 @@ Write the pid of the `conmon` process to a file. `conmon` runs in a separate pro **--cpu-period**=*limit* -Limit the CPU CFS (Completely Fair Scheduler) period +Set the CPU period for the Completely Fair Scheduler (CFS), which is a +duration in microseconds. Once the container's CPU quota is used up, it will +not be scheduled to run until the current period ends. Defaults to 100000 +microseconds. -Limit the container's CPU usage. This flag tell the kernel to restrict the container's CPU usage to the period you specify. +On some systems, changing the CPU limits may not be allowed for non-root +users. For more details, see +https://github.com/containers/podman/blob/master/troubleshooting.md#26-running-containers-with-cpu-limits-fails-with-a-permissions-error **--cpu-quota**=*limit* -Limit the CPU CFS (Completely Fair Scheduler) quota +Limit the CPU Completely Fair Scheduler (CFS) quota. Limit the container's CPU usage. By default, containers run with the full -CPU resource. This flag tell the kernel to restrict the container's CPU usage -to the quota you specify. +CPU resource. The limit is a number in microseconds. If you provide a number, +the container will be allowed to use that much CPU time until the CPU period +ends (controllable via **--cpu-period**). + +On some systems, changing the CPU limits may not be allowed for non-root +users. For more details, see +https://github.com/containers/podman/blob/master/troubleshooting.md#26-running-containers-with-cpu-limits-fails-with-a-permissions-error **--cpu-rt-period**=*microseconds* @@ -169,7 +179,13 @@ PID container CPU CPU share **--cpus**=*number* -Number of CPUs. The default is *0.0* which means no limit. +Number of CPUs. The default is *0.0* which means no limit. This is shorthand +for **--cpu-period** and **--cpu-quota**, so you may only set either +**--cpus** or **--cpu-period** and **--cpu-quota**. + +On some systems, changing the CPU limits may not be allowed for non-root +users. For more details, see +https://github.com/containers/podman/blob/master/troubleshooting.md#26-running-containers-with-cpu-limits-fails-with-a-permissions-error **--cpuset-cpus**=*cpus* diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index b86c9b363..aad179957 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -118,15 +118,27 @@ Write the pid of the **conmon** process to a file. As **conmon** runs in a separ **--cpu-period**=*limit* -Limit the container's CPU usage by setting CPU CFS (Completely Fair Scheduler) period. +Set the CPU period for the Completely Fair Scheduler (CFS), which is a +duration in microseconds. Once the container's CPU quota is used up, it will +not be scheduled to run until the current period ends. Defaults to 100000 +microseconds. + +On some systems, changing the CPU limits may not be allowed for non-root +users. For more details, see +https://github.com/containers/podman/blob/master/troubleshooting.md#26-running-containers-with-cpu-limits-fails-with-a-permissions-error **--cpu-quota**=*limit* -Limit the CPU CFS (Completely Fair Scheduler) quota. +Limit the CPU Completely Fair Scheduler (CFS) quota. Limit the container's CPU usage. By default, containers run with the full -CPU resource. This flag tell the kernel to restrict the container's CPU usage -to the quota you specify. +CPU resource. The limit is a number in microseconds. If you provide a number, +the container will be allowed to use that much CPU time until the CPU period +ends (controllable via **--cpu-period**). + +On some systems, changing the CPU limits may not be allowed for non-root +users. For more details, see +https://github.com/containers/podman/blob/master/troubleshooting.md#26-running-containers-with-cpu-limits-fails-with-a-permissions-error **--cpu-rt-period**=*microseconds* @@ -180,7 +192,13 @@ division of CPU shares: **--cpus**=*number* -Number of CPUs. The default is *0.0* which means no limit. +Number of CPUs. The default is *0.0* which means no limit. This is shorthand +for **--cpu-period** and **--cpu-quota**, so you may only set either +**--cpus** or **--cpu-period** and **--cpu-quota**. + +On some systems, changing the CPU limits may not be allowed for non-root +users. For more details, see +https://github.com/containers/podman/blob/master/troubleshooting.md#26-running-containers-with-cpu-limits-fails-with-a-permissions-error **--cpuset-cpus**=*number* @@ -12,11 +12,11 @@ require ( github.com/containernetworking/cni v0.8.0 github.com/containernetworking/plugins v0.8.7 github.com/containers/buildah v1.16.5 - github.com/containers/common v0.26.0 + github.com/containers/common v0.26.3 github.com/containers/conmon v2.0.20+incompatible - github.com/containers/image/v5 v5.6.0 + github.com/containers/image/v5 v5.7.0 github.com/containers/psgo v1.5.1 - github.com/containers/storage v1.23.5 + github.com/containers/storage v1.23.7 github.com/coreos/go-systemd/v22 v22.1.0 github.com/cri-o/ocicni v0.2.0 github.com/cyphar/filepath-securejoin v0.2.2 @@ -90,13 +90,13 @@ github.com/containernetworking/plugins v0.8.7/go.mod h1:R7lXeZaBzpfqapcAbHRW8/CY github.com/containers/buildah v1.16.5 h1:0tH2TJeZWbspWExHY0A7d7lpdYoxB5VFgRTbzc+qKGs= github.com/containers/buildah v1.16.5/go.mod h1:tqjupkpg4uqeQWhb7O6puyJwoIbpTkBrWAq1iUK9Wh0= github.com/containers/common v0.21.0/go.mod h1:8w8SVwc+P2p1MOnRMbSKNWXt1Iwd2bKFu2LLZx55DTM= -github.com/containers/common v0.26.0 h1:BCo/S5Dl8aRRG7vze+hoWdCd5xuThIP/tCB5NjTIn6g= -github.com/containers/common v0.26.0/go.mod h1:BCK8f8Ye1gvUVGcokJngJG4YC80c2Bjx/F9GyoIAVMc= +github.com/containers/common v0.26.3 h1:5Kb5fMmJ7/xMiJ+iEbPA+5pQpl/FGxCgJex4nml4Slo= +github.com/containers/common v0.26.3/go.mod h1:hJWZIlrl5MsE2ELNRa+MPp6I1kPbXHauuj0Ym4BsLG4= 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.5.2/go.mod h1:4PyNYR0nwlGq/ybVJD9hWlhmIsNra4Q8uOQX2s6E2uM= -github.com/containers/image/v5 v5.6.0 h1:r4AqIX4NO/X7OJkqX574zITV3fq0ZPn0pSlLsxWF6ww= -github.com/containers/image/v5 v5.6.0/go.mod h1:iUSWo3SOLqJo0CkZkKrHxqR6YWqrT98mkXFpE0MceE8= +github.com/containers/image/v5 v5.7.0 h1:fiTC8/Xbr+zEP6njGTZtPW/3UD7MC93nC9DbUoWdxkA= +github.com/containers/image/v5 v5.7.0/go.mod h1:8aOy+YaItukxghRORkvhq5ibWttHErzDLy6egrKfKos= 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.2/go.mod h1:nsOhbP19flrX6rE7ieGFvBlr7modwmNjsqWarIUce4M= @@ -106,8 +106,10 @@ github.com/containers/psgo v1.5.1 h1:MQNb7FLbXqBdqz6u4lI2QWizVz4RSTzs1+Nk9XT1iVA github.com/containers/psgo v1.5.1/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzPUWfawVU= github.com/containers/storage v1.20.2/go.mod h1:oOB9Ie8OVPojvoaKWEGSEtHbXUAs+tSyr7RO7ZGteMc= github.com/containers/storage v1.23.3/go.mod h1:0azTMiuBhArp/VUmH1o4DJAGaaH+qLtEu17pJ/iKJCg= -github.com/containers/storage v1.23.5 h1:He9I6y1vRVXYoQg4v2Q9HFAcX4dI3V5MCCrjeBcjkCY= -github.com/containers/storage v1.23.5/go.mod h1:ha26Q6ngehFNhf3AWoXldvAvwI4jFe3ETQAf/CeZPyM= +github.com/containers/storage v1.23.6 h1:3rcZ1KTNv8q7SkZ75gcrFGYqTeiuI04Zg7m9X1sCg/s= +github.com/containers/storage v1.23.6/go.mod h1:haFs0HRowKwyzvWEx9EgI3WsL8XCSnBDb5f8P5CAxJY= +github.com/containers/storage v1.23.7 h1:43ImvG/npvQSZXRjaudVvKISIuZSfI6qvtSNQQSGO/A= +github.com/containers/storage v1.23.7/go.mod h1:cUT2zHjtx+WlVri30obWmM2gpqpi8jfPsmIzP1TVpEI= 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= @@ -318,8 +320,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.11/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.0 h1:wJbzvpYMVGG9iTI9VxpnNZfd4DzMPoCWze3GgSqz8yg= -github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.1 h1:bPb7nMRdOZYDrpPMTA3EInUQrdgoBinqUuSwlGdKDdE= +github.com/klauspost/compress v1.11.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= @@ -360,8 +362,11 @@ github.com/moby/sys/mount v0.1.1 h1:mdhBytJ1SMmMat0gtzWWjFX/87K5j6E/7Q5z7rR0cZY= github.com/moby/sys/mount v0.1.1/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74= github.com/moby/sys/mountinfo v0.1.0/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o= github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o= -github.com/moby/sys/mountinfo v0.2.0 h1:HgYSHMWCj8D7w7TE/cQJfWrY6W3TUxs3pwGFyC5qCvE= github.com/moby/sys/mountinfo v0.2.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.3.1 h1:R+C9GycEzoR3GdwQ7mANRhJORnVDJiRkf0JMY82MeI0= +github.com/moby/sys/mountinfo v0.3.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.4.0 h1:1KInV3Huv18akCu58V7lzNlt+jFmqlu1EaErnEHE/VM= +github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/term v0.0.0-20200915141129-7f0af18e79f2 h1:SPoLlS9qUUnXcIY4pvA4CTwYjk0Is5f4UPEkeESr53k= github.com/moby/term v0.0.0-20200915141129-7f0af18e79f2/go.mod h1:TjQg8pa4iejrUrjiz0MCtMV38jdMNW4doKSiBrEvCQQ= github.com/moby/vpnkit v0.4.0/go.mod h1:KyjUrL9cb6ZSNNAUwZfqRjhwwgJ3BJN+kXh0t43WTUQ= @@ -503,7 +508,6 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= diff --git a/libpod/events/journal_linux.go b/libpod/events/journal_linux.go index 5d17a85b4..5e3be8009 100644 --- a/libpod/events/journal_linux.go +++ b/libpod/events/journal_linux.go @@ -69,35 +69,39 @@ func (e EventJournalD) Read(ctx context.Context, options ReadOptions) error { if err != nil { return errors.Wrapf(err, "failed to generate event options") } - j, err := sdjournal.NewJournal() //nolint + j, err := sdjournal.NewJournal() if err != nil { return err } - // TODO AddMatch and Seek seem to conflict - // Issue filed upstream -> https://github.com/coreos/go-systemd/issues/315 - // Leaving commented code in case upstream fixes things - //podmanJournal := sdjournal.Match{Field: "SYSLOG_IDENTIFIER", Value: "podman"} //nolint - //if err := j.AddMatch(podmanJournal.String()); err != nil { - // return errors.Wrap(err, "failed to add filter for event log") - //} + + // match only podman journal entries + podmanJournal := sdjournal.Match{Field: "SYSLOG_IDENTIFIER", Value: "podman"} + if err := j.AddMatch(podmanJournal.String()); err != nil { + return errors.Wrap(err, "failed to add journal filter for event log") + } + if len(options.Since) == 0 && len(options.Until) == 0 && options.Stream { if err := j.SeekTail(); err != nil { return errors.Wrap(err, "failed to seek end of journal") } - } else { - podmanJournal := sdjournal.Match{Field: "SYSLOG_IDENTIFIER", Value: "podman"} //nolint - if err := j.AddMatch(podmanJournal.String()); err != nil { - return errors.Wrap(err, "failed to add filter for event log") + // After SeekTail calling Next moves to a random entry. + // To prevent this we have to call Previous first. + // see: https://bugs.freedesktop.org/show_bug.cgi?id=64614 + if _, err := j.Previous(); err != nil { + return errors.Wrap(err, "failed to move journal cursor to previous entry") } } + // the api requires a next|prev before getting a cursor if _, err := j.Next(); err != nil { - return err + return errors.Wrap(err, "failed to move journal cursor to next entry") } + prevCursor, err := j.GetCursor() if err != nil { - return err + return errors.Wrap(err, "failed to get journal cursor") } + for { select { case <-ctx.Done(): @@ -106,30 +110,26 @@ func (e EventJournalD) Read(ctx context.Context, options ReadOptions) error { default: // fallthrough } + if _, err := j.Next(); err != nil { - return err + return errors.Wrap(err, "failed to move journal cursor to next entry") } newCursor, err := j.GetCursor() if err != nil { - return err + return errors.Wrap(err, "failed to get journal cursor") } if prevCursor == newCursor { if len(options.Until) > 0 || !options.Stream { break } - _ = j.Wait(sdjournal.IndefiniteWait) //nolint + _ = j.Wait(sdjournal.IndefiniteWait) continue } prevCursor = newCursor + entry, err := j.GetEntry() if err != nil { - return err - } - // TODO this keeps us from feeding the podman event parser with - // with regular journal content; it can be removed if the above - // problem with AddMatch is resolved. - if entry.Fields["PODMAN_EVENT"] == "" { - continue + return errors.Wrap(err, "failed to read journal entry") } newEvent, err := newEventFromJournalEntry(entry) if err != nil { diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go index 3a7662c41..31435ae91 100644 --- a/pkg/bindings/connection.go +++ b/pkg/bindings/connection.go @@ -214,19 +214,23 @@ func sshClient(_url *url.URL, secure bool, passPhrase string, identity string) ( authMethods = append(authMethods, ssh.Password(string(pass))) } + port := _url.Port() + if port == "" { + port = "22" + } + callback := ssh.InsecureIgnoreHostKey() if secure { - key := terminal.HostKey(_url.Hostname()) + host := _url.Hostname() + if port != "22" { + host = fmt.Sprintf("[%s]:%s", host, port) + } + key := terminal.HostKey(host) if key != nil { callback = ssh.FixedHostKey(key) } } - port := _url.Port() - if port == "" { - port = "22" - } - bastion, err := ssh.Dial("tcp", net.JoinHostPort(_url.Hostname(), port), &ssh.ClientConfig{ diff --git a/pkg/domain/infra/abi/images_list.go b/pkg/domain/infra/abi/images_list.go index 3e47dc67a..281b04294 100644 --- a/pkg/domain/infra/abi/images_list.go +++ b/pkg/domain/infra/abi/images_list.go @@ -5,6 +5,7 @@ import ( libpodImage "github.com/containers/podman/v2/libpod/image" "github.com/containers/podman/v2/pkg/domain/entities" + "github.com/pkg/errors" ) func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ([]*entities.ImageSummary, error) { @@ -43,12 +44,21 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) VirtualSize: img.VirtualSize, RepoTags: img.Names(), // may include tags and digests } - e.Labels, _ = img.Labels(context.TODO()) + e.Labels, err = img.Labels(ctx) + if err != nil { + return nil, errors.Wrapf(err, "error retrieving label for image %q: you may need to remove the image to resolve the error", img.ID()) + } - ctnrs, _ := img.Containers() + ctnrs, err := img.Containers() + if err != nil { + return nil, errors.Wrapf(err, "error retrieving containers for image %q: you may need to remove the image to resolve the error", img.ID()) + } e.Containers = len(ctnrs) - sz, _ := img.Size(context.TODO()) + sz, err := img.Size(ctx) + if err != nil { + return nil, errors.Wrapf(err, "error retrieving size of image %q: you may need to remove the image to resolve the error", img.ID()) + } e.Size = int64(*sz) summaries = append(summaries, &e) diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index d8e23b118..3814d161d 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -629,6 +629,13 @@ func SkipIfRootless(reason string) { } } +func SkipIfNotRootless(reason string) { + checkReason(reason) + if os.Geteuid() == 0 { + ginkgo.Skip("[notRootless]: " + reason) + } +} + func SkipIfNotFedora() { info := GetHostDistributionInfo() if info.Distribution != "fedora" { diff --git a/test/e2e/info_test.go b/test/e2e/info_test.go index 49f5f0ce6..bc4e6212b 100644 --- a/test/e2e/info_test.go +++ b/test/e2e/info_test.go @@ -5,9 +5,9 @@ import ( "io/ioutil" "os" "os/exec" + "os/user" "path/filepath" - "github.com/containers/podman/v2/pkg/rootless" . "github.com/containers/podman/v2/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -78,39 +78,35 @@ var _ = Describe("Podman Info", func() { }) It("podman info rootless storage path", func() { - if !rootless.IsRootless() { - Skip("test of rootless_storage_path is only meaningful as rootless") - } + SkipIfNotRootless("test of rootless_storage_path is only meaningful as rootless") SkipIfRemote("Only tests storage on local client") - oldHOME, hasHOME := os.LookupEnv("HOME") + configPath := filepath.Join(podmanTest.TempDir, ".config", "containers", "storage.conf") + os.Setenv("CONTAINERS_STORAGE_CONF", configPath) defer func() { - if hasHOME { - os.Setenv("HOME", oldHOME) - } else { - os.Unsetenv("HOME") - } + os.Unsetenv("CONTAINERS_STORAGE_CONF") }() - os.Setenv("HOME", podmanTest.TempDir) - configPath := filepath.Join(os.Getenv("HOME"), ".config", "containers", "storage.conf") err := os.RemoveAll(filepath.Dir(configPath)) Expect(err).To(BeNil()) err = os.MkdirAll(filepath.Dir(configPath), os.ModePerm) Expect(err).To(BeNil()) - rootlessStoragePath := `"/tmp/$HOME/$USER/$UID"` + rootlessStoragePath := `"/tmp/$HOME/$USER/$UID/storage"` driver := `"overlay"` storageOpt := `"/usr/bin/fuse-overlayfs"` storageConf := []byte(fmt.Sprintf("[storage]\ndriver=%s\nrootless_storage_path=%s\n[storage.options]\nmount_program=%s", driver, rootlessStoragePath, storageOpt)) err = ioutil.WriteFile(configPath, storageConf, os.ModePerm) Expect(err).To(BeNil()) - expect := filepath.Join("/tmp", os.Getenv("HOME"), os.Getenv("USER"), os.Getenv("UID")) + u, err := user.Current() + Expect(err).To(BeNil()) + + expect := filepath.Join("/tmp", os.Getenv("HOME"), u.Username, u.Uid, "storage") podmanPath := podmanTest.PodmanTest.PodmanBinary cmd := exec.Command(podmanPath, "info", "--format", "{{.Store.GraphRoot}}") out, err := cmd.CombinedOutput() fmt.Println(string(out)) Expect(err).To(BeNil()) - Expect(string(out)).To(ContainSubstring(expect)) + Expect(string(out)).To(Equal(expect)) }) }) diff --git a/troubleshooting.md b/troubleshooting.md index 4b0f2e1e4..c42afb642 100644 --- a/troubleshooting.md +++ b/troubleshooting.md @@ -644,3 +644,39 @@ $ podman run --read-only --rootfs /path/to/rootfs .... Another option would be to create an overlay file system on the directory as a lower and then then allow podman to create the files on the upper. + +### 26) Running containers with CPU limits fails with a permissions error + +On some systemd-based systems, non-root users do not have CPU limit delegation +permissions. This causes setting CPU limits to fail. + +#### Symptom + +Running a container with a CPU limit options such as `--cpus`, `--cpu-period`, +or `--cpu-quota` will fail with an error similar to the following: + + Error: opening file `cpu.max` for writing: Permission denied: OCI runtime permission denied error + +This means that CPU limit delegation is not enabled for the current user. + +#### Solution + +You can verify whether CPU limit delegation is enabled by running the following command: + + cat "/sys/fs/cgroup/user.slice/user-$(id -u).slice/user@$(id -u).service/cgroup.controllers" + +Example output might be: + + memory pids + +In the above example, `cpu` is not listed, which means the curent user does +not have permission to set CPU limits. + +If you want to enable CPU limit delegation for all users, you can create the +file `/etc/systemd/system/user@.service.d/delegate.conf` with the contents: + + [Service] + Delegate=memory pids cpu io + +After logging out and loggin back in, you should have permission to set CPU +limits. diff --git a/vendor/github.com/containers/common/pkg/config/config_local.go b/vendor/github.com/containers/common/pkg/config/config_local.go index 8a27c9626..21dab043f 100644 --- a/vendor/github.com/containers/common/pkg/config/config_local.go +++ b/vendor/github.com/containers/common/pkg/config/config_local.go @@ -79,7 +79,7 @@ func (c *ContainersConfig) validateUlimits() error { } func (c *ContainersConfig) validateTZ() error { - if c.TZ == "local" { + if c.TZ == "local" || c.TZ == "" { return nil } diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go index 4f2443e2f..5f8f4999f 100644 --- a/vendor/github.com/containers/common/pkg/config/default.go +++ b/vendor/github.com/containers/common/pkg/config/default.go @@ -224,14 +224,12 @@ func defaultConfigFromMemory() (*EngineConfig, error) { c.EventsLogFilePath = filepath.Join(c.TmpDir, "events", "events.log") - var storeOpts storage.StoreOptions if path, ok := os.LookupEnv("CONTAINERS_STORAGE_CONF"); ok { - storage.ReloadConfigurationFile(path, &storeOpts) - } else { - storeOpts, err = storage.DefaultStoreOptions(unshare.IsRootless(), unshare.GetRootlessUID()) - if err != nil { - return nil, err - } + storage.SetDefaultConfigFilePath(path) + } + storeOpts, err := storage.DefaultStoreOptions(unshare.IsRootless(), unshare.GetRootlessUID()) + if err != nil { + return nil, err } if storeOpts.GraphRoot == "" { diff --git a/vendor/github.com/containers/common/pkg/report/template.go b/vendor/github.com/containers/common/pkg/report/template.go index 07f9634a6..551fbb3cf 100644 --- a/vendor/github.com/containers/common/pkg/report/template.go +++ b/vendor/github.com/containers/common/pkg/report/template.go @@ -44,7 +44,6 @@ func NormalizeFormat(format string) string { if !strings.HasSuffix(f, "\n") { f += "\n" } - return f } @@ -97,6 +96,8 @@ func (t *Template) Parse(text string) (*Template, error) { if strings.HasPrefix(text, "table ") { t.isTable = true text = "{{range .}}" + NormalizeFormat(text) + "{{end}}" + } else { + text = NormalizeFormat(text) } tt, err := t.Template.Parse(text) diff --git a/vendor/github.com/containers/common/pkg/seccomp/default_linux.go b/vendor/github.com/containers/common/pkg/seccomp/default_linux.go index def8019a0..ddc25ac67 100644 --- a/vendor/github.com/containers/common/pkg/seccomp/default_linux.go +++ b/vendor/github.com/containers/common/pkg/seccomp/default_linux.go @@ -66,9 +66,13 @@ func DefaultProfile() *Seccomp { "chown", "chown32", "clock_adjtime", + "clock_adjtime64", "clock_getres", + "clock_getres_time64", "clock_gettime", + "clock_gettime64", "clock_nanosleep", + "clock_nanosleep_time64", "clone", "close", "connect", @@ -226,12 +230,14 @@ func DefaultProfile() *Seccomp { "pivot_root", "poll", "ppoll", + "ppoll_time64", "prctl", "pread64", "preadv", "preadv2", "prlimit64", "pselect6", + "pselect6_time64", "pwrite64", "pwritev", "pwritev2", @@ -343,10 +349,13 @@ func DefaultProfile() *Seccomp { "timer_delete", "timer_getoverrun", "timer_gettime", + "timer_gettime64", "timer_settime", "timerfd_create", "timerfd_gettime", + "timerfd_gettime64", "timerfd_settime", + "timerfd_settime64", "times", "tkill", "truncate", @@ -361,6 +370,7 @@ func DefaultProfile() *Seccomp { "unshare", "utime", "utimensat", + "utimensat_time64", "utimes", "vfork", "vmsplice", @@ -642,6 +652,7 @@ func DefaultProfile() *Seccomp { "settimeofday", "stime", "clock_settime", + "clock_settime64", }, Action: ActAllow, Args: []*Arg{}, diff --git a/vendor/github.com/containers/common/pkg/seccomp/seccomp.json b/vendor/github.com/containers/common/pkg/seccomp/seccomp.json index f58b2ae64..bb5956418 100644 --- a/vendor/github.com/containers/common/pkg/seccomp/seccomp.json +++ b/vendor/github.com/containers/common/pkg/seccomp/seccomp.json @@ -68,9 +68,13 @@ "chown", "chown32", "clock_adjtime", + "clock_adjtime64", "clock_getres", + "clock_getres_time64", "clock_gettime", + "clock_gettime64", "clock_nanosleep", + "clock_nanosleep_time64", "clone", "close", "connect", @@ -228,12 +232,14 @@ "pivot_root", "poll", "ppoll", + "ppoll_time64", "prctl", "pread64", "preadv", "preadv2", "prlimit64", "pselect6", + "pselect6_time64", "pwrite64", "pwritev", "pwritev2", @@ -345,10 +351,13 @@ "timer_delete", "timer_getoverrun", "timer_gettime", + "timer_gettime64", "timer_settime", "timerfd_create", "timerfd_gettime", + "timerfd_gettime64", "timerfd_settime", + "timerfd_settime64", "times", "tkill", "truncate", @@ -363,6 +372,7 @@ "unshare", "utime", "utimensat", + "utimensat_time64", "utimes", "vfork", "vmsplice", @@ -749,7 +759,8 @@ "names": [ "settimeofday", "stime", - "clock_settime" + "clock_settime", + "clock_settime64" ], "action": "SCMP_ACT_ALLOW", "args": [], diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go index d5d659434..8e497e7fa 100644 --- a/vendor/github.com/containers/common/version/version.go +++ b/vendor/github.com/containers/common/version/version.go @@ -1,4 +1,4 @@ package version // Version is the version of the build. -const Version = "0.26.0" +const Version = "0.26.3" diff --git a/vendor/github.com/containers/image/v5/copy/copy.go b/vendor/github.com/containers/image/v5/copy/copy.go index 873bdc67f..d8e3fa106 100644 --- a/vendor/github.com/containers/image/v5/copy/copy.go +++ b/vendor/github.com/containers/image/v5/copy/copy.go @@ -121,8 +121,6 @@ type imageCopier struct { diffIDsAreNeeded bool canModifyManifest bool canSubstituteBlobs bool - ociDecryptConfig *encconfig.DecryptConfig - ociEncryptConfig *encconfig.EncryptConfig ociEncryptLayers *[]int } @@ -259,7 +257,9 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, // FIXME? The cache is used for sources and destinations equally, but we only have a SourceCtx and DestinationCtx. // For now, use DestinationCtx (because blob reuse changes the behavior of the destination side more); eventually // we might want to add a separate CommonCtx — or would that be too confusing? - blobInfoCache: blobinfocache.DefaultCache(options.DestinationCtx), + blobInfoCache: blobinfocache.DefaultCache(options.DestinationCtx), + ociDecryptConfig: options.OciDecryptConfig, + ociEncryptConfig: options.OciEncryptConfig, } // Default to using gzip compression unless specified otherwise. if options.DestinationCtx == nil || options.DestinationCtx.CompressionFormat == nil { @@ -605,8 +605,6 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli src: src, // diffIDsAreNeeded is computed later canModifyManifest: len(sigs) == 0 && !destIsDigestedReference, - ociDecryptConfig: options.OciDecryptConfig, - ociEncryptConfig: options.OciEncryptConfig, ociEncryptLayers: options.OciEncryptLayers, } // Ensure _this_ copy sees exactly the intended data when either processing a signed image or signing it. @@ -621,7 +619,7 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli return nil, "", "", err } - destRequiresOciEncryption := (isEncrypted(src) && ic.ociDecryptConfig != nil) || options.OciEncryptLayers != nil + destRequiresOciEncryption := (isEncrypted(src) && ic.c.ociDecryptConfig != nil) || options.OciEncryptLayers != nil // We compute preferredManifestMIMEType only to show it in error messages. // Without having to add this context in an error message, we would be happy enough to know only that no conversion is needed. @@ -633,7 +631,7 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli // If src.UpdatedImageNeedsLayerDiffIDs(ic.manifestUpdates) will be true, it needs to be true by the time we get here. ic.diffIDsAreNeeded = src.UpdatedImageNeedsLayerDiffIDs(*ic.manifestUpdates) // If encrypted and decryption keys provided, we should try to decrypt - ic.diffIDsAreNeeded = ic.diffIDsAreNeeded || (isEncrypted(src) && ic.ociDecryptConfig != nil) || ic.ociEncryptConfig != nil + ic.diffIDsAreNeeded = ic.diffIDsAreNeeded || (isEncrypted(src) && ic.c.ociDecryptConfig != nil) || ic.c.ociEncryptConfig != nil if err := ic.copyLayers(ctx); err != nil { return nil, "", "", err @@ -1048,7 +1046,7 @@ type diffIDResult struct { func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, toEncrypt bool, pool *mpb.Progress) (types.BlobInfo, digest.Digest, error) { cachedDiffID := ic.c.blobInfoCache.UncompressedDigest(srcInfo.Digest) // May be "" // Diffs are needed if we are encrypting an image or trying to decrypt an image - diffIDIsNeeded := ic.diffIDsAreNeeded && cachedDiffID == "" || toEncrypt || (isOciEncrypted(srcInfo.MediaType) && ic.ociDecryptConfig != nil) + diffIDIsNeeded := ic.diffIDsAreNeeded && cachedDiffID == "" || toEncrypt || (isOciEncrypted(srcInfo.MediaType) && ic.c.ociDecryptConfig != nil) // If we already have the blob, and we don't need to compute the diffID, then we don't need to read it from the source. if !diffIDIsNeeded { @@ -1136,8 +1134,6 @@ func (ic *imageCopier) copyLayerFromStream(ctx context.Context, srcStream io.Rea return pipeWriter } } - ic.c.ociDecryptConfig = ic.ociDecryptConfig - ic.c.ociEncryptConfig = ic.ociEncryptConfig blobInfo, err := ic.c.copyBlobFromStream(ctx, srcStream, srcInfo, getDiffIDRecorder, ic.canModifyManifest, false, toEncrypt, bar) // Sets err to nil on success return blobInfo, diffIDChan, err diff --git a/vendor/github.com/containers/image/v5/directory/directory_dest.go b/vendor/github.com/containers/image/v5/directory/directory_dest.go index d70b6c07f..2b81c8360 100644 --- a/vendor/github.com/containers/image/v5/directory/directory_dest.go +++ b/vendor/github.com/containers/image/v5/directory/directory_dest.go @@ -194,7 +194,7 @@ func (d *dirImageDestination) PutBlob(ctx context.Context, stream io.Reader, inp // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. // If canSubstitute, TryReusingBlob can use an equivalent equivalent of the desired blob; in that case the returned info may not match the input. -// If the blob has been succesfully reused, returns (true, info, nil); info must contain at least a digest and size. +// If the blob has been successfully reused, returns (true, info, nil); info must contain at least a digest and size. // If the transport can not reuse the requested blob, TryReusingBlob returns (false, {}, nil); it returns a non-nil error only on an unexpected failure. // May use and/or update cache. func (d *dirImageDestination) TryReusingBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache, canSubstitute bool) (bool, types.BlobInfo, error) { diff --git a/vendor/github.com/containers/image/v5/docker/archive/transport.go b/vendor/github.com/containers/image/v5/docker/archive/transport.go index ff9e27482..9a48cb46c 100644 --- a/vendor/github.com/containers/image/v5/docker/archive/transport.go +++ b/vendor/github.com/containers/image/v5/docker/archive/transport.go @@ -50,7 +50,7 @@ type archiveReference struct { // Must not be set if ref is set. sourceIndex int // If not nil, must have been created from path (but archiveReader.path may point at a temporary - // file, not necesarily path precisely). + // file, not necessarily path precisely). archiveReader *tarfile.Reader // If not nil, must have been created for path archiveWriter *tarfile.Writer 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 e4308def1..797be45a2 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_client.go +++ b/vendor/github.com/containers/image/v5/docker/docker_client.go @@ -209,6 +209,7 @@ func dockerCertDir(sys *types.SystemContext, hostPort string) (string, error) { // newDockerClientFromRef returns a new dockerClient instance for refHostname (a host a specified in the Docker image reference, not canonicalized to dockerRegistry) // “write” specifies whether the client will be used for "write" access (in particular passed to lookaside.go:toplevelFromSection) +// signatureBase is always set in the return value func newDockerClientFromRef(sys *types.SystemContext, ref dockerReference, write bool, actions string) (*dockerClient, error) { registry := reference.Domain(ref.ref) auth, err := config.GetCredentials(sys, registry) @@ -216,7 +217,7 @@ func newDockerClientFromRef(sys *types.SystemContext, ref dockerReference, write return nil, errors.Wrapf(err, "error getting username and password") } - sigBase, err := configuredSignatureStorageBase(sys, ref, write) + sigBase, err := SignatureStorageBaseURL(sys, ref, write) if err != nil { return nil, err } diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go index 576dec495..ac63ac121 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go @@ -78,12 +78,12 @@ func (d *dockerImageDestination) SupportsSignatures(ctx context.Context) error { return err } switch { - case d.c.signatureBase != nil: - return nil case d.c.supportsSignatures: return nil + case d.c.signatureBase != nil: + return nil default: - return errors.Errorf("X-Registry-Supports-Signatures extension not supported, and lookaside is not configured") + return errors.Errorf("Internal error: X-Registry-Supports-Signatures extension not supported, and lookaside should not be empty configuration") } } @@ -284,7 +284,7 @@ func (d *dockerImageDestination) mountBlob(ctx context.Context, srcRepo referenc // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. // If canSubstitute, TryReusingBlob can use an equivalent equivalent of the desired blob; in that case the returned info may not match the input. -// If the blob has been succesfully reused, returns (true, info, nil); info must contain at least a digest and size. +// If the blob has been successfully reused, returns (true, info, nil); info must contain at least a digest and size. // If the transport can not reuse the requested blob, TryReusingBlob returns (false, {}, nil); it returns a non-nil error only on an unexpected failure. // May use and/or update cache. func (d *dockerImageDestination) TryReusingBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache, canSubstitute bool) (bool, types.BlobInfo, error) { @@ -335,7 +335,7 @@ func (d *dockerImageDestination) TryReusingBlob(ctx context.Context, info types. // On success we avoid the actual costly upload; so, in a sense, the success case is "free", but failures are always costly. // Even worse, docker/distribution does not actually reasonably implement canceling uploads // (it would require a "delete" action in the token, and Quay does not give that to anyone, so we can't ask); - // so, be a nice client and don't create unnecesary upload sessions on the server. + // so, be a nice client and don't create unnecessary upload sessions on the server. exists, size, err := d.blobExists(ctx, candidateRepo, candidate.Digest, extraScope) if err != nil { logrus.Debugf("... Failed: %v", err) @@ -479,12 +479,12 @@ func (d *dockerImageDestination) PutSignatures(ctx context.Context, signatures [ return err } switch { - case d.c.signatureBase != nil: - return d.putSignaturesToLookaside(signatures, *instanceDigest) case d.c.supportsSignatures: return d.putSignaturesToAPIExtension(ctx, signatures, *instanceDigest) + case d.c.signatureBase != nil: + return d.putSignaturesToLookaside(signatures, *instanceDigest) default: - return errors.Errorf("X-Registry-Supports-Signatures extension not supported, and lookaside is not configured") + return errors.Errorf("Internal error: X-Registry-Supports-Signatures extension not supported, and lookaside should not be empty configuration") } } @@ -502,9 +502,6 @@ func (d *dockerImageDestination) putSignaturesToLookaside(signatures [][]byte, m // NOTE: Keep this in sync with docs/signature-protocols.md! for i, signature := range signatures { url := signatureStorageURL(d.c.signatureBase, manifestDigest, i) - if url == nil { - return errors.Errorf("Internal error: signatureStorageURL with non-nil base returned nil") - } err := d.putOneSignature(url, signature) if err != nil { return err @@ -517,9 +514,6 @@ func (d *dockerImageDestination) putSignaturesToLookaside(signatures [][]byte, m // is sufficient. for i := len(signatures); ; i++ { url := signatureStorageURL(d.c.signatureBase, manifestDigest, i) - if url == nil { - return errors.Errorf("Internal error: signatureStorageURL with non-nil base returned nil") - } missing, err := d.c.deleteOneSignature(url) if err != nil { return err diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_src.go b/vendor/github.com/containers/image/v5/docker/docker_image_src.go index 4d2a9ed6c..70ca7661e 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image_src.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image_src.go @@ -53,7 +53,7 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerRef // contain the image, it will be used for all future pull actions. Always try the // non-mirror original location last; this both transparently handles the case // of no mirrors configured, and ensures we return the error encountered when - // acessing the upstream location if all endpoints fail. + // accessing the upstream location if all endpoints fail. pullSources, err := registry.PullSourcesFromReference(ref.ref) if err != nil { return nil, err @@ -238,6 +238,9 @@ func (s *dockerImageSource) getExternalBlob(ctx context.Context, urls []string) return nil, 0, errors.New("internal error: getExternalBlob called with no URLs") } for _, url := range urls { + // NOTE: we must not authenticate on additional URLs as those + // can be abused to leak credentials or tokens. Please + // refer to CVE-2020-15157 for more information. resp, err = s.c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, noAuth, nil) if err == nil { if resp.StatusCode != http.StatusOK { @@ -297,12 +300,12 @@ func (s *dockerImageSource) GetSignatures(ctx context.Context, instanceDigest *d return nil, err } switch { - case s.c.signatureBase != nil: - return s.getSignaturesFromLookaside(ctx, instanceDigest) case s.c.supportsSignatures: return s.getSignaturesFromAPIExtension(ctx, instanceDigest) + case s.c.signatureBase != nil: + return s.getSignaturesFromLookaside(ctx, instanceDigest) default: - return [][]byte{}, nil + return nil, errors.Errorf("Internal error: X-Registry-Supports-Signatures extension not supported, and lookaside should not be empty configuration") } } @@ -336,9 +339,6 @@ func (s *dockerImageSource) getSignaturesFromLookaside(ctx context.Context, inst signatures := [][]byte{} for i := 0; ; i++ { url := signatureStorageURL(s.c.signatureBase, manifestDigest, i) - if url == nil { - return nil, errors.Errorf("Internal error: signatureStorageURL with non-nil base returned nil") - } signature, missing, err := s.getOneSignature(ctx, url) if err != nil { return nil, err @@ -474,24 +474,19 @@ func deleteImage(ctx context.Context, sys *types.SystemContext, ref dockerRefere return errors.Errorf("Failed to delete %v: %s (%v)", deletePath, string(body), delete.Status) } - if c.signatureBase != nil { - manifestDigest, err := manifest.Digest(manifestBody) + manifestDigest, err := manifest.Digest(manifestBody) + if err != nil { + return err + } + + for i := 0; ; i++ { + url := signatureStorageURL(c.signatureBase, manifestDigest, i) + missing, err := c.deleteOneSignature(url) if err != nil { return err } - - for i := 0; ; i++ { - url := signatureStorageURL(c.signatureBase, manifestDigest, i) - if url == nil { - return errors.Errorf("Internal error: signatureStorageURL with non-nil base returned nil") - } - missing, err := c.deleteOneSignature(url) - if err != nil { - return err - } - if missing { - break - } + if missing { + break } } diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go index 8c38094cf..41d2c5e81 100644 --- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go +++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go @@ -94,7 +94,7 @@ func (d *Destination) HasThreadSafePutBlob() bool { // If stream.Read() at any time, ESPECIALLY at end of input, returns an error, PutBlob MUST 1) fail, and 2) delete any data stored so far. func (d *Destination) PutBlob(ctx context.Context, stream io.Reader, inputInfo types.BlobInfo, cache types.BlobInfoCache, isConfig bool) (types.BlobInfo, error) { // Ouch, we need to stream the blob into a temporary file just to determine the size. - // When the layer is decompressed, we also have to generate the digest on uncompressed datas. + // When the layer is decompressed, we also have to generate the digest on uncompressed data. if inputInfo.Size == -1 || inputInfo.Digest.String() == "" { logrus.Debugf("docker tarfile: input with unknown size, streaming to disk first ...") streamCopy, err := ioutil.TempFile(tmpdir.TemporaryDirectoryForBigFiles(d.sysCtx), "docker-tarfile-blob") @@ -159,7 +159,7 @@ func (d *Destination) PutBlob(ctx context.Context, stream io.Reader, inputInfo t // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. // If canSubstitute, TryReusingBlob can use an equivalent equivalent of the desired blob; in that case the returned info may not match the input. -// If the blob has been succesfully reused, returns (true, info, nil); info must contain at least a digest and size. +// If the blob has been successfully reused, returns (true, info, nil); info must contain at least a digest and size. // If the transport can not reuse the requested blob, TryReusingBlob returns (false, {}, nil); it returns a non-nil error only on an unexpected failure. // May use and/or update cache. func (d *Destination) TryReusingBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache, canSubstitute bool) (bool, types.BlobInfo, error) { diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go index 0db9a72b5..bd65ef844 100644 --- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go +++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/src.go @@ -287,7 +287,7 @@ func (s *Source) GetBlob(ctx context.Context, info types.BlobInfo, cache types.B // In particular, because the v2s2 manifest being generated uses // DiffIDs, any caller of GetBlob is going to be asking for DiffIDs of // layers not their _actual_ digest. The result is that copy/... will - // be verifing a "digest" which is not the actual layer's digest (but + // be verifying a "digest" which is not the actual layer's digest (but // is instead the DiffID). uncompressedStream, _, err := compression.AutoDecompress(underlyingStream) diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go index fd2c461d0..e0683b3cd 100644 --- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go +++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go @@ -48,7 +48,7 @@ func NewWriter(dest io.Writer) *Writer { } // lock does some sanity checks and locks the Writer. -// If this function suceeds, the caller must call w.unlock. +// If this function succeeds, the caller must call w.unlock. // Do not use Writer.mutex directly. func (w *Writer) lock() error { w.mutex.Lock() @@ -67,7 +67,7 @@ func (w *Writer) unlock() { // tryReusingBlobLocked checks whether the transport already contains, a blob, and if so, returns its metadata. // info.Digest must not be empty. -// If the blob has been succesfully reused, returns (true, info, nil); info must contain at least a digest and size. +// If the blob has been successfully reused, returns (true, info, nil); info must contain at least a digest and size. // If the transport can not reuse the requested blob, tryReusingBlob returns (false, {}, nil); it returns a non-nil error only on an unexpected failure. // The caller must have locked the Writer. func (w *Writer) tryReusingBlobLocked(info types.BlobInfo) (bool, types.BlobInfo, error) { diff --git a/vendor/github.com/containers/image/v5/docker/lookaside.go b/vendor/github.com/containers/image/v5/docker/lookaside.go index 6931fd07b..06d616d01 100644 --- a/vendor/github.com/containers/image/v5/docker/lookaside.go +++ b/vendor/github.com/containers/image/v5/docker/lookaside.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/containers/image/v5/docker/reference" + "github.com/containers/image/v5/internal/rootless" "github.com/containers/image/v5/types" "github.com/containers/storage/pkg/homedir" "github.com/ghodss/yaml" @@ -30,6 +31,12 @@ const builtinRegistriesDirPath = "/etc/containers/registries.d" // userRegistriesDirPath is the path to the per user registries.d. var userRegistriesDir = filepath.FromSlash(".config/containers/registries.d") +// defaultUserDockerDir is the default sigstore directory for unprivileged user +var defaultUserDockerDir = filepath.FromSlash(".local/share/containers/sigstore") + +// defaultDockerDir is the default sigstore directory for root +var defaultDockerDir = "/var/lib/containers/sigstore" + // registryConfiguration is one of the files in registriesDirPath configuring lookaside locations, or the result of merging them all. // NOTE: Keep this in sync with docs/registries.d.md! type registryConfiguration struct { @@ -45,11 +52,18 @@ type registryNamespace struct { } // signatureStorageBase is an "opaque" type representing a lookaside Docker signature storage. -// Users outside of this file should use configuredSignatureStorageBase and signatureStorageURL below. -type signatureStorageBase *url.URL // The only documented value is nil, meaning storage is not supported. - -// configuredSignatureStorageBase reads configuration to find an appropriate signature storage URL for ref, for write access if “write”. -func configuredSignatureStorageBase(sys *types.SystemContext, ref dockerReference, write bool) (signatureStorageBase, error) { +// Users outside of this file should use SignatureStorageBaseURL and signatureStorageURL below. +type signatureStorageBase *url.URL + +// SignatureStorageBaseURL reads configuration to find an appropriate signature storage URL for ref, for write access if “write”. +// the usage of the BaseURL is defined under docker/distribution registries—separate storage of docs/signature-protocols.md +// Warning: This function only exposes configuration in registries.d; +// just because this function returns an URL does not mean that the URL will be used by c/image/docker (e.g. if the registry natively supports X-R-S-S). +func SignatureStorageBaseURL(sys *types.SystemContext, ref types.ImageReference, write bool) (*url.URL, error) { + dr, ok := ref.(dockerReference) + if !ok { + return nil, errors.Errorf("ref must be a dockerReference") + } // FIXME? Loading and parsing the config could be cached across calls. dirPath := registriesDirPath(sys) logrus.Debugf(`Using registries.d directory %s for sigstore configuration`, dirPath) @@ -58,20 +72,23 @@ func configuredSignatureStorageBase(sys *types.SystemContext, ref dockerReferenc return nil, err } - topLevel := config.signatureTopLevel(ref, write) - if topLevel == "" { - return nil, nil - } - - url, err := url.Parse(topLevel) - if err != nil { - return nil, errors.Wrapf(err, "Invalid signature storage URL %s", topLevel) + topLevel := config.signatureTopLevel(dr, write) + var url *url.URL + if topLevel != "" { + url, err = url.Parse(topLevel) + if err != nil { + return nil, errors.Wrapf(err, "Invalid signature storage URL %s", topLevel) + } + } else { + // returns default directory if no sigstore specified in configuration file + url = builtinDefaultSignatureStorageDir(rootless.GetRootlessEUID()) + logrus.Debugf(" No signature storage configuration found for %s, using built-in default %s", dr.PolicyConfigurationIdentity(), url.String()) } // NOTE: Keep this in sync with docs/signature-protocols.md! // FIXME? Restrict to explicitly supported schemes? - repo := reference.Path(ref.ref) // Note that this is without a tag or digest. - if path.Clean(repo) != repo { // Coverage: This should not be reachable because /./ and /../ components are not valid in docker references - return nil, errors.Errorf("Unexpected path elements in Docker reference %s for signature storage", ref.ref.String()) + repo := reference.Path(dr.ref) // Note that this is without a tag or digest. + if path.Clean(repo) != repo { // Coverage: This should not be reachable because /./ and /../ components are not valid in docker references + return nil, errors.Errorf("Unexpected path elements in Docker reference %s for signature storage", dr.ref.String()) } url.Path = url.Path + "/" + repo return url, nil @@ -93,6 +110,14 @@ func registriesDirPath(sys *types.SystemContext) string { return systemRegistriesDirPath } +// builtinDefaultSignatureStorageDir returns default signature storage URL as per euid +func builtinDefaultSignatureStorageDir(euid int) *url.URL { + if euid != 0 { + return &url.URL{Scheme: "file", Path: filepath.Join(homedir.Get(), defaultUserDockerDir)} + } + return &url.URL{Scheme: "file", Path: defaultDockerDir} +} + // loadAndMergeConfig loads configuration files in dirPath func loadAndMergeConfig(dirPath string) (*registryConfiguration, error) { mergedConfig := registryConfiguration{Docker: map[string]registryNamespace{}} @@ -149,7 +174,7 @@ func loadAndMergeConfig(dirPath string) (*registryConfiguration, error) { } // config.signatureTopLevel returns an URL string configured in config for ref, for write access if “write”. -// (the top level of the storage, namespaced by repo.FullName etc.), or "" if no signature storage should be used. +// (the top level of the storage, namespaced by repo.FullName etc.), or "" if nothing has been configured. func (config *registryConfiguration) signatureTopLevel(ref dockerReference, write bool) string { if config.Docker != nil { // Look for a full match. @@ -178,7 +203,6 @@ func (config *registryConfiguration) signatureTopLevel(ref dockerReference, writ return url } } - logrus.Debugf(" No signature storage configuration found for %s", ref.PolicyConfigurationIdentity()) return "" } @@ -196,13 +220,10 @@ func (ns registryNamespace) signatureTopLevel(write bool) string { return "" } -// signatureStorageURL returns an URL usable for acessing signature index in base with known manifestDigest, or nil if not applicable. -// Returns nil iff base == nil. +// signatureStorageURL returns an URL usable for accessing signature index in base with known manifestDigest. +// base is not nil from the caller // NOTE: Keep this in sync with docs/signature-protocols.md! func signatureStorageURL(base signatureStorageBase, manifestDigest digest.Digest, index int) *url.URL { - if base == nil { - return nil - } url := *base url.Path = fmt.Sprintf("%s@%s=%s/signature-%d", url.Path, manifestDigest.Algorithm(), manifestDigest.Hex(), index+1) return &url diff --git a/vendor/github.com/containers/image/v5/docker/tarfile/dest.go b/vendor/github.com/containers/image/v5/docker/tarfile/dest.go index af1690683..e16829d96 100644 --- a/vendor/github.com/containers/image/v5/docker/tarfile/dest.go +++ b/vendor/github.com/containers/image/v5/docker/tarfile/dest.go @@ -86,7 +86,7 @@ func (d *Destination) PutBlob(ctx context.Context, stream io.Reader, inputInfo t // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. // If canSubstitute, TryReusingBlob can use an equivalent equivalent of the desired blob; in that case the returned info may not match the input. -// If the blob has been succesfully reused, returns (true, info, nil); info must contain at least a digest and size. +// If the blob has been successfully reused, returns (true, info, nil); info must contain at least a digest and size. // If the transport can not reuse the requested blob, TryReusingBlob returns (false, {}, nil); it returns a non-nil error only on an unexpected failure. // May use and/or update cache. func (d *Destination) TryReusingBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache, canSubstitute bool) (bool, types.BlobInfo, error) { diff --git a/vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go b/vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go index c4d42f3eb..5ea542bcf 100644 --- a/vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go +++ b/vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go @@ -131,7 +131,7 @@ var baseVariants = map[string]string{ "arm64": "v8", } -// WantedPlatforms returns all compatible platforms with the platform specifics possibly overriden by user, +// WantedPlatforms returns all compatible platforms with the platform specifics possibly overridden by user, // the most compatible platform is first. // If some option (arch, os, variant) is not present, a value from current platform is detected. func WantedPlatforms(ctx *types.SystemContext) ([]imgspecv1.Platform, error) { diff --git a/vendor/github.com/containers/image/v5/internal/rootless/rootless.go b/vendor/github.com/containers/image/v5/internal/rootless/rootless.go new file mode 100644 index 000000000..80623bfbc --- /dev/null +++ b/vendor/github.com/containers/image/v5/internal/rootless/rootless.go @@ -0,0 +1,25 @@ +package rootless + +import ( + "os" + "strconv" +) + +// GetRootlessEUID returns the UID of the current user (in the parent userNS, if any) +// +// Podman and similar software, in “rootless” configuration, when run as a non-root +// user, very early switches to a user namespace, where Geteuid() == 0 (but does not +// switch to a limited mount namespace); so, code relying on Geteuid() would use +// system-wide paths in e.g. /var, when the user is actually not privileged to write to +// them, and expects state to be stored in the home directory. +// +// If Podman is setting up such a user namespace, it records the original UID in an +// environment variable, allowing us to make choices based on the actual user’s identity. +func GetRootlessEUID() int { + euidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID") + if euidEnv != "" { + euid, _ := strconv.Atoi(euidEnv) + return euid + } + return os.Geteuid() +} diff --git a/vendor/github.com/containers/image/v5/oci/archive/oci_dest.go b/vendor/github.com/containers/image/v5/oci/archive/oci_dest.go index 0509eaa83..23d471325 100644 --- a/vendor/github.com/containers/image/v5/oci/archive/oci_dest.go +++ b/vendor/github.com/containers/image/v5/oci/archive/oci_dest.go @@ -103,7 +103,7 @@ func (d *ociArchiveImageDestination) PutBlob(ctx context.Context, stream io.Read // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. // If canSubstitute, TryReusingBlob can use an equivalent equivalent of the desired blob; in that case the returned info may not match the input. -// If the blob has been succesfully reused, returns (true, info, nil); info must contain at least a digest and size. +// If the blob has been successfully reused, returns (true, info, nil); info must contain at least a digest and size. // If the transport can not reuse the requested blob, TryReusingBlob returns (false, {}, nil); it returns a non-nil error only on an unexpected failure. // May use and/or update cache. func (d *ociArchiveImageDestination) TryReusingBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache, canSubstitute bool) (bool, types.BlobInfo, error) { diff --git a/vendor/github.com/containers/image/v5/oci/layout/oci_dest.go b/vendor/github.com/containers/image/v5/oci/layout/oci_dest.go index 48a32315b..0c88e1ef0 100644 --- a/vendor/github.com/containers/image/v5/oci/layout/oci_dest.go +++ b/vendor/github.com/containers/image/v5/oci/layout/oci_dest.go @@ -186,7 +186,7 @@ func (d *ociImageDestination) PutBlob(ctx context.Context, stream io.Reader, inp // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. // If canSubstitute, TryReusingBlob can use an equivalent equivalent of the desired blob; in that case the returned info may not match the input. -// If the blob has been succesfully reused, returns (true, info, nil); info must contain at least a digest and size. +// If the blob has been successfully reused, returns (true, info, nil); info must contain at least a digest and size. // If the transport can not reuse the requested blob, TryReusingBlob returns (false, {}, nil); it returns a non-nil error only on an unexpected failure. // May use and/or update cache. func (d *ociImageDestination) TryReusingBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache, canSubstitute bool) (bool, types.BlobInfo, error) { diff --git a/vendor/github.com/containers/image/v5/openshift/openshift-copies.go b/vendor/github.com/containers/image/v5/openshift/openshift-copies.go index 4b081bb29..d87f748e6 100644 --- a/vendor/github.com/containers/image/v5/openshift/openshift-copies.go +++ b/vendor/github.com/containers/image/v5/openshift/openshift-copies.go @@ -251,7 +251,7 @@ func getServerIdentificationPartialConfig(configAuthInfo clientcmdAuthInfo, conf // getUserIdentificationPartialConfig is a modified copy of k8s.io/kubernetes/pkg/client/unversioned/clientcmd.getUserIdentificationPartialConfig. // clientauth.Info object contain both user identification and server identification. We want different precedence orders for // both, so we have to split the objects and merge them separately -// we want this order of precedence for user identifcation +// we want this order of precedence for user identification // 1. configAuthInfo minus auth-path (the final result of command line flags and merged .kubeconfig files) // 2. configAuthInfo.auth-path (this file can contain information that conflicts with #1, and we want #1 to win the priority) // 3. if there is not enough information to idenfity the user, load try the ~/.kubernetes_auth file diff --git a/vendor/github.com/containers/image/v5/openshift/openshift.go b/vendor/github.com/containers/image/v5/openshift/openshift.go index 28bfc456d..c4c84dd54 100644 --- a/vendor/github.com/containers/image/v5/openshift/openshift.go +++ b/vendor/github.com/containers/image/v5/openshift/openshift.go @@ -410,7 +410,7 @@ func (d *openshiftImageDestination) PutBlob(ctx context.Context, stream io.Reade // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. // If canSubstitute, TryReusingBlob can use an equivalent equivalent of the desired blob; in that case the returned info may not match the input. -// If the blob has been succesfully reused, returns (true, info, nil); info must contain at least a digest and size. +// If the blob has been successfully reused, returns (true, info, nil); info must contain at least a digest and size. // If the transport can not reuse the requested blob, TryReusingBlob returns (false, {}, nil); it returns a non-nil error only on an unexpected failure. // May use and/or update cache. func (d *openshiftImageDestination) TryReusingBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache, canSubstitute bool) (bool, types.BlobInfo, error) { diff --git a/vendor/github.com/containers/image/v5/ostree/ostree_dest.go b/vendor/github.com/containers/image/v5/ostree/ostree_dest.go index 115097055..b518122e2 100644 --- a/vendor/github.com/containers/image/v5/ostree/ostree_dest.go +++ b/vendor/github.com/containers/image/v5/ostree/ostree_dest.go @@ -339,7 +339,7 @@ func (d *ostreeImageDestination) importConfig(repo *otbuiltin.Repo, blob *blobTo // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. // If canSubstitute, TryReusingBlob can use an equivalent equivalent of the desired blob; in that case the returned info may not match the input. -// If the blob has been succesfully reused, returns (true, info, nil); info must contain at least a digest and size. +// If the blob has been successfully reused, returns (true, info, nil); info must contain at least a digest and size. // If the transport can not reuse the requested blob, TryReusingBlob returns (false, {}, nil); it returns a non-nil error only on an unexpected failure. // May use and/or update cache. func (d *ostreeImageDestination) TryReusingBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache, canSubstitute bool) (bool, types.BlobInfo, error) { diff --git a/vendor/github.com/containers/image/v5/pkg/blobinfocache/default.go b/vendor/github.com/containers/image/v5/pkg/blobinfocache/default.go index 952bcf5a1..01abb8d1e 100644 --- a/vendor/github.com/containers/image/v5/pkg/blobinfocache/default.go +++ b/vendor/github.com/containers/image/v5/pkg/blobinfocache/default.go @@ -4,8 +4,8 @@ import ( "fmt" "os" "path/filepath" - "strconv" + "github.com/containers/image/v5/internal/rootless" "github.com/containers/image/v5/pkg/blobinfocache/boltdb" "github.com/containers/image/v5/pkg/blobinfocache/memory" "github.com/containers/image/v5/types" @@ -48,18 +48,9 @@ func blobInfoCacheDir(sys *types.SystemContext, euid int) (string, error) { return filepath.Join(dataDir, "containers", "cache"), nil } -func getRootlessUID() int { - uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID") - if uidEnv != "" { - u, _ := strconv.Atoi(uidEnv) - return u - } - return os.Geteuid() -} - // DefaultCache returns the default BlobInfoCache implementation appropriate for sys. func DefaultCache(sys *types.SystemContext) types.BlobInfoCache { - dir, err := blobInfoCacheDir(sys, getRootlessUID()) + dir, err := blobInfoCacheDir(sys, rootless.GetRootlessEUID()) if err != nil { logrus.Debugf("Error determining a location for %s, using a memory-only cache", blobInfoCacheFilename) return memory.New() 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 5d7598648..cf82ee861 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 @@ -35,6 +35,7 @@ type authPath struct { var ( defaultPerUIDPathFormat = filepath.FromSlash("/run/containers/%d/auth.json") + xdgConfigHomePath = filepath.FromSlash("containers/auth.json") xdgRuntimeDirPath = filepath.FromSlash("containers/auth.json") dockerHomePath = filepath.FromSlash(".docker/config.json") dockerLegacyHomePath = ".dockercfg" @@ -117,7 +118,7 @@ func GetAllCredentials(sys *types.SystemContext) (map[string]types.DockerAuthCon } } - // TODO(keyring): if we ever reenable the keyring support, we had to + // TODO(keyring): if we ever re-enable the keyring support, we had to // query all credentials from the keyring here. return authConfigs, nil @@ -136,8 +137,21 @@ func getAuthFilePaths(sys *types.SystemContext) []authPath { // Logging the error as a warning instead and moving on to pulling the image logrus.Warnf("%v: Trying to pull image in the event that it is a public image.", err) } + xdgCfgHome := os.Getenv("XDG_CONFIG_HOME") + if xdgCfgHome == "" { + xdgCfgHome = filepath.Join(homedir.Get(), ".config") + } + paths = append(paths, authPath{path: filepath.Join(xdgCfgHome, xdgConfigHomePath), legacyFormat: false}) + if dockerConfig := os.Getenv("DOCKER_CONFIG"); dockerConfig != "" { + paths = append(paths, + authPath{path: filepath.Join(dockerConfig, "config.json"), legacyFormat: false}, + ) + } else { + paths = append(paths, + authPath{path: filepath.Join(homedir.Get(), dockerHomePath), legacyFormat: false}, + ) + } paths = append(paths, - authPath{path: filepath.Join(homedir.Get(), dockerHomePath), legacyFormat: false}, authPath{path: filepath.Join(homedir.Get(), dockerLegacyHomePath), legacyFormat: true}, ) return paths @@ -245,7 +259,7 @@ func RemoveAllAuthentication(sys *types.SystemContext) error { }) } -// getPathToAuth gets the path of the auth.json file used for reading and writting credentials +// getPathToAuth gets the path of the auth.json file used for reading and writing credentials // returns the path, and a bool specifies whether the file is in legacy format func getPathToAuth(sys *types.SystemContext) (string, bool, error) { if sys != nil { diff --git a/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go b/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go index 43f2d5a85..1531d6943 100644 --- a/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go +++ b/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go @@ -63,7 +63,7 @@ func removeAllAuthFromKernelKeyring() error { // split string "type;uid;gid;perm;description" keyAttrs := strings.SplitN(keyAttr, ";", 5) if len(keyAttrs) < 5 { - return errors.Errorf("Key attributes of %d are not avaliable", k.ID()) + return errors.Errorf("Key attributes of %d are not available", k.ID()) } keyDescribe := keyAttrs[4] if strings.HasPrefix(keyDescribe, keyDescribePrefix) { diff --git a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go index 9a5712654..ea2b21575 100644 --- a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go +++ b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go @@ -363,7 +363,7 @@ type configWrapper struct { configPath string // path to system-wide registries.conf.d directory, or "" if not used configDirPath string - // path to user specificed registries.conf.d directory, or "" if not used + // path to user specified registries.conf.d directory, or "" if not used userConfigDirPath string } diff --git a/vendor/github.com/containers/image/v5/signature/mechanism.go b/vendor/github.com/containers/image/v5/signature/mechanism.go index bdf26c531..2c08c231e 100644 --- a/vendor/github.com/containers/image/v5/signature/mechanism.go +++ b/vendor/github.com/containers/image/v5/signature/mechanism.go @@ -28,8 +28,8 @@ type SigningMechanism interface { Verify(unverifiedSignature []byte) (contents []byte, keyIdentity string, err error) // UntrustedSignatureContents returns UNTRUSTED contents of the signature WITHOUT ANY VERIFICATION, // along with a short identifier of the key used for signing. - // WARNING: The short key identifier (which correponds to "Key ID" for OpenPGP keys) - // is NOT the same as a "key identity" used in other calls ot this interface, and + // WARNING: The short key identifier (which corresponds to "Key ID" for OpenPGP keys) + // is NOT the same as a "key identity" used in other calls to this interface, and // the values may have no recognizable relationship if the public key is not available. UntrustedSignatureContents(untrustedSignature []byte) (untrustedContents []byte, shortKeyIdentifier string, err error) } @@ -58,8 +58,8 @@ func NewEphemeralGPGSigningMechanism(blob []byte) (SigningMechanism, []string, e // gpgUntrustedSignatureContents returns UNTRUSTED contents of the signature WITHOUT ANY VERIFICATION, // along with a short identifier of the key used for signing. -// WARNING: The short key identifier (which correponds to "Key ID" for OpenPGP keys) -// is NOT the same as a "key identity" used in other calls ot this interface, and +// WARNING: The short key identifier (which corresponds to "Key ID" for OpenPGP keys) +// is NOT the same as a "key identity" used in other calls to this interface, and // the values may have no recognizable relationship if the public key is not available. func gpgUntrustedSignatureContents(untrustedSignature []byte) (untrustedContents []byte, shortKeyIdentifier string, err error) { // This uses the Golang-native OpenPGP implementation instead of gpgme because we are not doing any cryptography. @@ -75,7 +75,7 @@ func gpgUntrustedSignatureContents(untrustedSignature []byte) (untrustedContents // Coverage: An error during reading the body can happen only if // 1) the message is encrypted, which is not our case (and we don’t give ReadMessage the key // to decrypt the contents anyway), or - // 2) the message is signed AND we give ReadMessage a correspnding public key, which we don’t. + // 2) the message is signed AND we give ReadMessage a corresponding public key, which we don’t. return nil, "", err } diff --git a/vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go b/vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go index 277fba16b..a0afc34b4 100644 --- a/vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go +++ b/vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go @@ -167,8 +167,8 @@ func (m *gpgmeSigningMechanism) Verify(unverifiedSignature []byte) (contents []b // UntrustedSignatureContents returns UNTRUSTED contents of the signature WITHOUT ANY VERIFICATION, // along with a short identifier of the key used for signing. -// WARNING: The short key identifier (which correponds to "Key ID" for OpenPGP keys) -// is NOT the same as a "key identity" used in other calls ot this interface, and +// WARNING: The short key identifier (which corresponds to "Key ID" for OpenPGP keys) +// is NOT the same as a "key identity" used in other calls to this interface, and // the values may have no recognizable relationship if the public key is not available. func (m *gpgmeSigningMechanism) UntrustedSignatureContents(untrustedSignature []byte) (untrustedContents []byte, shortKeyIdentifier string, err error) { return gpgUntrustedSignatureContents(untrustedSignature) diff --git a/vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go b/vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go index 51f20f310..a05760284 100644 --- a/vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go +++ b/vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go @@ -151,8 +151,8 @@ func (m *openpgpSigningMechanism) Verify(unverifiedSignature []byte) (contents [ // UntrustedSignatureContents returns UNTRUSTED contents of the signature WITHOUT ANY VERIFICATION, // along with a short identifier of the key used for signing. -// WARNING: The short key identifier (which correponds to "Key ID" for OpenPGP keys) -// is NOT the same as a "key identity" used in other calls ot this interface, and +// WARNING: The short key identifier (which corresponds to "Key ID" for OpenPGP keys) +// is NOT the same as a "key identity" used in other calls to this interface, and // the values may have no recognizable relationship if the public key is not available. func (m *openpgpSigningMechanism) UntrustedSignatureContents(untrustedSignature []byte) (untrustedContents []byte, shortKeyIdentifier string, err error) { return gpgUntrustedSignatureContents(untrustedSignature) diff --git a/vendor/github.com/containers/image/v5/signature/policy_config.go b/vendor/github.com/containers/image/v5/signature/policy_config.go index 72fcf618a..a4873e9fa 100644 --- a/vendor/github.com/containers/image/v5/signature/policy_config.go +++ b/vendor/github.com/containers/image/v5/signature/policy_config.go @@ -1,4 +1,4 @@ -// policy_config.go hanles creation of policy objects, either by parsing JSON +// policy_config.go handles creation of policy objects, either by parsing JSON // or by programs building them programmatically. // The New* constructors are intended to be a stable API. FIXME: after an independent review. @@ -516,7 +516,7 @@ func newPolicyReferenceMatchFromJSON(data []byte) (PolicyReferenceMatch, error) return res, nil } -// newPRMMatchExact is NewPRMMatchExact, except it resturns the private type. +// newPRMMatchExact is NewPRMMatchExact, except it returns the private type. func newPRMMatchExact() *prmMatchExact { return &prmMatchExact{prmCommon{Type: prmTypeMatchExact}} } @@ -546,7 +546,7 @@ func (prm *prmMatchExact) UnmarshalJSON(data []byte) error { return nil } -// newPRMMatchRepoDigestOrExact is NewPRMMatchRepoDigestOrExact, except it resturns the private type. +// newPRMMatchRepoDigestOrExact is NewPRMMatchRepoDigestOrExact, except it returns the private type. func newPRMMatchRepoDigestOrExact() *prmMatchRepoDigestOrExact { return &prmMatchRepoDigestOrExact{prmCommon{Type: prmTypeMatchRepoDigestOrExact}} } @@ -576,7 +576,7 @@ func (prm *prmMatchRepoDigestOrExact) UnmarshalJSON(data []byte) error { return nil } -// newPRMMatchRepository is NewPRMMatchRepository, except it resturns the private type. +// newPRMMatchRepository is NewPRMMatchRepository, except it returns the private type. func newPRMMatchRepository() *prmMatchRepository { return &prmMatchRepository{prmCommon{Type: prmTypeMatchRepository}} } @@ -606,7 +606,7 @@ func (prm *prmMatchRepository) UnmarshalJSON(data []byte) error { return nil } -// newPRMExactReference is NewPRMExactReference, except it resturns the private type. +// newPRMExactReference is NewPRMExactReference, except it returns the private type. func newPRMExactReference(dockerReference string) (*prmExactReference, error) { ref, err := reference.ParseNormalizedNamed(dockerReference) if err != nil { @@ -652,7 +652,7 @@ func (prm *prmExactReference) UnmarshalJSON(data []byte) error { return nil } -// newPRMExactRepository is NewPRMExactRepository, except it resturns the private type. +// newPRMExactRepository is NewPRMExactRepository, except it returns the private type. func newPRMExactRepository(dockerRepository string) (*prmExactRepository, error) { if _, err := reference.ParseNormalizedNamed(dockerRepository); err != nil { return nil, InvalidPolicyFormatError(fmt.Sprintf("Invalid format of dockerRepository %s: %s", dockerRepository, err.Error())) diff --git a/vendor/github.com/containers/image/v5/signature/policy_eval.go b/vendor/github.com/containers/image/v5/signature/policy_eval.go index a1fb1eebb..edcbf52f4 100644 --- a/vendor/github.com/containers/image/v5/signature/policy_eval.go +++ b/vendor/github.com/containers/image/v5/signature/policy_eval.go @@ -1,5 +1,5 @@ // This defines the top-level policy evaluation API. -// To the extent possible, the interface of the fuctions provided +// To the extent possible, the interface of the functions provided // here is intended to be completely unambiguous, and stable for users // to rely on. @@ -47,7 +47,7 @@ type PolicyRequirement interface { // - sarUnknown if if this PolicyRequirement does not deal with signatures. // NOTE: sarUnknown should not be returned if this PolicyRequirement should make a decision but something failed. // Returning sarUnknown and a non-nil error value is invalid. - // WARNING: This makes the signature contents acceptable for futher processing, + // WARNING: This makes the signature contents acceptable for further processing, // but it does not necessarily mean that the contents of the signature are // consistent with local policy. // For example: @@ -166,7 +166,7 @@ func (pc *PolicyContext) requirementsForImageRef(ref types.ImageReference) Polic // verified). // NOTE: This may legitimately return an empty list and no error, if the image // has no signatures or only invalid signatures. -// WARNING: This makes the signature contents acceptable for futher processing, +// WARNING: This makes the signature contents acceptable for further processing, // but it does not necessarily mean that the contents of the signature are // consistent with local policy. // For example: diff --git a/vendor/github.com/containers/image/v5/signature/policy_reference_match.go b/vendor/github.com/containers/image/v5/signature/policy_reference_match.go index a148ede52..e2a21f01d 100644 --- a/vendor/github.com/containers/image/v5/signature/policy_reference_match.go +++ b/vendor/github.com/containers/image/v5/signature/policy_reference_match.go @@ -51,7 +51,7 @@ func (prm *prmMatchRepoDigestOrExact) matchesDockerReference(image types.Unparse return signature.String() == intended.String() case reference.Canonical: // We don’t actually compare the manifest digest against the signature here; that happens prSignedBy.in UnparsedImage.Manifest. - // Becase UnparsedImage.Manifest verifies the intended.Digest() against the manifest, and prSignedBy verifies the signature digest against the manifest, + // Because UnparsedImage.Manifest verifies the intended.Digest() against the manifest, and prSignedBy verifies the signature digest against the manifest, // we know that signature digest matches intended.Digest() (but intended.Digest() and signature digest may use different algorithms) return signature.Name() == intended.Name() default: // !reference.IsNameOnly(intended) diff --git a/vendor/github.com/containers/image/v5/signature/signature.go b/vendor/github.com/containers/image/v5/signature/signature.go index bc1c0e575..09f4f85e0 100644 --- a/vendor/github.com/containers/image/v5/signature/signature.go +++ b/vendor/github.com/containers/image/v5/signature/signature.go @@ -210,7 +210,7 @@ type signatureAcceptanceRules struct { validateSignedDockerManifestDigest func(digest.Digest) error } -// verifyAndExtractSignature verifies that unverifiedSignature has been signed, and that its principial components +// verifyAndExtractSignature verifies that unverifiedSignature has been signed, and that its principal components // match expected values, both as specified by rules, and returns it func verifyAndExtractSignature(mech SigningMechanism, unverifiedSignature []byte, rules signatureAcceptanceRules) (*Signature, error) { signed, keyIdentity, err := mech.Verify(unverifiedSignature) @@ -248,7 +248,7 @@ func verifyAndExtractSignature(mech SigningMechanism, unverifiedSignature []byte // There is NO REASON to expect the values to be correct, or not intentionally misleading // (including things like “✅ Verified by $authority”) func GetUntrustedSignatureInformationWithoutVerifying(untrustedSignatureBytes []byte) (*UntrustedSignatureInformation, error) { - // NOTE: This should eventualy do format autodetection. + // NOTE: This should eventually do format autodetection. mech, _, err := NewEphemeralGPGSigningMechanism([]byte{}) if err != nil { return nil, err diff --git a/vendor/github.com/containers/image/v5/storage/storage_image.go b/vendor/github.com/containers/image/v5/storage/storage_image.go index df4b67c7a..d24f8bbee 100644 --- a/vendor/github.com/containers/image/v5/storage/storage_image.go +++ b/vendor/github.com/containers/image/v5/storage/storage_image.go @@ -463,7 +463,7 @@ func (s *storageImageDestination) PutBlob(ctx context.Context, stream io.Reader, // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. // If canSubstitute, TryReusingBlob can use an equivalent equivalent of the desired blob; in that case the returned info may not match the input. -// If the blob has been succesfully reused, returns (true, info, nil); info must contain at least a digest and size. +// If the blob has been successfully reused, returns (true, info, nil); info must contain at least a digest and size. // If the transport can not reuse the requested blob, TryReusingBlob returns (false, {}, nil); it returns a non-nil error only on an unexpected failure. // May use and/or update cache. func (s *storageImageDestination) TryReusingBlob(ctx context.Context, blobinfo types.BlobInfo, cache types.BlobInfoCache, canSubstitute bool) (bool, types.BlobInfo, error) { @@ -657,7 +657,7 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t // Check if it's elsewhere and the caller just forgot to pass it to us in a PutBlob(), // or to even check if we had it. // Use none.NoCache to avoid a repeated DiffID lookup in the BlobInfoCache; a caller - // that relies on using a blob digest that has never been seeen by the store had better call + // that relies on using a blob digest that has never been seen by the store had better call // TryReusingBlob; not calling PutBlob already violates the documented API, so there’s only // so far we are going to accommodate that (if we should be doing that at all). logrus.Debugf("looking for diffID for blob %+v", blob.Digest) diff --git a/vendor/github.com/containers/image/v5/types/types.go b/vendor/github.com/containers/image/v5/types/types.go index 4f624cf33..5a91f0096 100644 --- a/vendor/github.com/containers/image/v5/types/types.go +++ b/vendor/github.com/containers/image/v5/types/types.go @@ -170,7 +170,7 @@ type BICReplacementCandidate struct { Location BICLocationReference } -// BlobInfoCache records data useful for reusing blobs, or substituing equivalent ones, to avoid unnecessary blob copies. +// BlobInfoCache records data useful for reusing blobs, or substituting equivalent ones, to avoid unnecessary blob copies. // // It records two kinds of data: // - Sets of corresponding digest vs. uncompressed digest ("DiffID") pairs: @@ -193,7 +193,7 @@ type BICReplacementCandidate struct { // can be directly reused within a registry, or mounted across registries within a registry server.) // // None of the methods return an error indication: errors when neither reading from, nor writing to, the cache, should be fatal; -// users of the cahce should just fall back to copying the blobs the usual way. +// users of the cache should just fall back to copying the blobs the usual way. type BlobInfoCache interface { // UncompressedDigest returns an uncompressed digest corresponding to anyDigest. // May return anyDigest if it is known to be uncompressed. @@ -306,7 +306,7 @@ type ImageDestination interface { // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. // If canSubstitute, TryReusingBlob can use an equivalent equivalent of the desired blob; in that case the returned info may not match the input. - // If the blob has been succesfully reused, returns (true, info, nil); info must contain at least a digest and size. + // If the blob has been successfully reused, returns (true, info, nil); info must contain at least a digest and size. // If the transport can not reuse the requested blob, TryReusingBlob returns (false, {}, nil); it returns a non-nil error only on an unexpected failure. // May use and/or update cache. TryReusingBlob(ctx context.Context, info BlobInfo, cache BlobInfoCache, canSubstitute bool) (bool, BlobInfo, error) diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go index 9c0ddcaed..b6b79f26c 100644 --- a/vendor/github.com/containers/image/v5/version/version.go +++ b/vendor/github.com/containers/image/v5/version/version.go @@ -6,7 +6,7 @@ const ( // VersionMajor is for an API incompatible changes VersionMajor = 5 // VersionMinor is for functionality in a backwards-compatible manner - VersionMinor = 6 + VersionMinor = 7 // VersionPatch is for backwards-compatible bug fixes VersionPatch = 0 diff --git a/vendor/github.com/containers/storage/.cirrus.yml b/vendor/github.com/containers/storage/.cirrus.yml index 6ba46ebbb..539bfeabb 100644 --- a/vendor/github.com/containers/storage/.cirrus.yml +++ b/vendor/github.com/containers/storage/.cirrus.yml @@ -17,14 +17,15 @@ env: #### #### Cache-image names to test with (double-quotes around names are critical) ### - FEDORA_NAME: "fedora-32" - PRIOR_FEDORA_NAME: "fedora-31" - UBUNTU_NAME: "ubuntu-20" - PRIOR_UBUNTU_NAME: "ubuntu-19" + FEDORA_NAME: "fedora" + PRIOR_FEDORA_NAME: "prior-fedora" + UBUNTU_NAME: "ubuntu" + PRIOR_UBUNTU_NAME: "prior-ubuntu" # GCE project where images live IMAGE_PROJECT: "libpod-218412" - _BUILT_IMAGE_SUFFIX: "libpod-6508632441356288" + # VM Image built in containers/automation_images + _BUILT_IMAGE_SUFFIX: "c4948709391728640" FEDORA_CACHE_IMAGE_NAME: "${FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}" PRIOR_FEDORA_CACHE_IMAGE_NAME: "${PRIOR_FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}" UBUNTU_CACHE_IMAGE_NAME: "${UBUNTU_NAME}-${_BUILT_IMAGE_SUFFIX}" diff --git a/vendor/github.com/containers/storage/.gitignore b/vendor/github.com/containers/storage/.gitignore index 64b9a98bd..99b40fbde 100644 --- a/vendor/github.com/containers/storage/.gitignore +++ b/vendor/github.com/containers/storage/.gitignore @@ -9,6 +9,7 @@ *.test .*.swp .DS_Store +.idea* # a .bashrc may be added to customize the build environment .bashrc .gopath/ diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION index ca8ec414e..2d27ccba1 100644 --- a/vendor/github.com/containers/storage/VERSION +++ b/vendor/github.com/containers/storage/VERSION @@ -1 +1 @@ -1.23.5 +1.23.7 diff --git a/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go b/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go index be4362dc0..e71ad69e2 100644 --- a/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go +++ b/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go @@ -422,7 +422,7 @@ func subvolLimitQgroup(path string, size uint64) error { // subvolQgroupStatus performs a BTRFS_IOC_TREE_SEARCH on the root path // with search key of BTRFS_QGROUP_STATUS_KEY. -// In case qgroup is enabled, the retuned key type will match BTRFS_QGROUP_STATUS_KEY. +// In case qgroup is enabled, the returned key type will match BTRFS_QGROUP_STATUS_KEY. // For more details please see https://github.com/kdave/btrfs-progs/blob/v4.9/qgroup.c#L1035 func subvolQgroupStatus(path string) error { dir, err := openDir(path) diff --git a/vendor/github.com/containers/storage/drivers/chown_unix.go b/vendor/github.com/containers/storage/drivers/chown_unix.go index 3a3978b71..1cadb089f 100644 --- a/vendor/github.com/containers/storage/drivers/chown_unix.go +++ b/vendor/github.com/containers/storage/drivers/chown_unix.go @@ -54,7 +54,7 @@ func platformLChown(path string, info os.FileInfo, toHost, toContainer *idtools. } // Make the change. - if err := syscall.Lchown(path, uid, gid); err != nil { + if err := os.Lchown(path, uid, gid); err != nil { return fmt.Errorf("%s: chown(%q): %v", os.Args[0], path, err) } // Restore the SUID and SGID bits if they were originally set. diff --git a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go index cba3d05ea..775dc1685 100644 --- a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go +++ b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go @@ -1213,7 +1213,11 @@ func (devices *DeviceSet) growFS(info *devInfo) error { return errors.Wrapf(err, "Failed to mount; dmesg: %s", string(dmesg.Dmesg(256))) } - defer unix.Unmount(fsMountPoint, unix.MNT_DETACH) + defer func() { + if err := mount.Unmount(fsMountPoint); err != nil { + logrus.Warnf("devmapper.growFS cleanup error: %v", err) + } + }() switch devices.BaseDeviceFilesystem { case ext4: @@ -2257,6 +2261,38 @@ func (devices *DeviceSet) cancelDeferredRemoval(info *devInfo) error { return err } +func (devices *DeviceSet) unmountAndDeactivateAll(dir string) { + files, err := ioutil.ReadDir(dir) + if err != nil { + logrus.Warnf("devmapper: unmountAndDeactivate: %s", err) + return + } + + for _, d := range files { + if !d.IsDir() { + continue + } + + name := d.Name() + fullname := path.Join(dir, name) + + // We use MNT_DETACH here in case it is still busy in some running + // container. This means it'll go away from the global scope directly, + // and the device will be released when that container dies. + if err := mount.Unmount(fullname); err != nil { + logrus.Warnf("devmapper.Shutdown error: %s", err) + } + + if devInfo, err := devices.lookupDevice(name); err != nil { + logrus.Debugf("devmapper: Shutdown lookup device %s, error: %s", name, err) + } else { + if err := devices.deactivateDevice(devInfo); err != nil { + logrus.Debugf("devmapper: Shutdown deactivate %s, error: %s", devInfo.Hash, err) + } + } + } +} + // Shutdown shuts down the device by unmounting the root. func (devices *DeviceSet) Shutdown(home string) error { logrus.Debugf("devmapper: [deviceset %s] Shutdown()", devices.devicePrefix) @@ -2278,45 +2314,7 @@ func (devices *DeviceSet) Shutdown(home string) error { // will be killed and we will not get a chance to save deviceset // metadata. Hence save this early before trying to deactivate devices. devices.saveDeviceSetMetaData() - - // ignore the error since it's just a best effort to not try to unmount something that's mounted - mounts, _ := mount.GetMounts() - mounted := make(map[string]bool, len(mounts)) - for _, mnt := range mounts { - mounted[mnt.Mountpoint] = true - } - - if err := filepath.Walk(path.Join(home, "mnt"), func(p string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if !info.IsDir() { - return nil - } - - if mounted[p] { - // We use MNT_DETACH here in case it is still busy in some running - // container. This means it'll go away from the global scope directly, - // and the device will be released when that container dies. - if err := unix.Unmount(p, unix.MNT_DETACH); err != nil { - logrus.Debugf("devmapper: Shutdown unmounting %s, error: %s", p, err) - } - } - - if devInfo, err := devices.lookupDevice(path.Base(p)); err != nil { - logrus.Debugf("devmapper: Shutdown lookup device %s, error: %s", path.Base(p), err) - } else { - if err := devices.deactivateDevice(devInfo); err != nil { - logrus.Debugf("devmapper: Shutdown deactivate %s , error: %s", devInfo.Hash, err) - } - } - - return nil - }); err != nil && !os.IsNotExist(err) { - devices.Unlock() - return err - } - + devices.unmountAndDeactivateAll(path.Join(home, "mnt")) devices.Unlock() info, _ := devices.lookupDeviceWithLock("") @@ -2420,7 +2418,9 @@ func (devices *DeviceSet) MountDevice(hash, path string, moptions graphdriver.Mo if fstype == xfs && devices.xfsNospaceRetries != "" { if err := devices.xfsSetNospaceRetries(info); err != nil { - unix.Unmount(path, unix.MNT_DETACH) + if err := mount.Unmount(path); err != nil { + logrus.Warnf("devmapper.MountDevice cleanup error: %v", err) + } devices.deactivateDevice(info) return err } @@ -2446,11 +2446,23 @@ func (devices *DeviceSet) UnmountDevice(hash, mountPath string) error { defer devices.Unlock() logrus.Debugf("devmapper: Unmount(%s)", mountPath) - if err := unix.Unmount(mountPath, unix.MNT_DETACH); err != nil { + if err := mount.Unmount(mountPath); err != nil { return err } logrus.Debug("devmapper: Unmount done") + // Remove the mountpoint here. Removing the mountpoint (in newer kernels) + // will cause all other instances of this mount in other mount namespaces + // to be killed (this is an anti-DoS measure that is necessary for things + // like devicemapper). This is necessary to avoid cases where a libdm mount + // that is present in another namespace will cause subsequent RemoveDevice + // operations to fail. We ignore any errors here because this may fail on + // older kernels which don't have + // torvalds/linux@8ed936b5671bfb33d89bc60bdcc7cf0470ba52fe applied. + if err := os.Remove(mountPath); err != nil { + logrus.Debugf("devmapper: error doing a remove on unmounted device %s: %v", mountPath, err) + } + return devices.deactivateDevice(info) } diff --git a/vendor/github.com/containers/storage/drivers/devmapper/driver.go b/vendor/github.com/containers/storage/drivers/devmapper/driver.go index 0afa6c84d..4149979a5 100644 --- a/vendor/github.com/containers/storage/drivers/devmapper/driver.go +++ b/vendor/github.com/containers/storage/drivers/devmapper/driver.go @@ -14,9 +14,9 @@ import ( "github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/locker" "github.com/containers/storage/pkg/mount" - "github.com/containers/storage/pkg/system" units "github.com/docker/go-units" "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" ) func init() { @@ -116,11 +116,13 @@ func (d *Driver) Metadata(id string) (map[string]string, error) { func (d *Driver) Cleanup() error { err := d.DeviceSet.Shutdown(d.home) - if err2 := mount.Unmount(d.home); err == nil { - err = err2 + umountErr := mount.Unmount(d.home) + // in case we have two errors, prefer the one from Shutdown() + if err != nil { + return err } - return err + return umountErr } // CreateFromTemplate creates a layer with the same contents and parent as another layer. @@ -148,7 +150,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error { return nil } -// Remove removes a device with a given id, unmounts the filesystem. +// Remove removes a device with a given id, unmounts the filesystem, and removes the mount point. func (d *Driver) Remove(id string) error { d.locker.Lock(id) defer d.locker.Unlock(id) @@ -163,7 +165,21 @@ func (d *Driver) Remove(id string) error { if err := d.DeviceSet.DeleteDevice(id, false); err != nil { return fmt.Errorf("failed to remove device %s: %v", id, err) } - return system.EnsureRemoveAll(path.Join(d.home, "mnt", id)) + + // Most probably the mount point is already removed on Put() + // (see DeviceSet.UnmountDevice()), but just in case it was not + // let's try to remove it here as well, ignoring errors as + // an older kernel can return EBUSY if e.g. the mount was leaked + // to other mount namespaces. A failure to remove the container's + // mount point is not important and should not be treated + // as a failure to remove the container. + mp := path.Join(d.home, "mnt", id) + err := unix.Rmdir(mp) + if err != nil && !os.IsNotExist(err) { + logrus.WithField("storage-driver", "devicemapper").Warnf("unable to remove mount point %q: %s", mp, err) + } + + return nil } // Get mounts a device with given id into the root filesystem @@ -226,10 +242,12 @@ func (d *Driver) Put(id string) error { if count := d.ctr.Decrement(mp); count > 0 { return nil } + err := d.DeviceSet.UnmountDevice(id, mp) if err != nil { - logrus.Errorf("devmapper: Error unmounting device %s: %s", id, err) + logrus.Errorf("devmapper: Error unmounting device %s: %v", id, err) } + return err } diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go index 1de771bb0..398fe6531 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go +++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go @@ -75,7 +75,7 @@ const ( maxDepth = 128 // idLength represents the number of random characters - // which can be used to create the unique link identifer + // which can be used to create the unique link identifier // for every layer. If this value is too long then the // page size limit for the mount command may be exceeded. // The idLength should be selected such that following equation @@ -219,7 +219,7 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error) return nil, errors.Wrap(err, "error recording metacopy-being-used status") } } else { - logrus.Warnf("overlay test mount did not indicate whether or not metacopy is being used: %v", err) + logrus.Infof("overlay test mount did not indicate whether or not metacopy is being used: %v", err) return nil, err } } @@ -280,7 +280,7 @@ func parseOptions(options []string) (*overlayOptions, error) { trimkey = strings.TrimPrefix(trimkey, ".") switch trimkey { case "override_kernel_check": - logrus.Warnf("overlay: override_kernel_check option was specified, but is no longer necessary") + logrus.Debugf("overlay: override_kernel_check option was specified, but is no longer necessary") case "mountopt": o.mountOptions = val case "size": @@ -444,14 +444,14 @@ func (d *Driver) useNaiveDiff() bool { logrus.Debugf("cached value indicated that native-diff is usable") } else { logrus.Debugf("cached value indicated that native-diff is not being used") - logrus.Warn(nativeDiffCacheText) + logrus.Info(nativeDiffCacheText) } useNaiveDiffOnly = !nativeDiffCacheResult return } if err := doesSupportNativeDiff(d.home, d.options.mountOptions); err != nil { nativeDiffCacheText = fmt.Sprintf("Not using native diff for overlay, this may cause degraded performance for building images: %v", err) - logrus.Warn(nativeDiffCacheText) + logrus.Info(nativeDiffCacheText) useNaiveDiffOnly = true } cachedFeatureRecord(d.runhome, feature, !useNaiveDiffOnly, nativeDiffCacheText) diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs.go b/vendor/github.com/containers/storage/drivers/zfs/zfs.go index 3e850d136..4e7290efc 100644 --- a/vendor/github.com/containers/storage/drivers/zfs/zfs.go +++ b/vendor/github.com/containers/storage/drivers/zfs/zfs.go @@ -160,7 +160,7 @@ func lookupZfsDataset(rootdir string) (string, error) { continue // may fail on fuse file systems } - if stat.Dev == wantedDev && m.Fstype == "zfs" { + if stat.Dev == wantedDev && m.FSType == "zfs" { return m.Source, nil } } diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod index 39db66641..f38266a16 100644 --- a/vendor/github.com/containers/storage/go.mod +++ b/vendor/github.com/containers/storage/go.mod @@ -1,4 +1,4 @@ -go 1.15 +go 1.14 module github.com/containers/storage @@ -8,23 +8,23 @@ require ( github.com/Microsoft/hcsshim v0.8.9 github.com/docker/go-units v0.4.0 github.com/hashicorp/go-multierror v1.1.0 - github.com/klauspost/compress v1.11.0 + github.com/klauspost/compress v1.11.1 github.com/klauspost/pgzip v1.2.5 github.com/mattn/go-shellwords v1.0.10 github.com/mistifyio/go-zfs v2.1.1+incompatible - github.com/moby/sys/mountinfo v0.1.3 + github.com/moby/sys/mountinfo v0.4.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/runc v1.0.0-rc91 github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2 github.com/opencontainers/selinux v1.6.0 github.com/pkg/errors v0.9.1 github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7 - github.com/sirupsen/logrus v1.6.0 + github.com/sirupsen/logrus v1.7.0 github.com/stretchr/testify v1.6.1 github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 github.com/tchap/go-patricia v2.3.0+incompatible github.com/vbatts/tar-split v0.11.1 golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 - golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775 + golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 gotest.tools v2.2.0+incompatible ) diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum index d1fb711b1..2aad798d8 100644 --- a/vendor/github.com/containers/storage/go.sum +++ b/vendor/github.com/containers/storage/go.sum @@ -62,8 +62,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.11.0 h1:wJbzvpYMVGG9iTI9VxpnNZfd4DzMPoCWze3GgSqz8yg= -github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.1 h1:bPb7nMRdOZYDrpPMTA3EInUQrdgoBinqUuSwlGdKDdE= +github.com/klauspost/compress v1.11.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -80,6 +80,8 @@ github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJd github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/moby/sys/mountinfo v0.1.3 h1:KIrhRO14+AkwKvG/g2yIpNMOUVZ02xNhOw8KY1WsLOI= github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o= +github.com/moby/sys/mountinfo v0.4.0 h1:1KInV3Huv18akCu58V7lzNlt+jFmqlu1EaErnEHE/VM= +github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 h1:7InQ7/zrOh6SlFjaXFubv0xX0HsuC9qJsdqm7bNQpYM= github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -113,6 +115,8 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -163,12 +167,15 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775 h1:TC0v2RSO1u2kn1ZugjrFXkRZAEaqMN/RW+OTZkBzmLE= golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go index 52577299c..a70806f40 100644 --- a/vendor/github.com/containers/storage/layers.go +++ b/vendor/github.com/containers/storage/layers.go @@ -907,11 +907,11 @@ func (r *layerStore) ParentOwners(id string) (uids, gids []int, err error) { for dir := filepath.Dir(layer.MountPoint); dir != "" && dir != string(os.PathSeparator); dir = filepath.Dir(dir) { st, err := system.Stat(dir) if err != nil { - return nil, nil, errors.Wrapf(err, "error reading ownership of directory %q", dir) + return nil, nil, errors.Wrap(err, "read directory ownership") } lst, err := system.Lstat(dir) if err != nil { - return nil, nil, errors.Wrapf(err, "error reading ownership of directory-in-case-it's-a-symlink %q", dir) + return nil, nil, err } fsuid := int(st.UID()) fsgid := int(st.GID()) diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go index ac0f5f336..4472511a2 100644 --- a/vendor/github.com/containers/storage/pkg/archive/archive.go +++ b/vendor/github.com/containers/storage/pkg/archive/archive.go @@ -694,29 +694,6 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L } } - var errors []string - for key, value := range hdr.Xattrs { - if err := system.Lsetxattr(path, key, []byte(value), 0); err != nil { - if err == syscall.ENOTSUP || (err == syscall.EPERM && inUserns) { - // We ignore errors here because not all graphdrivers support - // xattrs *cough* old versions of AUFS *cough*. However only - // ENOTSUP should be emitted in that case, otherwise we still - // bail. We also ignore EPERM errors if we are running in a - // user namespace. - errors = append(errors, err.Error()) - continue - } - return err - } - - } - - if len(errors) > 0 { - logrus.WithFields(logrus.Fields{ - "errors": errors, - }).Warn("ignored xattrs in archive: underlying filesystem doesn't support them") - } - // There is no LChmod, so ignore mode for symlink. Also, this // must happen after chown, as that can modify the file mode if err := handleLChmod(hdr, path, hdrInfo); err != nil { @@ -746,6 +723,30 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L return err } } + + var errors []string + for key, value := range hdr.Xattrs { + if err := system.Lsetxattr(path, key, []byte(value), 0); err != nil { + if err == syscall.ENOTSUP || (err == syscall.EPERM && inUserns) { + // We ignore errors here because not all graphdrivers support + // xattrs *cough* old versions of AUFS *cough*. However only + // ENOTSUP should be emitted in that case, otherwise we still + // bail. We also ignore EPERM errors if we are running in a + // user namespace. + errors = append(errors, err.Error()) + continue + } + return err + } + + } + + if len(errors) > 0 { + logrus.WithFields(logrus.Fields{ + "errors": errors, + }).Warn("ignored xattrs in archive: underlying filesystem doesn't support them") + } + return nil } @@ -1247,10 +1248,11 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) { }() options := &TarOptions{ - UIDMaps: archiver.UntarIDMappings.UIDs(), - GIDMaps: archiver.UntarIDMappings.GIDs(), - ChownOpts: archiver.ChownOpts, - InUserNS: rsystem.RunningInUserNS(), + UIDMaps: archiver.UntarIDMappings.UIDs(), + GIDMaps: archiver.UntarIDMappings.GIDs(), + ChownOpts: archiver.ChownOpts, + InUserNS: rsystem.RunningInUserNS(), + NoOverwriteDirNonDir: true, } err = archiver.Untar(r, filepath.Dir(dst), options) if err != nil { diff --git a/vendor/github.com/containers/storage/pkg/devicemapper/devmapper_log.go b/vendor/github.com/containers/storage/pkg/devicemapper/devmapper_log.go index b540281fa..082fb1ba3 100644 --- a/vendor/github.com/containers/storage/pkg/devicemapper/devmapper_log.go +++ b/vendor/github.com/containers/storage/pkg/devicemapper/devmapper_log.go @@ -12,7 +12,7 @@ import ( ) // DevmapperLogger defines methods required to register as a callback for -// logging events recieved from devicemapper. Note that devicemapper will send +// logging events received from devicemapper. Note that devicemapper will send // *all* logs regardless to callbacks (including debug logs) so it's // recommended to not spam the console with the outputs. type DevmapperLogger interface { diff --git a/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go b/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go index e5faf9aad..b3998fb35 100644 --- a/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go +++ b/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go @@ -13,7 +13,7 @@ import ( "github.com/sirupsen/logrus" ) -// PatternMatcher allows checking paths agaist a list of patterns +// PatternMatcher allows checking paths against a list of patterns type PatternMatcher struct { patterns []*Pattern exclusions bool diff --git a/vendor/github.com/containers/storage/pkg/idtools/idtools.go b/vendor/github.com/containers/storage/pkg/idtools/idtools.go index 5105720ba..0958c0c5d 100644 --- a/vendor/github.com/containers/storage/pkg/idtools/idtools.go +++ b/vendor/github.com/containers/storage/pkg/idtools/idtools.go @@ -291,7 +291,7 @@ func parseSubidFile(path, username string) (ranges, error) { func checkChownErr(err error, name string, uid, gid int) error { if e, ok := err.(*os.PathError); ok && e.Err == syscall.EINVAL { - return errors.Wrapf(err, "there might not be enough IDs available in the namespace (requested %d:%d for %s)", uid, gid, name) + return errors.Wrapf(err, "potentially insufficient UIDs or GIDs available in user namespace (requested %d:%d for %s): Check /etc/subuid and /etc/subgid", uid, gid, name) } return err } diff --git a/vendor/github.com/containers/storage/pkg/idtools/parser.go b/vendor/github.com/containers/storage/pkg/idtools/parser.go index 86f98f16e..1c819a1f9 100644 --- a/vendor/github.com/containers/storage/pkg/idtools/parser.go +++ b/vendor/github.com/containers/storage/pkg/idtools/parser.go @@ -8,13 +8,6 @@ import ( "strings" ) -func nonDigitsToWhitespace(r rune) rune { - if !strings.ContainsRune("0123456789", r) { - return ' ' - } - return r -} - func parseTriple(spec []string) (container, host, size uint32, err error) { cid, err := strconv.ParseUint(spec[0], 10, 32) if err != nil { @@ -33,9 +26,12 @@ func parseTriple(spec []string) (container, host, size uint32, err error) { // ParseIDMap parses idmap triples from string. func ParseIDMap(mapSpec []string, mapSetting string) (idmap []IDMap, err error) { - stdErr := fmt.Errorf("error initializing ID mappings: %s setting is malformed", mapSetting) + stdErr := fmt.Errorf("error initializing ID mappings: %s setting is malformed expected [\"uint32:uint32:uint32\"]: %q", mapSetting, mapSpec) for _, idMapSpec := range mapSpec { - idSpec := strings.Fields(strings.Map(nonDigitsToWhitespace, idMapSpec)) + if idMapSpec == "" { + continue + } + idSpec := strings.Split(idMapSpec, ":") if len(idSpec)%3 != 0 { return nil, stdErr } diff --git a/vendor/github.com/containers/storage/pkg/mount/mount.go b/vendor/github.com/containers/storage/pkg/mount/mount.go index 8273ab5a9..cd4bacd66 100644 --- a/vendor/github.com/containers/storage/pkg/mount/mount.go +++ b/vendor/github.com/containers/storage/pkg/mount/mount.go @@ -90,7 +90,7 @@ func RecursiveUnmount(target string) error { if err := Unmount(m.Mountpoint); err != nil && i == len(mounts)-1 { return err // Ignore errors for submounts and continue trying to unmount others - // The final unmount should fail if there ane any submounts remaining + // The final unmount should fail if there are any submounts remaining } } return nil diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo.go index efc6c406e..bb2da474f 100644 --- a/vendor/github.com/containers/storage/pkg/mount/mountinfo.go +++ b/vendor/github.com/containers/storage/pkg/mount/mountinfo.go @@ -1,21 +1,13 @@ package mount import ( - "github.com/containers/storage/pkg/fileutils" "github.com/moby/sys/mountinfo" ) type Info = mountinfo.Info +var Mounted = mountinfo.Mounted + func GetMounts() ([]*Info, error) { return mountinfo.GetMounts(nil) } - -// Mounted determines if a specified mountpoint has been mounted. -func Mounted(mountpoint string) (bool, error) { - mountpoint, err := fileutils.ReadSymlinkedPath(mountpoint) - if err != nil { - return false, err - } - return mountinfo.Mounted(mountpoint) -} diff --git a/vendor/github.com/containers/storage/storage.conf b/vendor/github.com/containers/storage/storage.conf index a8ec9d98b..64e02f327 100644 --- a/vendor/github.com/containers/storage/storage.conf +++ b/vendor/github.com/containers/storage/storage.conf @@ -47,7 +47,7 @@ additionalimagestores = [ # remap-group = "containers" # Root-auto-userns-user is a user name which can be used to look up one or more UID/GID -# ranges in the /etc/subuid and /etc/subgid file. These ranges will be partioned +# ranges in the /etc/subuid and /etc/subgid file. These ranges will be partitioned # to containers configured to create automatically a user namespace. Containers # configured to automatically create a user namespace can still overlap with containers # having an explicit mapping set. diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go index 2a34c84cc..6b51b405d 100644 --- a/vendor/github.com/containers/storage/store.go +++ b/vendor/github.com/containers/storage/store.go @@ -613,14 +613,14 @@ func GetStore(options StoreOptions) (Store, error) { if options.GraphRoot != "" { dir, err := filepath.Abs(options.GraphRoot) if err != nil { - return nil, errors.Wrapf(err, "error deriving an absolute path from %q", options.GraphRoot) + return nil, err } options.GraphRoot = dir } if options.RunRoot != "" { dir, err := filepath.Abs(options.RunRoot) if err != nil { - return nil, errors.Wrapf(err, "error deriving an absolute path from %q", options.RunRoot) + return nil, err } options.RunRoot = dir } @@ -2677,21 +2677,16 @@ func (s *store) MountImage(id string, mountOpts []string, mountLabel string) (st } func (s *store) Mount(id, mountLabel string) (string, error) { - container, err := s.Container(id) - var ( - uidMap, gidMap []idtools.IDMap - mountOpts []string - ) - if err == nil { - uidMap, gidMap = container.UIDMap, container.GIDMap - id = container.LayerID - mountOpts = container.MountOpts() - } options := drivers.MountOpts{ MountLabel: mountLabel, - UidMaps: uidMap, - GidMaps: gidMap, - Options: mountOpts, + } + // check if `id` is a container, then grab the LayerID, uidmap and gidmap, along with + // otherwise we assume the id is a LayerID and attempt to mount it. + if container, err := s.Container(id); err == nil { + id = container.LayerID + options.UidMaps = container.UIDMap + options.GidMaps = container.GIDMap + options.Options = container.MountOpts() } return s.mount(id, options) } @@ -3460,7 +3455,10 @@ func copyStringInterfaceMap(m map[string]interface{}) map[string]interface{} { } // defaultConfigFile path to the system wide storage.conf file -var defaultConfigFile = "/etc/containers/storage.conf" +var ( + defaultConfigFile = "/etc/containers/storage.conf" + defaultConfigFileSet = false +) // AutoUserNsMinSize is the minimum size for automatically created user namespaces const AutoUserNsMinSize = 1024 @@ -3475,21 +3473,24 @@ const RootAutoUserNsUser = "containers" // SetDefaultConfigFilePath sets the default configuration to the specified path func SetDefaultConfigFilePath(path string) { defaultConfigFile = path + defaultConfigFileSet = true + reloadConfigurationFileIfNeeded(defaultConfigFile, &defaultStoreOptions) } // DefaultConfigFile returns the path to the storage config file used func DefaultConfigFile(rootless bool) (string, error) { - if rootless { - if configHome := os.Getenv("XDG_CONFIG_HOME"); configHome != "" { - return filepath.Join(configHome, "containers/storage.conf"), nil - } - home := homedir.Get() - if home == "" { - return "", errors.New("cannot determine user's homedir") - } - return filepath.Join(home, ".config/containers/storage.conf"), nil + if defaultConfigFileSet || !rootless { + return defaultConfigFile, nil + } + + if configHome := os.Getenv("XDG_CONFIG_HOME"); configHome != "" { + return filepath.Join(configHome, "containers/storage.conf"), nil + } + home := homedir.Get() + if home == "" { + return "", errors.New("cannot determine user's homedir") } - return defaultConfigFile, nil + return filepath.Join(home, ".config/containers/storage.conf"), nil } // TOML-friendly explicit tables used for conversions. diff --git a/vendor/github.com/containers/storage/utils.go b/vendor/github.com/containers/storage/utils.go index b22263fe4..762c3a00d 100644 --- a/vendor/github.com/containers/storage/utils.go +++ b/vendor/github.com/containers/storage/utils.go @@ -76,7 +76,7 @@ func GetRootlessRuntimeDir(rootlessUID int) (string, error) { } path = filepath.Join(path, "containers") if err := os.MkdirAll(path, 0700); err != nil { - return "", errors.Wrapf(err, "unable to make rootless runtime dir %s", path) + return "", errors.Wrapf(err, "unable to make rootless runtime") } return path, nil } @@ -154,7 +154,7 @@ func getRootlessRuntimeDirIsolated(env rootlessRuntimeDirEnvironment) (string, e } resolvedHomeDir, err := filepath.EvalSymlinks(homeDir) if err != nil { - return "", errors.Wrapf(err, "cannot resolve %s", homeDir) + return "", err } return filepath.Join(resolvedHomeDir, "rundir"), nil } @@ -190,7 +190,7 @@ func getRootlessDirInfo(rootlessUID int) (string, string, error) { // on CoreOS /home is a symlink to /var/home, so resolve any symlink. resolvedHome, err := filepath.EvalSymlinks(home) if err != nil { - return "", "", errors.Wrapf(err, "cannot resolve %s", home) + return "", "", err } dataDir = filepath.Join(resolvedHome, ".local", "share") @@ -206,11 +206,10 @@ func getRootlessStorageOpts(rootlessUID int, systemOpts StoreOptions) (StoreOpti return opts, err } opts.RunRoot = rootlessRuntime - opts.GraphRoot = filepath.Join(dataDir, "containers", "storage") if systemOpts.RootlessStoragePath != "" { - opts.RootlessStoragePath = systemOpts.RootlessStoragePath + opts.GraphRoot = systemOpts.RootlessStoragePath } else { - opts.RootlessStoragePath = opts.GraphRoot + opts.GraphRoot = filepath.Join(dataDir, "containers", "storage") } if path, err := exec.LookPath("fuse-overlayfs"); err == nil { opts.GraphDriverName = "overlay" @@ -259,13 +258,24 @@ func defaultStoreOptionsIsolated(rootless bool, rootlessUID int, storageConf str } _, err = os.Stat(storageConf) if err != nil && !os.IsNotExist(err) { - return storageOpts, errors.Wrapf(err, "cannot stat %s", storageConf) + return storageOpts, err } - if err == nil { + if err == nil && !defaultConfigFileSet { defaultRootlessRunRoot = storageOpts.RunRoot defaultRootlessGraphRoot = storageOpts.GraphRoot storageOpts = StoreOptions{} reloadConfigurationFileIfNeeded(storageConf, &storageOpts) + if rootless && rootlessUID != 0 { + // If the file did not specify a graphroot or runroot, + // set sane defaults so we don't try and use root-owned + // directories + if storageOpts.RunRoot == "" { + storageOpts.RunRoot = defaultRootlessRunRoot + } + if storageOpts.GraphRoot == "" { + storageOpts.GraphRoot = defaultRootlessGraphRoot + } + } } if storageOpts.RunRoot != "" { runRoot, err := expandEnvPath(storageOpts.RunRoot, rootlessUID) @@ -282,26 +292,6 @@ func defaultStoreOptionsIsolated(rootless bool, rootlessUID int, storageConf str storageOpts.GraphRoot = graphRoot } - if rootless && rootlessUID != 0 { - if err == nil { - // If the file did not specify a graphroot or runroot, - // set sane defaults so we don't try and use root-owned - // directories - if storageOpts.RunRoot == "" { - storageOpts.RunRoot = defaultRootlessRunRoot - } - if storageOpts.GraphRoot == "" { - storageOpts.GraphRoot = defaultRootlessGraphRoot - } - if storageOpts.RootlessStoragePath != "" { - rootlessStoragePath, err := expandEnvPath(storageOpts.RootlessStoragePath, rootlessUID) - if err != nil { - return storageOpts, err - } - storageOpts.GraphRoot = rootlessStoragePath - } - } - } return storageOpts, nil } diff --git a/vendor/github.com/klauspost/compress/zstd/encoder_options.go b/vendor/github.com/klauspost/compress/zstd/encoder_options.go index 579206163..1209915bc 100644 --- a/vendor/github.com/klauspost/compress/zstd/encoder_options.go +++ b/vendor/github.com/klauspost/compress/zstd/encoder_options.go @@ -30,12 +30,13 @@ type encoderOptions struct { func (o *encoderOptions) setDefault() { *o = encoderOptions{ // use less ram: true for now, but may change. - concurrent: runtime.GOMAXPROCS(0), - crc: true, - single: nil, - blockSize: 1 << 16, - windowSize: 8 << 20, - level: SpeedDefault, + concurrent: runtime.GOMAXPROCS(0), + crc: true, + single: nil, + blockSize: 1 << 16, + windowSize: 8 << 20, + level: SpeedDefault, + allLitEntropy: true, } } diff --git a/vendor/github.com/moby/sys/mountinfo/doc.go b/vendor/github.com/moby/sys/mountinfo/doc.go index 21aa8dd59..b80e05efd 100644 --- a/vendor/github.com/moby/sys/mountinfo/doc.go +++ b/vendor/github.com/moby/sys/mountinfo/doc.go @@ -1,5 +1,6 @@ // Package mountinfo provides a set of functions to retrieve information about OS mounts. -// Currently it supports Linux. For historical reasons, there is also some support for FreeBSD, +// +// Currently it supports Linux. For historical reasons, there is also some support for FreeBSD and OpenBSD, // and a shallow implementation for Windows, but in general this is Linux-only package, so // the rest of the document only applies to Linux, unless explicitly specified otherwise. // @@ -8,17 +9,14 @@ // see different mounts. A per-process mountinfo table is available from /proc/<PID>/mountinfo, // where <PID> is a numerical process identifier. // -// In general, /proc is not a very effective interface, and mountinfo is not an exception. +// In general, /proc is not a very efficient interface, and mountinfo is not an exception. // For example, there is no way to get information about a specific mount point (i.e. it // is all-or-nothing). This package tries to hide the /proc ineffectiveness by using // parse filters while reading mountinfo. A filter can skip some entries, or stop // processing the rest of the file once the needed information is found. // -// For mountinfo filters that accept path as an argument, the path must be: -// - absolute; -// - having all symlinks resolved; -// - being cleaned. -// +// For mountinfo filters that accept path as an argument, the path must be absolute, +// having all symlinks resolved, and being cleaned (i.e. no extra slashes or dots). // One way to achieve all of the above is to employ filepath.Abs followed by // filepath.EvalSymlinks (the latter calls filepath.Clean on the result so // there is no need to explicitly call filepath.Clean). @@ -27,21 +25,20 @@ // of the cases where mountinfo should not be parsed: // // 1. Before performing a mount. Usually, this is not needed, but if required (say to -// prevent overmounts), to check whether a directory is mounted, call os.Lstat -// on it and its parent directory, and compare their st.Sys().(*syscall.Stat_t).Dev -// fields -- if they differ, then the directory is the mount point. NOTE this does -// not work for bind mounts. Optionally, the filesystem type can also be checked -// by calling unix.Statfs and checking the Type field (i.e. filesystem type). +// prevent over-mounts), to check whether a directory is mounted, call os.Lstat +// on it and its parent directory, and compare their st.Sys().(*syscall.Stat_t).Dev +// fields -- if they differ, then the directory is the mount point. NOTE this does +// not work for bind mounts. Optionally, the filesystem type can also be checked +// by calling unix.Statfs and checking the Type field (i.e. filesystem type). // // 2. After performing a mount. If there is no error returned, the mount succeeded; -// checking the mount table for a new mount is redundant and expensive. +// checking the mount table for a new mount is redundant and expensive. // // 3. Before performing an unmount. It is more efficient to do an unmount and ignore -// a specific error (EINVAL) which tells the directory is not mounted. +// a specific error (EINVAL) which tells the directory is not mounted. // // 4. After performing an unmount. If there is no error returned, the unmount succeeded. // // 5. To find the mount point root of a specific directory. You can perform os.Stat() -// on the directory and traverse up until the Dev field of a parent directory differs. - +// on the directory and traverse up until the Dev field of a parent directory differs. package mountinfo diff --git a/vendor/github.com/moby/sys/mountinfo/mounted_unix.go b/vendor/github.com/moby/sys/mountinfo/mounted_unix.go index c4d66b2f4..efb03978b 100644 --- a/vendor/github.com/moby/sys/mountinfo/mounted_unix.go +++ b/vendor/github.com/moby/sys/mountinfo/mounted_unix.go @@ -1,4 +1,4 @@ -// +build linux freebsd,cgo +// +build linux freebsd,cgo openbsd,cgo package mountinfo diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo.go b/vendor/github.com/moby/sys/mountinfo/mountinfo.go index 1987fcbb2..fe828c8f5 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo.go @@ -1,7 +1,6 @@ package mountinfo import ( - "io" "os" ) @@ -11,14 +10,6 @@ func GetMounts(f FilterFunc) ([]*Info, error) { return parseMountTable(f) } -// GetMountsFromReader retrieves a list of mounts from the -// reader provided, with an optional filter applied (use nil -// for no filter). This can be useful in tests or benchmarks -// that provide a fake mountinfo data. -func GetMountsFromReader(reader io.Reader, f FilterFunc) ([]*Info, error) { - return parseInfoFile(reader, f) -} - // Mounted determines if a specified path is a mount point. // // The argument must be an absolute path, with all symlinks resolved, and clean. @@ -55,18 +46,18 @@ type Info struct { // Mountpoint indicates the mount point relative to the process's root. Mountpoint string - // Opts represents mount-specific options. - Opts string + // Options represents mount-specific options. + Options string // Optional represents optional fields. Optional string - // Fstype indicates the type of filesystem, such as EXT3. - Fstype string + // FSType indicates the type of filesystem, such as EXT3. + FSType string // Source indicates filesystem specific information or "none". Source string - // VfsOpts represents per super block options. - VfsOpts string + // VFSOptions represents per super block options. + VFSOptions string } diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go index b30dc1625..b1c12d02b 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go @@ -1,3 +1,5 @@ +// +build freebsd,cgo openbsd,cgo + package mountinfo /* @@ -33,7 +35,7 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) { var mountinfo Info var skip, stop bool mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0]) - mountinfo.Fstype = C.GoString(&entry.f_fstypename[0]) + mountinfo.FSType = C.GoString(&entry.f_fstypename[0]) mountinfo.Source = C.GoString(&entry.f_mntfromname[0]) if filter != nil { @@ -54,7 +56,7 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) { func mounted(path string) (bool, error) { // Fast path: compare st.st_dev fields. - // This should always work for FreeBSD. + // This should always work for FreeBSD and OpenBSD. mounted, err := mountedByStat(path) if err == nil { return mounted, nil diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go index 8aebe1ad4..5869b2cee 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go @@ -6,12 +6,12 @@ import "strings" // used to filter out mountinfo entries we're not interested in, // and/or stop further processing if we found what we wanted. // -// It takes a pointer to the Info struct (not fully populated, -// currently only Mountpoint, Fstype, Source, and (on Linux) -// VfsOpts are filled in), and returns two booleans: +// It takes a pointer to the Info struct (fully populated with all available +// fields on the GOOS platform), and returns two booleans: // -// - skip: true if the entry should be skipped -// - stop: true if parsing should be stopped after the entry +// skip: true if the entry should be skipped; +// +// stop: true if parsing should be stopped after the entry. type FilterFunc func(*Info) (skip, stop bool) // PrefixFilter discards all entries whose mount points @@ -36,8 +36,8 @@ func SingleEntryFilter(mp string) FilterFunc { // ParentsFilter returns all entries whose mount points // can be parents of a path specified, discarding others. // -// For example, given `/var/lib/docker/something`, entries -// like `/var/lib/docker`, `/var` and `/` are returned. +// For example, given /var/lib/docker/something, entries +// like /var/lib/docker, /var and / are returned. func ParentsFilter(path string) FilterFunc { return func(m *Info) (bool, bool) { skip := !strings.HasPrefix(path, m.Mountpoint) @@ -45,12 +45,12 @@ func ParentsFilter(path string) FilterFunc { } } -// FstypeFilter returns all entries that match provided fstype(s). -func FstypeFilter(fstype ...string) FilterFunc { +// FSTypeFilter returns all entries that match provided fstype(s). +func FSTypeFilter(fstype ...string) FilterFunc { return func(m *Info) (bool, bool) { for _, t := range fstype { - if m.Fstype == t { - return false, false // don't skeep, keep going + if m.FSType == t { + return false, false // don't skip, keep going } } return true, false // skip, keep going diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go index cdfd37da5..e591c8365 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go @@ -1,5 +1,3 @@ -// +build go1.13 - package mountinfo import ( @@ -11,14 +9,18 @@ import ( "strings" ) -func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) { +// GetMountsFromReader retrieves a list of mounts from the +// reader provided, with an optional filter applied (use nil +// for no filter). This can be useful in tests or benchmarks +// that provide a fake mountinfo data. +// +// This function is Linux-specific. +func GetMountsFromReader(r io.Reader, filter FilterFunc) ([]*Info, error) { s := bufio.NewScanner(r) out := []*Info{} - var err error for s.Scan() { - if err = s.Err(); err != nil { - return nil, err - } + var err error + /* See http://man7.org/linux/man-pages/man5/proc.5.html @@ -70,12 +72,11 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) { p := &Info{} - // Fill in the fields that a filter might check p.Mountpoint, err = unescape(fields[4]) if err != nil { return nil, fmt.Errorf("Parsing '%s' failed: mount point: %w", fields[4], err) } - p.Fstype, err = unescape(fields[sepIdx+1]) + p.FSType, err = unescape(fields[sepIdx+1]) if err != nil { return nil, fmt.Errorf("Parsing '%s' failed: fstype: %w", fields[sepIdx+1], err) } @@ -83,19 +84,7 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) { if err != nil { return nil, fmt.Errorf("Parsing '%s' failed: source: %w", fields[sepIdx+2], err) } - p.VfsOpts = fields[sepIdx+3] - - // Run a filter soon so we can skip parsing/adding entries - // the caller is not interested in - var skip, stop bool - if filter != nil { - skip, stop = filter(p) - if skip { - continue - } - } - - // Fill in the rest of the fields + p.VFSOptions = fields[sepIdx+3] // ignore any numbers parsing errors, as there should not be any p.ID, _ = strconv.Atoi(fields[0]) @@ -112,7 +101,7 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) { return nil, fmt.Errorf("Parsing '%s' failed: root: %w", fields[3], err) } - p.Opts = fields[5] + p.Options = fields[5] // zero or more optional fields switch { @@ -124,11 +113,23 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) { p.Optional = strings.Join(fields[6:sepIdx-1], " ") } + // Run the filter after parsing all of the fields. + var skip, stop bool + if filter != nil { + skip, stop = filter(p) + if skip { + continue + } + } + out = append(out, p) if stop { break } } + if err := s.Err(); err != nil { + return nil, err + } return out, nil } @@ -141,12 +142,17 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) { } defer f.Close() - return parseInfoFile(f, filter) + return GetMountsFromReader(f, filter) } -// PidMountInfo collects the mounts for a specific process ID. If the process -// ID is unknown, it is better to use `GetMounts` which will inspect -// "/proc/self/mountinfo" instead. +// PidMountInfo retrieves the list of mounts from a given process' mount +// namespace. Unless there is a need to get mounts from a mount namespace +// different from that of a calling process, use GetMounts. +// +// This function is Linux-specific. +// +// Deprecated: this will be removed before v1; use GetMountsFromReader with +// opened /proc/<pid>/mountinfo as an argument instead. func PidMountInfo(pid int) ([]*Info, error) { f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid)) if err != nil { @@ -154,7 +160,7 @@ func PidMountInfo(pid int) ([]*Info, error) { } defer f.Close() - return parseInfoFile(f, nil) + return GetMountsFromReader(f, nil) } // A few specific characters in mountinfo path entries (root and mountpoint) @@ -173,7 +179,7 @@ func unescape(path string) (string, error) { } // The following code is UTF-8 transparent as it only looks for some - // specific characters (backslach and 0..7) with values < utf8.RuneSelf, + // specific characters (backslash and 0..7) with values < utf8.RuneSelf, // and everything else is passed through as is. buf := make([]byte, len(path)) bufLen := 0 diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go index 1eb8558c8..d33ebca09 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go @@ -1,10 +1,9 @@ -// +build !windows,!linux,!freebsd freebsd,!cgo +// +build !windows,!linux,!freebsd,!openbsd freebsd,!cgo openbsd,!cgo package mountinfo import ( "fmt" - "io" "runtime" ) @@ -14,10 +13,6 @@ func parseMountTable(_ FilterFunc) ([]*Info, error) { return nil, errNotImplemented } -func parseInfoFile(_ io.Reader, f FilterFunc) ([]*Info, error) { - return parseMountTable(f) -} - func mounted(path string) (bool, error) { return false, errNotImplemented } diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go index 5659c1b0f..13fad165e 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go @@ -1,16 +1,10 @@ package mountinfo -import "io" - func parseMountTable(_ FilterFunc) ([]*Info, error) { // Do NOT return an error! return nil, nil } -func parseInfoFile(_ io.Reader, f FilterFunc) ([]*Info, error) { - return parseMountTable(f) -} - func mounted(_ string) (bool, error) { return false, nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index 907dc944b..73c7402c9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -86,7 +86,7 @@ github.com/containers/buildah/pkg/secrets github.com/containers/buildah/pkg/supplemented github.com/containers/buildah/pkg/umask github.com/containers/buildah/util -# github.com/containers/common v0.26.0 +# github.com/containers/common v0.26.3 github.com/containers/common/pkg/apparmor github.com/containers/common/pkg/apparmor/internal/supported github.com/containers/common/pkg/auth @@ -102,7 +102,7 @@ github.com/containers/common/pkg/sysinfo github.com/containers/common/version # github.com/containers/conmon v2.0.20+incompatible github.com/containers/conmon/runner/config -# github.com/containers/image/v5 v5.6.0 +# github.com/containers/image/v5 v5.7.0 github.com/containers/image/v5/copy github.com/containers/image/v5/directory github.com/containers/image/v5/directory/explicitfilepath @@ -117,6 +117,7 @@ github.com/containers/image/v5/image github.com/containers/image/v5/internal/iolimits github.com/containers/image/v5/internal/pkg/keyctl github.com/containers/image/v5/internal/pkg/platform +github.com/containers/image/v5/internal/rootless github.com/containers/image/v5/internal/tmpdir github.com/containers/image/v5/internal/uploadreader github.com/containers/image/v5/manifest @@ -164,7 +165,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.23.5 +# github.com/containers/storage v1.23.7 github.com/containers/storage github.com/containers/storage/drivers github.com/containers/storage/drivers/aufs @@ -332,7 +333,7 @@ github.com/inconshreveable/mousetrap github.com/ishidawataru/sctp # github.com/json-iterator/go v1.1.10 github.com/json-iterator/go -# github.com/klauspost/compress v1.11.0 +# github.com/klauspost/compress v1.11.1 github.com/klauspost/compress/flate github.com/klauspost/compress/fse github.com/klauspost/compress/huff0 @@ -351,7 +352,7 @@ github.com/matttproud/golang_protobuf_extensions/pbutil github.com/mistifyio/go-zfs # github.com/moby/sys/mount v0.1.1 github.com/moby/sys/mount -# github.com/moby/sys/mountinfo v0.2.0 +# github.com/moby/sys/mountinfo v0.4.0 github.com/moby/sys/mountinfo # github.com/moby/term v0.0.0-20200915141129-7f0af18e79f2 github.com/moby/term |