diff --git a/.github/workflows/genesis-openembedded.yml b/.github/workflows/genesis-openembedded.yml index dc7d2b6..0aa5fab 100644 --- a/.github/workflows/genesis-openembedded.yml +++ b/.github/workflows/genesis-openembedded.yml @@ -35,6 +35,10 @@ jobs: perl -c mockbuild-all.pl perl -c BuildUtils.pm perl -c sbuild-all.pl + perl -c ipxe-xcat/mockbuild.pl + perl -c ipxe-xcat/sbuild.pl + perl -c ipxe-xcat/verify-payload.pl + rpmspec -P ipxe-xcat/ipxe-xcat.spec >/dev/null rpmspec -P \ -D 'genesis_arch x86_64' \ -D 'version 2.19.0' \ @@ -44,6 +48,9 @@ jobs: genesis-openembedded/build \ genesis-openembedded/package \ genesis-openembedded/verify-release \ + ipxe-xcat/mockbuild.pl \ + ipxe-xcat/sbuild.pl \ + ipxe-xcat/verify-payload.pl \ lib/XCAT/BuildUtils.pm \ lib/XCAT/GenesisRelease.pm \ mockbuild-all.pl \ @@ -51,6 +58,7 @@ jobs: t/common-repo-gate.t \ t/genesis_openembedded_release.t \ t/genesis_openembedded_consumer.t \ + t/ipxe_xcat_payload.t \ t/lib/XCAT/GenesisReleaseTest.pm - name: Run package tests @@ -59,6 +67,7 @@ jobs: prove -v t/build_timeout.t prove -v t/sbuild-all.t prove -v t/goconserver_cross_build.t + prove -v t/ipxe_xcat_payload.t prove -v t/mockbuild-all.t prove -v -It/lib t/genesis_openembedded_release.t sudo -E prove -v -It/lib t/genesis_openembedded_consumer.t diff --git a/BUILD.md b/BUILD.md index b532328..555655d 100644 --- a/BUILD.md +++ b/BUILD.md @@ -50,6 +50,7 @@ This guide uses the following placeholders consistently: - `/goconserver/mockbuild.pl` - `/conserver/mockbuild.pl` - `/xnba/mockbuild.pl` +- `/ipxe-xcat/mockbuild.pl` - `/mockbuild-perl-packages.pl` - `/buildrpms.pl` — only to build the OS-dependent `xCAT-genesis-base` package (unless `--skip-genesis` is set); the full xCAT core is built separately by the xcat-core pipeline, not here. @@ -103,7 +104,7 @@ Use these flags to skip specific operations: - `--skip-genesis` - Skips the `xCAT-genesis-base` build (`/buildrpms.pl --package xCAT-genesis-base`). - `--skip-xcat-dep` - - Skips non-perl xcat-dep package builders (`elilo`, `grub2-xcat`, `ipmitool-xcat`, `syslinux-xcat`, `goconserver`, `conserver-xcat`, `xnba-undi`). + - Skips non-perl xcat-dep package builders (`elilo`, `grub2-xcat`, `ipmitool-xcat`, `syslinux-xcat`, `goconserver`, `conserver-xcat`, `xnba-undi`, `ipxe-xcat`). - `--skip-perl` - Skips `/mockbuild-perl-packages.pl`. - With any of the three flags above, the run repository, the tarball and the deployed cell keep @@ -459,7 +460,7 @@ missing, and then builds the `[rocky-10-riscv64-xcat]` section of `packages-mani | goconserver | cross-compiled on the host (`GOARCH=riscv64`), packaged with `rpmbuild --target riscv64` | | grub2-xcat (noarch) | built in the native, EPEL-free `rocky-10-x86_64` chroot | | perl list6 + EPEL gap (`--epel-gap`) | `mockbuild-perl-packages.pl --target-arch riscv64 --noarch-mock-cfg rocky-10-x86_64 --epel-gap`: XS modules in the riscv64 chroot, noarch modules in the native chroot | -| elilo-xcat, syslinux-xcat, xnba-undi (noarch) | built in the native `rocky-10-x86_64` chroot, like grub2-xcat: a riscv64 management node serves the x86 nodes of a mixed cluster. The target is cross-built on x86_64 only, as its mock config states | +| elilo-xcat, ipxe-xcat, syslinux-xcat, xnba-undi (noarch) | built in the native `rocky-10-x86_64` chroot, like grub2-xcat: a riscv64 management node serves the x86 nodes of a mixed cluster. The target is cross-built on x86_64 only, as its mock config states | There is no EPEL for riscv64, so the perl deps of xCAT that EL10 otherwise takes from EPEL are built here as well (`--epel-gap` in `mockbuild-perl-packages.pl`: perl-Crypt-Blowfish, @@ -608,16 +609,16 @@ Codename ↔ version (the single supported set — `BuildUtils` is the source of `mk-build-deps`, so version constraints, `a | b` alternatives and arch qualifiers are honoured) are all **fatal** on failure — and since nothing survives the session, a package whose `debian/control` forgets a `Build-Depends` cannot build green on a sibling package's leftovers. -- **Per-arch package sets (`debs-manifest.conf`).** One `[-]` section per target. The - noarch boot components (`syslinux-xcat`/`grub2-xcat`/`elilo-xcat`/`xnba-undi`, `Architecture:all`) - are built ONCE on amd64 — single producer, their source is x86-only — and assembled into every - arch's `Packages` index. They are listed for **ppc64el too, as required-present**, so the gate - verifies the ppc repo actually carries them (a ppc MN needs them for netboot, matching the EL - manifest). `build_one_codename` **skips** an `Architecture:all` package on any non-amd64 arch - (detected via `control_binary_arch`), so ppc64el and riscv64 build only the genuinely - arch-specific compiled deps (`ipmitool-xcat`, `conserver-xcat`, `goconserver`) yet still verify the - boot components they need. The riscv64 sections require the same four boot components as - ppc64el: a riscv64 management node serves the x86 nodes of a mixed cluster. +- **Per-arch package sets (`debs-manifest.conf`).** One `[-]` section per target. + The noarch boot components (`syslinux-xcat`/`grub2-xcat`/`elilo-xcat`/`xnba-undi`/`ipxe-xcat`, + `Architecture:all`) are built ONCE on amd64 — single producer, most of them from x86-only source — + and assembled into every arch's `Packages` index. They are listed for **ppc64el too, as + required-present**, so the gate verifies the ppc repo actually carries them (a ppc MN needs them + for netboot, matching the EL manifest). `build_one_codename` **skips** an `Architecture:all` + package on any non-amd64 arch (detected via `control_binary_arch`), so ppc64el and riscv64 build + only the genuinely arch-specific compiled deps (`ipmitool-xcat`, `conserver-xcat`, `goconserver`) + yet still verify the boot components they need. The riscv64 sections require the same five boot + components as ppc64el: a riscv64 management node serves the x86 nodes of a mixed cluster. - **Fail-hard.** Any required chroot / package / artifact failure, or any version-pin mismatch, fails the whole run non-zero. - **Genesis keeps its maintained packaging.** A native `xcat-genesis-base` deb is INGESTED as-is when @@ -683,7 +684,7 @@ needs no `--mirror`. | ipmitool-xcat, conserver-xcat | `dpkg-buildpackage` in the emulated riscv64 chroot | | goconserver | same chroot, compiled by the Go toolchain the chroot installs for riscv64 | | grub2-xcat (`Architecture:all`) | built once on amd64 and assembled into the riscv64 index; listed in the riscv64 manifest sections as required-present, because a riscv64 management node needs it to netboot | -| syslinux-xcat, elilo-xcat, xnba-undi (`Architecture:all`) | built once on amd64 and assembled into the riscv64 index; required-present like grub2-xcat, because a riscv64 management node serves the x86 nodes of a mixed cluster | +| syslinux-xcat, elilo-xcat, xnba-undi, ipxe-xcat (`Architecture:all`) | built once on amd64 and assembled into the riscv64 index; required-present like grub2-xcat, because a riscv64 management node serves the x86 nodes of a mixed cluster | | xcat-genesis-base | not built: no riscv64 section names it, and the build skips the step when the manifest does not ask for it, so `--skip-genesis` is unnecessary here | The riscv64 ipmitool-xcat deb is installed into the chroot that built it and diff --git a/MockBuildUtils.pm b/MockBuildUtils.pm index ff62ed0..5e4a1d9 100644 --- a/MockBuildUtils.pm +++ b/MockBuildUtils.pm @@ -23,7 +23,7 @@ our @EXPORT_OK = qw( parse_evr evr_cmp evr_constraint_ok parse_pin rpmkeys_checksig_problem rpm_version rpm_release rpm_sigmd5 rpm_is_signed restamp_release_line cross_copy_genesis finalize_xcat_dep bump_dep_release_suffix - build_mock_uniqueext rpm_in_cell + build_mock_uniqueext rpm_in_cell resolve_mock_cfg ); # install_deps_packages($os_id): the host packages mockbuild-all.pl needs to run at all, for the @@ -723,4 +723,30 @@ sub build_mock_uniqueext { return sprintf("mba-%02d-%s-%s", $idx, $run_part, $label_part); } +# resolve_mock_cfg($os_id, $rel, $arch[, $cfg_dir]): the mock config for EL release $rel on this +# host, +epel--. /etc/os-release says 'almalinux' where mock-core-configs names the +# file 'alma', so the short form is tried too. $cfg_dir defaults to /etc/mock. +sub resolve_mock_cfg { + my ($os_id, $rel, $arch, $cfg_dir) = @_; + $cfg_dir //= '/etc/mock'; + my %short_forms = ( + almalinux => 'alma', + 'centos-stream' => 'centos-stream', + rocky => 'rocky', + ); + # Resolve by CONFIG-FILE existence, not by running `mock --print-root-path`: the latter can fail + # transiently (bootstrap chroot setup, a concurrent mock holding a lock) and made el10 flakily + # "resolve" to the long form that has no .cfg. Checking /.cfg is deterministic. + for my $id ($os_id, (exists $short_forms{$os_id} ? ($short_forms{$os_id}) : ())) { + my $candidate = "${id}+epel-${rel}-${arch}"; + if (-f "$cfg_dir/${candidate}.cfg") { + print "Mock config resolved: $candidate\n" if $id ne $os_id; + return $candidate; + } + } + my $short = $short_forms{$os_id} // $os_id; + die "Could not find mock config for ${os_id}+epel-${rel}-${arch} " + . "(tried $cfg_dir/${os_id}+epel-${rel}-${arch}.cfg and $cfg_dir/${short}+epel-${rel}-${arch}.cfg)\n"; +} + 1; diff --git a/debs-manifest.conf b/debs-manifest.conf index f4707b4..d991942 100644 --- a/debs-manifest.conf +++ b/debs-manifest.conf @@ -31,10 +31,11 @@ # PER-ARCH SETS (review concern #3 -- the arch matrix must be valid): # * Compiled, arch-specific deps that genuinely build on BOTH arches are listed for amd64 AND # ppc64el: ipmitool-xcat, conserver-xcat, goconserver (debian/control Architecture: any / *-ppc64el). -# * The noarch boot components (syslinux-xcat, grub2-xcat, elilo-xcat, xnba-undi) are +# * The noarch boot components (syslinux-xcat, grub2-xcat, elilo-xcat, xnba-undi, ipxe-xcat) are # Architecture:all: their SOURCE is x86-only (syslinux compiles with nasm/gcc-multilib; elilo/xnba -# are x86/EFI loaders; grub2-xcat is config/scripts), so they are BUILT ONCE on amd64 -- SINGLE -# PRODUCER, concern #3b -- and, being arch:all, assembled into EVERY arch's Packages index. They +# are x86/EFI loaders; grub2-xcat is config/scripts; ipxe-xcat repackages the iPXE release +# tree), so they are BUILT ONCE on amd64 -- SINGLE PRODUCER, concern #3b -- and, being +# arch:all, assembled into EVERY arch's Packages index. They # ARE listed for ppc64el too, as REQUIRED-PRESENT: a ppc MN needs them for netboot, so the gate # must verify the ppc repo carries them (matching the EL manifest and the historical 2.16 ppc dep # repo, minus the obsolete yaboot-xcat). sbuild-all.pl's build phase SKIPS an Architecture:all @@ -67,6 +68,7 @@ syslinux-xcat=3.86-2 grub2-xcat=2.12-2 elilo-xcat=3.14-6 xnba-undi=1.21.1-1 +ipxe-xcat=2.0.0-1 xcat-genesis-base=2.* [focal-ppc64el] @@ -77,6 +79,7 @@ syslinux-xcat=3.86-2 grub2-xcat=2.12-2 elilo-xcat=3.14-6 xnba-undi=1.21.1-1 +ipxe-xcat=2.0.0-1 xcat-genesis-base=2.* [focal-riscv64] @@ -87,6 +90,7 @@ syslinux-xcat=3.86-2 grub2-xcat=2.12-2 elilo-xcat=3.14-6 xnba-undi=1.21.1-1 +ipxe-xcat=2.0.0-1 # ============================ jammy (ubuntu22.04) ============================ [jammy-amd64] @@ -97,6 +101,7 @@ syslinux-xcat=3.86-2 grub2-xcat=2.12-2 elilo-xcat=3.14-6 xnba-undi=1.21.1-1 +ipxe-xcat=2.0.0-1 xcat-genesis-base=2.* [jammy-ppc64el] @@ -107,6 +112,7 @@ syslinux-xcat=3.86-2 grub2-xcat=2.12-2 elilo-xcat=3.14-6 xnba-undi=1.21.1-1 +ipxe-xcat=2.0.0-1 xcat-genesis-base=2.* [jammy-riscv64] @@ -117,6 +123,7 @@ syslinux-xcat=3.86-2 grub2-xcat=2.12-2 elilo-xcat=3.14-6 xnba-undi=1.21.1-1 +ipxe-xcat=2.0.0-1 # ============================ noble (ubuntu24.04) ============================ [noble-amd64] @@ -127,6 +134,7 @@ syslinux-xcat=3.86-2 grub2-xcat=2.12-2 elilo-xcat=3.14-6 xnba-undi=1.21.1-1 +ipxe-xcat=2.0.0-1 xcat-genesis-base=2.* [noble-ppc64el] @@ -137,6 +145,7 @@ syslinux-xcat=3.86-2 grub2-xcat=2.12-2 elilo-xcat=3.14-6 xnba-undi=1.21.1-1 +ipxe-xcat=2.0.0-1 xcat-genesis-base=2.* [noble-riscv64] @@ -147,6 +156,7 @@ syslinux-xcat=3.86-2 grub2-xcat=2.12-2 elilo-xcat=3.14-6 xnba-undi=1.21.1-1 +ipxe-xcat=2.0.0-1 # ============================ resolute (ubuntu26.04) ========================= [resolute-amd64] @@ -157,6 +167,7 @@ syslinux-xcat=3.86-2 grub2-xcat=2.12-2 elilo-xcat=3.14-6 xnba-undi=1.21.1-1 +ipxe-xcat=2.0.0-1 xcat-genesis-base=2.* [resolute-ppc64el] @@ -167,6 +178,7 @@ syslinux-xcat=3.86-2 grub2-xcat=2.12-2 elilo-xcat=3.14-6 xnba-undi=1.21.1-1 +ipxe-xcat=2.0.0-1 xcat-genesis-base=2.* [resolute-riscv64] @@ -177,6 +189,7 @@ syslinux-xcat=3.86-2 grub2-xcat=2.12-2 elilo-xcat=3.14-6 xnba-undi=1.21.1-1 +ipxe-xcat=2.0.0-1 # [shared] is NOT a build target. It describes the ONE pool the OpenEmbedded Genesis release is # published into (pool/main/xcat-genesis-openembedded), which every suite indexes and which no diff --git a/ipxe-xcat/.gitattributes b/ipxe-xcat/.gitattributes new file mode 100644 index 0000000..a23b4c5 --- /dev/null +++ b/ipxe-xcat/.gitattributes @@ -0,0 +1,2 @@ +# The licence texts stay byte-identical to their upstream sources. +licenses/** -whitespace diff --git a/ipxe-xcat/README b/ipxe-xcat/README new file mode 100644 index 0000000..0098522 --- /dev/null +++ b/ipxe-xcat/README @@ -0,0 +1,87 @@ +ipxe-xcat +========= + +This package installs the ipxeboot.tar.gz tree of the iPXE v2.0.0 release +under /tftpboot/xcat/ipxe. Nothing is rebuilt, and only the two shims are +replaced: see The shim. The x86_64-sb +and arm64-sb builds carry their Secure Boot signatures inside the files, and +the shim finds snponly.efi and ipxe.efi by name in its own directory, so the +package keeps every name, symlink and byte of the release tree. + +Files +----- + +ipxeboot-2.0.0.tar.gz + The ipxeboot.tar.gz asset of + https://github.com/ipxe/ipxe/releases/tag/v2.0.0, renamed. Its SHA-256, + 01a526d4cc791fc30362259c609d6c506cc64a7bdff51b9a5eb788354e17eee1, is the + digest that GitHub publishes for the asset. + +ipxe-2.0.0-source.tar.gz + The source archive of tag v2.0.0, commit + 12798ec29aa8a64d8675c4378b99f5fe28447afb, from + https://github.com/ipxe/ipxe/archive/refs/tags/v2.0.0.tar.gz. Its content + equals "git archive --prefix=ipxe-2.0.0/ v2.0.0". snpnet.c and undinet.c + are GPL2_OR_LATER without the UBDL, so snponly.efi and undionly.kpxe are + GPLv2+ as a whole. The package installs this archive with the binaries. + +ipxe-shimx64.efi, ipxe-shimaa64.efi + The ipxe-shimx64.efi and ipxe-shimaa64.efi assets of + https://github.com/ipxe/shim/releases/tag/ipxe-16.1, as ipxe replaced + them on 2026-05-27. Their SHA-256 values are the digests that GitHub + publishes for the assets. + +SHA256SUMS + The SHA-256 of both archives and both shims. Both builders check it + before the build. + +payload.sha256 + One line for each directory, file and symlink of the release tree, with + the SHA-256 of each file and the target of each symlink. After the build, + both builders unpack the RPM or deb and compare its /tftpboot/xcat/ipxe + with this list, entry for entry, with verify-payload.pl. A difference + fails the build. + +licenses/ + ipxe/COPYING, COPYING.GPLv2 and COPYING.UBDL are from iPXE tag v2.0.0. + shim/COPYRIGHT is from ipxe/shim tag ipxe-16.1. + shim/openssl/LICENSE is from openssl/openssl tag OpenSSL_1_0_2k, the + OpenSSL version that shim 16.1 carries in Cryptlib. + shim/gnu-efi/README.efilib is from rhboot/gnu-efi commit dc7fd96, the + gnu-efi commit that tag ipxe-16.1 pins. + +The shim +-------- + +The release tree carries shim 16.1 as x86_64-sb/shimx64.efi and +arm64-sb/shimaa64.efi, signed by the Microsoft Corporation UEFI CA 2011 +only. Firmware that trusts only the UEFI CA 2023 refuses them with Secure +Boot on. On 2026-05-27 ipxe replaced the ipxe/shim ipxe-16.1 release assets +with a build signed by both CAs. Both builders install ipxe-shimx64.efi and +ipxe-shimaa64.efi over the shims of the tree, under the same names, so the +ipxe-shim.efi and snponly-shim.efi links still point to them. payload.sha256 +lists the digests of the replacements. + +Update to a new release +----------------------- + +1. Download ipxeboot.tar.gz from the release, and compare its SHA-256 with + the digest on the release page. +2. Download the source archive of the tag, and compare its content with + "git archive" of the tag. +3. Replace both archives. Download ipxe-shimx64.efi and ipxe-shimaa64.efi + from the latest ipxe/shim release, and compare their SHA-256 with the + digests on its page. Drop them and their install lines when the shims of + the new tree carry the UEFI CA 2023 signature. +4. Write SHA256SUMS with sha256sum. +5. Write payload.sha256 from the tree with the shims in place: + + mkdir tree + tar -xzf ipxeboot-.tar.gz --strip-components=1 -C tree + cp ipxe-shimx64.efi tree/x86_64-sb/shimx64.efi + cp ipxe-shimaa64.efi tree/arm64-sb/shimaa64.efi + ./verify-payload.pl --generate tree > payload.sha256 + +6. Update licenses/ when the release changes its licence texts or its shim. +7. Set the version in ipxe-xcat.spec and debian/changelog, and the ipxe-xcat + pins in packages-manifest.conf and debs-manifest.conf. diff --git a/ipxe-xcat/SHA256SUMS b/ipxe-xcat/SHA256SUMS new file mode 100644 index 0000000..4759990 --- /dev/null +++ b/ipxe-xcat/SHA256SUMS @@ -0,0 +1,4 @@ +9ed6d029be901a0ccc87cb2e5f9c774620f30f84ebdd507c6dd3e1e6229b7bd5 ipxe-2.0.0-source.tar.gz +31c6d8ef9ed24dc810dd7b951cf86b2e9036a02dea8a32548c0e1c0ae4d6f1c9 ipxe-shimaa64.efi +5eecca2780bd49c900565e124516a1bd666ec5e012825f34991b6ba1ef2fa6cf ipxe-shimx64.efi +01a526d4cc791fc30362259c609d6c506cc64a7bdff51b9a5eb788354e17eee1 ipxeboot-2.0.0.tar.gz diff --git a/ipxe-xcat/debian/changelog b/ipxe-xcat/debian/changelog new file mode 100644 index 0000000..0770d47 --- /dev/null +++ b/ipxe-xcat/debian/changelog @@ -0,0 +1,6 @@ +ipxe-xcat (2.0.0-1) unstable; urgency=medium + + * Package the ipxeboot.tar.gz tree of the iPXE v2.0.0 release, with the + ipxe/shim 16.1 shims signed by both Microsoft UEFI CAs. + + -- xCAT Fri, 25 Sep 2026 12:00:00 +0000 diff --git a/ipxe-xcat/debian/compat b/ipxe-xcat/debian/compat new file mode 100644 index 0000000..48082f7 --- /dev/null +++ b/ipxe-xcat/debian/compat @@ -0,0 +1 @@ +12 diff --git a/ipxe-xcat/debian/control b/ipxe-xcat/debian/control new file mode 100644 index 0000000..4cafab9 --- /dev/null +++ b/ipxe-xcat/debian/control @@ -0,0 +1,16 @@ +Source: ipxe-xcat +Section: admin +Priority: optional +Maintainer: xCAT +Build-Depends: debhelper (>= 12) +Standards-Version: 4.5.0 +Homepage: https://ipxe.org/ + +Package: ipxe-xcat +Architecture: all +Depends: ${misc:Depends} +Description: iPXE network boot binaries from the upstream release + The ipxeboot.tar.gz tree of the iPXE 2.0.0 release, installed unchanged + under /tftpboot/xcat/ipxe. It carries the signed Secure Boot builds and + their shim. The source archive of the release tag is installed with the + documentation. diff --git a/ipxe-xcat/debian/copyright b/ipxe-xcat/debian/copyright new file mode 100644 index 0000000..4be3d40 --- /dev/null +++ b/ipxe-xcat/debian/copyright @@ -0,0 +1,37 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: iPXE +Source: https://github.com/ipxe/ipxe/releases/tag/v2.0.0 +Comment: ipxeboot-2.0.0.tar.gz is the ipxeboot.tar.gz asset of the iPXE v2.0.0 + release, unchanged. ipxe-2.0.0-source.tar.gz is the source archive of tag + v2.0.0, installed as /usr/share/doc/ipxe-xcat/ipxe-2.0.0-source.tar.gz. + . + The files x86_64-sb/shimx64.efi and arm64-sb/shimaa64.efi in the release tree + are shim 16.1, built by the iPXE project from ipxe/shim tag ipxe-16.1. Shim is + under the BSD licence in licenses/shim/COPYRIGHT and includes OpenSSL 1.0.2k + (licenses/shim/openssl/LICENSE) and gnu-efi (licenses/shim/gnu-efi/README.efilib). + . + The licence texts are installed in /usr/share/doc/ipxe-xcat/licenses/. + +Files: * +Copyright: Michael Brown and the iPXE contributors +License: GPL-2+ + iPXE files are licensed under the GNU General Public License, version 2 or + (at your option) any later version, unless the file states another licence. + Some files are licensed under version 2 only, some under BSD or MIT terms, + and most may also be used under the Unmodified Binary Distribution Licence + (licenses/ipxe/COPYING.UBDL). Each file in the source archive states its + own licence. + . + On Debian systems, the complete text of the GNU General Public License + version 2 can be found in /usr/share/common-licenses/GPL-2. + +Files: debian/* +Copyright: xCAT contributors +License: GPL-2+ + This packaging is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + . + On Debian systems, the complete text of the GNU General Public License + version 2 can be found in /usr/share/common-licenses/GPL-2. diff --git a/ipxe-xcat/debian/rules b/ipxe-xcat/debian/rules new file mode 100755 index 0000000..76ea015 --- /dev/null +++ b/ipxe-xcat/debian/rules @@ -0,0 +1,38 @@ +#!/usr/bin/make -f +# The payload is the upstream release tree, byte for byte: nothing strips it, and dh_compress and +# dh_fixperms leave /tftpboot and the licence texts alone. + +VERSION := $(shell dpkg-parsechangelog -S Version | sed 's/-[^-]*$$//') +DEST := debian/ipxe-xcat +DOC := $(DEST)/usr/share/doc/ipxe-xcat + +build build-arch build-indep: + +clean: + dh_testdir + dh_clean + +binary-arch: + +binary-indep: + dh_testdir + dh_testroot + dh_prep + install -d $(DEST)/tftpboot/xcat/ipxe $(DOC) + tar -xzf ipxeboot-$(VERSION).tar.gz --no-same-owner --strip-components=1 -C $(DEST)/tftpboot/xcat/ipxe + install -m 0644 ipxe-shimx64.efi $(DEST)/tftpboot/xcat/ipxe/x86_64-sb/shimx64.efi + install -m 0644 ipxe-shimaa64.efi $(DEST)/tftpboot/xcat/ipxe/arm64-sb/shimaa64.efi + install -m 0644 ipxe-$(VERSION)-source.tar.gz $(DOC)/ + cp -R licenses $(DOC)/licenses + dh_installdocs + dh_installchangelogs + dh_compress -Xlicenses/ + dh_fixperms -Xtftpboot/ + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch + +.PHONY: build build-arch build-indep clean binary-arch binary-indep binary diff --git a/ipxe-xcat/debian/source/format b/ipxe-xcat/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/ipxe-xcat/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/ipxe-xcat/ipxe-2.0.0-source.tar.gz b/ipxe-xcat/ipxe-2.0.0-source.tar.gz new file mode 100644 index 0000000..8b65f90 Binary files /dev/null and b/ipxe-xcat/ipxe-2.0.0-source.tar.gz differ diff --git a/ipxe-xcat/ipxe-shimaa64.efi b/ipxe-xcat/ipxe-shimaa64.efi new file mode 100644 index 0000000..23cbd01 Binary files /dev/null and b/ipxe-xcat/ipxe-shimaa64.efi differ diff --git a/ipxe-xcat/ipxe-shimx64.efi b/ipxe-xcat/ipxe-shimx64.efi new file mode 100644 index 0000000..0e215b1 Binary files /dev/null and b/ipxe-xcat/ipxe-shimx64.efi differ diff --git a/ipxe-xcat/ipxe-xcat.spec b/ipxe-xcat/ipxe-xcat.spec new file mode 100644 index 0000000..1bebff5 --- /dev/null +++ b/ipxe-xcat/ipxe-xcat.spec @@ -0,0 +1,59 @@ +# The payload is the upstream release, byte for byte: signed EFI files must not be stripped or +# otherwise touched by the build-root policy scripts. +%global debug_package %{nil} +%global __os_install_post %{nil} + +Name: ipxe-xcat +Version: 2.0.0 +Release: 1 +Summary: iPXE network boot binaries from the upstream release +License: GPL-2.0-only AND GPL-2.0-or-later AND BSD-2-Clause AND BSD-2-Clause-Patent AND BSD-3-Clause AND MIT AND OpenSSL +URL: https://ipxe.org/ +BuildArch: noarch + +Source0: ipxeboot-%{version}.tar.gz +Source1: ipxe-%{version}-source.tar.gz +Source2: licenses/ipxe/COPYING +Source3: licenses/ipxe/COPYING.GPLv2 +Source4: licenses/ipxe/COPYING.UBDL +Source5: licenses/shim/COPYRIGHT +Source6: licenses/shim/openssl/LICENSE +Source7: licenses/shim/gnu-efi/README.efilib +Source8: ipxe-shimx64.efi +Source9: ipxe-shimaa64.efi + +%description +The ipxeboot.tar.gz tree of the iPXE %{version} release, installed under +/tftpboot/xcat/ipxe. It carries the signed Secure Boot builds and their +shim. The shims are the ipxe/shim 16.1 assets signed by both Microsoft UEFI +CAs, 2011 and 2023, and every other file is unchanged. The source archive +of the release tag is installed with the documentation. + +%prep +%setup -q -c -T +install -D -m 0644 %{SOURCE2} licenses/ipxe/COPYING +install -D -m 0644 %{SOURCE3} licenses/ipxe/COPYING.GPLv2 +install -D -m 0644 %{SOURCE4} licenses/ipxe/COPYING.UBDL +install -D -m 0644 %{SOURCE5} licenses/shim/COPYRIGHT +install -D -m 0644 %{SOURCE6} licenses/shim/openssl/LICENSE +install -D -m 0644 %{SOURCE7} licenses/shim/gnu-efi/README.efilib + +%build + +%install +mkdir -p %{buildroot}/tftpboot/xcat/ipxe +tar -xzf %{SOURCE0} --no-same-owner --strip-components=1 -C %{buildroot}/tftpboot/xcat/ipxe +install -m 0644 %{SOURCE8} %{buildroot}/tftpboot/xcat/ipxe/x86_64-sb/shimx64.efi +install -m 0644 %{SOURCE9} %{buildroot}/tftpboot/xcat/ipxe/arm64-sb/shimaa64.efi +install -D -m 0644 %{SOURCE1} %{buildroot}%{_pkgdocdir}/ipxe-%{version}-source.tar.gz + +%files +/tftpboot/xcat/ipxe +%license licenses/ipxe licenses/shim +%dir %{_pkgdocdir} +%doc %{_pkgdocdir}/ipxe-%{version}-source.tar.gz + +%changelog +* Fri Sep 25 2026 xCAT - 2.0.0-1 +- Package the ipxeboot.tar.gz tree of the iPXE v2.0.0 release, with the + ipxe/shim 16.1 shims signed by both Microsoft UEFI CAs diff --git a/ipxe-xcat/ipxeboot-2.0.0.tar.gz b/ipxe-xcat/ipxeboot-2.0.0.tar.gz new file mode 100644 index 0000000..f206749 Binary files /dev/null and b/ipxe-xcat/ipxeboot-2.0.0.tar.gz differ diff --git a/ipxe-xcat/licenses/ipxe/COPYING b/ipxe-xcat/licenses/ipxe/COPYING new file mode 100644 index 0000000..342330b --- /dev/null +++ b/ipxe-xcat/licenses/ipxe/COPYING @@ -0,0 +1,12 @@ +In general iPXE files are licensed under the GPL. For historical +reasons, individual files may contain their own licence declarations. +Most builds of iPXE do not contain all iPXE code (in particular, most +builds will include only one driver), and so the overall licence can +vary depending on what target you are building. + +The resultant applicable licence(s) for any particular build can be +determined by using "make bin/xxxxxxx.yyy.licence"; for example: + + make bin/rtl8139.rom.licence + +to determine the resultant licence(s) for the build bin/rtl8139.rom diff --git a/ipxe-xcat/licenses/ipxe/COPYING.GPLv2 b/ipxe-xcat/licenses/ipxe/COPYING.GPLv2 new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/ipxe-xcat/licenses/ipxe/COPYING.GPLv2 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/ipxe-xcat/licenses/ipxe/COPYING.UBDL b/ipxe-xcat/licenses/ipxe/COPYING.UBDL new file mode 100644 index 0000000..780ddcd --- /dev/null +++ b/ipxe-xcat/licenses/ipxe/COPYING.UBDL @@ -0,0 +1,59 @@ +UNMODIFIED BINARY DISTRIBUTION LICENCE + + +PREAMBLE + +The GNU General Public License provides a legal guarantee that +software covered by it remains free (in the sense of freedom, not +price). It achieves this guarantee by imposing obligations on anyone +who chooses to distribute the software. + +Some of these obligations may be seen as unnecessarily burdensome. In +particular, when the source code for the software is already publicly +and freely available, there is minimal value in imposing upon each +distributor the obligation to provide the complete source code (or an +equivalent written offer to provide the complete source code). + +This Licence allows for the distribution of unmodified binaries built +from publicly available source code, without imposing the obligations +of the GNU General Public License upon anyone who chooses to +distribute only the unmodified binaries built from that source code. + +The extra permissions granted by this Licence apply only to unmodified +binaries built from source code which has already been made available +to the public in accordance with the terms of the GNU General Public +Licence. Nothing in this Licence allows for the creation of +closed-source modified versions of the Program. Any modified versions +of the Program are subject to the usual terms and conditions of the +GNU General Public License. + + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +This Licence applies to any Program or other work which contains a +notice placed by the copyright holder saying it may be distributed +under the terms of this Unmodified Binary Distribution Licence. All +terms used in the text of this Licence are to be interpreted as they +are used in version 2 of the GNU General Public License as published +by the Free Software Foundation. + +If you have made this Program available to the public in both source +code and executable form in accordance with the terms of the GNU +General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later +version, then you are hereby granted an additional permission to use, +copy, and distribute the unmodified executable form of this Program +(the "Unmodified Binary") without restriction, including the right to +permit persons to whom the Unmodified Binary is furnished to do +likewise, subject to the following conditions: + +- when started running, the Program must display an announcement which + includes the details of your existing publication of the Program + made in accordance with the terms of the GNU General Public License. + For example, the Program could display the URL of the publicly + available source code from which the Unmodified Binary was built. + +- when exercising your right to grant permissions under this Licence, + you do not need to refer directly to the text of this Licence, but + you may not grant permissions beyond those granted to you by this + Licence. diff --git a/ipxe-xcat/licenses/shim/COPYRIGHT b/ipxe-xcat/licenses/shim/COPYRIGHT new file mode 100644 index 0000000..3b5a464 --- /dev/null +++ b/ipxe-xcat/licenses/shim/COPYRIGHT @@ -0,0 +1,30 @@ +Copyright 2012 Red Hat, Inc + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + +Significant portions of this code are derived from Tianocore +(http://tianocore.sf.net) and are Copyright 2009-2012 Intel +Corporation. diff --git a/ipxe-xcat/licenses/shim/gnu-efi/README.efilib b/ipxe-xcat/licenses/shim/gnu-efi/README.efilib new file mode 100644 index 0000000..bb857ec --- /dev/null +++ b/ipxe-xcat/licenses/shim/gnu-efi/README.efilib @@ -0,0 +1,30 @@ + +The files in the "lib" and "inc" subdirectories are using the EFI Application +Toolkit distributed by Intel at http://developer.intel.com/technology/efi + +This code is covered by the following agreement: + +Copyright (c) 1998-2000 Intel Corporation + +Redistribution and use in source and binary forms, with or without modification, are permitted +provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and +the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this list of conditions +and the following disclaimer in the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. THE EFI SPECIFICATION AND ALL OTHER INFORMATION +ON THIS WEB SITE ARE PROVIDED "AS IS" WITH NO WARRANTIES, AND ARE SUBJECT +TO CHANGE WITHOUT NOTICE. diff --git a/ipxe-xcat/licenses/shim/openssl/LICENSE b/ipxe-xcat/licenses/shim/openssl/LICENSE new file mode 100644 index 0000000..fb03713 --- /dev/null +++ b/ipxe-xcat/licenses/shim/openssl/LICENSE @@ -0,0 +1,127 @@ + + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a dual license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. Actually both licenses are BSD-style + Open Source licenses. In case of any license issues related to OpenSSL + please contact openssl-core@openssl.org. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + diff --git a/ipxe-xcat/mockbuild.pl b/ipxe-xcat/mockbuild.pl new file mode 100755 index 0000000..fd674ff --- /dev/null +++ b/ipxe-xcat/mockbuild.pl @@ -0,0 +1,172 @@ +#!/usr/bin/perl +# ipxe-xcat/mockbuild.pl -- build the ipxe-xcat noarch RPM with mock from the committed release +# archives. The archives are checked against SHA256SUMS before the build, and the built RPM payload +# against payload.sha256 before anything is copied to --result-dir. +use strict; +use warnings; +use Cwd qw(abs_path); +use File::Basename qw(basename); +use File::Copy qw(copy); +use File::Path qw(make_path remove_tree); +use FindBin qw($RealBin); +use Getopt::Long qw(GetOptions); +use lib "$RealBin/..", "$RealBin/../lib"; +use MockBuildUtils qw(resolve_mock_cfg); +use XCAT::BuildUtils qw(capture_command digest_file print_step require_command run_command shell_quote); + +my $pkg_dir = abs_path($RealBin); +my $repo_root = abs_path("$pkg_dir/.."); +my $spec_file = "$pkg_dir/ipxe-xcat.spec"; + +my $work_dir = '/tmp/ipxe-xcat-mockbuild'; +my $mock_cfg = ''; +my $mock_uniqueext = ''; +my $result_dir = "$repo_root/build-output/list3/ipxe-xcat"; +my $log_dir = "$repo_root/build-logs/list3/ipxe-xcat"; +my $build_timestamp; + +GetOptions( + 'work-dir=s' => \$work_dir, + 'mock-cfg=s' => \$mock_cfg, + 'mock-uniqueext=s' => \$mock_uniqueext, + 'result-dir=s' => \$result_dir, + 'log-dir=s' => \$log_dir, + 'build-timestamp=i' => \$build_timestamp, +) or die usage(); + +die "Run as root (current uid=$>)\n" if $> != 0; +require_command($_) for qw(mock rpm rpm2cpio cpio bash sha256sum); + +my ($version, @sources) = spec_sources($spec_file); +die "Could not parse Version from $spec_file\n" if !$version; + +if (!$mock_cfg) { + my $os_id = capture_command('bash', '-c', 'source /etc/os-release; echo $ID'); + my $arch = capture_command('uname', '-m'); + $mock_cfg = resolve_mock_cfg($os_id, 10, $arch); +} +my @uniqueext = $mock_uniqueext ne '' ? ('--uniqueext', $mock_uniqueext) : (); + +my $epoch = $build_timestamp; +if (!defined $epoch) { + $epoch = `git -C \Q$repo_root\E log -1 --format=%ct HEAD 2>/dev/null` // ''; + chomp $epoch; + $epoch = time() if $epoch !~ /^\d+$/; +} +$ENV{SOURCE_DATE_EPOCH} = $epoch; + +print_step('Configuration'); +print "pkg_dir: $pkg_dir\n"; +print "version: $version\n"; +print "work_dir: $work_dir\n"; +print "result_dir: $result_dir\n"; +print "log_dir: $log_dir\n"; +print "mock_cfg: $mock_cfg\n"; + +print_step('Check the release archives'); +run_command('bash', '-c', 'cd ' . shell_quote($pkg_dir) . ' && sha256sum --check --strict SHA256SUMS'); + +print_step('Stage the sources'); +remove_tree($work_dir) if -d $work_dir; +my $sources_dir = "$work_dir/sources"; +make_path($sources_dir, $result_dir, $log_dir); +my %staged; +for my $source (@sources) { + my $name = basename($source); + die "Two Source files share the name $name\n" if $staged{$name}++; + copy("$pkg_dir/$source", "$sources_dir/$name") + or die "Failed to copy $pkg_dir/$source: $!\n"; +} +run_command('bash', '-c', 'cd ' . shell_quote($sources_dir) + . ' && sha256sum --check --strict ' . shell_quote("$pkg_dir/SHA256SUMS")); + +my $det_cfg = "$work_dir/mock-deterministic.cfg"; +open(my $cfg_fh, '>', $det_cfg) or die "Cannot write $det_cfg: $!\n"; +print {$cfg_fh} "include('/etc/mock/${mock_cfg}.cfg')\n"; +print {$cfg_fh} "config_opts['environment']['SOURCE_DATE_EPOCH'] = '$epoch'\n"; +close($cfg_fh) or die "Cannot write $det_cfg: $!\n"; +my @defines = map { ('--define', $_) } + ('use_source_date_epoch_as_buildtime 1', 'clamp_mtime_to_source_date_epoch 1', '_buildhost xcat-build'); + +print_step('Build the SRPM with mock'); +my $srpm_out = "$work_dir/srpm"; +make_path($srpm_out); +run_mock('mock', '-r', $det_cfg, @uniqueext, '--buildsrpm', '--spec', $spec_file, + '--sources', $sources_dir, '--resultdir', $srpm_out, @defines); +my @srpms = glob("$srpm_out/ipxe-xcat-*.src.rpm"); +die "Expected one SRPM in $srpm_out, found " . scalar(@srpms) . "\n" if @srpms != 1; + +print_step('Rebuild the RPM with mock'); +my $rpm_out = "$work_dir/rpm"; +make_path($rpm_out); +run_mock('mock', '-r', $det_cfg, @uniqueext, '--rebuild', $srpms[0], '--resultdir', $rpm_out, @defines); +my @rpms = glob("$rpm_out/ipxe-xcat-$version-*.noarch.rpm"); +die "Expected one ipxe-xcat noarch RPM in $rpm_out, found " . scalar(@rpms) . "\n" if @rpms != 1; +my $rpm = $rpms[0]; + +print_step('Check the RPM payload'); +my $payload = "$work_dir/payload"; +make_path($payload); +run_command('bash', '-o', 'pipefail', '-c', 'cd ' . shell_quote($payload) + . ' && rpm2cpio ' . shell_quote($rpm) . ' | cpio -idm --quiet'); +run_command('perl', "$pkg_dir/verify-payload.pl", "$payload/tftpboot/xcat/ipxe", + "$pkg_dir/payload.sha256"); +check_installed("$payload/usr/share/doc/ipxe-xcat/ipxe-$version-source.tar.gz", + "$pkg_dir/ipxe-$version-source.tar.gz"); +for my $licence (grep { m{^licenses/} } @sources) { + (my $installed = $licence) =~ s{^licenses/}{}; + check_installed("$payload/usr/share/licenses/ipxe-xcat/$installed", "$pkg_dir/$licence"); +} + +print_step('Collect the results'); +for my $file ($rpm, $srpms[0]) { + copy($file, $result_dir) or die "Failed to copy $file to $result_dir: $!\n"; + print "Copied: $result_dir/" . basename($file) . "\n"; +} +for my $log (qw(build.log root.log state.log)) { + copy("$rpm_out/$log", "$log_dir/$log") if -f "$rpm_out/$log"; + copy("$srpm_out/$log", "$log_dir/srpm-$log") if -f "$srpm_out/$log"; +} +print_step('Completed'); +exit 0; + +sub usage { + return <<"USAGE"; +Usage: $0 [options] + --work-dir PATH Temporary work directory (default: $work_dir) + --mock-cfg NAME Mock config (default: the EL10 config of this host) + --mock-uniqueext TEXT mock --uniqueext suffix for concurrent builds + --result-dir PATH Output directory for the RPM and SRPM + --log-dir PATH Output directory for the mock logs + --build-timestamp EPOCH SOURCE_DATE_EPOCH for a reproducible build +USAGE +} + +sub spec_sources { + my ($path) = @_; + open(my $fh, '<', $path) or die "Cannot read $path: $!\n"; + my ($version, @sources) = (''); + while (my $line = <$fh>) { + $version = $1 if $line =~ /^Version:\s*(\S+)/; + push @sources, $1 if $line =~ /^Source\d*:\s*(\S+)/; + } + close($fh); + s/%\{version\}/$version/g for @sources; + return ($version, @sources); +} + +sub check_installed { + my ($installed, $committed) = @_; + die "Missing from the RPM payload: $installed\n" if !-f $installed || -l $installed; + die "The RPM payload changed $installed\n" if digest_file($installed) ne digest_file($committed); +} + +# mock exits 30 when its package manager failed, most often a transient mirror error: retry once. +sub run_mock { + my (@command) = @_; + my $ok = eval { run_command(@command) }; + return 1 if $ok; + die $@ if $@ !~ /\(rc=30\)/; + print "mock failed with rc=30 (package manager); retrying once\n"; + return run_command(@command); +} diff --git a/ipxe-xcat/payload.sha256 b/ipxe-xcat/payload.sha256 new file mode 100644 index 0000000..3141d9b --- /dev/null +++ b/ipxe-xcat/payload.sha256 @@ -0,0 +1,54 @@ +# ipxe-xcat payload manifest, written by verify-payload.pl --generate +dir - arm32 +file 2a8d50db2b3b5f02302302b3161931c1142301f42d52c64c0005974b602b7092 arm32/ipxe-legacy.efi +file fa58061710e6fab23fc27c6d200d510453c3f14f3bc0715fa6804111f1e5fc74 arm32/ipxe.efi +file 206310f30306569ed2c6e0ef015b3ad24230b303a1ad1171e19c117c914a65d6 arm32/snponly.efi +dir - arm64 +dir - arm64-sb +link shimaa64.efi arm64-sb/ipxe-shim.efi +file 01b2438e6dc354c343590c308f1d4f000bc098be4d2237540432023abdbddcb8 arm64-sb/ipxe.efi +file 31c6d8ef9ed24dc810dd7b951cf86b2e9036a02dea8a32548c0e1c0ae4d6f1c9 arm64-sb/shimaa64.efi +link shimaa64.efi arm64-sb/snponly-shim.efi +file bed8da8639b45eeec55d41627349863efa5085a2113bb1193838b8a463e5f49e arm64-sb/snponly.efi +file cff2abf51b7b491d7c5e2ef68c45003a0b4c5e866cb5b20f162569746d53390d arm64/ipxe-legacy.efi +file a9cb6df506a68f3afa4bb94cf6cb8e3862a5a2ff3bf1d8027fea83f7e1d49217 arm64/ipxe.efi +file 03665b4184e4a0b8b9a889de0c7fb833fc48b02385e3fa40a4460db1122f1b36 arm64/snponly.efi +dir - i386 +file 9dc4aee199f582fb8f55cf8bfb4622998c5e71c2dde149d5bbdfe33121c925d8 i386/ipxe-legacy.efi +file df9bab29487d20af3fe9dda46afc775009ba1c089d2216098b9a6e82d906939b i386/ipxe-legacy.pxe +file ea63c6d3745e751e8db4f9c8d4c97efa883fb6d0fc57c697b3d13ad98c1bfe0c i386/ipxe.efi +file a0f144a5f7e10e567d189606c6c2320c1f43a228f9fb6148e7e52f5009fd789f i386/ipxe.pxe +file 81a086995758b889fba7f13d7c5255dc7eb87ed38350b8c03112b9f56556de98 i386/snponly.efi +file ef6ff013f988c52feb3e543dccf0bdc50cd1d68b8a4ab84b8975cef33f64e848 i386/undionly.kpxe +link x86_64/ipxe-legacy.efi ipxe-legacy.efi +link x86_64/ipxe-legacy.pxe ipxe-legacy.pxe +link x86_64/ipxe.efi ipxe.efi +link x86_64/ipxe.pxe ipxe.pxe +dir - loong64 +file 03b078b2ba00e97427b5d99b14035bdb7abdb48631aba8759cf95c24a2620b7e loong64/ipxe-legacy.efi +file c326c8bf54d8fc40fa6730907ee07cb44e8151ecc1397e1ddd2c0edef7cb2872 loong64/ipxe.efi +file fd7cb2df195ad5cc3a09f41fab23713afa23624ff664f83de0e7ca0fd5776fb7 loong64/snponly.efi +dir - riscv32 +file 41f76da3efc3293887a701f35cac389c04a3a8110743673e37451e3c6e24e507 riscv32/ipxe-legacy.efi +file 4afd51329213e50a4aaf24b397e8aba67910ca1e94ea3a6fab0e089d91ac69b8 riscv32/ipxe.efi +file 0a901453bde1392051e53bb1e75584a4eb7cc9c75a27a2b34d7b26ad21734f8f riscv32/snponly.efi +dir - riscv64 +file a72923e2ff600bd94628ef5f97a7ddd5c23fabdc9736fdaa2c22cfb7f0fe908d riscv64/ipxe-legacy.efi +file 53c926c45043c1f2ad03aa70aa22921accc3202865c791cc6023fa17d92f8f24 riscv64/ipxe.efi +file 95b9f6466e0d88fafe642c46d3d6024e4107cac24d2197664b62610f21a48585 riscv64/snponly.efi +link x86_64-sb sb +link x86_64/snponly.efi snponly.efi +link x86_64/undionly.kpxe undionly.kpxe +dir - x86_64 +dir - x86_64-sb +link shimx64.efi x86_64-sb/ipxe-shim.efi +file 6558e37887516b246d6a97122e8d18bedfe4197b7ba7f67bf1bf102a16678d33 x86_64-sb/ipxe.efi +file 5eecca2780bd49c900565e124516a1bd666ec5e012825f34991b6ba1ef2fa6cf x86_64-sb/shimx64.efi +link shimx64.efi x86_64-sb/snponly-shim.efi +file b1e67c3e4a1e8708ddfd0079ad4505e3a02245acb55ee9a95437ab3c507be82a x86_64-sb/snponly.efi +file 1d567f2e89a3c0cf0a184549918a3e799a47dc542df385c56e6b464e4765fae2 x86_64/ipxe-legacy.efi +file fc37ef1e4a4bd5d22f8db3c84e1718ac8b03fe20156cf2fc4b9e2ae5e4a348db x86_64/ipxe-legacy.pxe +file 868aa34057ff416ebf2fdfb5781de035e2c540477c04039198a9f8a9c6130034 x86_64/ipxe.efi +file 0fb21c695c82fd70d4f89732ddcd285063776e2bbd71de9a2c39e9cfe4b180b8 x86_64/ipxe.pxe +file f61c2ce34e05d7d857633df2e512d547df75b6aa18b2da152a7c9af222cfe28f x86_64/snponly.efi +file 4186562d21ff54e970d905751c9f36d628e73a51a94afe4a6a42f925b0df448c x86_64/undionly.kpxe diff --git a/ipxe-xcat/sbuild.pl b/ipxe-xcat/sbuild.pl new file mode 100755 index 0000000..c8a79c9 --- /dev/null +++ b/ipxe-xcat/sbuild.pl @@ -0,0 +1,55 @@ +#!/usr/bin/env perl +# ipxe-xcat/sbuild.pl -- per-package Ubuntu/Debian builder for ipxe-xcat, the apt analogue of +# ipxe-xcat/mockbuild.pl. Invoked by sbuild-all.pl per (codename,arch); also runnable standalone. +# The build runs on a copy of the package tree inside the --sbuild chroot, and it +# checks the archives before dpkg-buildpackage and the built payload after it, so a deb that +# differs from the release never reaches --result-dir. +use strict; +use warnings; +use Cwd qw(abs_path); +use File::Basename qw(basename); +use Getopt::Long qw(GetOptions); +use FindBin qw($RealBin); +use lib "$RealBin/.."; +use BuildUtils qw(chroot_name build_deb_in_chroot); + +my $pkg_dir = abs_path($RealBin); +my $pkg = basename($pkg_dir); +my ($codename, $arch, $chroot, $result_dir, $log_dir) = ('', '', '', '', ''); +my ($build_timestamp, $build_number, $skip_install) = (undef, undef, 0); +# --log-dir, --build-number and --skip-install keep the command line sbuild-all.pl passes to every +# builder; this package has no use for them. +GetOptions( + 'codename=s' => \$codename, 'arch=s' => \$arch, 'chroot=s' => \$chroot, + 'result-dir=s' => \$result_dir, 'log-dir=s' => \$log_dir, + 'build-timestamp=i' => \$build_timestamp, 'build-number=i' => \$build_number, + 'skip-install!' => \$skip_install, +) or die "bad options\n"; +$arch ||= `dpkg --print-architecture 2>/dev/null`; chomp $arch; $arch ||= 'amd64'; +die "FATAL: --codename required\n" unless $codename; +$chroot ||= chroot_name($codename, $arch); +$result_dir ||= "$pkg_dir/../build-output/sbuild/$codename/$arch"; +$build_timestamp = time() unless defined $build_timestamp; + +# ipxe-xcat is Architecture:all and is built once on amd64 (see debs-manifest.conf). +my $build = <<'BUILD'; +set -e +sha256sum --check --strict SHA256SUMS +dpkg-buildpackage -uc -us -b +version=$(dpkg-parsechangelog -S Version) +payload=$(mktemp -d) +dpkg-deb -x "../ipxe-xcat_${version}_all.deb" "$payload" +perl ./verify-payload.pl "$payload/tftpboot/xcat/ipxe" payload.sha256 +source_archive="ipxe-${version%-*}-source.tar.gz" +grep -F " $source_archive" SHA256SUMS \ + | (cd "$payload/usr/share/doc/ipxe-xcat" && sha256sum --check --strict -) +for licence in $(cd licenses && find . -type f); do + cmp "licenses/$licence" "$payload/usr/share/doc/ipxe-xcat/licenses/$licence" +done +rm -rf "$payload" +BUILD + +build_deb_in_chroot( + pkg => $pkg, chroot => $chroot, pkg_dir => $pkg_dir, result_dir => $result_dir, + build_timestamp => $build_timestamp, build => $build, +); diff --git a/ipxe-xcat/verify-payload.pl b/ipxe-xcat/verify-payload.pl new file mode 100755 index 0000000..fd5f759 --- /dev/null +++ b/ipxe-xcat/verify-payload.pl @@ -0,0 +1,118 @@ +#!/usr/bin/perl +# verify-payload.pl -- compare an unpacked ipxe-xcat tree with payload.sha256. +# +# verify-payload.pl --generate > payload.sha256 +# verify-payload.pl +# +# Each manifest line is "\t\t", sorted by path: "file" with the SHA-256 of the +# content, "link" with the symlink target, "dir" with "-". Paths are relative to , and +# symlinks are never followed. The check exits 0 when the tree matches the manifest entry for +# entry, 1 when it differs, and 2 on a usage or read error. +use strict; +use warnings; +use Digest::SHA (); +use File::Find (); +use Getopt::Long qw(GetOptions); + +my $generate = 0; +GetOptions('generate' => \$generate) or usage(); + +if ($generate) { + usage() if @ARGV != 1; + my $tree = scan_tree($ARGV[0]); + print "# ipxe-xcat payload manifest, written by verify-payload.pl --generate\n"; + for my $path (sort keys %{$tree}) { + print join("\t", @{ $tree->{$path} }, $path), "\n"; + } + exit 0; +} + +usage() if @ARGV != 2; +my ($root, $manifest_file) = @ARGV; +my $expected = read_manifest($manifest_file); +my $found = scan_tree($root); + +my @problems; +for my $path (sort keys %{$expected}) { + my ($type, $value) = @{ $expected->{$path} }; + if (!exists $found->{$path}) { + push @problems, "missing: $path"; + next; + } + my ($found_type, $found_value) = @{ $found->{$path} }; + if ($found_type ne $type) { + push @problems, "type changed: $path (expected $type, found $found_type)"; + } elsif ($type eq 'file' && $found_value ne $value) { + push @problems, "content changed: $path"; + } elsif ($type eq 'link' && $found_value ne $value) { + push @problems, "link target changed: $path (expected $value, found $found_value)"; + } +} +push @problems, map { "unexpected: $_" } grep { !exists $expected->{$_} } sort keys %{$found}; + +if (@problems) { + print STDERR "$_\n" for @problems; + print STDERR "payload does not match $manifest_file: " . scalar(@problems) . " difference(s)\n"; + exit 1; +} +print "payload matches $manifest_file: " . scalar(keys %{$expected}) . " entries\n"; +exit 0; + +sub usage { + print STDERR "Usage: $0 --generate \n $0 \n"; + exit 2; +} + +sub fail { + my ($message) = @_; + print STDERR "$0: $message\n"; + exit 2; +} + +sub scan_tree { + my ($dir) = @_; + $dir =~ s{/+\z}{} if $dir ne '/'; + fail("not a directory: $dir") if -l $dir || !-d $dir; + my %entries; + File::Find::find({ + no_chdir => 1, + wanted => sub { + my $path = $File::Find::name; + return if $path eq $dir; + my $relative = substr($path, length($dir) + 1); + lstat($path) or fail("cannot stat $path: $!"); + if (-l _) { + my $target = readlink($path); + fail("cannot read link $path: $!") if !defined $target; + $entries{$relative} = ['link', $target]; + } elsif (-d _) { + $entries{$relative} = ['dir', '-']; + } elsif (-f _) { + my $sha = Digest::SHA->new(256); + eval { $sha->addfile($path, 'b'); 1 } or fail("cannot read $path: $@"); + $entries{$relative} = ['file', $sha->hexdigest]; + } else { + $entries{$relative} = ['other', '-']; + } + }, + }, $dir); + return \%entries; +} + +sub read_manifest { + my ($file) = @_; + open(my $fh, '<', $file) or fail("cannot read $file: $!"); + my %entries; + while (my $line = <$fh>) { + chomp $line; + next if $line =~ /^\s*(?:#|$)/; + my ($type, $value, $path) = split(/\t/, $line, 3); + fail("$file line $.: malformed entry") + if !defined $path || $path eq '' || $type !~ /^(?:file|link|dir)$/ + || ($type eq 'file' && $value !~ /^[0-9a-f]{64}$/); + fail("$file line $.: duplicate path $path") if exists $entries{$path}; + $entries{$path} = [$type, $value]; + } + close($fh); + return \%entries; +} diff --git a/mockbuild-all.pl b/mockbuild-all.pl index 3f3efad..cdc1dac 100755 --- a/mockbuild-all.pl +++ b/mockbuild-all.pl @@ -15,7 +15,7 @@ use Parallel::ForkManager; use POSIX qw(strftime); use FindBin qw($RealBin); use lib $RealBin, "$RealBin/lib"; -use MockBuildUtils qw(sh_quote print_step version_matches required_pkgs rpm_in_cell +use MockBuildUtils qw(sh_quote print_step version_matches required_pkgs rpm_in_cell resolve_mock_cfg carry_over_rpms rpm_name rpm_arch rpm_source_rpm rpm_digests_ok install_deps_packages install_deps_command missing_perl_modules read_manifest verify_repo_packages verify_repo_signature verify_rpm_signatures @@ -412,8 +412,8 @@ my %forcearch_targets = ( arch => 'riscv64', # x86_64 only, as the mock config admits: syslinux-xcat builds on x86 and ppc64le alone. noarch_cfg => 'rocky-10-x86_64', - dep_builders => [qw(elilo-xcat grub2-xcat ipmitool-xcat syslinux-xcat goconserver conserver-xcat xnba-undi)], - required => [qw(ipmitool-xcat syslinux-xcat grub2-xcat xnba-undi + dep_builders => [qw(elilo-xcat grub2-xcat ipmitool-xcat syslinux-xcat goconserver conserver-xcat xnba-undi ipxe-xcat)], + required => [qw(ipmitool-xcat syslinux-xcat grub2-xcat xnba-undi ipxe-xcat perl-IO-Stty perl-HTTP-Async perl-Net-HTTPS-NB)], }, ); @@ -536,10 +536,11 @@ if (!$skip_build && !$dry_run && -d $run_root) { remove_tree($run_root); } -# All dep builders run natively on every arch. xnba-undi and grub2-xcat are noarch packagings of -# committed artifacts (an x86 UNDI ROM / the grub2 resource tarball) with no arch-specific build -# step, so ppc builds them the same as x86 -- no cross-arch import. A forcearch target builds -# only the builders its profile lists; the noarch ones run in the profile's native chroot. +# All dep builders run natively on every arch. xnba-undi, grub2-xcat and ipxe-xcat are noarch +# packagings of committed artifacts (an x86 UNDI ROM / the grub2 resource tarball / the iPXE release +# tree) with no arch-specific build step, so ppc builds them the same as x86 -- no cross-arch +# import. A forcearch target builds only the builders its profile lists; the noarch ones run in +# the profile's native chroot. # syslinux-xcat is noarch too, and its spec builds on x86 and ppc64le only. my @dep_builders = ( { name => 'elilo-xcat', script => "$repo_root/elilo/mockbuild.pl", noarch => 1 }, @@ -549,6 +550,7 @@ my @dep_builders = ( { name => 'goconserver', script => "$repo_root/goconserver/mockbuild.pl" }, { name => 'conserver-xcat', script => "$repo_root/conserver/mockbuild.pl" }, { name => 'xnba-undi', script => "$repo_root/xnba/mockbuild.pl", noarch => 1 }, + { name => 'ipxe-xcat', script => "$repo_root/ipxe-xcat/mockbuild.pl", noarch => 1 }, ); my %profile_builds = map { $_ => 1 } @{ $profile->{dep_builders} }; @@ -1040,11 +1042,11 @@ sub target_profile { noarch_cfg => $target, forcearch => 0, epel => 1, - dep_builders => [qw(elilo-xcat grub2-xcat ipmitool-xcat syslinux-xcat goconserver conserver-xcat xnba-undi)], + dep_builders => [qw(elilo-xcat grub2-xcat ipmitool-xcat syslinux-xcat goconserver conserver-xcat xnba-undi ipxe-xcat)], # xCAT Requires all of these on every arch, and every one of them builds natively on - # every arch (the noarch deps -- grub2-xcat, xnba-undi -- just repackage committed + # every arch (the noarch deps -- grub2-xcat, xnba-undi, ipxe-xcat -- just repackage committed # artifacts), so a self-sufficient per-arch build produces the whole set. - required => [qw(ipmitool-xcat syslinux-xcat grub2-xcat xnba-undi + required => [qw(ipmitool-xcat syslinux-xcat grub2-xcat xnba-undi ipxe-xcat perl-IO-Stty perl-HTTP-Async perl-Net-HTTPS-NB)], }; } @@ -2129,28 +2131,6 @@ sub collect_srpms { return ($copied, $skipped_non_src, $missing_roots); } -sub resolve_mock_cfg { - my ($os_id, $rel, $arch) = @_; - my %short_forms = ( - almalinux => 'alma', - 'centos-stream' => 'centos-stream', - rocky => 'rocky', - ); - # Resolve by CONFIG-FILE existence, not by running `mock --print-root-path`: the latter can fail - # transiently (bootstrap chroot setup, a concurrent mock holding a lock) and made el10 flakily - # "resolve" to the long form that has no .cfg. Checking /etc/mock/.cfg is deterministic. - for my $id ($os_id, (exists $short_forms{$os_id} ? ($short_forms{$os_id}) : ())) { - my $candidate = "${id}+epel-${rel}-${arch}"; - if (-f "/etc/mock/${candidate}.cfg") { - print "Mock config resolved: $candidate\n" if $id ne $os_id; - return $candidate; - } - } - my $short = $short_forms{$os_id} // $os_id; - die "Could not find mock config for ${os_id}+epel-${rel}-${arch} " - . "(tried /etc/mock/${os_id}+epel-${rel}-${arch}.cfg and /etc/mock/${short}+epel-${rel}-${arch}.cfg)\n"; -} - sub resolve_xcat_source { my ($requested, $root) = @_; # Prefer the sibling ../xcat-core (the real layout: source/xcat-core beside source/xcat-dep) diff --git a/packages-manifest.conf b/packages-manifest.conf index 5370461..74d3d9a 100644 --- a/packages-manifest.conf +++ b/packages-manifest.conf @@ -61,6 +61,7 @@ elilo-xcat=3.14 goconserver=>= 0.3.3-snap202011021058 grub2-xcat=1.0 ipmitool-xcat=>= 1.8.18-4 +ipxe-xcat=2.0.0 syslinux-xcat=>= 6.03-1 xnba-undi=>= 1.21.1-1 perl-HTML-Form=6.07 @@ -75,6 +76,7 @@ elilo-xcat=3.14 goconserver=>= 0.3.3-snap202011021058 grub2-xcat=1.0 ipmitool-xcat=>= 1.8.18-4 +ipxe-xcat=2.0.0 syslinux-xcat=>= 6.03-1 xnba-undi=>= 1.21.1-1 perl-HTML-Form=6.07 @@ -89,6 +91,7 @@ elilo-xcat=3.14 goconserver=>= 0.3.3-snap202011021058 grub2-xcat=1.0 ipmitool-xcat=>= 1.8.18-4 +ipxe-xcat=2.0.0 syslinux-xcat=>= 6.03-1 xnba-undi=>= 1.21.1-1 perl-HTTP-Async=>= 0.30-3 @@ -103,6 +106,7 @@ elilo-xcat=3.14 goconserver=>= 0.3.3-snap202011021058 grub2-xcat=1.0 ipmitool-xcat=>= 1.8.18-4 +ipxe-xcat=2.0.0 syslinux-xcat=>= 6.03-1 xnba-undi=>= 1.21.1-1 perl-HTTP-Async=>= 0.30-3 @@ -117,6 +121,7 @@ elilo-xcat=3.14 goconserver=>= 0.3.3-snap202011021058 grub2-xcat=1.0 ipmitool-xcat=>= 1.8.18-4 +ipxe-xcat=2.0.0 syslinux-xcat=>= 6.03-1 xnba-undi=>= 1.21.1-1 perl-Crypt-SSLeay=0.72 @@ -133,6 +138,7 @@ elilo-xcat=3.14 goconserver=>= 0.3.3-snap202011021058 grub2-xcat=1.0 ipmitool-xcat=>= 1.8.18-4 +ipxe-xcat=2.0.0 syslinux-xcat=>= 6.03-1 xnba-undi=>= 1.21.1-1 perl-Crypt-SSLeay=0.72 @@ -147,7 +153,7 @@ xCAT-genesis-base=>= 2:2.18.0 # EPEL-fed EL10 sections above in one way (see BUILD.md, "riscv64"): riscv64 has no EPEL, so the # perl deps EL10 otherwise takes from EPEL are built here too (perl-Crypt-Blowfish ... # perl-Path-Class below). perl-Path-Class is a build dep of perl-Crypt-SSLeay only. The x86 boot -# loaders (elilo-xcat, syslinux-xcat, xnba-undi) are noarch and are listed like on ppc64le: a +# loaders (elilo-xcat, ipxe-xcat, syslinux-xcat, xnba-undi) are noarch and are listed like on ppc64le: a # riscv64 management node serves the x86 nodes of a mixed cluster. # The per-EL perl set is the EL10 one plus perl-HTML-Form: EPEL supplies it on the other # architectures, nothing supplies it on riscv64, and perl-xCAT requires perl(HTML::Form). @@ -158,6 +164,7 @@ elilo-xcat=3.14 goconserver=>= 0.3.3-snap202011021058 grub2-xcat=1.0 ipmitool-xcat=>= 1.8.18-4 +ipxe-xcat=2.0.0 syslinux-xcat=>= 6.03-1 xnba-undi=>= 1.21.1-1 perl-Crypt-SSLeay=0.72 diff --git a/sbuild-all.pl b/sbuild-all.pl index b3bc92d..cae747d 100755 --- a/sbuild-all.pl +++ b/sbuild-all.pl @@ -17,7 +17,7 @@ # two arches build concurrently on their two hosts, so a per-arch build that also published would # interleave wipes of the same pool/dists/Release; and a partial or failed build must never reach # the published repo, nor stale debs accumulate in it (concern #1). -# 3. Per-arch package sets come from the manifest: the x86 boot components (syslinux/elilo/xnba, +# 3. Per-arch package sets come from the manifest: the x86 boot components (syslinux/elilo/xnba/ipxe-xcat, # Architecture:all) are built once on amd64 (single producer); ppc64el builds only the genuinely # arch-specific compiled deps (concern #3). # 4. Any required chroot / package / artifact failure, or any version-pin mismatch, fails the whole @@ -126,6 +126,7 @@ my %PKG_DIR = ( 'grub2-xcat' => 'grub2-xcat', 'elilo-xcat' => 'elilo', 'xnba-undi' => 'xnba', + 'ipxe-xcat' => 'ipxe-xcat', ); # Build the GetOptions map from the shared standard_options() spec (so the flag vocabulary matches @@ -556,7 +557,7 @@ sub build_one_codename { for my $pkg (@pkgs) { my $dir = $PKG_DIR{$pkg} or die "FATAL: no builder dir mapped for manifest package '$pkg'\n"; - # arch:all single-producer packages (grub2-xcat/syslinux-xcat/elilo-xcat/xnba-undi) are built + # arch:all single-producer packages (grub2-xcat/syslinux-xcat/elilo-xcat/xnba-undi/ipxe-xcat) are built # ONCE on amd64 -- their source is x86-only (syslinux compiles with nasm/gcc-multilib) -- and, # being Architecture:all, are assembled into every arch's Packages index. They stay REQUIRED in # the ppc64el manifest so the gate verifies the ppc repo actually carries them, but are NOT diff --git a/t/ipxe_xcat_payload.t b/t/ipxe_xcat_payload.t new file mode 100644 index 0000000..c589d94 --- /dev/null +++ b/t/ipxe_xcat_payload.t @@ -0,0 +1,142 @@ +#!/usr/bin/perl +# Behaviour test for ipxe-xcat/verify-payload.pl, the check between a built ipxe-xcat package and the +# release tree that the package must carry byte for byte. +# +# A manifest is written for a small fixture tree with the checker's own --generate mode. Each case +# damages a copy of the tree in one way and runs the check as a subprocess: the check must fail and +# name the path. A check that compared only names would pass every damage case below. The last block +# holds the committed payload.sha256 and SHA256SUMS to the committed release archives. +use strict; +use warnings; +use Test::More; +use Digest::SHA (); +use File::Basename qw(dirname); +use File::Copy qw(copy); +use File::Path qw(make_path); +use File::Temp qw(tempdir); +use FindBin qw($RealBin); +use IPC::Open3 qw(open3); + +my $pkg_dir = "$RealBin/../ipxe-xcat"; +my $checker = "$pkg_dir/verify-payload.pl"; +plan skip_all => 'ipxe-xcat/verify-payload.pl not found' unless -f $checker; + +my $tmp = tempdir(CLEANUP => 1); + +# Runs the checker; returns its exit code and its merged stdout and stderr. +sub run_checker { + my (@args) = @_; + my $pid = open3(my $in, my $out, undef, $^X, $checker, @args); + close($in); + my $text = do { local $/; <$out> } // ''; + waitpid($pid, 0); + return ($? >> 8, $text); +} + +sub write_file { + my ($path, $content) = @_; + make_path(dirname($path)); + open(my $fh, '>:raw', $path) or die "write $path: $!"; + print {$fh} $content; + close($fh) or die "close $path: $!"; +} + +sub make_tree { + my ($root) = @_; + write_file("$root/i386/undionly.kpxe", "undi\x00\x01"); + write_file("$root/x86_64-sb/snponly.efi", "MZ signed snponly"); + write_file("$root/x86_64-sb/shimx64.efi", "MZ signed shim"); + symlink('shimx64.efi', "$root/x86_64-sb/ipxe-shim.efi") or die "symlink: $!"; + symlink('x86_64-sb', "$root/sb") or die "symlink: $!"; + symlink('i386/undionly.kpxe', "$root/undionly.kpxe") or die "symlink: $!"; +} + +sub copy_tree { + my ($name) = @_; + my $copy = "$tmp/$name"; + system('cp', '-a', "$tmp/pristine", $copy) == 0 or die "cp -a to $copy failed"; + return $copy; +} + +make_tree("$tmp/pristine"); +my ($code, $manifest_text) = run_checker('--generate', "$tmp/pristine"); +is($code, 0, '--generate succeeds on a tree of files, directories and symlinks'); +my $manifest = "$tmp/payload.sha256"; +write_file($manifest, $manifest_text); +my @entries = grep { !/^#/ } split(/\n/, $manifest_text); +is(scalar(@entries), 8, 'the manifest has one entry for each directory, file and symlink'); +like($manifest_text, qr/^link\tx86_64-sb\tsb$/m, 'a symlink is recorded with its target, not followed'); + +($code, my $output) = run_checker("$tmp/pristine", $manifest); +is($code, 0, 'the unchanged tree passes') or diag($output); +like($output, qr/payload matches .*: 8 entries/, 'the check reports the number of entries'); +($code, $output) = run_checker("$tmp/pristine/", $manifest); +is($code, 0, 'a trailing slash on the tree path does not change the result') or diag($output); + +my @damage = ( + ['one changed byte', + sub { write_file("$_[0]/i386/undionly.kpxe", "undi\x00\x02") }, + qr{^content changed: i386/undionly\.kpxe$}m], + ['a missing file', + sub { unlink("$_[0]/x86_64-sb/snponly.efi") or die $! }, + qr{^missing: x86_64-sb/snponly\.efi$}m], + ['an extra file', + sub { write_file("$_[0]/x86_64-sb/extra.efi", 'extra') }, + qr{^unexpected: x86_64-sb/extra\.efi$}m], + ['an extra directory', + sub { make_path("$_[0]/arm64") }, + qr{^unexpected: arm64$}m], + ['a symlink with another target', + sub { unlink("$_[0]/sb") or die $!; symlink('i386', "$_[0]/sb") or die $! }, + qr{^link target changed: sb \(expected x86_64-sb, found i386\)$}m], + ['a symlink replaced by a copy of its target', + sub { unlink("$_[0]/x86_64-sb/ipxe-shim.efi") or die $!; + write_file("$_[0]/x86_64-sb/ipxe-shim.efi", "MZ signed shim") }, + qr{^type changed: x86_64-sb/ipxe-shim\.efi \(expected link, found file\)$}m], +); +my $n = 0; +for my $case (@damage) { + my ($name, $apply, $message) = @{$case}; + my $copy = copy_tree('damaged-' . ++$n); + $apply->($copy); + ($code, $output) = run_checker($copy, $manifest); + is($code, 1, "$name fails the check"); + like($output, $message, "$name is reported by path") or diag($output); +} + +write_file("$tmp/malformed.sha256", "file\tnot-a-digest\ti386/undionly.kpxe\n"); +($code) = run_checker("$tmp/pristine", "$tmp/malformed.sha256"); +is($code, 2, 'a malformed manifest line is an error, not a mismatch'); +write_file("$tmp/duplicate.sha256", "dir\t-\ti386\ndir\t-\ti386\n"); +($code) = run_checker("$tmp/pristine", "$tmp/duplicate.sha256"); +is($code, 2, 'a duplicate manifest path is an error'); +($code) = run_checker("$tmp/pristine/sb", $manifest); +is($code, 2, 'a tree path that is a symlink is refused'); + +# The committed manifest and checksums must describe the committed archives. +my @releases = glob("$pkg_dir/ipxeboot-*.tar.gz"); +is(scalar(@releases), 1, 'the package directory holds one release archive'); +SKIP: { + skip 'no release archive', 4 if @releases != 1; + my $release = "$tmp/release"; + make_path($release); + is(system('tar', '-xzf', $releases[0], '--strip-components=1', '-C', $release), 0, + 'the release archive unpacks'); + + # The builders install the ipxe/shim shims, signed by both UEFI CAs, over those of the release. + my %shims = ('ipxe-shimx64.efi' => 'x86_64-sb/shimx64.efi', 'ipxe-shimaa64.efi' => 'arm64-sb/shimaa64.efi'); + ($code, $output) = run_checker($release, "$pkg_dir/payload.sha256"); + is($code, 1, 'payload.sha256 does not describe the shims of the bare release tree'); + copy("$pkg_dir/$_", "$release/$shims{$_}") or die "copy $_: $!" for sort keys %shims; + ($code, $output) = run_checker($release, "$pkg_dir/payload.sha256"); + is($code, 0, 'payload.sha256 matches the release tree with the committed shims') or diag($output); + + open(my $fh, '<', "$pkg_dir/SHA256SUMS") or die "read SHA256SUMS: $!"; + my %sums = map { /^([0-9a-f]{64}) (\S+)$/ ? ($2, $1) : () } <$fh>; + close($fh); + my %actual = map { ($_, Digest::SHA->new(256)->addfile("$pkg_dir/$_", 'b')->hexdigest) } + grep { -f "$pkg_dir/$_" } keys %sums; + is_deeply(\%actual, \%sums, 'SHA256SUMS matches the committed archives and shims'); +} + +done_testing(); diff --git a/t/mockbuild-all.t b/t/mockbuild-all.t index c4b8b2b..674acf7 100644 --- a/t/mockbuild-all.t +++ b/t/mockbuild-all.t @@ -12,7 +12,7 @@ use File::Path qw(make_path); use File::Basename qw(basename); use MockBuildUtils qw(install_deps_packages install_deps_command missing_perl_modules required_pkgs version_matches rpm_sigmd5 rpm_version rpm_release rpm_is_signed - rpm_arch rpm_in_cell + rpm_arch rpm_in_cell resolve_mock_cfg skipped_builder carry_over_rpms source_package restamp_release_line cross_copy_genesis finalize_xcat_dep read_manifest verify_repo_packages verify_repo_signature verify_rpm_signatures @@ -31,6 +31,24 @@ sub quiet(&) { return wantarray ? @r : $r[0]; } +# ---- resolve_mock_cfg: /etc/os-release says almalinux, mock-core-configs names the file alma ----- +{ + my $dir = tempdir(CLEANUP => 1); + my $touch = sub { open(my $fh, '>', "$dir/$_[0].cfg") or die "$_[0]: $!"; close($fh); }; + $touch->('alma+epel-10-x86_64'); + $touch->('rocky+epel-9-x86_64'); + is(eval { resolve_mock_cfg('almalinux', 10, 'x86_64', $dir) }, 'alma+epel-10-x86_64', + 'an AlmaLinux host resolves to the alma config file'); + is(eval { resolve_mock_cfg('rocky', 9, 'x86_64', $dir) }, 'rocky+epel-9-x86_64', + 'an id that names its config file resolves to it'); + $touch->('almalinux+epel-10-x86_64'); + is(eval { resolve_mock_cfg('almalinux', 10, 'x86_64', $dir) }, 'almalinux+epel-10-x86_64', + 'a config file named after the os-release id is preferred'); + ok(!eval { resolve_mock_cfg('almalinux', 8, 'x86_64', $dir); 1 }, + 'a release with no config file is an error'); + like($@, qr{\Q$dir/alma+epel-8-x86_64.cfg\E}, 'the error names the config files it tried'); +} + # ---- required_pkgs: a skipped builder's packages are not required (clean --skip-* runs) ------- my @all = qw(elilo-xcat ipmitool-xcat perl-IO-Stty perl-Sys-Virt xCAT-genesis-base); is_deeply([required_pkgs(\@all, 0, 0, 0)], \@all, @@ -415,6 +433,10 @@ is(rpm_release(tempdir(CLEANUP => 1), 'nonexistent-pkg'), undef, 'rpm_release is cmp_ok(scalar(@targets), '>=', 1, 'packages-manifest.conf has at least one target section'); ok(!grep({ $_ eq 'common' } @targets), 'the shared-repo section is not treated as a build target'); my @missing = grep { !exists $m{$_}{'conserver-xcat'} } @targets; + # The upstream iPXE loaders ship beside xnba-undi, so a target that publishes one publishes both. + my @no_ipxe_xcat = grep { exists $m{$_}{'xnba-undi'} && !exists $m{$_}{'ipxe-xcat'} } @targets; + is_deeply(\@no_ipxe_xcat, [], 'every target that lists xnba-undi also lists ipxe-xcat') + or diag("missing ipxe-xcat in: @no_ipxe_xcat"); is_deeply(\@missing, [], 'conserver-xcat is present in every manifest target section') or diag("missing conserver-xcat in: @missing"); @@ -422,7 +444,7 @@ is(rpm_release(tempdir(CLEANUP => 1), 'nonexistent-pkg'), undef, 'rpm_release is # carries, at the same pins: a riscv64 MN serves the x86 nodes of a mixed cluster too. my ($ppc) = grep { /^[a-z+]+-10-ppc64le$/ } @targets; ok(defined $ppc, 'an EL10 ppc64le target section exists to compare against') or $ppc = ''; - for my $boot (qw(elilo-xcat grub2-xcat syslinux-xcat xnba-undi)) { + for my $boot (qw(elilo-xcat grub2-xcat ipxe-xcat syslinux-xcat xnba-undi)) { is($m{'rocky-10-riscv64-xcat'}{$boot}, $m{$ppc}{$boot}, "$boot pinned in the riscv64 target as in the EL10 ppc64le target"); } diff --git a/t/sbuild-all.t b/t/sbuild-all.t index c6c800c..099933f 100644 --- a/t/sbuild-all.t +++ b/t/sbuild-all.t @@ -302,14 +302,15 @@ SKIP: { is_deeply(\@miss_go, [], 'goconserver present in every manifest target') or diag("missing goconserver in: @miss_go"); - # The noarch boot components (syslinux-xcat, grub2-xcat, elilo-xcat, xnba-undi) are Architecture:all - # single-producer (built ONCE on amd64) but REQUIRED-PRESENT on EVERY target incl. ppc64el and - # riscv64, so the gate verifies those repos actually carry them (matches the EL manifest + the 2.16 - # ppc dep repo; a ppc or riscv64 MN serves the x86 nodes of a mixed cluster). It is the BUILD PHASE - # -- not the manifest -- that avoids rebuilding them off amd64 (build_one_codename skips an - # Architecture:all package on non-amd64; see the control_binary_arch test below). + # The noarch boot components (syslinux-xcat, grub2-xcat, elilo-xcat, xnba-undi, ipxe-xcat) are + # Architecture:all single-producer (built ONCE on amd64) but REQUIRED-PRESENT on EVERY target + # incl. ppc64el and riscv64, so the gate verifies those repos actually carry them (matches the + # EL manifest + the 2.16 ppc dep repo; a ppc or riscv64 MN serves the x86 nodes of a mixed + # cluster). It is the BUILD PHASE -- not the manifest -- that avoids rebuilding them off amd64 + # (build_one_codename skips an Architecture:all package on non-amd64; see the + # control_binary_arch test below). for my $t (@targets) { - for my $boot (qw(syslinux-xcat grub2-xcat elilo-xcat xnba-undi)) { + for my $boot (qw(syslinux-xcat grub2-xcat elilo-xcat xnba-undi ipxe-xcat)) { ok(exists $m{$t}{$boot}, "$boot required-present on $t (arch:all, verified on every arch)"); } } @@ -372,6 +373,17 @@ SKIP: { ok(!index_has_native_arch(undef, 'amd64'), 'undef index text -> not built (no crash)'); } +# ipxe-xcat is built once on amd64 like the other boot components. Its control file must declare +# Architecture: all, or every other arch would rebuild it. +{ + open my $fh, '<', "$FindBin::Bin/../ipxe-xcat/debian/control" or die "ipxe-xcat/debian/control: $!"; + my $ctl = do { local $/; <$fh> }; + close $fh; + is(control_binary_arch($ctl, 'ipxe-xcat'), 'all', 'ipxe-xcat is Architecture:all'); + ok(!skip_arch_all_on($ctl, 'ipxe-xcat', 'amd64'), 'ipxe-xcat is built on amd64'); + ok(skip_arch_all_on($ctl, 'ipxe-xcat', $_), "ipxe-xcat is not rebuilt on $_") for qw(ppc64el riscv64); +} + # ---- control_binary_arch: PURE Architecture lookup for a specific BINARY package in debian/control -- # Drives build_one_codename's "skip arch:all on non-amd64" (single-producer) decision. Must pick the # right binary paragraph -- e.g. the syslinux SOURCE is 'any' but the syslinux-xcat subpackage is 'all'. @@ -706,6 +718,7 @@ STUB 'grub2-xcat' => 'grub2-xcat', 'elilo-xcat' => 'elilo', 'xnba-undi' => 'xnba', + 'ipxe-xcat' => 'ipxe-xcat', ); my %manifest = read_manifest("$root/debs-manifest.conf"); my %seen;