Merge pull request #25521 from mheon/541_backports

Backports for v5.4.1
This commit is contained in:
openshift-merge-bot[bot] 2025-03-11 10:10:31 +00:00 committed by GitHub
commit 771d7a8d2c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 1090 additions and 67 deletions

View File

@ -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!

View File

@ -339,16 +339,18 @@ func copyToContainer(container string, containerPath string, hostPath string) er
return err
}
hostInfo := &copy.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)

View File

@ -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

View File

@ -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

View File

@ -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
View File

@ -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
View File

@ -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=

View File

@ -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
}

View File

@ -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,

View File

@ -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

View File

@ -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) {

View File

@ -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))

View File

@ -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'

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -1,4 +1,4 @@
package version
// Version is the version of the build.
const Version = "0.62.0"
const Version = "0.62.1"

View File

@ -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) {

View File

@ -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
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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.

View File

@ -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 = ""

6
vendor/modules.txt vendored
View File

@ -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