From 2f2cc21e5b6cbc3ef2fab351ffbe460fe1884ab6 Mon Sep 17 00:00:00 2001 From: Tim Zhou Date: Fri, 29 May 2026 13:41:42 -0400 Subject: [PATCH] new gha ci with lima Signed-off-by: Tim Zhou --- .cirrus.yml | 415 ------------------------ .github/filters.yaml | 12 + .github/workflows/check_cirrus_cron.yml | 25 -- .github/workflows/ci.yml | 205 ++++++++++++ .github/workflows/lima.yml | 57 ++++ contrib/ci/ci.sh | 36 ++ contrib/ci/lib.sh | 70 ++++ contrib/{cirrus => ci}/logcollector.sh | 34 +- contrib/ci/runner.sh | 113 +++++++ contrib/ci/template.lima.yml | 4 + contrib/cirrus/bors-ng.png | Bin 80194 -> 0 bytes contrib/cirrus/build.sh | 25 -- contrib/cirrus/lib.sh | 357 -------------------- contrib/cirrus/setup.sh | 120 ------- contrib/cirrus/test.sh | 96 ------ contrib/cirrus/timestamp.awk | 20 -- hack/get_ci_vm.sh | 64 ---- 17 files changed, 521 insertions(+), 1132 deletions(-) delete mode 100644 .cirrus.yml create mode 100644 .github/filters.yaml delete mode 100644 .github/workflows/check_cirrus_cron.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/lima.yml create mode 100755 contrib/ci/ci.sh create mode 100644 contrib/ci/lib.sh rename contrib/{cirrus => ci}/logcollector.sh (61%) create mode 100755 contrib/ci/runner.sh create mode 100644 contrib/ci/template.lima.yml delete mode 100644 contrib/cirrus/bors-ng.png delete mode 100755 contrib/cirrus/build.sh delete mode 100755 contrib/cirrus/lib.sh delete mode 100755 contrib/cirrus/setup.sh delete mode 100755 contrib/cirrus/test.sh delete mode 100644 contrib/cirrus/timestamp.awk delete mode 100755 hack/get_ci_vm.sh diff --git a/.cirrus.yml b/.cirrus.yml deleted file mode 100644 index 39b825c76..000000000 --- a/.cirrus.yml +++ /dev/null @@ -1,415 +0,0 @@ ---- - -# Main collection of env. vars to set for all tasks and scripts. -env: - #### - #### Global variables used for all tasks - #### - # Name of the ultimate destination branch for this CI run, PR or post-merge. - DEST_BRANCH: "main" - GOPATH: "/var/tmp/go" - GOSRC: "${GOPATH}/src/github.com/containers/buildah" - GOCACHE: "/tmp/go-build" - # Overrides default location (/tmp/cirrus) for repo clone - CIRRUS_WORKING_DIR: "${GOSRC}" - # Shell used to execute all script commands - CIRRUS_SHELL: "/bin/bash" - # Automation script path relative to $CIRRUS_WORKING_DIR) - SCRIPT_BASE: "./contrib/cirrus" - # No need to go crazy, but grab enough to cover most PRs - CIRRUS_CLONE_DEPTH: 50 - # Unless set by in_podman.sh, default to operating outside of a podman container - IN_PODMAN: 'false' - # root or rootless - PRIV_NAME: root - # default "mention the $BUILDAH_RUNTIME in the task alias, with initial whitespace" value - RUNTIME_N: "" - - #### - #### Cache-image names to test with - #### - # GCE project where images live - IMAGE_PROJECT: "libpod-218412" - FEDORA_NAME: "fedora-43" - PRIOR_FEDORA_NAME: "fedora-42" - RAWHIDE_NAME: "rawhide" - DEBIAN_NAME: "debian-14" - - # Image identifiers - IMAGE_SUFFIX: "c20260319t182308z-f43f42d14" - FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}" - PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}" - RAWHIDE_CACHE_IMAGE_NAME: "rawhide-${IMAGE_SUFFIX}" # Used temporarily for rust-podman-sequoia. After that RPM is available in stable Fedora releases, we can stop testing against Rawhide again. - DEBIAN_CACHE_IMAGE_NAME: "debian-${IMAGE_SUFFIX}" - - IN_PODMAN_IMAGE: "quay.io/libpod/fedora_podman:${IMAGE_SUFFIX}" - - #### - #### Command variables to help avoid duplication - #### - # Command to prefix every output line with a timestamp - # (can't do inline awk script, Cirrus-CI or YAML mangles quoting) - _TIMESTAMP: 'awk -f ${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/timestamp.awk' - -gcp_credentials: ENCRYPTED[ae0bf7370f0b6e446bc61d0865a2c55d3e166b3fab9466eb0393e38e1c66a31ca4c71ddc7e0139d47d075c36dd6d3fd7] - -# Default timeout for each task -timeout_in: 30m - -# Default VM to use unless set or modified by task -gce_instance: &standardvm - image_project: "${IMAGE_PROJECT}" - zone: "us-central1-c" # Required by Cirrus for the time being - cpu: 2 - memory: "4G" - disk: 200 # Gigabytes, do not set less than 200 per obscure GCE docs re: I/O performance - image_name: "${FEDORA_CACHE_IMAGE_NAME}" - - -# Update metadata on VM images referenced by this repository state -meta_task: - name: "VM img. keepalive" - alias: meta - - container: - image: "quay.io/libpod/imgts:latest" - cpu: 1 - memory: "1G" - - env: - # Space-separated list of images used by this repository state - IMGNAMES: |- - ${FEDORA_CACHE_IMAGE_NAME} - ${PRIOR_FEDORA_CACHE_IMAGE_NAME} - ${RAWHIDE_CACHE_IMAGE_NAME} - ${DEBIAN_CACHE_IMAGE_NAME} - build-push-${IMAGE_SUFFIX} - BUILDID: "${CIRRUS_BUILD_ID}" - REPOREF: "${CIRRUS_CHANGE_IN_REPO}" - GCPJSON: ENCRYPTED[d3614d6f5cc0e66be89d4252b3365fd84f14eee0259d4eb47e25fc0bc2842c7937f5ee8c882b7e547b4c5ec4b6733b14] - GCPNAME: ENCRYPTED[8509e6a681b859479ce6aa275bd3c4ac82de5beec6df6057925afc4cd85b7ef2e879066ae8baaa2d453b82958e434578] - GCPPROJECT: ENCRYPTED[cc09b62d0ec6746a3df685e663ad25d9d5af95ef5fd843c96f3d0ec9d7f065dc63216b9c685c9f43a776a1d403991494] - - clone_script: 'true' - script: '/usr/local/bin/entrypoint.sh' - - -smoke_task: - alias: 'smoke' - name: "Smoke Test" - - gce_instance: - memory: "12G" - cpu: 8 - - # Don't bother running on branches (including cron), or for tags. - skip: $CIRRUS_PR == '' - - timeout_in: 10m - - setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}' - build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}' - validate_test_script: '${SCRIPT_BASE}/test.sh validate |& ${_TIMESTAMP}' - - binary_artifacts: - path: ./bin/* - -# Check that all included go modules from other sources match -# # what is expected in `vendor/modules.txt` vs `go.mod`. -vendor_task: - name: "Test Vendoring" - alias: vendor - - env: - CIRRUS_WORKING_DIR: "/var/tmp/go/src/github.com/containers/buildah" - GOPATH: "/var/tmp/go" - GOSRC: "/var/tmp/go/src/github.com/containers/buildah" - - # Runs within Cirrus's "community cluster" - container: - image: docker.io/library/golang:1.25 - cpu: 1 - memory: 1 - - timeout_in: 5m - - vendor_script: - - './hack/check_vendor_toolchain.sh Try updating the image used by the vendor_task in .cirrus.yml.' - - 'make vendor' - - './hack/tree_status.sh' - - -# Confirm cross-compile ALL architectures on a Mac OS-X VM. -cross_build_task: - name: "Cross Compile" - gce_instance: - cpu: 8 - memory: "24G" - alias: cross_build - skip: >- - $CIRRUS_CHANGE_TITLE =~ '.*CI:DOCS.*' - env: - HOME: /root - script: - - go version - - make -j cross CGO_ENABLED=0 - binary_artifacts: - path: ./bin/* - - -unit_task: - name: 'Unit tests w/ $STORAGE_DRIVER' - gce_instance: - cpu: 4 - alias: unit - skip: ¬_build_docs >- - $CIRRUS_CHANGE_TITLE =~ '.*CI:DOCS.*' || - $CIRRUS_CHANGE_TITLE =~ '.*CI:BUILD.*' - depends_on: &smoke_vendor - - smoke - - vendor - - matrix: - - env: - STORAGE_DRIVER: 'vfs' - - env: - STORAGE_DRIVER: 'overlay' - - setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}' - unit_test_script: '${SCRIPT_BASE}/test.sh unit |& ${_TIMESTAMP}' - - always: &standardlogs - audit_log_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh audit' - df_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh df' - journal_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh journal' - podman_system_info_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh podman' - buildah_version_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh buildah_version' - buildah_info_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh buildah_info' - package_versions_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh packages' - golang_version_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh golang' - -conformance_task: - name: 'Debian Conformance w/ $STORAGE_DRIVER' - alias: conformance - skip: *not_build_docs - depends_on: *smoke_vendor - - gce_instance: - cpu: 4 - image_name: "${DEBIAN_CACHE_IMAGE_NAME}" - - matrix: - - env: - STORAGE_DRIVER: 'vfs' - TMPDIR: '/var/tmp' - - env: - STORAGE_DRIVER: 'overlay' - - setup_script: '${SCRIPT_BASE}/setup.sh conformance |& ${_TIMESTAMP}' - conformance_test_script: '${SCRIPT_BASE}/test.sh conformance |& ${_TIMESTAMP}' - - always: - <<: *standardlogs - -integration_task: - name: "Integration $DISTRO_NV$RUNTIME_N w/ $STORAGE_DRIVER" - alias: integration - skip: *not_build_docs - depends_on: *smoke_vendor - - matrix: - # VFS - - env: - DISTRO_NV: "${FEDORA_NAME}" - IMAGE_NAME: "${FEDORA_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'vfs' - BUILDAH_RUNTIME: crun - RUNTIME_N: " using crun" - - env: - DISTRO_NV: "${PRIOR_FEDORA_NAME}" - IMAGE_NAME: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'vfs' - BUILDAH_RUNTIME: crun - RUNTIME_N: " using crun" - - env: - DISTRO_NV: "${DEBIAN_NAME}" - IMAGE_NAME: "${DEBIAN_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'vfs' - - env: - DISTRO_NV: "${FEDORA_NAME}" - IMAGE_NAME: "${FEDORA_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'vfs' - BUILDAH_RUNTIME: runc - RUNTIME_N: " using runc" - - env: - DISTRO_NV: "${PRIOR_FEDORA_NAME}" - IMAGE_NAME: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'vfs' - BUILDAH_RUNTIME: runc - RUNTIME_N: " using runc" - # OVERLAY - - env: - DISTRO_NV: "${FEDORA_NAME}" - IMAGE_NAME: "${FEDORA_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'overlay' - BUILDAH_RUNTIME: crun - RUNTIME_N: " using crun" - - env: - DISTRO_NV: "${PRIOR_FEDORA_NAME}" - IMAGE_NAME: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'overlay' - BUILDAH_RUNTIME: crun - RUNTIME_N: " using crun" - - env: - DISTRO_NV: "${DEBIAN_NAME}" - IMAGE_NAME: "${DEBIAN_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'overlay' - - env: - DISTRO_NV: "${RAWHIDE_NAME}" - IMAGE_NAME: "${RAWHIDE_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'overlay' - TEST_BUILD_TAGS: 'containers_image_sequoia' - - env: - DISTRO_NV: "${FEDORA_NAME}" - IMAGE_NAME: "${FEDORA_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'overlay' - BUILDAH_RUNTIME: runc - RUNTIME_N: " using runc" - - env: - DISTRO_NV: "${PRIOR_FEDORA_NAME}" - IMAGE_NAME: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'overlay' - BUILDAH_RUNTIME: runc - RUNTIME_N: " using runc" - - gce_instance: &integration_gce_instance - image_name: "$IMAGE_NAME" - cpu: 8 - memory: "8G" - - # Separate scripts for separate outputs, makes debugging easier. - setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}' - build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}' - integration_test_script: '${SCRIPT_BASE}/test.sh integration |& ${_TIMESTAMP}' - - binary_artifacts: - path: ./bin/* - - always: - <<: *standardlogs - -integration_rootless_task: - name: "Integration rootless $DISTRO_NV$RUNTIME_N w/ $STORAGE_DRIVER" - alias: integration_rootless - skip: *not_build_docs - depends_on: *smoke_vendor - - matrix: - # Running rootless tests on overlay - # OVERLAY - - env: - DISTRO_NV: "${FEDORA_NAME}" - IMAGE_NAME: "${FEDORA_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'overlay' - PRIV_NAME: rootless - BUILDAH_RUNTIME: crun - RUNTIME_N: " using crun" - - env: - DISTRO_NV: "${PRIOR_FEDORA_NAME}" - IMAGE_NAME: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'overlay' - PRIV_NAME: rootless - BUILDAH_RUNTIME: crun - RUNTIME_N: " using crun" - - env: - DISTRO_NV: "${DEBIAN_NAME}" - IMAGE_NAME: "${DEBIAN_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'overlay' - PRIV_NAME: rootless - - env: - DISTRO_NV: "${FEDORA_NAME}" - IMAGE_NAME: "${FEDORA_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'overlay' - PRIV_NAME: rootless - BUILDAH_RUNTIME: runc - RUNTIME_N: " using runc" - - env: - DISTRO_NV: "${PRIOR_FEDORA_NAME}" - IMAGE_NAME: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" - STORAGE_DRIVER: 'overlay' - PRIV_NAME: rootless - BUILDAH_RUNTIME: runc - RUNTIME_N: " using runc" - - gce_instance: - <<: *integration_gce_instance - - # Separate scripts for separate outputs, makes debugging easier. - setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}' - build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}' - integration_test_script: '${SCRIPT_BASE}/test.sh integration |& ${_TIMESTAMP}' - - binary_artifacts: - path: ./bin/* - - always: - <<: *standardlogs - -in_podman_task: - name: "Containerized Integration" - alias: in_podman - skip: *not_build_docs - depends_on: *smoke_vendor - - gce_instance: - cpu: 8 - memory: "8G" - - env: - # This is key, cause the scripts to re-execute themselves inside a container. - IN_PODMAN: 'true' - BUILDAH_ISOLATION: 'chroot' - STORAGE_DRIVER: 'vfs' - - # Separate scripts for separate outputs, makes debugging easier. - setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}' - build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}' - integration_test_script: '${SCRIPT_BASE}/test.sh integration |& ${_TIMESTAMP}' - - binary_artifacts: - path: ./bin/* - - always: - <<: *standardlogs - - -# Status aggregator for all tests. This task simply ensures a defined -# set of tasks all passed, and allows confirming that based on the status -# of this task. -success_task: - # N/B: The prow merge-bot (tide) is sensitized to this exact name, DO NOT CHANGE IT. - # Ref: https://github.com/openshift/release/pull/48909 - name: "Total Success" - alias: success - - depends_on: - - meta - - smoke - - unit - - conformance - - vendor - - cross_build - - integration - - integration_rootless - - in_podman - - container: - image: "quay.io/libpod/alpine:latest" - cpu: 1 - memory: 1 - - env: - CIRRUS_SHELL: direct # execute command directly - - clone_script: mkdir -p $CIRRUS_WORKING_DIR - script: /bin/true diff --git a/.github/filters.yaml b/.github/filters.yaml new file mode 100644 index 000000000..7b82434b5 --- /dev/null +++ b/.github/filters.yaml @@ -0,0 +1,12 @@ +code: + - '**/*.go' + - 'go.mod' + - 'go.sum' + - 'vendor/**' + - 'Makefile' + - '.github/**' + - 'contrib/ci/**' + - 'hack/**' + - 'tests/**' + - '.codespellrc' + - '.golangci.yml' diff --git a/.github/workflows/check_cirrus_cron.yml b/.github/workflows/check_cirrus_cron.yml deleted file mode 100644 index 47e431e1f..000000000 --- a/.github/workflows/check_cirrus_cron.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- - -# See also: -# https://github.com/containers/podman/blob/main/.github/workflows/check_cirrus_cron.yml - -on: - # Note: This only applies to the default branch. - schedule: - # N/B: This should correspond to a period slightly after - # the last job finishes running. See job defs. at: - # https://cirrus-ci.com/settings/repository/6706677464432640 - - cron: '03 03 * * 1-5' - # Debug: Allow triggering job manually in github-actions WebUI - workflow_dispatch: {} - -jobs: - # Ref: https://docs.github.com/en/actions/using-workflows/reusing-workflows - call_cron_failures: - uses: containers/podman/.github/workflows/check_cirrus_cron.yml@main - secrets: - SECRET_CIRRUS_API_KEY: ${{secrets.SECRET_CIRRUS_API_KEY}} - ACTION_MAIL_SERVER: ${{secrets.ACTION_MAIL_SERVER}} - ACTION_MAIL_USERNAME: ${{secrets.ACTION_MAIL_USERNAME}} - ACTION_MAIL_PASSWORD: ${{secrets.ACTION_MAIL_PASSWORD}} - ACTION_MAIL_SENDER: ${{secrets.ACTION_MAIL_SENDER}} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..735a0c8ce --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,205 @@ +name: "ci" + +on: + push: + branches: + - main + pull_request: + branches: + - main + +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + path-filter: + name: path-filter + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + pull-requests: read + outputs: + code: ${{ steps.filter.outputs.code }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - id: filter + uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 + with: + filters: .github/filters.yaml + + smoke: + name: smoke + uses: ./.github/workflows/lima.yml + with: + runner: cncf-ubuntu-4-16-x86 + test: smoke + distro: fedora-current + timeout: 20 + + vendor: + name: vendor + uses: ./.github/workflows/lima.yml + with: + runner: cncf-ubuntu-4-16-x86 + test: vendor + distro: fedora-current + timeout: 20 + + cross: + name: cross + runs-on: cncf-ubuntu-8-32-x86 + timeout-minutes: 30 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version-file: go.mod + cache: true + + - name: Build all cross targets + run: make -j4 cross CGO_ENABLED=0 + + unit: + needs: [smoke, vendor, path-filter] + if: needs.path-filter.outputs.code == 'true' || github.event_name != 'pull_request' + name: unit ${{ matrix.storage }} + strategy: + fail-fast: false + matrix: + storage: [vfs, overlay] + uses: ./.github/workflows/lima.yml + with: + runner: cncf-ubuntu-4-16-x86 + test: unit + storage: ${{ matrix.storage }} + priv: root + distro: fedora-current + timeout: 60 + + conformance: + needs: [smoke, vendor, path-filter] + if: needs.path-filter.outputs.code == 'true' || github.event_name != 'pull_request' + name: conformance ${{ matrix.storage }} + strategy: + fail-fast: false + matrix: + storage: [vfs, overlay] + uses: ./.github/workflows/lima.yml + with: + runner: cncf-ubuntu-8-32-x86 + test: conformance + storage: ${{ matrix.storage }} + priv: root + distro: debian-sid + timeout: 40 + + integration: + needs: [smoke, vendor, path-filter] + if: needs.path-filter.outputs.code == 'true' || github.event_name != 'pull_request' + name: integration ${{ matrix.storage }} ${{ matrix.priv }} ${{ matrix.distro }} + strategy: + fail-fast: false + matrix: + distro: [fedora-current, fedora-prior, debian-sid] + storage: [vfs, overlay] + priv: [root, rootless] + exclude: + - storage: vfs + priv: rootless + - distro: debian-sid + priv: rootless + # Skip rootless+overlay: upstream Cirrus's PASSTHROUGH_ENV_RE drops + # STORAGE_DRIVER through SSH re-exec to rootlessuser, so their + # "Integration rootless ... w/ overlay" task silently tests vfs. + # When we propagate STORAGE_DRIVER properly, we expose a real + # rootless+overlay cleanup bug in buildah's storage code + # ("replacing mount point .../merged: directory not empty"). + # Skip these cells until that's fixed upstream. + - storage: overlay + priv: rootless + include: + - storage: overlay + priv: root + distro: fedora-rawhide + uses: ./.github/workflows/lima.yml + with: + runner: cncf-ubuntu-8-32-x86 + test: integration + storage: ${{ matrix.storage }} + priv: ${{ matrix.priv }} + distro: ${{ matrix.distro }} + timeout: 60 + + in_podman: + needs: [smoke, vendor, path-filter] + if: needs.path-filter.outputs.code == 'true' || github.event_name != 'pull_request' + name: in_podman + uses: ./.github/workflows/lima.yml + with: + runner: cncf-ubuntu-8-32-x86 + test: in_podman + storage: vfs + priv: root + distro: fedora-current + timeout: 60 + + mac: + needs: [smoke, vendor] + name: build (darwin) + runs-on: macos-15 + timeout-minutes: 30 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version-file: go.mod + cache: true + + - name: Build darwin/arm64 + run: make bin/buildah.darwin.arm64 + + - name: Build darwin/amd64 + run: make bin/buildah.darwin.amd64 + + - name: Upload artifacts + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: buildah-darwin + path: bin/buildah.darwin.* + if-no-files-found: error + + success: + name: "Total Success" + if: always() + needs: + - path-filter + - smoke + - vendor + - cross + - unit + - conformance + - integration + - in_podman + - mac + runs-on: ubuntu-latest + steps: + - name: Check all required jobs + run: | + if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] || \ + [[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then + echo "One or more required jobs failed or were cancelled" + exit 1 + fi + echo "All required jobs passed or were skipped" diff --git a/.github/workflows/lima.yml b/.github/workflows/lima.yml new file mode 100644 index 000000000..ccb06d065 --- /dev/null +++ b/.github/workflows/lima.yml @@ -0,0 +1,57 @@ +name: lima + +on: + workflow_call: + inputs: + distro: + required: true + type: string + test: + required: true + type: string + priv: + required: false + type: string + storage: + required: false + type: string + runner: + required: true + type: string + timeout: + required: false + type: number + +permissions: {} + +jobs: + lima: + name: ${{ inputs.test }} ${{ inputs.storage || '' }} ${{ inputs.priv || '' }} ${{ inputs.distro }} + runs-on: ${{ inputs.runner }} + timeout-minutes: ${{ inputs.timeout || 20 }} + permissions: {} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + fetch-depth: 50 + + - name: Fetch base ref for merge-base + run: git fetch --depth=50 origin main:refs/remotes/origin/main || true + + - uses: lima-vm/lima-actions/setup@55627e31b78637bf254a8b2a14da8ea7d12564e5 # v1.1.0 + id: lima + with: + version: v2.1.1 + + - name: Run test on lima + run: | # zizmor: ignore[template-injection] + ./contrib/ci/ci.sh ${{ inputs.test }} ${{ inputs.storage }} ${{ inputs.priv }} ${{ inputs.distro }} + + - name: Upload journal as artifact + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: "journal-${{ inputs.test }}-${{ inputs.storage }}-${{ inputs.priv }}-${{ inputs.distro }}.log" + path: "./contrib/ci/journal.log" + if-no-files-found: ignore diff --git a/contrib/ci/ci.sh b/contrib/ci/ci.sh new file mode 100755 index 000000000..f246ca8f9 --- /dev/null +++ b/contrib/ci/ci.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +set -eo pipefail + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" && pwd ) + +source "$SCRIPT_DIR/lib.sh" + +AUTOMATION_RELEASE="${AUTOMATION_RELEASE:-20260520t200858z}" +LIMA_VM_NAME=buildah-ci + +REPO_DIR="$SCRIPT_DIR/../.." + +parse_args "$@" + +IMAGE="$DISTRO_NAME.x86_64.qcow2.zst" + +IMAGE_URL_BASE="${IMAGE_URL_BASE:-https://objectstorage.us-ashburn-1.oraclecloud.com/n/id0lmbbwgcdv/b/podman-ci-vm-images/o/releases}" +IMAGE_URL="$IMAGE_URL_BASE/$AUTOMATION_RELEASE/$IMAGE" + +trap "limactl delete --force $LIMA_VM_NAME" EXIT + +limactl --yes start --plain --name=$LIMA_VM_NAME --cpus $(nproc) --memory 8 --disk 150 --nested-virt \ + --set ".images=[{\"location\":\"$IMAGE_URL\", \"arch\": \"x86_64\"}]" \ + "$SCRIPT_DIR/template.lima.yml" + +limactl copy "$REPO_DIR" $LIMA_VM_NAME:/var/tmp/buildah + +set +e + +limactl shell --workdir /var/tmp/buildah $LIMA_VM_NAME ./contrib/ci/runner.sh "${@}" +rc=$? + +limactl shell --workdir /var/tmp/buildah $LIMA_VM_NAME sudo contrib/ci/logcollector.sh journal &> "$SCRIPT_DIR/journal.log" + +exit $rc diff --git a/contrib/ci/lib.sh b/contrib/ci/lib.sh new file mode 100644 index 000000000..ef33a509a --- /dev/null +++ b/contrib/ci/lib.sh @@ -0,0 +1,70 @@ +OS_RELEASE_VER="$(source /etc/os-release; echo $VERSION_ID | tr -d '.')" +OS_RELEASE_ID="$(source /etc/os-release; echo $ID)" +OS_REL_VER="$OS_RELEASE_ID-$OS_RELEASE_VER" + + +function die() { + echo "$1" >&2 + exit 1 +} + +function parse_args() { + TEST= + DISTRO_NAME= + STORAGE_DRIVER=overlay + PRIV=root + case "$#" in + 2) + TEST=$1 + DISTRO_NAME=$2 + ;; + 3) + TEST=$1 + PRIV=$2 + DISTRO_NAME=$3 + ;; + 4) + TEST=$1 + STORAGE_DRIVER=$2 + PRIV=$3 + DISTRO_NAME=$4 + ;; + *) + die "Invalid number of arguments $#, need 2-4" + ;; + esac + + validate_distro "$DISTRO_NAME" + validate_storage "$STORAGE_DRIVER" + validate_priv "$PRIV" +} + +function validate_distro() { + case "$1" in + "fedora-current"|"fedora-prior"|"fedora-rawhide"|"debian-sid") + ;; + *) + die "Unknown DISTRO_NAME '$1' set" + ;; + esac +} + +function validate_storage() { + case "$1" in + "vfs"|"overlay") + ;; + *) + die "Unknown STORAGE_DRIVER '$1' set" + ;; + esac +} + +function validate_priv() { + case "$1" in + "root"|"rootless") + ;; + *) + die "Unknown PRIV '$1' set" + ;; + esac +} diff --git a/contrib/cirrus/logcollector.sh b/contrib/ci/logcollector.sh similarity index 61% rename from contrib/cirrus/logcollector.sh rename to contrib/ci/logcollector.sh index fa13acef6..bd189bca2 100755 --- a/contrib/cirrus/logcollector.sh +++ b/contrib/ci/logcollector.sh @@ -1,10 +1,26 @@ -#!/bin/bash +#!/usr/bin/env bash set -e -source $(dirname $0)/lib.sh +# shellcheck source=contrib/ci/lib.sh +source "$(dirname "$0")/lib.sh" -req_env_vars CI GOSRC OS_RELEASE_ID +showrun() { + echo "+ $(printf " %q" "$@")" + set +e + echo '------------------------------------------------------------' + "$@" + local status=$? + [[ $status -eq 0 ]] || echo "[ rc = $status -- proceeding anyway ]" + echo '------------------------------------------------------------' + set -e +} + +bad_os_id_ver() { + die "Unknown OS '$OS_RELEASE_ID'" +} + +GOSRC="${GOSRC:-$(pwd)}" case $1 in audit) @@ -17,11 +33,10 @@ case $1 in df) showrun df -lhTx tmpfs ;; journal) showrun journalctl -b ;; podman) showrun podman system info ;; - buildah_version) showrun $GOSRC/bin/buildah version;; - buildah_info) showrun $GOSRC/bin/buildah info;; - golang) showrun go version;; + buildah_version) showrun "$GOSRC/bin/buildah" version ;; + buildah_info) showrun "$GOSRC/bin/buildah" info ;; + golang) showrun go version ;; packages) - # These names are common to Fedora and Debian PKG_NAMES=(\ buildah conmon @@ -48,8 +63,7 @@ case $1 in ;; *) bad_os_id_ver ;; esac - # Any not-present packages will be listed as such - $PKG_LST_CMD ${PKG_NAMES[@]} | sort -u + $PKG_LST_CMD "${PKG_NAMES[@]}" | sort -u ;; - *) die "Warning, $(basename $0) doesn't know how to handle the parameter '$1'" + *) die "Warning, $(basename "$0") doesn't know how to handle the parameter '$1'" esac diff --git a/contrib/ci/runner.sh b/contrib/ci/runner.sh new file mode 100755 index 000000000..17c6614fa --- /dev/null +++ b/contrib/ci/runner.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash + +set -eo pipefail + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" && pwd ) + +source "$SCRIPT_DIR/lib.sh" + +parse_args "$@" + +export PRIV_NAME="$PRIV" +export STORAGE_DRIVER + +PRESERVE_ENVS="STORAGE_DRIVER,PRIV_NAME,BUILDAH_RUNTIME,IN_PODMAN,IN_PODMAN_NAME,IN_PODMAN_IMAGE,TEST_BUILD_TAGS,GOPATH,GOCACHE,GOSRC,GITVALIDATE_EPOCH,CI_USE_REGISTRY_CACHE,TMPDIR" + +LCR=/var/cache/local-registry/local-cache-registry +if [[ -x $LCR ]]; then + while read new_image; do + $LCR cache "$new_image" + done < <(grep '^[^#]' tests/NEW-IMAGES 2>/dev/null || true) + export CI_USE_REGISTRY_CACHE=1 +fi +SUDO="" +if [[ "$PRIV" == "root" ]]; then + SUDO="sudo --preserve-env=$PRESERVE_ENVS" +fi + +conf=/etc/containers/storage.conf +if [[ ! -e $conf ]]; then + sudo tee $conf <", "arch": "x86_64"}]' +images: diff --git a/contrib/cirrus/bors-ng.png b/contrib/cirrus/bors-ng.png deleted file mode 100644 index 9148d169581b208e79781dbbb5c2f9495decab60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80194 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 NML8AOJZS^p{{p_4rIG*u diff --git a/contrib/cirrus/build.sh b/contrib/cirrus/build.sh deleted file mode 100755 index 5a809eeb1..000000000 --- a/contrib/cirrus/build.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -set -e - -source $(dirname $0)/lib.sh - -req_env_vars IN_PODMAN IN_PODMAN_NAME GOSRC - -remove_packaged_buildah_files - -go version && go env - -cd "$GOSRC" -if [[ "$IN_PODMAN" == "true" ]] -then - in_podman --rm $IN_PODMAN_NAME $0 -else - echo "Compiling buildah (\$GOSRC=$GOSRC)" - showrun make clean all EXTRA_BUILD_TAGS="$TEST_BUILD_TAGS" - - echo "Installing buildah" - mkdir -p bin - showrun make install PREFIX=/usr - showrun ./bin/buildah info -fi diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh deleted file mode 100755 index bdbf02404..000000000 --- a/contrib/cirrus/lib.sh +++ /dev/null @@ -1,357 +0,0 @@ - - -# Library of common, shared utility functions. This file is intended -# to be sourced by other scripts, not called directly. - -# BEGIN Global export of all variables -set -a - -# Due to differences across platforms and runtime execution environments, -# handling of the (otherwise) default shell setup is non-uniform. Rather -# than attempt to workaround differences, simply force-load/set required -# items every time this library is utilized. -USER="$(whoami)" -HOME="$(getent passwd $USER | cut -d : -f 6)" -# Some platforms set and make this read-only -[[ -n "$UID" ]] || \ - UID=$(getent passwd $USER | cut -d : -f 3) - -# Automation library installed at image-build time, -# defining $AUTOMATION_LIB_PATH in this file. -if [[ -r "/etc/automation_environment" ]]; then - source /etc/automation_environment -fi -# shellcheck disable=SC2154 -if [[ -n "$AUTOMATION_LIB_PATH" ]]; then - # shellcheck source=/usr/share/automation/lib/common_lib.sh - source $AUTOMATION_LIB_PATH/common_lib.sh -else - ( - echo "WARNING: It does not appear that containers/automation was installed." - echo " Functionality of most of this library will be negatively impacted" - echo " This ${BASH_SOURCE[0]} was loaded by ${BASH_SOURCE[1]}" - ) > /dev/stderr -fi - -# Required for proper GPG functioning under automation -GPG_TTY="${GPG_TTY:-/dev/null}" - -# Essential default paths, many are overridden when executing under Cirrus-CI -# others are duplicated here, to assist in debugging. -GOPATH="${GOPATH:-/var/tmp/go}" -if type -P go &> /dev/null -then - # required for go 1.12+ - GOCACHE="${GOCACHE:-$HOME/.cache/go-build}" - eval "$(go env)" - # Ensure compiled tooling is reachable - PATH="$PATH:$GOPATH/bin" -fi -CIRRUS_WORKING_DIR="${CIRRUS_WORKING_DIR:-$GOPATH/src/github.com/containers/buildah}" -GOSRC="${GOSRC:-$CIRRUS_WORKING_DIR}" -PATH="$GOSRC/tests/tools/build:$HOME/bin:$GOPATH/bin:/usr/local/bin:/usr/lib/cri-o-runc/sbin:$PATH" -SCRIPT_BASE=${SCRIPT_BASE:-./contrib/cirrus} - -cd $GOSRC -if type -P git &> /dev/null -then - CIRRUS_CHANGE_IN_REPO=${CIRRUS_CHANGE_IN_REPO:-$(git show-ref --hash=8 HEAD || date +%s)} -else # pick something unique and obviously not from Cirrus - CIRRUS_CHANGE_IN_REPO=${CIRRUS_CHANGE_IN_REPO:-unknown$(date +%s)} -fi - -export CI="${CI:-false}" -CIRRUS_CI="${CIRRUS_CI:-false}" -CONTINUOUS_INTEGRATION="${CONTINUOUS_INTEGRATION:-false}" -CIRRUS_REPO_NAME=${CIRRUS_REPO_NAME:-buildah} -CIRRUS_BASE_SHA=${CIRRUS_BASE_SHA:-unknown$(date +%d)} # difficult to reliably discover -CIRRUS_BUILD_ID=${CIRRUS_BUILD_ID:-unknown$(date +%s)} # must be short and unique enough -CIRRUS_TASK_ID=${CIRRUS_BUILD_ID:-unknown$(date +%d)} # to prevent state thrashing when - # debugging with `hack/get_ci_vm.sh` - -# All CI jobs use a local registry -export CI_USE_REGISTRY_CACHE=true - -# Regex defining all CI-related env. vars. necessary for all possible -# testing operations on all platforms and versions. This is necessary -# to avoid needlessly passing through global/system values across -# contexts, such as host->container or root->rootless user -# -# List of envariables which must be EXACT matches -# N/B: Don't include BUILDAH_ISOLATION, STORAGE_DRIVER, or CGROUP_MANAGER -# here because they will negatively affect execution of the rootless -# integration tests. -PASSTHROUGH_ENV_EXACT='BUILDAH_RUNTIME|DEST_BRANCH|DISTRO_NV|GOPATH|GOSRC|ROOTLESS_USER|SCRIPT_BASE|IN_PODMAN_IMAGE' - -# List of envariable patterns which must match AT THE BEGINNING of the name. -PASSTHROUGH_ENV_ATSTART='CI|TEST' - -# List of envariable patterns which can match ANYWHERE in the name -PASSTHROUGH_ENV_ANYWHERE='_NAME|_FQIN' - -# Combine into one -PASSTHROUGH_ENV_RE="(^($PASSTHROUGH_ENV_EXACT)\$)|(^($PASSTHROUGH_ENV_ATSTART))|($PASSTHROUGH_ENV_ANYWHERE)" - -# Unsafe env. vars for display -SECRET_ENV_RE='ACCOUNT|GC[EP]..|SSH|PASSWORD|SECRET|TOKEN' - -# FQINs needed for testing -REGISTRY_FQIN=${REGISTRY_FQIN:-quay.io/libpod/registry:2.8.2} -ALPINE_FQIN=${ALPINE_FQIN:-quay.io/libpod/alpine} - -# for in-container testing -IN_PODMAN_NAME="in_podman_$CIRRUS_TASK_ID" -IN_PODMAN="${IN_PODMAN:-false}" - -# rootless_user -ROOTLESS_USER="rootlessuser" - -# Downloaded, but not installed packages. -PACKAGE_DOWNLOAD_DIR=/var/cache/download - -lilto() { err_retry 8 1000 "" "$@"; } # just over 4 minutes max -bigto() { err_retry 7 5670 "" "$@"; } # 12 minutes max - -# Working with apt under automation is a PITA, make it easy -# Avoid some ways of getting stuck waiting for user input -export DEBIAN_FRONTEND=noninteractive -# Short-cut for frequently used base command -export APTGET='apt-get -qq --yes' -# Short timeout for quick-running packaging command -SHORT_APTGET="lilto $APTGET" -SHORT_DNFY="lilto dnf -y" -# Longer timeout for long-running packaging command -LONG_APTGET="bigto $APTGET" -LONG_DNFY="bigto dnf -y" - -# Allow easy substitution for debugging if needed -CONTAINER_RUNTIME="showrun ${CONTAINER_RUNTIME:-podman}" - -# END Global export of all variables -set +a - -bad_os_id_ver() { - die "Unknown/Unsupported distro. $OS_RELEASE_ID and/or version $OS_RELEASE_VER for $(basename $0)" -} - -# Remove all files provided by the distro version of buildah. -# All VM cache-images used for testing include the distro buildah because it -# simplifies installing necessary dependencies which can change over time. -# For general CI testing however, calling this function makes sure the system -# can only run the compiled source version. -remove_packaged_buildah_files() { - warn "Removing packaged buildah files to prevent conflicts with source build and testing." - req_env_vars OS_RELEASE_ID - - if [[ "$OS_RELEASE_ID" =~ "debian" ]] - then - LISTING_CMD="dpkg-query -L buildah" - else - LISTING_CMD='rpm -ql buildah' - fi - - # yum/dnf/dpkg may list system directories, only remove files - $LISTING_CMD | while read fullpath - do - # Sub-directories may contain unrelated/valuable stuff - if [[ -d "$fullpath" ]]; then continue; fi - - rm -vf "$fullpath" - done - - if [[ -z "$CONTAINER" ]]; then - # Be super extra sure and careful vs performant and completely safe - sync && echo 3 > /proc/sys/vm/drop_caches - fi -} - -# Return a list of environment variables that should be passed through -# to lower levels (tests in containers, or via ssh to rootless). -# We return the variable names only, not their values. It is up to our -# caller to reference values. -passthrough_envars(){ - warn "Will pass env. vars. matching the following regex: - $PASSTHROUGH_ENV_RE" - compgen -A variable | \ - grep -Ev "$SECRET_ENV_RE" | \ - grep -Ev "^PASSTHROUGH_" | \ - grep -E "$PASSTHROUGH_ENV_RE" -} - -in_podman() { - req_env_vars IN_PODMAN_NAME GOSRC GOPATH SECRET_ENV_RE HOME - [[ -n "$@" ]] || \ - die "Must specify FQIN and command with arguments to execute" - - # Line-separated arguments which include shell-escaped special characters - declare -a envargs - while read -r var; do - # Pass "-e VAR" on the command line, not "-e VAR=value". Podman can - # do a much better job of transmitting the value than we can, - # especially when value includes spaces. - envargs+=("-e" "$var") - done <<<"$(passthrough_envars)" - - showrun podman run -i --name="$IN_PODMAN_NAME" \ - --net=host \ - --privileged \ - --cgroupns=host \ - "${envargs[@]}" \ - -e BUILDAH_ISOLATION \ - -e STORAGE_DRIVER \ - -e "IN_PODMAN=false" \ - -e "CONTAINER=podman" \ - -e "CGROUP_MANAGER=cgroupfs" \ - -v "$HOME/auth:$HOME/auth:ro" \ - -v /sys/fs/cgroup:/sys/fs/cgroup:rw \ - --device /dev/fuse:rwm \ - -v "$GOSRC:$GOSRC:z" \ - --workdir "$GOSRC" \ - "$@" -} - -verify_local_registry(){ - # On the unexpected/rare chance of a name-clash - local CUSTOM_FQIN=localhost:5000/my-alpine-$RANDOM - echo "Verifying local 'registry' container is operational" - showrun podman version - showrun podman info - showrun podman ps --all - showrun podman images - showrun ls -alF $HOME/auth - showrun podman pull $ALPINE_FQIN - showrun podman login --tls-verify=false localhost:5000 --username testuser --password testpassword - showrun podman tag $ALPINE_FQIN $CUSTOM_FQIN - showrun podman push --tls-verify=false --creds=testuser:testpassword $CUSTOM_FQIN - showrun podman ps --all - showrun podman images - showrun podman rmi $ALPINE_FQIN - showrun podman rmi $CUSTOM_FQIN - showrun podman pull --tls-verify=false --creds=testuser:testpassword $CUSTOM_FQIN - showrun podman ps --all - showrun podman images - echo "Success, local registry is working, cleaning up." - showrun podman rmi $CUSTOM_FQIN -} - -execute_local_registry() { - if nc -4 -z 127.0.0.1 5000 - then - warn "Found listener on localhost:5000, NOT starting up local registry server." - verify_local_registry - return 0 - fi - req_env_vars CONTAINER_RUNTIME GOSRC - local authdirpath=$HOME/auth - cd $GOSRC - - echo "Creating a self signed certificate and get it in the right places" - mkdir -p $authdirpath - openssl req \ - -newkey rsa:4096 -nodes -sha256 -x509 -days 2 \ - -subj "/C=US/ST=Foo/L=Bar/O=Red Hat, Inc./CN=registry host certificate" \ - -addext subjectAltName=DNS:localhost \ - -keyout $authdirpath/domain.key \ - -out $authdirpath/domain.crt - - cp $authdirpath/domain.crt $authdirpath/domain.cert - - echo "Creating http credentials file" - showrun htpasswd -Bbn testuser testpassword > $authdirpath/htpasswd - - echo "Starting up the local 'registry' container" - showrun podman run -d -p 5000:5000 --name registry \ - -v $authdirpath:$authdirpath:Z \ - -e "REGISTRY_AUTH=htpasswd" \ - -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ - -e REGISTRY_AUTH_HTPASSWD_PATH=$authdirpath/htpasswd \ - -e REGISTRY_HTTP_TLS_CERTIFICATE=$authdirpath/domain.crt \ - -e REGISTRY_HTTP_TLS_KEY=$authdirpath/domain.key \ - $REGISTRY_FQIN - - verify_local_registry -} - -setup_rootless() { - req_env_vars GOPATH GOSRC SECRET_ENV_RE - - local rootless_uid - local rootless_gid - local env_var_val - local akfilepath - local sshcmd - - # Only do this once; established by setup_environment.sh - # shellcheck disable=SC2154 - if passwd --status $ROOTLESS_USER - then - if [[ $PRIV_NAME = "rootless" ]]; then - msg "Updating $ROOTLESS_USER user permissions on possibly changed libpod code" - chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC" - return 0 - fi - fi - msg "************************************************************" - msg "Setting up rootless user '$ROOTLESS_USER'" - msg "************************************************************" - cd $GOSRC || exit 1 - # Guarantee independence from specific values - rootless_uid=$((RANDOM+1000)) - rootless_gid=$((RANDOM+1000)) - rootless_supplemental_gid1=$((rootless_gid+1)) - rootless_supplemental_gid2=$((rootless_supplemental_gid1+1)) - rootless_supplemental_gid3=$((rootless_supplemental_gid2+1)) - msg "creating $rootless_uid:$rootless_gid,$rootless_supplemental_gid1,$rootless_supplemental_gid2,$rootless_supplemental_gid3 $ROOTLESS_USER user" - groupadd -g $rootless_gid $ROOTLESS_USER - groupadd -g $rootless_supplemental_gid1 ${ROOTLESS_USER}sg1 - groupadd -g $rootless_supplemental_gid2 ${ROOTLESS_USER}sg2 - groupadd -g $rootless_supplemental_gid3 ${ROOTLESS_USER}sg3 - useradd -g $rootless_gid -G ${ROOTLESS_USER}sg1,${ROOTLESS_USER}sg2,${ROOTLESS_USER}sg3 -u $rootless_uid --no-user-group --create-home $ROOTLESS_USER - rootless_supplemental_gid4=$(awk 'BEGIN{FS=":"}/^rootlessuser:/{print $2+$3}' /etc/subgid) - groupadd -g $rootless_supplemental_gid4 ${ROOTLESS_USER}sg4 - usermod -G ${ROOTLESS_USER}sg1,${ROOTLESS_USER}sg2,${ROOTLESS_USER}sg3,${ROOTLESS_USER}sg4 $ROOTLESS_USER - msg "running id for $ROOTLESS_USER" - id $ROOTLESS_USER - - # We also set up rootless user for image-scp tests (running as root) - if [[ $PRIV_NAME = "rootless" ]]; then - chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC" - fi - echo "$ROOTLESS_USER ALL=(root) NOPASSWD: ALL" > /etc/sudoers.d/ci-rootless - - mkdir -p "$HOME/.ssh" "/home/$ROOTLESS_USER/.ssh" - - msg "Creating ssh key pairs" - [[ -r "$HOME/.ssh/id_rsa" ]] || \ - ssh-keygen -t rsa -P "" -f "$HOME/.ssh/id_rsa" - ssh-keygen -t ed25519 -P "" -f "/home/$ROOTLESS_USER/.ssh/id_ed25519" - ssh-keygen -t rsa -P "" -f "/home/$ROOTLESS_USER/.ssh/id_rsa" - - msg "Setup authorized_keys" - cat $HOME/.ssh/*.pub /home/$ROOTLESS_USER/.ssh/*.pub >> $HOME/.ssh/authorized_keys - cat $HOME/.ssh/*.pub /home/$ROOTLESS_USER/.ssh/*.pub >> /home/$ROOTLESS_USER/.ssh/authorized_keys - - msg "Ensure the ssh daemon is up and running within 5 minutes" - systemctl start sshd - lilto systemctl is-active sshd - - msg "Configure ssh file permissions" - chmod -R 700 "$HOME/.ssh" - chmod -R 700 "/home/$ROOTLESS_USER/.ssh" - chown -R $ROOTLESS_USER:$ROOTLESS_USER "/home/$ROOTLESS_USER/.ssh" - - msg " setup known_hosts for $USER" - ssh-keyscan localhost > /root/.ssh/known_hosts - - msg " setup known_hosts for $ROOTLESS_USER" - install -Z -m 700 -o $ROOTLESS_USER -g $ROOTLESS_USER \ - /root/.ssh/known_hosts /home/$ROOTLESS_USER/.ssh/known_hosts - - msg "Setting up pass-through env. vars for $ROOTLESS_USER" - while read -r env_var; do - # N/B: Some values contain spaces and other potential nasty-bits - # (i.e. $CIRRUS_COMMIT_MESSAGE). The %q conversion ensures proper - # bash-style escaping. - printf -- "export %s=%q\n" "${env_var}" "${!env_var}" | tee -a /home/$ROOTLESS_USER/ci_environment - done <<<"$(passthrough_envars)" -} diff --git a/contrib/cirrus/setup.sh b/contrib/cirrus/setup.sh deleted file mode 100755 index 959a18182..000000000 --- a/contrib/cirrus/setup.sh +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env bash - -set -e - -# N/B: In most (but not all) cases, these packages will already be installed -# in the VM image at build-time (from libpod repo.). Running package install -# again here, ensures that all cases are covered, and there is never any -# expectation mismatch. -source $(dirname $0)/lib.sh - -req_env_vars OS_RELEASE_ID OS_RELEASE_VER GOSRC IN_PODMAN_IMAGE CIRRUS_CHANGE_TITLE - -msg "Running df." -df -hT - -msg "Disabling git repository owner-check system-wide." -# Newer versions of git bark if repo. files are unexpectedly owned. -# This mainly affects rootless and containerized testing. But -# the testing environment is disposable, so we don't care.= -git config --system --add safe.directory $GOSRC - -# Support optional/draft testing using latest/greatest -# podman-next COPR packages. This requires a draft PR -# to ensure changes also pass CI w/o package updates. -if [[ "$OS_RELEASE_ID" =~ "fedora" ]] && \ - [[ "$CIRRUS_CHANGE_TITLE" =~ CI:NEXT ]] -then - # shellcheck disable=SC2154 - if [[ "$CIRRUS_PR_DRAFT" != "true" ]]; then - die "Magic 'CI:NEXT' string can only be used on DRAFT PRs" - fi - - showrun dnf copr enable rhcontainerbot/podman-next -y - showrun dnf upgrade -y -fi - -msg "Setting up $OS_RELEASE_ID $OS_RELEASE_VER" -cd $GOSRC -case "$OS_RELEASE_ID" in - fedora) - warn "Hard-coding podman to use crun" - cat > /etc/containers/containers.conf < /sys/block/sda/queue/scheduler - warn "I/O scheduler: $(cat /sys/block/sda/queue/scheduler)" -fi - -execute_local_registry # checks for existing port 5000 listener - -if [[ "$IN_PODMAN" == "true" ]] -then - req_env_vars IN_PODMAN_IMAGE IN_PODMAN_NAME - echo "Setting up image to use for \$IN_PODMAN=true testing" - cd $GOSRC - in_podman $IN_PODMAN_IMAGE $0 - showrun podman commit $IN_PODMAN_NAME $IN_PODMAN_NAME - showrun podman rm -f $IN_PODMAN_NAME -fi diff --git a/contrib/cirrus/test.sh b/contrib/cirrus/test.sh deleted file mode 100755 index 1f4fff42f..000000000 --- a/contrib/cirrus/test.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env bash - -set -e - -source $(dirname $0)/lib.sh - -req_env_vars IN_PODMAN IN_PODMAN_NAME GOSRC 1 - -# shellcheck disable=SC2154 -if [[ "$PRIV_NAME" == "rootless" ]] && [[ "$UID" -eq 0 ]]; then - # Remove /var/lib/cni, it is not required for rootless cni. - # We have to test that it works without this directory. - # https://github.com/containers/podman/issues/10857 - rm -rf /var/lib/cni - - # change permission of go src and cache directory - # so rootless user can access it - chown -R $ROOTLESS_USER:root /var/tmp/go - chmod -R g+rwx /var/tmp/go - - req_env_vars ROOTLESS_USER - msg "Re-executing test through ssh as user '$ROOTLESS_USER'" - msg "************************************************************" - set -x - exec ssh $ROOTLESS_USER@localhost \ - -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - -o CheckHostIP=no $GOSRC/$SCRIPT_BASE/test.sh $1 - # Does not return! -elif [[ "$UID" -ne 0 ]]; then - # Load important env. vars written during setup.sh (run as root) - # call to setup_rootless() - source /home/$ROOTLESS_USER/ci_environment -fi -# else: not running rootless, do nothing special - -msg "Test-time env. var. definitions (filtered):" -show_env_vars - -if [[ "$IN_PODMAN" == "true" ]] -then - cd $GOSRC - # Host build environment != container environment - showrun make clean - in_podman --rm $IN_PODMAN_NAME:latest $0 $1 -else - cd $GOSRC - - showrun make - showrun make install.tools - - case $1 in - validate) - showrun ooe.sh git remote add upstream "$CIRRUS_REPO_CLONE_URL" - showrun ooe.sh git remote update - if [[ -n "$CIRRUS_PR" ]]; then - echo "Validating a PR" - export GITVALIDATE_EPOCH="$CIRRUS_BASE_SHA" - elif [[ -n "$CIRRUS_TAG" ]]; then - echo "Refusing to validating a Tag" - return 0 - else - echo "Validating a Branch" - export GITVALIDATE_EPOCH="$CIRRUS_LAST_GREEN_CHANGE" - fi - echo "Linting & Validating from ${GITVALIDATE_EPOCH:-default EPOCH}" - showrun make lint LINTFLAGS="--timeout=20m --color=always -j1" - showrun make validate - ;; - unit) - race= - if [[ -z "$CIRRUS_PR" ]]; then - # If not running on a PR then run unit tests - # with appropriate `-race` flags. - race="-race" - fi - showrun make test-unit RACEFLAGS=$race - ;; - conformance) - # Typically it's undesirable to install packages at runtime. - # This test compares images built with the "latest" version - # of docker, against images built with buildah. Runtime installs - # are required to ensure the latest docker version is used. - [[ "$OS_RELEASE_ID" == "debian" ]] || \ - bad_os_id_ver - - systemctl enable --now docker - showrun make test-conformance - ;; - integration) - showrun make test-integration - ;; - *) - die "First parameter to $(basename $0) not supported: '$1'" - ;; - esac -fi diff --git a/contrib/cirrus/timestamp.awk b/contrib/cirrus/timestamp.awk deleted file mode 100644 index 95b312e51..000000000 --- a/contrib/cirrus/timestamp.awk +++ /dev/null @@ -1,20 +0,0 @@ - - -# This script is intended to be piped into by automation, in order to -# mark output lines with timing information. For example: -# /path/to/command |& awk --file timestamp.awk - -BEGIN { - STARTTIME=systime() - printf "[%s] START", strftime("%T") - printf " - All [+xxxx] lines that follow are relative to right now.\n" -} - -{ - printf "[%+05ds] %s\n", systime()-STARTTIME, $0 -} - -END { - printf "[%s] END", strftime("%T") - printf " - [%+05ds] total duration since START\n", systime()-STARTTIME -} diff --git a/hack/get_ci_vm.sh b/hack/get_ci_vm.sh deleted file mode 100755 index 28b3b7e89..000000000 --- a/hack/get_ci_vm.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env bash - -# -# For help and usage information, simply execute the script w/o any arguments. -# -# This script is intended to be run by Red Hat buildah developers who need -# to debug problems specifically related to Cirrus-CI automated testing. -# It requires that you have been granted prior access to create VMs in -# google-cloud. For non-Red Hat contributors, VMs are available as-needed, -# with supervision upon request. - -set -e - -SCRIPT_FILEPATH=$(realpath "${BASH_SOURCE[0]}") -SCRIPT_DIRPATH=$(dirname "$SCRIPT_FILEPATH") -REPO_DIRPATH=$(realpath "$SCRIPT_DIRPATH/../") - -# Help detect if we were called by get_ci_vm container -GET_CI_VM="${GET_CI_VM:-0}" -in_get_ci_vm() { - if ((GET_CI_VM==0)); then - echo "Error: $1 is not intended for use in this context" - exit 2 - fi -} - -# get_ci_vm APIv1 container entrypoint calls into this script -# to obtain required repo. specific configuration options. -if [[ "$1" == "--config" ]]; then - in_get_ci_vm "$1" - cat < /dev/stderr - source ./contrib/cirrus/lib.sh - echo "+ Running environment setup" > /dev/stderr - ./contrib/cirrus/setup.sh -else - # Create and access VM for specified Cirrus-CI task - mkdir -p $HOME/.config/gcloud/ssh - podman run -it --rm \ - --tz=local \ - -e NAME="$USER" \ - -e SRCDIR=/src \ - -e GCLOUD_ZONE="$GCLOUD_ZONE" \ - -e A_DEBUG="${A_DEBUG:-0}" \ - -v $REPO_DIRPATH:/src:O \ - -v $HOME/.config/gcloud:/root/.config/gcloud:z \ - -v $HOME/.config/gcloud/ssh:/root/.ssh:z \ - quay.io/libpod/get_ci_vm:latest "$@" -fi