Skip to content

Commit e074a41

Browse files
authored
install: Move /var mount test to TMT to reduce disk usage (#1910)
The "install to-filesystem with separate /var mount" test was causing disk space issues on GitHub Actions runners due to its large disk image requirements (12GB for partitions with LVM). Moving it to a TMT test allows it to run in a dedicated VM where disk space is not as constrained. The test verifies that bootc install to-filesystem correctly handles scenarios where /var is on a separate filesystem, which is a common production setup. Changes: - Remove the test from Rust integration tests (install.rs) - Add new TMT test: test-32-install-to-filesystem-var-mount.sh - Add package requirements (parted, lvm2, dosfstools, e2fsprogs) - Update tests.fmf and integration.fmf with new test entry Assisted-by: Claude Code (Opus 4.5) Signed-off-by: ckyrouac <ckyrouac@redhat.com>
1 parent 3b0f38a commit e074a41

4 files changed

Lines changed: 170 additions & 147 deletions

File tree

crates/tests-integration/src/install.rs

Lines changed: 0 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -93,153 +93,6 @@ pub(crate) fn run_alongside(image: &str, mut testargs: libtest_mimic::Arguments)
9393
cmd!(sh, "sudo {BASE_ARGS...} -v {tmpdisk}:/disk {image} bootc install to-disk --via-loopback /disk").run()?;
9494
Ok(())
9595
}),
96-
Trial::test(
97-
"install to-filesystem with separate /var mount",
98-
move || {
99-
let sh = &xshell::Shell::new()?;
100-
reset_root(sh, image)?;
101-
102-
// Clean up any leftover LVM state from previous failed runs
103-
let _ = cmd!(sh, "sudo vgchange -an BL").ignore_status().run();
104-
let _ = cmd!(sh, "sudo vgremove -f BL").ignore_status().run();
105-
106-
// Create work directory for the test
107-
let tmpd = sh.create_temp_dir()?;
108-
let work_dir = tmpd.path();
109-
110-
// Create a disk image with partitions for root and var
111-
let disk_img = work_dir.join("disk.img");
112-
let size = 1024 * 1024 * 1024; // 1 GiB
113-
let disk_file = std::fs::File::create(&disk_img)?;
114-
disk_file.set_len(size)?;
115-
drop(disk_file);
116-
117-
// Setup loop device
118-
let loop_dev = cmd!(sh, "sudo losetup -f --show {disk_img}")
119-
.read()?
120-
.trim()
121-
.to_string();
122-
123-
// Helper closure for cleanup
124-
let cleanup = |sh: &Shell, loop_dev: &str, target: &str| {
125-
// Unmount filesystems
126-
let _ = cmd!(sh, "sudo umount -R {target}").ignore_status().run();
127-
// Deactivate LVM
128-
let _ = cmd!(sh, "sudo vgchange -an BL").ignore_status().run();
129-
let _ = cmd!(sh, "sudo vgremove -f BL").ignore_status().run();
130-
// Detach loop device
131-
let _ = cmd!(sh, "sudo losetup -d {loop_dev}").ignore_status().run();
132-
};
133-
134-
// Create partition table
135-
if let Err(e) = (|| -> Result<()> {
136-
cmd!(sh, "sudo parted -s {loop_dev} mklabel gpt").run()?;
137-
// Create BIOS boot partition (for GRUB on GPT)
138-
cmd!(sh, "sudo parted -s {loop_dev} mkpart primary 1MiB 2MiB").run()?;
139-
cmd!(sh, "sudo parted -s {loop_dev} set 1 bios_grub on").run()?;
140-
// Create EFI partition
141-
cmd!(
142-
sh,
143-
"sudo parted -s {loop_dev} mkpart primary fat32 2MiB 202MiB"
144-
)
145-
.run()?;
146-
cmd!(sh, "sudo parted -s {loop_dev} set 2 esp on").run()?;
147-
// Create boot partition
148-
cmd!(
149-
sh,
150-
"sudo parted -s {loop_dev} mkpart primary ext4 202MiB 1226MiB"
151-
)
152-
.run()?;
153-
// Create LVM partition
154-
cmd!(sh, "sudo parted -s {loop_dev} mkpart primary 1226MiB 100%").run()?;
155-
156-
// Reload partition table
157-
cmd!(sh, "sudo partprobe {loop_dev}").run()?;
158-
std::thread::sleep(std::time::Duration::from_secs(2));
159-
160-
let efi_part2 = format!("{}p2", loop_dev); // EFI
161-
let root_part3 = format!("{}p3", loop_dev); // Boot
162-
let loop_part4 = format!("{}p4", loop_dev); // LVM
163-
164-
// Create filesystems on boot partitions
165-
cmd!(sh, "sudo mkfs.vfat -F32 {efi_part2}").run()?;
166-
cmd!(sh, "sudo mkfs.ext4 -F {root_part3}").run()?;
167-
168-
// Setup LVM
169-
cmd!(sh, "sudo pvcreate {loop_part4}").run()?;
170-
cmd!(sh, "sudo vgcreate BL {loop_part4}").run()?;
171-
172-
// Create logical volumes
173-
cmd!(sh, "sudo lvcreate -L 100M -n var02 BL").run()?;
174-
cmd!(sh, "sudo lvcreate -L 100M -n root02 BL").run()?;
175-
176-
// Create filesystems on logical volumes
177-
cmd!(sh, "sudo mkfs.ext4 -F /dev/BL/var02").run()?;
178-
cmd!(sh, "sudo mkfs.ext4 -F /dev/BL/root02").run()?;
179-
180-
// Get UUIDs
181-
let root_uuid = cmd!(sh, "sudo blkid -s UUID -o value /dev/BL/root02")
182-
.read()?
183-
.trim()
184-
.to_string();
185-
let boot_uuid = cmd!(sh, "sudo blkid -s UUID -o value {efi_part2}")
186-
.read()?
187-
.trim()
188-
.to_string();
189-
190-
// Mount the partitions
191-
let target_dir = work_dir.join("target");
192-
std::fs::create_dir_all(&target_dir)?;
193-
let target = target_dir.to_str().unwrap();
194-
195-
cmd!(sh, "sudo mount /dev/BL/root02 {target}").run()?;
196-
cmd!(sh, "sudo mkdir -p {target}/boot").run()?;
197-
cmd!(sh, "sudo mount {root_part3} {target}/boot").run()?;
198-
cmd!(sh, "sudo mkdir -p {target}/boot/efi").run()?;
199-
cmd!(sh, "sudo mount {efi_part2} {target}/boot/efi").run()?;
200-
201-
// Create EFI directory structure with some files (simulating existing EFI content)
202-
// This tests that bootc correctly handles /boot/efi as a mount point
203-
cmd!(sh, "sudo mkdir -p {target}/boot/efi/EFI/fedora").run()?;
204-
cmd!(sh, "sudo touch {target}/boot/efi/EFI/fedora/shimx64.efi").run()?;
205-
cmd!(sh, "sudo touch {target}/boot/efi/EFI/fedora/grubx64.efi").run()?;
206-
207-
// Critical: Mount /var as a separate partition
208-
cmd!(sh, "sudo mkdir -p {target}/var").run()?;
209-
cmd!(sh, "sudo mount /dev/BL/var02 {target}/var").run()?;
210-
211-
// Run bootc install to-filesystem
212-
// This should succeed and handle the separate /var mount correctly
213-
// Mount the target at /target inside the container for simplicity
214-
cmd!(
215-
sh,
216-
"sudo {BASE_ARGS...} -v {target}:/target -v /dev:/dev {image} bootc install to-filesystem --karg=root=UUID={root_uuid} --root-mount-spec=UUID={root_uuid} --boot-mount-spec=UUID={boot_uuid} /target"
217-
)
218-
.run()?;
219-
220-
// Verify the installation succeeded
221-
// Check that bootc created the necessary files
222-
cmd!(sh, "sudo test -d {target}/ostree").run()?;
223-
cmd!(sh, "sudo test -d {target}/ostree/repo").run()?;
224-
// Verify bootloader was installed
225-
cmd!(sh, "sudo test -d {target}/boot/grub2").run()?;
226-
227-
Ok(())
228-
})() {
229-
let target = work_dir.join("target");
230-
let target_str = target.to_str().unwrap();
231-
cleanup(sh, &loop_dev, target_str);
232-
return Err(e.into());
233-
}
234-
235-
// Clean up on success
236-
let target = work_dir.join("target");
237-
let target_str = target.to_str().unwrap();
238-
cleanup(sh, &loop_dev, target_str);
239-
240-
Ok(())
241-
},
242-
),
24396
Trial::test(
24497
"replace=alongside with ssh keys and a karg, and SELinux disabled",
24598
move || {

tmt/plans/integration.fmf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ prepare:
1818
- expect
1919
- ansible-core
2020
- zstd
21+
# Required for test-32-install-to-filesystem-var-mount
22+
- parted
23+
- lvm2
24+
- dosfstools
25+
- e2fsprogs
2126
when: running_env != image_mode
2227
- how: shell
2328
order: 98
@@ -147,4 +152,11 @@ execute:
147152
how: fmf
148153
test:
149154
- /tmt/tests/tests/test-31-switch-to-unified
155+
156+
/plan-32-install-to-filesystem-var-mount:
157+
summary: Test bootc install to-filesystem with separate /var mount
158+
discover:
159+
how: fmf
160+
test:
161+
- /tmt/tests/tests/test-32-install-to-filesystem-var-mount
150162
# END GENERATED PLANS
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# number: 32
2+
# tmt:
3+
# summary: Test bootc install to-filesystem with separate /var mount
4+
# duration: 30m
5+
# require:
6+
# - parted
7+
# - lvm2
8+
# - dosfstools
9+
# - e2fsprogs
10+
#
11+
#!/bin/bash
12+
# Test bootc install to-filesystem with a pre-existing /var mount point.
13+
# This verifies that bootc correctly handles scenarios where /var is on a
14+
# separate filesystem, which is a common production setup for managing
15+
# persistent data separately from the OS.
16+
17+
set -xeuo pipefail
18+
19+
# Use a generic target image to test skew between the bootc binary doing
20+
# the install and the target image
21+
TARGET_IMAGE="docker://quay.io/centos-bootc/centos-bootc:stream10"
22+
23+
echo "Testing bootc install to-filesystem with separate /var mount"
24+
25+
# Disable SELinux enforcement for the install
26+
setenforce 0
27+
28+
# Enable usr-overlay to allow modifications
29+
bootc usr-overlay
30+
31+
# Install required packages (bootc images are immutable, so we need to install
32+
# after usr-overlay is enabled)
33+
dnf install -y parted lvm2 dosfstools e2fsprogs
34+
35+
# Mask off conflicting ostree state
36+
if test -d /sysroot/ostree; then
37+
mount --bind /usr/share/empty /sysroot/ostree
38+
fi
39+
rm -vrf /usr/lib/bootupd/updates
40+
rm -vrf /usr/lib/bootc/bound-images.d
41+
42+
# Create a 12GB sparse disk image in /var/tmp (not /tmp which may be tmpfs)
43+
DISK_IMG=/var/tmp/disk-var-mount-test.img
44+
truncate -s 12G "$DISK_IMG"
45+
46+
# Setup loop device
47+
LOOP_DEV=$(losetup -f --show "$DISK_IMG")
48+
echo "Using loop device: $LOOP_DEV"
49+
50+
# Cleanup function
51+
cleanup() {
52+
set +e
53+
echo "Cleaning up..."
54+
umount -R /var/mnt/target 2>/dev/null
55+
vgchange -an BL 2>/dev/null
56+
vgremove -f BL 2>/dev/null
57+
losetup -d "$LOOP_DEV" 2>/dev/null
58+
rm -f "$DISK_IMG" 2>/dev/null
59+
}
60+
trap cleanup EXIT
61+
62+
# Create partition table
63+
parted -s "$LOOP_DEV" mklabel gpt
64+
# BIOS boot partition (for GRUB on GPT)
65+
parted -s "$LOOP_DEV" mkpart primary 1MiB 2MiB
66+
parted -s "$LOOP_DEV" set 1 bios_grub on
67+
# EFI partition (200 MiB)
68+
parted -s "$LOOP_DEV" mkpart primary fat32 2MiB 202MiB
69+
parted -s "$LOOP_DEV" set 2 esp on
70+
# Boot partition (1 GiB)
71+
parted -s "$LOOP_DEV" mkpart primary ext4 202MiB 1226MiB
72+
# LVM partition (rest of disk)
73+
parted -s "$LOOP_DEV" mkpart primary 1226MiB 100%
74+
75+
# Reload partition table
76+
partprobe "$LOOP_DEV"
77+
sleep 2
78+
79+
# Partition device names
80+
EFI_PART="${LOOP_DEV}p2"
81+
BOOT_PART="${LOOP_DEV}p3"
82+
LVM_PART="${LOOP_DEV}p4"
83+
84+
# Create filesystems on boot partitions
85+
mkfs.vfat -F32 "$EFI_PART"
86+
mkfs.ext4 -F "$BOOT_PART"
87+
88+
# Setup LVM
89+
pvcreate "$LVM_PART"
90+
vgcreate BL "$LVM_PART"
91+
92+
# Create logical volumes
93+
lvcreate -L 4G -n var02 BL
94+
lvcreate -L 5G -n root02 BL
95+
96+
# Create filesystems on logical volumes
97+
mkfs.ext4 -F /dev/BL/var02
98+
mkfs.ext4 -F /dev/BL/root02
99+
100+
# Get UUIDs for bootc install
101+
ROOT_UUID=$(blkid -s UUID -o value /dev/BL/root02)
102+
BOOT_UUID=$(blkid -s UUID -o value "$EFI_PART")
103+
104+
# Mount the partitions
105+
mkdir -p /var/mnt/target
106+
mount /dev/BL/root02 /var/mnt/target
107+
mkdir -p /var/mnt/target/boot
108+
mount "$BOOT_PART" /var/mnt/target/boot
109+
mkdir -p /var/mnt/target/boot/efi
110+
mount "$EFI_PART" /var/mnt/target/boot/efi
111+
112+
# Create EFI directory structure with some files (simulating existing EFI content)
113+
mkdir -p /var/mnt/target/boot/efi/EFI/fedora
114+
touch /var/mnt/target/boot/efi/EFI/fedora/shimx64.efi
115+
touch /var/mnt/target/boot/efi/EFI/fedora/grubx64.efi
116+
117+
# Critical: Mount /var as a separate partition
118+
mkdir -p /var/mnt/target/var
119+
mount /dev/BL/var02 /var/mnt/target/var
120+
121+
echo "Filesystem layout:"
122+
mount | grep /var/mnt/target || true
123+
df -h /var/mnt/target /var/mnt/target/boot /var/mnt/target/boot/efi /var/mnt/target/var
124+
125+
# Run bootc install to-filesystem
126+
# This should succeed and handle the separate /var mount correctly
127+
podman run \
128+
--rm --privileged \
129+
-v /var/mnt/target:/target \
130+
-v /dev:/dev \
131+
--pid=host \
132+
--security-opt label=type:unconfined_t \
133+
"$TARGET_IMAGE" \
134+
bootc install to-filesystem \
135+
--disable-selinux \
136+
--karg=root=UUID="$ROOT_UUID" \
137+
--root-mount-spec=UUID="$ROOT_UUID" \
138+
--boot-mount-spec=UUID="$BOOT_UUID" \
139+
/target
140+
141+
# Verify the installation succeeded
142+
echo "Verifying installation..."
143+
test -d /var/mnt/target/ostree
144+
test -d /var/mnt/target/ostree/repo
145+
# Verify bootloader was installed (grub2 or loader for different configurations)
146+
test -d /var/mnt/target/boot/grub2 || test -d /var/mnt/target/boot/loader
147+
148+
echo "Installation to-filesystem with separate /var mount succeeded!"

tmt/tests/tests.fmf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,13 @@
7979
summary: Onboard to unified storage, build derived image, and switch to it
8080
duration: 30m
8181
test: nu booted/test-switch-to-unified.nu
82+
83+
/test-32-install-to-filesystem-var-mount:
84+
summary: Test bootc install to-filesystem with separate /var mount
85+
duration: 30m
86+
require:
87+
- parted
88+
- lvm2
89+
- dosfstools
90+
- e2fsprogs
91+
test: bash booted/test-install-to-filesystem-var-mount.sh

0 commit comments

Comments
 (0)