summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/generate/systemd.go8
-rwxr-xr-xcontrib/cirrus/logformatter34
-rwxr-xr-xcontrib/cirrus/logformatter.t72
-rw-r--r--docs/source/markdown/podman-generate-systemd.1.md5
-rw-r--r--go.mod6
-rw-r--r--go.sum18
-rw-r--r--pkg/api/handlers/compat/images_push.go10
-rw-r--r--pkg/api/handlers/libpod/generate.go2
-rw-r--r--pkg/api/server/register_generate.go5
-rw-r--r--pkg/bindings/generate/types.go2
-rw-r--r--pkg/bindings/generate/types_systemd_options.go15
-rw-r--r--pkg/domain/entities/generate.go2
-rw-r--r--pkg/domain/infra/abi/images.go12
-rw-r--r--pkg/domain/infra/abi/play.go71
-rw-r--r--pkg/domain/infra/tunnel/generate.go3
-rw-r--r--pkg/specgen/generate/kube/kube.go12
-rw-r--r--pkg/specgen/generate/kube/volume.go64
-rw-r--r--pkg/systemd/generate/pods.go9
-rw-r--r--pkg/systemd/generate/pods_test.go46
-rw-r--r--test/e2e/generate_systemd_test.go13
-rw-r--r--test/e2e/play_kube_test.go116
-rw-r--r--vendor/github.com/containers/common/libimage/pull.go2
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go3
-rw-r--r--vendor/github.com/containers/common/pkg/config/containers.conf6
-rw-r--r--vendor/github.com/containers/common/pkg/config/nosystemd.go4
-rw-r--r--vendor/github.com/containers/common/pkg/config/systemd.go20
-rw-r--r--vendor/github.com/containers/common/pkg/manifests/manifests.go2
-rw-r--r--vendor/github.com/containers/storage/.cirrus.yml4
-rw-r--r--vendor/github.com/containers/storage/Vagrantfile25
-rw-r--r--vendor/github.com/containers/storage/go.mod1
-rw-r--r--vendor/github.com/containers/storage/go.sum2
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/archive.go7
-rw-r--r--vendor/github.com/containers/storage/pkg/chunked/storage_linux.go327
-rw-r--r--vendor/github.com/containers/storage/types/options.go4
-rw-r--r--vendor/github.com/jinzhu/copier/copier.go13
-rw-r--r--vendor/github.com/jinzhu/copier/go.mod2
-rw-r--r--vendor/github.com/mitchellh/mapstructure/CHANGELOG.md4
-rw-r--r--vendor/github.com/mitchellh/mapstructure/mapstructure.go8
-rw-r--r--vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go3
-rw-r--r--vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go3
-rw-r--r--vendor/github.com/opencontainers/image-spec/specs-go/version.go2
-rw-r--r--vendor/modules.txt10
42 files changed, 800 insertions, 177 deletions
diff --git a/cmd/podman/generate/systemd.go b/cmd/podman/generate/systemd.go
index 173b3656b..a363b7e94 100644
--- a/cmd/podman/generate/systemd.go
+++ b/cmd/podman/generate/systemd.go
@@ -23,6 +23,7 @@ const (
stopTimeoutFlagName = "stop-timeout"
stopTimeoutCompatFlagName = "time"
restartPolicyFlagName = "restart-policy"
+ restartSecFlagName = "restart-sec"
newFlagName = "new"
)
@@ -30,6 +31,7 @@ var (
files bool
format string
systemdRestart string
+ systemdRestartSec uint
startTimeout uint
stopTimeout uint
systemdOptions = entities.GenerateSystemdOptions{}
@@ -88,6 +90,9 @@ func init() {
flags.StringVar(&systemdRestart, restartPolicyFlagName, systemDefine.DefaultRestartPolicy, "Systemd restart-policy")
_ = systemdCmd.RegisterFlagCompletionFunc(restartPolicyFlagName, common.AutocompleteSystemdRestartOptions)
+ flags.UintVarP(&systemdRestartSec, restartSecFlagName, "", 0, "Systemd restart-sec")
+ _ = systemdCmd.RegisterFlagCompletionFunc(restartSecFlagName, completion.AutocompleteNone)
+
formatFlagName := "format"
flags.StringVar(&format, formatFlagName, "", "Print the created units in specified format (json)")
_ = systemdCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil))
@@ -111,6 +116,9 @@ func systemd(cmd *cobra.Command, args []string) error {
systemdOptions.New = true
}
+ if cmd.Flags().Changed(restartSecFlagName) {
+ systemdOptions.RestartSec = &systemdRestartSec
+ }
if cmd.Flags().Changed(startTimeoutFlagName) {
systemdOptions.StartTimeout = &startTimeout
}
diff --git a/contrib/cirrus/logformatter b/contrib/cirrus/logformatter
index 5156f9f8a..70f119b5b 100755
--- a/contrib/cirrus/logformatter
+++ b/contrib/cirrus/logformatter
@@ -37,12 +37,15 @@ table.synopsis { border: none; border-collapse: collapse; margin-left: 2em; marg
.synopsis td { font-weight: bold; font-size: 120%; font-family: monospace; }
/* test results */
+.testname { font-size: 125%; color: #444; }
.boring { color: #999; }
.timestamp { color: #999; }
.log-debug { color: #999; }
.log-info { color: #333; }
.log-warn { color: #f60; }
.log-error { color: #900; font-weight: bold; }
+.log-skip { color: #F90; }
+.log-slow { background: #FF0; color: #000; font-weight: bold; }
.subtest { background: #eee; }
.subsubtest { color: #F39; font-weight: bold; }
.string { color: #00c; }
@@ -205,11 +208,17 @@ END_HTML
print { $out_fh } "<pre> <!-- begin processed output -->\n";
+ # Assume rootful prompt, check for rootless (here and in log itself, below)
+ my $Prompt = '#';
+ $Prompt = '$' if $test_name =~ /rootless/;
+
# Main loop: read input, one line at a time, and write out reformatted
LINE:
while (my $line = <STDIN>) {
print $line; # Immediately dump back to stdout
+ $Prompt = '$' if $line =~ /Runner executing .* as rootless /;
+
# Remain robust in face of errors: always write stdout even if no HTML
next LINE if ! $out_fh;
@@ -328,7 +337,7 @@ END_HTML
next LINE;
}
# (bindings test sometimes emits 'Running' with leading bullet char)
- elsif ($line =~ /^•?Running:/) {
+ elsif ($line =~ s!^•?Running:!<span class="boring">$Prompt</span>!) {
# Highlight the important (non-boilerplate) podman command.
$line =~ s/\s+--remote\s+/ /g; # --remote takes no args
# Strip out the global podman options, but show them on hover
@@ -365,19 +374,27 @@ END_HTML
# an anchor so we can link to it later.
if ($after_divider++ == 2) {
# Sigh. There is no actual marker. Assume that anything with
- ## two leading spaces then alpha (not slashes) is a test name.
- if ($line =~ /^ [a-zA-Z]/) {
+ ## two leading spaces then alpha or hyphen (not slashes) is
+ ## a test name.
+ if ($line =~ /^ [a-zA-Z-]/) {
my $id = make_id($line, 'anchor');
$line = "<a name='t--$id'><h2>$line</h2></a>";
}
}
+ # Make SKIPPING and SLOW TEST visible
+ $line =~ s!(\[SKIPPING\].*)!<span class="log-skip">$1</span>!;
+ $line =~ s!(\[SLOW TEST.*\])!<span class="log-slow">$1</span>!;
+
+ # Highlight test name when it appears in the middle of commands.
+ # But make it boring, because we already have the test name in large
+ # bold just above. (Except in skipped tests).
+ $line =~ s!^(\s*)(\[It\]\s+.*)!$1<span class="testname">$2</span>!;
+
# Failure name corresponds to a previously-seen block.
- ## FIXME: sometimes there are three failures with the same name.
- ## ...I have no idea why or how to link to the right ones.
- # 1 2 2 3 3 14 4
- if ($line =~ /^(\[(Fail|Panic!)\] .* \[(It|BeforeEach)\] )([A-Za-z].*)/) {
+ # 1 2 2 3 3 14 4
+ if ($line =~ /^(\[(Fail|Panic!)\] .* \[(It|BeforeEach)\] )([A-Za-z-].*)/) {
my ($lhs, $type, $ginkgo_fluff, $testname) = ($1, $2, $3, $4);
my $id = make_id($testname, 'link');
@@ -486,7 +503,10 @@ sub make_id {
state %counter;
$name =~ s/^\s+|\s+$//g; # strip leading/trailing whitespace
+ $name =~ s/\&#\d+;//g; # 'doesn&#39;t' -> 'doesnt'
+ $name =~ s/\&quot;/-/g; # '&quot;path&quot;' -> '-path-'
$name =~ s/[^a-zA-Z0-9_-]/-/g; # Convert non-alphanumeric to dash
+ $name =~ s/-{3,}/-/g; # '------' to just '-'
# Keep a running tally of how many times we've seen this identifier
# for this given type! This lets us cross-match, in the bottom of
diff --git a/contrib/cirrus/logformatter.t b/contrib/cirrus/logformatter.t
index bd4179b5e..d905693ad 100755
--- a/contrib/cirrus/logformatter.t
+++ b/contrib/cirrus/logformatter.t
@@ -134,9 +134,35 @@ $SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}
[+0103s] 4810be0cfbd42241e349dbe7d50fbc54405cd320a6637c65fd5323f34d64af89
[+0104s] Running: /var/tmp/go/src/github.com/containers/libpod/bin/podman-remote --storage-opt vfs.imagestore=/tmp/podman/imagecachedir --root /tmp/podman_test553496330/crio --runroot /tmp/podman_test553496330/crio-run --runtime /usr/bin/runc --conmon /usr/bin/conmon --cni-config-dir /etc/cni/net.d --cgroup-manager systemd --tmpdir /tmp/podman_test553496330 --events-backend file --storage-driver vfs --remote --url unix:/run/user/12345/podman-xyz.sock pod rm -fa
[+0104s] 4810be0cfbd42241e349dbe7d50fbc54405cd320a6637c65fd5323f34d64af89 again
+
+
[+0107s] •
-[+0107s] ------------------------------
-[+0107s] podman system reset
+[+0523s] ------------------------------
+[+0523s] Podman play kube with build
+[+0523s] --build should override image in store
+[+0523s] /var/tmp/go/src/github.com/containers/podman/test/e2e/play_build_test.go:215
+
+
+[+0479s] •
+[+0479s] ------------------------------
+[+0479s] Podman pod rm
+[+0479s] podman pod rm -a doesn't remove a running container
+[+0479s] /var/tmp/go/src/github.com/containers/podman/test/e2e/pod_rm_test.go:119
+
+
+[+1405s] •
+[+1405s] ------------------------------
+[+1405s] Podman run entrypoint
+[+1405s] podman run entrypoint == [""]
+[+1405s] /var/tmp/go/src/github.com/containers/podman/test/e2e/run_entrypoint_test.go:47
+
+[+0184s] S [SKIPPING] [3.086 seconds]
+[+1385s] S [SKIPPING] in Spec Setup (BeforeEach) [0.001 seconds]
+
+[+1512s] Summarizing 6 Failures:
+[+1512s]
+[+1512s] [Fail] Podman play kube with build [It] --build should override image in store
+[+1512s] /var/tmp/go/src/github.com/containers/podman/test/e2e/play_build_test.go:259
>>>
$SCRIPT_BASE/integration_test.sh |&amp; ${TIMESTAMP}
[08:26:19] START - All [+xxxx] lines that follow are relative to right now.
@@ -150,9 +176,9 @@ $SCRIPT_BASE/integration_test.sh |&amp; ${TIMESTAMP}
<span class="timestamp"> </span> /var/tmp/go/src/github.com<a class="codelink" href='https://github.com/containers/podman/blob/40f5d8b1becd381c4e8283ed3940d09193e4fe06/test/e2e/pod_restart_test.go#L41'>/containers/podman/test/e2e/pod_restart_test.go:41</a>
<span class="timestamp"> </span>[BeforeEach] Podman pod restart
<span class="timestamp"> </span> /var/tmp/go/src/github.com<a class="codelink" href='https://github.com/containers/podman/blob/40f5d8b1becd381c4e8283ed3940d09193e4fe06/test/e2e/pod_restart_test.go#L18'>/containers/podman/test/e2e/pod_restart_test.go:18</a>
-<span class="timestamp"> </span>[It] podman pod restart single empty pod
+<span class="timestamp"> </span><span class="testname">[It] podman pod restart single empty pod</span>
<span class="timestamp"> </span> /var/tmp/go/src/github.com<a class="codelink" href='https://github.com/containers/podman/blob/40f5d8b1becd381c4e8283ed3940d09193e4fe06/test/e2e/pod_restart_test.go#L41'>/containers/podman/test/e2e/pod_restart_test.go:41</a>
-<span class="timestamp"> </span>Running: <span title="/var/tmp/go/src/github.com/containers/podman/bin/podman"><b>podman</b></span> <span class="boring" title="--storage-opt vfs.imagestore=/tmp/podman/imagecachedir
+<span class="timestamp"> </span><span class="boring">#</span> <span title="/var/tmp/go/src/github.com/containers/podman/bin/podman"><b>podman</b></span> <span class="boring" title="--storage-opt vfs.imagestore=/tmp/podman/imagecachedir
--root /tmp/podman_test553496330/crio
--runroot /tmp/podman_test553496330/crio-run
--runtime /usr/bin/runc
@@ -163,7 +189,7 @@ $SCRIPT_BASE/integration_test.sh |&amp; ${TIMESTAMP}
--events-backend file
--storage-driver vfs">[options]</span><b> pod create --infra=false --share</b>
<span class="timestamp"> </span>4810be0cfbd42241e349dbe7d50fbc54405cd320a6637c65fd5323f34d64af89
-<span class="timestamp"> </span>Running: <span title="/var/tmp/go/src/github.com/containers/podman/bin/podman"><b>podman</b></span> <span class="boring" title="--storage-opt vfs.imagestore=/tmp/podman/imagecachedir
+<span class="timestamp"> </span><span class="boring">#</span> <span title="/var/tmp/go/src/github.com/containers/podman/bin/podman"><b>podman</b></span> <span class="boring" title="--storage-opt vfs.imagestore=/tmp/podman/imagecachedir
--root /tmp/podman_test553496330/crio
--runroot /tmp/podman_test553496330/crio-run
--runtime /usr/bin/runc
@@ -177,7 +203,7 @@ $SCRIPT_BASE/integration_test.sh |&amp; ${TIMESTAMP}
<span class="timestamp"> </span>output:
<span class="timestamp"> </span>[AfterEach] Podman pod restart
<span class="timestamp"> </span> /var/tmp/go/src/github.com<a class="codelink" href='https://github.com/containers/podman/blob/40f5d8b1becd381c4e8283ed3940d09193e4fe06/test/e2e/pod_restart_test.go#L28'>/containers/podman/test/e2e/pod_restart_test.go:28</a>
-<span class="timestamp"> </span>Running: <span title="/var/tmp/go/src/github.com/containers/podman/bin/podman"><b>podman</b></span> <span class="boring" title="--storage-opt vfs.imagestore=/tmp/podman/imagecachedir
+<span class="timestamp"> </span><span class="boring">#</span> <span title="/var/tmp/go/src/github.com/containers/podman/bin/podman"><b>podman</b></span> <span class="boring" title="--storage-opt vfs.imagestore=/tmp/podman/imagecachedir
--root /tmp/podman_test553496330/crio
--runroot /tmp/podman_test553496330/crio-run
--runtime /usr/bin/runc
@@ -189,7 +215,7 @@ $SCRIPT_BASE/integration_test.sh |&amp; ${TIMESTAMP}
--storage-driver vfs">[options]</span><b> pod rm -fa</b>
<span class="timestamp"> </span>4810be0cfbd42241e349dbe7d50fbc54405cd320a6637c65fd5323f34d64af89
-<span class="timestamp">[+0104s] </span>Running: <span title="/var/tmp/go/src/github.com/containers/libpod/bin/podman-remote"><b>podman-remote</b></span> <span class="boring" title="--storage-opt vfs.imagestore=/tmp/podman/imagecachedir
+<span class="timestamp">[+0104s] </span><span class="boring">#</span> <span title="/var/tmp/go/src/github.com/containers/libpod/bin/podman-remote"><b>podman-remote</b></span> <span class="boring" title="--storage-opt vfs.imagestore=/tmp/podman/imagecachedir
--root /tmp/podman_test553496330/crio
--runroot /tmp/podman_test553496330/crio-run
--runtime /usr/bin/runc
@@ -207,4 +233,34 @@ $SCRIPT_BASE/integration_test.sh |&amp; ${TIMESTAMP}
</pre>
<hr />
<pre>
-<span class="timestamp">[+0107s] </span>podman system reset
+<span class="timestamp">[+0523s] </span>Podman play kube with build
+<span class="timestamp"> </span><a name='t----build-should-override-image-in-store--1'><h2> --build should override image in store</h2></a>
+<span class="timestamp"> </span> /var/tmp/go/src/github.com<a class="codelink" href='https://github.com/containers/podman/blob/40f5d8b1becd381c4e8283ed3940d09193e4fe06/test/e2e/play_build_test.go#L215'>/containers/podman/test/e2e/play_build_test.go:215</a>
+
+
+<span class="timestamp">[+0479s] </span>•
+</pre>
+<hr />
+<pre>
+<span class="timestamp">[+0479s] </span>Podman pod rm
+<span class="timestamp"> </span><a name='t--podman-pod-rm--a-doesnt-remove-a-running-container--1'><h2> podman pod rm -a doesn&#39;t remove a running container</h2></a>
+<span class="timestamp"> </span> /var/tmp/go/src/github.com<a class="codelink" href='https://github.com/containers/podman/blob/40f5d8b1becd381c4e8283ed3940d09193e4fe06/test/e2e/pod_rm_test.go#L119'>/containers/podman/test/e2e/pod_rm_test.go:119</a>
+
+
+<span class="timestamp">[+1405s] </span>•
+</pre>
+<hr />
+<pre>
+<span class="timestamp">[+1405s] </span>Podman run entrypoint
+<span class="timestamp"> </span><a name='t--podman-run-entrypoint---1'><h2> podman run entrypoint == [&quot;&quot;]</h2></a>
+<span class="timestamp"> </span> /var/tmp/go/src/github.com<a class="codelink" href='https://github.com/containers/podman/blob/40f5d8b1becd381c4e8283ed3940d09193e4fe06/test/e2e/run_entrypoint_test.go#L47'>/containers/podman/test/e2e/run_entrypoint_test.go:47</a>
+
+
+<span class="timestamp">[+0184s] </span>S <span class="log-skip">[SKIPPING] [3.086 seconds]</span>
+<span class="timestamp">[+1385s] </span>S <span class="log-skip">[SKIPPING] in Spec Setup (BeforeEach) [0.001 seconds]</span>
+
+
+<span class="timestamp">[+1512s] </span>Summarizing 6 Failures:
+[+1512s]
+<span class="timestamp"> </span><b>[Fail] Podman play kube with build [It] <a href='#t----build-should-override-image-in-store--1'>--build should override image in store</a></b>
+<span class="timestamp"> </span>/var/tmp/go/src/github.com<a class="codelink" href='https://github.com/containers/podman/blob/40f5d8b1becd381c4e8283ed3940d09193e4fe06/test/e2e/play_build_test.go#L259'>/containers/podman/test/e2e/play_build_test.go:259</a>
diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md
index bdcaa8ef1..363d042ae 100644
--- a/docs/source/markdown/podman-generate-systemd.1.md
+++ b/docs/source/markdown/podman-generate-systemd.1.md
@@ -51,6 +51,11 @@ Override the default stop timeout for the container with the given value in seco
Set the systemd restart policy. The restart-policy must be one of: "no", "on-success", "on-failure", "on-abnormal",
"on-watchdog", "on-abort", or "always". The default policy is *on-failure*.
+#### **--restart-sec**=*time*
+
+Set the systemd service restartsec value. Configures the time to sleep before restarting a service (as configured with restart-policy).
+Takes a value in seconds.
+
#### **--container-prefix**=*prefix*
Set the systemd unit name prefix for containers. The default is *container*.
diff --git a/go.mod b/go.mod
index 82dc3dfc3..2bdb97244 100644
--- a/go.mod
+++ b/go.mod
@@ -12,12 +12,12 @@ require (
github.com/containernetworking/cni v1.0.1
github.com/containernetworking/plugins v1.0.1
github.com/containers/buildah v1.23.1
- github.com/containers/common v0.46.1-0.20211125160015-ccf46abecd91
+ github.com/containers/common v0.46.1-0.20211202172647-e77d74bd1976
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.17.1-0.20211129144953-4f6d0b45be6c
github.com/containers/ocicrypt v1.1.2
github.com/containers/psgo v1.7.1
- github.com/containers/storage v1.37.1-0.20211122214631-59ba58582415
+ github.com/containers/storage v1.37.1-0.20211130181259-1a158c89a518
github.com/coreos/go-systemd/v22 v22.3.2
github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3
github.com/cyphar/filepath-securejoin v0.2.3
@@ -46,7 +46,7 @@ require (
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.17.0
github.com/opencontainers/go-digest v1.0.0
- github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283
+ github.com/opencontainers/image-spec v1.0.2-0.20211123152302-43a7dee1ec31
github.com/opencontainers/runc v1.0.2
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
github.com/opencontainers/runtime-tools v0.9.1-0.20211020193359-09d837bf40a7
diff --git a/go.sum b/go.sum
index 09a30d2a7..1bda27de7 100644
--- a/go.sum
+++ b/go.sum
@@ -262,8 +262,8 @@ github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNB
github.com/containers/buildah v1.23.1 h1:Tpc9DsRuU+0Oofewpxb6OJVNQjCu7yloN/obUqzfDTY=
github.com/containers/buildah v1.23.1/go.mod h1:4WnrN0yrA7ab0ppgunixu2WM1rlD2rG8QLJAKbEkZlQ=
github.com/containers/common v0.44.2/go.mod h1:7sdP4vmI5Bm6FPFxb3lvAh1Iktb6tiO1MzjUzhxdoGo=
-github.com/containers/common v0.46.1-0.20211125160015-ccf46abecd91 h1:h9SrSLSQkvluH/sEJ8X1rlBqCoGJtLvSOu4OGK0Qtuw=
-github.com/containers/common v0.46.1-0.20211125160015-ccf46abecd91/go.mod h1:PHwsa3UBgbvn2/MwpTQvyHXvVpuwfBrlDBx3GpIRPDQ=
+github.com/containers/common v0.46.1-0.20211202172647-e77d74bd1976 h1:xVOGL69ge+1RirZvnrEl9nATL75udt/Hy2BN8qcmeNY=
+github.com/containers/common v0.46.1-0.20211202172647-e77d74bd1976/go.mod h1:J8MxXan58zAWbNgpj4ODPlzsuJnYvNc2zKJCZPIMHYQ=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.16.0/go.mod h1:XgTpfAPLRGOd1XYyCU5cISFr777bLmOerCSpt/v7+Q4=
@@ -284,8 +284,8 @@ github.com/containers/storage v1.35.0/go.mod h1:qzYhasQP2/V9D9XdO+vRwkHBhsBO0ozn
github.com/containers/storage v1.36.0/go.mod h1:vbd3SKVQNHdmU5qQI6hTEcKPxnZkGqydG4f6uwrI5a8=
github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4=
github.com/containers/storage v1.37.1-0.20211119174841-bf170b3ddac0/go.mod h1:XjCNlt5JUUmRuTJXhFxHb9hHGPho7DNg3o4N/14prdQ=
-github.com/containers/storage v1.37.1-0.20211122214631-59ba58582415 h1:iqTDpYOxZibrkC7Mo7gCXuJDIT7wyIU432RTmRhlZqY=
-github.com/containers/storage v1.37.1-0.20211122214631-59ba58582415/go.mod h1:hvKpaiPRALDI7oz4Jx+AEch8iS/viRnc22HPilQROWU=
+github.com/containers/storage v1.37.1-0.20211130181259-1a158c89a518 h1:p44O35V8XCefRxOxU1aY6eT9XNMxkWA1drtJpsl211c=
+github.com/containers/storage v1.37.1-0.20211130181259-1a158c89a518/go.mod h1:T5DX08T/eKKRs0WGDhC/ztngMSth6YuHq15eF8C/Y5A=
github.com/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=
@@ -592,8 +592,9 @@ github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee h1:PAXLXk1heNZ5y
github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw=
-github.com/jinzhu/copier v0.3.2 h1:QdBOCbaouLDYaIPFfi1bKv5F5tPpeTwXe4sD0jqtz5w=
github.com/jinzhu/copier v0.3.2/go.mod h1:24xnZezI2Yqac9J61UC6/dG/k76ttpq0DdJI3QmUvro=
+github.com/jinzhu/copier v0.3.4 h1:mfU6jI9PtCeUjkjQ322dlff9ELjGDu975C2p/nrubVI=
+github.com/jinzhu/copier v0.3.4/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
@@ -693,8 +694,8 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo=
-github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
+github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
@@ -761,8 +762,9 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
-github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283 h1:TVzvdjOalkJBNkbpPVMAr4KV9QRf2IjfxdyxwAK78Gs=
github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
+github.com/opencontainers/image-spec v1.0.2-0.20211123152302-43a7dee1ec31 h1:Wh4aR2I6JFwySre9m3iHJYuMnvUFE/HT6qAXozRWi/E=
+github.com/opencontainers/image-spec v1.0.2-0.20211123152302-43a7dee1ec31/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
diff --git a/pkg/api/handlers/compat/images_push.go b/pkg/api/handlers/compat/images_push.go
index 5ecb429ae..3a84b5799 100644
--- a/pkg/api/handlers/compat/images_push.go
+++ b/pkg/api/handlers/compat/images_push.go
@@ -74,10 +74,16 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
return
}
imageName = possiblyNormalizedName
- if _, _, err := runtime.LibimageRuntime().LookupImage(possiblyNormalizedName, nil); err != nil {
+ localImage, _, err := runtime.LibimageRuntime().LookupImage(possiblyNormalizedName, nil)
+ if err != nil {
utils.ImageNotFound(w, imageName, errors.Wrapf(err, "failed to find image %s", imageName))
return
}
+ rawManifest, _, err := localImage.Manifest(r.Context())
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, err)
+ return
+ }
authconf, authfile, key, err := auth.GetCredentials(r)
if err != nil {
@@ -196,7 +202,7 @@ loop: // break out of for/select infinite loop
if tag == "" {
tag = "latest"
}
- report.Status = fmt.Sprintf("%s: digest: %s", tag, string(digestBytes))
+ report.Status = fmt.Sprintf("%s: digest: %s size: %d", tag, string(digestBytes), len(rawManifest))
if err := enc.Encode(report); err != nil {
logrus.Warnf("Failed to json encode error %q", err.Error())
}
diff --git a/pkg/api/handlers/libpod/generate.go b/pkg/api/handlers/libpod/generate.go
index 1411c680e..88fd69d45 100644
--- a/pkg/api/handlers/libpod/generate.go
+++ b/pkg/api/handlers/libpod/generate.go
@@ -22,6 +22,7 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) {
NoHeader bool `schema:"noHeader"`
TemplateUnitFile bool `schema:"templateUnitFile"`
RestartPolicy *string `schema:"restartPolicy"`
+ RestartSec uint `schema:"restartSec"`
StopTimeout uint `schema:"stopTimeout"`
StartTimeout uint `schema:"startTimeout"`
ContainerPrefix string `schema:"containerPrefix"`
@@ -53,6 +54,7 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) {
ContainerPrefix: query.ContainerPrefix,
PodPrefix: query.PodPrefix,
Separator: query.Separator,
+ RestartSec: &query.RestartSec,
}
report, err := containerEngine.GenerateSystemd(r.Context(), utils.GetName(r), options)
diff --git a/pkg/api/server/register_generate.go b/pkg/api/server/register_generate.go
index 0e36394cf..65340bf56 100644
--- a/pkg/api/server/register_generate.go
+++ b/pkg/api/server/register_generate.go
@@ -67,6 +67,11 @@ func (s *APIServer) registerGenerateHandlers(r *mux.Router) error {
// type: string
// default: "-"
// description: Systemd unit name separator between name/id and prefix.
+ // - in: query
+ // name: restartSec
+ // type: integer
+ // default: 0
+ // description: Configures the time to sleep before restarting a service.
// produces:
// - application/json
// responses:
diff --git a/pkg/bindings/generate/types.go b/pkg/bindings/generate/types.go
index 092474e4a..ce560c547 100644
--- a/pkg/bindings/generate/types.go
+++ b/pkg/bindings/generate/types.go
@@ -20,6 +20,8 @@ type SystemdOptions struct {
TemplateUnitFile *bool
// RestartPolicy - systemd restart policy.
RestartPolicy *string
+ // RestartSec - systemd service restartsec. Configures the time to sleep before restarting a service.
+ RestartSec *uint
// StartTimeout - time when starting the container.
StartTimeout *uint
// StopTimeout - time when stopping the container.
diff --git a/pkg/bindings/generate/types_systemd_options.go b/pkg/bindings/generate/types_systemd_options.go
index d60f1d70e..504d4da7f 100644
--- a/pkg/bindings/generate/types_systemd_options.go
+++ b/pkg/bindings/generate/types_systemd_options.go
@@ -92,6 +92,21 @@ func (o *SystemdOptions) GetRestartPolicy() string {
return *o.RestartPolicy
}
+// WithRestartSec set field RestartSec to given value
+func (o *SystemdOptions) WithRestartSec(value uint) *SystemdOptions {
+ o.RestartSec = &value
+ return o
+}
+
+// GetRestartSec returns value of field RestartSec
+func (o *SystemdOptions) GetRestartSec() uint {
+ if o.RestartSec == nil {
+ var z uint
+ return z
+ }
+ return *o.RestartSec
+}
+
// WithStartTimeout set field StartTimeout to given value
func (o *SystemdOptions) WithStartTimeout(value uint) *SystemdOptions {
o.StartTimeout = &value
diff --git a/pkg/domain/entities/generate.go b/pkg/domain/entities/generate.go
index 7e80e5d2d..e431a70af 100644
--- a/pkg/domain/entities/generate.go
+++ b/pkg/domain/entities/generate.go
@@ -10,6 +10,8 @@ type GenerateSystemdOptions struct {
New bool
// RestartPolicy - systemd restart policy.
RestartPolicy *string
+ // RestartSec - systemd service restartsec. Configures the time to sleep before restarting a service.
+ RestartSec *uint
// StartTimeout - time when starting the container.
StartTimeout *uint
// StopTimeout - time when stopping the container.
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 7a3451a7d..4346182d6 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -306,8 +306,16 @@ func (ir *ImageEngine) Push(ctx context.Context, source string, destination stri
pushOptions.SignBy = options.SignBy
pushOptions.InsecureSkipTLSVerify = options.SkipTLSVerify
- if options.CompressionFormat != "" {
- algo, err := compression.AlgorithmByName(options.CompressionFormat)
+ compressionFormat := options.CompressionFormat
+ if compressionFormat == "" {
+ config, err := ir.Libpod.GetConfigNoCopy()
+ if err != nil {
+ return err
+ }
+ compressionFormat = config.Engine.CompressionFormat
+ }
+ if compressionFormat != "" {
+ algo, err := compression.AlgorithmByName(compressionFormat)
if err != nil {
return err
}
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index bdf22cf0c..ab52fad64 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -239,27 +239,6 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
return nil, err
}
podSpec := entities.PodSpec{PodSpecGen: *p}
- volumes, err := kube.InitializeVolumes(podYAML.Spec.Volumes)
- if err != nil {
- return nil, err
- }
-
- seccompPaths, err := kube.InitializeSeccompPaths(podYAML.ObjectMeta.Annotations, options.SeccompProfileRoot)
- if err != nil {
- return nil, err
- }
-
- var ctrRestartPolicy string
- switch podYAML.Spec.RestartPolicy {
- case v1.RestartPolicyAlways:
- ctrRestartPolicy = define.RestartPolicyAlways
- case v1.RestartPolicyOnFailure:
- ctrRestartPolicy = define.RestartPolicyOnFailure
- case v1.RestartPolicyNever:
- ctrRestartPolicy = define.RestartPolicyNo
- default: // Default to Always
- ctrRestartPolicy = define.RestartPolicyAlways
- }
configMapIndex := make(map[string]struct{})
for _, configMap := range configMaps {
@@ -284,6 +263,56 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
configMaps = append(configMaps, cm)
}
+ volumes, err := kube.InitializeVolumes(podYAML.Spec.Volumes, configMaps)
+ if err != nil {
+ return nil, err
+ }
+
+ // Go through the volumes and create a podman volume for all volumes that have been
+ // defined by a configmap
+ for _, v := range volumes {
+ if v.Type == kube.KubeVolumeTypeConfigMap && !v.Optional {
+ vol, err := ic.Libpod.NewVolume(ctx, libpod.WithVolumeName(v.Source))
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot create a local volume for volume from configmap %q", v.Source)
+ }
+ mountPoint, err := vol.MountPoint()
+ if err != nil || mountPoint == "" {
+ return nil, errors.Wrapf(err, "unable to get mountpoint of volume %q", vol.Name())
+ }
+ // Create files and add data to the volume mountpoint based on the Items in the volume
+ for k, v := range v.Items {
+ dataPath := filepath.Join(mountPoint, k)
+ f, err := os.Create(dataPath)
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot create file %q at volume mountpoint %q", k, mountPoint)
+ }
+ defer f.Close()
+ _, err = f.WriteString(v)
+ if err != nil {
+ return nil, err
+ }
+ }
+ }
+ }
+
+ seccompPaths, err := kube.InitializeSeccompPaths(podYAML.ObjectMeta.Annotations, options.SeccompProfileRoot)
+ if err != nil {
+ return nil, err
+ }
+
+ var ctrRestartPolicy string
+ switch podYAML.Spec.RestartPolicy {
+ case v1.RestartPolicyAlways:
+ ctrRestartPolicy = define.RestartPolicyAlways
+ case v1.RestartPolicyOnFailure:
+ ctrRestartPolicy = define.RestartPolicyOnFailure
+ case v1.RestartPolicyNever:
+ ctrRestartPolicy = define.RestartPolicyNo
+ default: // Default to Always
+ ctrRestartPolicy = define.RestartPolicyAlways
+ }
+
if podOpt.Infra {
infraImage := util.DefaultContainerConfig().Engine.InfraImage
infraOptions := entities.NewInfraContainerCreateOptions()
diff --git a/pkg/domain/infra/tunnel/generate.go b/pkg/domain/infra/tunnel/generate.go
index d62a318d6..dd895b61f 100644
--- a/pkg/domain/infra/tunnel/generate.go
+++ b/pkg/domain/infra/tunnel/generate.go
@@ -19,6 +19,9 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string,
if opts.RestartPolicy != nil {
options.WithRestartPolicy(*opts.RestartPolicy)
}
+ if opts.RestartSec != nil {
+ options.WithRestartSec(*opts.RestartSec)
+ }
return generate.Systemd(ic.ClientCtx, nameOrID, options)
}
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index c502a6e62..6d9f598c9 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -310,6 +310,11 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
if !exists {
return nil, errors.Errorf("Volume mount %s specified for container but not configured in volumes", volume.Name)
}
+ // Skip if the volume is optional. This means that a configmap for a configmap volume was not found but it was
+ // optional so we can move on without throwing an error
+ if exists && volumeSource.Optional {
+ continue
+ }
dest, options, err := parseMountPath(volume.MountPath, volume.ReadOnly)
if err != nil {
@@ -341,6 +346,13 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
Options: options,
}
s.Volumes = append(s.Volumes, &namedVolume)
+ case KubeVolumeTypeConfigMap:
+ cmVolume := specgen.NamedVolume{
+ Dest: volume.MountPath,
+ Name: volumeSource.Source,
+ Options: options,
+ }
+ s.Volumes = append(s.Volumes, &cmVolume)
default:
return nil, errors.Errorf("Unsupported volume source type")
}
diff --git a/pkg/specgen/generate/kube/volume.go b/pkg/specgen/generate/kube/volume.go
index a8042b532..76ec0a390 100644
--- a/pkg/specgen/generate/kube/volume.go
+++ b/pkg/specgen/generate/kube/volume.go
@@ -23,6 +23,7 @@ type KubeVolumeType int
const (
KubeVolumeTypeBindMount KubeVolumeType = iota
KubeVolumeTypeNamed KubeVolumeType = iota
+ KubeVolumeTypeConfigMap KubeVolumeType = iota
)
// nolint:golint
@@ -31,6 +32,14 @@ type KubeVolume struct {
Type KubeVolumeType
// Path for bind mount or volume name for named volume
Source string
+ // Items to add to a named volume created where the key is the file name and the value is the data
+ // This is only used when there are volumes in the yaml that refer to a configmap
+ // Example: if configmap has data "SPECIAL_LEVEL: very" then the file name is "SPECIAL_LEVEL" and the
+ // data in that file is "very".
+ Items map[string]string
+ // If the volume is optional, we can move on if it is not found
+ // Only used when there are volumes in a yaml that refer to a configmap
+ Optional bool
}
// Create a KubeVolume from an HostPathVolumeSource
@@ -98,23 +107,64 @@ func VolumeFromPersistentVolumeClaim(claim *v1.PersistentVolumeClaimVolumeSource
}, nil
}
+func VolumeFromConfigMap(configMapVolumeSource *v1.ConfigMapVolumeSource, configMaps []v1.ConfigMap) (*KubeVolume, error) {
+ var configMap *v1.ConfigMap
+ kv := &KubeVolume{Type: KubeVolumeTypeConfigMap, Items: map[string]string{}}
+ for _, cm := range configMaps {
+ if cm.Name == configMapVolumeSource.Name {
+ matchedCM := cm
+ // Set the source to the config map name
+ kv.Source = cm.Name
+ configMap = &matchedCM
+ break
+ }
+ }
+
+ if configMap == nil {
+ // If the volumeSource was optional, move on even if a matching configmap wasn't found
+ if *configMapVolumeSource.Optional {
+ kv.Source = configMapVolumeSource.Name
+ kv.Optional = *configMapVolumeSource.Optional
+ return kv, nil
+ }
+ return nil, errors.Errorf("no such ConfigMap %q", configMapVolumeSource.Name)
+ }
+
+ // If there are Items specified in the volumeSource, that overwrites the Data from the configmap
+ if len(configMapVolumeSource.Items) > 0 {
+ for _, item := range configMapVolumeSource.Items {
+ if val, ok := configMap.Data[item.Key]; ok {
+ kv.Items[item.Path] = val
+ }
+ }
+ } else {
+ for k, v := range configMap.Data {
+ kv.Items[k] = v
+ }
+ }
+ return kv, nil
+}
+
// Create a KubeVolume from one of the supported VolumeSource
-func VolumeFromSource(volumeSource v1.VolumeSource) (*KubeVolume, error) {
- if volumeSource.HostPath != nil {
+func VolumeFromSource(volumeSource v1.VolumeSource, configMaps []v1.ConfigMap) (*KubeVolume, error) {
+ switch {
+ case volumeSource.HostPath != nil:
return VolumeFromHostPath(volumeSource.HostPath)
- } else if volumeSource.PersistentVolumeClaim != nil {
+ case volumeSource.PersistentVolumeClaim != nil:
return VolumeFromPersistentVolumeClaim(volumeSource.PersistentVolumeClaim)
- } else {
- return nil, errors.Errorf("HostPath and PersistentVolumeClaim are currently the only supported VolumeSource")
+ case volumeSource.ConfigMap != nil:
+ return VolumeFromConfigMap(volumeSource.ConfigMap, configMaps)
+ default:
+ return nil, errors.Errorf("HostPath, ConfigMap, and PersistentVolumeClaim are currently the only supported VolumeSource")
}
}
// Create a map of volume name to KubeVolume
-func InitializeVolumes(specVolumes []v1.Volume) (map[string]*KubeVolume, error) {
+func InitializeVolumes(specVolumes []v1.Volume, configMaps []v1.ConfigMap) (map[string]*KubeVolume, error) {
volumes := make(map[string]*KubeVolume)
for _, specVolume := range specVolumes {
- volume, err := VolumeFromSource(specVolume.VolumeSource)
+ volume, err := VolumeFromSource(specVolume.VolumeSource, configMaps)
if err != nil {
return nil, errors.Wrapf(err, "failed to create volume %q", specVolume.Name)
}
diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go
index 48252c737..f2d04dadc 100644
--- a/pkg/systemd/generate/pods.go
+++ b/pkg/systemd/generate/pods.go
@@ -30,6 +30,8 @@ type podInfo struct {
StopTimeout uint
// RestartPolicy of the systemd unit (e.g., no, on-failure, always).
RestartPolicy string
+ // RestartSec of the systemd unit. Configures the time to sleep before restarting a service.
+ RestartSec uint
// PIDFile of the service. Required for forking services. Must point to the
// PID of the associated conmon process.
PIDFile string
@@ -89,6 +91,9 @@ Before={{{{- range $index, $value := .RequiredServices -}}}}{{{{if $index}}}} {{
[Service]
Environment={{{{.EnvVariable}}}}=%n
Restart={{{{.RestartPolicy}}}}
+{{{{- if .RestartSec}}}}
+RestartSec={{{{.RestartSec}}}}
+{{{{- end}}}}
TimeoutStopSec={{{{.TimeoutStopSec}}}}
{{{{- if .ExecStartPre1}}}}
ExecStartPre={{{{.ExecStartPre1}}}}
@@ -242,6 +247,10 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
info.RestartPolicy = *options.RestartPolicy
}
+ if options.RestartSec != nil {
+ info.RestartSec = *options.RestartSec
+ }
+
// Make sure the executable is set.
if info.Executable == "" {
executable, err := os.Executable()
diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go
index 612908991..0889507a5 100644
--- a/pkg/systemd/generate/pods_test.go
+++ b/pkg/systemd/generate/pods_test.go
@@ -67,6 +67,33 @@ WantedBy=default.target
podGood := serviceInfo + headerInfo + podContent
podGoodNoHeaderInfo := serviceInfo + podContent
+ podGoodRestartSec := `# pod-123abc.service
+# autogenerated by Podman CI
+
+[Unit]
+Description=Podman pod-123abc.service
+Documentation=man:podman-generate-systemd(1)
+Wants=network-online.target
+After=network-online.target
+RequiresMountsFor=/var/run/containers/storage
+Requires=container-1.service container-2.service
+Before=container-1.service container-2.service
+
+[Service]
+Environment=PODMAN_SYSTEMD_UNIT=%n
+Restart=on-failure
+RestartSec=15
+TimeoutStopSec=102
+ExecStart=/usr/bin/podman start jadda-jadda-infra
+ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra
+ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra
+PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
+Type=forking
+
+[Install]
+WantedBy=default.target
+`
+
podGoodNamedNew := `# pod-123abc.service
# autogenerated by Podman CI
@@ -205,6 +232,25 @@ WantedBy=default.target
false,
false,
},
+ {"pod restartSec",
+ podInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "pod-123abc",
+ InfraNameOrID: "jadda-jadda-infra",
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 42,
+ PodmanVersion: "CI",
+ GraphRoot: "/var/lib/containers/storage",
+ RunRoot: "/var/run/containers/storage",
+ RequiredServices: []string{"container-1", "container-2"},
+ CreateCommand: []string{"podman", "pod", "create", "--name", "foo", "bar=arg with space"},
+ RestartSec: 15,
+ },
+ podGoodRestartSec,
+ false,
+ false,
+ false,
+ },
{"pod noHeader",
podInfo{
Executable: "/usr/bin/podman",
diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go
index 1cffdc62e..fd9ae5037 100644
--- a/test/e2e/generate_systemd_test.go
+++ b/test/e2e/generate_systemd_test.go
@@ -282,6 +282,19 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.OutputToString()).To(ContainSubstring(" pod create "))
})
+ It("podman generate systemd --restart-sec 15 --name foo", func() {
+ n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"})
+ n.WaitWithDefaultTimeout()
+ Expect(n).Should(Exit(0))
+
+ session := podmanTest.Podman([]string{"generate", "systemd", "--restart-sec", "15", "--name", "foo"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ // Grepping the output (in addition to unit tests)
+ Expect(session.OutputToString()).To(ContainSubstring("RestartSec=15"))
+ })
+
It("podman generate systemd --new=false pod", func() {
n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"})
n.WaitWithDefaultTimeout()
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index 82b543151..96ad2954c 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -380,6 +380,18 @@ spec:
persistentVolumeClaim:
claimName: {{ .PersistentVolumeClaim.ClaimName }}
{{- end }}
+ {{- if (eq .VolumeType "ConfigMap") }}
+ configMap:
+ name: {{ .ConfigMap.Name }}
+ optional: {{ .ConfigMap.Optional }}
+ {{- with .ConfigMap.Items }}
+ items:
+ {{- range . }}
+ - key: {{ .key }}
+ path: {{ .path }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
{{ end }}
{{ end }}
status: {}
@@ -619,14 +631,14 @@ func createSecret(podmanTest *PodmanTestIntegration, name string, value []byte)
Expect(secret).Should(Exit(0))
}
-// ConfigMap describes the options a kube yaml can be configured at configmap level
-type ConfigMap struct {
+// CM describes the options a kube yaml can be configured at configmap level
+type CM struct {
Name string
Data map[string]string
}
-func getConfigMap(options ...configMapOption) *ConfigMap {
- cm := ConfigMap{
+func getConfigMap(options ...configMapOption) *CM {
+ cm := CM{
Name: defaultConfigMapName,
Data: map[string]string{},
}
@@ -638,16 +650,16 @@ func getConfigMap(options ...configMapOption) *ConfigMap {
return &cm
}
-type configMapOption func(*ConfigMap)
+type configMapOption func(*CM)
func withConfigMapName(name string) configMapOption {
- return func(configmap *ConfigMap) {
+ return func(configmap *CM) {
configmap.Name = name
}
}
func withConfigMapData(k, v string) configMapOption {
- return func(configmap *ConfigMap) {
+ return func(configmap *CM) {
configmap.Data[k] = v
}
}
@@ -1047,11 +1059,18 @@ type PersistentVolumeClaim struct {
ClaimName string
}
+type ConfigMap struct {
+ Name string
+ Items []map[string]string
+ Optional bool
+}
+
type Volume struct {
VolumeType string
Name string
HostPath
PersistentVolumeClaim
+ ConfigMap
}
// getHostPathVolume takes a type and a location for a HostPath
@@ -1079,6 +1098,20 @@ func getPersistentVolumeClaimVolume(vName string) *Volume {
}
}
+// getConfigMap returns a new ConfigMap Volume given the name and items
+// of the ConfigMap.
+func getConfigMapVolume(vName string, items []map[string]string, optional bool) *Volume {
+ return &Volume{
+ VolumeType: "ConfigMap",
+ Name: defaultVolName,
+ ConfigMap: ConfigMap{
+ Name: vName,
+ Items: items,
+ Optional: optional,
+ },
+ }
+}
+
type Env struct {
Name string
Value string
@@ -2311,6 +2344,75 @@ VOLUME %s`, ALPINE, hostPathDir+"/")
Expect(inspect.OutputToString()).To(Equal(correct))
})
+ It("podman play kube ConfigMap volume with no items", func() {
+ volumeName := "cmVol"
+ cm := getConfigMap(withConfigMapName(volumeName), withConfigMapData("FOO", "foobar"))
+ cmYaml, err := getKubeYaml("configmap", cm)
+ Expect(err).To(BeNil())
+
+ ctr := getCtr(withVolumeMount("/test", false), withImage(BB))
+ pod := getPod(withVolume(getConfigMapVolume(volumeName, []map[string]string{}, false)), withCtr(ctr))
+ podYaml, err := getKubeYaml("pod", pod)
+ Expect(err).To(BeNil())
+ yamls := []string{cmYaml, podYaml}
+ err = generateMultiDocKubeYaml(yamls, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ cmData := podmanTest.Podman([]string{"exec", getCtrNameInPod(pod), "cat", "/test/FOO"})
+ cmData.WaitWithDefaultTimeout()
+ Expect(cmData).Should(Exit(0))
+ Expect(cmData.OutputToString()).To(Equal("foobar"))
+ })
+
+ It("podman play kube ConfigMap volume with items", func() {
+ volumeName := "cmVol"
+ cm := getConfigMap(withConfigMapName(volumeName), withConfigMapData("FOO", "foobar"))
+ cmYaml, err := getKubeYaml("configmap", cm)
+ Expect(err).To(BeNil())
+ volumeContents := []map[string]string{{
+ "key": "FOO",
+ "path": "BAR",
+ }}
+
+ ctr := getCtr(withVolumeMount("/test", false), withImage(BB))
+ pod := getPod(withVolume(getConfigMapVolume(volumeName, volumeContents, false)), withCtr(ctr))
+ podYaml, err := getKubeYaml("pod", pod)
+ Expect(err).To(BeNil())
+ yamls := []string{cmYaml, podYaml}
+ err = generateMultiDocKubeYaml(yamls, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ cmData := podmanTest.Podman([]string{"exec", getCtrNameInPod(pod), "cat", "/test/BAR"})
+ cmData.WaitWithDefaultTimeout()
+ Expect(cmData).Should(Exit(0))
+ Expect(cmData.OutputToString()).To(Equal("foobar"))
+
+ cmData = podmanTest.Podman([]string{"exec", getCtrNameInPod(pod), "cat", "/test/FOO"})
+ cmData.WaitWithDefaultTimeout()
+ Expect(cmData).Should(Not(Exit(0)))
+ })
+
+ It("podman play kube with a missing optional ConfigMap volume", func() {
+ volumeName := "cmVol"
+
+ ctr := getCtr(withVolumeMount("/test", false), withImage(BB))
+ pod := getPod(withVolume(getConfigMapVolume(volumeName, []map[string]string{}, true)), withCtr(ctr))
+ err = generateKubeYaml("pod", pod, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+ })
+
It("podman play kube applies labels to pods", func() {
var numReplicas int32 = 5
expectedLabelKey := "key1"
diff --git a/vendor/github.com/containers/common/libimage/pull.go b/vendor/github.com/containers/common/libimage/pull.go
index 1d1bc201b..59221d935 100644
--- a/vendor/github.com/containers/common/libimage/pull.go
+++ b/vendor/github.com/containers/common/libimage/pull.go
@@ -454,7 +454,7 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str
// NOTE that this is will even override --pull={false,never}. This is
// very likely a bug but a consistent one in Podman/Buildah and should
// be addressed at a later point.
- if pullPolicy != config.PullPolicyAlways {
+ if pullPolicy != config.PullPolicyAlways && pullPolicy != config.PullPolicyNever {
switch {
// User input clearly refer to a local image.
case strings.HasPrefix(imageName, "localhost/"):
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index 7ce0e5022..29c505e9c 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -420,6 +420,9 @@ type EngineConfig struct {
// ChownCopiedFiles tells the container engine whether to chown files copied
// into a container to the container's primary uid/gid.
ChownCopiedFiles bool `toml:"chown_copied_files,omitempty"`
+
+ // CompressionFormat is the compression format used to compress image layers.
+ CompressionFormat string `toml:"compression_format,omitempty"`
}
// SetOptions contains a subset of options in a Config. It's used to indicate if
diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf
index 8e305b57e..84b49b7e4 100644
--- a/vendor/github.com/containers/common/pkg/config/containers.conf
+++ b/vendor/github.com/containers/common/pkg/config/containers.conf
@@ -294,6 +294,12 @@ default_sysctls = [
#
#active_service = production
+# The compression format to use when pushing an image.
+# Valid options are: `gzip`, `zstd` and `zstd:chunked`.
+#
+#compression_format = "gzip"
+
+
# Cgroup management implementation used for the runtime.
# Valid options "systemd" or "cgroupfs"
#
diff --git a/vendor/github.com/containers/common/pkg/config/nosystemd.go b/vendor/github.com/containers/common/pkg/config/nosystemd.go
index 2a3b6fb35..f64b2dfc6 100644
--- a/vendor/github.com/containers/common/pkg/config/nosystemd.go
+++ b/vendor/github.com/containers/common/pkg/config/nosystemd.go
@@ -22,3 +22,7 @@ func defaultLogDriver() string {
func useSystemd() bool {
return false
}
+
+func useJournald() bool {
+ return false
+}
diff --git a/vendor/github.com/containers/common/pkg/config/systemd.go b/vendor/github.com/containers/common/pkg/config/systemd.go
index fab3ea437..186e8b343 100644
--- a/vendor/github.com/containers/common/pkg/config/systemd.go
+++ b/vendor/github.com/containers/common/pkg/config/systemd.go
@@ -4,12 +4,12 @@ package config
import (
"io/ioutil"
+ "path/filepath"
"strings"
"sync"
"github.com/containers/common/pkg/cgroupv2"
"github.com/containers/storage/pkg/unshare"
- "github.com/coreos/go-systemd/v22/sdjournal"
)
var (
@@ -67,12 +67,20 @@ func useJournald() bool {
if !useSystemd() {
return
}
- journal, err := sdjournal.NewJournal()
- if err != nil {
- return
+ for _, root := range []string{"/run/log/journal", "/var/log/journal"} {
+ dirs, err := ioutil.ReadDir(root)
+ if err != nil {
+ continue
+ }
+ for _, d := range dirs {
+ if d.IsDir() {
+ if _, err := ioutil.ReadDir(filepath.Join(root, d.Name())); err == nil {
+ usesJournald = true
+ return
+ }
+ }
+ }
}
- journal.Close()
- usesJournald = true
return
})
return usesJournald
diff --git a/vendor/github.com/containers/common/pkg/manifests/manifests.go b/vendor/github.com/containers/common/pkg/manifests/manifests.go
index ea9495ee7..5c2836893 100644
--- a/vendor/github.com/containers/common/pkg/manifests/manifests.go
+++ b/vendor/github.com/containers/common/pkg/manifests/manifests.go
@@ -74,6 +74,7 @@ func Create() List {
},
oci: v1.Index{
Versioned: imgspec.Versioned{SchemaVersion: 2},
+ MediaType: v1.MediaTypeImageIndex,
},
}
}
@@ -373,6 +374,7 @@ func FromBlob(manifestBytes []byte) (List, error) {
},
oci: v1.Index{
Versioned: imgspec.Versioned{SchemaVersion: 2},
+ MediaType: v1.MediaTypeImageIndex,
},
}
switch manifestType {
diff --git a/vendor/github.com/containers/storage/.cirrus.yml b/vendor/github.com/containers/storage/.cirrus.yml
index d080d790c..726acc3ae 100644
--- a/vendor/github.com/containers/storage/.cirrus.yml
+++ b/vendor/github.com/containers/storage/.cirrus.yml
@@ -17,8 +17,8 @@ env:
####
#### Cache-image names to test with (double-quotes around names are critical)
###
- FEDORA_NAME: "fedora-34"
- PRIOR_FEDORA_NAME: "fedora-33"
+ FEDORA_NAME: "fedora-35"
+ PRIOR_FEDORA_NAME: "fedora-34"
UBUNTU_NAME: "ubuntu-2104"
# GCE project where images live
diff --git a/vendor/github.com/containers/storage/Vagrantfile b/vendor/github.com/containers/storage/Vagrantfile
deleted file mode 100644
index c82c1f81b..000000000
--- a/vendor/github.com/containers/storage/Vagrantfile
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- mode: ruby -*-
-# vi: set ft=ruby :
-#
-# The fedora/28-cloud-base and debian/jessie64 boxes are also available for
-# the "virtualbox" provider. Set the VAGRANT_PROVIDER environment variable to
-# "virtualbox" to use them instead.
-#
-Vagrant.configure("2") do |config|
- config.vm.define "fedora" do |c|
- c.vm.box = "fedora/28-cloud-base"
- c.vm.synced_folder ".", "/vagrant", type: "rsync",
- rsync__exclude: "bundles", rsync__args: ["-vadz", "--delete"]
- c.vm.provision "shell", inline: <<-SHELL
- sudo /vagrant/vagrant/provision.sh
- SHELL
- end
- config.vm.define "debian" do |c|
- c.vm.box = "debian/jessie64"
- c.vm.synced_folder ".", "/vagrant", type: "rsync",
- rsync__exclude: "bundles", rsync__args: ["-vadz", "--delete"]
- c.vm.provision "shell", inline: <<-SHELL
- sudo /vagrant/vagrant/provision.sh
- SHELL
- end
-end
diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod
index 04d5adac4..57b634f17 100644
--- a/vendor/github.com/containers/storage/go.mod
+++ b/vendor/github.com/containers/storage/go.mod
@@ -7,6 +7,7 @@ require (
github.com/Microsoft/go-winio v0.5.1
github.com/Microsoft/hcsshim v0.9.1
github.com/containerd/stargz-snapshotter/estargz v0.10.1
+ github.com/cyphar/filepath-securejoin v0.2.3
github.com/docker/go-units v0.4.0
github.com/google/go-intervals v0.0.2
github.com/hashicorp/go-multierror v1.1.1
diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum
index 35328e287..94d46b21a 100644
--- a/vendor/github.com/containers/storage/go.sum
+++ b/vendor/github.com/containers/storage/go.sum
@@ -218,6 +218,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
+github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
+github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go
index 76544ff28..e7c4cfcf1 100644
--- a/vendor/github.com/containers/storage/pkg/archive/archive.go
+++ b/vendor/github.com/containers/storage/pkg/archive/archive.go
@@ -77,6 +77,10 @@ const (
containersOverrideXattr = "user.containers.override_stat"
)
+var xattrsToIgnore = map[string]interface{}{
+ "security.selinux": true,
+}
+
// Archiver allows the reuse of most utility functions of this package with a
// pluggable Untar function. To facilitate the passing of specific id mappings
// for untar, an archiver can be created with maps which will then be passed to
@@ -743,6 +747,9 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L
var errs []string
for key, value := range hdr.Xattrs {
+ if _, found := xattrsToIgnore[key]; found {
+ continue
+ }
if err := system.Lsetxattr(path, key, []byte(value), 0); err != nil {
if errors.Is(err, syscall.ENOTSUP) || (inUserns && errors.Is(err, syscall.EPERM)) {
// We ignore errors here because not all graphdrivers support
diff --git a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
index d18ab299b..52d21d689 100644
--- a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
+++ b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
@@ -13,6 +13,7 @@ import (
"reflect"
"sort"
"strings"
+ "sync/atomic"
"syscall"
"time"
@@ -25,6 +26,7 @@ import (
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/system"
"github.com/containers/storage/types"
+ securejoin "github.com/cyphar/filepath-securejoin"
"github.com/klauspost/compress/zstd"
"github.com/klauspost/pgzip"
digest "github.com/opencontainers/go-digest"
@@ -57,6 +59,10 @@ type chunkedDiffer struct {
gzipReader *pgzip.Reader
}
+var xattrsToIgnore = map[string]interface{}{
+ "security.selinux": true,
+}
+
func timeToTimespec(time time.Time) (ts unix.Timespec) {
if time.IsZero() {
// Return UTIME_OMIT special value
@@ -89,7 +95,7 @@ func copyFileContent(srcFd int, destFile string, dirfd int, mode os.FileMode, us
src := fmt.Sprintf("/proc/self/fd/%d", srcFd)
st, err := os.Stat(src)
if err != nil {
- return nil, -1, err
+ return nil, -1, fmt.Errorf("copy file content for %q: %w", destFile, err)
}
copyWithFileRange, copyWithFileClone := true, true
@@ -111,15 +117,15 @@ func copyFileContent(srcFd int, destFile string, dirfd int, mode os.FileMode, us
// If the destination file already exists, we shouldn't blow it away
dstFile, err := openFileUnderRoot(destFile, dirfd, newFileFlags, mode)
if err != nil {
- return nil, -1, err
+ return nil, -1, fmt.Errorf("open file %q under rootfs for copy: %w", destFile, err)
}
err = driversCopy.CopyRegularToFile(src, dstFile, st, &copyWithFileRange, &copyWithFileClone)
if err != nil {
dstFile.Close()
- return nil, -1, err
+ return nil, -1, fmt.Errorf("copy to file %q under rootfs: %w", destFile, err)
}
- return dstFile, st.Size(), err
+ return dstFile, st.Size(), nil
}
func prepareOtherLayersCache(layersMetadata map[string][]internal.FileMetadata) map[string]map[string][]*internal.FileMetadata {
@@ -153,7 +159,7 @@ func getLayersCache(store storage.Store) (map[string][]internal.FileMetadata, ma
defer manifestReader.Close()
manifest, err := ioutil.ReadAll(manifestReader)
if err != nil {
- return nil, nil, err
+ return nil, nil, fmt.Errorf("open manifest file for layer %q: %w", r.ID, err)
}
var toc internal.TOC
if err := json.Unmarshal(manifest, &toc); err != nil {
@@ -162,7 +168,7 @@ func getLayersCache(store storage.Store) (map[string][]internal.FileMetadata, ma
layersMetadata[r.ID] = toc.Entries
target, err := store.DifferTarget(r.ID)
if err != nil {
- return nil, nil, err
+ return nil, nil, fmt.Errorf("get checkout directory layer %q: %w", r.ID, err)
}
layersTarget[r.ID] = target
}
@@ -184,7 +190,7 @@ func GetDiffer(ctx context.Context, store storage.Store, blobSize int64, annotat
func makeZstdChunkedDiffer(ctx context.Context, store storage.Store, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (*chunkedDiffer, error) {
manifest, tocOffset, err := readZstdChunkedManifest(iss, blobSize, annotations)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("read zstd:chunked manifest: %w", err)
}
layersMetadata, layersTarget, err := getLayersCache(store)
if err != nil {
@@ -204,7 +210,7 @@ func makeZstdChunkedDiffer(ctx context.Context, store storage.Store, blobSize in
func makeEstargzChunkedDiffer(ctx context.Context, store storage.Store, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (*chunkedDiffer, error) {
manifest, tocOffset, err := readEstargzChunkedManifest(iss, blobSize, annotations)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("read zstd:chunked manifest: %w", err)
}
layersMetadata, layersTarget, err := getLayersCache(store)
if err != nil {
@@ -230,21 +236,21 @@ func makeEstargzChunkedDiffer(ctx context.Context, store storage.Store, blobSize
func copyFileFromOtherLayer(file *internal.FileMetadata, source string, otherFile *internal.FileMetadata, dirfd int, useHardLinks bool) (bool, *os.File, int64, error) {
srcDirfd, err := unix.Open(source, unix.O_RDONLY, 0)
if err != nil {
- return false, nil, 0, err
+ return false, nil, 0, fmt.Errorf("open source file %q: %w", source, err)
}
defer unix.Close(srcDirfd)
srcFile, err := openFileUnderRoot(otherFile.Name, srcDirfd, unix.O_RDONLY, 0)
if err != nil {
- return false, nil, 0, err
+ return false, nil, 0, fmt.Errorf("open source file %q under target rootfs: %w", otherFile.Name, err)
}
defer srcFile.Close()
dstFile, written, err := copyFileContent(int(srcFile.Fd()), file.Name, dirfd, 0, useHardLinks)
if err != nil {
- return false, nil, 0, err
+ return false, nil, 0, fmt.Errorf("copy content to %q: %w", file.Name, err)
}
- return true, dstFile, written, err
+ return true, dstFile, written, nil
}
// canDedupMetadataWithHardLink says whether it is possible to deduplicate file with otherFile.
@@ -280,10 +286,6 @@ func canDedupFileWithHardLink(file *internal.FileMetadata, fd int, s os.FileInfo
return false
}
- xattrsToIgnore := map[string]interface{}{
- "security.selinux": true,
- }
-
xattrs := make(map[string]string)
for _, x := range listXattrs {
v, err := system.Lgetxattr(path, x)
@@ -510,7 +512,7 @@ type missingChunk struct {
}
// setFileAttrs sets the file attributes for file given metadata
-func setFileAttrs(file *os.File, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
+func setFileAttrs(dirfd int, file *os.File, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions, usePath bool) error {
if file == nil || file.Fd() < 0 {
return errors.Errorf("invalid file")
}
@@ -520,54 +522,237 @@ func setFileAttrs(file *os.File, mode os.FileMode, metadata *internal.FileMetada
if err != nil {
return err
}
+
+ // If it is a symlink, force to use the path
if t == tar.TypeSymlink {
- return nil
+ usePath = true
+ }
+
+ baseName := ""
+ if usePath {
+ dirName := filepath.Dir(metadata.Name)
+ if dirName != "" {
+ parentFd, err := openFileUnderRoot(dirName, dirfd, unix.O_PATH|unix.O_DIRECTORY, 0)
+ if err != nil {
+ return err
+ }
+ defer parentFd.Close()
+
+ dirfd = int(parentFd.Fd())
+ }
+ baseName = filepath.Base(metadata.Name)
+ }
+
+ doChown := func() error {
+ if usePath {
+ return unix.Fchownat(dirfd, baseName, metadata.UID, metadata.GID, unix.AT_SYMLINK_NOFOLLOW)
+ }
+ return unix.Fchown(fd, metadata.UID, metadata.GID)
+ }
+
+ doSetXattr := func(k string, v []byte) error {
+ return unix.Fsetxattr(fd, k, v, 0)
+ }
+
+ doUtimes := func() error {
+ ts := []unix.Timespec{timeToTimespec(metadata.AccessTime), timeToTimespec(metadata.ModTime)}
+ if usePath {
+ return unix.UtimesNanoAt(dirfd, baseName, ts, unix.AT_SYMLINK_NOFOLLOW)
+ }
+ return unix.UtimesNanoAt(unix.AT_FDCWD, fmt.Sprintf("/proc/self/fd/%d", fd), ts, 0)
+ }
+
+ doChmod := func() error {
+ if usePath {
+ return unix.Fchmodat(dirfd, baseName, uint32(mode), unix.AT_SYMLINK_NOFOLLOW)
+ }
+ return unix.Fchmod(fd, uint32(mode))
}
- if err := unix.Fchown(fd, metadata.UID, metadata.GID); err != nil {
+ if err := doChown(); err != nil {
if !options.IgnoreChownErrors {
- return err
+ return fmt.Errorf("chown %q to %d:%d: %w", metadata.Name, metadata.UID, metadata.GID, err)
}
}
+ canIgnore := func(err error) bool {
+ return err == nil || errors.Is(err, unix.ENOSYS) || errors.Is(err, unix.ENOTSUP)
+ }
+
for k, v := range metadata.Xattrs {
+ if _, found := xattrsToIgnore[k]; found {
+ continue
+ }
data, err := base64.StdEncoding.DecodeString(v)
if err != nil {
- return err
+ return fmt.Errorf("decode xattr %q: %w", v, err)
}
- if err := unix.Fsetxattr(fd, k, data, 0); err != nil {
- return err
+ if err := doSetXattr(k, data); !canIgnore(err) {
+ return fmt.Errorf("set xattr %s=%q for %q: %w", k, data, metadata.Name, err)
}
}
- ts := []unix.Timespec{timeToTimespec(metadata.AccessTime), timeToTimespec(metadata.ModTime)}
- if err := unix.UtimesNanoAt(fd, "", ts, 0); err != nil && errors.Is(err, unix.ENOSYS) {
- return err
+ if err := doUtimes(); !canIgnore(err) {
+ return fmt.Errorf("set utimes for %q: %w", metadata.Name, err)
}
- if err := unix.Fchmod(fd, uint32(mode)); err != nil {
- return err
+ if err := doChmod(); !canIgnore(err) {
+ return fmt.Errorf("chmod %q: %w", metadata.Name, err)
}
return nil
}
+func openFileUnderRootFallback(dirfd int, name string, flags uint64, mode os.FileMode) (int, error) {
+ root := fmt.Sprintf("/proc/self/fd/%d", dirfd)
+
+ targetRoot, err := os.Readlink(root)
+ if err != nil {
+ return -1, err
+ }
+
+ hasNoFollow := (flags & unix.O_NOFOLLOW) != 0
+
+ fd := -1
+ // If O_NOFOLLOW is specified in the flags, then resolve only the parent directory and use the
+ // last component as the path to openat().
+ if hasNoFollow {
+ dirName := filepath.Dir(name)
+ if dirName != "" {
+ newRoot, err := securejoin.SecureJoin(root, filepath.Dir(name))
+ if err != nil {
+ return -1, err
+ }
+ root = newRoot
+ }
+
+ parentDirfd, err := unix.Open(root, unix.O_PATH, 0)
+ if err != nil {
+ return -1, err
+ }
+ defer unix.Close(parentDirfd)
+
+ fd, err = unix.Openat(parentDirfd, filepath.Base(name), int(flags), uint32(mode))
+ if err != nil {
+ return -1, err
+ }
+ } else {
+ newPath, err := securejoin.SecureJoin(root, name)
+ if err != nil {
+ return -1, err
+ }
+ fd, err = unix.Openat(dirfd, newPath, int(flags), uint32(mode))
+ if err != nil {
+ return -1, err
+ }
+ }
+
+ target, err := os.Readlink(fmt.Sprintf("/proc/self/fd/%d", fd))
+ if err != nil {
+ unix.Close(fd)
+ return -1, err
+ }
+
+ // Add an additional check to make sure the opened fd is inside the rootfs
+ if !strings.HasPrefix(target, targetRoot) {
+ unix.Close(fd)
+ return -1, fmt.Errorf("error while resolving %q. It resolves outside the root directory", name)
+ }
+
+ return fd, err
+}
+
+func openFileUnderRootOpenat2(dirfd int, name string, flags uint64, mode os.FileMode) (int, error) {
+ how := unix.OpenHow{
+ Flags: flags,
+ Mode: uint64(mode & 07777),
+ Resolve: unix.RESOLVE_IN_ROOT,
+ }
+ return unix.Openat2(dirfd, name, &how)
+}
+
+// skipOpenat2 is set when openat2 is not supported by the underlying kernel and avoid
+// using it again.
+var skipOpenat2 int32
+
+// openFileUnderRootRaw tries to open a file using openat2 and if it is not supported fallbacks to a
+// userspace lookup.
+func openFileUnderRootRaw(dirfd int, name string, flags uint64, mode os.FileMode) (int, error) {
+ var fd int
+ var err error
+ if atomic.LoadInt32(&skipOpenat2) > 0 {
+ fd, err = openFileUnderRootFallback(dirfd, name, flags, mode)
+ } else {
+ fd, err = openFileUnderRootOpenat2(dirfd, name, flags, mode)
+ // If the function failed with ENOSYS, switch off the support for openat2
+ // and fallback to using safejoin.
+ if err != nil && errors.Is(err, unix.ENOSYS) {
+ atomic.StoreInt32(&skipOpenat2, 1)
+ fd, err = openFileUnderRootFallback(dirfd, name, flags, mode)
+ }
+ }
+ return fd, err
+}
+
// openFileUnderRoot safely opens a file under the specified root directory using openat2
// name is the path to open relative to dirfd.
// dirfd is an open file descriptor to the target checkout directory.
-// flags are the flags top pass to the open syscall.
+// flags are the flags to pass to the open syscall.
// mode specifies the mode to use for newly created files.
func openFileUnderRoot(name string, dirfd int, flags uint64, mode os.FileMode) (*os.File, error) {
- how := unix.OpenHow{
- Flags: flags,
- Mode: uint64(mode & 07777),
- Resolve: unix.RESOLVE_IN_ROOT,
+ fd, err := openFileUnderRootRaw(dirfd, name, flags, mode)
+ if err == nil {
+ return os.NewFile(uintptr(fd), name), nil
+ }
+
+ hasCreate := (flags & unix.O_CREAT) != 0
+ if errors.Is(err, unix.ENOENT) && hasCreate {
+ parent := filepath.Dir(name)
+ if parent != "" {
+ newDirfd, err2 := openOrCreateDirUnderRoot(parent, dirfd, 0)
+ if err2 == nil {
+ defer newDirfd.Close()
+ fd, err := openFileUnderRootRaw(dirfd, name, flags, mode)
+ if err == nil {
+ return os.NewFile(uintptr(fd), name), nil
+ }
+ }
+ }
}
+ return nil, fmt.Errorf("open %q under the rootfs: %w", name, err)
+}
- fd, err := unix.Openat2(dirfd, name, &how)
- if err != nil {
- return nil, err
+// openOrCreateDirUnderRoot safely opens a directory or create it if it is missing.
+// name is the path to open relative to dirfd.
+// dirfd is an open file descriptor to the target checkout directory.
+// mode specifies the mode to use for newly created files.
+func openOrCreateDirUnderRoot(name string, dirfd int, mode os.FileMode) (*os.File, error) {
+ fd, err := openFileUnderRootRaw(dirfd, name, unix.O_DIRECTORY|unix.O_RDONLY, mode)
+ if err == nil {
+ return os.NewFile(uintptr(fd), name), nil
+ }
+
+ if errors.Is(err, unix.ENOENT) {
+ parent := filepath.Dir(name)
+ if parent != "" {
+ pDir, err2 := openOrCreateDirUnderRoot(parent, dirfd, mode)
+ if err2 != nil {
+ return nil, err
+ }
+ defer pDir.Close()
+
+ baseName := filepath.Base(name)
+
+ if err2 := unix.Mkdirat(int(pDir.Fd()), baseName, 0755); err2 != nil {
+ return nil, err
+ }
+
+ fd, err = openFileUnderRootRaw(int(pDir.Fd()), baseName, unix.O_DIRECTORY|unix.O_RDONLY, mode)
+ if err == nil {
+ return os.NewFile(uintptr(fd), name), nil
+ }
+ }
}
- return os.NewFile(uintptr(fd), name), nil
+ return nil, err
}
func (c *chunkedDiffer) createFileFromCompressedStream(dest string, dirfd int, reader io.Reader, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) (err error) {
@@ -631,7 +816,7 @@ func (c *chunkedDiffer) createFileFromCompressedStream(dest string, dirfd int, r
if digester.Digest() != manifestChecksum {
return fmt.Errorf("checksum mismatch for %q", dest)
}
- return setFileAttrs(file, mode, metadata, options)
+ return setFileAttrs(dirfd, file, mode, metadata, options, false)
}
func (c *chunkedDiffer) storeMissingFiles(streams chan io.ReadCloser, errs chan error, dest string, dirfd int, missingChunks []missingChunk, options *archive.TarOptions) error {
@@ -755,13 +940,13 @@ func (c *chunkedDiffer) retrieveMissingFiles(dest string, dirfd int, missingChun
return nil
}
-func safeMkdir(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
- parent := filepath.Dir(metadata.Name)
- base := filepath.Base(metadata.Name)
+func safeMkdir(dirfd int, mode os.FileMode, name string, metadata *internal.FileMetadata, options *archive.TarOptions) error {
+ parent := filepath.Dir(name)
+ base := filepath.Base(name)
parentFd := dirfd
if parent != "." {
- parentFile, err := openFileUnderRoot(parent, dirfd, unix.O_DIRECTORY|unix.O_PATH|unix.O_RDONLY, 0)
+ parentFile, err := openOrCreateDirUnderRoot(parent, dirfd, 0)
if err != nil {
return err
}
@@ -771,21 +956,21 @@ func safeMkdir(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, opt
if err := unix.Mkdirat(parentFd, base, uint32(mode)); err != nil {
if !os.IsExist(err) {
- return err
+ return fmt.Errorf("mkdir %q: %w", name, err)
}
}
- file, err := openFileUnderRoot(metadata.Name, dirfd, unix.O_RDONLY, 0)
+ file, err := openFileUnderRoot(name, dirfd, unix.O_DIRECTORY|unix.O_RDONLY, 0)
if err != nil {
return err
}
defer file.Close()
- return setFileAttrs(file, mode, metadata, options)
+ return setFileAttrs(dirfd, file, mode, metadata, options, false)
}
func safeLink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
- sourceFile, err := openFileUnderRoot(metadata.Linkname, dirfd, unix.O_RDONLY, 0)
+ sourceFile, err := openFileUnderRoot(metadata.Linkname, dirfd, unix.O_PATH|unix.O_RDONLY|unix.O_NOFOLLOW, 0)
if err != nil {
return err
}
@@ -794,7 +979,7 @@ func safeLink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, opti
destDir, destBase := filepath.Dir(metadata.Name), filepath.Base(metadata.Name)
destDirFd := dirfd
if destDir != "." {
- f, err := openFileUnderRoot(destDir, dirfd, unix.O_RDONLY, 0)
+ f, err := openOrCreateDirUnderRoot(destDir, dirfd, 0)
if err != nil {
return err
}
@@ -804,23 +989,33 @@ func safeLink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, opti
err = doHardLink(int(sourceFile.Fd()), destDirFd, destBase)
if err != nil {
- return err
+ return fmt.Errorf("create hardlink %q pointing to %q: %w", metadata.Name, metadata.Linkname, err)
}
- newFile, err := openFileUnderRoot(metadata.Name, dirfd, unix.O_WRONLY, 0)
+ newFile, err := openFileUnderRoot(metadata.Name, dirfd, unix.O_WRONLY|unix.O_NOFOLLOW, 0)
if err != nil {
+ // If the target is a symlink, open the file with O_PATH.
+ if errors.Is(err, unix.ELOOP) {
+ newFile, err := openFileUnderRoot(metadata.Name, dirfd, unix.O_PATH|unix.O_NOFOLLOW, 0)
+ if err != nil {
+ return err
+ }
+ defer newFile.Close()
+
+ return setFileAttrs(dirfd, newFile, mode, metadata, options, true)
+ }
return err
}
defer newFile.Close()
- return setFileAttrs(newFile, mode, metadata, options)
+ return setFileAttrs(dirfd, newFile, mode, metadata, options, false)
}
func safeSymlink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
destDir, destBase := filepath.Dir(metadata.Name), filepath.Base(metadata.Name)
destDirFd := dirfd
if destDir != "." {
- f, err := openFileUnderRoot(destDir, dirfd, unix.O_RDONLY, 0)
+ f, err := openOrCreateDirUnderRoot(destDir, dirfd, 0)
if err != nil {
return err
}
@@ -828,7 +1023,10 @@ func safeSymlink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, o
destDirFd = int(f.Fd())
}
- return unix.Symlinkat(metadata.Linkname, destDirFd, destBase)
+ if err := unix.Symlinkat(metadata.Linkname, destDirFd, destBase); err != nil {
+ return fmt.Errorf("create symlink %q pointing to %q: %w", metadata.Name, metadata.Linkname, err)
+ }
+ return nil
}
type whiteoutHandler struct {
@@ -837,13 +1035,16 @@ type whiteoutHandler struct {
}
func (d whiteoutHandler) Setxattr(path, name string, value []byte) error {
- file, err := openFileUnderRoot(path, d.Dirfd, unix.O_RDONLY, 0)
+ file, err := openOrCreateDirUnderRoot(path, d.Dirfd, 0)
if err != nil {
return err
}
defer file.Close()
- return unix.Fsetxattr(int(file.Fd()), name, value, 0)
+ if err := unix.Fsetxattr(int(file.Fd()), name, value, 0); err != nil {
+ return fmt.Errorf("set xattr %s=%q for %q: %w", name, value, path, err)
+ }
+ return nil
}
func (d whiteoutHandler) Mknod(path string, mode uint32, dev int) error {
@@ -852,7 +1053,7 @@ func (d whiteoutHandler) Mknod(path string, mode uint32, dev int) error {
dirfd := d.Dirfd
if dir != "" {
- dir, err := openFileUnderRoot(dir, d.Dirfd, unix.O_RDONLY, 0)
+ dir, err := openOrCreateDirUnderRoot(dir, d.Dirfd, 0)
if err != nil {
return err
}
@@ -861,12 +1062,16 @@ func (d whiteoutHandler) Mknod(path string, mode uint32, dev int) error {
dirfd = int(dir.Fd())
}
- return unix.Mknodat(dirfd, base, mode, dev)
+ if err := unix.Mknodat(dirfd, base, mode, dev); err != nil {
+ return fmt.Errorf("mknod %q: %w", path, err)
+ }
+
+ return nil
}
func checkChownErr(err error, name string, uid, gid int) error {
if errors.Is(err, syscall.EINVAL) {
- return errors.Wrapf(err, "potentially insufficient UIDs or GIDs available in user namespace (requested %d:%d for %s): Check /etc/subuid and /etc/subgid if configured locally", uid, gid, name)
+ return fmt.Errorf("potentially insufficient UIDs or GIDs available in user namespace (requested %d:%d for %s): Check /etc/subuid and /etc/subgid if configured locally: %w", uid, gid, name, err)
}
return err
}
@@ -961,7 +1166,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
dirfd, err := unix.Open(dest, unix.O_RDONLY|unix.O_PATH, 0)
if err != nil {
- return output, err
+ return output, fmt.Errorf("cannot open %q: %w", dest, err)
}
defer unix.Close(dirfd)
@@ -1021,7 +1226,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
return err
}
defer file.Close()
- if err := setFileAttrs(file, mode, &r, options); err != nil {
+ if err := setFileAttrs(dirfd, file, mode, &r, options, false); err != nil {
return err
}
return nil
@@ -1033,7 +1238,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
}
case tar.TypeDir:
- if err := safeMkdir(dirfd, mode, &r, options); err != nil {
+ if err := safeMkdir(dirfd, mode, r.Name, &r, options); err != nil {
return output, err
}
continue
@@ -1070,7 +1275,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
finalizeFile := func(dstFile *os.File) error {
if dstFile != nil {
defer dstFile.Close()
- if err := setFileAttrs(dstFile, mode, &r, options); err != nil {
+ if err := setFileAttrs(dirfd, dstFile, mode, &r, options, false); err != nil {
return err
}
}
diff --git a/vendor/github.com/containers/storage/types/options.go b/vendor/github.com/containers/storage/types/options.go
index 8a3858d9f..fe4274efd 100644
--- a/vendor/github.com/containers/storage/types/options.go
+++ b/vendor/github.com/containers/storage/types/options.go
@@ -42,6 +42,10 @@ func init() {
defaultStoreOptions.GraphDriverName = ""
if _, err := os.Stat(defaultOverrideConfigFile); err == nil {
+ // The DefaultConfigFile(rootless) function returns the path
+ // of the used storage.conf file, by returning defaultConfigFile
+ // If override exists containers/storage uses it by default.
+ defaultConfigFile = defaultOverrideConfigFile
ReloadConfigurationFileIfNeeded(defaultOverrideConfigFile, &defaultStoreOptions)
} else {
if !os.IsNotExist(err) {
diff --git a/vendor/github.com/jinzhu/copier/copier.go b/vendor/github.com/jinzhu/copier/copier.go
index 412ff5497..6d21da869 100644
--- a/vendor/github.com/jinzhu/copier/copier.go
+++ b/vendor/github.com/jinzhu/copier/copier.go
@@ -348,10 +348,15 @@ func deepFields(reflectType reflect.Type) []reflect.StructField {
for i := 0; i < reflectType.NumField(); i++ {
v := reflectType.Field(i)
- if v.Anonymous {
- fields = append(fields, deepFields(v.Type)...)
- } else {
- fields = append(fields, v)
+ // PkgPath is the package path that qualifies a lower case (unexported)
+ // field name. It is empty for upper case (exported) field names.
+ // See https://golang.org/ref/spec#Uniqueness_of_identifiers
+ if v.PkgPath == "" {
+ if v.Anonymous {
+ fields = append(fields, deepFields(v.Type)...)
+ } else {
+ fields = append(fields, v)
+ }
}
}
diff --git a/vendor/github.com/jinzhu/copier/go.mod b/vendor/github.com/jinzhu/copier/go.mod
index 531422dcb..309801e9b 100644
--- a/vendor/github.com/jinzhu/copier/go.mod
+++ b/vendor/github.com/jinzhu/copier/go.mod
@@ -1,3 +1,3 @@
module github.com/jinzhu/copier
-go 1.15
+go 1.13
diff --git a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
index 9fe803a5e..38a099162 100644
--- a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
+++ b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.4.3
+
+* Fix cases where `json.Number` didn't decode properly [GH-261]
+
## 1.4.2
* Custom name matchers to support any sort of casing, formatting, etc. for
diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go
index dcee0f2d6..6b81b0067 100644
--- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go
+++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go
@@ -684,16 +684,12 @@ func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) e
}
case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
jn := data.(json.Number)
- i, err := jn.Int64()
+ i, err := strconv.ParseUint(string(jn), 0, 64)
if err != nil {
return fmt.Errorf(
"error decoding json.Number into %s: %s", name, err)
}
- if i < 0 && !d.config.WeaklyTypedInput {
- return fmt.Errorf("cannot parse '%s', %d overflows uint",
- name, i)
- }
- val.SetUint(uint64(i))
+ val.SetUint(i)
default:
return fmt.Errorf(
"'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go
index 4e6c4b236..82da6c6a8 100644
--- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go
+++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go
@@ -21,6 +21,9 @@ import "github.com/opencontainers/image-spec/specs-go"
type Index struct {
specs.Versioned
+ // MediaType specificies the type of this document data structure e.g. `application/vnd.oci.image.index.v1+json`
+ MediaType string `json:"mediaType,omitempty"`
+
// Manifests references platform specific manifests.
Manifests []Descriptor `json:"manifests"`
diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go
index 7ff32c40b..d72d15ce4 100644
--- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go
+++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go
@@ -20,6 +20,9 @@ import "github.com/opencontainers/image-spec/specs-go"
type Manifest struct {
specs.Versioned
+ // MediaType specificies the type of this document data structure e.g. `application/vnd.oci.image.manifest.v1+json`
+ MediaType string `json:"mediaType,omitempty"`
+
// Config references a configuration object for a container, by digest.
// The referenced configuration object is a JSON blob that the runtime uses to set up the container.
Config Descriptor `json:"config"`
diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/version.go b/vendor/github.com/opencontainers/image-spec/specs-go/version.go
index 58f1095ab..31f99cf64 100644
--- a/vendor/github.com/opencontainers/image-spec/specs-go/version.go
+++ b/vendor/github.com/opencontainers/image-spec/specs-go/version.go
@@ -22,7 +22,7 @@ const (
// VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 0
// VersionPatch is for backwards-compatible bug fixes
- VersionPatch = 1
+ VersionPatch = 2
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = "-dev"
diff --git a/vendor/modules.txt b/vendor/modules.txt
index a104465c6..04f15620c 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -106,7 +106,7 @@ github.com/containers/buildah/pkg/rusage
github.com/containers/buildah/pkg/sshagent
github.com/containers/buildah/pkg/util
github.com/containers/buildah/util
-# github.com/containers/common v0.46.1-0.20211125160015-ccf46abecd91
+# github.com/containers/common v0.46.1-0.20211202172647-e77d74bd1976
## explicit
github.com/containers/common/libimage
github.com/containers/common/libimage/manifests
@@ -219,7 +219,7 @@ github.com/containers/psgo/internal/dev
github.com/containers/psgo/internal/host
github.com/containers/psgo/internal/proc
github.com/containers/psgo/internal/process
-# github.com/containers/storage v1.37.1-0.20211122214631-59ba58582415
+# github.com/containers/storage v1.37.1-0.20211130181259-1a158c89a518
## explicit
github.com/containers/storage
github.com/containers/storage/drivers
@@ -437,7 +437,7 @@ github.com/imdario/mergo
github.com/inconshreveable/mousetrap
# github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee
github.com/ishidawataru/sctp
-# github.com/jinzhu/copier v0.3.2
+# github.com/jinzhu/copier v0.3.4
github.com/jinzhu/copier
# github.com/json-iterator/go v1.1.12
## explicit
@@ -469,7 +469,7 @@ github.com/matttproud/golang_protobuf_extensions/pbutil
github.com/miekg/pkcs11
# github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
github.com/mistifyio/go-zfs
-# github.com/mitchellh/mapstructure v1.4.2
+# github.com/mitchellh/mapstructure v1.4.3
github.com/mitchellh/mapstructure
# github.com/moby/sys/mount v0.2.0
github.com/moby/sys/mount
@@ -545,7 +545,7 @@ github.com/onsi/gomega/types
# github.com/opencontainers/go-digest v1.0.0
## explicit
github.com/opencontainers/go-digest
-# github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283
+# github.com/opencontainers/image-spec v1.0.2-0.20211123152302-43a7dee1ec31
## explicit
github.com/opencontainers/image-spec/specs-go
github.com/opencontainers/image-spec/specs-go/v1