@@ -222,10 +222,9 @@ proc::print_help_and_exit() {
222222 echo " Usage:"
223223 echo " $0 --in <input_file> --out <output_file> --config-dir <cryptpilot_config_dir> --rootfs-passphrase <rootfs_encrypt_passphrase> [--package <rpm_package>...]"
224224 echo " $0 --in <input_file> --out <output_file> --config-dir <cryptpilot_config_dir> --rootfs-no-encryption [--package <rpm_package>...]"
225- echo " $0 --device <device> --config-dir <cryptpilot_config_dir> --rootfs-passphrase <rootfs_encrypt_passphrase> [--package <rpm_package>...]"
226225 echo " "
227226 echo " Options:"
228- echo " -d, --device <device> The device to operate on ."
227+ echo " -d, --device <device> Deprecated: operating on devices is no longer supported. Use --in/--out instead ."
229228 echo " --in <input_file> The input OS image file (vhd or qcow2)."
230229 echo " --out <output_file> The output OS image file (vhd or qcow2)."
231230 echo " -c, --config-dir <cryptpilot_config_dir> The directory containing cryptpilot configuration files."
@@ -237,7 +236,6 @@ proc::print_help_and_exit() {
237236 echo " --package <rpm_package> Specify an RPM package name or path to the RPM file to install in to the disk before"
238237 echo " -b, --boot_part_size <size> Instead of using the default partition size(512MB), specify the size of the boot partition"
239238 echo " converting. This can be specified multiple times."
240- echo " --wipe-freed-space Wipe the freed space with zero, so that the qemu-img convert would generate smaller image"
241239 echo " --uki Generate a Unified Kernel Image image and boot from it instead of boot with GRUB"
242240 echo " --uki-append-cmdline <cmdline> Append custom command line parameters when generating a UKI image. By default, only essential"
243241 echo " parameters are included. This option allows you to extend the kernel command line. The default"
@@ -1126,10 +1124,9 @@ EOF
11261124
11271125 }
11281126
1129- if [ " ${operate_on_device} " = false ]; then
1130- # File mode: mount rootfs from source-write, EFI/boot from output
1131- local rootfs_mount_point=" ${workdir} /rootfs"
1132- local source_write_rootfs_part=" ${source_write_device} p${source_rootfs_part_num} "
1127+ # File mode: mount rootfs from source-write, EFI/boot from output
1128+ local rootfs_mount_point=" ${workdir} /rootfs"
1129+ local source_write_rootfs_part=" ${source_write_device} p${source_rootfs_part_num} "
11331130
11341131 # Clear the read-only flag set by tune2fs during shrink, so we can mount rw for dracut
11351132 log::info " Clearing read-only flag on source-write rootfs"
@@ -1201,10 +1198,6 @@ EOF
12011198 fi
12021199 done
12031200 disk::umount_wait_busy " ${rootfs_mount_point} "
1204- else
1205- # Device mode: use run_in_chroot_mounts
1206- run_in_chroot_mounts " /dev/mapper/rootfs" " $efi_part " " $boot_file_path " update_initrd_inner " $uki " " $uki_append_cmdline "
1207- fi
12081201}
12091202
12101203step::shrink_rootfs () {
@@ -1244,19 +1237,6 @@ step::shrink_rootfs() {
12441237 echo " Block count: $after_shrink_block_count "
12451238 echo " Size in Bytes: $after_shrink_size_in_bytes "
12461239 echo " Size in Sector: $after_shrink_size_in_sector "
1247-
1248- if [ " ${wipe_freed_space} " = true ]; then
1249- log::info " Wipe rootfs partition on device ${before_shrink_size_in_bytes} bytes"
1250- dd status=progress if=/dev/zero of=" ${rootfs_orig_part} " count=" ${before_shrink_size_in_bytes} " iflag=count_bytes bs=64M
1251- fi
1252-
1253- # In file mode, do NOT delete the rootfs partition — we need it for dd from source-read.
1254- # In device mode, delete it to make room for LUKS/LVM.
1255- if [ " ${operate_on_device} " = true ]; then
1256- log::info " Deleting original rootfs partition"
1257- parted " $device " --script -- rm " ${rootfs_orig_part_num} "
1258- partprobe " $device "
1259- fi
12601240}
12611241
12621242step::prepare_output_and_snapshots () {
@@ -1399,13 +1379,8 @@ step::copy_partitions() {
13991379step::setup_rootfs_lv_with_encrypt () {
14001380 local rootfs_passphrase=$1
14011381
1402- if [ " ${operate_on_device} " = false ]; then
1403- local output_rootfs_part=" ${output_device} p${rootfs_orig_part_num} "
1404- local source_rootfs_part=" ${source_read_device} p${source_rootfs_part_num} "
1405- else
1406- local output_rootfs_part=" ${rootfs_orig_part} "
1407- local source_rootfs_part=" ${rootfs_read_device} "
1408- fi
1382+ local output_rootfs_part=" ${output_device} p${rootfs_orig_part_num} "
1383+ local source_rootfs_part=" ${source_read_device} p${source_rootfs_part_num} "
14091384
14101385 # LUKS directly on the target partition
14111386 log::info " Encrypting rootfs partition with LUKS2"
@@ -1429,13 +1404,8 @@ step::setup_rootfs_lv_with_encrypt() {
14291404}
14301405
14311406step::setup_rootfs_lv_without_encrypt () {
1432- if [ " ${operate_on_device} " = false ]; then
1433- local output_rootfs_part=" ${output_device} p${rootfs_orig_part_num} "
1434- local source_rootfs_part=" ${source_read_device} p${source_rootfs_part_num} "
1435- else
1436- local output_rootfs_part=" ${rootfs_orig_part} "
1437- local source_rootfs_part=" ${rootfs_read_device} "
1438- fi
1407+ local output_rootfs_part=" ${output_device} p${rootfs_orig_part_num} "
1408+ local source_rootfs_part=" ${source_read_device} p${source_rootfs_part_num} "
14391409
14401410 # Copy only the shrunk filesystem (partition may be larger than actual filesystem)
14411411 local fs_block_size fs_block_count rootfs_size
@@ -1447,11 +1417,7 @@ step::setup_rootfs_lv_without_encrypt() {
14471417}
14481418
14491419step::setup_rootfs_hash_lv () {
1450- if [ " ${operate_on_device} " = false ]; then
1451- local source_rootfs_part=" ${source_read_device} p${source_rootfs_part_num} "
1452- else
1453- local source_rootfs_part=" ${rootfs_read_device} "
1454- fi
1420+ local source_rootfs_part=" ${source_read_device} p${source_rootfs_part_num} "
14551421 local rootfs_hash_file_path=" ${workdir} /rootfs_hash.img"
14561422
14571423 # Calculate filesystem size for verity (partition may be larger than actual filesystem)
@@ -1468,19 +1434,8 @@ step::setup_rootfs_hash_lv() {
14681434 > " ${workdir} /rootfs_hash.roothash"
14691435 cat " ${workdir} /rootfs_hash.status"
14701436
1471- if [ " ${operate_on_device} " = true ]; then
1472- # Device mode: store hash in LVM partition inside the encrypted container
1473- local rootfs_hash_size_in_byte
1474- rootfs_hash_size_in_byte=$( stat --printf=" %s" " ${rootfs_hash_file_path} " )
1475- proc::hook_exit " [[ -e /dev/mapper/cryptpilot-rootfs_hash ]] && disk::dm_remove_all ${device} "
1476- proc::exec_subshell_flose_fds lvcreate -n rootfs_hash --size " ${rootfs_hash_size_in_byte} " B cryptpilot
1477- dd status=progress " if=${rootfs_hash_file_path} " of=/dev/mapper/cryptpilot-rootfs_hash bs=4M
1478- rm -f " ${rootfs_hash_file_path} "
1479- disk::dm_remove_all " ${device} "
1480- else
1481- # File mode: keep hash in workdir (will be included in initrd via --include)
1482- log::info " Verity hash file stored at ${rootfs_hash_file_path} "
1483- fi
1437+ # File mode: keep hash in workdir (will be included in initrd via --include)
1438+ log::info " Verity hash file stored at ${rootfs_hash_file_path} "
14841439
14851440 # Recording rootfs hash in metadata file
14861441 log::info " Generate metadata file"
@@ -1500,8 +1455,6 @@ main() {
15001455 exit 1
15011456 fi
15021457
1503- local operate_on_device
1504- local device
15051458 local input_file
15061459 local output_file
15071460 local config_dir
@@ -1518,14 +1471,13 @@ main() {
15181471 local rootfs_orig_part_num
15191472 local rootfs_orig_part_exist=false
15201473 local source_rootfs_part_num # Source partition number (unchanged; differs from output when boot partition is added)
1521- local wipe_freed_space=false
15221474 local uki=false
15231475 local uki_append_cmdline=" console=tty0 console=ttyS0,115200n8"
15241476
15251477 while [[ " $# " -gt 0 ]]; do
15261478 case $1 in
15271479 -d | --device)
1528- device= " $2 "
1480+ log::warn " --device is deprecated: operating on devices is no longer supported. Use --in/--out instead. "
15291481 shift 2
15301482 ;;
15311483 --in)
@@ -1561,7 +1513,7 @@ main() {
15611513 shift 2
15621514 ;;
15631515 --wipe-freed-space)
1564- wipe_freed_space=true
1516+ log::warn " --wipe-freed-space is deprecated: no longer needed with the new qcow2 overlay architecture "
15651517 shift 1
15661518 ;;
15671519 --uki)
@@ -1581,15 +1533,8 @@ main() {
15811533 esac
15821534 done
15831535
1584- if [ -n " ${device:- } " ]; then
1585- if [ -n " ${input_file:- } " ] || [ -n " ${output_file:- } " ]; then
1586- proc::fatal " Cannot specify both --device and --in/--out"
1587- fi
1588- operate_on_device=true
1589- elif [ -n " ${input_file:- } " ] && [ -n " ${output_file:- } " ]; then
1590- operate_on_device=false
1591- else
1592- proc::fatal " Must specify either --device or --in/--out"
1536+ if [ -z " ${input_file:- } " ] || [ -z " ${output_file:- } " ]; then
1537+ proc::fatal " Must specify both --in and --out"
15931538 fi
15941539
15951540 if [ -z " ${config_dir:- } " ]; then
@@ -1606,38 +1551,13 @@ main() {
16061551 proc::fatal " Must specify either --rootfs-passphrase or --rootfs-no-encryption"
16071552 fi
16081553
1609- if [ " ${operate_on_device} " = true ]; then
1610- if [ ! -b " ${device} " ]; then
1611- proc::fatal " Input device $device does not exist"
1612- fi
1613-
1614- # In a better way to notice user that the data on the device may be lost if the operation is failed or canceled.
1615- log::warn " This operation will overwrite data on the device ($device ), and may cause data loss if the operation is failed or canceled. Make sure you have create a backup of the data !!!"
1616- while true ; do
1617- read -r -p " Are you sure you want to continue? (y/n) " yn
1618- case $yn in
1619- [y]* )
1620- log::success " Starting to convert the disk ..."
1621- break
1622- ;;
1623- [n]* )
1624- log::info " Operation canceled."
1625- exit
1626- ;;
1627- * ) log::warn " Please answer 'y' or 'n'." ;;
1628- esac
1629- done
1630- elif [ " ${operate_on_device} " = false ]; then
1631- if [ ! -f " $input_file " ]; then
1632- proc::fatal " Input file $input_file does not exist"
1633- fi
1554+ if [ ! -f " $input_file " ]; then
1555+ proc::fatal " Input file $input_file does not exist"
1556+ fi
16341557
1635- # Check if the input file is a vhd or qcow2
1636- if [[ " $input_file " != * .vhd ]] && [[ " $input_file " != * .qcow2 ]] && [[ " $input_file " != * .img ]]; then
1637- proc::fatal " Input file $input_file is not supported, should be a vhd or qcow2 file"
1638- fi
1639- else
1640- proc::print_help_and_exit 1
1558+ # Check if the input file is a vhd or qcow2
1559+ if [[ " $input_file " != * .vhd ]] && [[ " $input_file " != * .qcow2 ]] && [[ " $input_file " != * .img ]]; then
1560+ proc::fatal " Input file $input_file is not supported, should be a vhd, qcow2, or img file"
16411561 fi
16421562
16431563 log::setup_log_file
@@ -1672,48 +1592,44 @@ main() {
16721592 #
16731593 log::step " [ 1 ] Prepare disk"
16741594
1675- if [ " $operate_on_device " = true ]; then
1676- log::info " Using device: $device "
1677- else
1678- log::info " Using input file: $input_file "
1679- qemu-img info " ${input_file} "
1680-
1681- # Clean up any leftover overlay files from previous runs
1682- for overlay_file in " ${input_file} .source-mod" " ${input_file} .source-read" " ${input_file} .source-write" ; do
1683- if [ -f " ${overlay_file} " ]; then
1684- log::warn " Temporary file ${overlay_file} already exists from a previous run, deleting it"
1685- rm -f " ${overlay_file} "
1686- fi
1687- done
1595+ log::info " Using input file: $input_file "
1596+ qemu-img info " ${input_file} "
16881597
1689- # Try to detect input file format
1690- local input_format
1691- input_format=$( qemu-img info " ${input_file} " | grep ' ^file format:' | awk ' {print $3}' )
1692-
1693- # Create source-mod overlay: all modifications (yum, grub, shrink) go here
1694- source_mod_file=" ${input_file} .source-mod"
1695- proc::hook_exit " rm -f ${source_mod_file} "
1696- qemu-img create -f qcow2 -b " ${input_file} " -F " ${input_format} " " ${source_mod_file} " > /dev/null
1697- log::info " Created source-mod overlay: ${source_mod_file} "
1698-
1699- # Create output file upfront (same virtual size as input)
1700- local virtual_size_bytes
1701- virtual_size_bytes=$( qemu-img info --output=json " ${input_file} " | grep ' "virtual-size"' | grep -o ' [0-9]\+' )
1702- qemu-img create -f qcow2 -o size=" ${virtual_size_bytes} " " ${output_file} " > /dev/null
1703- log::info " Created output file: ${output_file} (virtual size: ${virtual_size_bytes} bytes)"
1704-
1705- # Allocate and connect NBD devices one at a time
1706- disk::nbd_connect " ${source_mod_file} " source_mod_device --discard=on --detect-zeroes=unmap
1707- log::info " Mapped source-mod to NBD device ${source_mod_device} :"
1708- fdisk -l " ${source_mod_device} "
1709-
1710- disk::nbd_connect " ${output_file} " output_device --discard=on --detect-zeroes=unmap
1711- log::info " Mapped output to NBD device ${output_device} :"
1712- fdisk -l " ${output_device} "
1713-
1714- # For backward compatibility in partition detection functions, alias device to source_mod_device
1715- device=" ${source_mod_device} "
1716- fi
1598+ # Clean up any leftover overlay files from previous runs
1599+ for overlay_file in " ${input_file} .source-mod" " ${input_file} .source-read" " ${input_file} .source-write" ; do
1600+ if [ -f " ${overlay_file} " ]; then
1601+ log::warn " Temporary file ${overlay_file} already exists from a previous run, deleting it"
1602+ rm -f " ${overlay_file} "
1603+ fi
1604+ done
1605+
1606+ # Try to detect input file format
1607+ local input_format
1608+ input_format=$( qemu-img info " ${input_file} " | grep ' ^file format:' | awk ' {print $3}' )
1609+
1610+ # Create source-mod overlay: all modifications (yum, grub, shrink) go here
1611+ source_mod_file=" ${input_file} .source-mod"
1612+ proc::hook_exit " rm -f ${source_mod_file} "
1613+ qemu-img create -f qcow2 -b " ${input_file} " -F " ${input_format} " " ${source_mod_file} " > /dev/null
1614+ log::info " Created source-mod overlay: ${source_mod_file} "
1615+
1616+ # Create output file upfront (same virtual size as input)
1617+ local virtual_size_bytes
1618+ virtual_size_bytes=$( qemu-img info --output=json " ${input_file} " | grep ' "virtual-size"' | grep -o ' [0-9]\+' )
1619+ qemu-img create -f qcow2 -o size=" ${virtual_size_bytes} " " ${output_file} " > /dev/null
1620+ log::info " Created output file: ${output_file} (virtual size: ${virtual_size_bytes} bytes)"
1621+
1622+ # Allocate and connect NBD devices one at a time
1623+ disk::nbd_connect " ${source_mod_file} " source_mod_device --discard=on --detect-zeroes=unmap
1624+ log::info " Mapped source-mod to NBD device ${source_mod_device} :"
1625+ fdisk -l " ${source_mod_device} "
1626+
1627+ disk::nbd_connect " ${output_file} " output_device --discard=on --detect-zeroes=unmap
1628+ log::info " Mapped output to NBD device ${output_device} :"
1629+ fdisk -l " ${output_device} "
1630+
1631+ # Alias device to source_mod_device for backward compatibility with partition detection functions
1632+ device=" ${source_mod_device} "
17171633
17181634 disk::assert_disk_not_busy " ${device} "
17191635
@@ -1770,37 +1686,21 @@ main() {
17701686 #
17711687 # 5. Preparing output file and snapshots
17721688 #
1773- if [ " ${operate_on_device} " = false ]; then
1774- # File-based mode: use qcow2 overlays
1775- log::step " [ 5 ] Preparing output file and snapshots"
1776- step::prepare_output_and_snapshots
1777- else
1778- # Device mode: create read-only loop device on source partition
1779- # as a replacement for rootfs.img
1780- log::step " [ 5 ] Creating read-only snapshot of source partition"
1781- rootfs_read_device=$( losetup -r --sizelimit " ${after_shrink_size_in_bytes} " --show -f " ${rootfs_orig_part} " )
1782- log::info " Created read-only loop device: ${rootfs_read_device} "
1783- proc::hook_exit " losetup -d ${rootfs_read_device} 2>/dev/null || true"
1784- fi
1689+ log::step " [ 5 ] Preparing output file and snapshots"
1690+ step::prepare_output_and_snapshots
17851691
17861692 #
17871693 # 6. Copying EFI and boot partitions
17881694 #
17891695 log::step " [ 6 ] Copying EFI and boot partitions"
1790- if [ " ${operate_on_device} " = false ]; then
1791- step::copy_partitions
1792- fi
1696+ step::copy_partitions
17931697
17941698 #
17951699 # 7. Setting up rootfs logical volume
17961700 #
17971701 log::step " [ 7 ] Setting up rootfs logical volume"
17981702 if [ " ${rootfs_no_encryption} " = false ]; then
1799- if [ " ${operate_on_device} " = false ]; then
1800- step::setup_rootfs_lv_with_encrypt " ${rootfs_passphrase} "
1801- else
1802- step::setup_rootfs_lv_with_encrypt " ${rootfs_passphrase} "
1803- fi
1703+ step::setup_rootfs_lv_with_encrypt " ${rootfs_passphrase} "
18041704 else
18051705 step::setup_rootfs_lv_without_encrypt
18061706 fi
@@ -1829,27 +1729,18 @@ main() {
18291729 # 10. Cleaning up
18301730 #
18311731 log::step " [ 10 ] Cleaning up"
1832- if [ " ${operate_on_device} " = true ]; then
1833- disk::dm_remove_all " ${device} "
1834- blockdev --flushbufs " ${device} "
1835- fi
18361732
1837- if [ " ${operate_on_device} " = true ]; then
1838- log::success " --------------------------------"
1839- log::success " Everything done, the device is ready to use: ${device} "
1840- else
1841- #
1842- # 11. Finalizing
1843- #
1844- log::step " [ 11 ] Finalizing"
1845- qemu-nbd -d " ${source_read_device} "
1846- qemu-nbd -d " ${source_write_device} "
1847- qemu-nbd -d " ${output_device} "
1848- sleep 2
1849-
1850- log::success " --------------------------------"
1851- log::success " Everything done, the new disk image is ready to use: ${output_file} "
1852- fi
1733+ #
1734+ # 11. Finalizing
1735+ #
1736+ log::step " [ 11 ] Finalizing"
1737+ qemu-nbd -d " ${source_read_device} "
1738+ qemu-nbd -d " ${source_write_device} "
1739+ qemu-nbd -d " ${output_device} "
1740+ sleep 2
1741+
1742+ log::success " --------------------------------"
1743+ log::success " Everything done, the new disk image is ready to use: ${output_file} "
18531744
18541745 echo
18551746 log::info " You can calculate reference value of the disk with:"
0 commit comments