@@ -93,6 +93,143 @@ 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+ // Create work directory for the test
103+ let tmpd = sh. create_temp_dir ( ) ?;
104+ let work_dir = tmpd. path ( ) ;
105+
106+ // Create a disk image with partitions for root and var
107+ let disk_img = work_dir. join ( "disk.img" ) ;
108+ let size = 12 * 1024 * 1024 * 1024 ;
109+ let disk_file = std:: fs:: File :: create ( & disk_img) ?;
110+ disk_file. set_len ( size) ?;
111+ drop ( disk_file) ;
112+
113+ // Setup loop device
114+ let loop_dev = cmd ! ( sh, "sudo losetup -f --show {disk_img}" )
115+ . read ( ) ?
116+ . trim ( )
117+ . to_string ( ) ;
118+
119+ // Helper closure for cleanup
120+ let cleanup = |sh : & Shell , loop_dev : & str , target : & str | {
121+ // Unmount filesystems
122+ let _ = cmd ! ( sh, "sudo umount -R {target}" ) . ignore_status ( ) . run ( ) ;
123+ // Deactivate LVM
124+ let _ = cmd ! ( sh, "sudo vgchange -an BL" ) . ignore_status ( ) . run ( ) ;
125+ let _ = cmd ! ( sh, "sudo vgremove -f BL" ) . ignore_status ( ) . run ( ) ;
126+ // Detach loop device
127+ let _ = cmd ! ( sh, "sudo losetup -d {loop_dev}" ) . ignore_status ( ) . run ( ) ;
128+ } ;
129+
130+ // Create partition table
131+ if let Err ( e) = ( || -> Result < ( ) > {
132+ cmd ! ( sh, "sudo parted -s {loop_dev} mklabel gpt" ) . run ( ) ?;
133+ // Create BIOS boot partition (for GRUB on GPT)
134+ cmd ! ( sh, "sudo parted -s {loop_dev} mkpart primary 1MiB 2MiB" ) . run ( ) ?;
135+ cmd ! ( sh, "sudo parted -s {loop_dev} set 1 bios_grub on" ) . run ( ) ?;
136+ // Create EFI partition
137+ cmd ! (
138+ sh,
139+ "sudo parted -s {loop_dev} mkpart primary fat32 2MiB 202MiB"
140+ )
141+ . run ( ) ?;
142+ cmd ! ( sh, "sudo parted -s {loop_dev} set 2 esp on" ) . run ( ) ?;
143+ // Create boot partition
144+ cmd ! (
145+ sh,
146+ "sudo parted -s {loop_dev} mkpart primary ext4 202MiB 1226MiB"
147+ )
148+ . run ( ) ?;
149+ // Create LVM partition
150+ cmd ! ( sh, "sudo parted -s {loop_dev} mkpart primary 1226MiB 100%" ) . run ( ) ?;
151+
152+ // Reload partition table
153+ cmd ! ( sh, "sudo partprobe {loop_dev}" ) . run ( ) ?;
154+ std:: thread:: sleep ( std:: time:: Duration :: from_secs ( 2 ) ) ;
155+
156+ let loop_part2 = format ! ( "{}p2" , loop_dev) ; // EFI
157+ let loop_part3 = format ! ( "{}p3" , loop_dev) ; // Boot
158+ let loop_part4 = format ! ( "{}p4" , loop_dev) ; // LVM
159+
160+ // Create filesystems on boot partitions
161+ cmd ! ( sh, "sudo mkfs.vfat -F32 {loop_part2}" ) . run ( ) ?;
162+ cmd ! ( sh, "sudo mkfs.ext4 -F {loop_part3}" ) . run ( ) ?;
163+
164+ // Setup LVM
165+ cmd ! ( sh, "sudo pvcreate {loop_part4}" ) . run ( ) ?;
166+ cmd ! ( sh, "sudo vgcreate BL {loop_part4}" ) . run ( ) ?;
167+
168+ // Create logical volumes
169+ cmd ! ( sh, "sudo lvcreate -L 4G -n var02 BL" ) . run ( ) ?;
170+ cmd ! ( sh, "sudo lvcreate -L 5G -n root02 BL" ) . run ( ) ?;
171+
172+ // Create filesystems on logical volumes
173+ cmd ! ( sh, "sudo mkfs.ext4 -F /dev/BL/var02" ) . run ( ) ?;
174+ cmd ! ( sh, "sudo mkfs.ext4 -F /dev/BL/root02" ) . run ( ) ?;
175+
176+ // Get UUIDs
177+ let root_uuid = cmd ! ( sh, "sudo blkid -s UUID -o value /dev/BL/root02" )
178+ . read ( ) ?
179+ . trim ( )
180+ . to_string ( ) ;
181+ let boot_uuid = cmd ! ( sh, "sudo blkid -s UUID -o value {loop_part2}" )
182+ . read ( ) ?
183+ . trim ( )
184+ . to_string ( ) ;
185+
186+ // Mount the partitions
187+ let target_dir = work_dir. join ( "target" ) ;
188+ std:: fs:: create_dir_all ( & target_dir) ?;
189+ let target = target_dir. to_str ( ) . unwrap ( ) ;
190+
191+ cmd ! ( sh, "sudo mount /dev/BL/root02 {target}" ) . run ( ) ?;
192+ cmd ! ( sh, "sudo mkdir -p {target}/boot" ) . run ( ) ?;
193+ cmd ! ( sh, "sudo mount {loop_part3} {target}/boot" ) . run ( ) ?;
194+ cmd ! ( sh, "sudo mkdir -p {target}/boot/efi" ) . run ( ) ?;
195+ cmd ! ( sh, "sudo mount {loop_part2} {target}/boot/efi" ) . run ( ) ?;
196+
197+ // Critical: Mount /var as a separate partition
198+ cmd ! ( sh, "sudo mkdir -p {target}/var" ) . run ( ) ?;
199+ cmd ! ( sh, "sudo mount /dev/BL/var02 {target}/var" ) . run ( ) ?;
200+
201+ // Run bootc install to-filesystem
202+ // This should succeed and handle the separate /var mount correctly
203+ // Mount the target at /target inside the container for simplicity
204+ cmd ! (
205+ sh,
206+ "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"
207+ )
208+ . run ( ) ?;
209+
210+ // Verify the installation succeeded
211+ // Check that bootc created the necessary files
212+ cmd ! ( sh, "sudo test -d {target}/ostree" ) . run ( ) ?;
213+ cmd ! ( sh, "sudo test -d {target}/ostree/repo" ) . run ( ) ?;
214+ // Verify bootloader was installed
215+ cmd ! ( sh, "sudo test -d {target}/boot/grub2" ) . run ( ) ?;
216+
217+ Ok ( ( ) )
218+ } ) ( ) {
219+ let target = work_dir. join ( "target" ) ;
220+ let target_str = target. to_str ( ) . unwrap ( ) ;
221+ cleanup ( sh, & loop_dev, target_str) ;
222+ return Err ( e. into ( ) ) ;
223+ }
224+
225+ // Clean up on success
226+ let target = work_dir. join ( "target" ) ;
227+ let target_str = target. to_str ( ) . unwrap ( ) ;
228+ cleanup ( sh, & loop_dev, target_str) ;
229+
230+ Ok ( ( ) )
231+ } ,
232+ ) ,
96233 Trial :: test (
97234 "replace=alongside with ssh keys and a karg, and SELinux disabled" ,
98235 move || {
0 commit comments