2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-10-21 15:18:19 +00:00
Commit Graph

28749 Commits

Author SHA1 Message Date
Vinícius Ferrão 0cca31bd2b test(statelite): run the liteimg archive test with the native tests
The liteimg archive test runs real cpio and gzip, and puts compressor
and ctorrent fixtures in PATH. That is a native test, so it moves out
of the unit suite. The pull-request workflow runs it explicitly.

A missing Linux tool now fails the test instead of skipping it. An
ilitefile fixture replaces the runcmd override, so liteimg runs its
commands through the real runcmd.
2026-10-14 13:14:50 -03:00
Vinícius Ferrão 9c3dd711e0 test(imgport): cover an import that cannot open an image table
When an import cannot open a table of the image definition, it must
fail. The published image, its checksum, the kernel, the ramdisk and
the image definition must stay.
2026-10-13 16:51:34 -03:00
Vinícius Ferrão 0beb6ece16 test(packimage): cover an image directory with a space
The removal of abandoned stages, a publication that removes the other
archive formats, and rmimage must work in an image directory with a
space. A directory or file that the first word of its path names must
stay.
2026-10-13 16:51:34 -03:00
Vinícius Ferrão 87c58da302 fix(packimage): take the image directory literally when removing files
The removal of abandoned stages, the removal of the other archive
formats after a publication, and rmimage found their files with glob.
glob splits a pattern at a space, so for an image directory such as
"/install/custom images/node" the first word named another path.
rmtree then removed that directory, with its images. glob also takes a
wildcard character in the path of the image directory as a pattern.

image_dir_entries now lists the image directory itself and matches the
names of its entries, and these removals use it.
2026-10-13 16:51:34 -03:00
Vinícius Ferrão 75228f394d test(packimage): cover a checksum symlink through a failed publication
When the archive or metainfo rename fails, the checksum symlink must go
back. When the symlink cannot go back, the error must report it, and its
previous content must go back.
2026-10-13 16:51:34 -03:00
Vinícius Ferrão c0f3d212f5 fix(packimage): keep a checksum symlink through a failed publication
A failed publication put back only the content of the previous checksum
file. A checksum symlink became a regular file, which a later switch of
the symlinks would leave stale.

publish_rootimg now keeps the previous checksum entry, and a rollback
renames it back. When that rename fails, the previous content goes
back, and the error reports it.
2026-10-13 16:51:34 -03:00
Vinícius Ferrão c5c28f1448 test(packimage): cover staging that keeps the previous archive
When the previous archive can neither go back nor move out of staging,
the error must name the staging directory, and the directory must stay
after its owner drops it. The removal of abandoned stages must leave
it, and rmimage must remove it. After a publication that succeeds,
staging must hold no previous file, so that the removal of abandoned
stages removes it.
2026-10-13 16:51:33 -03:00
Vinícius Ferrão e06910c1de fix(packimage): keep the staging that holds the previous archive
When a failed publication could not put back the previous archive or
metainfo, it moved them to a .rootimg-previous-* directory. When that
move failed too, they stayed in the staging directory, which packimage,
liteimg and imgimport then removed. The only copy of the previous files
was lost.

Staging that keeps a previous file now stays, and the error names it.
The removal of abandoned stages leaves it, and rmimage removes it with
the image. A publication removes its previous files from staging
otherwise, so only a failed one leaves them.
2026-10-13 16:51:33 -03:00
Vinícius Ferrão bf718e019f test(packimage): cover a rollback that cannot put back the metainfo
When the previous metainfo cannot go back after a failed publication,
the error must name a directory that keeps it. A previous checksum that
cannot go back must be reported.
2026-10-13 16:51:33 -03:00
Vinícius Ferrão 989b9f4645 fix(packimage): keep the previous metainfo that a rollback cannot put back
When a publication failed, the rollback put back the previous metainfo
and checksum without checking either step. A metainfo that could not go
back stayed in staging, which cleanup then removed, and the rollback
reported nothing. The rollback now checks each step. It moves a previous
metainfo that cannot go back next to the image, as it does with a
previous archive, and reports where. It also reports a checksum that it
cannot put back.
2026-10-13 16:51:33 -03:00
Vinícius Ferrão 40409e854f test(utils): cover a lock that a waiting process takes after a release
When a process releases a lock that another process waits for, the
waiting process must take the lock. A third process must not take it
while the waiting process holds it.
2026-10-13 16:51:33 -03:00
Vinícius Ferrão 2437ef7846 fix(utils): lock the file that the lock path names
release_lock removes the lock file before it unlocks it. A process that
waited in acquire_lock then held a lock on a file without a name, while
a third process created a new file at the path and locked it too. Both
ran at once, for example two imports, or an import and a kit command.
acquire_lock now checks that the file that it locked is the one at the
path, and tries again when it is not. lock_dir returns the directory of
the lock files.
2026-10-13 16:51:33 -03:00
Vinícius Ferrão e1e9b9b14b test(packimage): cover a first archive whose publication fails
When no archive was published before and a rename of the publication
fails, no archive, checksum or metainfo may remain where none was, and
no directory for a previous archive may be created.
2026-10-13 16:51:33 -03:00
Vinícius Ferrão a95ca8bf6e fix(packimage): remove a first archive whose publication fails
When no archive was published before, as for the first pack or a change
of format, and the metainfo rename failed after the archive rename, the
rollback looked for a previous archive that did not exist. It reported
that archive as kept in an empty directory, and left the new archive and
its checksum published. The rollback now removes the new archive and its
checksum.
2026-10-13 16:51:32 -03:00
Vinícius Ferrão 0c554cc541 docs(packimage): describe the root image checksum
Describe the .sha256 file that packimage and liteimg write, and how
nodeset has nodes check it. Describe the rootimgchecksum attributes of
the site and the osimage, the upgrade that keeps existing images
unchecked, and the nodeset warning. Describe the checksum that genimage
and nodeset write for an image packed before this release.
2026-10-13 16:51:32 -03:00
Vinícius Ferrão ddec430138 test(rmimage): cover the removal of the image archives
rmimage must hold the image lock and remove the stateless and statelite
archives with their checksums and metainfo, and the .rootimgcheck
marker. It must remove the temporary directory that this host abandoned
and a kept previous archive. It must keep the temporary directory of
another host and files that are not part of the image.
2026-10-13 16:51:32 -03:00
Vinícius Ferrão 2ec6029c95 fix(rmimage): remove the statelite archive and the checksum files
rmimage removed rootimg.* from the image directory. That missed rootimg-
statelite.gz with its checksum and metainfo, and the .rootimgcheck
marker of the initial ramdisk. A temporary directory that an interrupted
packimage, liteimg or imgimport left on this host also stayed, with a
partial archive in it.

rmimage now removes these files, the temporary directories that writers
on this host abandoned, and the .rootimg-previous-* directories that
failed publications kept. rootimg_stage and rmimage share this cleanup
through remove_abandoned_rootimg_stages.
2026-10-13 16:51:32 -03:00
Vinícius Ferrão 6c665f8ce1 test(nodeset): cover the SLES statelite ramdisk boot files
A SLES statelite ramdisk node built with dracut must boot
initrd-stateless.gz, and nodeset must copy that file to TFTP. A statelite
ramdisk node without dracut and a statelite NFS node must still boot
initrd-statelite.gz.
2026-10-13 16:51:32 -03:00
Vinícius Ferrão 810e3bf66d fix(nodeset): copy the initial ramdisk that SLES statelite ramdisk nodes boot
A SLES statelite ramdisk image built with dracut boots
initrd-stateless.gz, but nodeset copied only initrd-statelite.gz to the
TFTP directory and checked only for that file. Nodes requested an initial
ramdisk that nodeset never copied, or one that an older nodeset left.

nodeset now chooses the initial ramdisk once, then copies, checks and
boots that file, as it does on Red Hat.
2026-10-13 16:51:32 -03:00
Vinícius Ferrão a1c685b21f test(nodeset): cover the Ubuntu statelite ramdisk command line
An Ubuntu statelite ramdisk node must get the imgurl of
rootimg-statelite.gz and no NFS root, and must boot the initial ramdisk
that nodeset copies to TFTP. A statelite NFS node must still mount the
image over NFS.
2026-10-13 16:51:32 -03:00
Vinícius Ferrão d9fb4703f9 fix(nodeset): give Ubuntu statelite ramdisk nodes the root image URL
The statelite branch of debian.pm tested rootfstype without its $, so it
compared the string rootfstype with ramdisk and always took the NFS root
branch. Ubuntu statelite ramdisk nodes got an NFS root and no imgurl, so
they never downloaded rootimg-statelite.gz.

nodeset now tests $rootfstype, and Ubuntu statelite ramdisk nodes get
the imgurl of rootimg-statelite.gz, as on Red Hat and SUSE.
2026-10-13 16:51:31 -03:00
Vinícius Ferrão 94a6e6565b test(xcatconfig): cover the root image check of an upgrade
The upgrade step must set rootimgchecksum to no for the stateless and
statelite images that do not set it, also for an image without a
linuximage row. It must keep an image that sets the attribute, leave
other images alone, and set site.rootimgchecksum to yes. A later
upgrade, and an upgrade after the administrator set the site attribute,
must change no image.
2026-10-13 16:51:25 -03:00
Vinícius Ferrão 459c13bbc9 feat(xcatconfig): keep the images of an upgrade unchecked
The root image check is on by default, so an upgrade from a release
without it would turn it on for every existing stateless and statelite
image. Their nodes would then need a checksum and an initial ramdisk
that can check.

On an upgrade, while site.rootimgchecksum is not set, xcatconfig sets
the rootimgchecksum attribute to no for each of these images that does
not set it, and then sets site.rootimgchecksum to yes. The existing
images keep booting unchecked, and new images get the check. A later
upgrade finds the site attribute set and changes nothing. A new
installation sets site.rootimgchecksum to yes.
2026-10-13 15:29:22 -03:00
Vinícius Ferrão 8766f841a4 test(nodeset): cover the root image checksum setting at nodeset
nodeset must ask nodes to check by default, with rootimgchecksum=yes. It
must leave the argument out when the site or the image turns the check
off, and the image value must win. For a statelite ramdisk node,
STATEMNT must stay after the image URL. nodeset must warn once for each
image whose initial ramdisk has no matching marker, and not for a marked
one. This must hold on the Red Hat, SUSE and Ubuntu plugins. A marker
must hold the checksum of its initial ramdisk, and imgimport must place
the marker that a bundle carries. With --noupdateinitrd, the copy in
TFTP must decide the warning. A failed copy must leave no boot entry and
keep the boot files in TFTP.

genimage and nodeset must write the checksum of an archive packed before
the check. They must write it also when no marker shows that the initial
ramdisk checks it, and when the check is turned off. They must keep a
published checksum. With the check off, a checksum that cannot be
written must not refuse the node. When another host holds the
publication lock, genimage must keep the initial ramdisk in TFTP.
nodeset must then report the node and keep its boot files. When the
first node of an image fails this step, the next node must copy the boot
files.
2026-10-13 15:29:22 -03:00
Vinícius Ferrão f8469e2074 feat(nodeset): tell nodes the root image checksum setting
Nodes could not know whether an image turned the root image checksum on.
An initial ramdisk built before the check booted the image unchecked,
and nothing reported it. An archive packed before the check had no
checksum for a new initial ramdisk to find.

When the image or the site turns the checksum on, nodeset adds
rootimgchecksum=yes to the kernel command line of the node. This applies
to stateless and statelite ramdisk nodes. genimage writes
<initrd>.rootimgcheck next to an initial ramdisk that can check. The
marker holds the SHA-256 checksum of the initial ramdisk, so a replaced
ramdisk does not match it. imgexport and imgimport carry the marker with
the ramdisk.

When the checksum is on, nodeset warns once for each image whose initial
ramdisk has no matching marker. Its nodes may boot the image unchecked.
nodeset judges the initial ramdisk in TFTP after it copies the boot
files, because nodes boot that copy, also with --noupdateinitrd. A copy
that fails is now an error for the node, instead of a boot entry for the
previous boot files.

genimage and nodeset write a checksum for each archive of the image
directory that has none, also when the check is off. Nodes with older
boot entries still check. genimage does it before it copies a new
initial ramdisk to TFTP, and nodeset before it copies the boot files of
a node. Both hold the publication lock while they write. When they
cannot write the checksum, they keep the boot files that nodes use now
and report how to recover. With the check off, nodeset reports it as a
warning instead, and still sets up the node. nodeset marks the boot
files of an image as copied only after this step succeeds. When the
first node of an image fails it, the next node copies them.

The change covers the Red Hat, SUSE and Ubuntu nodeset plugins, which
share one helper in xCAT::SvrUtils.
2026-10-13 15:29:22 -03:00
Vinícius Ferrão fd0468a72f test(netboot): cover the checksum check of the root image download
The test runs each changed xcatroot in a bubblewrap sandbox, with stub
curl, wget, logger, mount and sleep. An image that matches its checksum
must be extracted without a wait, also when a later line of the checksum
file holds it. An image that matches no line must not be extracted. A
download that began before packimage replaced the image must match the
checksum file fetched before it. A damaged download, a failed checksum
download and a checksum file without a checksum must each lead to one
more download. A file that an interrupted download left must be checked
before it is used. A missing checksum file and a missing sha256sum must
keep the node retrying. Without rootimgchecksum=yes, or with
rootimgchecksum=no, the image must be extracted unchecked.
2026-10-13 15:29:22 -03:00
Vinícius Ferrão b08b4cbd58 feat(netboot): check the root image against its published checksum
xcatroot extracted whatever curl or wget downloaded, so a damaged
download became the root file system of the node.

After the download, xcatroot fetches the .sha256 file next to the image
and compares it with sha256sum. It also fetches that file before each
download. A download passes when it matches a line of either file, so a
download that began before packimage replaced the image still passes.
The check can fail for any reason, such as a missing checksum file or a
missing sha256sum. xcatroot then removes the download, logs the reason,
waits, and downloads the image again. A file that an earlier attempt
left is checked like a new download. xcatroot checks only when the
kernel argument rootimgchecksum=yes asks for it, and logs when it does
not check. An older xCAT server never passes the argument, so a new
initial ramdisk boots from it unchecked, as before.

The change covers the stateless modules of dracut 033, 047 and 105 for
the Red Hat family, dracut 033 for SUSE, and the Ubuntu module. These
modules also download statelite ramdisk images. Their initial ramdisks
now include sha256sum.
2026-10-13 15:29:21 -03:00
Vinícius Ferrão a4ac441a5d test(statelite): cover the ramdisk archive that liteimg publishes
liteimg must take the image lock and keep the previous archive while it
packs and after a failed pack. It must publish the new archive with its
checksum, also when the check is turned off. It must change nothing
while the lock is held. With --tracker, it must name the given tracker
URL and describe the new archive under its final name.
2026-10-13 15:29:21 -03:00
Vinícius Ferrão 883549fea2 feat(statelite): publish the liteimg ramdisk archive with its checksum
liteimg deleted rootimg-statelite.gz before it packed a statelite
ramdisk image, and wrote the new archive in place. It ignored a failed
pack, so nodes could get no image or a partial one. It took no image
lock. --tracker took no value, so the metainfo named the tracker 1, and
it described rootimg.gz instead of the new archive.

liteimg now takes the image lock and packs into the temporary directory
that packimage uses. It fails when a command of the pack fails. It
writes the SHA-256 checksum, and publishes it with the archive through
publish_rootimg. --tracker takes the tracker URL, as it does for
packimage, and the metainfo describes the new archive. Nodes keep
downloading the previous archive until the new one replaces it.
2026-10-13 15:29:21 -03:00
Vinícius Ferrão a22f848e8e test(imgport): cover the publication of an imported root image
An import of a cpio, tar or squashfs root image over a published image
must take the image lock that packimage takes. It must replace the
image, its checksum, the kernel and the ramdisk. It must keep the
previous image as .ORIG, remove the previous metainfo, keep other
formats, and leave no temporary directory. With the check turned off,
the import must still write the checksum. When the image lock is held,
the import must fail and keep the published image, checksum, kernel,
ramdisk and image definition. When the publication lock of another host
is held, or the imported image or its checksum cannot be published, the
import must fail. The published image, checksum and metainfo must then
stay, with their kernel and ramdisk.
2026-10-13 15:29:21 -03:00
Vinícius Ferrão 529d25f96c feat(imgport): publish an imported root image the way packimage does
imgimport moved the published root image away, then moved the copy from
the bundle in. When the bundle was on another file system, that move was
a copy. Nodes could get no image or a partial one. The checksum that
packimage had published for the previous image also stayed.

imgimport now takes the image lock that genimage, packimage and rmimage
use. It stages the imported image and its checksum in the image
directory. It publishes both with the packimage helper, under the same
publication lock. It writes the checksum whatever the rootimgchecksum
attribute of the imported image, as packimage does. The previous image
stays as .ORIG through a hard link, and its metainfo is removed.

imgimport also places the root image before the kernel and ramdisk now.
When it cannot publish the root image, it stops, so the kernel and
ramdisk keep matching the published image. It takes the image lock
before it imports the image definition, so an import that another image
command blocks changes nothing.
2026-10-13 15:29:20 -03:00
Vinícius Ferrão 63470e4fe0 test(packimage): cover the checksum of the root image archive
Each packed format must publish the SHA-256 checksum of the new archive
next to it, readable by nodes. The checksums of other formats must stay,
for nodes that already download them. A pack that fails while it
compresses, lists or reads the files must keep the previous checksum. A
pack must publish the checksum also when the image and the site turn the
check off. An image that turns the check on overrides the site, and 'no'
and '0' both turn it off.

While the archive is replaced, the checksum file must list the new and
the previous archive, also one packed before the check. The previous
metainfo must be gone by then. Then the checksum file must list only the
new archive. A failed rename of the checksum list, the archive or the
metainfo must leave the previous archive, checksum and metainfo, also
without hard links. When the previous archive can be neither linked nor
copied, nothing must change. A copy under umask 0077 must keep the mode
of the previous archive. A checksum file that keeps the previous line
must not fail the publication. A pack whose previous metainfo cannot be
moved aside must keep the previous archive and checksum. A previous
archive that cannot be put back must be kept outside the staging
directory, with its metainfo and checksum.
2026-10-13 15:29:20 -03:00
Vinícius Ferrão 6660ca7a06 feat(packimage): publish the SHA-256 checksum of the root image archive
A node could not tell a damaged root image download from a good one,
because packimage published nothing to check it against.

packimage now writes rootimg.<suffix>.sha256 in sha256sum format next to
the archive. It builds the checksum in the temporary directory with the
archive, and publish_rootimg publishes both under the publication lock.
A pack that fails before publication keeps the previous archive and
checksum. When packimage removes the other formats, it keeps their
checksums, so a node that already downloads one can still check it.

Until the archive is replaced, the checksum file lists the new and the
previous archive. publish_rootimg computes the line of a previous
archive that has none. The published archive then matches a line of it
at each step, also when the publisher is killed. The previous metainfo
leaves first, so it never describes the new archive. publish_rootimg
keeps a link to the previous archive, or a copy with its mode without
hard links. When a step fails, the previous archive, checksum and
metainfo stay or come back. When it can keep the previous archive in
neither way, it publishes nothing. When it cannot put the previous
archive back, it keeps it in a .rootimg-previous-* directory and names
that directory in the error.

The new site.rootimgchecksum attribute is yes by default, and the
rootimgchecksum attribute of an osimage overrides it. They tell nodeset
whether nodes check the archive. packimage publishes the checksum
whatever their value, because nodes with older boot entries can still
check.
2026-10-13 15:29:20 -03:00
Vinícius Ferrão bc69dedf64 refactor(packimage): move root image staging and publication to SvrUtils
imgimport must replace a root image the way packimage does. Move the
host-scoped temporary directory and the locked publication from
packimage to xCAT::SvrUtils, so both commands can share them. The
publication still covers the archive and its metainfo. The behavior of
packimage does not change.
2026-10-13 12:00:11 -03:00
Vinícius Ferrão 27e01fbd74 test(packimage): match the held publication lock by holder and recovery
The publication lock moves to a helper that imgimport also uses, and its
message will name both commands. Match the holder and the recovery step
of the message instead of the command name.

The test also made publication fail with a directory in place of the
previous metainfo. Publication will move that metainfo aside, which
works for a directory. Make rename and unlink of that path fail instead.
2026-10-13 12:00:11 -03:00
Daniel Hilst be9c063981 Merge pull request #7913 from VersatusHPC/test/r26-ubuntu-image-behavior
test(ubuntu): exercise media imports and genimage behavior
2026-10-13 11:21:29 -03:00
Daniel Hilst ba6d3c15a9 Merge pull request #7905 from VersatusHPC/test/r26-ddns-policy-behavior
test(ddns): verify key-file behavior instead of source layout
2026-10-13 10:58:11 -03:00
Daniel Hilst d1f63dfc25 Merge pull request #7925 from VersatusHPC/test/r26-genesis-behavior
test(genesis): exercise startup and OpenEmbedded build contracts
2026-10-13 10:16:23 -03:00
Daniel Hilst abf0f2228f Merge pull request #7935 from VersatusHPC/refactor/r26-package-lifecycle
refactor(packaging): share package lifecycle helpers
2026-10-13 10:00:14 -03:00
Vinícius Ferrão 105069634d docs(test): describe Genesis test boundaries 2026-10-12 15:56:25 -03:00
Vinícius Ferrão 54ce837c6f test(genesis): evaluate OpenEmbedded build contracts 2026-10-12 15:56:25 -03:00
Vinícius Ferrão 5408e25a54 test(genesis): run secondary DHCP cases through startup 2026-10-12 15:56:25 -03:00
Vinícius Ferrão 6a0629571c test(ddns): verify key-file behavior instead of source layout
Remove source-pattern and helper-call counts. Check key-file creation and
replacement through the real DDNS code, with file access redirected to a
temporary fixture. Keep the signing and named configuration checks.
2026-10-12 15:07:57 -03:00
Vinícius Ferrão 4a202f1b52 test(genesis): exercise InfiniBand startup through doxcat 2026-10-12 15:07:00 -03:00
Vinícius Ferrão b2a73685fb docs(test): document Ubuntu image fixture boundaries
Describe the native test prerequisites, external command doubles and the image-building behavior these fixtures do not qualify.
2026-10-12 13:58:45 -03:00
Vinícius Ferrão 320a1a1299 test(ubuntu): inspect resolver files in generated initrds
Run the unchanged initrd builder with fixture binaries and inspect both generated archives. Replace source extraction with checks for selected libraries and their contents.
2026-10-12 13:58:45 -03:00
Vinícius Ferrão a4e14299ee test(ubuntu): exercise genimage mirror selection
Read site settings from an isolated database and inspect the sources.list written into the image. Stop at an injected package-metadata failure without downloading packages.
2026-10-12 13:58:45 -03:00
Vinícius Ferrão 5013f85774 test(ubuntu): check debootstrap architecture arguments
Run genimage and inspect the arguments passed to debootstrap instead of evaluating an extracted assignment. Keep the existing ppc64le pass-through explicit.
2026-10-12 13:58:45 -03:00
Vinícius Ferrão 114efc35e1 test(ubuntu): exercise live-media imports and warnings
Replace source-text assertions with real media imports in an isolated filesystem and database. Run the native fixture before the package build in CI.
2026-10-12 13:58:32 -03:00
Daniel Hilst 495bb36db9 Merge pull request #7930 from VersatusHPC/fix/packimage-atomic-archive
fix(packimage): replace the root image archive only after a complete pack
2026-10-12 13:36:30 -03:00