diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 945b0d7d5e..b9bf85ecb8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-12-26T15:20:08Z by kres fcff05e. +# Generated on 2025-01-14T13:54:20Z by kres fcff05e. name: default concurrency: @@ -3453,6 +3453,99 @@ jobs: /tmp/logs-*.tar.gz /tmp/support-*.zip retention-days: "5" + integration-uki: + permissions: + actions: read + contents: write + issues: read + packages: write + pull-requests: read + runs-on: + - self-hosted + - talos + if: contains(fromJSON(needs.default.outputs.labels), 'integration/uki') + needs: + - default + steps: + - name: gather-system-info + id: system-info + uses: kenchan0130/actions-system-info@v1.3.0 + continue-on-error: true + - name: print-system-info + run: | + MEMORY_GB=$((${{ steps.system-info.outputs.totalmem }}/1024/1024/1024)) + + OUTPUTS=( + "CPU Core: ${{ steps.system-info.outputs.cpu-core }}" + "CPU Model: ${{ steps.system-info.outputs.cpu-model }}" + "Hostname: ${{ steps.system-info.outputs.hostname }}" + "NodeName: ${NODE_NAME}" + "Kernel release: ${{ steps.system-info.outputs.kernel-release }}" + "Kernel version: ${{ steps.system-info.outputs.kernel-version }}" + "Name: ${{ steps.system-info.outputs.name }}" + "Platform: ${{ steps.system-info.outputs.platform }}" + "Release: ${{ steps.system-info.outputs.release }}" + "Total memory: ${MEMORY_GB} GB" + ) + + for OUTPUT in "${OUTPUTS[@]}";do + echo "${OUTPUT}" + done + continue-on-error: true + - name: checkout + uses: actions/checkout@v4 + - name: Unshallow + run: | + git fetch --prune --unshallow + - name: Set up Docker Buildx + id: setup-buildx + uses: docker/setup-buildx-action@v3 + with: + driver: remote + endpoint: tcp://buildkit-amd64.ci.svc.cluster.local:1234 + timeout-minutes: 10 + - name: Download artifacts + if: github.event_name != 'schedule' + uses: actions/download-artifact@v4 + with: + name: talos-artifacts + path: _out + - name: Fix artifact permissions + if: github.event_name != 'schedule' + run: | + xargs -a _out/executable-artifacts -I {} chmod +x {} + - name: ci-temp-release-tag + if: github.event_name != 'schedule' + run: | + make ci-temp-release-tag + - name: build + if: github.event_name == 'schedule' + env: + IMAGE_REGISTRY: registry.dev.siderolabs.io + PLATFORM: linux/amd64 + PUSH: "true" + run: | + make talosctl-linux-amd64 installer imager _out/integration-test-linux-amd64 + - name: talosctl-cni-bundle + if: github.event_name == 'schedule' + run: | + make talosctl-cni-bundle + - name: integration-uki + env: + GITHUB_STEP_NAME: ${{ github.job}}-integration-uki + IMAGE_REGISTRY: registry.dev.siderolabs.io + WITH_UKI: "true" + run: | + sudo -E make e2e-qemu + - name: save artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: talos-logs-integration-uki + path: |- + /tmp/logs-*.tar.gz + /tmp/support-*.zip + retention-days: "5" push: permissions: actions: read diff --git a/.github/workflows/integration-uki-cron.yaml b/.github/workflows/integration-uki-cron.yaml new file mode 100644 index 0000000000..d7f7477c0c --- /dev/null +++ b/.github/workflows/integration-uki-cron.yaml @@ -0,0 +1,96 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2025-01-14T13:54:20Z by kres fcff05e. + +name: integration-uki-cron +concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true +"on": + schedule: + - cron: 30 3 * * * +jobs: + default: + runs-on: + - self-hosted + - talos + steps: + - name: gather-system-info + id: system-info + uses: kenchan0130/actions-system-info@v1.3.0 + continue-on-error: true + - name: print-system-info + run: | + MEMORY_GB=$((${{ steps.system-info.outputs.totalmem }}/1024/1024/1024)) + + OUTPUTS=( + "CPU Core: ${{ steps.system-info.outputs.cpu-core }}" + "CPU Model: ${{ steps.system-info.outputs.cpu-model }}" + "Hostname: ${{ steps.system-info.outputs.hostname }}" + "NodeName: ${NODE_NAME}" + "Kernel release: ${{ steps.system-info.outputs.kernel-release }}" + "Kernel version: ${{ steps.system-info.outputs.kernel-version }}" + "Name: ${{ steps.system-info.outputs.name }}" + "Platform: ${{ steps.system-info.outputs.platform }}" + "Release: ${{ steps.system-info.outputs.release }}" + "Total memory: ${MEMORY_GB} GB" + ) + + for OUTPUT in "${OUTPUTS[@]}";do + echo "${OUTPUT}" + done + continue-on-error: true + - name: checkout + uses: actions/checkout@v4 + - name: Unshallow + run: | + git fetch --prune --unshallow + - name: Set up Docker Buildx + id: setup-buildx + uses: docker/setup-buildx-action@v3 + with: + driver: remote + endpoint: tcp://buildkit-amd64.ci.svc.cluster.local:1234 + timeout-minutes: 10 + - name: Download artifacts + if: github.event_name != 'schedule' + uses: actions/download-artifact@v4 + with: + name: talos-artifacts + path: _out + - name: Fix artifact permissions + if: github.event_name != 'schedule' + run: | + xargs -a _out/executable-artifacts -I {} chmod +x {} + - name: ci-temp-release-tag + if: github.event_name != 'schedule' + run: | + make ci-temp-release-tag + - name: build + if: github.event_name == 'schedule' + env: + IMAGE_REGISTRY: registry.dev.siderolabs.io + PLATFORM: linux/amd64 + PUSH: "true" + run: | + make talosctl-linux-amd64 installer imager _out/integration-test-linux-amd64 + - name: talosctl-cni-bundle + if: github.event_name == 'schedule' + run: | + make talosctl-cni-bundle + - name: integration-uki + env: + GITHUB_STEP_NAME: ${{ github.job}}-integration-uki + IMAGE_REGISTRY: registry.dev.siderolabs.io + WITH_UKI: "true" + run: | + sudo -E make e2e-qemu + - name: save artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: talos-logs-integration-uki + path: |- + /tmp/logs-*.tar.gz + /tmp/support-*.zip + retention-days: "5" diff --git a/.github/workflows/slack-notify.yaml b/.github/workflows/slack-notify.yaml index 6b19882b4c..510ffcc54f 100644 --- a/.github/workflows/slack-notify.yaml +++ b/.github/workflows/slack-notify.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-12-26T15:20:08Z by kres fcff05e. +# Generated on 2025-01-14T13:54:20Z by kres fcff05e. name: slack-notify "on": @@ -10,6 +10,7 @@ name: slack-notify - integration-qemu-cron - integration-conformance-cron - integration-trusted-boot-cron + - integration-uki-cron - integration-provision-0-cron - integration-provision-1-cron - integration-provision-2-cron diff --git a/.kres.yaml b/.kres.yaml index b72d6316f8..9ad2b769c1 100644 --- a/.kres.yaml +++ b/.kres.yaml @@ -54,6 +54,7 @@ spec: - e2e-docker-short - integration-qemu - integration-trusted-boot + - integration-uki - integration-provision-0 - integration-provision-1 - integration-provision-2 @@ -470,6 +471,57 @@ spec: artifactPath: /tmp/logs-*.tar.gz additionalArtifacts: - "/tmp/support-*.zip" + - name: integration-uki + buildxOptions: + enabled: true + depends: + - default + runners: + - self-hosted + - talos + crons: + - '30 3 * * *' + triggerLabels: + - integration/uki + steps: + - name: download-artifacts + conditions: + - not-on-schedule + artifactStep: + type: download + artifactName: talos-artifacts + artifactPath: _out + - name: ci-temp-release-tag + conditions: + - not-on-schedule + - name: build + conditions: + - only-on-schedule + command: talosctl-linux-amd64 installer imager _out/integration-test-linux-amd64 + environment: + PLATFORM: linux/amd64 + IMAGE_REGISTRY: registry.dev.siderolabs.io + PUSH: true + - name: talosctl-cni-bundle + conditions: + - only-on-schedule + - name: integration-uki + command: e2e-qemu + withSudo: true + environment: + GITHUB_STEP_NAME: ${{ github.job}}-integration-uki + WITH_UKI: true + IMAGE_REGISTRY: registry.dev.siderolabs.io + - name: save-talos-logs + conditions: + - always + artifactStep: + type: upload + artifactName: talos-logs-integration-uki + disableExecutableListGeneration: true + artifactPath: /tmp/logs-*.tar.gz + additionalArtifacts: + - "/tmp/support-*.zip" - name: integration-provision-0 buildxOptions: enabled: true diff --git a/Makefile b/Makefile index 33b86d8b42..f26a4bb112 100644 --- a/Makefile +++ b/Makefile @@ -446,7 +446,7 @@ image-%: ## Builds the specified image. Valid options are aws, azure, digital-oc docker run --rm -t -v /dev:/dev -v $(PWD)/$(ARTIFACTS):/secureboot:ro -v $(PWD)/$(ARTIFACTS):/out -e SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH) --network=host --privileged $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) $* --arch $$arch $(IMAGER_ARGS) ; \ done -images-essential: image-aws image-azure image-gcp image-metal secureboot-installer ## Builds only essential images used in the CI (AWS, GCP, and Metal). +images-essential: image-aws image-azure image-gcp image-metal image-metal-uki uki-installer secureboot-installer ## Builds only essential images used in the CI (AWS, GCP, and Metal). images: image-akamai image-aws image-azure image-digital-ocean image-exoscale image-cloudstack image-gcp image-hcloud image-iso image-metal image-nocloud image-opennebula image-openstack image-oracle image-scaleway image-upcloud image-vmware image-vultr ## Builds all known images (AWS, Azure, DigitalOcean, Exoscale, Cloudstack, GCP, HCloud, Metal, NoCloud, OpenNebula, OpenStack, Oracle, Scaleway, UpCloud, Vultr and VMware). @@ -602,6 +602,11 @@ provision-tests-track-%: REGISTRY=$(IMAGE_REGISTRY) \ ARTIFACTS=$(ARTIFACTS) +uki-installer: + $(MAKE) image-installer \ + IMAGER_ARGS="--extra-kernel-arg=console=ttyS0" + crane push $(ARTIFACTS)/installer-$${arch}.tar $(REGISTRY_AND_USERNAME)/installer:$(IMAGE_TAG)-$${arch}-uki ; \ + installer-with-extensions: $(ARTIFACTS)/extensions/_out/extensions-metadata $(MAKE) image-installer \ IMAGER_ARGS="--base-installer-image=$(REGISTRY_AND_USERNAME)/installer:$(IMAGE_TAG) $(shell cat $(ARTIFACTS)/extensions/_out/extensions-metadata | $(EXTENSIONS_FILTER_COMMAND) | xargs -n 1 echo --system-extension-image)" diff --git a/go.mod b/go.mod index c7968ef01d..897b7f2414 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/siderolabs/talos -go 1.23.3 +go 1.23.4 replace ( // see e.g. https://github.com/grpc/grpc-go/issues/6696 diff --git a/go.work b/go.work index dbcf1a238b..cf3fd50adc 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.23.3 +go 1.23.4 use ( . diff --git a/hack/test/e2e-qemu.sh b/hack/test/e2e-qemu.sh index da806baf10..59d952e240 100755 --- a/hack/test/e2e-qemu.sh +++ b/hack/test/e2e-qemu.sh @@ -218,6 +218,15 @@ case "${WITH_IOMMU:-false}" in ;; esac +case "${WITH_UKI:-false}" in + false) + ;; + *) + INSTALLER_IMAGE=${INSTALLER_IMAGE}-amd64-uki + QEMU_FLAGS+=("--uki-path=_out/metal-amd64-uki.efi") + ;; +esac + function create_cluster { build_registry_mirrors diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/options/options.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/options/options.go index 41a5de4ea9..9129226d41 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/options/options.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/options/options.go @@ -8,6 +8,7 @@ package options import ( "fmt" + "github.com/foxboron/go-uefi/efi" "github.com/siderolabs/go-blockdevice/v2/blkid" "github.com/siderolabs/talos/pkg/machinery/constants" @@ -63,6 +64,8 @@ type BootAssets struct { } // FillDefaults fills in default paths to be used when in the context of the installer. +// +//nolint:gocyclo func (assets *BootAssets) FillDefaults(arch string) { if assets.KernelPath == "" { assets.KernelPath = fmt.Sprintf(constants.KernelAssetPath, arch) @@ -74,6 +77,10 @@ func (assets *BootAssets) FillDefaults(arch string) { if assets.UKIPath == "" { assets.UKIPath = fmt.Sprintf(constants.UKIAssetPath, arch) + + if efi.GetSecureBoot() && !efi.GetSetupMode() { + assets.UKIPath = fmt.Sprintf(constants.SignedUKIAssetPath, arch) + } } if assets.SDBootPath == "" { diff --git a/pkg/imager/out.go b/pkg/imager/out.go index 5b837ec058..17819a1fa7 100644 --- a/pkg/imager/out.go +++ b/pkg/imager/out.go @@ -393,17 +393,10 @@ func (i *Imager) outInstaller(ctx context.Context, path string, report *reporter printf("generating artifacts layer") + ukiPath := strings.TrimLeft(fmt.Sprintf(constants.UKIAssetPath, i.prof.Arch), "/") + if i.prof.SecureBootEnabled() { - artifacts = append(artifacts, - filemap.File{ - ImagePath: strings.TrimLeft(fmt.Sprintf(constants.UKIAssetPath, i.prof.Arch), "/"), - SourcePath: i.ukiPath, - }, - filemap.File{ - ImagePath: strings.TrimLeft(fmt.Sprintf(constants.SDBootAssetPath, i.prof.Arch), "/"), - SourcePath: i.sdBootPath, - }, - ) + ukiPath = strings.TrimLeft(fmt.Sprintf(constants.SignedUKIAssetPath, i.prof.Arch), "/") } else { artifacts = append(artifacts, filemap.File{ @@ -417,6 +410,17 @@ func (i *Imager) outInstaller(ctx context.Context, path string, report *reporter ) } + artifacts = append(artifacts, + filemap.File{ + ImagePath: strings.TrimLeft(fmt.Sprintf(constants.SDBootAssetPath, i.prof.Arch), "/"), + SourcePath: i.sdBootPath, + }, + filemap.File{ + ImagePath: ukiPath, + SourcePath: i.ukiPath, + }, + ) + if !quirks.New(i.prof.Version).SupportsOverlay() { for _, extraArtifact := range []struct { sourcePath string diff --git a/pkg/imager/profile/profile.go b/pkg/imager/profile/profile.go index bb5ff9554d..93a287cbee 100644 --- a/pkg/imager/profile/profile.go +++ b/pkg/imager/profile/profile.go @@ -108,10 +108,6 @@ func (p *Profile) Validate() error { return errors.New("disk size is required for image output") } case OutKindInstaller: - if !p.SecureBootEnabled() && len(p.Customization.ExtraKernelArgs) > 0 { - return fmt.Errorf("customization of kernel args is not supported for %s output in !secureboot mode", p.Output.Kind) - } - if len(p.Customization.MetaContents) > 0 { return fmt.Errorf("customization of meta partition is not supported for %s output", p.Output.Kind) } diff --git a/pkg/machinery/constants/constants.go b/pkg/machinery/constants/constants.go index 14dd527582..65d42a03c5 100644 --- a/pkg/machinery/constants/constants.go +++ b/pkg/machinery/constants/constants.go @@ -630,11 +630,17 @@ const ( RootfsAsset = "rootfs.sqsh" // UKIAsset defines a well known name for our UKI filename. - UKIAsset = "vmlinuz.efi.signed" + UKIAsset = "vmlinuz.efi" + + // SignedUKIAsset defines a well known name for our UKI filename. + SignedUKIAsset = "vmlinuz.efi.signed" // UKIAssetPath is the path to the UKI in the installer. UKIAssetPath = "/usr/install/%s/" + UKIAsset + // SignedUKIAssetPath is the path to the UKI in the installer. + SignedUKIAssetPath = "/usr/install/%s/" + SignedUKIAsset + // SDStubAsset defines a well known name for our systemd-stub filename. SDStubAsset = "systemd-stub.efi"