diff --git a/.github/workflows/build-container-image.yml b/.github/workflows/build-container-image.yml index fc6eff50..48dbca7f 100644 --- a/.github/workflows/build-container-image.yml +++ b/.github/workflows/build-container-image.yml @@ -1,9 +1,14 @@ --- name: Build Container Image on: + merge_group: pull_request: branches: - main + paths-ignore: + - '*.md' + - 'LICENSE' + - 'CODEOWNERS' push: branches: - main diff --git a/.github/workflows/test-iso.yml b/.github/workflows/test-iso.yml index 0465b1b9..0d099d5c 100644 --- a/.github/workflows/test-iso.yml +++ b/.github/workflows/test-iso.yml @@ -10,6 +10,7 @@ on: - '*.md' - 'LICENSE' - 'CODEOWNERS' + workflow_dispatch: jobs: build-and-push-iso: @@ -18,15 +19,30 @@ jobs: container: image: fedora:39 options: "--privileged" + volumes: + - "/:/host" permissions: contents: read packages: write strategy: fail-fast: false matrix: - version: + version: - 38 - 39 + secure_boot: + - true + - false + include: + - secure_boot: true + SECURE_BOOT_KEY_URL: 'https://github.com/ublue-os/akmods/raw/main/certs/public_key.der' + ENROLLMENT_PASSWORD: 'ublue-os' + SECURE_BOOT_STRING: '-secure' + - secure_boot: false + SECURE_BOOT_KEY_URL: '' + ENROLLMENT_PASSWORD: '' + SECURE_BOOT_STRING: '' + steps: - name: Checkout uses: actions/checkout@v4 @@ -41,6 +57,18 @@ jobs: VERSION: ${{ matrix.version }} ACTION_REPO: ${{ github.repository }} ACTION_REF: ${{ github.ref }} + SECURE_BOOT_KEY_URL: ${{ matrix.SECURE_BOOT_KEY_URL }} + ENROLLMENT_PASSWORD: ${{ matrix.ENROLLMENT_PASSWORD }} + + - name: Upload ISO as artifact + uses: actions/upload-artifact@v4 + with: + name: base-main-${{ matrix.version }}${{ matrix.SECURE_BOOT_STRING }}.iso + path: end_iso/* + if-no-files-found: error + retention-days: 0 + compression-level: 0 + overwrite: true check: name: Check build successful @@ -55,4 +83,4 @@ jobs: run: exit 1 - name: Exit shell: bash - run: exit 0 \ No newline at end of file + run: exit 0 diff --git a/Containerfile b/Containerfile index 249b95b9..00708e08 100644 --- a/Containerfile +++ b/Containerfile @@ -13,6 +13,8 @@ ENV IMAGE_TAG="${VERSION}" ENV VARIANT="Kinoite" ENV VERSION="${VERSION}" ENV WEB_UI="false" +ENV SECURE_BOOT_KEY_URL="" +ENV ENROLLMENT_PASSWORD="ublue-os" COPY ./ /isogenerator WORKDIR /isogenerator @@ -23,4 +25,4 @@ RUN dnf install -y make && \ VOLUME /isogenerator/output -ENTRYPOINT ["sh", "-c", "make output/${IMAGE_NAME}-${IMAGE_TAG}.iso ARCH=${ARCH} VERSION=${VERSION} IMAGE_REPO=${IMAGE_REPO} IMAGE_NAME=${IMAGE_NAME} IMAGE_TAG=${IMAGE_TAG} VARIANT=${VARIANT} WEB_UI=${WEB_UI}"] +ENTRYPOINT /isogenerator/entrypoint.sh diff --git a/Makefile b/Makefile index 697c7212..33cb762c 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,8 @@ IMAGE_TAG = $(VERSION) EXTRA_BOOT_PARAMS = VARIANT = Kinoite WEB_UI = false +ENROLLMENT_PASSWORD = ublue-os +SECURE_BOOT_KEY_URL = # Generated vars ## Formatting = _UPPERCASE @@ -35,6 +37,7 @@ $(IMAGE_NAME)-$(IMAGE_TAG).iso: output/$(IMAGE_NAME)-$(IMAGE_TAG).iso output/$(IMAGE_NAME)-$(IMAGE_TAG).iso: boot.iso container/$(IMAGE_NAME)-$(IMAGE_TAG) xorriso/input.txt mkdir $(_BASE_DIR)/output || true xorriso -dialog on < $(_BASE_DIR)/xorriso/input.txt + implantisomd5 $(_BASE_DIR)/output/$(IMAGE_NAME)-$(IMAGE_TAG).iso # Step 1: Generate Lorax Templates lorax_templates/%.tmpl: lorax_templates/%.tmpl.in @@ -48,11 +51,16 @@ lorax_templates/%.tmpl: lorax_templates/%.tmpl.in # Step 2: Build boot.iso using Lorax boot.iso: lorax_templates/set_installer.tmpl lorax_templates/configure_upgrades.tmpl - rm -Rf $(_BASE_DIR)/results + rm -Rf $(_BASE_DIR)/results || true + rm /etc/rpm/macros.image-language-conf || true + + # Set the enrollment password + sed 's/@ENROLLMENT_PASSWORD@/$(ENROLLMENT_PASSWORD)/' $(_BASE_DIR)/scripts/enroll-secureboot-key.sh.in > $(_BASE_DIR)/scripts/enroll-secureboot-key.sh - # Remove the "Test this media & install" menu entry - sed -i '/menuentry '\''Test this media & install @PRODUCT@ @VERSION@'\'' --class fedora --class gnu-linux --class gnu --class os {/,/}/d' /usr/share/lorax/templates.d/99-generic/config_files/x86/grub2-bios.cfg - sed -i '/menuentry '\''Test this media & install @PRODUCT@ @VERSION@'\'' --class fedora --class gnu-linux --class gnu --class os {/,/}/d' /usr/share/lorax/templates.d/99-generic/config_files/x86/grub2-efi.cfg + # 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 # Set the default menu entry to the first one sed -i 's/set default="1"/set default="0"/' /usr/share/lorax/templates.d/99-generic/config_files/x86/grub2-bios.cfg @@ -62,12 +70,16 @@ boot.iso: lorax_templates/set_installer.tmpl lorax_templates/configure_upgrades. sed -i 's/linux @KERNELPATH@ @ROOT@ quiet/linux @KERNELPATH@ @ROOT@ quiet $(EXTRA_BOOT_PARAMS)/g' /usr/share/lorax/templates.d/99-generic/config_files/x86/grub2-bios.cfg sed -i 's/linuxefi @KERNELPATH@ @ROOT@ quiet/linuxefi @KERNELPATH@ @ROOT@ quiet $(EXTRA_BOOT_PARAMS)/g' /usr/share/lorax/templates.d/99-generic/config_files/x86/grub2-efi.cfg + sed -i 's/linux @KERNELPATH@ @ROOT@ rd.live.check quiet/linux @KERNELPATH@ @ROOT@ rd.live.check quiet $(EXTRA_BOOT_PARAMS)/g' /usr/share/lorax/templates.d/99-generic/config_files/x86/grub2-bios.cfg + sed -i 's/linuxefi @KERNELPATH@ @ROOT@ rd.live.check quiet/linuxefi @KERNELPATH@ @ROOT@ rd.live.check quiet $(EXTRA_BOOT_PARAMS)/g' /usr/share/lorax/templates.d/99-generic/config_files/x86/grub2-efi.cfg + sed -i 's/linux @KERNELPATH@ @ROOT@ nomodeset quiet/linux @KERNELPATH@ @ROOT@ nomodeset quiet $(EXTRA_BOOT_PARAMS)/g' /usr/share/lorax/templates.d/99-generic/config_files/x86/grub2-bios.cfg sed -i 's/linuxefi @KERNELPATH@ @ROOT@ nomodeset quiet/linuxefi @KERNELPATH@ @ROOT@ nomodeset quiet $(EXTRA_BOOT_PARAMS)/g' /usr/share/lorax/templates.d/99-generic/config_files/x86/grub2-efi.cfg sed -i 's/linux @KERNELPATH@ @ROOT@ inst.rescue quiet/linux @KERNELPATH@ @ROOT@ inst.rescue quiet $(EXTRA_BOOT_PARAMS)/g' /usr/share/lorax/templates.d/99-generic/config_files/x86/grub2-bios.cfg sed -i 's/linuxefi @KERNELPATH@ @ROOT@ inst.rescue quiet/linuxefi @KERNELPATH@ @ROOT@ inst.rescue quiet $(EXTRA_BOOT_PARAMS)/g' /usr/share/lorax/templates.d/99-generic/config_files/x86/grub2-efi.cfg + # Build boot.iso lorax -p $(IMAGE_NAME) -v $(VERSION) -r $(VERSION) -t $(VARIANT) \ --isfinal --buildarch=$(ARCH) --volid=$(_VOLID) \ $(_LORAX_ARGS) \ @@ -87,7 +99,7 @@ container/$(IMAGE_NAME)-$(IMAGE_TAG): podman rmi $(IMAGE_REPO)/$(IMAGE_NAME):$(IMAGE_TAG) install-deps: - dnf install -y lorax xorriso podman git rpm-ostree + dnf install -y lorax xorriso podman git # Step 4: Generate xorriso script xorriso/%.sh: xorriso/%.sh.in diff --git a/README.md b/README.md index e6ceee2f..3f3e5056 100644 --- a/README.md +++ b/README.md @@ -16,32 +16,45 @@ This will create an ISO with the baked in defaults of the container image. See [Customizing](#customizing) for information about customizing the image that gets created. The variable can either be defined as environment variables or as command arguments. Examples: -Creating Bluefin GTS ISO +Creating Universal Blue Silverblue ISO ```bash -docker run --rm --privileged --volume .:/isogenerator/output -e VERSION=38 -e IMAGE_NAME=bluefin -e IMAGE_TAG=gts -e VARIANT=Silverblue ghcr.io/ublue-os/isogenerator:38 +docker run --rm --privileged --volume .:/isogenerator/output -e VERSION=39 -e IMAGE_NAME=silverblue-main -e IMAGE_TAG=latest -e VARIANT=Silverblue ghcr.io/ublue-os/isogenerator:39 +``` +```bash +# Requires sudo to run +sudo podman run --rm --privileged --volume .:/isogenerator/output -e VERSION=39 -e IMAGE_NAME=silverblue-main -e IMAGE_TAG=latest -e VARIANT=Silverblue ghcr.io/ublue-os/isogenerator:39 ``` -Creating Bazzite Latest ISO +Creating Universal Blue Kinoite ISO +```bash +docker run --rm --privileged --volume .:/isogenerator/output -e VERSION=39 -e IMAGE_NAME=kinoite-main -e IMAGE_TAG=latest -e VARIANT=Kinoite ghcr.io/ublue-os/isogenerator:39 +``` ```bash -docker run --rm --privileged --volume .:/isogenerator/output -e VERSION=39 -e IMAGE_NAME=bazzite -e IMAGE_TAG=latest -e VARIANT=Kinoite ghcr.io/ublue-os/isogenerator:39 +# Requires sudo to run +sudo podman run --rm --privileged --volume .:/isogenerator/output -e VERSION=39 -e IMAGE_NAME=kinoite-main -e IMAGE_TAG=latest -e VARIANT=Kinoite ghcr.io/ublue-os/isogenerator:39 ``` ## Customizing The following variables can be used to customize the create image. -| Variable | Description | Default Value | -| ----------------- | -------------------------------------------------------- | ---------------------- | -| ARCH | Architecture for image to build | x86_64 | -| VERSION | Fedora version of installer to build | 39 | -| IMAGE_REPO | Repository containing the source container image | ghcr.io/ublue-os | -| IMAGE_NAME | Name of the source container image | base-main | -| IMAGE_TAG | Tag of the source container image | *VERSION* | -| EXTRA_BOOT_PARAMS | Extra params used by grub to boot the anaconda installer | \[empty\] | -| VARIANT | Source container variant\* | Kinoite | -| WEB_UI | Enable Anaconda WebUI (experimental) | false | - -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 +| Variable | Description | Default Value | +| ----------------- | ------------------------------------------------------------ | ---------------------- | +| ARCH | Architecture for image to build | x86_64 | +| VERSION | Fedora version of installer to build | 39 | +| IMAGE_REPO | Repository containing the source container image | ghcr.io/ublue-os | +| IMAGE_NAME | Name of the source container image | base-main | +| IMAGE_TAG | Tag of the source container image | *VERSION* | +| EXTRA_BOOT_PARAMS | Extra params used by grub to boot the anaconda installer | \[empty\] | +| VARIANT | Source container variant\* | Kinoite | +| WEB_UI | Enable Anaconda WebUI (experimental) | false | +| ENROLLMENT_PASSWORD | Password used to enroll secure boot key into BIOS\*\* | isogenerator | +| SECURE_BOOT_KEY_URL | URL used to download your secure boot key for enrollment\*\* | \[empty\] | + +\*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 + +\*\*NOTE: ENROLLMENT_PASSWORD and SECURE_BOOT_KEY_URL are not required. They are only required if you are creating specific kernel modules or if you are using Universal Blue Kernel Modules. + +Our public key for our kmods is located here: https://github.com/ublue-os/akmods/raw/main/certs/public_key.der ## 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/ublue-os/isogenerator`, 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. diff --git a/action.yml b/action.yml index 83438cd9..2b74fd8b 100644 --- a/action.yml +++ b/action.yml @@ -32,6 +32,13 @@ inputs: description: Enable Anaconda WebUI required: true default: "false" + ENROLLMENT_PASSWORD: + description: Used for supporting secure boot (requires SECURE_BOOT_KEY_URL to be defined) + required: false + default: "ublue-os" + SECURE_BOOT_KEY_URL: + description: Secure boot key that is installed from URL location + required: false ACTION_REPO: description: Repository with the build action required: false @@ -107,7 +114,9 @@ runs: VARIANT=${{ inputs.VARIANT }} \ VERSION=${{ inputs.VERSION }} \ WEB_UI=${{ inputs.WEB_UI }} \ - EXTRA_BOOT_PARAMS=${{ inputs.EXTRA_BOOT_PARAMS }} + EXTRA_BOOT_PARAMS=${{ inputs.EXTRA_BOOT_PARAMS }} \ + SECURE_BOOT_KEY_URL=${{ inputs.SECURE_BOOT_KEY_URL }} \ + ENROLLMENT_PASSWORD=${{ inputs.ENROLLMENT_PASSWORD }} - name: Create deploy.iso and generate sha256 checksum shell: bash @@ -123,13 +132,3 @@ runs: mkdir end_iso sha256sum ${{ inputs.IMAGE_NAME }}-${{ inputs.IMAGE_TAG || inputs.VERSION }}.iso > ./end_iso/${{ inputs.IMAGE_NAME }}-${{ inputs.IMAGE_TAG || inputs.VERSION }}-CHECKSUM mv ${{ inputs.IMAGE_NAME }}-${{ inputs.IMAGE_TAG || inputs.VERSION }}.iso end_iso/ - - - name: Upload ISO as artifact - uses: actions/upload-artifact@v4 - with: - name: ${{ inputs.IMAGE_NAME }}-${{ inputs.IMAGE_TAG || inputs.VERSION }}.iso - path: end_iso/* - if-no-files-found: error - retention-days: 0 - compression-level: 0 - overwrite: true diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 00000000..27160e89 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -eu + +# pre-create loop devices manually. In containers we can't use losetup for that. +mknod -m 0660 /dev/loop0 b 7 0 2>/dev/null || true + +make output/${IMAGE_NAME}-${IMAGE_TAG}.iso \ + ARCH=${ARCH} \ + VERSION=${VERSION} \ + IMAGE_REPO=${IMAGE_REPO} \ + IMAGE_NAME=${IMAGE_NAME} \ + IMAGE_TAG=${IMAGE_TAG} \ + VARIANT=${VARIANT} \ + WEB_UI=${WEB_UI} \ + SECURE_BOOT_KEY_URL=${SECURE_BOOT_KEY_URL} \ + ENROLLMENT_PASSWORD=${ENROLLMENT_PASSWORD} diff --git a/scripts/enroll-secureboot-key.sh b/scripts/enroll-secureboot-key.sh.in similarity index 73% rename from scripts/enroll-secureboot-key.sh rename to scripts/enroll-secureboot-key.sh.in index df91def8..dd1fd4e2 100755 --- a/scripts/enroll-secureboot-key.sh +++ b/scripts/enroll-secureboot-key.sh.in @@ -2,14 +2,8 @@ set -oue pipefail -readonly SECUREBOOT_KEY="/run/install/repo/ublue-os-akmods-public-key.der" -readonly ENROLLMENT_PASSWORD="ublue-os" - -SYS_ID="$(cat /sys/devices/virtual/dmi/id/product_name)" -if [[ ":Jupiter:Galileo:" =~ ":$SYS_ID:" ]]; then - echo "Steam Deck hardware detected. Skipping key enrollment." - exit 0 -fi +readonly ENROLLMENT_PASSWORD=@ENROLLMENT_PASSWORD@ +readonly SECUREBOOT_KEY="/run/install/repo/sb_pubkey.der" if [[ ! -d "/sys/firmware/efi" ]]; then echo "EFI mode not detected. Skipping key enrollment." @@ -17,8 +11,14 @@ if [[ ! -d "/sys/firmware/efi" ]]; then fi if [[ ! -f "${SECUREBOOT_KEY}" ]]; then - echo "Secure boot key not found: ${SECUREBOOT_KEY}" - exit 1 + echo "Secure boot key not provided: ${SECUREBOOT_KEY}" + exit 0 +fi + +SYS_ID="$(cat /sys/devices/virtual/dmi/id/product_name)" +if [[ ":Jupiter:Galileo:" =~ ":$SYS_ID:" ]]; then + echo "Steam Deck hardware detected. Skipping key enrollment." + exit 0 fi mokutil --timeout -1 || : diff --git a/scripts/ublue-os-akmods-public-key.der b/scripts/ublue-os-akmods-public-key.der deleted file mode 100644 index 98507ab7..00000000 Binary files a/scripts/ublue-os-akmods-public-key.der and /dev/null differ diff --git a/xorriso/gen_input.sh.in b/xorriso/gen_input.sh.in index 917675b3..eb585edc 100644 --- a/xorriso/gen_input.sh.in +++ b/xorriso/gen_input.sh.in @@ -5,8 +5,10 @@ echo "-outdev $(pwd)/output/@IMAGE_NAME@-@IMAGE_TAG@.iso" echo "-boot_image any replay" echo "-joliet on" echo "-compliance joliet_long_names" -echo "-map $(pwd)/scripts/ublue-os-akmods-public-key.der ublue-os-akmods-public-key.der" -echo "-chmod 0444 /ublue-os-akmods-public-key.der" +if [ -f $(pwd)/sb_pubkey.der ]; then + echo "-map $(pwd)/sb_pubkey.der sb_pubkey.der" + echo "-chmod 0444 /sb_pubkey.der" +fi echo "-map $(pwd)/scripts/enroll-secureboot-key.sh enroll-secureboot-key.sh" echo "-chmod 0777 enroll-secureboot-key.sh" cd container