diff --git a/.codacy/markdownlint.rb b/.codacy/markdownlint.rb new file mode 100644 index 0000000..fcd51bc --- /dev/null +++ b/.codacy/markdownlint.rb @@ -0,0 +1,2 @@ +all +rule 'MD033', :allowed_elements => ["a","img","picture","source"] \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index b443a7a..4cac71d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -12,6 +12,7 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' @@ -24,8 +25,9 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Version [e.g. 22] + +- OS: [e.g. iOS] +- Version [e.g. 22] **Additional context** Add any other context about the problem here. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..00c7839 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,17 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "github-actions" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "daily" + - package-ecosystem: "github-actions" # See documentation for possible values + directory: "/external" # Location of package manifests + schedule: + interval: "daily" + ignore: + - dependency-name: "lorax" diff --git a/.github/workflows/bot_commands.yml b/.github/workflows/bot_commands.yml index c6ced5d..44522d1 100644 --- a/.github/workflows/bot_commands.yml +++ b/.github/workflows/bot_commands.yml @@ -85,9 +85,6 @@ jobs: with: pr: ${{ github.event.issue.number }} parent_job_name: Run ISO Tests - iso_name-38: ${{ needs.load_vars.outputs.IMAGE_NAME }}-38.iso - iso_name-39: ${{ needs.load_vars.outputs.IMAGE_NAME }}-39.iso - iso_name-40: ${{ needs.load_vars.outputs.IMAGE_NAME }}-40.iso run_test_deployment: name: Run ISO Deployment Tests @@ -106,6 +103,3 @@ jobs: with: pr: ${{ github.event.issue.number }} parent_job_name: Run ISO Deployment Tests - iso_name-38: ${{ needs.load_vars.outputs.IMAGE_NAME }}-38.iso - iso_name-39: ${{ needs.load_vars.outputs.IMAGE_NAME }}-39.iso - iso_name-40: ${{ needs.load_vars.outputs.IMAGE_NAME }}-40.iso diff --git a/.github/workflows/build_container.yml b/.github/workflows/build_container.yml index 23966d1..53f412d 100644 --- a/.github/workflows/build_container.yml +++ b/.github/workflows/build_container.yml @@ -1,3 +1,5 @@ +name: Build Container + on: workflow_call: inputs: @@ -24,7 +26,7 @@ jobs: statuses: write steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: recursive fetch-depth: 0 @@ -48,6 +50,7 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} job_name: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }}" + per_page: 100 - name: Set status if: inputs.pr && always() @@ -69,8 +72,10 @@ jobs: tags: | type=ref,event=branch type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} + type=raw,value=${{ github.sha }} + type=semver,pattern=v{{version}} + type=semver,pattern=v{{major}}.{{minor}} + type=semver,pattern=v{{major}}.{{minor}}.{{patch}} - name: Docker meta for PR if: inputs.pr @@ -81,6 +86,7 @@ jobs: ghcr.io/${{ github.repository }} tags: | pr-${{ inputs.pr }} + ${{ github.sha }} - name: Buildah Build id: build-image @@ -90,6 +96,13 @@ jobs: tags: ${{ steps.meta.outputs.tags || steps.meta_pr.outputs.tags }} labels: ${{ steps.meta.outputs.labels || steps.meta_pr.outputs.labels }} + - name: Login to GitHub Container Registry + uses: docker/login-action@v3.6.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Push image uses: redhat-actions/push-to-registry@v2 with: @@ -106,4 +119,26 @@ jobs: status: ${{ job.status }} context: ${{ env.JOB_NAME }} sha: ${{ env.sha }} - targetUrl: ${{ steps.jobs.outputs.html_url }} \ No newline at end of file + targetUrl: ${{ steps.jobs.outputs.html_url }} + + - name: Install Cosign + if: startsWith(github.ref, 'refs/tags/v') + uses: sigstore/cosign-installer@v3.10.0 + + - name: Sign the images + if: startsWith(github.ref, 'refs/tags/v') + env: + TAGS: ${{ steps.build-image.outputs.tags }} + COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} + COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} + run: | + images="" + digest="" + for tag in ${TAGS}; do + if [[ -z "${digest}" ]] + then + digest=$(cat $(echo ${tag} | tr '/:' '--')_digest.txt) + fi + images+="${tag}@${digest} " + done + cosign sign --key env://COSIGN_PRIVATE_KEY --yes ${images} diff --git a/.github/workflows/build_iso.yml b/.github/workflows/build_iso.yml index 572cdbf..6cd33ef 100644 --- a/.github/workflows/build_iso.yml +++ b/.github/workflows/build_iso.yml @@ -1,3 +1,5 @@ +name: Build ISO + on: workflow_call: inputs: @@ -7,16 +9,6 @@ on: parent_job_name: required: true type: string - outputs: - iso_name-38: - description: "Version 38 ISO Name" - value: ${{ jobs.build_iso.outputs.iso_name-38 }} - iso_name-39: - description: "Version 39 ISO Name" - value: ${{ jobs.build_iso.outputs.iso_name-39 }} - iso_name-40: - description: "Version 40 ISO Name" - value: ${{ jobs.build_iso.outputs.iso_name-40 }} jobs: load_vars: @@ -37,18 +29,10 @@ jobs: continue-on-error: false strategy: fail-fast: false - matrix: - version: - - 38 - - 39 - - 40 - outputs: - iso_name-38: ${{ steps.save_output.outputs.iso_name-38 }} - iso_name-39: ${{ steps.save_output.outputs.iso_name-39 }} - iso_name-40: ${{ steps.save_output.outputs.iso_name-40 }} + matrix: ${{ fromJson(needs.load_vars.outputs.BUILD_MATRIX) }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: recursive @@ -69,7 +53,8 @@ jobs: id: jobs with: github_token: ${{ secrets.GITHUB_TOKEN }} - job_name: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }} (${{ matrix.version }})" + job_name: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }} (${{ matrix.version }}, ${{ matrix.flatpaks }}, ${{ matrix.image_repo }})" + per_page: 100 - name: Set status if: inputs.pr && always() @@ -77,7 +62,7 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} status: pending - context: ${{ env.JOB_NAME }} (${{ matrix.version }}) + context: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }} (${{ matrix.version }}, ${{ matrix.flatpaks }}, ${{ matrix.image_repo }})" sha: ${{ env.sha }} targetUrl: ${{ steps.jobs.outputs.html_url }} @@ -120,30 +105,28 @@ jobs: id: build with: arch: ${{ needs.load_vars.outputs.ARCH }} - image_name: ${{ needs.load_vars.outputs.IMAGE_NAME }} - image_repo: ${{ needs.load_vars.outputs.IMAGE_REPO }} + image_name: ${{ matrix.image_name }} + image_repo: ${{ matrix.image_repo}} + image_src: ${{ matrix.image_src }} image_tag: ${{ matrix.version }} version: ${{ matrix.version }} + repos: ${{ matrix.repos }} variant: ${{ needs.load_vars.outputs.VARIANT }} - flatpak_remote_refs_dir: /github/workspace/${{ needs.load_vars.outputs.FLATPAK_REMOTE_REFS_DIR }} + flatpak_remote_refs: ${{ matrix.flatpaks == 'flatpak_refs' && needs.load_vars.outputs.FLATPAK_REMOTE_REFS || '' }} + flatpak_remote_refs_dir: ${{ matrix.flatpaks == 'flatpak_refs_dir' && needs.load_vars.outputs.FLATPAK_REMOTE_REFS_DIR || '' }} secure_boot_key_url: ${{ needs.load_vars.outputs.SECURE_BOOT_KEY_URL }} enrollment_password: ${{ needs.load_vars.outputs.ENROLLMENT_PASSWORD }} - iso_name: ${{ needs.load_vars.outputs.IMAGE_NAME }}-${{ matrix.version }}.iso - - - name: Save output - id: save_output - shell: bash - run: | - echo "iso_name-${{ matrix.version }}=${{ steps.build.outputs.iso_name}}" >> $GITHUB_OUTPUT + iso_name: build/${{ matrix.image_name }}-${{ matrix.version }}${{ matrix.flatpaks == 'false' && '' || format('-{0}', matrix.flatpaks) }}.iso - name: Upload ISO as artifact + if: matrix.version != 'fake' id: upload uses: actions/upload-artifact@v4 with: - name: ${{ steps.build.outputs.iso_name }} + name: ${{ matrix.image_name }}-${{ matrix.version }}${{ matrix.flatpaks == 'false' && '' || format('-{0}', matrix.flatpaks) }} path: | - ${{ steps.build.outputs.iso_path }} - ${{ steps.build.outputs.iso_path }}-CHECKSUM + build/${{ matrix.image_name }}-${{ matrix.version }}${{ matrix.flatpaks == 'false' && '' || format('-{0}', matrix.flatpaks) }}.iso + build/${{ matrix.image_name }}-${{ matrix.version }}${{ matrix.flatpaks == 'false' && '' || format('-{0}', matrix.flatpaks) }}.iso-CHECKSUM if-no-files-found: error retention-days: 0 compression-level: 0 @@ -155,6 +138,7 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} status: ${{ job.status }} - context: ${{ env.JOB_NAME }} (${{ matrix.version }}) + context: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }} (${{ matrix.version }}, ${{ matrix.flatpaks }}, ${{ matrix.image_repo }})" sha: ${{ env.sha }} targetUrl: ${{ steps.jobs.outputs.html_url }} + diff --git a/.github/workflows/build_vars.yml b/.github/workflows/build_vars.yml index 3ec77e8..8a60657 100644 --- a/.github/workflows/build_vars.yml +++ b/.github/workflows/build_vars.yml @@ -1,18 +1,71 @@ +name: Build Vars + on: workflow_call: outputs: ARCH: value: 'x86_64' - IMAGE_NAME: - value: 'base' - IMAGE_REPO: - value: 'quay.io/fedora-ostree-desktops' - IMAGE_TAG: - value: '39' + BUILD_MATRIX: + value: ' + { + "version": [ + "41", + "42", + "43" + ], + "flatpaks": [ + "false", + "flatpak_refs_dir", + "flatpak_refs" + ], + "image_repo": [ + "ghcr.io/ublue-os", + "quay.io/fedora", + "quay.io/fedora-ostree-desktops" + ], + "include": [ + { + "image_repo": "ghcr.io/ublue-os", + "image_name": "base-main", + }, + { + "image_repo": "quay.io/fedora", + "image_name": "fedora-bootc" + }, + { + "image_repo": "quay.io/fedora-ostree-desktops", + "image_name": "base-atomic" + } + ], + "exclude": [ + { + "image_repo": "quay.io/fedora", + "flatpaks": "flatpak_refs_dir" + }, + { + "image_repo": "quay.io/fedora", + "flatpaks": "flatpak_refs" + }, + { + "image_repo": "quay.io/fedora-ostree-desktops", + "flatpaks": "flatpak_refs_dir" + }, + { + "image_repo": "quay.io/fedora-ostree-desktops", + "flatpaks": "flatpak_refs" + }, + { + "image_repo": "ghcr.io/ublue-os", + "version": "43" + } + ] + }' VARIANT: value: 'Server' FLATPAK_REMOTE_REFS_DIR: value: flatpak_refs + FLATPAK_REMOTE_REFS: + value: "app/org.mozilla.firefox/x86_64/stable app/org.videolan.VLC/x86_64/stable" SECURE_BOOT_KEY_URL: value: 'https://github.com/ublue-os/akmods/raw/main/certs/public_key.der' ENROLLMENT_PASSWORD: diff --git a/.github/workflows/clean_repo.yml b/.github/workflows/clean_repo.yml new file mode 100644 index 0000000..a19ddd5 --- /dev/null +++ b/.github/workflows/clean_repo.yml @@ -0,0 +1,143 @@ +name: Clean Container Registry +on: +# schedule: +# - cron: '0 21 * * 0' + + workflow_dispatch: + +jobs: + delete_untagged: + name: Delete Untagged Packages + runs-on: ubuntu-latest + steps: + - name: Delete Untagged Packages + uses: Chizkiyahu/delete-untagged-ghcr-action@v5 + with: + token: ${{ secrets.PACKAGE_DELETER }} + repository_owner: ${{ github.repository_owner }} + repository: ${{ github.repository }} + untagged_only: true + owner_type: user + + delete_old_pr: + name: Delete Old PR Packages + runs-on: ubuntu-latest + permissions: + packages: read + steps: + - name: Delete Old PR Packages + id: all_tags + run: | + curl -L \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ github.token }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "https://api.github.com/user/packages/container/build-container-installer/versions" > all_packages.json + curl -L \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ github.token }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository }}/pulls | \ + jq -r '.[] | select(.state == "open") | .number' | \ + sed 's/^/pr-/g' > open_prs + cat << EOF | python + import json + import re + + prs = open("open_prs", "r") + open_prs = prs.readlines() + open_prs = [x.strip() for x in open_prs] + + all_packages = open('all_packages.json') + data = json.load(all_packages) + + delete_versions = open("delete_versions", "w") + + for i in data: + delete = True + for tag in i['metadata']['container']['tags']: + if not re.match('pr-.*', tag): + delete = False + continue + if tag in open_prs: + delete = False + if delete: + print("delete", i['id']) + delete_versions.write(str(i['id'])) + delete_versions.write("\n") + print(i['metadata']['container']['tags']) + EOF + + for id in $(cat delete_versions) + do + curl -L \ + -X DELETE \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.PACKAGE_DELETER }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/user/packages/container/build-container-installer/versions/${id} + done + + + delete_old_branches: + name: Delete Old Branch Packages + runs-on: ubuntu-latest + permissions: + packages: read + steps: + - name: Delete Old Branch Packages + run: | + curl -L \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ github.token }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "https://api.github.com/user/packages/container/build-container-installer/versions" > all_packages.json + curl -L \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ github.token }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository }}/branches | jq -r '.[].name' > branches + + cat << EOF | python + import json + import re + + branches_f = open("branches", "r") + branches = branches_f.readlines() + branches = [x.strip() for x in branches] + + all_packages_f = open('all_packages.json') + data = json.load(all_packages_f) + + delete_versions = open("delete_versions", "w") + + for i in data: + delete = True + for tag in i['metadata']['container']['tags']: + if re.match('v[0-9]+\\\.[0-9]+\\\.[0-9]+', tag): + delete = False + continue + if re.match('pr-.*', tag): + delete = False + continue + if tag in branches: + delete = False + continue + if tag == "latest": + delete = False + if delete: + print("delete", i['id']) + delete_versions.write(str(i['id'])) + delete_versions.write("\n") + print(i['metadata']['container']['tags']) + EOF + + for id in $(cat delete_versions) + do + curl -L \ + -X DELETE \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.PACKAGE_DELETER }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/user/packages/container/build-container-installer/versions/${id} + done diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 6ad1c0a..ac6193f 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -7,7 +7,7 @@ name: Mark stale issues and pull requests on: schedule: - - cron: '39 21 * * *' + - cron: '0 21 * * *' jobs: stale: @@ -18,7 +18,7 @@ jobs: pull-requests: write steps: - - uses: actions/stale@v5 + - uses: actions/stale@v9 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'Issue is stale and will be closed in 14 days if there is no further activity' diff --git a/.github/workflows/test_deployment.yml b/.github/workflows/test_deployment.yml index e1951be..8738ded 100644 --- a/.github/workflows/test_deployment.yml +++ b/.github/workflows/test_deployment.yml @@ -1,3 +1,5 @@ +name: Test Deployment + on: workflow_call: inputs: @@ -7,17 +9,6 @@ on: parent_job_name: required: true type: string - iso_name-38: - required: true - type: string - iso_name-39: - required: true - type: string - iso_name-40: - required: true - type: string - - jobs: load_vars: @@ -37,14 +28,10 @@ jobs: continue-on-error: false strategy: fail-fast: false - matrix: - version: - - 38 - - 39 - - 40 + matrix: ${{ fromJson(needs.load_vars.outputs.BUILD_MATRIX) }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: recursive @@ -65,7 +52,8 @@ jobs: id: jobs with: github_token: ${{ secrets.GITHUB_TOKEN }} - job_name: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }} (${{ matrix.version }})" + job_name: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }} (${{ matrix.version }}, ${{ matrix.flatpaks }}, ${{ matrix.image_repo }})" + per_page: 100 - name: Set status if: inputs.pr && always() @@ -73,105 +61,45 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} status: pending - context: ${{ env.JOB_NAME }} (${{ matrix.version }}) + context: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }} (${{ matrix.version }}, ${{ matrix.flatpaks }}, ${{ matrix.image_repo }})" sha: ${{ env.sha }} targetUrl: ${{ steps.jobs.outputs.html_url }} - name: Install test tools run: | sudo apt-get update - sudo apt-get install -y make - sudo make install-test-deps PACKAGE_MANAGER=apt-get + sudo apt-get install -y unzip make + sudo make test/vm/install-deps PACKAGE_MANAGER=apt-get - name: Download generated ISO uses: actions/download-artifact@v4 with: - name: ${{ inputs[format('iso_name-{0}', matrix.version)] }} + name: ${{ matrix.image_name }}-${{ matrix.version }}${{ matrix.flatpaks == 'false' && '' || format('-{0}', matrix.flatpaks) }} - - name: Add Kickstart and Grub options to ISO - run: | - mv ${{ inputs[format('iso_name-{0}', matrix.version)] }} deploy.iso - sudo mkdir /mnt/iso || true - sudo mount -o loop deploy.iso /mnt/iso - cp /mnt/iso/boot/grub2/grub.cfg grub.cfg - sudo umount /mnt/iso - sed -i 's/quiet/console=ttyS0,115200n8 inst.ks=cdrom:\/ks.cfg/' grub.cfg - sed -i 's/set default="1"/set default="0"/' grub.cfg - sed -i 's/set timeout=60/set timeout=1/' grub.cfg - cat << EOF > ks.cfg - lang en_US.UTF-8 - keyboard us - timezone Americas/New_York - zerombr - clearpart --all --initlabel - autopart - poweroff - user --name=core --groups=wheel --password=foobar - %include /usr/share/anaconda/interactive-defaults.ks - EOF - xorriso -dialog on << EOF - -indev deploy.iso - -outdev test.iso - -boot_image any replay - -map ks.cfg ks.cfg - -chmod 0444 ks.cfg - -map grub.cfg boot/grub2/grub.cfg - -end - EOF - - - name: Create VM disk - run: | - qemu-img create -f qcow2 disk.qcow2 50G - - - name: Install the test VM - run: | - timeout 1h qemu-system-x86_64 -name "Anaconda" -boot d -m 4096 -cpu qemu64 -display none -cdrom test.iso -smp 2 -hda disk.qcow2 -serial telnet:localhost:4321,server=on,wait=off & QEMU_PID=$! - echo "PID: $QEMU_PID" - timeout 1m bash -c "while ! (echo > /dev/tcp/127.0.0.1/4321); do sleep 0.1; done" - (nc localhost 4321 | tee vm.stdout) & - wait $QEMU_PID - - - name: Start the test VM + - name: Run VM Tests env: VM_USER: core VM_PASS: foobar VM_IP: "127.0.0.1" VM_PORT: "5555" run: | - mkfifo vm.stdin - qemu-system-x86_64 -name "Anaconda" \ - -m 4096 -cpu qemu64 -display none -smp 2 \ - -chardev socket,path=/tmp/qga.sock,server=on,wait=off,id=qga0 \ - -device e1000,netdev=net0 \ - -netdev user,id=net0,hostfwd=tcp::${VM_PORT}-:22 \ - -device virtio-serial \ - -device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0 \ - -boot c -hda disk.qcow2 -serial telnet:localhost:4321,server=on,wait=off & export QEMU_PID=$! - echo "PID: $QEMU_PID" - - timeout 1m bash -c "while ! (echo > /dev/tcp/127.0.0.1/4321); do sleep 0.1; done" - (tail -f vm.stdin | nc localhost 4321 | tee vm.stdout) & - - timeout 30m bash -c "while ! (echo > /dev/tcp/${VM_IP}/${VM_PORT}); do sleep 1; done" - - if ! (echo > /dev/tcp/${VM_IP}/${VM_PORT}) - then - echo "SSH must be installed and enabled inside the container" - fi - - echo "VM ready for tests at IP ${VM_IP}:${VM_PORT}" - - make test-vm VM_IP=${VM_IP} VM_PORT=${VM_PORT} VM_USER=${VM_USER} VM_PASS=${VM_PASS} \ + make test/vm \ ARCH=${{ needs.load_vars.outputs.ARCH}} \ - IMAGE_NAME=${{ needs.load_vars.outputs.IMAGE_NAME}} \ - IMAGE_REPO=${{ needs.load_vars.outputs.IMAGE_REPO}} \ + ENROLLMENT_PASSWORD=${{ needs.load_vars.outputs.ENROLLMENT_PASSWORD }} \ + ${{ matrix.flatpaks == 'flatpak_refs' && format('FLATPAK_REMOTE_REFS="{0}"', needs.load_vars.outputs.FLATPAK_REMOTE_REFS) || '' }} \ + ${{ matrix.flatpaks == 'flatpak_refs_dir' && format('FLATPAK_REMOTE_REFS_DIR="{0}"', needs.load_vars.outputs.FLATPAK_REMOTE_REFS_DIR) || '' }} \ + IMAGE_NAME=${{ matrix.image_name }} \ + IMAGE_REPO=${{ matrix.image_repo }} \ IMAGE_TAG=${{ matrix.version }} \ - VERSION=${{ matrix.version }} \ - VARIANT=${{ needs.load_vars.outputs.VARIANT }} \ - FLATPAK_REMOTE_REFS_DIR=${{ needs.load_vars.outputs.FLATPAK_REMOTE_REFS_DIR }} \ + ISO_NAME=${{ matrix.image_name }}-${{ matrix.version }}${{ matrix.flatpaks == 'false' && '' || format('-{0}', matrix.flatpaks) }}.iso \ + ${{ matrix.repos != '' && format('REPOS="{0}"', matrix.repos) || '' }} \ SECURE_BOOT_KEY_URL=${{ needs.load_vars.outputs.SECURE_BOOT_KEY_URL }} \ - ENROLLMENT_PASSWORD=${{ needs.load_vars.outputs.ENROLLMENT_PASSWORD }} - kill $QEMU_PID + VARIANT=${{ needs.load_vars.outputs.VARIANT }} \ + VERSION=${{ matrix.version }} \ + VM_IP=${VM_IP} \ + VM_PASS=${VM_PASS} \ + VM_PORT=${VM_PORT} \ + VM_USER=${VM_USER} - name: Set status if: inputs.pr && always() @@ -179,6 +107,6 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} status: ${{ job.status }} - context: ${{ env.JOB_NAME }} (${{ matrix.version }}) + context: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }} (${{ matrix.version }}, ${{ matrix.flatpaks }}, ${{ matrix.image_repo }})" sha: ${{ env.sha }} targetUrl: ${{ steps.jobs.outputs.html_url }} diff --git a/.github/workflows/test_iso.yml b/.github/workflows/test_iso.yml index be442a3..049fc11 100644 --- a/.github/workflows/test_iso.yml +++ b/.github/workflows/test_iso.yml @@ -1,3 +1,5 @@ +name: Test ISO + on: workflow_call: inputs: @@ -7,16 +9,6 @@ on: parent_job_name: required: true type: string - iso_name-38: - required: true - type: string - iso_name-39: - required: true - type: string - iso_name-40: - required: true - type: string - jobs: load_vars: @@ -36,14 +28,10 @@ jobs: continue-on-error: false strategy: fail-fast: false - matrix: - version: - - 38 - - 39 - - 40 + matrix: ${{ fromJson(needs.load_vars.outputs.BUILD_MATRIX) }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: recursive @@ -64,7 +52,8 @@ jobs: id: jobs with: github_token: ${{ secrets.GITHUB_TOKEN }} - job_name: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }} (${{ matrix.version }})" + job_name: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }} (${{ matrix.version }}, ${{ matrix.flatpaks }}, ${{ matrix.image_repo }})" + per_page: 100 - name: Set status if: inputs.pr && always() @@ -72,7 +61,7 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} status: pending - context: ${{ env.JOB_NAME }} (${{ matrix.version }}) + context: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }} (${{ matrix.version }}, ${{ matrix.flatpaks }}, ${{ matrix.image_repo }})" sha: ${{ env.sha }} targetUrl: ${{ steps.jobs.outputs.html_url }} @@ -80,31 +69,28 @@ jobs: run: | sudo apt-get update sudo apt-get install -y make - sudo make install-test-deps PACKAGE_MANAGER=apt-get + sudo make test/iso/install-deps PACKAGE_MANAGER=apt-get - name: Download generated ISO uses: actions/download-artifact@v4 with: - name: ${{ inputs[format('iso_name-{0}', matrix.version)] }} - - - name: Verify ISO - run: | - checkisomd5 ${{ inputs[format('iso_name-{0}', matrix.version)] }} - sha256sum -c ${{ inputs[format('iso_name-{0}', matrix.version)] }}-CHECKSUM + name: ${{ matrix.image_name }}-${{ matrix.version }}${{ matrix.flatpaks == 'false' && '' || format('-{0}', matrix.flatpaks) }} - name: Run ISO checks run: | - mv ${{ inputs[format('iso_name-{0}', matrix.version)] }} deploy.iso - make test-iso \ + make test/iso \ ARCH=${{ needs.load_vars.outputs.ARCH}} \ - IMAGE_NAME=${{ needs.load_vars.outputs.IMAGE_NAME}} \ - IMAGE_REPO=${{ needs.load_vars.outputs.IMAGE_REPO}} \ + ENROLLMENT_PASSWORD=${{ needs.load_vars.outputs.ENROLLMENT_PASSWORD }} \ + ${{ matrix.flatpaks == 'flatpak_refs' && format('FLATPAK_REMOTE_REFS="{0}"', needs.load_vars.outputs.FLATPAK_REMOTE_REFS) || '' }} \ + ${{ matrix.flatpaks == 'flatpak_refs_dir' && format('FLATPAK_REMOTE_REFS_DIR="{0}"', needs.load_vars.outputs.FLATPAK_REMOTE_REFS_DIR) || '' }} \ + IMAGE_NAME=${{ matrix.image_name }} \ + IMAGE_REPO=${{ matrix.image_repo }} \ IMAGE_TAG=${{ matrix.version }} \ - VERSION=${{ matrix.version }} \ - VARIANT=${{ needs.load_vars.outputs.VARIANT }} \ - FLATPAK_REMOTE_REFS_DIR=${{ needs.load_vars.outputs.FLATPAK_REMOTE_REFS_DIR }} \ + ISO_NAME=${{ matrix.image_name }}-${{ matrix.version }}${{ matrix.flatpaks == 'false' && '' || format('-{0}', matrix.flatpaks) }}.iso \ + ${{ matrix.repos != '' && format('REPOS="{0}"', matrix.repos) || '' }} \ SECURE_BOOT_KEY_URL=${{ needs.load_vars.outputs.SECURE_BOOT_KEY_URL }} \ - ENROLLMENT_PASSWORD=${{ needs.load_vars.outputs.ENROLLMENT_PASSWORD }} + VARIANT=${{ needs.load_vars.outputs.VARIANT }} \ + VERSION=${{ matrix.version }} - name: Set status if: inputs.pr && always() @@ -112,6 +98,6 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} status: ${{ job.status }} - context: ${{ env.JOB_NAME }} (${{ matrix.version }}) + context: "${{ inputs.parent_job_name }} / ${{ env.JOB_NAME }} (${{ matrix.version }}, ${{ matrix.flatpaks }}, ${{ matrix.image_repo }})" sha: ${{ env.sha }} - targetUrl: ${{ steps.jobs.outputs.html_url }} \ No newline at end of file + targetUrl: ${{ steps.jobs.outputs.html_url }} diff --git a/.github/workflows/variables.yml b/.github/workflows/test_repo.yml similarity index 69% rename from .github/workflows/variables.yml rename to .github/workflows/test_repo.yml index e697fa0..59071c0 100644 --- a/.github/workflows/variables.yml +++ b/.github/workflows/test_repo.yml @@ -1,4 +1,4 @@ -name: Repo Tests +name: Test Repo on: push: @@ -20,8 +20,11 @@ jobs: contents: read steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Run test run: | - /bin/bash tests/repo/vars.sh \ No newline at end of file + sudo apt-get update + sudo apt-get install -y make + sudo make test/repo/install-deps + make test/repo \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 506c430..52e8305 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,4 +1,4 @@ -name: Tests +name: All Tests on: push: @@ -27,39 +27,34 @@ jobs: build_container: name: Build Container uses: ./.github/workflows/build_container.yml + secrets: inherit with: pr: ${{ inputs.pr }} parent_job_name: ${{ inputs.parent_job_name && format('{0} / ', inputs.parent_job_name) }}Build Container - build_iso: - name: Build ISO + build_isos: + name: Build ISOs needs: - build_container uses: ./.github/workflows/build_iso.yml with: pr: ${{ inputs.pr }} - parent_job_name: ${{ inputs.parent_job_name && format('{0} / ', inputs.parent_job_name) }}Build ISO + parent_job_name: ${{ inputs.parent_job_name && format('{0} / ', inputs.parent_job_name) }}Build ISOs - test_iso: - name: Test ISO + test_isos: + name: Test ISOs needs: - - build_iso + - build_isos uses: ./.github/workflows/test_iso.yml with: pr: ${{ inputs.pr }} - parent_job_name: ${{ inputs.parent_job_name && format('{0} / ', inputs.parent_job_name) }}Test ISO - iso_name-38: ${{ needs.build_iso.outputs.iso_name-38 }} - iso_name-39: ${{ needs.build_iso.outputs.iso_name-39 }} - iso_name-40: ${{ needs.build_iso.outputs.iso_name-40 }} + parent_job_name: ${{ inputs.parent_job_name && format('{0} / ', inputs.parent_job_name) }}Test ISOs - test_deployment: - name: Test Deployment + test_deployments: + name: Test Deployments needs: - - build_iso + - build_isos uses: ./.github/workflows/test_deployment.yml with: pr: ${{ inputs.pr }} - parent_job_name: ${{ inputs.parent_job_name && format('{0} / ', inputs.parent_job_name) }}Test Deployment - iso_name-38: ${{ needs.build_iso.outputs.iso_name-38 }} - iso_name-39: ${{ needs.build_iso.outputs.iso_name-39 }} - iso_name-40: ${{ needs.build_iso.outputs.iso_name-40 }} \ No newline at end of file + parent_job_name: ${{ inputs.parent_job_name && format('{0} / ', inputs.parent_job_name) }}Test Deployments diff --git a/.github/workflows/update_wiki.yml b/.github/workflows/update_wiki.yml new file mode 100644 index 0000000..fce015c --- /dev/null +++ b/.github/workflows/update_wiki.yml @@ -0,0 +1,50 @@ +name: Update Wiki +on: + push: + branches: + - main + paths: + - 'docs/**' + - '.github/workflows/update_wiki.yml' + +jobs: + update-wiki: + name: Update Wiki + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Install packages + run: | + sudo apt install -y make rsync + # Checkout Main Repo + - uses: actions/checkout@v5 + + # Checkout Wiki Repo + - uses: actions/checkout@v5 + with: + repository: ${{github.repository}}.wiki + persist-credentials: true + path: wiki + ref: master + + # Generate final files + - name: Generate Files + run: | + cd ${GITHUB_WORKSPACE}/docs + make + + # Copy Docs + - name: Copy files + run: | + rsync -av --exclude='.git/*' ${GITHUB_WORKSPACE}/docs/ ${GITHUB_WORKSPACE}/wiki/ + + # Push Changes + - name: Push changes + run: | + cd ${GITHUB_WORKSPACE}/wiki/ + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add . + git commit -m "Add changes" + git push diff --git a/.gitignore b/.gitignore index f116d91..df805b5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,13 @@ /debugdata /build +/flatpaks/script.sh +/flatpaks/repo +/flatpaks/list.txt /lorax_templates/post_* /pkglists -/repos +/repos/*.repo /results /xorriso/input.txt -/xorriso/*.sh /original-pkgsizes.txt /final-pkgsizes.txt /lorax.conf diff --git a/.gitmodules b/.gitmodules index e05748a..3ac6662 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "external/fedora-lorax-templates"] path = external/fedora-lorax-templates url = https://pagure.io/fedora-lorax-templates.git - branch = f39 + branch = f40 [submodule "external/lorax"] path = external/lorax url = https://github.com/weldr/lorax.git diff --git a/.mdlrc b/.mdlrc new file mode 100644 index 0000000..17717c6 --- /dev/null +++ b/.mdlrc @@ -0,0 +1 @@ +style "#{File.dirname(__FILE__)}/.codacy/markdownlint.rb" \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..2625bca --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "Makefile.inputs": "makefile" + } +} \ No newline at end of file diff --git a/Containerfile b/Containerfile index fc097e5..18b844b 100644 --- a/Containerfile +++ b/Containerfile @@ -1,6 +1,6 @@ -FROM fedora:40 +FROM fedora:42 -ARG VERSION=40 +ARG VERSION=42 ENV ARCH="x86_64" ENV IMAGE_NAME="base" @@ -19,7 +19,7 @@ VOLUME /build-container-installer/build VOLUME /build-container-installer/repos VOLUME /cache -RUN dnf install -y make && make install-deps +RUN dnf install -y make && make install-deps && dnf clean all ENTRYPOINT ["/bin/bash", "/build-container-installer/entrypoint.sh"] diff --git a/Makefile b/Makefile index b596037..9f85c58 100644 --- a/Makefile +++ b/Makefile @@ -1,115 +1,51 @@ -# Configuration vars -## Formatting = UPPERCASE -# General -ADDITIONAL_TEMPLATES = -ARCH = x86_64 -EXTRA_BOOT_PARAMS = -IMAGE_NAME = base -IMAGE_REPO = quay.io/fedora-ostree-desktops -IMAGE_TAG = $(VERSION) -REPOS = $(subst :,\:,$(shell ls /etc/yum.repos.d/*.repo)) -ROOTFS_SIZE = 4 -VARIANT = Server -VERSION = 39 -WEB_UI = false -# Flatpak -FLATPAK_REMOTE_NAME = flathub -FLATPAK_REMOTE_URL = https://flathub.org/repo/flathub.flatpakrepo -FLATPAK_REMOTE_REFS = -FLATPAK_REMOTE_REFS_DIR = -FLATPAK_DIR = -# Secure boot -ENROLLMENT_PASSWORD = -SECURE_BOOT_KEY_URL = +include Makefile.inputs ################### # Hidden vars +export SHELL := /bin/sh # Cache -DNF_CACHE = -PACKAGE_MANAGER = dnf +export DNF_CACHE := +export PACKAGE_MANAGER := dnf # Functions ## Formatting = lowercase # Get a list of templates for the feature # $1 = feature -get_templates = $(shell ls lorax_templates/$(1)_*.tmpl) \ - $(foreach file,$(notdir $(shell ls lorax_templates/scripts/post/$(1)_*)),lorax_templates/post_$(file).tmpl) +define get_templates + $(wildcard lorax_templates/$(1)_*.tmpl) + $(foreach file,$(notdir $(wildcard lorax_templates/scripts/post/$(1)_*)),lorax_templates/post_$(file).tmpl) +endef -# Get a list of tests for the feature -# $1 = test type -# $2 = feature -run_tests = tests="$(shell ls tests/$(1)/$(2)_*)"; \ - if [ -n "$$tests" ]; \ - then \ - chmod +x $$tests; \ - for test in $$tests; \ - do \ - $(foreach var,$(_VARS),$(var)=$($(var))) ./$${test}; \ - RC=$$?; if [ $$RC != 0 ]; then exit $$RC; fi; \ - done; \ - fi - -# Converts a post script to a template -# $1 = script to convert -# $2 = file on ISO to write -# $3 = whether to copy the '<%' lines to the template -convert_post_to_tmpl = header=0; \ - skip=0; \ - while read -r line; \ - do \ - if [[ $$line =~ ^\<\% ]]; \ - then \ - if [[ '$(3)' == 'true' ]]; \ - then \ - echo $$line >> lorax_templates/post_$(1).tmpl; \ - fi; \ - echo >> lorax_templates/post_$(1).tmpl; \ - else \ - if [[ $$header == 0 ]]; \ - then \ - if [[ $$line =~ ^\#\#\ (.*)$$ ]]; \ - then \ - echo "append $(2) \"%post --erroronfail $${BASH_REMATCH[1]}\"" >> lorax_templates/post_$(1).tmpl; \ - skip=1; \ - else \ - echo "append $(2) \"%post --erroronfail\"" >> lorax_templates/post_$(1).tmpl; \ - fi; \ - header=1; \ - fi; \ - if [[ $$skip == 0 ]]; \ - then \ - echo "append $(2) \"$${line//\"/\\\"}\"" >> lorax_templates/post_$(1).tmpl; \ - fi; \ - skip=0; \ - fi; \ - done < lorax_templates/scripts/post/$(1); \ - echo "append $(2) \"%end\"" >> lorax_templates/post_$(1).tmpl +define install_pkg + $(PACKAGE_MANAGER) install -y $(if $(findstring dnf,$(PACKAGE_MANAGER)),--disablerepo='*-testing') +endef +export install_pkg # Generated/internal vars ## Formatting = _UPPERCASE -_BASE_DIR = $(shell pwd) -_IMAGE_REPO_ESCAPED = $(subst /,\/,$(IMAGE_REPO)) -_IMAGE_REPO_DOUBLE_ESCAPED = $(subst \,\\\,$(_IMAGE_REPO_ESCAPED)) -_LORAX_ARGS = -_LORAX_TEMPLATES = $(call get_templates,install) -_REPO_FILES = $(subst /etc/yum.repos.d,repos,$(REPOS)) -_TEMP_DIR = $(shell mktemp -d) -_TEMPLATE_VARS = ARCH _BASE_DIR IMAGE_NAME IMAGE_REPO _IMAGE_REPO_DOUBLE_ESCAPED _IMAGE_REPO_ESCAPED IMAGE_TAG REPOS _RHEL VARIANT VERSION WEB_UI -_VOLID = $(firstword $(subst -, ,$(IMAGE_NAME)))-$(ARCH)-$(IMAGE_TAG) +_IMAGE_REPO_ESCAPED := $(subst /,\/,$(IMAGE_REPO)) +_IMAGE_REPO_DOUBLE_ESCAPED := $(subst \,\\\,$(_IMAGE_REPO_ESCAPED)) +_LORAX_ARGS := +export _LORAX_TEMPLATES := $(call get_templates,install) lorax_templates/install_include_post.tmpl +_REPO_FILES := $(subst /etc/yum.repos.d,repos,$(REPOS)) +_TEMP_DIR := $(shell mktemp -d) +_TEMPLATE_VARS := ARCH IMAGE_NAME IMAGE_REPO _IMAGE_REPO_DOUBLE_ESCAPED _IMAGE_REPO_ESCAPED IMAGE_SIGNED IMAGE_TAG REPOS _RHEL VARIANT VERSION WEB_UI +_VOLID := $(firstword $(subst -, ,$(IMAGE_NAME)))-$(ARCH)-$(IMAGE_TAG) ifeq ($(findstring redhat.repo,$(REPOS)),redhat.repo) -_RHEL = true +export _RHEL := true +export _LORAX_TEMPLATES += $(call get_templates,rhel) else -_RHEL = false +undefine _RHEL endif ifeq ($(_RHEL),true) _LORAX_ARGS += --nomacboot --noupgrade else ifeq ($(VARIANT),Server) -_LORAX_ARGS += --macboot --noupgrade +_LORAX_ARGS += --macboot --noupgrade --squashfs-only else -_LORAX_ARGS += --nomacboot +_LORAX_ARGS += --nomacboot --squashfs-only endif ifeq ($(WEB_UI),true) @@ -117,173 +53,96 @@ _LORAX_ARGS += -i anaconda-webui endif ifneq ($(DNF_CACHE),) -_LORAX_ARGS += --cachedir $(DNF_CACHE) -_LORAX_TEMPLATES += $(call get_templates,cache) -_TEMPLATE_VARS += DNF_CACHE + _LORAX_ARGS += --cachedir $(DNF_CACHE) +export _LORAX_TEMPLATES += $(call get_templates,cache) + _TEMPLATE_VARS += DNF_CACHE endif ifneq ($(FLATPAK_DIR),) -_FLATPAK_REPO_GPG = $(shell curl -L $(FLATPAK_REMOTE_URL) | grep -i '^GPGKey=' | cut -d= -f2) -_FLATPAK_REPO_URL = $(shell curl -L $(FLATPAK_REMOTE_URL) | grep -i '^URL=' | cut -d= -f2) -_LORAX_ARGS += -i flatpak-libs -_LORAX_TEMPLATES += $(call get_templates,flatpak) -_TEMPLATE_VARS += FLATPAK_DIR FLATPAK_REMOTE_NAME FLATPAK_REMOTE_REFS FLATPAK_REMOTE_URL _FLATPAK_REPO_GPG _FLATPAK_REPO_URL + _FLATPAK_REPO_GPG := $(shell curl -L $(FLATPAK_REMOTE_URL) | grep -i '^GPGKey=' | cut -d= -f2) +export _FLATPAK_REPO_URL := $(shell curl -L $(FLATPAK_REMOTE_URL) | grep -i '^URL=' | cut -d= -f2) + _LORAX_ARGS += -i flatpak-libs +export _LORAX_TEMPLATES += $(call get_templates,flatpak) + _TEMPLATE_VARS += FLATPAK_DIR FLATPAK_REMOTE_NAME FLATPAK_REMOTE_REFS FLATPAK_REMOTE_URL _FLATPAK_REPO_GPG _FLATPAK_REPO_URL else ifneq ($(FLATPAK_REMOTE_REFS_DIR),) -COLLECTED_REFS = $(foreach file,$(shell ls $(FLATPAK_REMOTE_REFS_DIR)/*),$(shell cat $(file))) -FLATPAK_REMOTE_REFS += $(sort $(COLLECTED_REFS)) + COLLECTED_REFS := $(foreach file,$(filter-out README.md Makefile,$(wildcard $(FLATPAK_REMOTE_REFS_DIR)/*)),$(shell cat $(file))) +export FLATPAK_REMOTE_REFS += $(sort $(COLLECTED_REFS)) endif ifneq ($(FLATPAK_REMOTE_REFS),) -_FLATPAK_REPO_GPG = $(shell curl -L $(FLATPAK_REMOTE_URL) | grep -i '^GPGKey=' | cut -d= -f2) -_FLATPAK_REPO_URL = $(shell curl -L $(FLATPAK_REMOTE_URL) | grep -i '^URL=' | cut -d= -f2) -_LORAX_ARGS += -i flatpak-libs -_LORAX_TEMPLATES += $(call get_templates,flatpak) \ - external/fedora-lorax-templates/ostree-based-installer/lorax-embed-flatpaks.tmpl -_TEMPLATE_VARS += FLATPAK_DIR FLATPAK_REMOTE_NAME FLATPAK_REMOTE_REFS FLATPAK_REMOTE_URL _FLATPAK_REPO_GPG _FLATPAK_REPO_URL + _FLATPAK_REPO_GPG := $(shell curl -L $(FLATPAK_REMOTE_URL) | grep -i '^GPGKey=' | cut -d= -f2) +export _FLATPAK_REPO_URL := $(shell curl -L $(FLATPAK_REMOTE_URL) | grep -i '^URL=' | cut -d= -f2) + _LORAX_ARGS += -i flatpak-libs +export _LORAX_TEMPLATES += $(call get_templates,flatpak) \ + external/fedora-lorax-templates/ostree-based-installer/lorax-embed-flatpaks.tmpl + _TEMPLATE_VARS += FLATPAK_DIR FLATPAK_REMOTE_NAME FLATPAK_REMOTE_REFS FLATPAK_REMOTE_URL _FLATPAK_REPO_GPG _FLATPAK_REPO_URL endif endif ifneq ($(SECURE_BOOT_KEY_URL),) -_LORAX_TEMPLATES += $(call get_templates,secureboot) -_TEMPLATE_VARS += ENROLLMENT_PASSWORD +export _LORAX_TEMPLATES += $(call get_templates,secureboot) + _TEMPLATE_VARS += ENROLLMENT_PASSWORD endif -# Step 7: Build end ISO +_SUBDIRS := container external flatpak_refs lorax_templates repos xorriso test + +# Create checksum ## Default action -build/deploy.iso: boot.iso container/$(IMAGE_NAME)-$(IMAGE_TAG) xorriso/input.txt - mkdir $(_BASE_DIR)/build || true - xorriso -dialog on < $(_BASE_DIR)/xorriso/input.txt - implantisomd5 build/deploy.iso +$(ISO_NAME)-CHECKSUM: $(ISO_NAME) + cd $(dir $(ISO_NAME)) && sha256sum $(notdir $(ISO_NAME)) > $(notdir $(ISO_NAME))-CHECKSUM -external/lorax/branch-$(VERSION): - git config advice.detachedHead false - cd external/lorax && git reset --hard HEAD && git checkout tags/$(shell cd external/lorax && git tag -l lorax-$(VERSION).* --sort=creatordate | tail -n 1) - touch external/lorax/branch-$(VERSION) +# Build end ISO +$(ISO_NAME): results/images/boot.iso container/$(IMAGE_NAME)-$(IMAGE_TAG) xorriso/input.txt + $(if $(wildcard $(dir $(ISO_NAME))),,mkdir -p $(dir $(ISO_NAME)); chmod ugo=rwX $(dir $(ISO_NAME))) + xorriso -dialog on < xorriso/input.txt + implantisomd5 $(ISO_NAME) + chmod ugo=r $(ISO_NAME) + $(if $(GITHUB_OUTPUT), echo "iso_name=$(ISO_NAME)" >> $(GITUHB_OUTPUT)) -# Step 1: Generate Lorax Templates -lorax_templates/post_%.tmpl: lorax_templates/scripts/post/% - $(call convert_post_to_tmpl,$*,usr/share/anaconda/post-scripts/$*.ks,true) +# Download the secure boot key +sb_pubkey.der: + curl --fail -L -o sb_pubkey.der $(SECURE_BOOT_KEY_URL) -repos: $(_REPO_FILES) - -# Step 2: Replace vars in repo files -repos/%.repo: /etc/yum.repos.d/%.repo - mkdir repos || true - cp /etc/yum.repos.d/$*.repo $(_BASE_DIR)/repos/$*.repo - sed -i "s/\$$releasever/${VERSION}/g" $(_BASE_DIR)/repos/$*.repo - sed -i "s/\$$basearch/${ARCH}/g" $(_BASE_DIR)/repos/$*.repo - -# Step 3: Build boot.iso using Lorax -boot.iso: external/lorax/branch-$(VERSION) $(filter lorax_templates/%,$(_LORAX_TEMPLATES)) $(_REPO_FILES) - rm -Rf $(_BASE_DIR)/results || true - mv /etc/rpm/macros.image-language-conf $(_TEMP_DIR)/macros.image-language-conf || true - - # Download the secure boot key - if [ -n "$(SECURE_BOOT_KEY_URL)" ]; \ - then \ - curl --fail -L -o $(_BASE_DIR)/sb_pubkey.der $(SECURE_BOOT_KEY_URL); \ - fi +# Build boot.iso using Lorax +results/images/boot.iso: external/lorax/branch-$(VERSION) $(filter lorax_templates/%,$(_LORAX_TEMPLATES)) $(filter repos/%,$(_REPO_FILES)) $(if $(SECURE_BOOT_KEY_URL),sb_pubkey.der) + $(if $(wildcard results), rm -Rf results) + $(if $(wildcard /etc/rpm/macros.image-language-conf),mv /etc/rpm/macros.image-language-conf $(_TEMP_DIR)/macros.image-language-conf) lorax -p $(IMAGE_NAME) -v $(VERSION) -r $(VERSION) -t $(VARIANT) \ - --isfinal --squashfs-only --buildarch=$(ARCH) --volid=$(_VOLID) --sharedir $(_BASE_DIR)/external/lorax/share/templates.d/99-generic \ + --isfinal --buildarch=$(ARCH) --volid=$(_VOLID) --sharedir $(PWD)/external/lorax/share/templates.d/99-generic \ $(_LORAX_ARGS) \ - $(foreach file,$(_REPO_FILES),--repo $(_BASE_DIR)/$(file)) \ - $(foreach file,$(_LORAX_TEMPLATES),--add-template $(_BASE_DIR)/$(file)) \ + $(foreach file,$(_REPO_FILES),--repo $(patsubst repos/%,$(PWD)/repos/%,$(file))) \ + $(foreach file,$(_LORAX_TEMPLATES),--add-template $(PWD)/$(file)) \ $(foreach file,$(ADDITIONAL_TEMPLATES),--add-template $(file)) \ $(foreach file,$(_FLATPAK_TEMPLATES),--add-template $(file)) \ - $(foreach file,$(_EXTERNAL_TEMPLATES),--add-template $(_BASE_DIR)/external/$(file)) \ + $(foreach file,$(_EXTERNAL_TEMPLATES),--add-template $(PWD)/external/$(file)) \ --rootfs-size $(ROOTFS_SIZE) \ $(foreach var,$(_TEMPLATE_VARS),--add-template-var "$(shell echo $(var) | tr '[:upper:]' '[:lower:]')=$($(var))") \ - $(_BASE_DIR)/results/ - mv $(_BASE_DIR)/results/images/boot.iso $(_BASE_DIR)/ - mv -f $(_TEMP_DIR)/macros.image-language-conf /etc/rpm/macros.image-language-conf || true - -# Step 4: Download container image -container/$(IMAGE_NAME)-$(IMAGE_TAG): - mkdir $(_BASE_DIR)/container || true - skopeo copy docker://$(IMAGE_REPO)/$(IMAGE_NAME):$(IMAGE_TAG) oci:$(_BASE_DIR)/container/$(IMAGE_NAME)-$(IMAGE_TAG) - -# Step 5: Generate xorriso script -xorriso/%.sh: xorriso/%.sh.in - sed -i 's/quiet/quiet $(EXTRA_BOOT_PARAMS)/g' results/boot/grub2/grub.cfg - sed -i 's/quiet/quiet $(EXTRA_BOOT_PARAMS)/g' results/EFI/BOOT/grub.cfg - $(eval _VARS = FLATPAK_DIR IMAGE_NAME IMAGE_TAG ARCH VERSION) - $(foreach var,$(_VARS),$(var)=$($(var))) envsubst '$(foreach var,$(_VARS),$$$(var))' < $(_BASE_DIR)/xorriso/$*.sh.in > $(_BASE_DIR)/xorriso/$*.sh - -# Step 6: Generate xorriso input -xorriso/input.txt: xorriso/gen_input.sh - bash $(_BASE_DIR)/xorriso/gen_input.sh | tee $(_BASE_DIR)/xorriso/input.txt + results/ + $(if $(wildcard $(_TEMP_DIR)/macros.image-language-conf),mv -f $(_TEMP_DIR)/macros.image-language-conf /etc/rpm/macros.image-language-conf) +FILES_TO_CLEAN := $(wildcard build debugdata pkglists results original-pkgsizes.txt final-pkgsizes.txt lorax.conf *.iso *log) +.PHONY: clean clean: - rm -Rf $(_BASE_DIR)/build || true - rm -Rf $(_BASE_DIR)/container || true - rm -Rf $(_BASE_DIR)/debugdata || true - rm -Rf $(_BASE_DIR)/pkglists || true - rm -Rf $(_BASE_DIR)/repos || true - rm -Rf $(_BASE_DIR)/results || true - rm -f $(_BASE_DIR)/lorax_templates/*.tmpl || true - rm -f $(_BASE_DIR)/xorriso/input.txt || true - rm -f $(_BASE_DIR)/xorriso/*.sh || true - rm -f $(_BASE_DIR)/{original,final}-pkgsizes.txt || true - rm -f $(_BASE_DIR)/lorax.conf || true - rm -f $(_BASE_DIR)/*.iso || true - rm -f $(_BASE_DIR)/*.log || true + rm -Rf $(FILES_TO_CLEAN) + $(foreach DIR,$(_SUBDIRS),$(MAKE) -w -C $(DIR) clean;) +.PHONY: install-deps install-deps: - if [ "$(PACKAGE_MANAGER)" =~ apt.* ]; then $(PACKAGE_MANAGER) update; fi - $(PACKAGE_MANAGER) install -y lorax xorriso skopeo flatpak dbus-daemon ostree coreutils gettext git - -install-test-deps: - if [ "$(PACKAGE_MANAGER)" =~ apt.* ]; then $(PACKAGE_MANAGER) update; fi - $(PACKAGE_MANAGER) install -y qemu qemu-utils xorriso unzip qemu-system-x86 netcat socat jq isomd5sum ansible make coreutils squashfs-tools + $(install_pkg) lorax xorriso coreutils gettext syslinux-nonlinux + $(foreach DIR,$(filter-out test,$(_SUBDIRS)),$(MAKE) -w -C $(DIR) install-deps;) -test: test-iso test-vm +.PHONY: $(_SUBDIRS) $(wildcard test/*) $(wildcard test/*/*) +test $(addsuffix /*,$(_SUBDIRS)): + $(eval DIR=$(firstword $(subst /, ,$@))) + $(if $(filter-out $(DIR),$@), $(eval TARGET=$(subst $(DIR)/,,$@)),$(eval TARGET=)) + $(MAKE) -w -C $(DIR) $(TARGET) -test-repo: - bash tests/repo/vars.sh - -test-iso: - $(eval _VARS = VERSION FLATPAK_REMOTE_NAME _FLATPAK_REPO_URL) - - sudo modprobe loop - sudo mkdir /mnt/iso /mnt/install - sudo mount -o loop deploy.iso /mnt/iso - sudo mount -t squashfs -o loop /mnt/iso/images/install.img /mnt/install - - # install tests - $(call run_tests,iso,install) - - # flapak tests - if [ -n "$(FLATPAK_REMOTE_REFS)" ]; then $(call run_tests,iso,flatpak); fi - - # Cleanup - sudo umount /mnt/install - sudo umount /mnt/iso - -ansible_inventory: - echo "ungrouped:" > ansible_inventory - echo " hosts:" >> ansible_inventory - echo " vm:" >> ansible_inventory - echo " ansible_host: ${VM_IP}" >> ansible_inventory - echo " ansible_port: ${VM_PORT}" >> ansible_inventory - echo " ansible_user: ${VM_USER}" >> ansible_inventory - echo " ansible_password: ${VM_PASS}" >> ansible_inventory - echo " ansible_become_pass: ${VM_PASS}" >> ansible_inventory - echo " ansible_ssh_common_args: '-o StrictHostKeyChecking=no'" >> ansible_inventory - -test-vm: ansible_inventory - $(eval _VARS = IMAGE_REPO IMAGE_NAME IMAGE_TAG) - - ansible -i ansible_inventory -m ansible.builtin.wait_for_connection vm - - # install tests - $(call run_tests,vm,install) - - # flapak tests - if [ -n "$(FLATPAK_REMOTE_REFS)" ]; then $(call run_tests,vm,flatpak); fi - -.PHONY: clean install-deps install-test-deps test test-iso test-vm +.DEFAULT: + $(eval DIR=$(firstword $(subst /, ,$@))) + $(if $(filter-out $(DIR),$@), $(eval TARGET=$(subst $(DIR)/,,$@)),$(eval TARGET=)) + $(MAKE) -w -C $(DIR) $(TARGET) diff --git a/Makefile.inputs b/Makefile.inputs new file mode 100644 index 0000000..a77e4f2 --- /dev/null +++ b/Makefile.inputs @@ -0,0 +1,26 @@ +# Configuration vars +## Formatting = UPPERCASE +# General +export ADDITIONAL_TEMPLATES := +export ARCH := x86_64 +export EXTRA_BOOT_PARAMS := +export IMAGE_NAME := base +export IMAGE_REPO := quay.io/fedora-ostree-desktops +export IMAGE_SRC := +export IMAGE_TAG = $(VERSION) +export IMAGE_SIGNED := true + REPOS := $(subst :,\:,$(wildcard /etc/yum.repos.d/*.repo)) +export ROOTFS_SIZE := 4 +export VARIANT := Server +export VERSION := 39 +export WEB_UI := false +# Flatpak +export FLATPAK_REMOTE_NAME := flathub +export FLATPAK_REMOTE_URL := https://flathub.org/repo/flathub.flatpakrepo +export FLATPAK_REMOTE_REFS := +export FLATPAK_REMOTE_REFS_DIR := +export FLATPAK_DIR := +# Secure boot +export ENROLLMENT_PASSWORD := +export SECURE_BOOT_KEY_URL := +export ISO_NAME := build/deploy.iso diff --git a/README.md b/README.md index f386545..fdea723 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,14 @@ -![Build status](https://github.com/jasonn3/build-container-installer/actions/workflows/tests.yml/badge.svg?event=push) +[![Build status](https://github.com/jasonn3/build-container-installer/actions/workflows/tests.yml/badge.svg?event=push)](https://github.com/jasonn3/build-container-installer/actions/workflows/tests.yml) +[![Codacy Badge](https://app.codacy.com/project/badge/Grade/35a48e77e64f469ba19d60a1a1e0be71)](https://app.codacy.com/gh/JasonN3/build-container-installer/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) # Build Container Installer Action -This action is used to enerate an ISO for installing an OSTree stored in a container image. This utilizes the anaconda command `ostreecontainer` + +This action is used to generate an ISO for installing an OSTree stored in a container image. This utilizes the anaconda command `ostreecontainer`, which also supports bootc. ## Usage + This action is designed to be called from a GitHub workflow using the following format + ```yaml - name: Build ISO uses: jasonn3/build-container-installer@main @@ -25,120 +29,22 @@ This action is designed to be called from a GitHub workflow using the following with: name: ${{ steps.build.outputs.iso_name }} path: | - ${{ steps.build.outputs.iso_path }} - ${{ steps.build.outputs.iso_path }}-CHECKSUM - if-no-files-found: error - retention-days: 0 - compression-level: 0 + ${{ steps.build.outputs.iso_path }}/${{ steps.build.outputs.iso_name }} + ${{ steps.build.outputs.iso_path }}/${{ steps.build.outputs.iso_name }}-CHECKSUM + if-no-files-found: error + retention-days: 0 + compression-level: 0 ``` -See [Customizing](#customizing) for information about customizing the ISO that gets created using `with` +**See the [Wiki](https://github.com/JasonN3/build-container-installer/wiki) for development and usage information.** -## Customizing -The following variables can be used to customize the created ISO. -### Inputs -| Variable | Description | Default Value | Action | Container | Makefile | -| ----------------------- | ---------------------------------------------------------------------------- | -------------------------------------------- | ------------------ | ------------------ | ------------------ | -| additional_templates | Space delimited list of additional Lorax templates to include | \[empty\] | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| arch | Architecture for image to build | x86_64 | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| enrollment_password | Used for supporting secure boot (requires SECURE_BOOT_KEY_URL to be defined) | container-installer | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| extra_boot_params | Extra params used by grub to boot the anaconda installer | \[empty\] | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| flatpak_remote_name | Name of the Flatpak repo on the destination OS | flathub | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| flatpak_remote_refs | Space separated list of flatpak refs to install | \[empty\] | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| flatpak_remote_refs_dir | Directory that contains files that list the flatpak refs to install | \[empty\] | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| flatpak_remote_url | URL of the flatpakrepo file | https://flathub.org/repo/flathub.flatpakrepo | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| image_name | Name of the source container image | base | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| image_repo | Repository containing the source container image | quay.io/fedora-ostree-desktops | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| image_tag | Tag of the source container image | *VERSION* | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| iso_name | Name of the ISO you wish to output when completed | build/deploy.iso | :white_check_mark: | :x: | :x: | -| repos | List of repo files for Lorax to use | /etc/yum.repos.d/*.repo | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| rootfs_size | The size (in GiB) for the squashfs runtime volume | 2 | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| secure_boot_key_url | Secure boot key that is installed from URL location\*\* | \[empty\] | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| variant | Source container variant\* | Server | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| version | Fedora version of installer to build | 39 | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| web_ui | Enable Anaconda WebUI (experimental) | false | :white_check_mark: | :white_check_mark: | :white_check_mark: | +## Star History -\*Available options for VARIANT can be found by running `dnf provides system-release`. -Variant will be the third item in the package name. Example: `fedora-release-kinoite-39-34.noarch` will be kinoite - -\*\* If you need to reference a local file, you can use `file://*path*` - -### Outputs -| Variable | Description | Usage | -| -------- | ----------------------------------------| ------------------------------------------------ | -| iso_name | The name of the resulting .iso | ${{ steps.YOUR_ID_FOR_ACTION.outputs.iso_name }} | -| iso_path | The name and path of the resulting .iso | ${{ steps.YOUR_ID_FOR_ACTION.outputs.iso_name }} | - -For outputs, see example above. - -## Development -### Makefile -The Makefile contains all of the commands that are run in the action. There are separate targets for each file generated, however `make` can be used to generate the final image and `make clean` can be used to clean up the workspace. The resulting ISO will be stored in the `build` directory. - -`make install-deps` can be used to install the necessary packages - -See [Customizing](#customizing) for information about customizing the ISO that gets created. All variable should be specified CAPITALIZED. - -### Container -A container with `make install-deps` already run is provided at `ghcr.io/jasonn3/build-container-installer:latest` - -To use the container file, run `docker run --privileged --volume .:/build-container-installer/build ghcr.io/jasonn3/build-container-installer:latest`. - -This will create an ISO with the baked in defaults of the container image. The resulting file will be called `deploy.iso` - -See [Customizing](#customizing) for information about customizing the ISO that gets created. The variable can either be defined as environment variables. All variable should be specified CAPITALIZED. -Examples: - -Building an ISO to install Fedora 38 -```bash -docker run --rm --privileged --volume .:/github/workspace/build ghcr.io/jasonn3/build-container-installer:latest VERSION=38 IMAGE_NAME=base IMAGE_TAG=38 VARIANT=Server -``` - -Building an ISO to install Fedora 39 -```bash -docker run --rm --privileged --volume .:/github/workspace/build ghcr.io/jasonn3/build-container-installer:latest VERSION=39 IMAGE_NAME=base IMAGE_TAG=39 VARIANT=Server -``` - -### VSCode Dev Container -There is a dev container configuration provided for development. By default it will use the existing container image available at `ghcr.io/jasonn3/build-container-installer:latest`, however, you can have it build a new image by editing `.devcontainer/devcontainer.json` and replacing `image` with `build`. `Ctrl+/` can be used to comment and uncomment blocks of code within VSCode. - -The code from VSCode will be available at `/workspaces/build-container-installer` once the container has started. - -Privileged is required for access to loop devices for lorax. - -Use existing container image: -``` -{ - "name": "Existing Dockerfile", - // "build": { - // "context": "..", - // "dockerfile": "../Containerfile", - // "args": { - // "version": "39" - // } - // }, - "image": "ghcr.io/jasonn3/build-container-installer:latest", - "overrideCommand": true, - "shutdownAction": "stopContainer", - "privileged": true -} -``` - -Build a new container image: -``` -{ - "name": "Existing Dockerfile", - "build": { - "context": "..", - "dockerfile": "../Containerfile", - "args": { - "version": "39" - } - }, - //"image": "ghcr.io/jasonn3/build-container-installer:latest", - "overrideCommand": true, - "shutdownAction": "stopContainer", - "privileged": true -} -``` + + + + + Star History Chart + + diff --git a/action.yml b/action.yml index c856f54..3615f05 100644 --- a/action.yml +++ b/action.yml @@ -29,18 +29,18 @@ inputs: required: false default: "true" enrollment_password: - description: Used for supporting secure boot (requires secure_boot_key_url to be defined) + description: Used for supporting secure boot (requires SECURE_BOOT_KEY_URL to be defined) required: false default: "container-installer" extra_boot_params: description: Extra params used by grub to boot the anaconda installer required: false flatpak_remote_name: - description: Name of the Flatpak remote repo + description: Name of the Flatpak repo on the destination OS required: false default: "flathub" flatpak_remote_refs: - description: Space delimited list of refs to the flatpak packages to install + description: Space separated list of flatpak refs to install required: false default: "" flatpak_remote_refs_dir: @@ -48,7 +48,7 @@ inputs: required: false default: "" flatpak_remote_url: - description: The URL of the Flatpak remote flatpakrepo file + description: URL of the flatpakrepo file required: false default: https://flathub.org/repo/flathub.flatpakrepo image_name: @@ -59,18 +59,29 @@ inputs: description: Repository containing the source container image required: true default: quay.io/fedora-ostree-desktops + image_signed: + description: Whether the container image is signed. The policy to test the signing must be configured inside the container image + required: false + default: "true" + image_src: + description: Overrides the source of the container image. Must be formatted for the skopeo copy command + required: false image_tag: - description: Tag of the source container image. Defaults to the installer version + description: Tag of the source container image required: false iso_name: - description: "Name of the resulting ISO. Relative paths are relative to github.workspace" + description: Name of the ISO you wish to output when completed required: false default: build/deploy.iso + make_target: + description: Overrides the default make target + required: false repos: description: List of repo files for Lorax to use required: false rootfs_size: description: The size (in GiB) for the squashfs runtime volume + default: "2" secure_boot_key_url: description: Secure boot key that is installed from URL location required: false @@ -78,7 +89,7 @@ inputs: description: Overrides the skopeo cache key required: false variant: - description: "Source container variant. Available options can be found by running `dnf provides system-release`. Variant will be the third item in the package name. Example: `fedora-release-kinoite-39-34.noarch` will be kinonite" + description: "Source container variant. Available options can be found by running `dnf provides system-release`. Variant will be the third item in the package name. Example: `fedora-release-kinoite-39-34.noarch` will be kinoite" required: true default: Server version: @@ -92,11 +103,14 @@ inputs: outputs: iso_name: - value: ${{ steps.rename_iso.outputs.iso_name }} + value: ${{ steps.docker.outputs.iso_name }} description: The name of the resulting .iso iso_path: - value: ${{ steps.rename_iso.outputs.iso_path }} - description: The name and path of the resulting .iso + value: ${{ steps.docker.outputs.iso_path }} + description: The path of the resulting .iso + flatpak_refs: + value: ${{ steps.docker.outputs.flatpak_refs }} + description: The list of Flatpak refs runs: using: composite @@ -135,49 +149,30 @@ runs: mkdir /cache/skopeo || true - name: Determine Flatpak dependencies - if: inputs.enable_flatpak_dependencies == 'true' + if: inputs.enable_flatpak_dependencies == 'true' && (inputs.flatpak_remote_refs != '' || inputs.flatpak_remote_refs_dir != '') id: flatpak_dependencies shell: bash run: | - image="${{ inputs.image_repo }}/${{ inputs.image_name }}:${{ inputs.image_tag }}" - # Make temp space - FLATPAK_DIR=$(basename $(mktemp -d -p ${{ github.workspace }} flatpak.XXX)) - # Get list of refs from directory - sudo mkdir /github || true - sudo ln -s ${{ github.workspace }} /github/workspace - DIR_REFS=$(cat ${{ inputs.flatpak_remote_refs_dir }}/* | tr '\n' ' ' ) - # Generate install script - cat << EOF > ${{ github.workspace }}/${FLATPAK_DIR}/script.sh - cat /flatpak_dir/script.sh - mkdir -p /flatpak/flatpak /flatpak/triggers - mkdir /var/tmp || true - chmod -R 1777 /var/tmp - flatpak config --system --set languages "*" - flatpak remote-add --system ${{ inputs.flatpak_remote_name }} ${{ inputs.flatpak_remote_url }} - flatpak install --system -y ${{ inputs.flatpak_remote_refs }} ${DIR_REFS} - ostree init --repo=/flatpak_dir/repo --mode=archive-z2 - for i in \$(ostree refs --repo=\${FLATPAK_SYSTEM_DIR}/repo | grep '^deploy/' | sed 's/^deploy\///g') - do - echo "Copying \${i}..." - ostree --repo=/flatpak_dir/repo pull-local \${FLATPAK_SYSTEM_DIR}/repo \$(ostree --repo=\${FLATPAK_SYSTEM_DIR}/repo rev-parse ${{ inputs.flatpak_remote_name }}/\${i}) - mkdir -p \$(dirname /flatpak_dir/repo/refs/heads/\${i}) - ostree --repo=\${FLATPAK_SYSTEM_DIR}/repo rev-parse ${{ inputs.flatpak_remote_name }}/\${i} > /flatpak_dir/repo/refs/heads/\${i} - done - flatpak build-update-repo /flatpak_dir/repo - ostree refs --repo=/flatpak_dir/repo - EOF - docker run --rm --privileged --entrypoint bash -e FLATPAK_SYSTEM_DIR=/flatpak/flatpak -e FLATPAK_TRIGGERSDIR=/flatpak/triggers --volume ${{ github.workspace }}/${FLATPAK_DIR}:/flatpak_dir ${image} /flatpak_dir/script.sh - echo "flatpak_dir=${FLATPAK_DIR}" >> $GITHUB_OUTPUT - docker rmi ${image} + cd ${{ github.action_path }} + make flatpaks/repo \ + FLATPAK_REMOTE_NAME="${{ inputs.flatpak_remote_name }}" \ + ${{ inputs.flatpak_remote_refs && format('FLATPAK_REMOTE_REFS="{0}"', inputs.flatpak_remote_refs) || ''}} \ + ${{ inputs.flatpak_remote_refs_dir && format('FLATPAK_REMOTE_REFS_DIR="{0}/{1}"', github.workspace, inputs.flatpak_remote_refs_dir) || ''}} \ + FLATPAK_REMOTE_URL="${{ inputs.flatpak_remote_url }}" \ + IMAGE_NAME="${{ inputs.image_name }}" \ + IMAGE_REPO="${{ inputs.image_repo }}" \ + IMAGE_SRC="${{ inputs.image_src }}" \ + IMAGE_TAG="${{ inputs.image_tag || inputs.version }}" - name: Run docker image + id: docker env: ACTION_REPO: ${{ github.action_repository }} ACTION_REF: ${{ github.action_ref }} shell: bash run: | image=$(echo "ghcr.io/${ACTION_REPO}" | tr [:upper:] [:lower:]) - # Check if running inside01 of the action repo + # Check if running inside of the action repo if [[ -z "${ACTION_REPO}" ]] then image=$(echo "ghcr.io/${{ github.repository }}" | tr [:upper:] [:lower:]) @@ -207,30 +202,43 @@ runs: then echo "ERROR: flatpak_remote_refs is mutually exclusive to flatpak_remote_refs_dir" exit 1 - else - if [[ -n "${{ inputs.flatpak_remote_refs }}" ]] - then - vars="${vars} FLATPAK_REMOTE_REFS=\"${{ inputs.flatpak_remote_refs }}\"" - else - vars="${vars} FLATPAK_REMOTE_REFS_DIR=\"${{ inputs.flatpak_remote_refs_dir }}\"" - fi fi docker run --privileged --volume ${{ github.workspace }}:/github/workspace/ ${cache} ${image}:${tag} \ + ${{ inputs.make_target }} \ ADDITIONAL_TEMPLATES="${{ inputs.additional_templates }}" \ ARCH="${{ inputs.arch }}" \ DNF_CACHE="/cache/dnf" \ ENROLLMENT_PASSWORD="${{ inputs.enrollment_password }}" \ + EXTRA_BOOT_PARAMS="${{ inputs.extra_boot_params }}" \ FLATPAK_REMOTE_NAME="${{ inputs.flatpak_remote_name }}" \ - ${vars} \ + ${{ inputs.flatpak_remote_refs && format('FLATPAK_REMOTE_REFS="{0}"', inputs.flatpak_remote_refs) || ''}} \ + ${{ inputs.flatpak_remote_refs_dir && format('FLATPAK_REMOTE_REFS_DIR="/github/workspace/{0}"', inputs.flatpak_remote_refs_dir) || ''}} \ FLATPAK_REMOTE_URL="${{ inputs.flatpak_remote_url }}" \ FLATPAK_DIR="${{ steps.flatpak_dependencies.outputs.flatpak_dir && format('/github/workspace/{0}', steps.flatpak_dependencies.outputs.flatpak_dir) || '' }}" \ IMAGE_NAME="${{ inputs.image_name }}" \ IMAGE_REPO="${{ inputs.image_repo }}" \ + IMAGE_SIGNED="${{ inputs.image_signed }}" \ + IMAGE_SRC="${{ inputs.image_src }}" \ IMAGE_TAG="${{ inputs.image_tag || inputs.version }}" \ + ISO_NAME=/github/workspace/${{ inputs.iso_name }} \ + ${{ inputs.repos && format('REPOS="{0}"', inputs.repos) || '' }} \ SECURE_BOOT_KEY_URL="${{ inputs.secure_boot_key_url }}" \ VARIANT="${{ inputs.variant }}" \ VERSION="${{ inputs.version }}" \ WEB_UI="${{ inputs.web_ui }}" + echo "iso_path=$(dirname ${{ inputs.iso_name }})" >> $GITHUB_OUTPUT + echo "iso_name=$(basename ${{ inputs.iso_name }})" >> $GITHUB_OUTPUT + if [[ "${{ steps.flatpak_dependencies.outputs.flatpak_dir }}" != '' ]] + then + echo "flatpak_refs=$(cat ${{ github.workspace }}/${{ steps.flatpak_dependencies.outputs.flatpak_dir }}/list.txt | tr '\n' ' ')" >> $GITHUB_OUTPUT + else + if [[ "${{ inputs.flatpak_remote_refs_dir }}" != '' ]] + then + echo "flatpak_refs=$(cat ${{ github.workspace }}/${{ inputs.flatpak_remote_refs_dir }}/* | tr '\n' ' ')" >> $GITHUB_OUTPUT + else + echo "flatpak_refs=${{ inputs.flatpak_remote_refs}}" >> $GITHUB_OUTPUT + fi + fi - name: Save dnf cache env: @@ -249,27 +257,3 @@ runs: with: path: /cache/skopeo key: ${{ inputs.skopeo_cache_key || env.skopeo_cache_key }} - - - - name: Rename ISO file - id: rename_iso - shell: bash - run: | - if [[ ! ( "${{ inputs.iso_name }}" =~ \.iso$ ) ]] - then - iso_name="${{ inputs.iso_name }}.iso" - else - iso_name="${{ inputs.iso_name }}" - fi - if [[ "${{ inputs.iso_name }}" =~ ^/ ]] - then - full_path="${iso_name}" - else - full_path="${{ github.workspace }}/${iso_name}" - fi - mv ${{ github.workspace }}/build/deploy.iso ${full_path} || true - cd $(dirname ${full_path}) - iso_fn=$(basename ${iso_name}) - sha256sum ${iso_fn} > ${iso_fn}-CHECKSUM - echo "iso_path=${full_path}" >> $GITHUB_OUTPUT - echo "iso_name=${iso_fn}" >> $GITHUB_OUTPUT diff --git a/container/Makefile b/container/Makefile new file mode 100644 index 0000000..9e662dc --- /dev/null +++ b/container/Makefile @@ -0,0 +1,11 @@ +$(IMAGE_NAME)-$(IMAGE_TAG): + skopeo copy $(if $(IMAGE_SRC),$(IMAGE_SRC),docker://$(IMAGE_REPO)/$(IMAGE_NAME):$(IMAGE_TAG)) oci:$(IMAGE_NAME)-$(IMAGE_TAG) + +install-deps: + $(install_pkg) skopeo + +FILES=$(filter-out Makefile,$(wildcard *)) +clean: +ifneq ($(FILES),) + rm -Rf $(FILES) +endif \ No newline at end of file diff --git a/cosign.pub b/cosign.pub new file mode 100644 index 0000000..4d5e06d --- /dev/null +++ b/cosign.pub @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEY4ljyIhI2w9DOptB4WT20S+K5ts3 +GJTEKRkXmIYEXGfyKpJMdlGCWeg2kOam5dNhWKXXl46d3eBBo9S53TPpyQ== +-----END PUBLIC KEY----- diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..49f871b --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,12 @@ +SHELL = /bin/bash + +docs: + find -name '*.md' -print0 | xargs -0 -I {} bash -c ' \ + source_file=$${1:2}; \ + final_file=$${source_file//\//_}; \ + mv "$${source_file}" "$${final_file}"; \ + no_ext_source=$${source_file:0:-3}; \ + no_ext_final=$${final_file:0:-3}; \ + sed -i "s;(\(../\)*$${source_file});($${no_ext_final});g" $$(find -name '\''*.md'\''); \ + ' _ {} + find . -type d -empty -delete diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..2091ec8 --- /dev/null +++ b/docs/README.md @@ -0,0 +1 @@ +These are the files for the [wiki](https://github.com/JasonN3/build-container-installer/wiki) \ No newline at end of file diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md new file mode 100644 index 0000000..7e637e7 --- /dev/null +++ b/docs/_Sidebar.md @@ -0,0 +1,11 @@ +- [Home](home.md) +- [Usage](usage.md) +- Development + - [Using the Makefile](development/makefile.md) + - [Using the Container](development/container.md) + - [Using the VSCode Dev Container](development/vscode.md) + +- Examples + - [Adding Flatpaks](examples/adding-flatpaks.md) + +- [Known Errors](known_errors.md) diff --git a/docs/development/container.md b/docs/development/container.md new file mode 100644 index 0000000..0e0a0ef --- /dev/null +++ b/docs/development/container.md @@ -0,0 +1,22 @@ +# Using the Container + +A container with `make install-deps` already run is provided at `ghcr.io/jasonn3/build-container-installer:latest` + +To use the container file, run `podman run --privileged --volume .:/build-container-installer/build ghcr.io/jasonn3/build-container-installer:latest`. + +This will create an ISO with the baked in defaults of the container image. The resulting file will be called `deploy.iso` + +See [Inputs](usage#inputs) for information about customizing the ISO that gets created. The variables can be defined as environment variables or command arguments. All variables should be specified in CAPITALIZED form. +Examples: + +Building an ISO to install Fedora 39 +```bash +podman run --rm --privileged --volume .:/build-container-installer/build ghcr.io/jasonn3/build-container-installer:latest VERSION=39 IMAGE_NAME=base IMAGE_TAG=39 VARIANT=Server +``` + +Building an ISO to install Fedora 40 +```bash +podman run --rm --privileged --volume .:/build-container-installer/build ghcr.io/jasonn3/build-container-installer:latest VERSION=40 IMAGE_NAME=base IMAGE_TAG=40 VARIANT=Server +``` + +The same commands are also available using `docker` by replacing `podman` with `docker` in each command. diff --git a/docs/development/makefile.md b/docs/development/makefile.md new file mode 100644 index 0000000..be37851 --- /dev/null +++ b/docs/development/makefile.md @@ -0,0 +1,7 @@ +# Using the Makefile + +The Makefile contains all the commands that are run in the action. There are separate targets for each file generated, however `make` can be used to generate the final image and `make clean` can be used to clean up the workspace. The resulting ISO will be stored in the `build` directory. + +`make install-deps` can be used to install the necessary packages. + +See [Inputs](usage#inputs) for information about the available parameters. All variables should be specified in CAPITALIZED form. diff --git a/docs/development/vscode.md b/docs/development/vscode.md new file mode 100644 index 0000000..4b22fe9 --- /dev/null +++ b/docs/development/vscode.md @@ -0,0 +1,46 @@ +# Using the VSCode Dev Container + +There is a dev container configuration provided for development. By default, it will use the existing container image available at `ghcr.io/jasonn3/build-container-installer:latest`. However, you can have it build a new image by editing `.devcontainer/devcontainer.json` and replacing `image` with `build`. `Ctrl+/` can be used to comment and uncomment blocks of code within VSCode. + +The code from VSCode will be available at `/workspaces/build-container-installer` once the container has started. + +Privileged is required for access to loop devices for lorax. + +## Use existing container image + +```diff +{ + "name": "Existing Image", +- "build": { +- "context": "..", +- "dockerfile": "../Containerfile", +- "args": { +- "version": "39" +- } +- }, ++ "image": "ghcr.io/jasonn3/build-container-installer:latest", + "overrideCommand": true, + "shutdownAction": "stopContainer", + "privileged": true +} +``` + +## Build a new container image + +```diff +{ + "name": "New Image", ++ "build": { ++ "context": "..", ++ "dockerfile": "../Containerfile", ++ "args": { ++ "version": "39" ++ } ++ }, +- "image": "ghcr.io/jasonn3/build-container-installer:latest", + "overrideCommand": true, + "shutdownAction": "stopContainer", + "privileged": true +} +``` + diff --git a/docs/examples/adding-flatpaks.md b/docs/examples/adding-flatpaks.md new file mode 100644 index 0000000..153b740 --- /dev/null +++ b/docs/examples/adding-flatpaks.md @@ -0,0 +1,74 @@ +# Adding Flatpaks + +- [Directly using refs](#directly-using-refs) +- [Using a directory](#using-a-directory) + +## Directly using refs + +Action: +Specify the following in your workflow: + +```yaml +- name: Build ISO + uses: jasonn3/build-container-installer@main + id: build + with: + flatpak_remote_name: flathub + flatpak_remote_url: https://flathub.org/repo/flathub.flatpakrepo + flatpak_remote_refs: app/org.videolan.VLC/x86_64/stable runtime/org.kde.Platform/x86_64/5.15-23.08 +``` + +Podman: +Run the following command: + +```bash +podman run --privileged --volume ./:/github/workspace/ ghcr.io/jasonn3/build-container-installer:main \ + FLATPAK_REMOTE_NAME=flathub \ + FLATPAK_REMOTE_URL=https://flathub.org/repo/flathub.flatpakrepo \ + FLATPAK_REMOTE_REFS="app/org.videolan.VLC/x86_64/stable runtime/org.kde.Platform/x86_64/5.15-23.08" +``` + +--- + +## Using a directory + +Action: + +1. Create a directory within your GitHub repo named flatpak_refs +1. Create a file within flatpak_refs with the following content + +```plaintext +app/org.videolan.VLC/x86_64/stable +runtime/org.kde.Platform/x86_64/5.15-23.08 +``` + +Specify the following in your workflow: + +```yaml +- name: Build ISO + uses: jasonn3/build-container-installer@main + id: build + with: + flatpak_remote_name: flathub + flatpak_remote_url: https://flathub.org/repo/flathub.flatpakrepo + flatpak_remote_refs_dir: /github/workspace/flatpak_refs +``` + +Podman: + +1. Create a directory named flatpak_refs +1. Create a file within flatpak_refs with the following content + +```plaintext +app/org.videolan.VLC/x86_64/stable +runtime/org.kde.Platform/x86_64/5.15-23.08 +``` + +Run the following command: + +```bash +podman run --privileged --volume ./:/github/workspace/ ghcr.io/jasonn3/build-container-installer:main \ + FLATPAK_REMOTE_NAME=flathub \ + FLATPAK_REMOTE_URL=https://flathub.org/repo/flathub.flatpakrepo \ + FLATPAK_REMOTE_REFS="app/org.videolan.VLC/x86_64/stable runtime/org.kde.Platform/x86_64/5.15-23.08" +``` diff --git a/docs/home.md b/docs/home.md new file mode 100644 index 0000000..f7e2096 --- /dev/null +++ b/docs/home.md @@ -0,0 +1,14 @@ +Welcome to the build-container-installer wiki! + +## Index + +- [Usage](usage.md) +- Development + - [Using the Makefile](development/makefile.md) + - [Using the Container](development/container.md) + - [Using the VSCode Dev Container](development/vscode.md) + +- Examples + - [Adding Flatpaks](examples/adding-flatpaks.md) + +- [Known Errors](known_errors.md) diff --git a/docs/known_errors.md b/docs/known_errors.md new file mode 100644 index 0000000..bda0b22 --- /dev/null +++ b/docs/known_errors.md @@ -0,0 +1,7 @@ +# Known Errors + +This page describes known errors and how to resolve them. + +## failed to write boot loader configuration + +Add `RUN bootupctl backend generate-update-metadata` at the end of your Dockerfile/Containerfile \ No newline at end of file diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..9ffeb8e --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,68 @@ +# Usage + +This action is designed to be called from a GitHub workflow using the following format + +```yaml +- name: Build ISO + uses: jasonn3/build-container-installer@main + id: build + with: + arch: ${{ env.ARCH}} + image_name: ${{ env.IMAGE_NAME}} + image_repo: ${{ env.IMAGE_REPO}} + image_tag: ${{ env.IMAGE_TAG }} + version: ${{ env.VERSION }} + variant: ${{ env.VARIANT }} + iso_name: ${{ env.IMAGE_NAME }}-${{ env.IMAGE_TAG }}-${{ env.VERSION }}.iso + +# This example is for uploading your ISO as a Github artifact. You can do something similar using any cloud storage, so long as you copy the output +- name: Upload ISO as artifact + id: upload + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.build.outputs.iso_name }} + path: | + ${{ steps.build.outputs.iso_path }}/${{ steps.build.outputs.iso_name }} + ${{ steps.build.outputs.iso_path }}/${{ steps.build.outputs.iso_name }}-CHECKSUM + if-no-files-found: error + retention-days: 0 + compression-level: 0 +``` + +## Inputs + +| Variable | Description | Default Value | Action | Container/Makefile | +| ----------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------- | ------------------ | ------------------ | +| additional_templates | Space delimited list of additional Lorax templates to include | \[empty\] | :white_check_mark: | :white_check_mark: | +| arch | Architecture for image to build | x86_64 | :white_check_mark: | :white_check_mark: | +| enrollment_password | Used for supporting secure boot (requires SECURE_BOOT_KEY_URL to be defined) | container-installer | :white_check_mark: | :white_check_mark: | +| extra_boot_params | Extra params used by grub to boot the anaconda installer | \[empty\] | :white_check_mark: | :white_check_mark: | +| flatpak_remote_name | Name of the Flatpak repo on the destination OS | flathub | :white_check_mark: | :white_check_mark: | +| flatpak_remote_refs | Space separated list of flatpak refs to install | \[empty\] | :white_check_mark: | :white_check_mark: | +| flatpak_remote_refs_dir | Directory that contains files that list the flatpak refs to install | \[empty\] | :white_check_mark: | :white_check_mark: | +| flatpak_remote_url | URL of the flatpakrepo file | | :white_check_mark: | :white_check_mark: | +| image_name | Name of the source container image | base | :white_check_mark: | :white_check_mark: | +| image_repo | Repository containing the source container image | quay.io/fedora-ostree-desktops | :white_check_mark: | :white_check_mark: | +| image_signed | Whether the container image is signed. The policy to test the signing must be configured inside the container image | true | :white_check_mark: | :white_check_mark: | +| image_src | Overrides the source of the container image. Must be formatted for the skopeo copy command | \[empty\] | :white_check_mark: | :white_check_mark: | +| image_tag | Tag of the source container image | *VERSION* | :white_check_mark: | :white_check_mark: | +| iso_name | Name of the ISO you wish to output when completed | build/deploy.iso | :white_check_mark: | :white_check_mark: | +| make_target | Overrides the default make target | *ISO_NAME*-Checksum | :white_check_mark: | :x: | +| repos | List of repo files for Lorax to use | /etc/yum.repos.d/*.repo | :white_check_mark: | :white_check_mark: | +| rootfs_size | The size (in GiB) for the squashfs runtime volume | 2 | :white_check_mark: | :white_check_mark: | +| secure_boot_key_url | Secure boot key that is installed from URL location\*\* | \[empty\] | :white_check_mark: | :white_check_mark: | +| variant | Source container variant\* | Server | :white_check_mark: | :white_check_mark: | +| version | Fedora version of installer to build | 39 | :white_check_mark: | :white_check_mark: | +| web_ui | Enable Anaconda WebUI (experimental) | false | :white_check_mark: | :white_check_mark: | + +\*Available options for VARIANT can be found by running `dnf provides system-release`. +Variant will be the third item in the package name. Example: `fedora-release-kinoite-39-34.noarch` will be kinoite + +\*\* If you need to reference a local file, you can use `file://*path*` + +## Outputs + +| Variable | Description | Usage | +| -------- | ----------------------------------------| ------------------------------------------------ | +| iso_name | The name of the resulting .iso | ${{ steps.YOUR_ID_FOR_ACTION.outputs.iso_name }} | +| iso_path | The path to the resulting .iso | ${{ steps.YOUR_ID_FOR_ACTION.outputs.iso_path }} | diff --git a/entrypoint.sh b/entrypoint.sh index e7c579f..ba58634 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -5,13 +5,6 @@ set -ex # Create /dev/loop0 if it doesn't already exist. `losetup` has an issue creating it during the first run mknod -m 0660 /dev/loop0 b 7 0 2>/dev/null || true -for i -do - key=$(echo ${i} | cut -d= -f1) - value=$(echo ${i} | cut -d= -f2-) - export ${key}="${value}" -done - if [[ -d /cache/skopeo ]] then ln -s /cache/skopeo /build-container-installer/container @@ -22,18 +15,5 @@ then mkdir /cache/dnf fi -# Pull container -make container/${IMAGE_NAME}-${IMAGE_TAG} "$@" - -# Build base ISO -make boot.iso "$@" - -# Add container to ISO -make build/deploy.iso "$@" - -# Make output dir in github workspace -mkdir /github/workspace/build || true - -# Copy resulting iso to github workspace and fix permissions -cp build/deploy.iso /github/workspace/build -chmod -R ugo=rwX /github/workspace/build +# Run make command +make "$@" diff --git a/external/Makefile b/external/Makefile new file mode 100644 index 0000000..0cac3e7 --- /dev/null +++ b/external/Makefile @@ -0,0 +1,12 @@ +lorax/branch-$(VERSION): + git config advice.detachedHead false + cd lorax && git reset --hard HEAD && git checkout $(if $(_RHEL),rhel$(word 1,$(subst ., ,$(VERSION)))-branch,tags/$(shell cd lorax && git tag -l lorax-$(VERSION).* --sort=creatordate | grep -v 'lorax-40\.5' | tail -n 1)) + touch lorax/branch-$(VERSION) + +install-deps: +# Used by external/fedora-lorax-templates/ostree-based-installer/lorax-embed-flatpaks.tmpl + $(install_pkg) flatpak dbus-daemon ostree +# Used to clone proper lorax branch + $(install_pkg) git + +clean: \ No newline at end of file diff --git a/flatpaks/Makefile b/flatpaks/Makefile new file mode 100644 index 0000000..7729d01 --- /dev/null +++ b/flatpaks/Makefile @@ -0,0 +1,43 @@ +IMAGE := $(IMAGE_REPO)/$(IMAGE_NAME):$(IMAGE_TAG) +FLATPAK_DIR := $(if $(GITHUB_WORKSPACE),$(shell mktemp -d -p $(GITHUB_WORKSPACE) flatpak.XXX),$(PWD)/flatpaks) + +.PHONY: full_list +full_list: repo + cat $(FLATPAK_DIR)/list.txt >&2 + + +repo: script.sh + $(if $(GITHUB_WORKSPACE),cp script.sh $(FLATPAK_DIR)/) + docker run --rm --privileged --entrypoint bash -e FLATPAK_SYSTEM_DIR=/flatpak/flatpak -e FLATPAK_TRIGGERSDIR=/flatpak/triggers --volume $(FLATPAK_DIR):/flatpak_dir $(IMAGE) /flatpak_dir/script.sh + $(if $(GITHUB_OUTPUT),echo "flatpak_dir=$(subst $(GITHUB_WORKSPACE)/,,$(FLATPAK_DIR))" >> $(GITHUB_OUTPUT)) + docker rmi $(IMAGE) + +script.sh: + cat << EOF > script.sh + which flatpak &> /dev/null || dnf install -y flatpak + mkdir -p /flatpak/flatpak /flatpak/triggers + mkdir /var/tmp || true + chmod -R 1777 /var/tmp + flatpak config --system --set languages "*" + flatpak remote-add --system $(FLATPAK_REMOTE_NAME) $(FLATPAK_REMOTE_URL) + flatpak install --system -y $(FLATPAK_REMOTE_REFS) + ostree init --repo=/flatpak_dir/repo --mode=archive-z2 + for i in \$$(ostree refs --repo=\$${FLATPAK_SYSTEM_DIR}/repo | grep '^deploy/' | sed 's/^deploy\///g') + do + echo "Copying \$${i}..." + ostree --repo=/flatpak_dir/repo pull-local \$${FLATPAK_SYSTEM_DIR}/repo \$$(ostree --repo=\$${FLATPAK_SYSTEM_DIR}/repo rev-parse $(FLATPAK_REMOTE_NAME)/\$${i}) + mkdir -p \$$(dirname /flatpak_dir/repo/refs/heads/\$${i}) + ostree --repo=\$${FLATPAK_SYSTEM_DIR}/repo rev-parse $(FLATPAK_REMOTE_NAME)/\$${i} > /flatpak_dir/repo/refs/heads/\$${i} + done + flatpak build-update-repo /flatpak_dir/repo + ostree refs --repo=/flatpak_dir/repo | tee /flatpak_dir/list.txt + EOF + +install-deps: + +clean: + $(if $(wildcard script.sh),rm script.sh) + $(if $(wildcard repo),rm -Rf repo) + $(if $(wildcard list.txt),rm list.txt) + +.ONESHELL: \ No newline at end of file diff --git a/lorax_templates/Makefile b/lorax_templates/Makefile new file mode 100644 index 0000000..b2e80e5 --- /dev/null +++ b/lorax_templates/Makefile @@ -0,0 +1,52 @@ +# Converts a post script to a template +# $1 = script to convert +# $2 = file on ISO to write +# $3 = whether to copy the '<%' lines to the template +define convert_post_to_tmpl + header=0; \ + skip=0; \ + while read -r line; \ + do \ + if [[ $$line =~ ^\<\% ]]; \ + then \ + if [[ '$(3)' == 'true' ]]; \ + then \ + echo $$line >> post_$(1).tmpl; \ + fi; \ + echo >> post_$(1).tmpl; \ + else \ + if [[ $$header == 0 ]]; \ + then \ + if [[ $$line =~ ^\#\#\ (.*)$$ ]]; \ + then \ + echo "append $(2) \"%post --erroronfail $${BASH_REMATCH[1]}\"" >> post_$(1).tmpl; \ + skip=1; \ + else \ + echo "append $(2) \"%post --erroronfail\"" >> post_$(1).tmpl; \ + fi; \ + header=1; \ + fi; \ + if [[ $$skip == 0 ]]; \ + then \ + echo "append $(2) \"$${line//\"/\\\"}\"" >> post_$(1).tmpl; \ + fi; \ + skip=0; \ + fi; \ + done < scripts/post/$(1); \ + echo "append $(2) \"%end\"" >> post_$(1).tmpl +endef + +post_%.tmpl: scripts/post/% + $(call convert_post_to_tmpl,$*,usr/share/anaconda/post-scripts/$*.ks,true) + +install_include_post.tmpl: + echo '<%page />' > install_include_post.tmpl + for file in $(patsubst post_%.tmpl, %, $(filter post_%, $(notdir $(_LORAX_TEMPLATES)))); do echo "append usr/share/anaconda/interactive-defaults.ks \"%include /usr/share/anaconda/post-scripts/$${file}.ks\"" >> install_include_post.tmpl; done + +install-deps: + +FILES=$(wildcard post_*) install_include_post.tmpl +clean: +ifneq ($(FILES),) + rm -Rf $(FILES) +endif diff --git a/lorax_templates/flatpak_set_repo.tmpl b/lorax_templates/flatpak_set_repo.tmpl index 0d8db43..b7fae2d 100644 --- a/lorax_templates/flatpak_set_repo.tmpl +++ b/lorax_templates/flatpak_set_repo.tmpl @@ -1,8 +1,8 @@ <%page args="flatpak_remote_name, _flatpak_repo_url, version"/> % if int(version) >= 41: +append etc/anaconda/conf.d/anaconda.conf "[Payload]" append etc/anaconda/conf.d/anaconda.conf "flatpak_remote = ${flatpak_remote_name} ${_flatpak_repo_url}" % else: replace "flatpak_manager\.add_remote\(\".*\", \".*\"\)" "flatpak_manager.add_remote(\"${flatpak_remote_name}\", \"${_flatpak_repo_url}\")" /usr/lib64/python*/site-packages/pyanaconda/modules/payloads/payload/rpm_ostree/flatpak_installation.py replace "flatpak_manager\.replace_installed_refs_remote\(\".*\"\)" "flatpak_manager.replace_installed_refs_remote(\"${flatpak_remote_name}\")" /usr/lib64/python*/site-packages/pyanaconda/modules/payloads/payload/rpm_ostree/flatpak_installation.py % endif - diff --git a/lorax_templates/scripts/post/install_configure_upgrades b/lorax_templates/scripts/post/install_configure_upgrades index f474d93..20ca2ae 100644 --- a/lorax_templates/scripts/post/install_configure_upgrades +++ b/lorax_templates/scripts/post/install_configure_upgrades @@ -1,7 +1,18 @@ -<%page args="image_repo, _image_repo_double_escaped, image_name, image_tag, _rhel, version"/> +<%page args="image_repo, _image_repo_double_escaped, image_name, image_signed, image_tag, _rhel, version"/> + if (which bootc &> /dev/null) && [ ${_rhel} == 'false' && ${version} -ge 39 ] then - bootc switch --mutate-in-place --enforce-container-sigpolicy --transport registry ${image_repo}/${image_name}:${image_tag} + if [ ${image_signed} == 'true' ] + then + bootc switch --mutate-in-place --enforce-container-sigpolicy --transport registry ${image_repo}/${image_name}:${image_tag} + else + bootc switch --mutate-in-place --transport registry ${image_repo}/${image_name}:${image_tag} + fi else - sed -i 's/container-image-reference=.*/container-image-reference=ostree-image-signed:docker:\/\/${_image_repo_double_escaped}\/${image_name}:${image_tag}/' /ostree/deploy/default/deploy/*.origin + if [ ${image_signed} == 'true' ] + then + sed -i 's/container-image-reference=.*/container-image-reference=ostree-image-signed:docker:\/\/${_image_repo_double_escaped}\/${image_name}:${image_tag}/' /ostree/deploy/default/deploy/*.origin + else + sed -i 's/container-image-reference=.*/container-image-reference=ostree-unverified-image:docker:\/\/${_image_repo_double_escaped}\/${image_name}:${image_tag}/' /ostree/deploy/default/deploy/*.origin + fi fi diff --git a/repos/Makefile b/repos/Makefile new file mode 100644 index 0000000..63e2f7f --- /dev/null +++ b/repos/Makefile @@ -0,0 +1,15 @@ +repos: $(_REPO_FILES) + +# Step 2: Replace vars in repo files +%.repo: /etc/yum.repos.d/%.repo + cp /etc/yum.repos.d/$*.repo $*.repo + sed -i "s/\$$releasever/$(VERSION)/g" $*.repo + sed -i "s/\$$basearch/$(ARCH)/g" $*.repo + +install-deps: + +FILES=$(wildcard *.repo) +clean: +ifneq ($(FILES),) + rm -Rf $(FILES) +endif \ No newline at end of file diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..c9785c7 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,23 @@ +all: $(filter-out README.md Makefile,$(wildcard *)) + +$(filter-out README.md Makefile,$(wildcard *)): + $(eval DIR=$(firstword $(subst /, ,$@))) + $(MAKE) -w -C $(DIR) + +$(filter-out README.md Makefile,$(wildcard */*)): + $(eval DIR=$(firstword $(subst /, ,$@))) + $(eval TARGET=$(subst $(DIR)/,,$@)) + $(MAKE) -w -C $(DIR) $(TARGET) + +.DEFAULT: + $(eval DIR=$(firstword $(subst /, ,$@))) + $(if $(filter-out $(DIR),$@), $(eval TARGET=$(subst $(DIR)/,,$@)),$(eval TARGET=)) + $(MAKE) -w -C $(DIR) $(TARGET) + +install-deps: + $(foreach DIR,$(filter-out README.md Makefile,$(wildcard *)),$(MAKE) -w -C $(DIR) install-deps;) + +clean: + $(foreach DIR,$(filter-out README.md Makefile,$(wildcard *)),$(MAKE) -w -C $(DIR) clean;) + +.PHONY: all $(filter-out README.md Makefile,$(wildcard *)) $(filter-out README.md Makefile,$(wildcard */*)) \ No newline at end of file diff --git a/test/iso/Makefile b/test/iso/Makefile new file mode 100644 index 0000000..3f3f76f --- /dev/null +++ b/test/iso/Makefile @@ -0,0 +1,25 @@ +ISO_NAME=deploy.iso +ISO_TESTS=$(wildcard install_*) $(if $(FLATPAK_REMOTE_REFS),$(wildcard flatpak_*))$(if $(FLATPAK_DIR),$(wildcard flatpak_*)) + +all: $(ISO_TESTS) clean + +$(ISO_TESTS): mnt/iso + $(eval _VARS = ISO_NAME VERSION FLATPAK_REMOTE_NAME _FLATPAK_REPO_URL) + chmod +x $@ + $(foreach var,$(_VARS),$(var)=$($(var))) ./$@ + +mnt/iso: + sudo modprobe loop + sudo mkdir -p mnt/iso mnt/install + sudo mount -o loop ../../$(ISO_NAME) mnt/iso + sudo mount -t squashfs -o loop mnt/iso/images/install.img mnt/install + +clean: + sudo umount mnt/install || true + sudo umount mnt/iso || true + sudo rmdir mnt/install mnt/iso + +install-deps: + $(install_pkg) isomd5sum coreutils squashfs-tools curl + +.PHONY: all $(ISO_TESTS) clean \ No newline at end of file diff --git a/tests/iso/README.md b/test/iso/README.md similarity index 100% rename from tests/iso/README.md rename to test/iso/README.md diff --git a/test/iso/flatpak_repo_updated.sh b/test/iso/flatpak_repo_updated.sh new file mode 100644 index 0000000..c8187ff --- /dev/null +++ b/test/iso/flatpak_repo_updated.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +if [[ ${VERSION} -ge 41 ]] +then + result=0 + grep "^\[Payload\]" mnt/install/etc/anaconda/conf.d/anaconda.conf > /dev/null || { + echo "Missing [Payload] header" + result=1 + } + grep "^flatpak_remote = ${FLATPAK_REMOTE_NAME} ${_FLATPAK_REPO_URL}" mnt/install/etc/anaconda/conf.d/anaconda.conf > /dev/null || { + echo "Missing flatpak_remote option" + result=1 + } + exit ${result} +fi + +add_line=$(grep flatpak_manager.add_remote mnt/install/usr/lib64/python*/site-packages/pyanaconda/modules/payloads/payload/rpm_ostree/flatpak_installation.py) + +add_line_repo=$(echo "${add_line}" | grep "${FLATPAK_REMOTE_NAME}") +add_line_url=$(echo "${add_line}" | grep "${_FLATPAK_REPO_URL}") + +result=0 +if [ -z "${add_line_repo}" ] +then + echo "Repo name not updated on add_remote line" + echo "${add_line}" + result=1 +else + echo "Repo name found on add_remote line" +fi + +if [ -z "${add_line_url}" ] +then + echo "Repo url not updated on add_remote line" + echo "${add_line}" + result=1 +else + echo "Repo url found on add_remote line" +fi + +replace_line=$(grep flatpak_manager.replace_installed_refs_remote mnt/install/usr/lib64/python*/site-packages/pyanaconda/modules/payloads/payload/rpm_ostree/flatpak_installation.py) + +replace_line_repo=$(echo "${replace_line}" | grep "${FLATPAK_REMOTE_NAME}") + +if [ -z "${replace_line_repo}" ] +then + echo "Repo name not updated on replace_installed_refs line" + echo "${replace_line}" + result=1 +else + echo "Repo name found on replace_installed_refs line" +fi + +exit ${result} \ No newline at end of file diff --git a/test/iso/install_hash.sh b/test/iso/install_hash.sh new file mode 100644 index 0000000..6989399 --- /dev/null +++ b/test/iso/install_hash.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +#set -ex + +checkisomd5 "../../${ISO_NAME}" +if [[ $? != 0 ]] +then + echo "Found:" + checkisomd5 --md5sumonly "../../${ISO_NAME}" + echo "Expected:" + implantisomd5 --force "../../${ISO_NAME}" +fi + +cd "$(dirname "../../${ISO_NAME}")" && sha256sum -c "$(basename "${ISO_NAME}")-CHECKSUM" \ No newline at end of file diff --git a/tests/iso/install_os-release.sh b/test/iso/install_os-release.sh similarity index 71% rename from tests/iso/install_os-release.sh rename to test/iso/install_os-release.sh index ccef46c..788111a 100644 --- a/tests/iso/install_os-release.sh +++ b/test/iso/install_os-release.sh @@ -1,6 +1,6 @@ #!/bin/bash -FOUND_VERSION=$(cat /mnt/install/etc/os-release | grep VERSION_ID | cut -d= -f2) +FOUND_VERSION=$(grep VERSION_ID mnt/install/etc/os-release | cut -d= -f2 | tr -d '"') if [[ ${FOUND_VERSION} != ${VERSION} ]] then diff --git a/test/repo/Makefile b/test/repo/Makefile new file mode 100644 index 0000000..3c395c3 --- /dev/null +++ b/test/repo/Makefile @@ -0,0 +1,11 @@ +REPO_TESTS=$(filter-out README.md Makefile,$(wildcard *)) + +all: $(REPO_TESTS) + +$(REPO_TESTS): + chmod +x $@ + ./$@ + +install-deps: + +.PHONY: $(REPO_TESTS) \ No newline at end of file diff --git a/test/repo/vars.py b/test/repo/vars.py new file mode 100755 index 0000000..497b67e --- /dev/null +++ b/test/repo/vars.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python + +makefile = open('../../Makefile.inputs', 'r') +makefile_lines = makefile.readlines() + +inputs = {} +outputs = {} +errors = 0 + +for line in makefile_lines: + if line.startswith('#'): + makefile_lines.remove(line) + continue + parts = line.split('=', 1) + if parts[0].startswith('export'): + var_name = parts[0].strip().split(' ')[1].lower() + else: + var_name = parts[0].strip().lower() + inputs[var_name] = {'default_value': parts[1].strip(), 'makefile': True} + +action = open('../../action.yml', 'r') +action_lines = action.readlines() + +at_inputs = False +at_outputs = False +for line in action_lines: + if not at_inputs: + if line.strip() == 'inputs:': + at_inputs = True + continue + else: + if line.startswith(' '): + parts = line.strip().split(':', 1) + if parts[0] == 'description': + inputs[var_name]['description'] = parts[1].strip() + if parts[0] == 'deprecationMessage': + inputs[var_name]['deprecated'] = True + if parts[0] == 'default': + if 'default' in inputs[var_name]: + if inputs[var_name]['default_value'] != parts[1].strip().strip('"'): + print("ERROR: Default value for " + var_name + " in action.yml does not match Makefile") + errors += 1 + else: + inputs[var_name]['default_value'] = parts[1].strip().strip('"') + elif line.startswith(' '): + var_name = line.strip().strip(':').lower() + if not var_name in inputs: + inputs[var_name] = {} + inputs[var_name]['action'] = True + else: + at_inputs = False + + if not at_outputs: + if line.strip() == 'outputs:': + at_outputs = True + continue + else: + if line.startswith(' '): + parts = line.strip().split(':', 1) + if parts[0] == 'description': + outputs[var_name]['description'] = parts[1].strip() + if parts[0] == 'deprecationMessage': + outputs[var_name]['deprecated'] = True + if parts[0] == 'default': + outputs[var_name]['default_value'] = parts[1].strip().strip('"') + elif line.startswith(' '): + var_name = line.strip().strip(':').lower() + outputs[var_name] = {} + else: + at_outputs = False + + +readme = open('../../README.md', 'r') +readme_lines = readme.readlines() + +at_inputs = False +skip_header = True +at_outputs = False +for line in readme_lines: + if not at_inputs: + if line.strip() == '### Inputs': + at_inputs = True + continue + else: + if skip_header: + if line.startswith('| -----'): + skip_header = False + continue + else: + if not line.startswith('|'): + at_inputs = False + continue + parts = line.split('|') + var_name = parts[1].strip().lower() + if not var_name in inputs: + print("ERROR: " + var_name + " is not listed in action.yml or Makefile") + errors += 1 + continue + if 'description' in inputs[var_name]: + if parts[2].strip().strip('\*') != inputs[var_name]['description']: + print("WARNING: " + var_name + " description in README.md does not match action.yml") + if 'default_value' in inputs[var_name]: + if not parts[3].strip().strip('"<>').startswith('*'): + if inputs[var_name]['default_value'] == "": + if parts[3].strip().strip('"') != '\\[empty\\]': + print("ERROR: " + var_name + " default value in README.md does not match action.yml") + print("Found " + parts[3].strip().strip('"<>')) + print("Expected " + inputs[var_name]['default_value']) + errors += 1 + elif parts[3].strip().strip('"<>') != inputs[var_name]['default_value']: + print("ERROR: " + var_name + " default value in README.md does not match action.yml") + print("Found " + parts[3].strip().strip('"<>')) + print("Expected " + inputs[var_name]['default_value']) + errors += 1 + if 'action' in inputs[var_name] and inputs[var_name]['action']: + if parts[4].strip() != ':white_check_mark:': + print("WARNING: " + var_name + " not labeled as in action.yml in the README.md") + if 'makefile' in inputs[var_name] and inputs[var_name]['makefile']: + if parts[4].strip() != ':white_check_mark:': + print("WARNING: " + var_name + " not labeled as in Makefile in the README.md") + +exit(errors) \ No newline at end of file diff --git a/test/vm/Makefile b/test/vm/Makefile new file mode 100644 index 0000000..6578595 --- /dev/null +++ b/test/vm/Makefile @@ -0,0 +1,100 @@ +VM_TESTS=$(wildcard install_*) $(if $(FLATPAK_REMOTE_REFS),$(wildcard flatpak_*))$(if $(FLATPAK_DIR),$(wildcard flatpak_*)) + +all: $(VM_TESTS) clean + +$(VM_TESTS): start_vm ansible_inventory + $(eval _VARS = IMAGE_REPO IMAGE_NAME IMAGE_TAG) + + ansible -i ansible_inventory -m ansible.builtin.wait_for_connection vm + + chmod +x $@ + $(foreach var,$(_VARS),$(var)=$($(var))) ./$@ + +ansible_inventory: + echo "ungrouped:" > ansible_inventory + echo " hosts:" >> ansible_inventory + echo " vm:" >> ansible_inventory + echo " ansible_host: $(VM_IP)" >> ansible_inventory + echo " ansible_port: $(VM_PORT)" >> ansible_inventory + echo " ansible_user: $(VM_USER)" >> ansible_inventory + echo " ansible_password: $(VM_PASS)" >> ansible_inventory + echo " ansible_become_pass: $(VM_PASS)" >> ansible_inventory + echo " ansible_ssh_common_args: '-o StrictHostKeyChecking=no'" >> ansible_inventory + +.PHONY: $(VM_TESTS) install-deps + +install-deps: + $(install_pkg) qemu-system qemu-utils xorriso qemu-system-x86 ncat socat jq ansible curl + +files/mnt/iso: + $(if $(wildcard files/mnt),,mkdir files/mnt) + $(if $(wildcard files/mnt/iso),,mkdir files/mnt/iso) + sudo mount -o loop ../../$(ISO_NAME) files/mnt/iso + +files/grub.cfg: files/mnt/iso + cp files/mnt/iso/$(if $(_RHEL),isolinux/grub.conf,boot/grub2/grub.cfg) files/grub.cfg + sed -i 's/quiet/console=ttyS0,115200n8 inst.ks=cdrom:\/ks.cfg/' files/grub.cfg + sed -i 's/set default="1"/set default="0"/' files/grub.cfg + sed -i 's/set timeout=60/set timeout=1/' files/grub.cfg + +.PHONY: clean +clean: + $(if $(wildcard start_vm), kill "$(shell cat start_vm)") + $(if $(wildcard files/mnt/iso),sudo umount files/mnt/iso) + $(if $(wildcard files/mnt/iso),rmdir files/mnt/iso) + $(if $(wildcard ansible_inventory),rm ansible_inventory) + $(if $(wildcard files/install.iso),rm files/install.iso) + $(if $(wildcard files/disk.qcow2),rm files/disk.qcow2) + $(if $(wildcard install_os),rm install_os) + $(if $(wildcard start_vm),rm start_vm) + +files/install.iso: files/grub.cfg + xorriso -dialog on << EOF + -indev ../../$(ISO_NAME) + -outdev files/install.iso + -boot_image any replay + -joliet on + -compliance joliet_long_names + -map files/ks.cfg ks.cfg + -chmod 0444 ks.cfg + -map files/grub.cfg $(if $(_RHEL),isolinux/grub.conf,boot/grub2/grub.cfg) + -end + EOF + +files/disk.qcow2: + qemu-img create -f qcow2 files/disk.qcow2 50G + +install_os: files/install.iso files/disk.qcow2 + timeout 1h qemu-system-x86_64 -name "Anaconda" -boot d -m 4096 -cpu qemu64 -display none -cdrom files/install.iso -smp 2 -hda files/disk.qcow2 -serial telnet:localhost:4321,server=on,wait=off & QEMU_PID=$$! + echo "PID: $$QEMU_PID" + timeout 1m bash -c "while ! (echo > /dev/tcp/127.0.0.1/4321); do sleep 0.1; done" + (nc localhost 4321 | tee vm.stdout) & + wait $$QEMU_PID + touch install_os + +.ONESHELL: + +start_vm: install_os + mkfifo vm.stdin + qemu-system-x86_64 -name "Anaconda" \ + -m 4096 -cpu qemu64 -display none -smp 2 \ + -chardev socket,path=/tmp/qga.sock,server=on,wait=off,id=qga0 \ + -device e1000,netdev=net0 \ + -netdev user,id=net0,hostfwd=tcp::$(VM_PORT)-:22 \ + -device virtio-serial \ + -device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0 \ + -boot c -hda files/disk.qcow2 -serial telnet:localhost:4321,server=on,wait=off & export QEMU_PID=$$! + echo "PID: $$QEMU_PID" + + timeout 1m bash -c "while ! (echo > /dev/tcp/127.0.0.1/4321); do sleep 0.1; done" + (tail -f vm.stdin | nc localhost 4321 | tee vm.stdout) & + + timeout 30m bash -c "while ! (echo > /dev/tcp/$(VM_IP)/$(VM_PORT)); do sleep 1; done" + + if ! (echo > /dev/tcp/$(VM_IP)/$(VM_PORT)) + then + echo "SSH must be installed and enabled inside the container" + fi + + echo "VM ready for tests at IP $(VM_IP):$(VM_PORT)" + echo $$QEMU_PID > start_vm diff --git a/tests/vm/README.md b/test/vm/README.md similarity index 100% rename from tests/vm/README.md rename to test/vm/README.md diff --git a/test/vm/files/ks.cfg b/test/vm/files/ks.cfg new file mode 100644 index 0000000..280583d --- /dev/null +++ b/test/vm/files/ks.cfg @@ -0,0 +1,9 @@ +lang en_US.UTF-8 +keyboard us +timezone Americas/New_York +zerombr +clearpart --all --initlabel +autopart +poweroff +user --name=core --groups=wheel --password=foobar +%include /usr/share/anaconda/interactive-defaults.ks diff --git a/tests/vm/flatpak_fedora_repo_disabled.yml b/test/vm/flatpak_fedora_repo_disabled.yml similarity index 67% rename from tests/vm/flatpak_fedora_repo_disabled.yml rename to test/vm/flatpak_fedora_repo_disabled.yml index f87ff80..eb87099 100644 --- a/tests/vm/flatpak_fedora_repo_disabled.yml +++ b/test/vm/flatpak_fedora_repo_disabled.yml @@ -1,6 +1,6 @@ #!/usr/bin/env -S ansible-playbook -i ./ansible_inventory --- -- name: Test for installed flatpaks +- name: Test fedora flatpak repo wasn't enabled hosts: vm gather_facts: no @@ -10,7 +10,9 @@ register: services_state - name: Check that flatpak-add-fedora-repos is disabled + when: services_state['ansible_facts']['services']['flatpak-add-fedora-repos.service'] is defined ansible.builtin.assert: that: - services_state['ansible_facts']['services']['flatpak-add-fedora-repos.service']['status'] == 'disabled' - fail_msg: 'flatpak-add-fedora-repos.service is not disabled' \ No newline at end of file + fail_msg: 'flatpak-add-fedora-repos.service is not disabled' + success_msg: 'flatpak-add-fedora-repos.service is correctly disabled' diff --git a/tests/vm/flatpak_installed.yml b/test/vm/flatpak_installed.yml similarity index 100% rename from tests/vm/flatpak_installed.yml rename to test/vm/flatpak_installed.yml diff --git a/tests/vm/flatpak_update.yml b/test/vm/flatpak_update.yml similarity index 91% rename from tests/vm/flatpak_update.yml rename to test/vm/flatpak_update.yml index 7d004cd..3f80685 100644 --- a/tests/vm/flatpak_update.yml +++ b/test/vm/flatpak_update.yml @@ -1,6 +1,6 @@ #!/usr/bin/env -S ansible-playbook -i ./ansible_inventory --- -- name: Test for flatpaks +- name: Test flatpak update hosts: vm gather_facts: no diff --git a/tests/vm/install_image_source.yml b/test/vm/install_image_source.yml similarity index 100% rename from tests/vm/install_image_source.yml rename to test/vm/install_image_source.yml diff --git a/tests/iso/flatpak_repo_updated.sh b/tests/iso/flatpak_repo_updated.sh deleted file mode 100644 index b5ee240..0000000 --- a/tests/iso/flatpak_repo_updated.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -add_line=$(grep flatpak_manager.add_remote /mnt/install/usr/lib64/python*/site-packages/pyanaconda/modules/payloads/payload/rpm_ostree/flatpak_installation.py) - -add_line_repo=$(echo ${add_line} | grep ${FLATPAK_REMOTE_NAME}) -add_line_url=$(echo ${add_line} | grep ${_FLATPAK_REPO_URL}) - -result=0 -if [ -z "${add_line_repo}" ] -then - echo "Repo name not updated on add_remote line" - result=1 -else - echo "Repo name found on add_remote line" -fi - -if [ -z "${add_line_url}" ] -then - echo "Repo url not updated on add_remote line" - result=1 -else - echo "Repo url found on add_remote line" -fi - -replace_line=$(grep flatpak_manager.replace_installed_refs_remote /mnt/install/usr/lib64/python*/site-packages/pyanaconda/modules/payloads/payload/rpm_ostree/flatpak_installation.py) - -replace_line_repo=$(echo ${replace_line} | grep ${FLATPAK_REMOTE_NAME}) - -if [ -z "${replace_line_repo}" ] -then - echo "Repo name not updated on replace_installed_refs line" - result=1 -else - echo "Repo name found on replace_installed_refs line" -fi - -exit ${result} \ No newline at end of file diff --git a/tests/repo/vars.sh b/tests/repo/vars.sh deleted file mode 100644 index 2e4302e..0000000 --- a/tests/repo/vars.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -vars=() - -while read -r line -do - if ! [[ $line =~ ^# ]] - then - vars+=$(echo $line | cut -d= -f1 | tr [:upper:] [:lower:]) - fi - if [[ $line =~ ^########## ]] - then - break - fi -done < Makefile - -result=0 - -for var in $vars -do - grep "^| ${var}" README.md > /dev/null - if [[ $? != 0 ]] - then - echo "$var not found in README.md" - result=1 - fi -done - -for var in $vars -do - grep "^ ${var}:" action.yml > /dev/null - if [[ $? != 0 ]] - then - echo "$var not found in action.yml" - result=1 - fi -done - -exit ${result} \ No newline at end of file diff --git a/xorriso/Makefile b/xorriso/Makefile new file mode 100644 index 0000000..b2f5d87 --- /dev/null +++ b/xorriso/Makefile @@ -0,0 +1,14 @@ +input.txt: gen_input.sh + find + $(if $(wildcard ../results/boot/grub2/grub.cfg),sed -i 's/quiet/quiet $(EXTRA_BOOT_PARAMS)/g' ../results/boot/grub2/grub.cfg) + sed -i 's/quiet/quiet $(EXTRA_BOOT_PARAMS)/g' ../results/EFI/BOOT/grub.cfg + $(eval _VARS = ARCH FLATPAK_DIR IMAGE_NAME IMAGE_TAG ISO_NAME VERSION) + $(foreach var,$(_VARS),$(var)=$($(var))) bash gen_input.sh | tee input.txt + +install-deps: + +FILES=$(wildcard input.txt) +clean: +ifneq ($(FILES),) + rm -Rf $(FILES) +endif \ No newline at end of file diff --git a/xorriso/gen_input.sh b/xorriso/gen_input.sh new file mode 100644 index 0000000..0329186 --- /dev/null +++ b/xorriso/gen_input.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +echo "-report_about WARNING" +echo "-indev ${PWD}/../results/images/boot.iso" +echo "-outdev ${ISO_NAME}" +echo "-boot_image any replay" +echo "-joliet on" +echo "-compliance joliet_long_names" +pushd "${PWD}/../results" > /dev/null +#for file in $(find .) +for file in ./boot/grub2/grub.cfg ./EFI/BOOT/grub.cfg +do + if [[ "$file" == "./images/boot.iso" ]] + then + continue + fi + if [[ -f ${PWD}/${file} ]] + then + echo "-map ${PWD}/${file} ${file:2}" + echo "-chmod 0444 ${file:2}" + fi +done +popd > /dev/null + +if [[ -n "${FLATPAK_DIR}" ]] +then + pushd "${FLATPAK_DIR}" > /dev/null + for file in $(find repo) + do + if [[ "${file}" == "repo/.lock" ]] + then + continue + fi + echo "-map ${PWD}/${file} flatpak/${file}" + echo "-chmod 0444 flatpak/${file}" + done + popd > /dev/null +fi + +if [ -f "${PWD}/../sb_pubkey.der" ] +then + echo "-map ${PWD}/../sb_pubkey.der sb_pubkey.der" + echo "-chmod 0444 /sb_pubkey.der" +fi + +pushd "${PWD}/../container" > /dev/null +for file in $(find "${IMAGE_NAME}-${IMAGE_TAG}" -type f) +do + echo "-map ${PWD}/${file} ${file}" + echo "-chmod 0444 ${file}" +done +popd > /dev/null +echo "-end" diff --git a/xorriso/gen_input.sh.in b/xorriso/gen_input.sh.in deleted file mode 100644 index 0a993bc..0000000 --- a/xorriso/gen_input.sh.in +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -echo "-indev $(pwd)/boot.iso" -echo "-outdev $(pwd)/build/deploy.iso" -echo "-boot_image any replay" -echo "-joliet on" -echo "-compliance joliet_long_names" -echo "-map $(pwd)/results/boot/grub2/grub.cfg boot/grub2/grub.cfg" -echo "-chmod 0444 boot/grub2/grub.cfg" -echo "-map $(pwd)/results/EFI/BOOT/grub.cfg EFI/BOOT/grub.cfg" -echo "-chmod 0444 EFI/BOOT/grub.cfg" - -if [[ -n "${FLATPAK_DIR}" ]] -then - pushd ${FLATPAK_DIR} > /dev/null - for file in $(find *) - do - echo "-map $(pwd)/${file} flatpak/${file}" - echo "-chmod 0444 flatpak/${file}" - done - popd > /dev/null -fi - -if [ -f $(pwd)/sb_pubkey.der ] -then - echo "-map $(pwd)/sb_pubkey.der sb_pubkey.der" - echo "-chmod 0444 /sb_pubkey.der" -fi - -pushd container > /dev/null -for file in $(find ${IMAGE_NAME}-${IMAGE_TAG}) -do - echo "-map $(pwd)/${file} ${file}" - echo "-chmod 0444 ${file}" -done -popd > /dev/null -echo "-end"