2
0
mirror of https://github.com/xcat2/xcat-dep.git synced 2026-09-12 12:36:23 +00:00
Commit Graph

975 Commits

Author SHA1 Message Date
Vinícius Ferrão 87d0e347e3 feat(genesis): package s390x images 2026-09-04 13:59:45 -03:00
Daniel Hilst 765b844b4e Merge pull request #62 from VersatusHPC/fix/xcat-dep-matrix-build
fix(build): Build xcat-dep across the CD matrix: EL 8/9/10
2026-09-02 09:46:24 -03:00
Daniel Hilst c4c9492e57 fix(xcat-dep): merge master after the riscv64 and Ubuntu builds landed
Master gained the EL10 riscv64 forcearch target (PR #66) and the Perl Ubuntu
build (PR #63). Both touch the files this branch rewrites, so the merge is
resolved per file:

mockbuild-all.pl, mockbuild-perl-packages.pl keep the forcearch target profile,
the noarch chroot and --epel-gap from master, and this branch's manifest gate,
atomic per-cell deploy and per-package chroot scrub. assert_required_deps is
dropped: verify_target_repo replaced it. The post-join bootstrap scrub now reads
the uniqueext and the config recorded when the chroot was made, because the wave
loop of master no longer numbers packages in @packages order.

packages-manifest.conf gains a [rocky-10-riscv64-xcat] section. A target with no
section is fatal, so without it the riscv64 target cannot run.

goconserver/mockbuild.pl builds in the mock chroot for the host arch and cross-
compiles on the host for a foreign --target-arch. A forcearch chroot would run
the Go toolchain under qemu. Both paths overlay the pinned go.mod/go.sum and
ship server.conf as YAML.

The host-install smoke stays removed (it corrupts the build host rpm database).
The checks that do not install on the host are kept: the chroot install of a
cross-built ipmitool-xcat and XS perl module, and the binfmt run of the cross-
built goconserver binaries.

goconserver/gomod/ takes the pin of master, whose `go` directive is the lower of
the two, so both the EL10 chroot and the Ubuntu sbuild toolchain accept it.

t/genesis_openembedded_consumer.t: the skip count of the RPM block is 64, the
number of tests it runs. Both sides carried a stale number.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-02 09:39:55 -03:00
Daniel Hilst 65691bf1b6 Merge pull request #63 from VersatusHPC/fix/xcat-dep-ubuntu-matrix-build
feat(xcat-dep): add the Ubuntu/Debian sbuild dependency-build matrix
2026-09-02 09:16:53 -03:00
Daniel Hilst 3bd8228008 Merge pull request #66 from VersatusHPC/feature/riscv64
feat(xcat-dep): build the EL10 riscv64 dependency repository
2026-09-02 09:15:57 -03:00
Daniel Hilst 5bb9cfa2b2 feat(xcat-dep): --install-deps makes a build host able to run the script
A CD run died at compile time inside XCAT::BuildUtils because xcat-master-ub was
missing File::Slurper: "Can't locate File/Slurper.pm in @INC", in the middle of a
build. It was fixed by hand, so the next unprovisioned host fails the same way
and the documented install line can drift from what the code actually loads.

--install-deps installs this host's prerequisites and exits: the sbuild/schroot
toolchain plus the modules. It then LOADS each module and fails naming any that
is still missing, rather than trusting apt's exit code.

That probe earned its place immediately: the first list named libipc-cmd-perl,
which does not exist on Ubuntu -- IPC::Cmd is core there -- and apt failed the
whole install over it. The package is gone from the list and the module is
asserted by loading instead, with a test that pins both halves of that reasoning.

The list and the command are pure functions in BuildUtils, so the decision is
unit-tested and the side effect stays in the caller. Run on xcat-master-ub and
xcat-master-ub-ppc: both report every module present.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-27 15:30:47 -03:00
Daniel Hilst 1e9ec56bdc feat(xcat-dep): --install-deps makes a build host able to run the script
Two CD runs died at compile time inside XCAT::BuildUtils because a builder was
missing a Perl module the script loads: perl-File-Slurper on xcat-master-ub and
perl-IPC-Cmd on xcat-master-ppc. Both surfaced as "Can't locate ... in @INC" in
the middle of a build, and both were fixed by hand -- so the next unprovisioned
host fails the same way, and BUILD.md's install line can drift from what the code
actually requires.

--install-deps installs this host's prerequisites and exits: the toolchain plus
the modules, through dnf or zypper as the host's ID dictates. It then LOADS each
module and fails naming any that is still missing, rather than trusting the
package manager's exit code -- a package that installs cleanly but leaves the
module unusable is exactly the failure this exists to prevent.

The list and the command are pure functions in MockBuildUtils, so the decision is
unit-tested (package sets per family, the right installer non-interactively, and
the probe reporting only what genuinely cannot be loaded); the side effect stays
in the caller. Run on xcat-master and xcat-master-ppc: both report every module
present. xcat-master-suse is unreachable and still needs it.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-27 15:29:58 -03:00
Daniel Hilst a35343f60e feat(xcat-dep): gate the shared Genesis pool on a manifest section of its own
Every package in a suite pool is gated against debs-manifest.conf, but the
OpenEmbedded Genesis release is published into pool/main/xcat-genesis-openembedded
-- one pool every suite indexes, described by no [<codename>-<arch>] section. So
nothing asserted the published pool was complete: its packages were checked only
as they were copied, against the release checksums, and a pool that lost one
afterwards would publish quietly.

[shared] describes that pool -- all seven architectures, pinned '2.*' like
xcat-genesis-base, because they are built FROM xcat-core and their version walks
with it. A glob rather than an EVR floor: pins in this manifest are exact-or-glob
(version_matches), and the '>= epoch:version-release' form is an EL-side feature
of packages-manifest.conf. verify_shared_pool runs on the side tree before the
swap, so an incomplete pool is never published.

[shared] is not a build target, so the manifest now has two kinds of section. No
code iterates sections blindly, but t/sbuild-all.t did -- twice -- so it now
selects <codename>-<arch> sections and asserts the shared-pool section is not
treated as a target. The consumer fixtures carry the shipped [shared] section
verbatim: publishing a release against a manifest that lacks it is refused, not
silently ungated.

Verified the gate fails when removed, and when [shared] and the pool disagree.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-26 18:31:59 -03:00
Daniel Hilst b280fb8b48 feat(xcat-dep): gate the shared Genesis repository on a manifest section of its own
Every package in the per-EL cells is gated against packages-manifest.conf, but
the OpenEmbedded Genesis release is published into xcat-dep/common, which sits
BESIDE those cells and is described by no [<target>] section. Nothing asserted
the published shared repository was complete: its packages were checked only as
they were copied, against the release checksums, so a repository that lost one
afterwards would publish quietly.

[common] describes that repository -- all seven architectures, floored at the
paired xcat-core version (>= 2.18.0; these carry no Epoch, unlike
xCAT-genesis-base). verify_common_repo runs on the STAGE, before the atomic swap,
so an incomplete shared repo is never published. Completeness only: the release
checksums cover the bytes and the deploy asserts every signature.

[common] is not a build target, so the manifest now has two kinds of section.
No code iterates sections blindly, but t/mockbuild-all.t did, and asserted
conserver-xcat in every one; it now selects target-named sections and asserts
the shared-repo section is NOT treated as a target.

t/common-repo-gate.t drives the real publish path and asserts on the repository
left behind. Verified it fails without the gate, and that dropping an
architecture from [common] is caught.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-26 18:24:19 -03:00
Daniel Hilst bbb711431f fix(xcat-dep): pin the release-sensitive deps to xCAT's own EVR floors
The manifest pinned most packages by %{VERSION} alone, so the gate accepted an
rpm with the right Version and a Release older than xCAT will install against --
xCAT states several of these as ">= version-release" Requires (PR #62 review).

Converted, in every section, to the floors taken verbatim from xcat-core's specs:
goconserver >= 0.3.3-snap202011021058, xnba-undi >= 1.21.1-1,
syslinux-xcat >= 6.03-1, ipmitool-xcat >= 1.8.18-4 (xCAT.spec / xCATsn.spec),
perl-HTTP-Async >= 0.30-3, perl-Net-HTTPS-NB >= 0.14-3 (xCAT-server.spec). Where
two specs disagree the stronger floor is used. Each was checked against the EVR
this repository actually builds, using the gate's own comparator, so none of them
reds a build that is in fact correct.

grub2-xcat is deliberately left on its Version pin. xCAT-server asks for
'>= 2.02-0.76.el7.1.snap201905160255', but the grub2-xcat built here -- and shipped
by both published channels today -- is 1.0-2, which cannot satisfy it. Encoding
that Requires would fail every build over a discrepancy that lives in xcat-core,
so it is documented in the manifest header and reported upstream instead.

t/mockbuild-all.t now guards the shipped manifest: every release-sensitive
package keeps an EVR floor in every section, and grub2-xcat stays the documented
exception. Verified the guard fails when a floor is regressed to a bare version.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-26 17:23:42 -03:00
Daniel Hilst 36f9e38a26 fix(xcat-dep): gate each target on the whole manifest, whatever this run built
verify_target_repo filtered the manifest through required_pkgs() with the
invocation's --skip-genesis / --skip-perl / --skip-xcat-dep, so the flags that
describe what a run BUILT also decided what the verified repository was allowed
to lack: a repo with no xCAT-genesis-base passed whenever the verifying run
carried --skip-genesis (PR #62 review). Those flags mean "this invocation did not
build it", never "the repository may ship without it" -- a package an earlier run
produced is still expected to be present. The gate now takes the manifest whole.

No change for the CD pipeline, which passes no package-selection skips; it closes
the hole for the documented skip-mode and finalize invocations.

The Genesis-release consumer fixtures now pass --no-verify-repo. Their dependency
packages are copies of a single rpm, so no manifest describes them the way a real
one describes a real build -- with the gate honest, a fixture manifest could only
be satisfied by lying about what the cell contains. The gate is covered instead
against purpose-built rpms in t/verify-repo-el.t, and those runs still need a
manifest SECTION to exist, which is all they ever needed.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-26 17:18:20 -03:00
Daniel Hilst 632379e2d8 test(xcat-dep): capture --skip-* weakening the per-target repo gate
verify_target_repo filters the manifest through required_pkgs() with the
invocation's --skip-genesis / --skip-perl / --skip-xcat-dep, so the flags that
say what THIS run built also decide what the verified repository is allowed to
be missing. A repo with no xCAT-genesis-base passes when the verifying run was
given --skip-genesis (PR #62 review).

Drives the real `mockbuild-all.pl --verify-repo` over fixture repos built from
two minimal rpms, so the gate reads real header names. The assertions are on the
reported problems rather than the exit code: a standalone --verify-repo demands a
repomd signature by contract and these fixtures are unsigned, so it exits
non-zero either way -- what separates a working gate from a broken one is
whether the missing package is NAMED. The complete-repo baseline is asserted too,
so the test cannot pass by the gate simply always complaining.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-26 17:15:08 -03:00
Daniel Hilst 73ad97d5a2 fix(xcat-dep): gate publication on the whole manifest, whatever this run built
verify_assembled_repo filtered the manifest through required_pkgs() with this
invocation's --skip-genesis / --skip-xcat-dep. Since the documented publish-only
run IS `--skip-build --skip-genesis --publish`, the flags that describe what this
invocation built were also deciding what the published repository was allowed to
lack -- so a repository with no xcat-genesis-base passed its own publication
gate (PR #63 review).

Those flags mean "this invocation did not build it", never "the repository may
ship without it": a package built by an earlier run is still expected in the
tree, which the side tree is seeded from. The gate now takes the manifest whole.
The other two required_pkgs() call sites are unchanged and correct -- they choose
what to BUILD and what to validate in THIS arch's staging.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-26 17:13:23 -03:00
Daniel Hilst 6ef17ea546 test(xcat-dep): capture --skip-* weakening the publication gate
The documented publish-only invocation is
`sbuild-all.pl --skip-build --skip-genesis --publish`, and verify_assembled_repo
passes those same flags to required_pkgs() when deciding what the PUBLISHED
repository must contain. So the flags that say what this INVOCATION built also
decide what the repository is allowed to be missing, and a repo carrying no
xcat-genesis-base passes its own publication gate.

Assert the gate on a repo missing Genesis (with --skip-genesis) and on one
missing a compiled dep (with --skip-xcat-dep). Both fixtures keep native stanzas
for the arch, so the failure under test is the missing PACKAGE and not the arch
reading as absent. Both fail on the current gate.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-26 17:11:52 -03:00
Daniel Hilst 9ce1bd0751 fix(xcat-dep): retry the Build-Depends install, refreshing the index
A CI run of this branch died on resolute/ppc64el with a 404 fetching
libssl-dev_3.5.5-1ubuntu3.4_ppc64el.deb: a development suite rolled openssl and
dropped that version from the pool while the chroot's index still named it.
mk-build-deps was the one apt operation in the in-chroot script NOT wrapped in
apt_retry, so a single transient mirror inconsistency failed the package -- and,
with the matrix running failFast, took the other architecture's in-flight builds
down with it.

Retry it the same way the rest of the script retries apt, refreshing the index
between attempts, since a stale index is precisely what produces this. It stays
FATAL once the attempts are spent: a package must never build against whatever
the chroot happens to carry. The refresh goes through apt_retry, so every
apt-get in the script still runs under the fatal helper.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-25 18:43:14 -03:00
Vinícius Ferrão 5ae275c733 docs(BUILD.md): riscv64 notes on perl-Net-DNS 0.80, goconserver stripping, disk use
Record what differs from the EPEL-fed x86_64 repo (perl-Net-DNS stays at the
EPEL-free 0.80 noarch build; newer XS-free Net-DNS is a follow-up), how the
cross-built goconserver is stripped, and that the per-package mock chroots of
a riscv64 run add up under /var/lib/mock so --max-parallel also bounds disk.
2026-08-25 18:31:44 -03:00
Vinícius Ferrão 08d59ced0d fix(goconserver): strip the cross-compiled binaries at link time
For a native build rpm's brp-strip strips the Go binaries; for a cross build
(--target-arch riscv64 on x86_64) the host strip cannot handle the foreign
ELF and the rpm shipped unstripped 19 MB binaries. Pass -s -w to the Go
linker for cross builds only, so the riscv64 rpm is stripped like the
native ones; native builds are unchanged.
2026-08-25 18:31:44 -03:00
Vinícius Ferrão e52b31e1fd build(mockbuild): retry a mock run once when its package manager fails (rc=30)
A riscv64 run lost perl-Crypt-SSLeay to a transient mirror problem: the
bootstrap chroot's dnf got HTTP 404 for BaseOS primary.xml.gz on every Rocky
mirror (metadata mid-sync) and mock exited 30 (YumError) from --buildsrpm,
which the builder treated as a hard failure. Give the mock-driven builders --
mockbuild-perl-packages.pl, ipmitool, grub2-xcat and conserver -- a small
run_mock wrapper that reruns the same mock command once when it exits 30
(the package-manager failure code; build failures exit 10 and are not
retried), and use it for their --buildsrpm/--rebuild invocations.
2026-08-25 18:31:43 -03:00
Vinícius Ferrão 374a9c6028 build(mockbuild-all): build and deploy the EL10 riscv64 dependency repository
mockbuild-all.pl only knew the mock-core-configs targets <os>+epel-<rel>-<arch>
and only ever built the host arch. Teach it the forcearch targets shipped in
mock-configs/ (today rocky-10-riscv64-xcat), selected with --target, so an
x86_64 host cross-builds and deploys rh10/riscv64 exactly like the native
per-EL repos (rh<rel>/<arch> layout, xcat-dep.repo with the xcat.org baseurl,
mklocalrepo.sh, buildinfo.txt, optional signing).

A target now has a profile (target_profile): EL release, arch of the rpms,
the mock config for its noarch deps, the dep builders to run and the required
set asserted after deploy. The native targets keep today's profile (every
builder, host arch, the full required set). The riscv64 profile:

  - builds ipmitool-xcat, conserver-xcat and goconserver for riscv64
    (--target-arch riscv64 to the builders: emulated mock rebuilds for the C
    ones, GOARCH cross-compile + rpmbuild --target for goconserver);
  - builds grub2-xcat, a noarch packaging, in the native EPEL-free
    rocky-10-<host arch> chroot rather than the emulated one;
  - does not build the x86 bootloaders (elilo-xcat, syslinux-xcat, xnba-undi)
    and does not require them;
  - runs mockbuild-perl-packages.pl with --target-arch riscv64,
    --noarch-mock-cfg rocky-10-<host arch> and --epel-gap, since riscv64 has
    no EPEL to take xCAT's other perl deps from;
  - installs mock-configs/<target>.cfg into /etc/mock/ when it is missing there
    (mock and the builders' include('/etc/mock/<target>.cfg') overlays need
    it); a host copy that differs from the shipped one is an error, never
    silently used.

$arch is now the arch of the target being built (set per target), $host_arch
the uname -m one used to pick the default rh8/rh9/rh10 targets; the deploy and
the repo metadata take the arch from the target profile. --scrub-all-chroots
also scrubs the noarch chroot. BUILD.md documents the riscv64 build, what it
produces and the known exclusions (perl-DB_File, perl-SOAP-Lite).
2026-08-25 18:31:43 -03:00
Vinícius Ferrão 7ffc621b79 feat(perl): build the EPEL-only perl deps of xCAT where there is no EPEL
EL10 x86_64/ppc64le take these perl deps of xCAT from EPEL; riscv64 has no EPEL
and Rocky Linux 10 riscv64 BaseOS/AppStream/CRB do not carry them, so xcat-dep
builds them for that arch. Add them to mockbuild-perl-packages.pl's package
table, and a --epel-gap switch that appends them to the build list (the
default list6 build is unchanged):

  perl-Crypt-Blowfish  EPEL 10 src.rpm (2.14-25.el10_0, vendored now; the spec
                       in the dir is a SUSE one); its optional tests need
                       Crypt::CBC, so it 'needs' our perl-Crypt-CBC
  perl-Crypt-CBC       perl-Crypt-CBC.spec + Crypt-CBC-2.33.tar.gz: the spec
                       is now the Fedora one of the vendored fc29 src.rpm
                       (release 21) with the BuildRequires an EL10 buildroot
                       lacks (make, perl-interpreter); it replaces the SUSE
                       spec (perl-macros) that could not build on EL (noarch)
  perl-Crypt-Rijndael  perl-Crypt-Rijndael-1.13-10.fc29.src.rpm
  perl-Digest-SHA1     perl-Digest-SHA1-2.13-23.fc28.src.rpm
  perl-Expect          perl-Expect-1.35-6.fc29.src.rpm          (noarch)
  perl-Mail-Sender     perl-Mail-Sender-0.903-7.fc29.src.rpm    (noarch)
  perl-Net-DNS         Net-DNS.spec + Net-DNS-0.80.tar.gz, now built with
                       --noxs as noarch (the cpan2rpm spec hard-coded
                       buildarch x86_64 for the XS dn_expand) and with the
                       BuildRequires cpan2rpm specs never carry; release 2
  perl-Net-IP          perl-Net-IP-1.26-30.el10_0.src.rpm       (noarch)
  perl-Path-Class      new dir, EPEL 10 src.rpm (0.37-24.el10_0, noarch): only
                       a build dep -- Crypt-SSLeay's Makefile.PL needs it --
                       so perl-Crypt-SSLeay 'needs' it; on x86_64 EPEL still
                       provides it and nothing changes there

Two EPEL-only deps of xCAT are deliberately not built: perl-SOAP-Lite
(1.27-3.fc29 src.rpm is in the table for completeness, but its BuildRequires
IO::SessionData, MIME::Lite, XML::Parser::Lite and Test::XML are EPEL-only as
well, so it can neither be built nor installed without EPEL; xCAT uses it for
HP blade/VirtualBox support only) and perl-DB_File (needs libdb, which EL10
dropped and Rocky Linux 10 riscv64 does not have at all; only xCAT-server's
Confluent client uses it and xCAT-server merely recommends the package).
2026-08-25 18:30:13 -03:00
Vinícius Ferrão 4704e595e9 build(mockbuild): let the per-package builders produce another arch (forcearch)
The per-package builders take the arch of what they build from 'uname -m', which
is wrong for a forcearch mock config such as rocky-10-riscv64-xcat built on an
x86_64 host: the chroot produces riscv64 rpms and the scripts then reject them
("Unexpected RPM arch"). Give every arch-producing builder a --target-arch
option (default: uname -m, so nothing changes for native builds):

- ipmitool/mockbuild.pl, conserver/mockbuild.pl: look for and verify
  <target-arch> rpms. ipmitool's install smoke test cannot install a foreign
  rpm on the host, so for a cross build it installs the rpm into the build
  chroot with mock --install and runs ipmitool-xcat -V there (conserver already
  smoke-tests in the chroot).
- goconserver/mockbuild.pl: the binaries are built on the host, so cross-compile
  with GOARCH (x86_64 amd64, aarch64 arm64, riscv64 riscv64, ...) and package
  with rpmbuild --target <arch>; rpm refuses 'BuildArch: <foreign arch>' on
  this host ("No compatible architectures found for build"), so that line is
  only emitted for native builds. A cross build cannot install its rpm on the
  host either, so the smoke test unpacks it and runs goconserver and congo
  through the binfmt handler (qemu-user-static) the forcearch mock builds of
  the other deps need anyway.
- mockbuild-perl-packages.pl: --target-arch for the 'native' rpm check and the
  default result/log dirs; the 'native' (XS) packages of a cross build are
  smoke-tested inside the build chroot (mock --install, then perl -M<module>
  there) instead of on the host; --noarch-mock-cfg to build the noarch
  packages in a native chroot of the same release instead of the emulated one
  (the rpms are identical for every arch, and an emulated perl build is an
  order of magnitude slower); and a 'needs' key in the package table: a
  package that needs others is built after them, in waves, with their rpms
  installed into its chroot via mock --additional-package. Needs outside the
  selected set are ignored, so the default list6 build is unchanged (the
  chroot provides the module, e.g. from EPEL). This is what lets an EPEL-free
  chroot build perl-Crypt-Blowfish on top of our own perl-Crypt-CBC, or
  perl-Crypt-SSLeay with perl-Path-Class.
2026-08-25 18:30:13 -03:00
Vinícius Ferrão 9f074d3004 feat(perl): add the perl-Net-IP source dir
xCAT::NetworkUtils uses Net::IP, and perl-Net-IP is EPEL-only on EL10, so an
architecture without EPEL (riscv64) has to get it from xcat-dep. Vendor the
EPEL 10 source rpm, as the other per-package dirs do with their Fedora
src.rpms:

  perl-Net-IP/perl-Net-IP-1.26-30.el10_0.src.rpm      (noarch)

and register it in mockbuild-perl-packages.pl's package table in 'srpm' mode
(not in the default build list: EL10 x86_64/ppc64le keep taking it from EPEL).
2026-08-25 18:30:13 -03:00
Vinícius Ferrão 002df3ca0a build(mock): add the rocky-10-riscv64-xcat forcearch configuration
xcat-dep has no riscv64 build host, and mock-core-configs' rocky-10-riscv64.cfg
cannot be used from the x86_64 hosts that build the repos: it only admits a
riscv64 host (legal_host_arches) and names its chroot 'rocky-10-x86_64'.

Ship mock-configs/rocky-10-riscv64-xcat.cfg: the stock templates/rocky-10.tpl
(BaseOS/AppStream/CRB/extras for $basearch=riscv64) with root
'rocky-10-riscv64-xcat', target_arch riscv64, legal_host_arches x86_64+riscv64
and forcearch riscv64, so mock runs the Rocky Linux 10 riscv64 chroot through
user-mode QEMU and the packages are built by the chroot's own riscv64
toolchain. There is no EPEL for riscv64, so nothing EPEL-only is reachable from
this chroot (the build scripts deal with that in the following commits).

Document in BUILD.md what the host needs before this config works: a static
qemu-riscv64 registered in binfmt_misc with the F flag (EL10 has no
qemu-user-static-riscv package; take the binary from a Fedora container), the
/usr/bin/qemu-riscv64-static file mock insists on, podman for the bootstrap
image, golang for the goconserver cross-compile, the install of the config
into /etc/mock/ and the commands that validate the setup. Verified on an
x86_64 EL10 host with mock 6.7: chroot init in about 3.5 minutes, 'uname -m'
inside the chroot reports riscv64.
2026-08-25 18:30:12 -03:00
Vinícius Ferrão ff7e48b480 feat(grub2-xcat): ship the EL10 riscv64 grub2 UEFI image
riscv64 nodes boot through UEFI firmware and grub2 only, and xCAT hands
DHCP client architecture 27 (0x001b) the boot file
boot/grub2/grub2.riscv64. Nothing shipped that file.

Add the unmodified grub2 UEFI image from the Rocky Linux 10 riscv64
BaseOS tree (EFI/BOOT/grubriscv64.efi, the copy used for installation
media and network boot, built from grub2-2.12-46.el10_2.rocky.0.1.src.rpm,
GPL-3.0-or-later, provenance and checksum recorded in the readme) as
Source2, install it under /tftpboot/boot/grub2/riscv64-efi/ and let the
rpm and deb scripts copy it to /tftpboot/boot/grub2/grub2.riscv64 the
same way grub2.ppc is made from the POWER core image. mockbuild.pl
verifies the image type (it reads the PE header itself: file(1) only
learned the RISC-V machine types in 5.38, so an EL8 build host would
reject a good image), the rpm payload and the installed file (byte for
byte the source image); the deb installs the same tree.
2026-08-25 18:30:12 -03:00
Daniel Hilst 2a4eb248b4 feat(xcat-dep): merge master and share one Genesis pool across every apt suite
PR #65 changed where the OpenEmbedded Genesis packages live. On the RPM side
they are published once under xcat-dep/common; on the APT side, once under
pool/main/xcat-genesis-openembedded, with every suite's Packages index pointing
at that one copy instead of each suite carrying its own. It made that change in
build-apt-repo.sh -- the script this branch deletes, having absorbed apt assembly
and signing into sbuild-all.pl -- so the layout is ported here rather than lost.

sbuild-all.pl:

- --genesis-release now rebuilds a single shared pool inside the side tree and
  indexes it into every suite, so a release is stored once rather than once per
  codename. The debs are Architecture:all and identical everywhere; the previous
  per-suite copy multiplied hundreds of megabytes by the number of suites.
- Because every suite's index points into that pool, publishing a release must
  cover every suite: a run whose --dists omits one is refused, instead of leaving
  that suite indexing files the new release retired.
- OpenEmbedded Genesis debs are dropped from suite pools unconditionally now,
  not only when a release is being published -- they belong to the shared pool.
- Published files get an explicit mode 0644: they are served by a web server
  running as another user, and inheriting the builder's umask is how that breaks.

master's transaction machinery (per-file backups, --force-unlock recovery of an
interrupted publisher) is deliberately NOT ported: it exists because the shell
publisher writes into the live repository. sbuild-all.pl assembles a complete
side tree, gates it, and renames it into place under one global publish lock, so
a failed or killed run leaves the published repository untouched and there is no
half-written state to recover. The tests assert that guarantee directly.

The APT consumer tests now drive sbuild-all.pl's publish path with master's new
expectations: the shared pool holds one complete release, suite pools hold none
of it, every suite/arch index carries the shared Filename, a later single-suite
rebuild keeps using the pool, a partial-suite release is refused, and a
publication that cannot be signed leaves the packages, indexes and key exactly
as they were.

Full suite green: 416 tests on xcat-master (rome01, EL10) and 414 on
xcat-master-ub, where the APT cases actually run.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-25 18:10:35 -03:00
Daniel Hilst 6a50444d96 fix(xcat-dep): merge master after the Genesis common repository landed
PR #65 moved the OpenEmbedded Genesis release out of the per-EL cells: it is now
published once into <repo-dep>/common, under its own repository lock, and each
per-EL deploy only drops stale OpenEmbedded packages. That rewrites the same
deploy path this branch rewrites, so the merge had to reconcile the two.

Resolution:

- deploy_target keeps this branch's staged, verified, atomically swapped cell,
  and adopts master's model inside it: the release is no longer installed here,
  so the stage only calls remove_genesis_packages before it is signed. master's
  sign/index/write-metadata already run on the stage, and assert_required_deps
  stays gone -- verify_target_repo, which also asserts pinned versions and every
  rpm signature, replaced it.
- master's lock and publication state (@HELD_LOCKS, the common stage/backup
  globals, the INT/TERM/HUP handlers) replaces this branch's single $HELD_LOCK,
  which the merged lock helpers no longer use.
- rpmsign takes master's explicit --define %__gpg, and the redundant bare
  `use FindBin` is dropped: this branch already imports $RealBin from it.
- BUILD.md keeps master's note that per-target tarballs exclude xcat-dep/common;
  the --skip-xcat section stays out, that flag being gone from this branch.

master's new consumer tests needed the same two adaptations as the ones merged
last time, for the same reasons: test_signed_common_rpm_repository and
test_rpm_repository_lock point --repo-root at a scratch tree, which on this
branch must carry a packages-manifest.conf section for the synthetic target, and
every run's --skip-xcat became --skip-genesis -- this branch removed --skip-xcat
(Getopt::Long silently prefix-matched it to --skip-xcat-dep) and --skip-genesis
is what makes xcat-core's buildrpms.pl unnecessary.

Green as root: 325 tests on xcat-master (rome01, EL10) and 327 on
xcat-master-ub, which also runs the APT cases. perlcritic is clean over the
gated file list, and build-apt-repo.sh still passes bash -n.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-25 18:00:08 -03:00
Daniel Hilst 8ca6032927 Merge pull request #65 from VersatusHPC/feat/genesis-common-repository
feat(genesis): publish OpenEmbedded images in common repositories
2026-08-25 09:37:14 -03:00
Vinícius Ferrão 3bb7c2eb4f test(genesis): use explicit fractional sleep
Signed-off-by: Vinícius Ferrão <2031761+viniciusferrao@users.noreply.github.com>
2026-08-25 00:36:00 -03:00
Vinícius Ferrão 6f25ddc0eb fix(genesis): own RPM helper directory 2026-08-24 23:51:09 -03:00
Vinícius Ferrão 8a893f6eec test(genesis): require helper directory ownership 2026-08-24 23:47:00 -03:00
Vinícius Ferrão 0f75e018ee docs(genesis): clarify suite publication 2026-08-24 23:25:15 -03:00
Vinícius Ferrão 37e8d12299 fix(genesis): guard package cleanup 2026-08-24 23:25:15 -03:00
Vinícius Ferrão f1eb5e0cb0 fix(genesis): finish publisher recovery 2026-08-24 23:25:15 -03:00
Vinícius Ferrão 09336c27a8 test(genesis): cover publisher shutdown 2026-08-24 23:20:55 -03:00
Vinícius Ferrão 4f8abc7861 docs(genesis): document repository recovery 2026-08-24 22:54:56 -03:00
Vinícius Ferrão d7351b4c64 fix(genesis): harden repository publication 2026-08-24 22:54:56 -03:00
Vinícius Ferrão f6ceb0c613 fix(genesis): clean package lifecycle 2026-08-24 22:54:55 -03:00
Vinícius Ferrão acaad842ce test(genesis): cover signing key rollback 2026-08-24 22:42:21 -03:00
Vinícius Ferrão 0fbb4f64d9 test(genesis): cover interrupted publication 2026-08-24 22:37:29 -03:00
Vinícius Ferrão 7769d433a0 test(genesis): cover repository publication gaps 2026-08-24 22:30:32 -03:00
Vinícius Ferrão 582d541bf3 chore(genesis): mark dynamic profile source 2026-08-24 21:58:20 -03:00
Vinícius Ferrão 0fee49d1e3 test(genesis): expect image refresh hooks 2026-08-24 21:51:36 -03:00
Vinícius Ferrão 20e2d7616d fix(genesis): complete repository handoff 2026-08-24 21:48:59 -03:00
Vinícius Ferrão 30f62ab06a test(genesis): require portable offline setup 2026-08-24 21:47:42 -03:00
Vinícius Ferrão 4c2fa1f791 fix(genesis): publish shared repositories safely 2026-08-24 21:44:00 -03:00
Vinícius Ferrão de50ffeb69 test(genesis): cover publication failures 2026-08-24 21:33:51 -03:00
Vinícius Ferrão 1c94bca320 fix(genesis): refresh updated boot images 2026-08-24 21:30:16 -03:00
Vinícius Ferrão 919fe0152f test(genesis): require package refresh hooks 2026-08-24 21:27:39 -03:00
Vinícius Ferrão ab6bfee319 docs(genesis): explain shared APT refreshes 2026-08-24 20:48:55 -03:00
Vinícius Ferrão 5c455a9bbe test(genesis): cover repository refresh and signing 2026-08-24 20:48:55 -03:00