├── .cirrus.yml ├── .github ├── renovate.json5 └── workflows │ ├── check_cirrus_cron.yml │ └── rerun_cirrus_cron.yml ├── CODE-OF-CONDUCT.md ├── LICENSE ├── OWNERS ├── README.md ├── SECURITY.md ├── aio ├── Containerfile ├── README.md ├── containers.conf ├── test.sh └── user-containers.conf ├── buildah ├── Containerfile ├── README.md └── containers.conf ├── ci ├── Containerfile ├── README.md ├── aio_build_push.sh ├── containers_build_push.sh ├── shellcheck.sh ├── tag_version.sh ├── test.sh └── validate.sh ├── podman ├── Containerfile ├── README.md ├── containers.conf └── podman-containers.conf └── skopeo ├── Containerfile └── README.md /.cirrus.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # Main collection of env. vars to set for all tasks and scripts. 4 | env: 5 | # Shell used to execute all script commands 6 | CIRRUS_SHELL: "/bin/bash" 7 | # No need to go crazy, but grab enough to cover most PRs 8 | CIRRUS_CLONE_DEPTH: 10 9 | IMAGE_SUFFIX: "c20250422t130822z-f42f41d13" 10 | 11 | gcp_credentials: ENCRYPTED[88b219cf6b4f2d70c4ff7f8c6c3186396102e14a27b47b985e40a0a0bc5337a270f9eee195b36ff6b3e2f07558998a95] 12 | 13 | validate_task: 14 | name: "Validate" 15 | alias: "validate" 16 | only_if: &is_pr $CIRRUS_PR != '' 17 | timeout_in: 5m 18 | container: &ci_container 19 | # Ref: https://cirrus-ci.org/guide/docker-builder-vm/#dockerfile-as-a-ci-environment 20 | dockerfile: "ci/Containerfile" 21 | cpu: 1 22 | memory: 1 23 | script: 24 | - "ci/shellcheck.sh" 25 | - "ci/validate.sh" 26 | 27 | test_build-push_task: 28 | name: "Test build-push scripts function" 29 | alias: test_build-push 30 | only_if: *is_pr 31 | # No need to test if changes don't include ... 32 | skip: "!changesInclude('.cirrus.yml', 'build-push/**/*')" 33 | depends_on: 34 | - validate 35 | gce_instance: &build_push_test_vm 36 | image_project: "libpod-218412" 37 | image_name: 'build-push-${IMAGE_SUFFIX}' 38 | zone: "us-central1-a" 39 | disk: 200 40 | script: | 41 | ./ci/test.sh 42 | 43 | test_image_build_task: 44 | alias: test_image_build 45 | name: Test build ${CTX_SUB}/${FLAVOR_NAME} image 46 | only_if: *is_pr 47 | depends_on: 48 | - test_build-push 49 | gce_instance: &build_push 50 | <<: *build_push_test_vm 51 | type: "t2d-standard-4" # Extra muscle needed for multi-arch emulation 52 | env: 53 | ARCHES: amd64 54 | DRYRUN: 1 # Don't actually push anything, only build. 55 | A_DEBUG: 1 56 | EXPORT_FILENAME: quay_io-${CTX_SUB}-${FLAVOR_NAME}-latest 57 | matrix: &pbs_matrix 58 | - env: 59 | FLAVOR_NAME: upstream 60 | matrix: &pbs_images 61 | - env: 62 | CTX_SUB: podman 63 | # N/B: The following skip conditions also apply to the 64 | # cron_image_build task via the pbs_images alias. Build 65 | # skipping is desirable only for PRs, never for Cirrus-cron. 66 | skip: | 67 | $CIRRUS_PR != '' && 68 | !changesInclude('.cirrus.yml', 69 | 'ci/containers_build_push.sh', 'ci/tag_version.sh', 70 | 'podman/*') 71 | - env: 72 | CTX_SUB: buildah 73 | skip: | 74 | $CIRRUS_PR != '' && 75 | !changesInclude('.cirrus.yml', 76 | 'ci/containers_build_push.sh', 'ci/tag_version.sh', 77 | 'buildah/*') 78 | - env: 79 | CTX_SUB: skopeo 80 | skip: | 81 | $CIRRUS_PR != '' && 82 | !changesInclude('.cirrus.yml', 83 | 'ci/containers_build_push.sh', 'ci/tag_version.sh', 84 | 'skopeo/*') 85 | - env: 86 | FLAVOR_NAME: testing 87 | matrix: *pbs_images 88 | - env: 89 | FLAVOR_NAME: stable 90 | matrix: *pbs_images 91 | build_script: &pbs_script | 92 | source /etc/automation_environment 93 | ./ci/containers_build_push.sh ${CIRRUS_REPO_CLONE_URL} ${CTX_SUB} ${FLAVOR_NAME} 94 | export_script: | 95 | podman save --multi-image-archive --output ./${EXPORT_FILENAME}.tar quay.io/${CTX_SUB}/${FLAVOR_NAME}:latest 96 | image_export_artifacts: 97 | path: ./${EXPORT_FILENAME}.tar 98 | type: application/octet-stream 99 | 100 | cron_image_build_task: 101 | alias: cron_image_build 102 | name: Build ${CTX_SUB}/${FLAVOR_NAME} image 103 | only_if: $CIRRUS_CRON == 'cron_image_build_task' 104 | gce_instance: *build_push 105 | env: 106 | CONTAINERS_USERNAME: &cntu ENCRYPTED[f94aa9610f678dc79ca45d49ee4c41a43da9468094883eb386ea907f6218cd49df61f892105109da8b5309523db3ed0b] 107 | CONTAINERS_PASSWORD: &cntp ENCRYPTED[84a2784130e2c359afa70ad0575b04f448d248ca947d130d3450eb01676e7f934b6de621a167edf56cd4901396dfe7e2] 108 | PODMAN_USERNAME: ENCRYPTED[c7c6506427eeecce7c709a94fb7547987545cb4ba7e607e249444b3588a41069ad116781f3187018c12c6fff0fd425d7] 109 | PODMAN_PASSWORD: ENCRYPTED[f7c321e7dfb017e4111e0fc3c0f7eb2e743d11f4eddca5cf209c2f25e2c778eb33ab746b6ef91233e570ac3d547a86f0] 110 | BUILDAH_USERNAME: ENCRYPTED[58742c385f0938a25cd523837bee50bf40db7c2523dc4506b9a1c3d72233e828ad9527ca638c18eb825d2ceef6d5b31d] 111 | BUILDAH_PASSWORD: ENCRYPTED[3d400b0547ef4d56c54dbf05e2ecdc0a1d5b2a3013f194b3e090bed6b1ab67fafbef6dca06cbb2b889b88f894143d40a] 112 | SKOPEO_USERNAME: ENCRYPTED[7290f519ec778c3f21353c0279f55ff6e2a59d9fd9b816db8f0a0549f2ea22efc297feb9f7422a6b9f2a6c22f30e1027] 113 | SKOPEO_PASSWORD: ENCRYPTED[ad43d3aefef388b22c2e0c837678ff3754994563dbe9574717e7aa68a847e64401b501c882d733149d7896a1d617f806] 114 | matrix: *pbs_matrix 115 | script: *pbs_script 116 | 117 | test_aio_image_build_task: 118 | alias: test_aio_image_build 119 | name: "Test build AIO image" 120 | only_if: *is_pr 121 | skip: "!changesInclude('.cirrus.yml', 'ci/aio_build_push.sh', 'ci/tag_version.sh', 'aio/**/*')" 122 | depends_on: 123 | - test_build-push 124 | gce_instance: *build_push 125 | env: 126 | ARCHES: amd64 127 | DRYRUN: 1 # Don't actually push anything, only build. 128 | A_DEBUG: 1 129 | EXPORT_FILENAME: quay_io-containers-aio-latest 130 | build_script: &aio_script | 131 | source /etc/automation_environment 132 | ./ci/aio_build_push.sh ${CIRRUS_REPO_CLONE_URL} 133 | export_script: | 134 | podman save --multi-image-archive --output ./${EXPORT_FILENAME}.tar quay.io/containers/aio:latest 135 | image_export_artifacts: 136 | path: ./${EXPORT_FILENAME}.tar 137 | type: application/octet-stream 138 | test_script: ./aio/test.sh 139 | 140 | cron_aio_build_task: 141 | alias: cron_aio_build 142 | name: "Build AIO image" 143 | only_if: $CIRRUS_CRON == 'cron_aio_build_task' 144 | gce_instance: *build_push 145 | env: 146 | CONTAINERS_USERNAME: *cntu 147 | CONTAINERS_PASSWORD: *cntp 148 | build_script: *aio_script 149 | 150 | # This task is critical. It updates the "last-used by" timestamp stored 151 | # in metadata for all VM images. This mechanism functions in tandem with 152 | # an out-of-band pruning operation to remove disused VM images. 153 | meta_task: 154 | name: "VM img. keepalive" 155 | alias: meta 156 | container: 157 | cpu: 1 158 | memory: 1 159 | image: quay.io/libpod/imgts:latest 160 | env: 161 | # Space-separated list of images used by this repository state 162 | IMGNAMES: build-push-${IMAGE_SUFFIX} 163 | BUILDID: "${CIRRUS_BUILD_ID}" 164 | REPOREF: "${CIRRUS_REPO_NAME}" 165 | GCPJSON: ENCRYPTED[3d93b3b386062c8f0f512237bc18d32f0cff1813076260492670ddcadd5fdb525269a0511c02f6bce5327848b7f1faf2] 166 | GCPNAME: ENCRYPTED[132257954e3b64ecabf71d7d45ee9225d64695febb70a73857850826016ff7a21837ac178e39e4e729c93b65352f54ae] 167 | GCPPROJECT: libpod-218412 168 | clone_script: /bin/true 169 | script: /usr/local/bin/entrypoint.sh 170 | 171 | success_task: 172 | alias: success 173 | name: Total Success 174 | only_if: *is_pr 175 | depends_on: 176 | - validate 177 | - test_build-push 178 | - test_image_build 179 | - test_aio_image_build 180 | - meta 181 | container: 182 | <<: *ci_container 183 | clone_script: /bin/true 184 | script: /bin/true 185 | -------------------------------------------------------------------------------- /.github/renovate.json5: -------------------------------------------------------------------------------- 1 | /* 2 | Renovate is a service similar to GitHub Dependabot, but with 3 | (fantastically) more configuration options. So many options 4 | in fact, if you're new I recommend glossing over this cheat-sheet 5 | prior to the official documentation: 6 | 7 | https://www.augmentedmind.de/2021/07/25/renovate-bot-cheat-sheet 8 | 9 | Configuration Update/Change Procedure: 10 | 1. Make changes 11 | 2. Manually validate changes (from repo-root): 12 | 13 | podman run -it \ 14 | -v ./.github/renovate.json5:/usr/src/app/renovate.json5:z \ 15 | docker.io/renovate/renovate:latest \ 16 | renovate-config-validator 17 | 3. Commit. 18 | 19 | Configuration Reference: 20 | https://docs.renovatebot.com/configuration-options/ 21 | 22 | Monitoring Dashboard: 23 | https://app.renovatebot.com/dashboard#github/containers 24 | 25 | Note: The Renovate bot will create/manage it's business on 26 | branches named 'renovate/*'. Otherwise, and by 27 | default, the only the copy of this file that matters 28 | is the one on the `main` branch. No other branches 29 | will be monitored or touched in any way. 30 | */ 31 | 32 | { 33 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 34 | 35 | /************************************************* 36 | ****** Global/general configuration options ***** 37 | *************************************************/ 38 | 39 | // Re-use predefined sets of configuration options to DRY 40 | "extends": [ 41 | // https://github.com/containers/automation/blob/main/renovate/defaults.json5 42 | "github>containers/automation//renovate/defaults.json5" 43 | ], 44 | 45 | // Permit automatic rebasing when base-branch changes by more than 46 | // one commit. 47 | "rebaseWhen": "behind-base-branch", 48 | 49 | /************************************************* 50 | *** Repository-specific configuration options *** 51 | *************************************************/ 52 | 53 | "ignorePaths": [ 54 | "**/ci/**" 55 | ], 56 | 57 | } 58 | -------------------------------------------------------------------------------- /.github/workflows/check_cirrus_cron.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | on: 4 | # Note: This only applies to the default branch. 5 | schedule: 6 | # N/B: This should correspond to a period slightly after 7 | # the last job finishes running. See job defs. at: 8 | # https://cirrus-ci.com/settings/repository/5678990556397568 9 | - cron: '03 03 * * 1-5' 10 | # Debug: Allow triggering job manually in github-actions WebUI 11 | workflow_dispatch: {} 12 | 13 | jobs: 14 | # Ref: https://docs.github.com/en/actions/using-workflows/reusing-workflows 15 | call_cron_failures: 16 | uses: containers/podman/.github/workflows/check_cirrus_cron.yml@main 17 | secrets: inherit 18 | -------------------------------------------------------------------------------- /.github/workflows/rerun_cirrus_cron.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # See also: https://github.com/containers/podman/blob/main/.github/workflows/rerun_cirrus_cron.yml 4 | 5 | on: 6 | # Note: This only applies to the default branch. 7 | schedule: 8 | # N/B: This should correspond to a period slightly after 9 | # the last job finishes running. See job defs. at: 10 | # https://cirrus-ci.com/settings/repository/5678990556397568 11 | - cron: '01 01 * * 1-5' 12 | # Debug: Allow triggering job manually in github-actions WebUI 13 | workflow_dispatch: {} 14 | 15 | jobs: 16 | # Ref: https://docs.github.com/en/actions/using-workflows/reusing-workflows 17 | call_cron_rerun: 18 | uses: containers/podman/.github/workflows/rerun_cirrus_cron.yml@main 19 | secrets: inherit 20 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Monorepo menagerie of images build automation project Code of Conduct 2 | 3 | Monorepo menagerie of images build automation project follows the 4 | [Containers Community Code of Conduct](https://github.com/containers/common/blob/main/CODE-OF-CONDUCT.md). 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | https://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | https://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - TomSweeneyRedHat 3 | - baude 4 | - cevich 5 | - edsantiago 6 | - lsm5 7 | - mheon 8 | - rhatdan 9 | reviewers: 10 | - TomSweeneyRedHat 11 | - baude 12 | - cevich 13 | - edsantiago 14 | - lsm5 15 | - mheon 16 | - rhatdan 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Image Build 2 | 3 | Monorepo menagerie of container images and associated build automation 4 | 5 | ## Podman / Buildah / Skopeo 6 | 7 | ## Overview 8 | 9 | The latest version of these docs may be obtained from [the upstream 10 | repo.](https://github.com/containers/image_build/blob/main/README.md) 11 | 12 | These directories contain the Containerfiles necessary to create the images housed on 13 | quay.io under their namespace in addition to the 'containers' namespace. These 14 | images are public and can be pulled without credentials. These container images are secured and the 15 | resulting containers can run safely with or without privileges. 16 | 17 | The container images are built using the latest Fedora and then the respective tools are installed. 18 | The `$PATH` in the container images is set to the default provided by Fedora. Neither the 19 | `$ENTRYPOINT` nor the `$WORKDIR` variables are set within these container images, and as 20 | such they default to `/`. 21 | 22 | The container images are tagged as follows, where `*` represents either `podman`, `buildah` 23 | or `skopeo`: 24 | 25 | * `quay.io/containers/*:` and `quay.io/*/stable:` - 26 | These images are built daily. They are intended to contain the latest stable 27 | versions of their respective container tool. For the most recent `` tags (`vX`, 28 | `vX.Y`, and `vX.Y.Z`) the image contents will be updated daily to incorporate 29 | (especially) security updates. 30 | * `quay.io/containers/*:-immutable` - Uses the same source as the 'stable' 31 | images, built daily, but version-tags are never overwritten once pushed. Tags 32 | will only be removed in case of an extreme security problem. Otherwise, these 33 | images are intended for users that value an unchanging image tag and digest over 34 | daily security updates. All three `` values are available, `vX-immutable`, 35 | `vX.Y-immutable` and `vX.Y.Z-immutable`. 36 | * `quay.io/containers/*:latest` and `quay.io/*/stable:latest` - 37 | Built daily using the same `Containerfile` as above. The tool versions 38 | will remain the "latest" available in Fedora. 39 | * `quay.io/containers/aio:latest` and `quay.io/containers/aio:` - 40 | "All In One" image containing Podman, Buildah, and Skopeo. Built weekly 41 | using a similar `Containerfile` as the Podman and Buildah images. It's a 42 | smaller, minimal image, intended to be used as a base-image for development 43 | containers or CI/automation. 44 | * `quay.io/*/testing:latest` - This image is built daily, using the 45 | latest tooling version available in the Fedora `updates-testing` repository. 46 | * `quay.io/*/upstream:latest` - This image is built daily using the latest 47 | code found on the main branch of the respective upstream repository. Due to the 48 | image changing frequently, it's not guaranteed to be stable or even executable. 49 | Note: The actual tool compilation [occurs continuously in 50 | COPR](https://copr.fedorainfracloud.org/coprs/rhcontainerbot/podman-next/). 51 | 52 | ## Podman Sample Usage 53 | 54 | [Please see the subdirectory README.md](https://github.com/containers/image_build/blob/main/podman/README.md) 55 | 56 | ## Buildah Sample Usage 57 | 58 | [Please see the subdirectory README.md](https://github.com/containers/image_build/blob/main/buildah/README.md) 59 | 60 | ## Skopeo Sample Usage 61 | 62 | [Please see the subdirectory README.md](https://github.com/containers/image_build/blob/main/skopeo/README.md) 63 | 64 | ## All In One Sample Usage 65 | 66 | [Please see the subdirectory README.md](https://github.com/containers/image_build/blob/main/aio/README.md) 67 | 68 | ## Automation 69 | 70 | **Warning**: It's easily possible this section is out of date or hasn't been updated. 71 | 72 | The exact details of all build automation in every context is best obtained directly from 73 | [`.cirrus.yml`](https://github.com/containers/image_build/blob/main/.cirrus.yml) and 74 | any workflows defined under 75 | [`.github/workflows`](https://github.com/containers/image_build/tree/main/.github/workflows). 76 | What follows is simply a general overview. 77 | 78 | ### Tooling 79 | 80 | The heart of all builds is the `containers/automation` repo [build-push.sh script](https://github.com/containers/automation/tree/main/build-push). 81 | Put simply it does exactly what its name suggests; however, it also has some additional useful features: 82 | 83 | * The script always produces manifest-list (i.e. multiple "images" all packed under a single name). Unless overridden, 84 | the build will run in parallel for the `amd64`, `arm64`, `ppc64le`, and `s390x` architectures. For this to work, the 85 | qemu-user-static package (or [container](https://github.com/multiarch/qemu-user-static)) is required to be installed 86 | and loaded into the kernel. For the automated builds, this is already available and setup in the VM image. 87 | * Before and after building, `build-push.sh` is able to execute additional commands/scripts. These are very 88 | useful for 89 | [preparing the context](https://github.com/containers/automation/tree/main/build-push#use-in-automation-with-additional-preparation) 90 | and/or 91 | [modifying image output and/or tags](https://github.com/containers/automation/tree/main/build-push#use-in-automation-with-modified-images). 92 | Otherwise the script only/ever builds a `latest` tag. At the end, the script will search for and push _any_ 93 | (could be zero) command-line named images regardless of tag. 94 | * After building, the script will inspect the output of _existing_ named images to ensure it contains manifests for all 95 | specified architectures. This is needed to ensure the output represents the input parameters, in case the post-build 96 | modification script 97 | mangled something. 98 | * If [a pair of magic envars are set](https://github.com/containers/automation/tree/main/build-push#use-in-build-automation) 99 | the script will pushes all images matching the name given on the command-line (i.e. the base image-name w/o a tag). 100 | **Great care is required w/in the CI/automation setup to ensure these envar values cannot leak.** 101 | 102 | ### Automation runtime 103 | 104 | The [containers/automation_images](https://github.com/containers/automation_images) repo produces a VM image 105 | dedicated for use by automation in this repo. Specifically, the VM is setup 106 | [using a simple script](https://github.com/containers/automation_images/blob/main/cache_images/build-push_packaging.sh) 107 | to make sure all the required packages are installed, along with the common automation library and 108 | [the build-push.sh script](https://github.com/containers/automation/tree/main/build-push). Note that it always installs 109 | the latest library and script, so any related problems can be quickly fixed with a CI VM image rebuild. 110 | 111 | ### Automation scripts 112 | 113 | All the top-level build scripts used by automation in this repo, for all contexts, resides under the `ci` subdirectory. These are tailored for each type of build since some (i.e. Podman, Buildah, and Skopeo) are pushed to multiple registry namespaces. However in all cases, these scripts ultimately end up simply calling 114 | [the build-push.sh script](https://github.com/containers/automation/tree/main/build-push). 115 | 116 | ### Image Labels and Annotations 117 | 118 | All build scripts (under the `ci` subdirectory) add labels (and annotation) prefixed with `built.by`. These can be 119 | extremely helpful for auditing purposes after-the-fact. For example if a pushed image has something wrong with it, 120 | the build log URL (`built.by.logs`) are available for some time. Or, if there's any question of what version of 121 | build script was used, these details are available in `built.by.commit` (git commit) `built.by.exec` (script) 122 | and `built.by.digest` (script hash). 123 | 124 | **Note:** Both labels and annotations are set simply due to script logic convenience and to meet 125 | future and 126 | [past OCI recommendations](https://specs.opencontainers.org/image-spec/annotations/#back-compatibility-with-label-schema). 127 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Security and Disclosure Information Policy for Monorepo menagerie of images build automation project 2 | 3 | Monorepo menagerie of images build automation Project follows the 4 | [Security and Disclosure Information Policy](https://github.com/containers/common/blob/main/SECURITY.md) 5 | for the Containers Projects. 6 | -------------------------------------------------------------------------------- /aio/Containerfile: -------------------------------------------------------------------------------- 1 | # aio/Containerfile 2 | # 3 | # Build an all in one Podman, Buildah, Skopeo container 4 | # image from the latest stable version of Podman on the 5 | # Fedoras Updates System. 6 | # https://bodhi.fedoraproject.org/updates/?search=podman 7 | # https://bodhi.fedoraproject.org/updates/?search=buildah 8 | # https://bodhi.fedoraproject.org/updates/?search=skopeo 9 | # This image is intended to be used as-is, or as a base- 10 | # image for development work or use in CI/CD systems. 11 | 12 | FROM registry.fedoraproject.org/fedora-minimal:latest 13 | 14 | # When building for multiple-architectures in parallel using emulation 15 | # it's really easy for one/more dnf processes to timeout or mis-count 16 | # the minimum download rates. Bump both to be extremely forgiving of 17 | # an overworked host. 18 | RUN echo -e "\n\n# Added during image build" >> /etc/dnf/dnf.conf && \ 19 | echo -e "minrate=100\ntimeout=60\n" >> /etc/dnf/dnf.conf 20 | 21 | RUN microdnf -y makecache && \ 22 | microdnf -y update && \ 23 | microdnf -y install podman buildah skopeo fuse-overlayfs openssh-clients \ 24 | --exclude "container-selinux,qemu-*" && \ 25 | rpm --setcaps shadow-utils 2>/dev/null && \ 26 | microdnf clean all && \ 27 | rm -rf /var/cache /var/log/dnf* /var/log/yum.* 28 | 29 | # It's assumed `user` will end up with UID/GID 1000 30 | RUN useradd user && \ 31 | echo -e "user:1:999\nuser:1001:64535" > /etc/subuid && \ 32 | echo -e "user:1:999\nuser:1001:64535" > /etc/subgid 33 | 34 | ADD /containers.conf /etc/containers/containers.conf 35 | ADD /user-containers.conf /home/user/.config/containers/containers.conf 36 | 37 | RUN mkdir -p /home/user/.local/share/containers && \ 38 | mkdir -p /home/user/.config/containers && \ 39 | chown user:user -R /home/user && \ 40 | chmod 644 /etc/containers/containers.conf 41 | 42 | # Copy & modify the defaults to provide reference if runtime changes needed. 43 | # Changes here are required for running with fuse-overlay storage inside container. 44 | RUN sed -e 's|^#mount_program|mount_program|g' \ 45 | -e '/additionalimage.*/a "/var/lib/shared",' \ 46 | -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \ 47 | /usr/share/containers/storage.conf \ 48 | > /etc/containers/storage.conf 49 | 50 | # Setup internal Podman to pass subscriptions down from host to internal container 51 | RUN printf '/run/secrets/etc-pki-entitlement:/run/secrets/etc-pki-entitlement\n/run/secrets/rhsm:/run/secrets/rhsm\n' > /etc/containers/mounts.conf 52 | 53 | # Note VOLUME options must always happen after the chown call above 54 | # RUN commands can not modify existing volumes 55 | VOLUME /var/lib/containers 56 | VOLUME /home/user/.local/share/containers 57 | 58 | RUN mkdir -p /var/lib/shared/overlay-images \ 59 | /var/lib/shared/overlay-layers \ 60 | /var/lib/shared/vfs-images \ 61 | /var/lib/shared/vfs-layers && \ 62 | touch /var/lib/shared/overlay-images/images.lock && \ 63 | touch /var/lib/shared/overlay-layers/layers.lock && \ 64 | touch /var/lib/shared/vfs-images/images.lock && \ 65 | touch /var/lib/shared/vfs-layers/layers.lock 66 | 67 | ENV _CONTAINERS_USERNS_CONFIGURED="" \ 68 | BUILDAH_ISOLATION=chroot 69 | -------------------------------------------------------------------------------- /aio/README.md: -------------------------------------------------------------------------------- 1 | [comment]: <> (***ATTENTION*** ***WARNING*** ***ALERT*** ***CAUTION*** ***DANGER***) 2 | [comment]: <> () 3 | [comment]: <> (ANY changes made below, once committed/merged must) 4 | [comment]: <> (be manually copy/pasted -in markdown- into the description) 5 | [comment]: <> (field on Quay at the following locations:) 6 | [comment]: <> () 7 | [comment]: <> (https://quay.io/repository/containers/aio) 8 | [comment]: <> () 9 | [comment]: <> (***ATTENTION*** ***WARNING*** ***ALERT*** ***CAUTION*** ***DANGER***) 10 | 11 | ![PODMAN logo](https://raw.githubusercontent.com/containers/common/main/logos/podman-logo-full-vert.png) 12 | ![buildah logo](https://cdn.rawgit.com/containers/buildah/main/logos/buildah-logo_large.png) 13 | 14 | 15 | # All In One: Podman, Buildah and Skopeo Image 16 | 17 | ## Build information 18 | 19 | Please see the [containers/image_build repo. README.md for build 20 | details](https://github.com/containers/image_build/blob/main/README.md). 21 | 22 | ## Sample Usage 23 | 24 | Running as 'root' inside the container: 25 | 26 | ``` 27 | # Create a directory on the host to mount the container's 28 | # /var/lib/container directory to so containers can be 29 | # run within the container. 30 | mkdir /var/lib/mycontainers 31 | 32 | # Run a shell in the container, will full nested container run and build 33 | # possibilities: 34 | podman run -it --net=host --security-opt label=disable --privileged \ 35 | --security-opt seccomp=unconfined --device /dev/fuse:rw \ 36 | -v /var/lib/mycontainers:/var/lib/containers:Z \ 37 | quay.io/containers/aio:latest 38 | ``` 39 | 40 | Running rootless inside the container: 41 | ``` 42 | mkdir $HOME/mycontainers 43 | 44 | # Run a shell in the container, will full nested container run and build 45 | # possibilities: 46 | podman run -it --net=host --security-opt label=disable --privileged \ 47 | --security-opt seccomp=unconfined --device /dev/fuse:rw \ 48 | --user user --userns=keep-id:uid=1000,gid=1000 \ 49 | -v $HOME/mycontainers:/home/user/.local/share/containers:Z \ 50 | quay.io/containers/aio:latest 51 | ``` 52 | 53 | **Note:** If you encounter a `fuse: device not found` error when running the container image, it is likely that 54 | the fuse kernel module has not been loaded on your host system. Use the command `modprobe fuse` to load the 55 | module and then run the container image. To enable this automatically at boot time, you can add a configuration 56 | file to `/etc/modules.load.d`. See `man modules-load.d` for more details. 57 | -------------------------------------------------------------------------------- /aio/containers.conf: -------------------------------------------------------------------------------- 1 | [containers] 2 | netns="host" 3 | userns="host" 4 | ipcns="host" 5 | utsns="host" 6 | cgroupns="host" 7 | cgroups="disabled" 8 | log_driver = "k8s-file" 9 | 10 | [engine] 11 | cgroup_manager = "cgroupfs" 12 | events_logger="file" 13 | runtime="crun" 14 | -------------------------------------------------------------------------------- /aio/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is not intended for humans. It's meant to be run 4 | # by a CI system after a test-build of the 5 | # quay.io/containers/aio:latest manifest list. 6 | 7 | set -eo pipefail 8 | 9 | if [[ -r "/etc/automation_environment" ]]; then 10 | source /etc/automation_environment # defines AUTOMATION_LIB_PATH 11 | #shellcheck disable=SC1090,SC2154 12 | source "$AUTOMATION_LIB_PATH/common_lib.sh" 13 | dbg "Using automation common library version $(<$AUTOMATION_LIB_PATH/../AUTOMATION_VERSION)" 14 | else 15 | echo "Expecting to find automation common library installed." 16 | exit 1 17 | fi 18 | 19 | FQIN="quay.io/containers/aio:latest" 20 | FQIN_FILE="$(basename $FQIN | tr ':' '-').tar" 21 | 22 | # msg() doesn't support a prefix, nor show file/line-no. 23 | # Abuse warn() to print testing messages and make them stand-out. 24 | WARNING_MSG_PREFIX="***** TEST:" 25 | msg() { warn "$1"; } 26 | 27 | # These tests need to be run rootless, assume the environment is disposable. 28 | # N/B: This condition does not return! 29 | if [[ "$UID" -eq 0 ]]; then 30 | msg "Check that $FQIN exists in local storage" 31 | showrun podman manifest exists $FQIN 32 | 33 | msg "Verify manifest-list contains image for amd64 architecture" 34 | arches=$(showrun podman manifest inspect $FQIN | showrun jq -r -e '.manifests[].platform.architecture') 35 | showrun grep -F -x -q 'amd64' <<<"$arches" 36 | 37 | msg "Verify skopeo can inspect the local manifest list" 38 | showrun skopeo inspect --raw containers-storage:$FQIN | jq . 39 | 40 | msg "Setting up for rootless testing" 41 | TESTUSER="testuser$RANDOM" 42 | showrun useradd "$TESTUSER" 43 | export TUHOME="/home/$TESTUSER" 44 | showrun podman save -o "$TUHOME/$FQIN_FILE" "$FQIN" 45 | showrun chown $TESTUSER:$TESTUSER "$TUHOME/$FQIN_FILE" 46 | (umask 077; showrun mkdir -p "/root/.ssh") 47 | (umask 077; showrun ssh-keyscan localhost >> "/root/.ssh/known_hosts") 48 | showrun ssh-keygen -t rsa -P "" -f "/root/.ssh/id_rsa" 49 | (umask 077; showrun mkdir -p "$TUHOME/.ssh") 50 | showrun cp "/root/.ssh/id_rsa.pub" "$TUHOME/.ssh/authorized_keys" 51 | showrun chown -R $TESTUSER:$TESTUSER "$TUHOME/.ssh" 52 | showrun chmod 0600 "$TUHOME/.ssh/authorized_keys" 53 | # $SCRIPT_PATH/$SCRIPT_FILENAME defined by automation library 54 | # shellcheck disable=SC2154 55 | showrun exec ssh $TESTUSER@localhost $SCRIPT_PATH/$SCRIPT_FILENAME 56 | fi 57 | 58 | # SCRIPT_FILENAME defined by automation library 59 | # shellcheck disable=SC2154 60 | TMPD=$(mktemp -p '' -d ${SCRIPT_FILENAME}_XXXXX_tmp) 61 | trap "podman unshare rm -rf '$TMPD'" EXIT 62 | 63 | msg "Loading test image" 64 | showrun podman load -i $HOME/$FQIN_FILE 65 | 66 | # These tests come directly from the aio/README.md examples 67 | mkdir $TMPD/cntr_storage 68 | mkdir $TMPD/context 69 | echo -e 'FROM registry.fedoraproject.org/fedora-minimal:latest\nENV TESTING=true' > $TMPD/context/Containerfile 70 | for tool in buildah podman; do 71 | msg "Verify $tool can create a simple image as root inside $FQIN" 72 | showrun podman unshare rm -rf $TMPD/cntr_storage/* $TMPD/cntr_storage/.??* 73 | showrun podman run -i --rm --net=host --security-opt label=disable --privileged \ 74 | --security-opt seccomp=unconfined --device /dev/fuse:rw \ 75 | -v $TMPD/cntr_storage:/var/lib/containers:Z \ 76 | -v $TMPD/context:/root/context:Z \ 77 | $FQIN $tool build -t root_testimage /root/context 78 | 79 | msg "Verify $tool can create a simple image as rootless inside $FQIN" 80 | showrun podman unshare rm -rf $TMPD/cntr_storage/* $TMPD/cntr_storage/.??* 81 | showrun podman run -i --rm --net=host --security-opt label=disable --privileged \ 82 | --security-opt seccomp=unconfined --device /dev/fuse:rw \ 83 | --user user --userns=keep-id:uid=1000,gid=1000 \ 84 | -v $TMPD/cntr_storage:/home/user/.local/share/containers:Z \ 85 | -v $TMPD/context:/home/user/context:Z \ 86 | $FQIN $tool build -t rootless_testimage /home/user/context 87 | done 88 | -------------------------------------------------------------------------------- /aio/user-containers.conf: -------------------------------------------------------------------------------- 1 | [containers] 2 | volumes = [ 3 | "/proc:/proc", 4 | ] 5 | default_sysctls = [] 6 | -------------------------------------------------------------------------------- /buildah/Containerfile: -------------------------------------------------------------------------------- 1 | # buildah/Containerfile 2 | # 3 | # Build a Buildah container image from the latest version 4 | # of Fedora. 5 | # 6 | # FLAVOR defaults to stable if unset 7 | # 8 | # FLAVOR=stable acquires a stable version of Buildah 9 | # from the Fedoras Updates System. 10 | # FLAVOR=testing acquires a testing version of Buildah 11 | # from the Fedoras Updates System. 12 | # FLAVOR=upstream acquires a testing version of Buildah 13 | # from the Fedora Copr Buildsystem. 14 | # https://copr.fedorainfracloud.org/coprs/rhcontainerbot/podman-next/ 15 | # 16 | # https://bodhi.fedoraproject.org/updates/?search=buildah 17 | # 18 | # This image can be used to create a secured container 19 | # that runs safely with privileges within the container. 20 | # 21 | 22 | FROM registry.fedoraproject.org/fedora:latest 23 | ARG FLAVOR=stable 24 | 25 | label "io.containers.capabilities"="CHOWN,DAC_OVERRIDE,FOWNER,FSETID,KILL,NET_BIND_SERVICE,SETFCAP,SETGID,SETPCAP,SETUID,CHOWN,DAC_OVERRIDE,FOWNER,FSETID,KILL,NET_BIND_SERVICE,SETFCAP,SETGID,SETPCAP,SETUID,SYS_CHROOT" 26 | 27 | # When building for multiple-architectures in parallel using emulation 28 | # it's really easy for one/more dnf processes to timeout or mis-count 29 | # the minimum download rates. Bump both to be extremely forgiving of 30 | # an overworked host. 31 | RUN echo -e "\n\n# Added during image build" >> /etc/dnf/dnf.conf && \ 32 | echo -e "minrate=100\ntimeout=60\n" >> /etc/dnf/dnf.conf 33 | 34 | ARG INSTALL_RPMS="buildah fuse-overlayfs ucpp" 35 | 36 | # Don't include container-selinux and remove 37 | # directories used by dnf that are just taking 38 | # up space. 39 | # TODO: rpm --setcaps... needed due to Fedora (base) image builds 40 | # being (maybe still?) affected by 41 | # https://bugzilla.redhat.com/show_bug.cgi?id=1995337#c3 42 | RUN dnf -y makecache && \ 43 | dnf -y update && \ 44 | rpm --setcaps shadow-utils 2>/dev/null && \ 45 | case "${FLAVOR}" in \ 46 | stable) \ 47 | dnf -y install $INSTALL_RPMS --exclude container-selinux \ 48 | ;; \ 49 | testing) \ 50 | dnf -y install $INSTALL_RPMS --exclude container-selinux \ 51 | --enablerepo=updates-testing \ 52 | ;; \ 53 | upstream) \ 54 | dnf -y install 'dnf-command(copr)' --enablerepo=updates-testing && \ 55 | dnf -y copr enable rhcontainerbot/podman-next && \ 56 | dnf -y install $INSTALL_RPMS \ 57 | --exclude container-selinux \ 58 | --enablerepo=updates-testing \ 59 | ;; \ 60 | *) \ 61 | printf "\\nFLAVOR argument must be set and valid, currently: '${FLAVOR}'\\n\\n" 1>&2 && \ 62 | exit 1 \ 63 | ;; \ 64 | esac && \ 65 | ln -s /usr/bin/ucpp /usr/local/bin/cpp && \ 66 | dnf -y clean all && \ 67 | rm -rf /var/cache /var/log/dnf* /var/log/yum.* 68 | 69 | ADD ./containers.conf /etc/containers/ 70 | 71 | # Setup internal Buildah to pass secrets/subscriptions down from host to internal container 72 | RUN printf '/run/secrets/etc-pki-entitlement:/run/secrets/etc-pki-entitlement\n/run/secrets/rhsm:/run/secrets/rhsm\n' > /etc/containers/mounts.conf 73 | 74 | # Copy & modify the defaults to provide reference if runtime changes needed. 75 | # Changes here are required for running with fuse-overlay storage inside container. 76 | RUN sed -e 's|^#mount_program|mount_program|g' \ 77 | -e '/additionalimage.*/a "/var/lib/shared",' \ 78 | -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \ 79 | /usr/share/containers/storage.conf \ 80 | > /etc/containers/storage.conf && \ 81 | chmod 644 /etc/containers/storage.conf && \ 82 | chmod 644 /etc/containers/containers.conf 83 | 84 | RUN mkdir -p /var/lib/shared/overlay-images \ 85 | /var/lib/shared/overlay-layers \ 86 | /var/lib/shared/vfs-images \ 87 | /var/lib/shared/vfs-layers && \ 88 | touch /var/lib/shared/overlay-images/images.lock && \ 89 | touch /var/lib/shared/overlay-layers/layers.lock && \ 90 | touch /var/lib/shared/vfs-images/images.lock && \ 91 | touch /var/lib/shared/vfs-layers/layers.lock 92 | 93 | # Define uid/gid ranges for our user https://github.com/containers/buildah/issues/3053 94 | RUN useradd build && \ 95 | echo -e "build:1:999\nbuild:1001:64535" > /etc/subuid && \ 96 | echo -e "build:1:999\nbuild:1001:64535" > /etc/subgid && \ 97 | mkdir -p /home/build/.local/share/containers && \ 98 | mkdir -p /home/build/.config/containers && \ 99 | chown -R build:build /home/build 100 | # See: https://github.com/containers/buildah/issues/4669 101 | # Copy & modify the config for the `build` user and remove the global 102 | # `runroot` and `graphroot` which current `build` user cannot access, 103 | # in such case storage will choose a runroot in `/var/tmp`. 104 | RUN sed -e 's|^#mount_program|mount_program|g' \ 105 | -e 's|^graphroot|#graphroot|g' \ 106 | -e 's|^runroot|#runroot|g' \ 107 | /etc/containers/storage.conf \ 108 | > /home/build/.config/containers/storage.conf && \ 109 | chown build:build /home/build/.config/containers/storage.conf 110 | 111 | VOLUME /var/lib/containers 112 | VOLUME /home/build/.local/share/containers 113 | 114 | # Set an environment variable to default to chroot isolation for RUN 115 | # instructions and "buildah run". 116 | ENV BUILDAH_ISOLATION=chroot 117 | -------------------------------------------------------------------------------- /buildah/README.md: -------------------------------------------------------------------------------- 1 | [comment]: <> (***ATTENTION*** ***WARNING*** ***ALERT*** ***CAUTION*** ***DANGER***) 2 | [comment]: <> () 3 | [comment]: <> (ANY changes made below, once committed/merged must) 4 | [comment]: <> (be manually copy/pasted -in markdown- into the description) 5 | [comment]: <> (field on Quay at the following locations:) 6 | [comment]: <> () 7 | [comment]: <> (https://quay.io/repository/containers/buildah) 8 | [comment]: <> (https://quay.io/repository/buildah/stable) 9 | [comment]: <> (https://quay.io/repository/buildah/testing) 10 | [comment]: <> (https://quay.io/repository/buildah/upstream) 11 | [comment]: <> () 12 | [comment]: <> (***ATTENTION*** ***WARNING*** ***ALERT*** ***CAUTION*** ***DANGER***) 13 | 14 | ![buildah logo](https://cdn.rawgit.com/containers/buildah/main/logos/buildah-logo_large.png) 15 | 16 | # Buildah Image 17 | 18 | ## Build information 19 | 20 | Please see the [containers/image_build repo. README.md for build 21 | details](https://github.com/containers/image_build/blob/main/README.md). 22 | 23 | ## Sample Usage 24 | 25 | Although not required, it is suggested that [Podman](https://github.com/containers/podman) be used with these container images. 26 | 27 | ``` 28 | podman pull docker://quay.io/buildah/stable:latest 29 | 30 | podman run stable buildah version 31 | 32 | # Create a directory on the host to mount the container's 33 | # /var/lib/container directory to so containers can be 34 | # run within the container. 35 | mkdir /var/lib/mycontainer 36 | 37 | # Run the image detached using the host's network in a container name 38 | # buildahctr, turn off label and seccomp confinement in the container 39 | # and then do a little shell hackery to keep the container up and running. 40 | podman run --detach --name=buildahctr --net=host --security-opt label=disable --security-opt seccomp=unconfined --device /dev/fuse:rw -v /var/lib/mycontainer:/var/lib/containers:Z stable sh -c 'while true ;do sleep 100000 ; done' 41 | 42 | podman exec -it buildahctr /bin/sh 43 | 44 | # Now inside of the container 45 | 46 | buildah from alpine 47 | 48 | buildah images 49 | 50 | exit 51 | ``` 52 | 53 | **Note:** If you encounter a `fuse: device not found` error when running the container image, it is likely that 54 | the fuse kernel module has not been loaded on your host system. Use the command `modprobe fuse` to load the 55 | module and then run the container image. To enable this automatically at boot time, you can add a configuration 56 | file to `/etc/modules.load.d`. See `man modules-load.d` for more details. 57 | -------------------------------------------------------------------------------- /buildah/containers.conf: -------------------------------------------------------------------------------- 1 | [engine] 2 | cgroup_manager = "cgroupfs" 3 | -------------------------------------------------------------------------------- /ci/Containerfile: -------------------------------------------------------------------------------- 1 | # This dockerfile defines the environment for Cirrus-CI when 2 | # running automated checks and tests. 3 | # 4 | # When using the dockerfile-as-ci feature of Cirrus-CI, it's unsafe 5 | # to rely on COPY or ADD instructions. See documentation for warning. 6 | # https://cirrus-ci.org/guide/docker-builder-vm/#dockerfile-as-a-ci-environment 7 | 8 | FROM quay.io/centos/centos:stream9-minimal 9 | MAINTAINER https://github.com/containers/image_build/ci 10 | 11 | RUN microdnf update -y && \ 12 | microdnf install -y epel-release && \ 13 | microdnf install -y \ 14 | ShellCheck \ 15 | findutils \ 16 | gawk \ 17 | git \ 18 | jq \ 19 | sed \ 20 | util-linux \ 21 | && \ 22 | microdnf clean all 23 | 24 | ARG A_URL="https://raw.githubusercontent.com/containers/automation/master/bin/install_automation.sh" 25 | ENV AUTOMATION_VERSION="5.0.0" 26 | RUN curl -sL "$A_URL" | bash -s "$AUTOMATION_VERSION" 27 | -------------------------------------------------------------------------------- /ci/README.md: -------------------------------------------------------------------------------- 1 | # DO NOT USE 2 | 3 | This directory contains elements only intended to be run by 4 | CI under in a very specific environments. Any use of these 5 | scripts outside their intended environments may cause harm. 6 | -------------------------------------------------------------------------------- /ci/aio_build_push.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is not intended for humans. It should be run by secure 4 | # (maintainer-only) cron-like automation or in maintainer-authorized PRs. 5 | # Its primary purpose is to build and push the multi-arch all-in-one (AIO) 6 | # skopeo, buildah, podman container image. 7 | # 8 | # The first argument to the script, should be the git URL of the repository 9 | # containing the build context. This is assumed to be the $CWD. This URL will 10 | # be used to add several labels the images identifying the context source. 11 | # 12 | # Optionally, the `$ARCHES` environment variable may be set to a comma-separated 13 | # list of golang-centric architectures to include in the build. It is assumed 14 | # that the necessary emulation is setup to handle building of non-native arches. 15 | # Note: these builds will run in parallel, which can make the output difficult 16 | # to read. 17 | 18 | set -eo pipefail 19 | 20 | if [[ -r "/etc/automation_environment" ]]; then 21 | source /etc/automation_environment # defines AUTOMATION_LIB_PATH 22 | #shellcheck disable=SC1090,SC2154 23 | source "$AUTOMATION_LIB_PATH/common_lib.sh" 24 | dbg "Using automation common library version $(<$AUTOMATION_LIB_PATH/../AUTOMATION_VERSION)" 25 | else 26 | echo "Expecting to find automation common library installed." 27 | exit 1 28 | fi 29 | 30 | if [[ -z $(type -P build-push.sh) ]]; then 31 | die "It does not appear that build-push.sh is installed properly" 32 | fi 33 | 34 | if [[ -z "$1" ]]; then 35 | die "Expecting a git repository URI as the first argument." 36 | fi 37 | 38 | # Assume transitive debugging state for build-push.sh if set 39 | export A_DEBUG 40 | 41 | # Arches to build by default - may be overridden for testing 42 | ARCHES="${ARCHES:-amd64,ppc64le,s390x,arm64}" 43 | 44 | # First arg, URL for repository for informational purposes 45 | REPO_URL="$1" 46 | 47 | _REG="quay.io" 48 | 49 | # Make allowances for system testing 50 | if [[ ! "$REPO_URL" =~ github\.com ]] && [[ ! "$REPO_URL" =~ ^file:///tmp/ ]]; then 51 | die "Script requires a repo hosted on github, received '$REPO_URL'." 52 | _REG="example.com" 53 | fi 54 | 55 | REPO_FQIN="$_REG/containers/aio" 56 | 57 | req_env_vars REPO_URL CI SCRIPT_PATH 58 | 59 | # Common library defines SCRIPT_FILENAME 60 | # shellcheck disable=SC2154 61 | dbg "$SCRIPT_FILENAME operating constants: 62 | REPO_URL=$REPO_URL 63 | ARCHES=$ARCHES 64 | REPO_FQIN=$REPO_FQIN 65 | " 66 | 67 | # Set non-zero to avoid actually executing build-push, simply print 68 | # the command-line that would have been executed 69 | DRYRUN=${DRYRUN:-0} 70 | _DRNOPUSH="" 71 | if ((DRYRUN)); then 72 | _DRNOPUSH="--nopush" 73 | warn "Operating in dry-run mode with $_DRNOPUSH" 74 | fi 75 | 76 | ### MAIN 77 | 78 | head_sha=$(git rev-parse HEAD) 79 | dbg "HEAD is $head_sha" 80 | 81 | # Docs should always be in the context directory. 82 | [[ -r "./aio/README.md" ]] || \ 83 | die "Expected to find $PWD/aio/README.md file" 84 | docs_url="${REPO_URL%.git}/blob/${head_sha}/aio/README.md" 85 | 86 | # There's no useful way to track a combined podman, buildah, and skopeo version. 87 | version_tag=$(date -u +v%Y.%m.%d) 88 | # Note: There's no actual "aio" FLAVOR, the argument is being abused here 89 | # to avoid writing an entirely separate tag_version.sh. 90 | # SCRIPT_PATH is defined by the automation library 91 | # shellcheck disable=SC2154 92 | modcmdarg="$SCRIPT_PATH/tag_version.sh aio $version_tag" 93 | 94 | # Labels to add to all images as per 95 | # https://specs.opencontainers.org/image-spec/annotations/?v=v1.0.1 96 | declare -a label_args 97 | 98 | # Use both labels and annotations since some older tools only support labels 99 | # Ref: https://github.com/opencontainers/image-spec/blob/main/annotations.md 100 | for arg in "--label" "--annotation"; do 101 | label_args+=(\ 102 | "$arg=org.opencontainers.image.created=$(date -u --iso-8601=seconds)" 103 | "$arg=org.opencontainers.image.authors=podman@lists.podman.io" 104 | "$arg=org.opencontainers.image.url=https://$_REG/containers/aio" 105 | "$arg=org.opencontainers.image.source=${REPO_URL%.git}/blob/${head_sha}/aio/" 106 | "$arg=org.opencontainers.image.revision=$head_sha" 107 | "$arg=org.opencontainers.image.version=$version_tag" 108 | "$arg=org.opencontainers.image.documentation=${docs_url}" 109 | ) 110 | 111 | # Save users from themselves, block super-duper old versions from being used 112 | label_args+=("$arg=quay.expires-after=365d") 113 | 114 | # Definitely not any official spec., but offers a quick reference to exactly what produced 115 | # the images and it's current signature. 116 | label_args+=(\ 117 | "$arg=built.by.repo=${REPO_URL}" 118 | "$arg=built.by.commit=${head_sha}" 119 | "$arg=built.by.exec=$(basename ${BASH_SOURCE[0]})" 120 | "$arg=built.by.digest=sha256:$(sha256sum<${BASH_SOURCE[0]} | awk '{print $1}')" 121 | ) 122 | 123 | # Script may not be running under Cirrus-CI 124 | if [[ -n "$CIRRUS_TASK_ID" ]]; then 125 | label_args+=("$arg=built.by.logs=https://cirrus-ci.com/task/$CIRRUS_TASK_ID") 126 | fi 127 | done 128 | 129 | dbg "Building AIO manifest-list '$_REG/containers/aio" 130 | showrun build-push.sh \ 131 | $_DRNOPUSH \ 132 | --arches="$ARCHES" \ 133 | --modcmd="$modcmdarg" \ 134 | "$_REG/containers/aio" \ 135 | "./aio" 136 | -------------------------------------------------------------------------------- /ci/containers_build_push.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is not intended for humans. It should be run by secure 4 | # (maintainer-only) cron-like automation or in maintainer-authorized PRs. 5 | # Its primary purpose is to build and push multi-arch skopeo, buildah, podman 6 | # container images to multiple locations. The destination repository namespace 7 | # as well as the image contents are controlled by the "FLAVOR" argument 8 | # described below. 9 | # 10 | # The first argument to the script, should be the git URL of the repository 11 | # containing the build context. This is assumed to be the $CWD. This URL will 12 | # be used to add standard labels to the images identifying the source build 13 | # context. 14 | # 15 | # The second argument to this script is the path (relative to the first argument) 16 | # of the build context subdirectory. In other words, the subdirectory holding 17 | # the `Containerfile`. If no `Containerfile` is found, the build will fail. 18 | # 19 | # The third argument indicates the image "FLAVOR", which will be passed into 20 | # the build as a `--build-arg`. This is used by the `Containerfile` to alter 21 | # the build to produce a 'stable' (with 'immutable'), 'testing', or 'upstream' image. 22 | # Importantly, this value also determines where the image is pushed, see the 23 | # top-level README.md for more details. 24 | # 25 | # Optionally, the `$ARCHES` environment variable may be set to a comma-separated 26 | # list of golang-centric architectures to include in the build. It is assumed 27 | # that the necessary emulation is setup to handle building of non-native arches. 28 | # Note: these builds will run in parallel, which can make the output difficult 29 | # to read. 30 | 31 | set -eo pipefail 32 | 33 | if [[ -r "/etc/automation_environment" ]]; then 34 | source /etc/automation_environment # defines AUTOMATION_LIB_PATH 35 | #shellcheck disable=SC1090,SC2154 36 | source "$AUTOMATION_LIB_PATH/common_lib.sh" 37 | dbg "Using automation common library version $(<$AUTOMATION_LIB_PATH/../AUTOMATION_VERSION)" 38 | else 39 | echo "Expecting to find automation common library installed." 40 | exit 1 41 | fi 42 | 43 | if [[ -z $(type -P build-push.sh) ]]; then 44 | die "It does not appear that build-push.sh is installed properly" 45 | fi 46 | 47 | if [[ -z "$1" ]]; then 48 | die "Expecting a git repository URI as the first argument." 49 | fi 50 | 51 | if [[ "$#" -lt 3 ]]; then 52 | #shellcheck disable=SC2145 53 | die "Must be called with at least three arguments, got '$*'" 54 | fi 55 | 56 | req_env_vars CI SCRIPT_PATH 57 | 58 | # Assume transitive debugging state for build-push.sh if set 59 | if [[ "$(automation_version | cut -d '.' -f 1)" -ge 4 ]]; then 60 | # Valid for version 4.0.0 and above only 61 | export A_DEBUG 62 | else 63 | export DEBUG 64 | fi 65 | 66 | # Arches to build by default - may be overridden for testing 67 | ARCHES="${ARCHES:-amd64,ppc64le,s390x,arm64}" 68 | 69 | # First arg, URL for repository for informational purposes 70 | REPO_URL="$1" 71 | 72 | # Make allowances for system testing 73 | if [[ ! "$REPO_URL" =~ github\.com ]] && [[ ! "$REPO_URL" =~ ^file:///tmp/ ]]; then 74 | die "Script requires a repo hosted on github, received '$REPO_URL'." 75 | fi 76 | 77 | # Second arg (CTX_SUB) is the context subdirectory relative to the clone path 78 | CTX_SUB="$2" 79 | 80 | # Third arg is the FLAVOR build-arg value 81 | FLAVOR_NAME="$3" 82 | 83 | _REG="quay.io" 84 | if [[ "$CTX_SUB" =~ testing ]]; then 85 | dbg "System tests are running, using example/test registry name." 86 | _REG="example.com" 87 | fi 88 | 89 | REPO_FQIN="$_REG/$CTX_SUB/$FLAVOR_NAME" 90 | req_env_vars REPO_URL CTX_SUB FLAVOR_NAME 91 | 92 | # Common library defines SCRIPT_FILENAME 93 | # shellcheck disable=SC2154 94 | dbg "$SCRIPT_FILENAME operating constants: 95 | REPO_URL=$REPO_URL 96 | CTX_SUB=$CTX_SUB 97 | FLAVOR_NAME=$FLAVOR_NAME 98 | ARCHES=$ARCHES 99 | REPO_FQIN=$REPO_FQIN 100 | " 101 | 102 | # Set non-zero to avoid actually executing build-push, simply print 103 | # the command-line that would have been executed 104 | DRYRUN=${DRYRUN:-0} 105 | _DRNOPUSH="" 106 | if ((DRYRUN)); then 107 | _DRNOPUSH="--nopush" 108 | warn "Operating in dry-run mode with $_DRNOPUSH" 109 | fi 110 | 111 | ### MAIN 112 | 113 | declare -a build_args 114 | build_args=("--build-arg=FLAVOR=$FLAVOR_NAME") 115 | 116 | head_sha=$(git rev-parse HEAD) 117 | dbg "HEAD is $head_sha" 118 | 119 | # Docs should always be in one of two places, otherwise don't list any. 120 | docs_url="" 121 | for _docs_subdir in "$CTX_SUB/README.md" "$(dirname $CTX_SUB)/README.md"; do 122 | if [[ -r "./$_docs_subdir" ]]; then 123 | dbg "Found README.md under './$_docs_subdir'" 124 | docs_url="${REPO_URL%.git}/blob/${head_sha}/$_docs_subdir" 125 | break 126 | fi 127 | done 128 | 129 | # Labels to add to all images as per 130 | # https://specs.opencontainers.org/image-spec/annotations/?v=v1.0.1 131 | declare -a label_args 132 | 133 | # Use both labels and annotations since some older tools only support labels 134 | # Ref: https://github.com/opencontainers/image-spec/blob/main/annotations.md 135 | for arg in "--label" "--annotation"; do 136 | label_args+=(\ 137 | "$arg=org.opencontainers.image.created=$(date -u --iso-8601=seconds)" 138 | "$arg=org.opencontainers.image.authors=podman@lists.podman.io" 139 | "$arg=org.opencontainers.image.source=${REPO_URL%.git}/blob/${head_sha}/${CTX_SUB}/" 140 | "$arg=org.opencontainers.image.revision=$head_sha" 141 | ) 142 | 143 | if [[ -n "$docs_url" ]]; then 144 | label_args+=("$arg=org.opencontainers.image.documentation=${docs_url}") 145 | fi 146 | 147 | # Definitely not any official spec., but offers a quick reference to exactly what produced 148 | # the images and it's current signature. 149 | label_args+=(\ 150 | "$arg=built.by.repo=${REPO_URL}" 151 | "$arg=built.by.commit=${head_sha}" 152 | "$arg=built.by.exec=$(basename ${BASH_SOURCE[0]})" 153 | "$arg=built.by.digest=sha256:$(sha256sum<${BASH_SOURCE[0]} | awk '{print $1}')" 154 | ) 155 | 156 | # Script may not be running under Cirrus-CI 157 | if [[ -n "$CIRRUS_TASK_ID" ]]; then 158 | label_args+=("$arg=built.by.logs=https://cirrus-ci.com/task/$CIRRUS_TASK_ID") 159 | fi 160 | done 161 | 162 | # SCRIPT_PATH is defined by the automation library 163 | # shellcheck disable=SC2154 164 | modcmdarg="$SCRIPT_PATH/tag_version.sh $FLAVOR_NAME" 165 | 166 | # For stable images, the version number of the command is needed for tagging and labeling. 167 | if [[ "$FLAVOR_NAME" == "stable" ]]; then 168 | # only native arch is needed to extract the version 169 | dbg "Building temporary local-arch image to extract $FLAVOR_NAME version number" 170 | fqin_tmp="$CTX_SUB:temp" 171 | showrun podman build --arch=amd64 -t $fqin_tmp "${build_args[@]}" ./$CTX_SUB 172 | 173 | case "$CTX_SUB" in 174 | skopeo*) version_cmd="--version" ;; 175 | buildah*) version_cmd="buildah --version" ;; 176 | podman*) version_cmd="podman --version" ;; 177 | testing*) version_cmd="cat FAKE_VERSION" ;; 178 | *) die "Unknown/unsupported context '$CTX_SUB'" ;; 179 | esac 180 | 181 | pvcmd="podman run -i --rm $fqin_tmp $version_cmd" 182 | dbg "Extracting version with command: $pvcmd" 183 | version_output=$($pvcmd) 184 | dbg "version output: '$version_output'" 185 | img_cmd_version=$(awk -r -e '/^.+ version /{print $3}' <<<"$version_output") 186 | dbg "parsed version: $img_cmd_version" 187 | test -n "$img_cmd_version" 188 | 189 | label_args+=("--label=org.opencontainers.image.version=$img_cmd_version" 190 | "--annotation=org.opencontainers.image.version=$img_cmd_version") 191 | 192 | # tag-version.sh expects this arg. when FLAVOR_NAME=stable 193 | modcmdarg+=" $img_cmd_version" 194 | 195 | dbg "Building $FLAVOR_NAME manifest-list '$_REG/containers/$CTX_SUB'" 196 | 197 | for arg in "--label" "--annotation"; do 198 | label_args+=("$arg=org.opencontainers.image.url=https://$_REG/containers/$CTX_SUB") 199 | done 200 | 201 | # Stable (with immutable) images get pushed to 'containers' namespace as latest & version-tagged. 202 | # Immutable images are never pushed if they already exist. 203 | showrun build-push.sh \ 204 | $_DRNOPUSH \ 205 | --arches="$ARCHES" \ 206 | --modcmd="$modcmdarg" \ 207 | "$_REG/containers/$CTX_SUB" \ 208 | "./$CTX_SUB" \ 209 | "${build_args[@]}" \ 210 | "${label_args[@]}" 211 | elif [[ "$FLAVOR_NAME" == "testing" ]]; then 212 | label_args+=("--label=quay.expires-after=30d" 213 | "--annotation=quay.expires-after=30d") 214 | elif [[ "$FLAVOR_NAME" == "upstream" ]]; then 215 | label_args+=("--label=quay.expires-after=15d" 216 | "--annotation=quay.expires-after=15d") 217 | fi 218 | 219 | dbg "Building manifest-list '$REPO_FQIN'" 220 | 221 | for arg in "--label" "--annotation"; do 222 | label_args+=("$arg=org.opencontainers.image.url=https://${REPO_FQIN}") 223 | done 224 | 225 | # All flavors are pushed to quay.io//, both 226 | # latest and version-tagged (if available). Immutable 227 | # images are only version-tagged, and are never pushed if they 228 | # already exist. 229 | showrun build-push.sh \ 230 | $_DRNOPUSH \ 231 | --arches="$ARCHES" \ 232 | --modcmd="$modcmdarg" \ 233 | "$REPO_FQIN" \ 234 | "./$CTX_SUB" \ 235 | "${build_args[@]}" \ 236 | "${label_args[@]}" 237 | -------------------------------------------------------------------------------- /ci/shellcheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is intended to be executed by humans or automation. 4 | # It simply provides a one-command way of executing shellcheck 5 | # in a uniform way 6 | 7 | set -eo pipefail 8 | 9 | cd $(realpath $(dirname "${BASH_SOURCE[0]}")/../) 10 | pwd 11 | shellcheck --color=always --format=tty \ 12 | --shell=bash --external-sources \ 13 | --enable add-default-case,avoid-nullary-conditions,check-unassigned-uppercase \ 14 | --exclude SC2046,SC2034,SC2090,SC2064 \ 15 | --wiki-link-count=0 --severity=warning \ 16 | ./*/*.sh 17 | 18 | echo "PASS" 19 | -------------------------------------------------------------------------------- /ci/tag_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is not intended for humans. It should only be referenced 4 | # as an argument to the build-push.sh `--modcmd` option. It's purpose 5 | # is to ensure stable images are re-tagged with a verison-number 6 | # using a specific scheme, cooresponding to the included tool's version. 7 | # It expects two arguments, the first is the "flavor" of the image. 8 | # Typically 'upstream', 'testing', or 'stable'. The second argument 9 | # is optional, when provided it should be the container-image's tool 10 | # version number (e.g. podman version). 11 | 12 | set -eo pipefail 13 | 14 | if [[ -r "/etc/automation_environment" ]]; then 15 | source /etc/automation_environment # defines AUTOMATION_LIB_PATH 16 | #shellcheck disable=SC1090,SC2154 17 | source "$AUTOMATION_LIB_PATH/common_lib.sh" 18 | else 19 | echo "Unexpected operating environment" 20 | exit 1 21 | fi 22 | 23 | # Vars defined by build-push.sh spec. for mod scripts 24 | req_env_vars SCRIPT_FILENAME SCRIPT_FILEPATH RUNTIME PLATFORMOS FQIN CONTEXT \ 25 | PUSH ARCHES REGSERVER NAMESPACE IMGNAME MODCMD 26 | 27 | if [[ "$#" -eq 0 ]]; then 28 | # Defined by common automation library 29 | # shellcheck disable=SC2154 30 | die "$SCRIPT_FILENAME expects at least one argument" 31 | fi 32 | 33 | if [[ "$#" -ge 1 ]]; then 34 | FLAVOR_NAME="$1" 35 | # Version is optional 36 | unset VERSION 37 | [[ -z "$2" ]] || \ 38 | VERSION="v${2#v}" 39 | fi 40 | 41 | if [[ -z "$FLAVOR_NAME" ]]; then 42 | # Defined by common_lib.sh 43 | # shellcheck disable=SC2154 44 | warn "$SCRIPT_FILENAME passed empty flavor-name argument." 45 | elif [[ -z "$VERSION" ]]; then 46 | warn "$SCRIPT_FILENAME received empty version argument." 47 | fi 48 | 49 | # Given the image tag as an argument, apply the tag as appropriate given $FLAVOR_NAME 50 | # N/B: For the "immutable" flavor, the tag will have `-immutable` appended to it. 51 | handle_tagging() { 52 | local existing tag imtag 53 | tag="$1" 54 | 55 | [[ -n "$tag" ]] || \ 56 | die "handle_tagging() received an empty tag argument." 57 | 58 | # Images are always tagged using the source $FQIN:latest 59 | [[ "$tag" != "latest" ]] || \ 60 | die "handle_tagging() must never be run with tag argument 'latest'." 61 | 62 | # Stable images get -immutable tags only if they don't already exist 63 | if [[ "$FLAVOR_NAME" == "stable" ]]; then 64 | imtag="${tag}-immutable" 65 | # ci/test.sh tests never push, there's never any remote image to check. 66 | existing="" 67 | 68 | # The FQIN envar is defined by the build-push.sh caller 69 | # shellcheck disable=SC2154 70 | if [[ ! "$FQIN" =~ testing ]]; then 71 | existing=$(skopeo list-tags docker://$FQIN | jq -e -r '.Tags[]') 72 | fi 73 | 74 | if grep -F -x -q "$imtag" <<<"$existing"; then 75 | msg "Skipping; $FQIN:$imtag already exists in registry." 76 | else 77 | msg "Tagging new $FQIN:${tag}-immutable" 78 | # The RUNTIME envar is defined by the build-push.sh caller 79 | # shellcheck disable=SC2154 80 | $RUNTIME tag $FQIN:latest $FQIN:$imtag 81 | fi 82 | fi 83 | 84 | dbg "Tagging $FQIN:latest $FQIN:$tag" 85 | $RUNTIME tag $FQIN:latest $FQIN:$tag 86 | msg "Successfully tagged $FQIN:$tag" 87 | } 88 | 89 | # shellcheck disable=SC2154 90 | dbg "$SCRIPT_FILENAME operating on '$FLAVOR_NAME' flavor of '$FQIN' with tool version '$VERSION' (optional)" 91 | 92 | if [[ "$FLAVOR_NAME" == "stable" ]]; then 93 | # Stable images must all be tagged with a version number. 94 | # Confirm this value is passed in by caller. 95 | if grep -E -q '^v[0-9]+\.[0-9]+\.[0-9]+'<<<"$VERSION"; then 96 | msg "Using provided image command version '$VERSION'" 97 | else 98 | die "Encountered unexpected/non-conforming version '$VERSION'" 99 | fi 100 | 101 | handle_tagging $VERSION 102 | 103 | # Tag as x.y to provide a consistent tag even for a future z+1 104 | xy_ver=$(awk -F '.' '{print $1"."$2}'<<<"$VERSION") 105 | handle_tagging $xy_ver 106 | 107 | # Tag as x to provide consistent tag even for a future y+1 108 | x_ver=$(awk -F '.' '{print $1}'<<<"$xy_ver") 109 | handle_tagging $x_ver 110 | elif [[ "$FLAVOR_NAME" == "aio" ]]; then 111 | # Not a real flavor, see aio_build_push.sh 112 | handle_tagging $VERSION 113 | else 114 | warn "$SCRIPT_FILENAME not version-tagging for '$FLAVOR_NAME' flavor'$FQIN'" 115 | fi 116 | -------------------------------------------------------------------------------- /ci/test.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | # DO NOT USE - This script is intended to be called by the Cirrus-CI 4 | # `test_build-push` task. It is not intended to be used otherwise 5 | # and may cause harm. It's purpose is to confirm the 6 | # 'containers_build_push.sh' script behaves in an expected way, given 7 | # a special testing git repository (setup here) as input. 8 | 9 | set -eo pipefail 10 | 11 | source /etc/automation_environment 12 | source $AUTOMATION_LIB_PATH/common_lib.sh 13 | 14 | req_env_vars CIRRUS_CI CIRRUS_CHANGE_IN_REPO 15 | 16 | # Architectures to test with (golang standard names) 17 | TESTARCHES="amd64 arm64" 18 | # containers_build_push.sh is sensitive to this value 19 | ARCHES=$(tr " " ","<<<"$TESTARCHES") 20 | export ARCHES 21 | # Contrived "version" for testing purposes 22 | FAKE_VER_X=$RANDOM 23 | FAKE_VER_Y=$RANDOM 24 | FAKE_VER_Z=$RANDOM 25 | FAKE_VERSION="$FAKE_VER_X.$FAKE_VER_Y.$FAKE_VER_Z" 26 | # Contrived source repository for testing 27 | SRC_TMP=$(mktemp -p '' -d tmp-build-push-test-XXXX) 28 | # Do not change, containers_build_push.sh is sensitive to the 'testing' name 29 | TEST_FQIN=example.com/testing/stable 30 | # Stable build should result in manifest list tagged this 31 | TEST_FQIN2=example.com/containers/testing 32 | # Don't allow containers_build_push.sh or tag_version.sh to auto-update at runtime 33 | export BUILDPUSHAUTOUPDATED=1 34 | 35 | trap "rm -rf $SRC_TMP" EXIT 36 | 37 | # containers_build_push.sh expects a git repository argument 38 | msg " 39 | ##### Constructing local test repository #####" 40 | cd $SRC_TMP 41 | showrun git init -b main . 42 | mkdir testing 43 | cd testing 44 | git config --local user.name "Testy McTestface" 45 | git config --local user.email "test@example.com" 46 | git config --local advice.detachedHead "false" 47 | git config --local commit.gpgsign "false" 48 | # Set a default flavor in the Containerfile to detect missing 49 | echo "build-push-test version v$FAKE_VERSION" | tee "FAKE_VERSION" 50 | cat < /FLAVOUR 55 | EOF 56 | # This file is looked up by the build script. 57 | echo "Test Docs" > README.md 58 | # The images will have the repo & commit ID set as labels 59 | git add --all 60 | git commit -m 'test repo initial commit' 61 | TEST_REVISION=$(git rev-parse HEAD) 62 | 63 | TEST_REPO_URL="file://$SRC_TMP" 64 | 65 | # Print an error message and exit non-zero if the FQIN:TAG indicated 66 | # by the first argument does not exist. 67 | manifest_exists() { 68 | msg "Confirming existence of manifest list '$1'" 69 | if ! showrun podman manifest exists "$1"; then 70 | die "Failed to find expected manifest-list '$1'" 71 | fi 72 | } 73 | 74 | # Given the flavor-name as the first argument, verify built image 75 | # expectations. For 'stable' image, verify that containers_build_push.sh will properly 76 | # version-tagged both FQINs. For 'immutable' verify version tags only for TEST_FQIN2. 77 | # For other flavors, verify expected labels on the `latest` tagged FQINs. 78 | verify_built_images() { 79 | local _fqin _arch xy_ver x_ver img_ver img_src img_rev _fltr 80 | local test_tag expected_flavor _test_fqins img_docs 81 | expected_flavor="$1" 82 | msg " 83 | ##### Testing execution of '$expected_flavor' images for arches $TESTARCHES #####" 84 | podman --version 85 | req_env_vars TESTARCHES FAKE_VERSION TEST_FQIN TEST_FQIN2 CIRRUS_REPO_CLONE_URL 86 | 87 | declare -a _test_fqins 88 | _test_fqins=("${TEST_FQIN%stable}$expected_flavor") 89 | if [[ "$expected_flavor" == "stable" ]]; then 90 | _test_fqins+=("$TEST_FQIN2") 91 | test_tag="v$FAKE_VERSION" 92 | xy_ver="v$FAKE_VER_X.$FAKE_VER_Y" 93 | x_ver="v$FAKE_VER_X" 94 | else 95 | test_tag="latest" 96 | xy_ver="latest" 97 | x_ver="latest" 98 | fi 99 | 100 | for _fqin in "${_test_fqins[@]}"; do 101 | manifest_exists $_fqin:$test_tag 102 | 103 | if [[ "$expected_flavor" == "stable" ]]; then 104 | manifest_exists $_fqin:$xy_ver 105 | manifest_exists $_fqin:$x_ver 106 | manifest_exists $_fqin:${test_tag}-immutable 107 | manifest_exists $_fqin:${xy_ver}-immutable 108 | manifest_exists $_fqin:${x_ver}-immutable 109 | 110 | msg "Confirming there is no 'latest-immutable' tag" 111 | if showrun podman manifest exists $_fqin:latest-immutable; then 112 | die "The latest tag must never ever have an immutable suffix" 113 | fi 114 | fi 115 | 116 | for _arch in $TESTARCHES; do 117 | msg "Testing container can execute '/bin/true'" 118 | showrun podman run -i --arch=$_arch --rm "$_fqin:$test_tag" /bin/true 119 | 120 | msg "Testing container FLAVOR build-arg passed correctly" 121 | showrun podman run -i --arch=$_arch --rm "$_fqin:$test_tag" \ 122 | cat /FLAVOUR | tee /dev/stderr | grep -Fxq "FLAVOUR=$expected_flavor" 123 | done 124 | 125 | if [[ "$expected_flavor" == "stable" ]]; then 126 | msg "Testing image $_fqin:$test_tag version label" 127 | _fltr='.[].Config.Labels."org.opencontainers.image.version"' 128 | img_ver=$(podman inspect $_fqin:$test_tag | jq -r -e "$_fltr") 129 | showrun test "$img_ver" == "v$FAKE_VERSION" 130 | fi 131 | 132 | msg "Testing image $_fqin:$test_tag source label" 133 | _fltr='.[].Config.Labels."org.opencontainers.image.source"' 134 | img_src=$(podman inspect $_fqin:$test_tag | jq -r -e "$_fltr") 135 | msg " img_src=$img_src" 136 | # Checked at beginning of script 137 | # shellcheck disable=SC2154 138 | showrun grep -F -q "$TEST_REPO_URL" <<<"$img_src" 139 | showrun grep -F -q "$TEST_REVISION" <<<"$img_src" 140 | 141 | msg "Testing image $_fqin:$test_tag url label" 142 | _fltr='.[].Config.Labels."org.opencontainers.image.url"' 143 | img_url=$(podman inspect $_fqin:$test_tag | jq -r -e "$_fltr") 144 | msg " img_url=$img_url" 145 | showrun grep -F -q "example.com" <<<"$img_url" 146 | 147 | 148 | msg "Testing image $_fqin:$test_tag revision label" 149 | _fltr='.[].Config.Labels."org.opencontainers.image.revision"' 150 | img_rev=$(podman inspect $_fqin:$test_tag | jq -r -e "$_fltr") 151 | msg " img_rev=$img_rev" 152 | showrun test "$img_rev" == "$TEST_REVISION" 153 | 154 | msg "Testing image $_fqin:$test_tag built.by.commit label" 155 | _fltr='.[].Config.Labels."built.by.commit"' 156 | img_bbc=$(podman inspect $_fqin:$test_tag | jq -r -e "$_fltr") 157 | msg " img_bbc=$img_bbc" 158 | # Checked at beginning of script 159 | # shellcheck disable=SC2154 160 | showrun test "$img_bbc" == "$TEST_REVISION" 161 | 162 | msg "Testing image $_fqin:$test_tag docs label" 163 | _fltr='.[].Config.Labels."org.opencontainers.image.documentation"' 164 | img_docs=$(podman inspect $_fqin:$test_tag | jq -r -e "$_fltr") 165 | msg " img_docs=$img_docs" 166 | showrun grep -F -q "README.md" <<<"$img_docs" 167 | done 168 | } 169 | 170 | remove_built_images() { 171 | local fqin tag 172 | local -a tags 173 | 174 | buildah --version 175 | 176 | tags=( latest ) 177 | for tag in v$FAKE_VERSION v$FAKE_VER_X.$FAKE_VER_Y v$FAKE_VER_X; do 178 | tags+=( "$tag" "${tag}-immutable" ) 179 | done 180 | 181 | for fqin in $TEST_FQIN $TEST_FQIN2; do 182 | for tag in "${tags[@]}"; do 183 | # Not all tests produce every possible tag 184 | podman manifest rm $fqin:$tag &> /dev/null || true 185 | done 186 | done 187 | } 188 | 189 | req_env_vars CIRRUS_WORKING_DIR 190 | # shellcheck disable=SC2154 191 | _cbp=$CIRRUS_WORKING_DIR/ci/containers_build_push.sh 192 | 193 | cd $SRC_TMP 194 | 195 | for flavor_arg in stable foobarbaz; do 196 | msg " 197 | ##### Testing build-push $flavor_arg flavor run of '$TEST_FQIN' & '$TEST_FQIN2' #####" 198 | remove_built_images 199 | export DRYRUN=1 # Force containers_build_push.sh not to push anything 200 | req_env_vars ARCHES DRYRUN flavor_arg 201 | # containers_build_push.sh is sensitive to 'testing' value. 202 | env A_DEBUG=1 $_cbp $TEST_REPO_URL testing $flavor_arg 203 | verify_built_images $flavor_arg 204 | done 205 | -------------------------------------------------------------------------------- /ci/validate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is intended to be run by Cirrus-CI to validate PR 4 | # content prior to building any images. It should not be run 5 | # under any other context. 6 | 7 | set -eo pipefail 8 | 9 | source /etc/automation_environment 10 | source $AUTOMATION_LIB_PATH/common_lib.sh 11 | 12 | req_env_vars CIRRUS_PR CIRRUS_BASE_SHA CIRRUS_PR_TITLE CIRRUS_USER_PERMISSION 13 | 14 | show_env_vars 15 | 16 | # Defined by Cirrus-CI 17 | # shellcheck disable=SC2154 18 | [[ "$CIRRUS_CI" == "true" ]] || \ 19 | die "This script is only/ever intended to be run by Cirrus-CI." 20 | 21 | # This is imperfect security-wise, but attempt to catch an accidental 22 | # change in Cirrus-CI Repository settings. Namely the hard-to-read 23 | # "slider" that enables non-contributors to run Cirrus-CI jobs. We 24 | # don't want that on this repo, ever. because there are sensitive 25 | # secrets in use. This variable is set by CI and validated non-empty above 26 | # shellcheck disable=SC2154 27 | if [[ "$CIRRUS_USER_PERMISSION" != "write" ]] && [[ "$CIRRUS_USER_PERMISSION" != "admin" ]]; then 28 | die "CI Execution not supported with permission level '$CIRRUS_USER_PERMISSION'" 29 | fi 30 | 31 | ### The following checks only apply if validating a PR 32 | if [[ -z "$CIRRUS_PR" ]]; then 33 | echo "Not validating IMG_SFX changes outside of a PR" 34 | exit 0 35 | fi 36 | 37 | # For Docs-only PRs, no further checks are needed 38 | # Variable is defined by Cirrus-CI at runtime 39 | # shellcheck disable=SC2154 40 | if [[ "$CIRRUS_PR_TITLE" =~ CI:DOCS ]]; then 41 | msg "This looks like a docs-only PR, skipping further validation checks." 42 | exit 0 43 | fi 44 | 45 | # TODO: Check other stuff 46 | -------------------------------------------------------------------------------- /podman/Containerfile: -------------------------------------------------------------------------------- 1 | # podman/Containerfile 2 | # 3 | # Build a Podman container image from the latest 4 | # stable version of Podman on the Fedoras Updates System. 5 | # https://bodhi.fedoraproject.org/updates/?search=podman 6 | # This image can be used to create a secured container 7 | # that runs safely with privileges within the container. 8 | # 9 | # FLAVOR defaults to stable if unset 10 | # 11 | # FLAVOR=stable acquires a stable version of Podman 12 | # from the Fedoras Updates System. 13 | # FLAVOR=testing acquires a testing version of Podman 14 | # from the Fedoras Updates System. 15 | # FLAVOR=upstream acquires a testing version of Podman 16 | # from the Fedora Copr Buildsystem. 17 | # https://copr.fedorainfracloud.org/coprs/rhcontainerbot/podman-next/ 18 | # 19 | # https://bodhi.fedoraproject.org/updates/?search=podman 20 | 21 | FROM registry.fedoraproject.org/fedora:latest 22 | ARG FLAVOR=stable 23 | 24 | # When building for multiple-architectures in parallel using emulation 25 | # it's really easy for one/more dnf processes to timeout or mis-count 26 | # the minimum download rates. Bump both to be extremely forgiving of 27 | # an overworked host. 28 | RUN echo -e "\n\n# Added during image build" >> /etc/dnf/dnf.conf && \ 29 | echo -e "minrate=100\ntimeout=60\n" >> /etc/dnf/dnf.conf 30 | 31 | ARG INSTALL_RPMS="podman fuse-overlayfs openssh-clients ucpp" 32 | 33 | # Don't include container-selinux and remove 34 | # directories used by dnf that are just taking 35 | # up space. 36 | # TODO: rpm --setcaps... needed due to Fedora (base) image builds 37 | # being (maybe still?) affected by 38 | # https://bugzilla.redhat.com/show_bug.cgi?id=1995337#c3 39 | RUN dnf -y makecache && \ 40 | dnf -y update && \ 41 | rpm --setcaps shadow-utils 2>/dev/null && \ 42 | case "${FLAVOR}" in \ 43 | stable) \ 44 | dnf -y install $INSTALL_RPMS --exclude container-selinux \ 45 | ;; \ 46 | testing) \ 47 | dnf -y install $INSTALL_RPMS --exclude container-selinux \ 48 | --enablerepo updates-testing \ 49 | ;; \ 50 | upstream) \ 51 | dnf -y install 'dnf-command(copr)' --enablerepo=updates-testing && \ 52 | dnf -y copr enable rhcontainerbot/podman-next && \ 53 | dnf -y install $INSTALL_RPMS \ 54 | --exclude container-selinux \ 55 | --enablerepo=updates-testing \ 56 | ;; \ 57 | *) \ 58 | printf "\\nFLAVOR argument must be set and valid, currently: '${FLAVOR}'\\n\\n" 1>&2 && \ 59 | exit 1 \ 60 | ;; \ 61 | esac && \ 62 | ln -s /usr/bin/ucpp /usr/local/bin/cpp && \ 63 | dnf clean all && \ 64 | rm -rf /var/cache /var/log/dnf* /var/log/yum.* 65 | 66 | RUN useradd podman && \ 67 | echo -e "podman:1:999\npodman:1001:64535" > /etc/subuid && \ 68 | echo -e "podman:1:999\npodman:1001:64535" > /etc/subgid 69 | 70 | ADD /containers.conf /etc/containers/containers.conf 71 | ADD /podman-containers.conf /home/podman/.config/containers/containers.conf 72 | 73 | RUN mkdir -p /home/podman/.local/share/containers && \ 74 | chown podman:podman -R /home/podman && \ 75 | chmod 644 /etc/containers/containers.conf 76 | 77 | # Copy & modify the defaults to provide reference if runtime changes needed. 78 | # Changes here are required for running with fuse-overlay storage inside container. 79 | RUN sed -e 's|^#mount_program|mount_program|g' \ 80 | -e '/additionalimage.*/a "/var/lib/shared",' \ 81 | -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \ 82 | /usr/share/containers/storage.conf \ 83 | > /etc/containers/storage.conf 84 | 85 | # Setup internal Podman to pass subscriptions down from host to internal container 86 | RUN printf '/run/secrets/etc-pki-entitlement:/run/secrets/etc-pki-entitlement\n/run/secrets/rhsm:/run/secrets/rhsm\n' > /etc/containers/mounts.conf 87 | 88 | # Note VOLUME options must always happen after the chown call above 89 | # RUN commands can not modify existing volumes 90 | VOLUME /var/lib/containers 91 | VOLUME /home/podman/.local/share/containers 92 | 93 | RUN mkdir -p /var/lib/shared/overlay-images \ 94 | /var/lib/shared/overlay-layers \ 95 | /var/lib/shared/vfs-images \ 96 | /var/lib/shared/vfs-layers && \ 97 | touch /var/lib/shared/overlay-images/images.lock && \ 98 | touch /var/lib/shared/overlay-layers/layers.lock && \ 99 | touch /var/lib/shared/vfs-images/images.lock && \ 100 | touch /var/lib/shared/vfs-layers/layers.lock 101 | 102 | ENV _CONTAINERS_USERNS_CONFIGURED="" \ 103 | BUILDAH_ISOLATION=chroot 104 | -------------------------------------------------------------------------------- /podman/README.md: -------------------------------------------------------------------------------- 1 | [comment]: <> (***ATTENTION*** ***WARNING*** ***ALERT*** ***CAUTION*** ***DANGER***) 2 | [comment]: <> () 3 | [comment]: <> (ANY changes made below, once committed/merged must) 4 | [comment]: <> (be manually copy/pasted -in markdown- into the description) 5 | [comment]: <> (field on Quay at the following locations:) 6 | [comment]: <> () 7 | [comment]: <> (https://quay.io/repository/containers/podman) 8 | [comment]: <> (https://quay.io/repository/podman/stable) 9 | [comment]: <> (https://quay.io/repository/podman/testing) 10 | [comment]: <> (https://quay.io/repository/podman/upstream) 11 | [comment]: <> () 12 | [comment]: <> (***ATTENTION*** ***WARNING*** ***ALERT*** ***CAUTION*** ***DANGER***) 13 | 14 | ![PODMAN logo](https://raw.githubusercontent.com/containers/common/main/logos/podman-logo-full-vert.png) 15 | 16 | # Podman Image 17 | 18 | ## Build information 19 | 20 | Please see the [containers/image_build repo. README.md for build 21 | details](https://github.com/containers/image_build/blob/main/README.md). 22 | 23 | ## Sample Usage 24 | 25 | ``` 26 | podman pull docker://quay.io/podman/stable:latest 27 | 28 | podman run --privileged stable podman version 29 | 30 | # Create a directory on the host to mount the container's 31 | # /var/lib/container directory to so containers can be 32 | # run within the container. 33 | mkdir /var/lib/mycontainer 34 | 35 | # Run the image detached using the host's network in a container name 36 | # podmanctr, turn off label and seccomp confinement in the container 37 | # and then do a little shell hackery to keep the container up and running. 38 | podman run --detach --name=podmanctr --net=host --security-opt label=disable --security-opt seccomp=unconfined --device /dev/fuse:rw -v /var/lib/mycontainer:/var/lib/containers:Z --privileged stable sh -c 'while true ;do sleep 100000 ; done' 39 | 40 | podman exec -it podmanctr /bin/sh 41 | 42 | # Now inside of the container 43 | 44 | podman pull alpine 45 | 46 | podman images 47 | 48 | exit 49 | ``` 50 | 51 | **Note:** If you encounter a `fuse: device not found` error when running the container image, it is likely that 52 | the fuse kernel module has not been loaded on your host system. Use the command `modprobe fuse` to load the 53 | module and then run the container image. To enable this automatically at boot time, you can add a configuration 54 | file to `/etc/modules.load.d`. See `man modules-load.d` for more details. 55 | 56 | ### Blog Post with Details 57 | 58 | Dan Walsh wrote a blog post on the [Enable Sysadmin](https://www.redhat.com/sysadmin/) site titled [How to use Podman inside of a container](https://www.redhat.com/sysadmin/podman-inside-container). In it, he details how to use these images as a rootful and as a rootless user. Please refer to this blog for more detailed information. 59 | -------------------------------------------------------------------------------- /podman/containers.conf: -------------------------------------------------------------------------------- 1 | [containers] 2 | netns="host" 3 | userns="host" 4 | ipcns="host" 5 | utsns="host" 6 | cgroupns="host" 7 | cgroups="disabled" 8 | log_driver = "k8s-file" 9 | [engine] 10 | cgroup_manager = "cgroupfs" 11 | events_logger="file" 12 | runtime="crun" 13 | -------------------------------------------------------------------------------- /podman/podman-containers.conf: -------------------------------------------------------------------------------- 1 | [containers] 2 | volumes = [ 3 | "/proc:/proc", 4 | ] 5 | default_sysctls = [] 6 | -------------------------------------------------------------------------------- /skopeo/Containerfile: -------------------------------------------------------------------------------- 1 | # skopeo/Containerfile 2 | # 3 | # Build a Skopeo container image from the latest 4 | # stable version of Skopeo on the Fedoras Updates System. 5 | # https://bodhi.fedoraproject.org/updates/?search=skopeo 6 | # This image can be used to create a secured container 7 | # that runs safely with privileges within the container. 8 | # 9 | # FLAVOR defaults to stable if unset 10 | # 11 | # FLAVOR=stable acquires a stable version of Skopeo 12 | # from the Fedoras Updates System. 13 | # FLAVOR=testing acquires a testing version of Skopeo 14 | # from the Fedoras Updates System. 15 | # FLAVOR=upstream acquires a testing version of Skopeo 16 | # from the Fedora Copr Buildsystem. 17 | # https://copr.fedorainfracloud.org/coprs/rhcontainerbot/podman-next/ 18 | # 19 | # https://bodhi.fedoraproject.org/updates/?search=skopeo 20 | 21 | FROM registry.fedoraproject.org/fedora:latest 22 | ARG FLAVOR=stable 23 | 24 | # When building for multiple-architectures in parallel using emulation 25 | # it's really easy for one/more dnf processes to timeout or mis-count 26 | # the minimum download rates. Bump both to be extremely forgiving of 27 | # an overworked host. 28 | RUN echo -e "\n\n# Added during image build" >> /etc/dnf/dnf.conf && \ 29 | echo -e "minrate=100\ntimeout=60\n" >> /etc/dnf/dnf.conf 30 | 31 | # Don't include container-selinux and remove 32 | # directories used by dnf that are just taking 33 | # up space. 34 | # TODO: rpm --setcaps... needed due to Fedora (base) image builds 35 | # being (maybe still?) affected by 36 | # https://bugzilla.redhat.com/show_bug.cgi?id=1995337#c3 37 | RUN dnf -y update && \ 38 | rpm --setcaps shadow-utils 2>/dev/null && \ 39 | case "${FLAVOR}" in \ 40 | stable) \ 41 | dnf -y install skopeo fuse-overlayfs --exclude container-selinux \ 42 | ;; \ 43 | testing) \ 44 | dnf -y install skopeo fuse-overlayfs --exclude container-selinux \ 45 | --enablerepo updates-testing \ 46 | ;; \ 47 | upstream) \ 48 | dnf -y install 'dnf-command(copr)' --enablerepo=updates-testing && \ 49 | dnf -y copr enable rhcontainerbot/podman-next && \ 50 | dnf -y install skopeo fuse-overlayfs \ 51 | --exclude container-selinux \ 52 | --enablerepo=updates-testing \ 53 | ;; \ 54 | *) \ 55 | printf "\\nFLAVOR argument must be set and valid, currently: '${FLAVOR}'\\n\\n" 1>&2 && \ 56 | exit 1 \ 57 | ;; \ 58 | esac && \ 59 | dnf clean all && \ 60 | rm -rf /var/cache /var/log/dnf* /var/log/yum.* 61 | 62 | RUN useradd skopeo && \ 63 | echo skopeo:100000:65536 > /etc/subuid && \ 64 | echo skopeo:100000:65536 > /etc/subgid 65 | 66 | # Copy & modify the defaults to provide reference if runtime changes needed. 67 | # Changes here are required for running with fuse-overlay storage inside container. 68 | RUN sed -e 's|^#mount_program|mount_program|g' \ 69 | -e '/additionalimage.*/a "/var/lib/shared",' \ 70 | -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \ 71 | /usr/share/containers/storage.conf \ 72 | > /etc/containers/storage.conf 73 | 74 | # Setup the ability to use additional stores 75 | # with this container image. 76 | RUN mkdir -p /var/lib/shared/overlay-images \ 77 | /var/lib/shared/overlay-layers && \ 78 | touch /var/lib/shared/overlay-images/images.lock && \ 79 | touch /var/lib/shared/overlay-layers/layers.lock 80 | 81 | # Point to the Authorization file 82 | ENV REGISTRY_AUTH_FILE=/tmp/auth.json 83 | 84 | # Set the entrypoint 85 | ENTRYPOINT ["/usr/bin/skopeo"] 86 | -------------------------------------------------------------------------------- /skopeo/README.md: -------------------------------------------------------------------------------- 1 | [comment]: <> (***ATTENTION*** ***WARNING*** ***ALERT*** ***CAUTION*** ***DANGER***) 2 | [comment]: <> () 3 | [comment]: <> (ANY changes made below, once committed/merged must) 4 | [comment]: <> (be manually copy/pasted -in markdown- into the description) 5 | [comment]: <> (field on Quay at the following locations:) 6 | [comment]: <> () 7 | [comment]: <> (https://quay.io/repository/containers/skopeo) 8 | [comment]: <> (https://quay.io/repository/skopeo/stable) 9 | [comment]: <> (https://quay.io/repository/skopeo/testing) 10 | [comment]: <> (https://quay.io/repository/skopeo/upstream) 11 | [comment]: <> () 12 | [comment]: <> (***ATTENTION*** ***WARNING*** ***ALERT*** ***CAUTION*** ***DANGER***) 13 | 14 | 15 | 16 | # Skopeo Image 17 | 18 | ## Build information 19 | 20 | Please see the [containers/image_build repo. README.md for build 21 | details](https://github.com/containers/image_build/blob/main/README.md). 22 | 23 | ## Sample Usage 24 | 25 | Although not required, it is suggested that [Podman](https://github.com/containers/podman) be used with these container images. 26 | 27 | ``` 28 | # Get Help on Skopeo 29 | podman run docker://quay.io/skopeo/stable:latest --help 30 | 31 | # Get help on the Skopeo Copy command 32 | podman run docker://quay.io/skopeo/stable:latest copy --help 33 | 34 | # Copy the Skopeo container image from quay.io to 35 | # a private registry 36 | podman run docker://quay.io/skopeo/stable:latest copy docker://quay.io/skopeo/stable docker://registry.internal.company.com/skopeo 37 | 38 | # Inspect the fedora:latest image 39 | podman run docker://quay.io/skopeo/stable:latest inspect --config docker://registry.fedoraproject.org/fedora:latest | jq 40 | ``` 41 | 42 | ## Sample Usage with private registry 43 | 44 | 1. Assuming one isn't already defined, setup a Podman secret with the `auth.json` contents. 45 | Alternatively, see the [`containers-auth.json` man 46 | page](https://github.com/containers/image/blob/main/docs/containers-auth.json.5.md) 47 | for the file format. Regardless 48 | of how the file is created, using it as a Podman secret provides more protections than 49 | a simple bind-mount. 50 | 51 | ``` 52 | $ auth_tmp=$(mktemp) 53 | $ echo '{}' > $auth_tmp # JSON formating is required 54 | $ podman login --authfile=$auth_tmp example.com/registry 55 | $ podman secret create registry_name-auth $auth_tmp 56 | $ rm $auth_tmp 57 | ``` 58 | 59 | 2. Pass the Podman secret into the Skopeo container along with the intended Skopeo command. 60 | For example, to retrieve metadata for `example.com/registry/image_name:tag` run: 61 | 62 | ``` 63 | $ podman run --secret=registry_name-auth \ 64 | docker://quay.io/skopeo/stable:latest \ 65 | inspect --authfile=/run/secrets/registry_name_auth \ 66 | docker://example.com/registry/image_name:tag 67 | ``` 68 | 69 | ***NOTE:*** The `--authfile` argument must appear after the sub-command (i.e. `inspect` above) 70 | --------------------------------------------------------------------------------