mirror of https://github.com/containers/podman.git
Merge pull request #25521 from mheon/541_backports
Backports for v5.4.1
This commit is contained in:
commit
771d7a8d2c
|
|
@ -1,5 +1,22 @@
|
|||
# Release Notes
|
||||
|
||||
## 5.4.1
|
||||
### Bugfixes
|
||||
- Fixed a bug where volume quotas were not being applied ([#25368](https://github.com/containers/podman/issues/25368)).
|
||||
- Fixed a bug where the `--pid-limit=-1` option did not function properly with containers using the `runc` OCI runtime.
|
||||
- Fixed a bug where the `podman artifact pull` command did not respect the `--retry-delay` option.
|
||||
- Fixed a bug where Podman would leak a file and directory for every container created.
|
||||
- Fixed a bug where the `podman wait` command would sometimes error when waiting for a container set to auto-remove.
|
||||
- Fixed a bug where Quadlet `.kube` units would not report an error (and stay running) even when a pod failed to start ([#20667](https://github.com/containers/podman/issues/20667)).
|
||||
|
||||
### API
|
||||
- Fixed a bug where the Compat DF endpoint did not correctly report total size of all images.
|
||||
|
||||
### Misc
|
||||
- Updated Buildah to v1.39.2
|
||||
- Updated the containers/common library to v0.62.1
|
||||
- Updated the containers/image library to v5.34.1
|
||||
|
||||
## 5.4.0
|
||||
### Features
|
||||
- A preview of Podman's support for OCI artifacts has been added through the `podman artifact` suite of commands, including `add`, `inspect`, `ls`, `pull`, `push`, and `rm`. This support is very early and not fully complete, and the command line interface for these tools has not been finalized. We welcome feedback on the new artifact experience through our issue tracker!
|
||||
|
|
|
|||
|
|
@ -339,16 +339,18 @@ func copyToContainer(container string, containerPath string, hostPath string) er
|
|||
return err
|
||||
}
|
||||
|
||||
hostInfo := ©.FileInfo{}
|
||||
var err error
|
||||
|
||||
isStdin := false
|
||||
if hostPath == "-" {
|
||||
hostPath = os.Stdin.Name()
|
||||
isStdin = true
|
||||
}
|
||||
|
||||
// Make sure that host path exists.
|
||||
hostInfo, err := copy.ResolveHostPath(hostPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%q could not be found on the host: %w", hostPath, err)
|
||||
} else {
|
||||
// Make sure that host path exists if not copying from stdin.
|
||||
hostInfo, err = copy.ResolveHostPath(hostPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%q could not be found on the host: %w", hostPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
containerBaseName, containerInfo, containerResolvedToParentDir, err := resolvePathOnDestinationContainer(container, containerPath, isStdin)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<installer-script minSpecVersion="1.000000">
|
||||
<title>Podman __VERSION__</title>
|
||||
<background mime-type="image/png" file="banner.png" scaling="proportional"/>
|
||||
<background mime-type="image/svg+xml" file="banner.svg" scaling="proportional"/>
|
||||
<welcome file="welcome.html" mime-type="text/html" />
|
||||
<conclusion file="conclusion.html" mime-type="text/html" />
|
||||
<license file="LICENSE.txt"/>
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 49 KiB |
|
|
@ -0,0 +1,424 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="149.71002mm"
|
||||
height="344.495mm"
|
||||
viewBox="0 0 149.71002 344.49499"
|
||||
version="1.1"
|
||||
id="svg2674"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs2668" />
|
||||
<metadata
|
||||
id="metadata2671">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
transform="translate(436.97793,61.541525)">
|
||||
<g
|
||||
id="g1208">
|
||||
<g
|
||||
id="g2422">
|
||||
<g
|
||||
id="g3222">
|
||||
<g
|
||||
aria-label="podman"
|
||||
id="text164931"
|
||||
style="font-size:37.592px;line-height:22.5552px;letter-spacing:0px;word-spacing:0px;fill:#892ca0;stroke-width:0.264583px"
|
||||
transform="matrix(0.67370844,0,0,0.67370844,-164.0368,284.29134)">
|
||||
<path
|
||||
d="m -358.34296,-93.074374 c -2.93217,0 -5.48843,1.12776 -7.10488,3.345688 v -3.157728 h -3.45847 v 27.216608 h 3.60883 v -10.300208 c 1.65405,2.142744 4.13512,3.232912 6.95452,3.232912 5.82676,0 10.07466,-4.059936 10.07466,-10.187432 0,-6.089904 -4.2479,-10.14984 -10.07466,-10.14984 z m -0.30073,17.179544 c -3.79679,0 -6.69138,-2.781808 -6.69138,-7.029704 0,-4.210304 2.89459,-6.992112 6.69138,-6.992112 3.83438,0 6.72897,2.781808 6.72897,6.992112 0,4.247896 -2.89459,7.029704 -6.72897,7.029704 z"
|
||||
style="font-weight:500;font-family:Montserrat;-inkscape-font-specification:'Montserrat Medium';letter-spacing:-2.11667px"
|
||||
id="path1388" />
|
||||
<path
|
||||
d="m -335.33997,-72.737102 c 5.97712,0 10.3378,-4.247896 10.3378,-10.187432 0,-5.939536 -4.36068,-10.14984 -10.3378,-10.14984 -5.97713,0 -10.3754,4.210304 -10.3754,10.14984 0,5.939536 4.39827,10.187432 10.3754,10.187432 z m 0,-3.157728 c -3.83439,0 -6.72897,-2.781808 -6.72897,-7.029704 0,-4.247896 2.89458,-6.992112 6.72897,-6.992112 3.83438,0 6.69137,2.744216 6.69137,6.992112 0,4.247896 -2.85699,7.029704 -6.69137,7.029704 z"
|
||||
style="font-weight:500;font-family:Montserrat;-inkscape-font-specification:'Montserrat Medium';letter-spacing:-2.11667px"
|
||||
id="path1390" />
|
||||
<path
|
||||
d="m -305.4201,-89.879054 c -1.65405,-2.142744 -4.13512,-3.19532 -6.95452,-3.19532 -5.82676,0 -10.07465,4.059936 -10.07465,10.14984 0,6.089904 4.24789,10.187432 10.07465,10.187432 2.93218,0 5.48843,-1.12776 7.10489,-3.38328 v 3.157728 h 3.45846 v -27.893266 h -3.60883 z m -6.65378,13.984224 c -3.83439,0 -6.72897,-2.781808 -6.72897,-7.029704 0,-4.247896 2.89458,-6.992112 6.72897,-6.992112 3.79679,0 6.69137,2.744216 6.69137,6.992112 0,4.247896 -2.89458,7.029704 -6.69137,7.029704 z"
|
||||
style="font-weight:500;font-family:Montserrat;-inkscape-font-specification:'Montserrat Medium';letter-spacing:-2.11667px"
|
||||
id="path1392" />
|
||||
<path
|
||||
d="m -272.16273,-93.074374 c -3.38328,0 -6.16509,1.428496 -7.66877,3.684016 -1.31572,-2.481072 -3.87197,-3.684016 -6.91692,-3.684016 -3.00736,0 -5.45084,1.12776 -6.87934,3.157728 v -2.969768 h -3.45846 v 19.92376 h 3.60883 V -83.22527 c 0,-4.32308 2.36829,-6.616192 5.97713,-6.616192 3.2705,0 5.1501,1.917192 5.1501,5.82676 v 11.052048 h 3.60883 V -83.22527 c 0,-4.32308 2.3683,-6.616192 5.97713,-6.616192 3.2705,0 5.1501,1.917192 5.1501,5.82676 v 11.052048 h 3.60884 v -11.46556 c 0,-5.864352 -3.3081,-8.64616 -8.15747,-8.64616 z"
|
||||
style="font-weight:500;font-family:Montserrat;-inkscape-font-specification:'Montserrat Medium';letter-spacing:-2.11667px;fill:#808080"
|
||||
id="path1394" />
|
||||
<path
|
||||
d="m -252.21292,-93.074374 c -3.19532,0 -6.16509,0.902208 -8.23265,2.556256 l 1.50368,2.706624 c 1.54128,-1.31572 3.94716,-2.142744 6.31546,-2.142744 3.57124,0 5.33806,1.766824 5.33806,4.811776 v 0.714248 h -5.71398 c -5.93954,0 -8.0071,2.63144 -8.0071,5.82676 0,3.458464 2.857,5.864352 7.36804,5.864352 3.12013,0 5.33806,-1.052576 6.541,-2.856992 v 2.63144 h 3.42088 v -12.02944 c 0,-5.45084 -3.08255,-8.08228 -8.53339,-8.08228 z m -0.82702,17.555464 c -2.74422,0 -4.39827,-1.240536 -4.39827,-3.232912 0,-1.69164 1.01499,-3.082544 4.58623,-3.082544 h 5.56361 v 2.781808 c -0.9022,2.293112 -3.04495,3.533648 -5.75157,3.533648 z"
|
||||
style="font-weight:500;font-family:Montserrat;-inkscape-font-specification:'Montserrat Medium';letter-spacing:-2.11667px;fill:#808080"
|
||||
id="path1396" />
|
||||
<path
|
||||
d="m -228.46632,-93.074374 c -3.15773,0 -5.71398,1.165352 -7.18007,3.19532 v -3.00736 h -3.45846 v 19.92376 h 3.60883 V -83.22527 c 0,-4.32308 2.48107,-6.616192 6.31545,-6.616192 3.42088,0 5.37566,1.917192 5.37566,5.82676 v 11.052048 h 3.60883 v -11.46556 c 0,-5.864352 -3.42087,-8.64616 -8.27024,-8.64616 z"
|
||||
style="font-weight:500;font-family:Montserrat;-inkscape-font-specification:'Montserrat Medium';letter-spacing:-2.11667px;fill:#808080"
|
||||
id="path1398" />
|
||||
</g>
|
||||
<g
|
||||
id="g3147"
|
||||
transform="matrix(0.7661413,0,0,0.7661413,0.58715789,307.14584)">
|
||||
<path
|
||||
id="path10348"
|
||||
d="m -444.08179,-150.6252 c -2.77363,0.65127 -4.83282,0.84476 -7.76516,0.85419"
|
||||
style="fill:none;fill-opacity:1;stroke:#3c6eb4;stroke-width:1.37375;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<g
|
||||
id="g9866"
|
||||
transform="matrix(1.6130363,0,0,1.6122057,-2404.4952,261.95405)"
|
||||
style="stroke-width:1.07323">
|
||||
<path
|
||||
id="rect9822"
|
||||
d="m 1196.4002,-277.28841 c -6.3145,0 -11.4334,5.11824 -11.4334,11.4319 0,5.60953 0.1555,10.87478 -3.8973,11.52796 2.2201,1.74955 31.1822,1.47773 31.1822,0.0657 -3.9446,-0.40986 -3.9311,-5.05055 -4.1745,-11.47895 -0.2435,-6.42839 -5.3624,-11.54663 -11.677,-11.54663 z"
|
||||
style="opacity:1;fill:#d7d8da;fill-opacity:1;stroke:#000000;stroke-width:0.851873;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<ellipse
|
||||
transform="matrix(0.99938194,-0.03515294,0.03512104,0.99938307,0,0)"
|
||||
style="opacity:1;fill:#f1f1f1;fill-opacity:1;stroke:none;stroke-width:0.851873;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:6;stroke-opacity:1"
|
||||
id="ellipse9760"
|
||||
cx="1196.4897"
|
||||
cy="-221.69182"
|
||||
rx="1.2185711"
|
||||
ry="1.2784375" />
|
||||
<ellipse
|
||||
transform="matrix(0.99946418,-0.03273147,0.0377188,0.99928839,0,0)"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#60605b;stroke-width:0.851878;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:6;stroke-opacity:1"
|
||||
id="ellipse9762"
|
||||
cx="1205.7982"
|
||||
cy="-224.76184"
|
||||
rx="3.8366725"
|
||||
ry="3.3919933" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.567915;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 1203.9748,-270.3367 c -0.3302,-0.40944 -0.849,-0.66007 -1.375,-0.66415 -0.4959,-0.004 -0.9897,0.21029 -1.3258,0.57498"
|
||||
id="path9764" />
|
||||
<g
|
||||
id="g9774"
|
||||
style="stroke-width:0.820075;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
transform="matrix(0.69366503,-0.00293008,0.00289825,0.69135666,529.16872,-257.19815)">
|
||||
<g
|
||||
style="stroke-width:0.820075;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="g9772"
|
||||
transform="translate(0,-0.52916667)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.820075;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 962.30591,-5.7829972 0.0993,1.9843749 c 0,0 1.58751,1.4221355 2.51355,-0.033073 0,0 -0.0993,-0.8268214 -0.16541,-1.0914047"
|
||||
id="path9768" />
|
||||
<path
|
||||
id="path9770"
|
||||
d="m 962.28751,-5.7829972 -0.0993,1.9843749 c 0,0 -1.58751,1.4221355 -2.51355,-0.033073 0,0 0.0993,-0.8268214 0.16541,-1.0914047"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.820075;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
id="path9776"
|
||||
style="fill:#808080;fill-opacity:1;stroke:#000000;stroke-width:0.567915;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 1197.9362,-265.07184 c -0.1012,-0.25799 -0.1029,-0.77483 -0.4026,-0.77357 -0.2995,0.002 -0.5774,-0.1914 -0.872,-0.19011 -0.2946,0.002 -0.571,0.19636 -0.8707,0.19765 -0.2993,0.002 -0.2975,0.51817 -0.396,0.77704 -0.1011,0.25897 1.275,1.09288 1.275,1.09288 0,0 1.3673,-0.84575 1.2663,-1.10389 z" />
|
||||
<path
|
||||
id="path9778"
|
||||
d="m 1188.9919,-270.28459 c 0.3005,-0.43161 0.8005,-0.71808 1.3248,-0.75912 0.4944,-0.0387 1.002,0.14023 1.3629,0.48043"
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.567915;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<g
|
||||
transform="translate(-0.1322934,-148.99351)"
|
||||
id="g9786"
|
||||
style="stroke-width:1.07323">
|
||||
<ellipse
|
||||
ry="1.9430941"
|
||||
rx="1.8695227"
|
||||
cy="-75.635956"
|
||||
cx="-1206.3459"
|
||||
id="ellipse9782"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#892ca0;stroke-width:0.851873;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
transform="matrix(-0.99938215,0.03514721,0.03512674,0.99938287,0,0)" />
|
||||
<ellipse
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.851873;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="ellipse9784"
|
||||
cx="1206.9153"
|
||||
cy="-76.182663"
|
||||
rx="0.91933995"
|
||||
ry="0.96816051"
|
||||
transform="matrix(0.99938215,-0.03514721,0.03512674,0.99938287,0,0)" />
|
||||
</g>
|
||||
<g
|
||||
id="g9796"
|
||||
style="stroke:#60605b;stroke-width:0.654754;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
transform="matrix(-0.86763199,-0.04368486,-0.04400126,0.8648962,2029.5877,-215.68906)">
|
||||
<g
|
||||
style="stroke-width:0.654754"
|
||||
id="g9794">
|
||||
<path
|
||||
id="path9788"
|
||||
d="m 956.32834,-6.2874931 c -2.17461,0.00852 -3.90258,0.727992 -5.25392,1.62519"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#60605b;stroke-width:0.654754;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path9790"
|
||||
d="m 957.00529,-5.3889116 c -2.45021,0.3102076 -3.99116,1.6666651 -5.21618,2.999397"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#60605b;stroke-width:0.654754;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path9792"
|
||||
d="m 957.14608,-4.4502461 c -2.0377,0.8062397 -3.03766,2.4684328 -3.7999,4.05763317"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#60605b;stroke-width:0.654754;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.86340059,-0.09610492,0.09623303,0.86064955,368.1354,-165.50024)"
|
||||
style="stroke:#60605b;stroke-width:0.654754;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="g9806">
|
||||
<g
|
||||
id="g9804"
|
||||
style="stroke-width:0.654754">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#60605b;stroke-width:0.654754;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 956.32834,-6.2874931 c -2.17461,0.00852 -3.90258,0.727992 -5.25392,1.62519"
|
||||
id="path9798" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#60605b;stroke-width:0.654754;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 957.00529,-5.3889116 c -2.45021,0.3102076 -3.99116,1.6666651 -5.21618,2.999397"
|
||||
id="path9800" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#60605b;stroke-width:0.654754;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 956.99206,-4.4197862 c -2.0377,0.8062397 -3.03766,2.4684328 -3.7999,4.05763312"
|
||||
id="path9802" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-0.1322934,-149.16808)"
|
||||
id="g9812"
|
||||
style="stroke-width:1.07323">
|
||||
<ellipse
|
||||
transform="matrix(0.99967764,-0.0253894,0.02538424,0.99967777,0,0)"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#892ca0;stroke-width:0.851873;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="ellipse9808"
|
||||
cx="1193.2991"
|
||||
cy="-87.545464"
|
||||
rx="1.8695223"
|
||||
ry="1.9430944" />
|
||||
<ellipse
|
||||
transform="matrix(-0.99967764,0.0253894,0.02538424,0.99967777,0,0)"
|
||||
ry="0.96816063"
|
||||
rx="0.91933978"
|
||||
cy="-88.092163"
|
||||
cx="-1192.7297"
|
||||
id="ellipse9810"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.851873;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
</g>
|
||||
<ellipse
|
||||
ry="1.2784375"
|
||||
rx="1.2185711"
|
||||
cy="-221.06982"
|
||||
cx="1214.1729"
|
||||
id="ellipse9814"
|
||||
style="opacity:1;fill:#f1f1f1;fill-opacity:1;stroke:none;stroke-width:0.851873;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:6;stroke-opacity:1"
|
||||
transform="matrix(0.99938194,-0.03515294,0.03512104,0.99938307,0,0)" />
|
||||
<path
|
||||
id="path9833"
|
||||
d="m 1196.6606,-258.19566 a 8.2351559,7.2429689 0 0 0 -7.6956,4.68912 c 4.7591,0.2089 10.6723,0.19768 15.4021,0.0114 a 8.2351559,7.2429689 0 0 0 -7.7065,-4.7005 z"
|
||||
style="opacity:1;fill:#f1f1f1;fill-opacity:1;stroke:none;stroke-width:0.851873;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
<path
|
||||
id="path10202"
|
||||
d="m -441.19238,-147.76894 c -6.18191,2.47555 -19.23662,1.9851 -31.5371,2.03356 -12.30048,0.0485 -26.99296,-0.47221 -29.4343,-2.93479"
|
||||
style="fill:none;fill-opacity:1;stroke:#3c6eb4;stroke-width:1.37375;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path9868"
|
||||
d="m -476.82225,-137.27468 c 0,1.74289 0,3.45904 -0.0294,5.09968 10.91678,2.00336 21.81435,2.04244 32.05407,0.0313 -0.0727,-1.55033 -0.12288,-3.20973 -0.18415,-4.96015 -0.33558,-9.58012 -7.38786,-16.29178 -16.08778,-16.29179 -8.70009,-2e-5 -15.75271,6.7118 -15.75271,16.12094 z"
|
||||
style="fill:#d7d8da;fill-opacity:1;stroke:#000000;stroke-width:1.37375;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<ellipse
|
||||
transform="matrix(0.99938258,-0.03513486,0.03513911,0.99938243,0,0)"
|
||||
style="fill:#f1f1f1;fill-opacity:1;stroke:none;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:6;stroke-opacity:1"
|
||||
id="ellipse9870"
|
||||
cx="-467.93243"
|
||||
cy="-153.02394"
|
||||
rx="1.9655981"
|
||||
ry="2.0611057" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.915833;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m -450.7952,-145.80336 c -0.43792,-0.54266 -1.12583,-0.8748 -1.82313,-0.88024 -0.65755,-0.005 -1.31224,0.27864 -1.75805,0.76203"
|
||||
id="path9874" />
|
||||
<path
|
||||
id="path9886"
|
||||
d="m -470.66267,-145.73375 c 0.39874,-0.57207 1.06164,-0.95168 1.75684,-1.00606 0.65557,-0.0513 1.32856,0.18584 1.8072,0.63674"
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.915833;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<ellipse
|
||||
transform="matrix(-0.99938278,0.03512913,0.03514482,0.99938223,0,0)"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#892ca0;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="ellipse9888"
|
||||
cx="447.0918"
|
||||
cy="-157.10309"
|
||||
rx="2.4790154"
|
||||
ry="2.5752487" />
|
||||
<ellipse
|
||||
transform="matrix(0.99938278,-0.03512913,0.03514482,0.99938223,0,0)"
|
||||
ry="1.2831359"
|
||||
rx="1.2190586"
|
||||
cy="-157.82765"
|
||||
cx="-446.33694"
|
||||
id="ellipse9890"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<path
|
||||
d="m -441.8137,-132.98859 -2.87591,0.82923 c -10.34738,2.0268 -21.24494,1.98772 -32.16172,-0.0156 l -4.37107,-0.81359"
|
||||
style="fill:none;fill-opacity:1;stroke:#3c6eb4;stroke-width:1.37375;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path10111" />
|
||||
<g
|
||||
id="g9900"
|
||||
style="stroke:#60605b;stroke-width:0.990478;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
transform="matrix(-0.93494181,-0.0460695,-0.04741483,0.91210891,437.99142,-86.849912)">
|
||||
<path
|
||||
id="path9898"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#60605b;stroke-width:0.990478;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 957.14608,-4.4502461 c -2.0377,0.8062397 -3.03766,2.4684328 -3.7999,4.05763317 m 3.65911,-4.99629867 c -2.45021,0.3102076 -3.99116,1.6666651 -5.21618,2.999397 m 4.53923,-3.8979785 c -2.17461,0.00852 -3.90258,0.727992 -5.25392,1.62519" />
|
||||
</g>
|
||||
<g
|
||||
style="stroke:#60605b;stroke-width:0.990478;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="g9910"
|
||||
transform="matrix(0.93038214,-0.10135107,0.10369867,0.90763043,-1354.1858,-33.902671)">
|
||||
<path
|
||||
id="path9904"
|
||||
d="m 956.32834,-6.2874931 c -2.17461,0.00852 -3.90258,0.727992 -5.25392,1.62519"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#60605b;stroke-width:0.990478;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path9906"
|
||||
d="m 957.00529,-5.3889116 c -2.45021,0.3102076 -3.99116,1.6666651 -5.21618,2.999397"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#60605b;stroke-width:0.990478;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path9908"
|
||||
d="m 956.99206,-4.4197862 c -2.0377,0.8062397 -3.03766,2.4684328 -3.7999,4.05763312"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#60605b;stroke-width:0.990478;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
<ellipse
|
||||
ry="2.575248"
|
||||
rx="2.4790156"
|
||||
cy="-153.14551"
|
||||
cx="-464.84341"
|
||||
id="ellipse9914"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#892ca0;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
transform="matrix(0.99967797,-0.02537634,0.02539731,0.99967744,0,0)" />
|
||||
<ellipse
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="ellipse9916"
|
||||
cx="465.59827"
|
||||
cy="-153.87009"
|
||||
rx="1.2190588"
|
||||
ry="1.2831357"
|
||||
transform="matrix(-0.99967797,0.02537634,0.02539731,0.99967744,0,0)" />
|
||||
<ellipse
|
||||
ry="2.0611057"
|
||||
rx="1.9655981"
|
||||
cy="-152.13847"
|
||||
cx="-442.74612"
|
||||
id="ellipse9920"
|
||||
style="fill:#f1f1f1;fill-opacity:1;stroke:none;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:6;stroke-opacity:1"
|
||||
transform="matrix(0.99938258,-0.03513486,0.03513911,0.99938243,0,0)" />
|
||||
<ellipse
|
||||
transform="matrix(0.99941617,-0.03416617,0.0361353,0.99934691,0,0)"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#60605b;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:6;stroke-opacity:1"
|
||||
id="ellipse9872"
|
||||
cx="-455.26074"
|
||||
cy="-151.74422"
|
||||
rx="5.1658988"
|
||||
ry="4.7670693" />
|
||||
<path
|
||||
id="path9884"
|
||||
style="fill:#808080;fill-opacity:1;stroke:#000000;stroke-width:0.915833;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m -458.44336,-137.5779 c -0.16269,-0.41594 -0.17706,-1.14424 -0.64937,-1.24717 l -1.40654,-0.30649 -1.40447,0.31866 c -0.47092,0.10696 -0.47992,0.83539 -0.6388,1.25275 -0.16269,0.4175 2.0566,1.76195 2.0566,1.76195 0,0 2.20543,-1.36354 2.04258,-1.7797 z" />
|
||||
<path
|
||||
id="path9966"
|
||||
d="m -460.7362,-135.31601 c -0.12115,0.19235 -0.30132,0.34666 -0.50987,0.43825 -0.22292,0.0973 -0.47473,0.12271 -0.71547,0.0857 -0.16961,-0.0261 -0.33455,-0.086 -0.48564,-0.16909 0,0.009 0,0.0173 0,0.026 0,1.07482 0.87141,1.94615 1.94618,1.94615 1.07477,0 1.946,-0.87133 1.946,-1.94615 1.8e-4,-0.009 1.8e-4,-0.0138 0,-0.0223 -0.15057,0.0813 -0.3117,0.13984 -0.48009,0.16545 -0.24074,0.0367 -0.49274,0.0121 -0.71565,-0.0857 -0.20838,-0.0916 -0.38802,-0.2459 -0.50969,-0.43825 -0.31828,-0.78325 -0.25961,-0.57731 -0.47577,0 z"
|
||||
style="fill:#ff8080;fill-opacity:1;stroke:#000000;stroke-width:0.915833;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path10198"
|
||||
style="fill:none;fill-opacity:1;stroke:#3c6eb4;stroke-width:1.37375;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m -458.77064,-127.6947 c -12.41384,0.25266 -18.71067,-0.70982 -29.09162,-3.23324" />
|
||||
<path
|
||||
d="m -455.9013,-124.32208 c -5.5554,0.61207 -10.15838,0.72756 -15.08432,0.0139"
|
||||
style="fill:none;fill-opacity:1;stroke:#3c6eb4;stroke-width:1.37375;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path10200" />
|
||||
<path
|
||||
style="fill:#d7d8da;fill-opacity:1;stroke:#000000;stroke-width:1.37375;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m -503.61272,-141.79238 c 0,1.40777 0,2.794 -0.0225,4.11918 7.87159,1.6182 15.72952,1.64977 23.11289,0.0253 -0.0502,-1.25225 -0.09,-2.59261 -0.13327,-4.0065 -0.24195,-7.73821 -5.62912,-11.2833 -11.59071,-11.2833 -5.96159,0 -11.36641,3.54523 -11.36641,11.14535 z"
|
||||
id="path10296" />
|
||||
<path
|
||||
id="path10298"
|
||||
d="m -485.20407,-147.92322 c -0.31851,-0.37308 -0.80436,-0.59755 -1.29491,-0.59827 -0.4666,-6.8e-4 -0.93008,0.20012 -1.24871,0.54099"
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.915833;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.915833;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m -499.37838,-147.88935 c 0.29596,-0.38442 0.76349,-0.63142 1.24784,-0.65924 0.46944,-0.027 0.94708,0.15177 1.28349,0.48029"
|
||||
id="path10302" />
|
||||
<ellipse
|
||||
ry="2.2342417"
|
||||
rx="2.1739042"
|
||||
cy="-160.29672"
|
||||
cx="480.3786"
|
||||
id="ellipse10306"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#892ca0;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
transform="matrix(-0.99939588,0.03475453,0.03552362,0.99936884,0,0)" />
|
||||
<ellipse
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="ellipse10308"
|
||||
cx="-479.71671"
|
||||
cy="-160.92535"
|
||||
rx="1.0690199"
|
||||
ry="1.1132268"
|
||||
transform="matrix(0.99939588,-0.03475453,0.03552362,0.99936884,0,0)" />
|
||||
<ellipse
|
||||
transform="matrix(0.99968481,-0.02510557,0.02567121,0.99967044,0,0)"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#892ca0;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="ellipse10310"
|
||||
cx="-494.4819"
|
||||
cy="-155.9659"
|
||||
rx="2.1739182"
|
||||
ry="2.2342269" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#60605b;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:6;stroke-opacity:1"
|
||||
d="m -492.31258,-142.58811 c -2.04693,0.0696 -3.65101,1.65127 -3.58282,3.53275 0.0238,0.63822 0.24237,1.94483 0.63055,2.47322 2.06007,0.11123 4.10755,0.12351 6.10045,0.0438 0.46757,-0.60775 0.70688,-2.02662 0.68151,-2.76926 -0.0683,-1.8814 -1.78285,-3.35012 -3.82969,-3.28054 z"
|
||||
id="ellipse10326" />
|
||||
<ellipse
|
||||
transform="matrix(-0.99968481,0.02510557,0.02567121,0.99967044,0,0)"
|
||||
ry="1.1132195"
|
||||
rx="1.0690267"
|
||||
cy="-156.59453"
|
||||
cx="495.1438"
|
||||
id="ellipse10312"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<path
|
||||
d="m -490.68885,-139.25523 c -0.11942,-0.30312 -0.13153,-0.83386 -0.47992,-0.90887 l -1.03946,-0.22336 -1.03808,0.23222 c -0.34805,0.0779 -0.35462,0.6088 -0.47214,0.91293 -0.11942,0.30426 1.52008,1.28402 1.52008,1.28402 0,0 1.62998,-0.99367 1.50952,-1.29694 z"
|
||||
style="fill:#808080;fill-opacity:1;stroke:#000000;stroke-width:0.915833;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path10328" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;stroke:#3c6eb4;stroke-width:1.37375;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m -505.35243,-134.46781 c 4.78315,1.26171 8.33422,1.63659 13.39134,1.65487"
|
||||
id="path10340" />
|
||||
<ellipse
|
||||
ry="1.6968153"
|
||||
rx="1.6181881"
|
||||
cy="-155.41756"
|
||||
cx="-479.56949"
|
||||
id="ellipse10355"
|
||||
style="fill:#f1f1f1;fill-opacity:1;stroke:none;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:6;stroke-opacity:1"
|
||||
transform="matrix(0.99938258,-0.03513486,0.03513911,0.99938243,0,0)" />
|
||||
<ellipse
|
||||
transform="matrix(0.99938258,-0.03513486,0.03513911,0.99938243,0,0)"
|
||||
style="fill:#f1f1f1;fill-opacity:1;stroke:none;stroke-width:1.37375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:6;stroke-opacity:1"
|
||||
id="ellipse10357"
|
||||
cx="-494.2135"
|
||||
cy="-155.93234"
|
||||
rx="1.6181881"
|
||||
ry="1.6968153" />
|
||||
<path
|
||||
id="path10338"
|
||||
d="m -506.66483,-138.36006 c 9.56648,2.52339 20.50611,2.33448 28.38463,0.17319"
|
||||
style="fill:none;fill-opacity:1;stroke:#3c6eb4;stroke-width:1.37375;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -9,7 +9,7 @@ podman\-import - Import a tarball and save it as a filesystem image
|
|||
**podman image import** [*options*] *path* [*reference*]
|
||||
|
||||
## DESCRIPTION
|
||||
**podman import** imports a tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz)
|
||||
**podman import** imports a tarball (.tar, .tar.gz, .tgz)
|
||||
and saves it as a filesystem image. Remote tarballs can be specified using a URL.
|
||||
Various image instructions can be configured with the **--change** flag and
|
||||
a commit message can be set using the **--message** flag.
|
||||
|
|
|
|||
6
go.mod
6
go.mod
|
|
@ -13,11 +13,11 @@ require (
|
|||
github.com/checkpoint-restore/checkpointctl v1.3.0
|
||||
github.com/checkpoint-restore/go-criu/v7 v7.2.0
|
||||
github.com/containernetworking/plugins v1.5.1
|
||||
github.com/containers/buildah v1.39.0
|
||||
github.com/containers/common v0.62.0
|
||||
github.com/containers/buildah v1.39.2
|
||||
github.com/containers/common v0.62.1
|
||||
github.com/containers/conmon v2.0.20+incompatible
|
||||
github.com/containers/gvisor-tap-vsock v0.8.3
|
||||
github.com/containers/image/v5 v5.34.0
|
||||
github.com/containers/image/v5 v5.34.1
|
||||
github.com/containers/libhvee v0.9.0
|
||||
github.com/containers/ocicrypt v1.2.1
|
||||
github.com/containers/psgo v1.9.0
|
||||
|
|
|
|||
12
go.sum
12
go.sum
|
|
@ -76,16 +76,16 @@ github.com/containernetworking/cni v1.2.3 h1:hhOcjNVUQTnzdRJ6alC5XF+wd9mfGIUaj8F
|
|||
github.com/containernetworking/cni v1.2.3/go.mod h1:DuLgF+aPd3DzcTQTtp/Nvl1Kim23oFKdm2okJzBQA5M=
|
||||
github.com/containernetworking/plugins v1.5.1 h1:T5ji+LPYjjgW0QM+KyrigZbLsZ8jaX+E5J/EcKOE4gQ=
|
||||
github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM=
|
||||
github.com/containers/buildah v1.39.0 h1:/OpzH7eMQYLg6pyguk6vugqScoZm8fIiN6wgMre9nUY=
|
||||
github.com/containers/buildah v1.39.0/go.mod h1:PTC4lCOwVfT3esN7Kxf2j8Aa3uqxsyUZudECLeGJlkY=
|
||||
github.com/containers/common v0.62.0 h1:Sl9WE5h7Y/F3bejrMAA4teP1EcY9ygqJmW4iwSloZ10=
|
||||
github.com/containers/common v0.62.0/go.mod h1:Yec+z8mrSq4rydHofrnDCBqAcNA/BGrSg1kfFUL6F6s=
|
||||
github.com/containers/buildah v1.39.2 h1:YaFMNnuTr7wKYKQDHkm7yyP9HhWVrNB4DA+DjYUS9k4=
|
||||
github.com/containers/buildah v1.39.2/go.mod h1:Vb4sDbEq06qQqk29mcGw/1qit8dyukpfL4hwNQ5t+z8=
|
||||
github.com/containers/common v0.62.1 h1:durvu7Kelb8PYgX7bwuAg/d5LKj2hs3cAaqcU7Vnqus=
|
||||
github.com/containers/common v0.62.1/go.mod h1:n9cEboBmY3AnTk1alkq4t7sLM4plwkDCiaWbsf67YxE=
|
||||
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/gvisor-tap-vsock v0.8.3 h1:Am3VdjXTn8Mn+dNhgkiRcCFOTSM8u9aWKLW3KTHOGjk=
|
||||
github.com/containers/gvisor-tap-vsock v0.8.3/go.mod h1:46MvrqNuRNbjV4ZsZ3mHVJjR2Eh+fpyRh72EvWWFFjU=
|
||||
github.com/containers/image/v5 v5.34.0 h1:HPqQaDUsox/3mC1pbOyLAIQEp0JhQqiUZ+6JiFIZLDI=
|
||||
github.com/containers/image/v5 v5.34.0/go.mod h1:/WnvUSEfdqC/ahMRd4YJDBLrpYWkGl018rB77iB3FDo=
|
||||
github.com/containers/image/v5 v5.34.1 h1:/m2bkFnuedTyNkzma8s7cFLjeefPIb4trjyafWhIlwM=
|
||||
github.com/containers/image/v5 v5.34.1/go.mod h1:/WnvUSEfdqC/ahMRd4YJDBLrpYWkGl018rB77iB3FDo=
|
||||
github.com/containers/libhvee v0.9.0 h1:5UxJMka1lDfxTeITA25Pd8QVVttJAG43eQS1Getw1tc=
|
||||
github.com/containers/libhvee v0.9.0/go.mod h1:p44VJd8jMIx3SRN1eM6PxfCEwXQE0lJ0dQppCAlzjPQ=
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
|
||||
|
|
|
|||
|
|
@ -598,7 +598,7 @@ func (c *Container) WaitForExit(ctx context.Context, pollInterval time.Duration)
|
|||
defer c.lock.Unlock()
|
||||
|
||||
if err := c.syncContainer(); err != nil {
|
||||
if errors.Is(err, define.ErrNoSuchCtr) {
|
||||
if errors.Is(err, define.ErrNoSuchCtr) || errors.Is(err, define.ErrCtrRemoved) {
|
||||
// if the container is not valid at this point as it was deleted,
|
||||
// check if the exit code was recorded in the db.
|
||||
exitCode, err := c.runtime.state.GetContainerExitCode(id)
|
||||
|
|
@ -645,7 +645,7 @@ func (c *Container) WaitForExit(ctx context.Context, pollInterval time.Duration)
|
|||
|
||||
// we locked again so we must sync the state
|
||||
if err := c.syncContainer(); err != nil {
|
||||
if errors.Is(err, define.ErrNoSuchCtr) {
|
||||
if errors.Is(err, define.ErrNoSuchCtr) || errors.Is(err, define.ErrCtrRemoved) {
|
||||
// if the container is not valid at this point as it was deleted,
|
||||
// check if the exit code was recorded in the db.
|
||||
exitCode, err := c.runtime.state.GetContainerExitCode(id)
|
||||
|
|
@ -767,6 +767,12 @@ func (c *Container) WaitForConditionWithInterval(ctx context.Context, waitTimeou
|
|||
// This allows callers to actually wait for the ctr to be removed.
|
||||
if wantedStates[define.ContainerStateRemoving] &&
|
||||
(errors.Is(err, define.ErrNoSuchCtr) || errors.Is(err, define.ErrCtrRemoved)) {
|
||||
// check if the exit code was recorded in the db to return it
|
||||
exitCode, err := c.runtime.state.GetContainerExitCode(c.ID())
|
||||
if err == nil {
|
||||
trySend(exitCode, nil)
|
||||
}
|
||||
|
||||
trySend(-1, nil)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ func GetDiskUsage(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
utils.WriteResponse(w, http.StatusOK, handlers.DiskUsage{DiskUsage: docker.DiskUsage{
|
||||
LayersSize: 0,
|
||||
LayersSize: df.ImagesSize,
|
||||
Images: imgs,
|
||||
Containers: ctnrs,
|
||||
Volumes: vols,
|
||||
|
|
|
|||
|
|
@ -283,6 +283,19 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
|
|||
var configMaps []v1.ConfigMap
|
||||
|
||||
ranContainers := false
|
||||
// set the ranContainers bool to true if at least one container was successfully started.
|
||||
setRanContainers := func(r *entities.PlayKubeReport) {
|
||||
if !ranContainers {
|
||||
for _, p := range r.Pods {
|
||||
// If the list of container errors is less then the total number of pod containers then we know it didn't start.
|
||||
if len(p.ContainerErrors) < len(p.Containers)+len(p.InitContainers) {
|
||||
ranContainers = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: both, the service container and the proxies, should ideally
|
||||
// be _state_ of an object. The Kube code below is quite Spaghetti-code
|
||||
// which we should refactor at some point to make it easier to extend
|
||||
|
|
@ -364,7 +377,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
|
|||
|
||||
report.Pods = append(report.Pods, r.Pods...)
|
||||
validKinds++
|
||||
ranContainers = true
|
||||
setRanContainers(r)
|
||||
case "DaemonSet":
|
||||
var daemonSetYAML v1apps.DaemonSet
|
||||
|
||||
|
|
@ -380,7 +393,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
|
|||
|
||||
report.Pods = append(report.Pods, r.Pods...)
|
||||
validKinds++
|
||||
ranContainers = true
|
||||
setRanContainers(r)
|
||||
case "Deployment":
|
||||
var deploymentYAML v1apps.Deployment
|
||||
|
||||
|
|
@ -396,7 +409,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
|
|||
|
||||
report.Pods = append(report.Pods, r.Pods...)
|
||||
validKinds++
|
||||
ranContainers = true
|
||||
setRanContainers(r)
|
||||
case "Job":
|
||||
var jobYAML v1.Job
|
||||
|
||||
|
|
@ -412,7 +425,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
|
|||
|
||||
report.Pods = append(report.Pods, r.Pods...)
|
||||
validKinds++
|
||||
ranContainers = true
|
||||
setRanContainers(r)
|
||||
case "PersistentVolumeClaim":
|
||||
var pvcYAML v1.PersistentVolumeClaim
|
||||
|
||||
|
|
@ -473,10 +486,14 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
|
|||
return nil, fmt.Errorf("YAML document does not contain any supported kube kind")
|
||||
}
|
||||
|
||||
if !options.ServiceContainer {
|
||||
return report, nil
|
||||
}
|
||||
|
||||
// If we started containers along with a service container, we are
|
||||
// running inside a systemd unit and need to set the main PID.
|
||||
|
||||
if options.ServiceContainer && ranContainers {
|
||||
if ranContainers {
|
||||
switch len(notifyProxies) {
|
||||
case 0: // Optimization for containers/podman/issues/17345
|
||||
// No container needs sdnotify, so we can mark the
|
||||
|
|
@ -509,6 +526,12 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
|
|||
}
|
||||
|
||||
report.ServiceContainerID = serviceContainer.ID()
|
||||
} else if serviceContainer != nil {
|
||||
// No containers started, make sure to stop the service container.
|
||||
// Note because the pods still do exists and are not removed by default we cannot remove it.
|
||||
if err := serviceContainer.StopWithTimeout(0); err != nil {
|
||||
logrus.Errorf("Failed to stop service container: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return report, nil
|
||||
|
|
@ -715,9 +738,6 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
|
|||
}
|
||||
|
||||
p := specgen.NewPodSpecGenerator()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p, err = entities.ToPodSpecGen(*p, &podOpt)
|
||||
if err != nil {
|
||||
|
|
@ -1143,7 +1163,6 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
|
|||
}
|
||||
for id, err := range podStartErrors {
|
||||
playKubePod.ContainerErrors = append(playKubePod.ContainerErrors, fmt.Errorf("starting container %s: %w", id, err).Error())
|
||||
fmt.Println(playKubePod.ContainerErrors)
|
||||
}
|
||||
|
||||
// Wait for each proxy to receive a READY message. Use a wait
|
||||
|
|
@ -1633,7 +1652,7 @@ func getBuildFile(imageName string, cwd string) (string, error) {
|
|||
// If the error is not because the file does not exist, take
|
||||
// a mulligan and try Dockerfile. If that also fails, return that
|
||||
// error
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
logrus.Error(err.Error())
|
||||
}
|
||||
|
||||
|
|
@ -1643,7 +1662,7 @@ func getBuildFile(imageName string, cwd string) (string, error) {
|
|||
return dockerfilePath, nil
|
||||
}
|
||||
// Strike two
|
||||
if os.IsNotExist(err) {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return "", nil
|
||||
}
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
package e2e_test
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
|
@ -253,6 +256,87 @@ var _ = Describe("run basic podman commands", func() {
|
|||
Expect(run).To(Exit(0))
|
||||
Expect(build.outputToString()).To(ContainSubstring(name))
|
||||
})
|
||||
|
||||
It("Copy ops", func() {
|
||||
var (
|
||||
stdinDirectory = "stdin-dir"
|
||||
stdinFile = "file.txt"
|
||||
)
|
||||
|
||||
now := time.Now()
|
||||
|
||||
tarBuffer := &bytes.Buffer{}
|
||||
tw := tar.NewWriter(tarBuffer)
|
||||
|
||||
// Write a directory header to the tar
|
||||
err := tw.WriteHeader(&tar.Header{
|
||||
Name: stdinDirectory,
|
||||
Mode: int64(0640 | fs.ModeDir),
|
||||
Gid: 1000,
|
||||
ModTime: now,
|
||||
ChangeTime: now,
|
||||
AccessTime: now,
|
||||
Typeflag: tar.TypeDir,
|
||||
})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
// Write a file header to the tar
|
||||
err = tw.WriteHeader(&tar.Header{
|
||||
Name: path.Join(stdinDirectory, stdinFile),
|
||||
Mode: 0755,
|
||||
Uid: 1000,
|
||||
ModTime: now,
|
||||
ChangeTime: now,
|
||||
AccessTime: now,
|
||||
})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
err = tw.Close()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
name := randomString()
|
||||
i := new(initMachine)
|
||||
session, err := mb.setName(name).setCmd(i.withImage(mb.imagePath).withNow()).run()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(session).To(Exit(0))
|
||||
|
||||
bm := basicMachine{}
|
||||
newImgs, err := mb.setCmd(bm.withPodmanCommand([]string{"pull", "quay.io/libpod/alpine_nginx"})).run()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(newImgs).To(Exit(0))
|
||||
Expect(newImgs.outputToStringSlice()).To(HaveLen(1))
|
||||
|
||||
createAlp, err := mb.setCmd(bm.withPodmanCommand([]string{"create", "quay.io/libpod/alpine_nginx"})).run()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(createAlp).To(Exit(0))
|
||||
Expect(createAlp.outputToStringSlice()).To(HaveLen(1))
|
||||
|
||||
// Testing stdin copy with archive mode disabled (ownership will be determined by the tar file)
|
||||
containerID := createAlp.outputToStringSlice()[0]
|
||||
cpTar, err := mb.setCmd(bm.withPodmanCommand([]string{"cp", "-a=false", "-", containerID + ":/tmp"})).setStdin(tarBuffer).run()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(cpTar).To(Exit(0))
|
||||
|
||||
start, err := mb.setCmd(bm.withPodmanCommand([]string{"start", containerID})).run()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(start).To(Exit(0))
|
||||
|
||||
// Check the directory is created with the appropriate mode, uid, gid
|
||||
exec, err := mb.setCmd(bm.withPodmanCommand([]string{"exec", containerID, "stat", "-c", "%a %u %g", "/tmp/stdin-dir"})).run()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(exec).To(Exit(0))
|
||||
execStdOut := exec.outputToStringSlice()
|
||||
Expect(execStdOut).To(HaveLen(1))
|
||||
Expect(execStdOut[0]).To(Equal("640 0 1000"))
|
||||
|
||||
// Check the file is created with the appropriate mode, uid, gid
|
||||
exec, err = mb.setCmd(bm.withPodmanCommand([]string{"exec", containerID, "stat", "-c", "%a %u %g", "/tmp/stdin-dir/file.txt"})).run()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(exec).To(Exit(0))
|
||||
execStdOut = exec.outputToStringSlice()
|
||||
Expect(execStdOut).To(HaveLen(1))
|
||||
Expect(execStdOut[0]).To(Equal("755 1000 0"))
|
||||
})
|
||||
})
|
||||
|
||||
func testHTTPServer(port string, shouldErr bool, expectedResponse string) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package e2e_test
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
|
@ -44,6 +45,7 @@ type machineSession struct {
|
|||
|
||||
type machineTestBuilder struct {
|
||||
cmd []string
|
||||
stdin io.Reader
|
||||
imagePath string
|
||||
name string
|
||||
names []string
|
||||
|
|
@ -139,6 +141,13 @@ func (m *machineTestBuilder) setCmd(mc machineCommand) *machineTestBuilder {
|
|||
m.names = append(m.names, m.name)
|
||||
}
|
||||
m.cmd = mc.buildCmd(m)
|
||||
m.stdin = nil
|
||||
return m
|
||||
}
|
||||
|
||||
// setStdin sets the stdin for the next command to be run
|
||||
func (m *machineTestBuilder) setStdin(data io.Reader) *machineTestBuilder {
|
||||
m.stdin = data
|
||||
return m
|
||||
}
|
||||
|
||||
|
|
@ -152,7 +161,7 @@ func (m *machineTestBuilder) setTimeout(timeout time.Duration) *machineTestBuild
|
|||
func (m *machineTestBuilder) toQemuInspectInfo() ([]machine.InspectInfo, int, error) {
|
||||
args := []string{"machine", "inspect"}
|
||||
args = append(args, m.names...)
|
||||
session, err := runWrapper(m.podmanBinary, args, defaultTimeout, true)
|
||||
session, err := runWrapper(m.podmanBinary, args, nil, defaultTimeout, true)
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
|
|
@ -162,20 +171,24 @@ func (m *machineTestBuilder) toQemuInspectInfo() ([]machine.InspectInfo, int, er
|
|||
}
|
||||
|
||||
func (m *machineTestBuilder) runWithoutWait() (*machineSession, error) {
|
||||
return runWrapper(m.podmanBinary, m.cmd, m.timeout, false)
|
||||
return runWrapper(m.podmanBinary, m.cmd, m.stdin, m.timeout, false)
|
||||
}
|
||||
|
||||
func (m *machineTestBuilder) run() (*machineSession, error) {
|
||||
s, err := runWrapper(m.podmanBinary, m.cmd, m.timeout, true)
|
||||
s, err := runWrapper(m.podmanBinary, m.cmd, m.stdin, m.timeout, true)
|
||||
return s, err
|
||||
}
|
||||
|
||||
func runWrapper(podmanBinary string, cmdArgs []string, timeout time.Duration, wait bool) (*machineSession, error) {
|
||||
func runWrapper(podmanBinary string, cmdArgs []string, stdinData io.Reader, timeout time.Duration, wait bool) (*machineSession, error) {
|
||||
if len(os.Getenv("DEBUG")) > 0 {
|
||||
cmdArgs = append([]string{"--log-level=debug"}, cmdArgs...)
|
||||
}
|
||||
GinkgoWriter.Println(podmanBinary + " " + strings.Join(cmdArgs, " "))
|
||||
c := exec.Command(podmanBinary, cmdArgs...)
|
||||
if stdinData != nil {
|
||||
c.Stdin = stdinData
|
||||
}
|
||||
|
||||
session, err := Start(c, GinkgoWriter, GinkgoWriter)
|
||||
if err != nil {
|
||||
Fail(fmt.Sprintf("Unable to start session: %q", err))
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ t POST containers/create Image=$IMAGE Volumes='{"/test":{}}' HostConfig='{"Binds
|
|||
.Id~[0-9a-f]\\{64\\}
|
||||
cid=$(jq -r '.Id' <<<"$output")
|
||||
|
||||
# Verify image takes size
|
||||
t GET system/df 200 '.LayersSize=12180391'
|
||||
t GET libpod/system/df 200 '.ImagesSize=12180391'
|
||||
|
||||
# Verify that one container references the volume
|
||||
t GET system/df 200 '.Volumes[0].UsageData.RefCount=1'
|
||||
|
||||
|
|
|
|||
|
|
@ -1107,6 +1107,59 @@ EOF
|
|||
service_cleanup $QUADLET_SERVICE_NAME inactive
|
||||
}
|
||||
|
||||
# https://github.com/containers/podman/issues/20667
|
||||
@test "quadlet kube - start error" {
|
||||
local port=$(random_free_port)
|
||||
# Create the YAMl file
|
||||
pod_name="p-$(safename)"
|
||||
container_name="c-$(safename)"
|
||||
yaml_source="$PODMAN_TMPDIR/start_err$(safename).yaml"
|
||||
cat >$yaml_source <<EOF
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: $pod_name
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- "top"
|
||||
image: $IMAGE
|
||||
name: $container_name
|
||||
ports:
|
||||
- containerPort: 80
|
||||
hostPort: $port
|
||||
EOF
|
||||
|
||||
# Bind the port to force a an error when starting the pod
|
||||
timeout --foreground -v --kill=10 10 nc -l 127.0.0.1 $port &
|
||||
nc_pid=$!
|
||||
|
||||
# Create the Quadlet file
|
||||
local quadlet_file=$PODMAN_TMPDIR/start_err_$(safename).kube
|
||||
cat > $quadlet_file <<EOF
|
||||
[Kube]
|
||||
Yaml=${yaml_source}
|
||||
EOF
|
||||
|
||||
run_quadlet "$quadlet_file"
|
||||
|
||||
run -0 systemctl daemon-reload
|
||||
|
||||
echo "$_LOG_PROMPT systemctl start $QUADLET_SERVICE_NAME"
|
||||
run systemctl start $QUADLET_SERVICE_NAME
|
||||
echo $output
|
||||
assert $status -eq 1 "systemctl start should report failure"
|
||||
|
||||
run -0 systemctl show --property=ActiveState $QUADLET_SERVICE_NAME
|
||||
assert "$output" == "ActiveState=failed" "unit must be in failed state"
|
||||
|
||||
echo "$_LOG_PROMPT journalctl -u $QUADLET_SERVICE_NAME"
|
||||
run -0 journalctl -eu $QUADLET_SERVICE_NAME
|
||||
assert "$output" =~ "$port: bind: address already in use" "journal contains the real podman start error"
|
||||
|
||||
kill "$nc_pid"
|
||||
}
|
||||
|
||||
@test "quadlet - image files" {
|
||||
local quadlet_tmpdir=$PODMAN_TMPDIR/quadlets
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ env:
|
|||
#### Global variables used for all tasks
|
||||
####
|
||||
# Name of the ultimate destination branch for this CI run, PR or post-merge.
|
||||
DEST_BRANCH: "main"
|
||||
DEST_BRANCH: "release-1.39"
|
||||
GOPATH: "/var/tmp/go"
|
||||
GOSRC: "${GOPATH}/src/github.com/containers/buildah"
|
||||
GOCACHE: "/tmp/go-build"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,15 @@
|
|||
|
||||
# Changelog
|
||||
|
||||
## v1.39.2 (2025-03-03)
|
||||
|
||||
[release-1.39] Bump c/image to v5.34.1, c/common v0.62.1
|
||||
|
||||
## v1.39.1 (2025-02-25)
|
||||
|
||||
chroot createPlatformContainer: use MS_REMOUNT
|
||||
chore(deps): update module github.com/go-jose/go-jose/v4 to v4.0.5 [security]
|
||||
|
||||
## v1.39.0 (2025-01-31)
|
||||
|
||||
Bump c/storage v1.57.1, c/image 5.34.0, c/common v0.62.0
|
||||
|
|
|
|||
|
|
@ -1,3 +1,11 @@
|
|||
- Changelog for v1.39.2 (2025-03-03)
|
||||
* [release-1.39] Bump c/image to v5.34.1, c/common v0.62.1
|
||||
|
||||
- Changelog for v1.39.1 (2025-02-25)
|
||||
|
||||
* chroot createPlatformContainer: use MS_REMOUNT
|
||||
* chore(deps): update module github.com/go-jose/go-jose/v4 to v4.0.5 [security]
|
||||
|
||||
- Changelog for v1.39.0 (2025-01-31)
|
||||
* Bump c/storage v1.57.1, c/image 5.34.0, c/common v0.62.0
|
||||
* Update module github.com/containers/storage to v1.57.0
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ func createPlatformContainer(options runUsingChrootExecSubprocOptions) error {
|
|||
return fmt.Errorf("changing to host root directory: %w", err)
|
||||
}
|
||||
// make sure we only unmount things under this tree
|
||||
if err := unix.Mount(".", ".", "bind", unix.MS_BIND|unix.MS_SLAVE|unix.MS_REC, ""); err != nil {
|
||||
if err := unix.Mount(".", ".", "bind", unix.MS_REMOUNT|unix.MS_BIND|unix.MS_SLAVE|unix.MS_REC, ""); err != nil {
|
||||
return fmt.Errorf("tweaking mount flags on host root directory before unmounting from mount namespace: %w", err)
|
||||
}
|
||||
// detach this (unnamed?) old directory
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ const (
|
|||
// identify working containers.
|
||||
Package = "buildah"
|
||||
// Version for the Package. Also used by .packit.sh for Packit builds.
|
||||
Version = "1.39.0"
|
||||
Version = "1.39.2"
|
||||
|
||||
// DefaultRuntime if containers.conf fails.
|
||||
DefaultRuntime = "runc"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package version
|
||||
|
||||
// Version is the version of the build.
|
||||
const Version = "0.62.0"
|
||||
const Version = "0.62.1"
|
||||
|
|
|
|||
|
|
@ -108,19 +108,10 @@ func (f *fulcioTrustRoot) verifyFulcioCertificateAtTime(relevantTime time.Time,
|
|||
}
|
||||
}
|
||||
|
||||
untrustedLeafCerts, err := cryptoutils.UnmarshalCertificatesFromPEM(untrustedCertificateBytes)
|
||||
untrustedCertificate, err := parseLeafCertFromPEM(untrustedCertificateBytes)
|
||||
if err != nil {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("parsing leaf certificate: %v", err))
|
||||
return nil, err
|
||||
}
|
||||
switch len(untrustedLeafCerts) {
|
||||
case 0:
|
||||
return nil, internal.NewInvalidSignatureError("no certificate found in signature certificate data")
|
||||
case 1:
|
||||
break // OK
|
||||
default:
|
||||
return nil, internal.NewInvalidSignatureError("unexpected multiple certificates present in signature certificate data")
|
||||
}
|
||||
untrustedCertificate := untrustedLeafCerts[0]
|
||||
|
||||
// Go rejects Subject Alternative Name that has no DNSNames, EmailAddresses, IPAddresses and URIs;
|
||||
// we match SAN ourselves, so override that.
|
||||
|
|
@ -195,6 +186,21 @@ func (f *fulcioTrustRoot) verifyFulcioCertificateAtTime(relevantTime time.Time,
|
|||
return untrustedCertificate.PublicKey, nil
|
||||
}
|
||||
|
||||
func parseLeafCertFromPEM(untrustedCertificateBytes []byte) (*x509.Certificate, error) {
|
||||
untrustedLeafCerts, err := cryptoutils.UnmarshalCertificatesFromPEM(untrustedCertificateBytes)
|
||||
if err != nil {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("parsing leaf certificate: %v", err))
|
||||
}
|
||||
switch len(untrustedLeafCerts) {
|
||||
case 0:
|
||||
return nil, internal.NewInvalidSignatureError("no certificate found in signature certificate data")
|
||||
case 1: // OK
|
||||
return untrustedLeafCerts[0], nil
|
||||
default:
|
||||
return nil, internal.NewInvalidSignatureError("unexpected multiple certificates present in signature certificate data")
|
||||
}
|
||||
}
|
||||
|
||||
func verifyRekorFulcio(rekorPublicKeys []*ecdsa.PublicKey, fulcioTrustRoot *fulcioTrustRoot, untrustedRekorSET []byte,
|
||||
untrustedCertificateBytes []byte, untrustedIntermediateChainBytes []byte, untrustedBase64Signature string,
|
||||
untrustedPayloadBytes []byte) (crypto.PublicKey, error) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
package signature
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"github.com/containers/image/v5/signature/internal"
|
||||
"github.com/sigstore/sigstore/pkg/cryptoutils"
|
||||
)
|
||||
|
||||
type pkiTrustRoot struct {
|
||||
caRootsCertificates *x509.CertPool
|
||||
caIntermediateCertificates *x509.CertPool
|
||||
subjectEmail string
|
||||
subjectHostname string
|
||||
}
|
||||
|
||||
func (p *pkiTrustRoot) validate() error {
|
||||
if p.subjectEmail == "" && p.subjectHostname == "" {
|
||||
return errors.New("Internal inconsistency: PKI use set up without subject email or subject hostname")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func verifyPKI(pkiTrustRoot *pkiTrustRoot, untrustedCertificateBytes []byte, untrustedIntermediateChainBytes []byte) (crypto.PublicKey, error) {
|
||||
var untrustedIntermediatePool *x509.CertPool
|
||||
if pkiTrustRoot.caIntermediateCertificates != nil {
|
||||
untrustedIntermediatePool = pkiTrustRoot.caIntermediateCertificates.Clone()
|
||||
} else {
|
||||
untrustedIntermediatePool = x509.NewCertPool()
|
||||
}
|
||||
if len(untrustedIntermediateChainBytes) > 0 {
|
||||
untrustedIntermediateChain, err := cryptoutils.UnmarshalCertificatesFromPEM(untrustedIntermediateChainBytes)
|
||||
if err != nil {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("loading certificate chain: %v", err))
|
||||
}
|
||||
if len(untrustedIntermediateChain) > 1 {
|
||||
for _, untrustedIntermediateCert := range untrustedIntermediateChain[:len(untrustedIntermediateChain)-1] {
|
||||
untrustedIntermediatePool.AddCert(untrustedIntermediateCert)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
untrustedCertificate, err := parseLeafCertFromPEM(untrustedCertificateBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := untrustedCertificate.Verify(x509.VerifyOptions{
|
||||
Intermediates: untrustedIntermediatePool,
|
||||
Roots: pkiTrustRoot.caRootsCertificates,
|
||||
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
|
||||
}); err != nil {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("veryfing leaf certificate failed: %v", err))
|
||||
}
|
||||
|
||||
if pkiTrustRoot.subjectEmail != "" {
|
||||
if !slices.Contains(untrustedCertificate.EmailAddresses, pkiTrustRoot.subjectEmail) {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("Required email %q not found (got %q)",
|
||||
pkiTrustRoot.subjectEmail,
|
||||
untrustedCertificate.EmailAddresses))
|
||||
}
|
||||
}
|
||||
if pkiTrustRoot.subjectHostname != "" {
|
||||
if err = untrustedCertificate.VerifyHostname(pkiTrustRoot.subjectHostname); err != nil {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("Unexpected subject hostname: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
return untrustedCertificate.PublicKey, nil
|
||||
}
|
||||
|
|
@ -71,6 +71,17 @@ func PRSigstoreSignedWithFulcio(fulcio PRSigstoreSignedFulcio) PRSigstoreSignedO
|
|||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedWithPKI specifies a value for the "pki" field when calling NewPRSigstoreSigned.
|
||||
func PRSigstoreSignedWithPKI(p PRSigstoreSignedPKI) PRSigstoreSignedOption {
|
||||
return func(pr *prSigstoreSigned) error {
|
||||
if pr.PKI != nil {
|
||||
return InvalidPolicyFormatError(`"pki" already specified`)
|
||||
}
|
||||
pr.PKI = p
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedWithRekorPublicKeyPath specifies a value for the "rekorPublicKeyPath" field when calling NewPRSigstoreSigned.
|
||||
func PRSigstoreSignedWithRekorPublicKeyPath(rekorPublicKeyPath string) PRSigstoreSignedOption {
|
||||
return func(pr *prSigstoreSigned) error {
|
||||
|
|
@ -159,8 +170,11 @@ func newPRSigstoreSigned(options ...PRSigstoreSignedOption) (*prSigstoreSigned,
|
|||
if res.Fulcio != nil {
|
||||
keySources++
|
||||
}
|
||||
if res.PKI != nil {
|
||||
keySources++
|
||||
}
|
||||
if keySources != 1 {
|
||||
return nil, InvalidPolicyFormatError("exactly one of keyPath, keyPaths, keyData, keyDatas and fulcio must be specified")
|
||||
return nil, InvalidPolicyFormatError("exactly one of keyPath, keyPaths, keyData, keyDatas, fulcio, and pki must be specified")
|
||||
}
|
||||
|
||||
rekorSources := 0
|
||||
|
|
@ -182,6 +196,9 @@ func newPRSigstoreSigned(options ...PRSigstoreSignedOption) (*prSigstoreSigned,
|
|||
if res.Fulcio != nil && rekorSources == 0 {
|
||||
return nil, InvalidPolicyFormatError("At least one of rekorPublickeyPath, rekorPublicKeyPaths, rekorPublickeyData and rekorPublicKeyDatas must be specified if fulcio is used")
|
||||
}
|
||||
if res.PKI != nil && rekorSources > 0 {
|
||||
return nil, InvalidPolicyFormatError("rekorPublickeyPath, rekorPublicKeyPaths, rekorPublickeyData and rekorPublicKeyDatas are not supported for pki")
|
||||
}
|
||||
|
||||
if res.SignedIdentity == nil {
|
||||
return nil, InvalidPolicyFormatError("signedIdentity not specified")
|
||||
|
|
@ -218,9 +235,10 @@ var _ json.Unmarshaler = (*prSigstoreSigned)(nil)
|
|||
func (pr *prSigstoreSigned) UnmarshalJSON(data []byte) error {
|
||||
*pr = prSigstoreSigned{}
|
||||
var tmp prSigstoreSigned
|
||||
var gotKeyPath, gotKeyPaths, gotKeyData, gotKeyDatas, gotFulcio bool
|
||||
var gotKeyPath, gotKeyPaths, gotKeyData, gotKeyDatas, gotFulcio, gotPKI bool
|
||||
var gotRekorPublicKeyPath, gotRekorPublicKeyPaths, gotRekorPublicKeyData, gotRekorPublicKeyDatas bool
|
||||
var fulcio prSigstoreSignedFulcio
|
||||
var pki prSigstoreSignedPKI
|
||||
var signedIdentity json.RawMessage
|
||||
if err := internal.ParanoidUnmarshalJSONObject(data, func(key string) any {
|
||||
switch key {
|
||||
|
|
@ -253,6 +271,9 @@ func (pr *prSigstoreSigned) UnmarshalJSON(data []byte) error {
|
|||
case "rekorPublicKeyDatas":
|
||||
gotRekorPublicKeyDatas = true
|
||||
return &tmp.RekorPublicKeyDatas
|
||||
case "pki":
|
||||
gotPKI = true
|
||||
return &pki
|
||||
case "signedIdentity":
|
||||
return &signedIdentity
|
||||
default:
|
||||
|
|
@ -303,6 +324,9 @@ func (pr *prSigstoreSigned) UnmarshalJSON(data []byte) error {
|
|||
if gotRekorPublicKeyDatas {
|
||||
opts = append(opts, PRSigstoreSignedWithRekorPublicKeyDatas(tmp.RekorPublicKeyDatas))
|
||||
}
|
||||
if gotPKI {
|
||||
opts = append(opts, PRSigstoreSignedWithPKI(&pki))
|
||||
}
|
||||
opts = append(opts, PRSigstoreSignedWithSignedIdentity(tmp.SignedIdentity))
|
||||
|
||||
res, err := newPRSigstoreSigned(opts...)
|
||||
|
|
@ -440,3 +464,167 @@ func (f *prSigstoreSignedFulcio) UnmarshalJSON(data []byte) error {
|
|||
*f = *res
|
||||
return nil
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKIOption is a way to pass values to NewPRSigstoreSignedPKI
|
||||
type PRSigstoreSignedPKIOption func(*prSigstoreSignedPKI) error
|
||||
|
||||
// PRSigstoreSignedPKIWithCARootsPath specifies a value for the "caRootsPath" field when calling NewPRSigstoreSignedPKI
|
||||
func PRSigstoreSignedPKIWithCARootsPath(caRootsPath string) PRSigstoreSignedPKIOption {
|
||||
return func(p *prSigstoreSignedPKI) error {
|
||||
if p.CARootsPath != "" {
|
||||
return InvalidPolicyFormatError(`"caRootsPath" already specified`)
|
||||
}
|
||||
p.CARootsPath = caRootsPath
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKIWithCARootsData specifies a value for the "caRootsData" field when calling NewPRSigstoreSignedPKI
|
||||
func PRSigstoreSignedPKIWithCARootsData(caRootsData []byte) PRSigstoreSignedPKIOption {
|
||||
return func(p *prSigstoreSignedPKI) error {
|
||||
if p.CARootsData != nil {
|
||||
return InvalidPolicyFormatError(`"caRootsData" already specified`)
|
||||
}
|
||||
p.CARootsData = caRootsData
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKIWithCAIntermediatesPath specifies a value for the "caIntermediatesPath" field when calling NewPRSigstoreSignedPKI
|
||||
func PRSigstoreSignedPKIWithCAIntermediatesPath(caIntermediatesPath string) PRSigstoreSignedPKIOption {
|
||||
return func(p *prSigstoreSignedPKI) error {
|
||||
if p.CAIntermediatesPath != "" {
|
||||
return InvalidPolicyFormatError(`"caIntermediatesPath" already specified`)
|
||||
}
|
||||
p.CAIntermediatesPath = caIntermediatesPath
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKIWithCAIntermediatesData specifies a value for the "caIntermediatesData" field when calling NewPRSigstoreSignedPKI
|
||||
func PRSigstoreSignedPKIWithCAIntermediatesData(caIntermediatesData []byte) PRSigstoreSignedPKIOption {
|
||||
return func(p *prSigstoreSignedPKI) error {
|
||||
if p.CAIntermediatesData != nil {
|
||||
return InvalidPolicyFormatError(`"caIntermediatesData" already specified`)
|
||||
}
|
||||
p.CAIntermediatesData = caIntermediatesData
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKIWithSubjectEmail specifies a value for the "subjectEmail" field when calling NewPRSigstoreSignedPKI
|
||||
func PRSigstoreSignedPKIWithSubjectEmail(subjectEmail string) PRSigstoreSignedPKIOption {
|
||||
return func(p *prSigstoreSignedPKI) error {
|
||||
if p.SubjectEmail != "" {
|
||||
return InvalidPolicyFormatError(`"subjectEmail" already specified`)
|
||||
}
|
||||
p.SubjectEmail = subjectEmail
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKIWithSubjectHostname specifies a value for the "subjectHostname" field when calling NewPRSigstoreSignedPKI
|
||||
func PRSigstoreSignedPKIWithSubjectHostname(subjectHostname string) PRSigstoreSignedPKIOption {
|
||||
return func(p *prSigstoreSignedPKI) error {
|
||||
if p.SubjectHostname != "" {
|
||||
return InvalidPolicyFormatError(`"subjectHostname" already specified`)
|
||||
}
|
||||
p.SubjectHostname = subjectHostname
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// newPRSigstoreSignedPKI is NewPRSigstoreSignedPKI, except it returns the private type
|
||||
func newPRSigstoreSignedPKI(options ...PRSigstoreSignedPKIOption) (*prSigstoreSignedPKI, error) {
|
||||
res := prSigstoreSignedPKI{}
|
||||
for _, o := range options {
|
||||
if err := o(&res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if res.CARootsPath != "" && res.CARootsData != nil {
|
||||
return nil, InvalidPolicyFormatError("caRootsPath and caRootsData cannot be used simultaneously")
|
||||
}
|
||||
if res.CARootsPath == "" && res.CARootsData == nil {
|
||||
return nil, InvalidPolicyFormatError("At least one of caRootsPath and caRootsData must be specified")
|
||||
}
|
||||
|
||||
if res.CAIntermediatesPath != "" && res.CAIntermediatesData != nil {
|
||||
return nil, InvalidPolicyFormatError("caIntermediatesPath and caIntermediatesData cannot be used simultaneously")
|
||||
}
|
||||
|
||||
if res.SubjectEmail == "" && res.SubjectHostname == "" {
|
||||
return nil, InvalidPolicyFormatError("At least one of subjectEmail, subjectHostname must be specified")
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// NewPRSigstoreSignedPKI returns a PRSigstoreSignedPKI based on options.
|
||||
func NewPRSigstoreSignedPKI(options ...PRSigstoreSignedPKIOption) (PRSigstoreSignedPKI, error) {
|
||||
return newPRSigstoreSignedPKI(options...)
|
||||
}
|
||||
|
||||
// Compile-time check that prSigstoreSignedPKI implements json.Unmarshaler.
|
||||
var _ json.Unmarshaler = (*prSigstoreSignedPKI)(nil)
|
||||
|
||||
func (p *prSigstoreSignedPKI) UnmarshalJSON(data []byte) error {
|
||||
*p = prSigstoreSignedPKI{}
|
||||
var tmp prSigstoreSignedPKI
|
||||
var gotCARootsPath, gotCARootsData, gotCAIntermediatesPath, gotCAIntermediatesData, gotSubjectEmail, gotSubjectHostname bool
|
||||
if err := internal.ParanoidUnmarshalJSONObject(data, func(key string) any {
|
||||
switch key {
|
||||
case "caRootsPath":
|
||||
gotCARootsPath = true
|
||||
return &tmp.CARootsPath
|
||||
case "caRootsData":
|
||||
gotCARootsData = true
|
||||
return &tmp.CARootsData
|
||||
case "caIntermediatesPath":
|
||||
gotCAIntermediatesPath = true
|
||||
return &tmp.CAIntermediatesPath
|
||||
case "caIntermediatesData":
|
||||
gotCAIntermediatesData = true
|
||||
return &tmp.CAIntermediatesData
|
||||
case "subjectEmail":
|
||||
gotSubjectEmail = true
|
||||
return &tmp.SubjectEmail
|
||||
case "subjectHostname":
|
||||
gotSubjectHostname = true
|
||||
return &tmp.SubjectHostname
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var opts []PRSigstoreSignedPKIOption
|
||||
if gotCARootsPath {
|
||||
opts = append(opts, PRSigstoreSignedPKIWithCARootsPath(tmp.CARootsPath))
|
||||
}
|
||||
if gotCARootsData {
|
||||
opts = append(opts, PRSigstoreSignedPKIWithCARootsData(tmp.CARootsData))
|
||||
}
|
||||
if gotCAIntermediatesPath {
|
||||
opts = append(opts, PRSigstoreSignedPKIWithCAIntermediatesPath(tmp.CAIntermediatesPath))
|
||||
}
|
||||
if gotCAIntermediatesData {
|
||||
opts = append(opts, PRSigstoreSignedPKIWithCAIntermediatesData(tmp.CAIntermediatesData))
|
||||
}
|
||||
if gotSubjectEmail {
|
||||
opts = append(opts, PRSigstoreSignedPKIWithSubjectEmail(tmp.SubjectEmail))
|
||||
}
|
||||
if gotSubjectHostname {
|
||||
opts = append(opts, PRSigstoreSignedPKIWithSubjectHostname(tmp.SubjectHostname))
|
||||
}
|
||||
|
||||
res, err := newPRSigstoreSignedPKI(opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*p = *res
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,11 +97,64 @@ func (f *prSigstoreSignedFulcio) prepareTrustRoot() (*fulcioTrustRoot, error) {
|
|||
return &fulcio, nil
|
||||
}
|
||||
|
||||
// prepareTrustRoot creates a pkiTrustRoot from the input data.
|
||||
// (This also prevents external implementations of this interface, ensuring that prSigstoreSignedPKI is the only one.)
|
||||
func (p *prSigstoreSignedPKI) prepareTrustRoot() (*pkiTrustRoot, error) {
|
||||
caRootsCertPEMs, err := loadBytesFromConfigSources(configBytesSources{
|
||||
inconsistencyErrorMessage: `Internal inconsistency: both "caRootsPath" and "caRootsData" specified`,
|
||||
path: p.CARootsPath,
|
||||
data: p.CARootsData,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(caRootsCertPEMs) != 1 {
|
||||
return nil, errors.New(`Internal inconsistency: PKI specified with not exactly one of "caRootsPath" nor "caRootsData"`)
|
||||
}
|
||||
rootsCerts := x509.NewCertPool()
|
||||
if ok := rootsCerts.AppendCertsFromPEM(caRootsCertPEMs[0]); !ok {
|
||||
return nil, errors.New("error loading PKI CA Roots certificates")
|
||||
}
|
||||
pki := pkiTrustRoot{
|
||||
caRootsCertificates: rootsCerts,
|
||||
subjectEmail: p.SubjectEmail,
|
||||
subjectHostname: p.SubjectHostname,
|
||||
}
|
||||
caIntermediateCertPEMs, err := loadBytesFromConfigSources(configBytesSources{
|
||||
inconsistencyErrorMessage: `Internal inconsistency: both "caIntermediatesPath" and "caIntermediatesData" specified`,
|
||||
path: p.CAIntermediatesPath,
|
||||
data: p.CAIntermediatesData,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if caIntermediateCertPEMs != nil {
|
||||
if len(caIntermediateCertPEMs) != 1 {
|
||||
return nil, errors.New(`Internal inconsistency: PKI specified with invalid value from "caIntermediatesPath" or "caIntermediatesData"`)
|
||||
}
|
||||
intermediatePool := x509.NewCertPool()
|
||||
trustedIntermediates, err := cryptoutils.UnmarshalCertificatesFromPEM(caIntermediateCertPEMs[0])
|
||||
if err != nil {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("loading trusted intermediate certificates: %v", err))
|
||||
}
|
||||
for _, trustedIntermediateCert := range trustedIntermediates {
|
||||
intermediatePool.AddCert(trustedIntermediateCert)
|
||||
}
|
||||
pki.caIntermediateCertificates = intermediatePool
|
||||
}
|
||||
|
||||
if err := pki.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pki, nil
|
||||
}
|
||||
|
||||
// sigstoreSignedTrustRoot contains an already parsed version of the prSigstoreSigned policy
|
||||
type sigstoreSignedTrustRoot struct {
|
||||
publicKeys []crypto.PublicKey
|
||||
fulcio *fulcioTrustRoot
|
||||
rekorPublicKeys []*ecdsa.PublicKey
|
||||
pki *pkiTrustRoot
|
||||
}
|
||||
|
||||
func (pr *prSigstoreSigned) prepareTrustRoot() (*sigstoreSignedTrustRoot, error) {
|
||||
|
|
@ -166,6 +219,14 @@ func (pr *prSigstoreSigned) prepareTrustRoot() (*sigstoreSignedTrustRoot, error)
|
|||
}
|
||||
}
|
||||
|
||||
if pr.PKI != nil {
|
||||
p, err := pr.PKI.prepareTrustRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.pki = p
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
|
|
@ -189,13 +250,23 @@ func (pr *prSigstoreSigned) isSignatureAccepted(ctx context.Context, image priva
|
|||
}
|
||||
untrustedPayload := sig.UntrustedPayload()
|
||||
|
||||
keySources := 0
|
||||
if trustRoot.publicKeys != nil {
|
||||
keySources++
|
||||
}
|
||||
if trustRoot.fulcio != nil {
|
||||
keySources++
|
||||
}
|
||||
if trustRoot.pki != nil {
|
||||
keySources++
|
||||
}
|
||||
|
||||
var publicKeys []crypto.PublicKey
|
||||
switch {
|
||||
case trustRoot.publicKeys != nil && trustRoot.fulcio != nil: // newPRSigstoreSigned rejects such combinations.
|
||||
return sarRejected, errors.New("Internal inconsistency: Both a public key and Fulcio CA specified")
|
||||
case trustRoot.publicKeys == nil && trustRoot.fulcio == nil: // newPRSigstoreSigned rejects such combinations.
|
||||
return sarRejected, errors.New("Internal inconsistency: Neither a public key nor a Fulcio CA specified")
|
||||
|
||||
case keySources > 1: // newPRSigstoreSigned rejects more than one key sources.
|
||||
return sarRejected, errors.New("Internal inconsistency: More than one of public key, Fulcio, or PKI specified")
|
||||
case keySources == 0: // newPRSigstoreSigned rejects empty key sources.
|
||||
return sarRejected, errors.New("Internal inconsistency: A public key, Fulcio, or PKI must be specified.")
|
||||
case trustRoot.publicKeys != nil:
|
||||
if trustRoot.rekorPublicKeys != nil {
|
||||
untrustedSET, ok := untrustedAnnotations[signature.SigstoreSETAnnotationKey]
|
||||
|
|
@ -254,6 +325,24 @@ func (pr *prSigstoreSigned) isSignatureAccepted(ctx context.Context, image priva
|
|||
return sarRejected, err
|
||||
}
|
||||
publicKeys = []crypto.PublicKey{pk}
|
||||
|
||||
case trustRoot.pki != nil:
|
||||
if trustRoot.rekorPublicKeys != nil { // newPRSigstoreSigned rejects such combinations.
|
||||
return sarRejected, errors.New("Internal inconsistency: PKI specified with a Rekor public key")
|
||||
}
|
||||
untrustedCert, ok := untrustedAnnotations[signature.SigstoreCertificateAnnotationKey]
|
||||
if !ok {
|
||||
return sarRejected, fmt.Errorf("missing %s annotation", signature.SigstoreCertificateAnnotationKey)
|
||||
}
|
||||
var untrustedIntermediateChainBytes []byte
|
||||
if untrustedIntermediateChain, ok := untrustedAnnotations[signature.SigstoreIntermediateCertificateChainAnnotationKey]; ok {
|
||||
untrustedIntermediateChainBytes = []byte(untrustedIntermediateChain)
|
||||
}
|
||||
pk, err := verifyPKI(trustRoot.pki, []byte(untrustedCert), untrustedIntermediateChainBytes)
|
||||
if err != nil {
|
||||
return sarRejected, err
|
||||
}
|
||||
publicKeys = []crypto.PublicKey{pk}
|
||||
}
|
||||
|
||||
if len(publicKeys) == 0 {
|
||||
|
|
|
|||
|
|
@ -111,16 +111,16 @@ type prSignedBaseLayer struct {
|
|||
type prSigstoreSigned struct {
|
||||
prCommon
|
||||
|
||||
// KeyPath is a pathname to a local file containing the trusted key. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas and Fulcio must be specified.
|
||||
// KeyPath is a pathname to a local file containing the trusted key. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas, Fulcio, and PKI must be specified.
|
||||
KeyPath string `json:"keyPath,omitempty"`
|
||||
// KeyPaths is a set of pathnames to local files containing the trusted key(s). Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas and Fulcio must be specified.
|
||||
// KeyPaths is a set of pathnames to local files containing the trusted key(s). Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas, Fulcio, and PKI must be specified.
|
||||
KeyPaths []string `json:"keyPaths,omitempty"`
|
||||
// KeyData contains the trusted key, base64-encoded. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas and Fulcio must be specified.
|
||||
// KeyData contains the trusted key, base64-encoded. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas, Fulcio, and PKI must be specified.
|
||||
KeyData []byte `json:"keyData,omitempty"`
|
||||
// KeyDatas is a set of trusted keys, base64-encoded. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas and Fulcio must be specified.
|
||||
// KeyDatas is a set of trusted keys, base64-encoded. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas, Fulcio, and PKI must be specified.
|
||||
KeyDatas [][]byte `json:"keyDatas,omitempty"`
|
||||
|
||||
// Fulcio specifies which Fulcio-generated certificates are accepted. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas and Fulcio must be specified.
|
||||
// Fulcio specifies which Fulcio-generated certificates are accepted. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas, Fulcio, and PKI must be specified.
|
||||
// If Fulcio is specified, one of RekorPublicKeyPath or RekorPublicKeyData must be specified as well.
|
||||
Fulcio PRSigstoreSignedFulcio `json:"fulcio,omitempty"`
|
||||
|
||||
|
|
@ -141,6 +141,9 @@ type prSigstoreSigned struct {
|
|||
// otherwise it is optional (and Rekor inclusion is not required if a Rekor public key is not specified).
|
||||
RekorPublicKeyDatas [][]byte `json:"rekorPublicKeyDatas,omitempty"`
|
||||
|
||||
// PKI specifies which PKI-generated certificates are accepted. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas, Fulcio, and PKI must be specified.
|
||||
PKI PRSigstoreSignedPKI `json:"pki,omitempty"`
|
||||
|
||||
// SignedIdentity specifies what image identity the signature must be claiming about the image.
|
||||
// Defaults to "matchRepoDigestOrExact" if not specified.
|
||||
// Note that /usr/bin/cosign interoperability might require using repo-only matching.
|
||||
|
|
@ -167,6 +170,30 @@ type prSigstoreSignedFulcio struct {
|
|||
SubjectEmail string `json:"subjectEmail,omitempty"`
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKI contains PKI configuration options for a "sigstoreSigned" PolicyRequirement.
|
||||
type PRSigstoreSignedPKI interface {
|
||||
// prepareTrustRoot creates a pkiTrustRoot from the input data.
|
||||
// (This also prevents external implementations of this interface, ensuring that prSigstoreSignedPKI is the only one.)
|
||||
prepareTrustRoot() (*pkiTrustRoot, error)
|
||||
}
|
||||
|
||||
// prSigstoreSignedPKI contains non-fulcio certificate PKI configuration options for prSigstoreSigned
|
||||
type prSigstoreSignedPKI struct {
|
||||
// CARootsPath a path to a file containing accepted CA root certificates, in PEM format. Exactly one of CARootsPath and CARootsData must be specified.
|
||||
CARootsPath string `json:"caRootsPath"`
|
||||
// CARootsData contains accepted CA root certificates in PEM format, all of that base64-encoded. Exactly one of CARootsPath and CARootsData must be specified.
|
||||
CARootsData []byte `json:"caRootsData"`
|
||||
// CAIntermediatesPath a path to a file containing accepted CA intermediate certificates, in PEM format. Only one of CAIntermediatesPath or CAIntermediatesData can be specified, not both.
|
||||
CAIntermediatesPath string `json:"caIntermediatesPath"`
|
||||
// CAIntermediatesData contains accepted CA intermediate certificates in PEM format, all of that base64-encoded. Only one of CAIntermediatesPath or CAIntermediatesData can be specified, not both.
|
||||
CAIntermediatesData []byte `json:"caIntermediatesData"`
|
||||
|
||||
// SubjectEmail specifies the expected email address imposed on the subject to which the certificate was issued. At least one of SubjectEmail and SubjectHostname must be specified.
|
||||
SubjectEmail string `json:"subjectEmail"`
|
||||
// SubjectHostname specifies the expected hostname imposed on the subject to which the certificate was issued. At least one of SubjectEmail and SubjectHostname must be specified.
|
||||
SubjectHostname string `json:"subjectHostname"`
|
||||
}
|
||||
|
||||
// PolicyReferenceMatch specifies a set of image identities accepted in PolicyRequirement.
|
||||
// The type is public, but its implementation is private.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const (
|
|||
// VersionMinor is for functionality in a backwards-compatible manner
|
||||
VersionMinor = 34
|
||||
// VersionPatch is for backwards-compatible bug fixes
|
||||
VersionPatch = 0
|
||||
VersionPatch = 1
|
||||
|
||||
// VersionDev indicates development branch. Releases will be empty string.
|
||||
VersionDev = ""
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ github.com/containernetworking/cni/pkg/version
|
|||
# github.com/containernetworking/plugins v1.5.1
|
||||
## explicit; go 1.20
|
||||
github.com/containernetworking/plugins/pkg/ns
|
||||
# github.com/containers/buildah v1.39.0
|
||||
# github.com/containers/buildah v1.39.2
|
||||
## explicit; go 1.22.8
|
||||
github.com/containers/buildah
|
||||
github.com/containers/buildah/bind
|
||||
|
|
@ -179,7 +179,7 @@ github.com/containers/buildah/pkg/sshagent
|
|||
github.com/containers/buildah/pkg/util
|
||||
github.com/containers/buildah/pkg/volumes
|
||||
github.com/containers/buildah/util
|
||||
# github.com/containers/common v0.62.0
|
||||
# github.com/containers/common v0.62.1
|
||||
## explicit; go 1.22.8
|
||||
github.com/containers/common/internal
|
||||
github.com/containers/common/internal/attributedstring
|
||||
|
|
@ -252,7 +252,7 @@ github.com/containers/conmon/runner/config
|
|||
# github.com/containers/gvisor-tap-vsock v0.8.3
|
||||
## explicit; go 1.22.0
|
||||
github.com/containers/gvisor-tap-vsock/pkg/types
|
||||
# github.com/containers/image/v5 v5.34.0
|
||||
# github.com/containers/image/v5 v5.34.1
|
||||
## explicit; go 1.22.8
|
||||
github.com/containers/image/v5/copy
|
||||
github.com/containers/image/v5/directory
|
||||
|
|
|
|||
Loading…
Reference in New Issue