From d100d303f648130c7abfd6bce2c820c578f8dd38 Mon Sep 17 00:00:00 2001 From: AlmaLinux RelEng Bot Date: Tue, 14 Apr 2026 05:59:58 -0400 Subject: [PATCH] import CS guestfs-tools-1.54.0-9.el10 --- .gitignore | 2 +- ...e-note-about-GNU-gettext-to-build-se.patch | 34 + ...pdate-link-to-templates-to-use-https.patch | 23 + ...ace-cpu-host-with-cpu-max-in-example.patch | 32 + ...ze-Implement-inject-blnsvr-operation.patch | 222 ---- 0004-Update-common-submodule.patch | 344 ------ ...for-selinux-relabelling-and-Windows-.patch | 143 +++ 0005-Update-common-submodule.patch | 139 ++- 0006-.gitignore-Ignore-.bak-files.patch | 22 + ...Use-quoted-string-literals-in-a-few-.patch | 206 ++++ ...mplates-make-template.ml-Fix-quoting.patch | 26 + ...s-make-template.ml-Use-quoted-string.patch | 33 + ...s-make-template.ml-Add-str-and-unix-.patch | 43 + ...-Use-power-of-2-for-initial-size-of-.patch | 76 ++ 0012-builder-Build-fedora-42-template.patch | 123 ++ 0013-Update-common-submodule.patch | 61 + 0014-common-update-submodule.patch | 427 +++++++ 0015-pod-Document-removal-of-sm-options.patch | 150 +++ ...guests-Increase-size-of-Windows-imag.patch | 31 + ...w-class-field-to-output-of-virt-insp.patch | 72 ++ ...ndows_group_policy-is-Windows-GPOs-d.patch | 52 + ...of-libguestfs-winsupport-features-ex.patch | 6 +- ...-builder-Disable-opensuse-repository.patch | 2 +- ...s-try-to-find-and-print-the-filesyst.patch | 139 +++ ...ome-entries-in-.gitignore-into-order.patch | 35 + ...NULL-as-a-convenient-list-terminator.patch | 35 + ...stems-virt-log-virt-ls-virt-tail-to-.patch | 1032 +++++++++++++++++ ...ptionally-display-filesystem-version.patch | 473 ++++++++ copy-patches.sh | 2 +- guestfs-tools-1.52.1.tar.gz.sig | 17 - guestfs-tools-1.54.0.tar.gz.sig | 17 + guestfs-tools.spec | 102 +- sources | 2 +- 33 files changed, 3466 insertions(+), 657 deletions(-) create mode 100644 0001-docs-Move-release-note-about-GNU-gettext-to-build-se.patch create mode 100644 0002-builder-Update-link-to-templates-to-use-https.patch create mode 100644 0003-builder-Replace-cpu-host-with-cpu-max-in-example.patch delete mode 100644 0003-customize-Implement-inject-blnsvr-operation.patch delete mode 100644 0004-Update-common-submodule.patch create mode 100644 0004-customize-Fixes-for-selinux-relabelling-and-Windows-.patch create mode 100644 0006-.gitignore-Ignore-.bak-files.patch create mode 100644 0007-builder-sysprep-Use-quoted-string-literals-in-a-few-.patch create mode 100644 0008-builder-templates-make-template.ml-Fix-quoting.patch create mode 100644 0009-builder-templates-make-template.ml-Use-quoted-string.patch create mode 100644 0010-builder-templates-make-template.ml-Add-str-and-unix-.patch create mode 100644 0011-daemon-generator-Use-power-of-2-for-initial-size-of-.patch create mode 100644 0012-builder-Build-fedora-42-template.patch create mode 100644 0013-Update-common-submodule.patch create mode 100644 0014-common-update-submodule.patch create mode 100644 0015-pod-Document-removal-of-sm-options.patch create mode 100644 0016-test-data-phony-guests-Increase-size-of-Windows-imag.patch create mode 100644 0017-inspector-Add-new-class-field-to-output-of-virt-insp.patch create mode 100644 0018-inspector-Add-windows_group_policy-is-Windows-GPOs-d.patch rename 0001-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch => 0019-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch (84%) rename 0002-RHEL-builder-Disable-opensuse-repository.patch => 0020-RHEL-builder-Disable-opensuse-repository.patch (94%) create mode 100644 0021-inspector-For-xfs-try-to-find-and-print-the-filesyst.patch create mode 100644 0022-Sort-some-entries-in-.gitignore-into-order.patch create mode 100644 0023-build-Add-NULL-as-a-convenient-list-terminator.patch create mode 100644 0024-Move-virt-filesystems-virt-log-virt-ls-virt-tail-to-.patch create mode 100644 0025-filesystems-Optionally-display-filesystem-version.patch delete mode 100644 guestfs-tools-1.52.1.tar.gz.sig create mode 100644 guestfs-tools-1.54.0.tar.gz.sig diff --git a/.gitignore b/.gitignore index c36e9c1..529d8a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -guestfs-tools-1.52.1.tar.gz +guestfs-tools-1.54.0.tar.gz libguestfs.keyring diff --git a/0001-docs-Move-release-note-about-GNU-gettext-to-build-se.patch b/0001-docs-Move-release-note-about-GNU-gettext-to-build-se.patch new file mode 100644 index 0000000..7cf17b4 --- /dev/null +++ b/0001-docs-Move-release-note-about-GNU-gettext-to-build-se.patch @@ -0,0 +1,34 @@ +From 3a99e87bdee6c20a6286aa3e10bb2c2d896fb2ed Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 21 May 2025 15:02:44 +0100 +Subject: [PATCH] docs: Move release note about GNU gettext to build section + +Fixes: commit 9b7410c220f1111e6acef88efbbaee3fea4019b8 +Updates: commit 80ce443e5eb7323e9b7b5cef30b8f7673ca51d67 +(cherry picked from commit bf4fef4f2b45a2016c42094f8e4fe18abc8d90e2) +--- + docs/guestfs-tools-release-notes-1.54.pod | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/docs/guestfs-tools-release-notes-1.54.pod b/docs/guestfs-tools-release-notes-1.54.pod +index b44eb19a2..ab9062303 100644 +--- a/docs/guestfs-tools-release-notes-1.54.pod ++++ b/docs/guestfs-tools-release-notes-1.54.pod +@@ -78,6 +78,8 @@ Some deprecated autoconf macros are no longer used. + + Fix some issues when building on macOS (Mohamed Akram). + ++Fix compatibility with GNU gettext 0.25. ++ + =head2 Internals + + The tests were modified to use a set of common functions and remove +@@ -87,8 +89,6 @@ nbdkit. + Some internal OCaml List and String functions that we used have been + replaced by ones from the OCaml stdlib, reducing code maintenance. + +-Fix compatibility with GNU gettext 0.25. +- + =head2 Bugs fixed + + =begin comment diff --git a/0002-builder-Update-link-to-templates-to-use-https.patch b/0002-builder-Update-link-to-templates-to-use-https.patch new file mode 100644 index 0000000..842b604 --- /dev/null +++ b/0002-builder-Update-link-to-templates-to-use-https.patch @@ -0,0 +1,23 @@ +From 2eae3778a32b18944a6a561e10a35eae74fa11f0 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 3 Jun 2025 08:29:57 +0100 +Subject: [PATCH] builder: Update link to templates to use https + +Fixes: https://issues.redhat.com/browse/RHEL-94873 +Reported-by: Xiang Hua Chen +(cherry picked from commit 5a2458f38d40e5c6f3eceb8e7de162724ff9e374) +--- + builder/libguestfs.conf.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/builder/libguestfs.conf.in b/builder/libguestfs.conf.in +index 8d8feab75..08b6a6234 100644 +--- a/builder/libguestfs.conf.in ++++ b/builder/libguestfs.conf.in +@@ -1,5 +1,5 @@ + [libguestfs.org] +-uri=http://builder.libguestfs.org/index.asc ++uri=https://builder.libguestfs.org/index.asc + gpgkey=file://@SYSCONFDIR@/virt-builder/repos.d/libguestfs.gpg + + [archive.libguestfs.org] diff --git a/0003-builder-Replace-cpu-host-with-cpu-max-in-example.patch b/0003-builder-Replace-cpu-host-with-cpu-max-in-example.patch new file mode 100644 index 0000000..01c4e2e --- /dev/null +++ b/0003-builder-Replace-cpu-host-with-cpu-max-in-example.patch @@ -0,0 +1,32 @@ +From b6401279c65497506eac2eaf61470bf6f49e89e7 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 16 Jun 2025 21:47:41 +0100 +Subject: [PATCH] builder: Replace -cpu host with -cpu max in example + +When KVM isn't present, some versions of qemu may print: + + qemu-system-x86_64: Could not access KVM kernel module: No such file or directory + qemu-system-x86_64: failed to initialize kvm: No such file or directory + qemu-system-x86_64: falling back to tcg + qemu-system-x86_64: CPU model 'host' requires KVM or HVF + +Use -cpu max instead which should work in both cases. + +(cherry picked from commit 2e93abca5acaa69cd6fd08b70079e8f432539076) +--- + builder/virt-builder.pod | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod +index 05bef1e05..ff0ec250c 100644 +--- a/builder/virt-builder.pod ++++ b/builder/virt-builder.pod +@@ -1043,7 +1043,7 @@ following could be used to boot the virtual machine: + + qemu-system-x86_64 \ + -machine accel=kvm:tcg \ +- -cpu host \ ++ -cpu max \ + -m 2048 \ + -drive file=disk.img,format=raw,if=virtio + diff --git a/0003-customize-Implement-inject-blnsvr-operation.patch b/0003-customize-Implement-inject-blnsvr-operation.patch deleted file mode 100644 index ff7ae18..0000000 --- a/0003-customize-Implement-inject-blnsvr-operation.patch +++ /dev/null @@ -1,222 +0,0 @@ -From 566e21933505606a64fe6e7c154ffb90209e7101 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 16 May 2024 12:49:24 +0100 -Subject: [PATCH] customize: Implement --inject-blnsvr operation - -Also updates the common submodule with the generated changes from -libguestfs, and the implementation of Inject_virtio_win.inject_blnsvr. - -(cherry picked from commit 80d258baa49214c8e59b91d6085595c9b989fc0d) ---- - common | 2 +- - customize/customize_run.ml | 13 +++++++++++-- - 2 files changed, 12 insertions(+), 3 deletions(-) - -Submodule common 93a7f3af5..830cbdcf4: -diff --git a/common/mlcustomize/customize-options.pod b/common/mlcustomize/customize-options.pod -index ff93630d8..b2ac57526 100644 ---- a/common/mlcustomize/customize-options.pod -+++ b/common/mlcustomize/customize-options.pod -@@ -193,6 +193,18 @@ L. - Set the hostname of the guest to C. You can use a - dotted hostname.domainname (FQDN) if you want. - -+=item B<--inject-blnsvr> METHOD -+ -+Inject the Balloon Server (F) into a Windows guest. -+This operation also injects a firstboot script so that the Balloon -+Server is installed when the guest boots. -+ -+The parameter is the same as used by the I<--inject-virtio-win> operation. -+ -+Note that to do a full conversion of a Windows guest from a -+foreign hypervisor like VMware (which involves many other operations) -+you should use the L tool instead of this. -+ - =item B<--inject-qemu-ga> METHOD - - Inject the QEMU Guest Agent into a Windows guest. The guest -diff --git a/common/mlcustomize/customize-synopsis.pod b/common/mlcustomize/customize-synopsis.pod -index bb0ce1255..957de8cf2 100644 ---- a/common/mlcustomize/customize-synopsis.pod -+++ b/common/mlcustomize/customize-synopsis.pod -@@ -3,16 +3,16 @@ - [--copy SOURCE:DEST] [--copy-in LOCALPATH:REMOTEDIR] - [--delete PATH] [--edit FILE:EXPR] [--firstboot SCRIPT] - [--firstboot-command 'CMD+ARGS'] [--firstboot-install PKG,PKG..] -- [--hostname HOSTNAME] [--inject-qemu-ga METHOD] -- [--inject-virtio-win METHOD] [--install PKG,PKG..] -- [--link TARGET:LINK[:LINK..]] [--mkdir DIR] [--move SOURCE:DEST] -- [--password USER:SELECTOR] [--root-password SELECTOR] -- [--run SCRIPT] [--run-command 'CMD+ARGS'] [--scrub FILE] -- [--sm-attach SELECTOR] [--sm-register] [--sm-remove] -- [--sm-unregister] [--ssh-inject USER[:SELECTOR]] -- [--tar-in TARFILE:REMOTEDIR] [--timezone TIMEZONE] [--touch FILE] -- [--truncate FILE] [--truncate-recursive PATH] -- [--uninstall PKG,PKG..] [--update] [--upload FILE:DEST] -- [--write FILE:CONTENT] [--no-logfile] -+ [--hostname HOSTNAME] [--inject-blnsvr METHOD] -+ [--inject-qemu-ga METHOD] [--inject-virtio-win METHOD] -+ [--install PKG,PKG..] [--link TARGET:LINK[:LINK..]] [--mkdir DIR] -+ [--move SOURCE:DEST] [--password USER:SELECTOR] -+ [--root-password SELECTOR] [--run SCRIPT] -+ [--run-command 'CMD+ARGS'] [--scrub FILE] [--sm-attach SELECTOR] -+ [--sm-register] [--sm-remove] [--sm-unregister] -+ [--ssh-inject USER[:SELECTOR]] [--tar-in TARFILE:REMOTEDIR] -+ [--timezone TIMEZONE] [--touch FILE] [--truncate FILE] -+ [--truncate-recursive PATH] [--uninstall PKG,PKG..] [--update] -+ [--upload FILE:DEST] [--write FILE:CONTENT] [--no-logfile] - [--password-crypto md5|sha256|sha512] [--no-selinux-relabel] - [--selinux-relabel] [--sm-credentials SELECTOR] -diff --git a/common/mlcustomize/customize_cmdline.ml b/common/mlcustomize/customize_cmdline.ml -index 48ee33445..c4d6a77d5 100644 ---- a/common/mlcustomize/customize_cmdline.ml -+++ b/common/mlcustomize/customize_cmdline.ml -@@ -61,6 +61,8 @@ and op = [ - (* --firstboot-install PKG,PKG.. *) - | `Hostname of string - (* --hostname HOSTNAME *) -+ | `InjectBalloonServer of string -+ (* --inject-blnsvr METHOD *) - | `InjectQemuGA of string - (* --inject-qemu-ga METHOD *) - | `InjectVirtioWin of string -@@ -286,6 +288,12 @@ let rec argspec () = - s_"Set the hostname" - ), - Some "HOSTNAME", "Set the hostname of the guest to C. You can use a\ndotted hostname.domainname (FQDN) if you want."; -+ ( -+ [ L"inject-blnsvr" ], -+ Getopt.String (s_"METHOD", fun s -> List.push_front (`InjectBalloonServer s) ops), -+ s_"Inject the Balloon Server into a Windows guest" -+ ), -+ Some "METHOD", "Inject the Balloon Server (F) into a Windows guest.\nThis operation also injects a firstboot script so that the Balloon\nServer is installed when the guest boots.\n\nThe parameter is the same as used by the I<--inject-virtio-win> operation.\n\nNote that to do a full conversion of a Windows guest from a\nforeign hypervisor like VMware (which involves many other operations)\nyou should use the L tool instead of this."; - ( - [ L"inject-qemu-ga" ], - Getopt.String (s_"METHOD", fun s -> List.push_front (`InjectQemuGA s) ops), -diff --git a/common/mlcustomize/customize_cmdline.mli b/common/mlcustomize/customize_cmdline.mli -index 51a156eae..ee62961a1 100644 ---- a/common/mlcustomize/customize_cmdline.mli -+++ b/common/mlcustomize/customize_cmdline.mli -@@ -53,6 +53,8 @@ and op = [ - (* --firstboot-install PKG,PKG.. *) - | `Hostname of string - (* --hostname HOSTNAME *) -+ | `InjectBalloonServer of string -+ (* --inject-blnsvr METHOD *) - | `InjectQemuGA of string - (* --inject-qemu-ga METHOD *) - | `InjectVirtioWin of string -diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml -index 2a30b2008..4e0ed0e0e 100644 ---- a/common/mlcustomize/inject_virtio_win.ml -+++ b/common/mlcustomize/inject_virtio_win.ml -@@ -24,6 +24,8 @@ open Common_gettext.Gettext - - open Regedit - -+let re_blnsvr = PCRE.compile ~caseless:true "\\bblnsvr\\.exe$" -+ - type t = { - g : Guestfs.guestfs; (** guestfs handle *) - -@@ -267,6 +269,18 @@ and inject_qemu_ga t = - configure_qemu_ga t msi_files; - msi_files <> [] (* return true if we found some qemu-ga MSI files *) - -+and inject_blnsvr t = -+ let files = copy_blnsvr t in -+ match files with -+ | [] -> false (* Didn't find or install anything. *) -+ -+ (* We usually find blnsvr.exe in two locations (drivers/by-os and -+ * drivers/by-driver). Pick the first. -+ *) -+ | blnsvr :: _ -> -+ configure_blnsvr t blnsvr; -+ true -+ - and add_guestor_to_registry t ((g, root) as reg) drv_name drv_pciid = - let ddb_node = g#hivex_node_get_child root "DriverDatabase" in - -@@ -351,6 +365,11 @@ and copy_qemu_ga t = - (fun () -> - error (f_"root directory ‘/’ is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log.")) - -+and copy_blnsvr t = -+ copy_from_virtio_win t "/" "/" (virtio_iso_path_matches_blnsvr t) -+ (fun () -> -+ error (f_"root directory ‘/’ is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log.")) -+ - (* Copy all files from virtio_win directory/ISO located in [srcdir] - * subdirectory and all its subdirectories to the [destdir]. The directory - * hierarchy is not preserved, meaning all files will be directly in [destdir]. -@@ -513,6 +532,10 @@ and virtio_iso_path_matches_qemu_ga t path = - | ("x86_64", "rhev-qga64.msi") -> true - | _ -> false - -+(* Find blnsvr for the current Windows version. *) -+and virtio_iso_path_matches_blnsvr t path = -+ virtio_iso_path_matches_guest_os t path && PCRE.matches re_blnsvr path -+ - (* Look up in libosinfo for the OS, and copy all the locally - * available files specified as drivers for that OS to the [destdir]. - * -@@ -586,3 +609,10 @@ and configure_qemu_ga t files = - Firstboot.add_firstboot_powershell t.g t.root - (sprintf "install-%s.ps1" msi_path) !psh_script; - ) files -+ -+and configure_blnsvr t blnsvr = -+ let cmd = sprintf "\ -+ @echo off\n\ -+ echo Installing %s\n\ -+ c:\\%s -i\n" blnsvr blnsvr in -+ Firstboot.add_firstboot_script t.g t.root (sprintf "install-%s" blnsvr) cmd -diff --git a/common/mlcustomize/inject_virtio_win.mli b/common/mlcustomize/inject_virtio_win.mli -index d14f04973..d273c4dd3 100644 ---- a/common/mlcustomize/inject_virtio_win.mli -+++ b/common/mlcustomize/inject_virtio_win.mli -@@ -93,3 +93,11 @@ val inject_qemu_ga : t -> bool - the MSI(s). - - Returns [true] iff we were able to inject qemu-ga. *) -+ -+val inject_blnsvr : t -> bool -+(** Inject the Balloon Server ([blnsvr.exe]) into a Windows guest. -+ -+ A firstboot script is also injected which should install -+ the server by running [blnsvr -i]. -+ -+ Returns [true] iff we were able to inject the Balloon Server. *) -diff --git a/customize/customize_run.ml b/customize/customize_run.ml -index 1314d6e30..1d7c13eaf 100644 ---- a/customize/customize_run.ml -+++ b/customize/customize_run.ml -@@ -113,8 +113,8 @@ let run (g : G.guestfs) root (ops : ops) = - Hashtbl.replace passwords user pw - in - -- (* Helper function to convert --inject-qemu-ga/--inject-virtio-win -- * method parameter into a virtio-win handle. -+ (* Helper function to convert --inject-blnsvr/--inject-qemu-ga/ -+ * --inject-virtio-win method parameter into a virtio-win handle. - *) - let get_virtio_win_handle op meth = - if g#inspect_get_type root <> "windows" then ( -@@ -216,6 +216,15 @@ let run (g : G.guestfs) root (ops : ops) = - if not (Hostname.set_hostname g root hostname) then - warning (f_"hostname could not be set for this type of guest") - -+ | `InjectBalloonServer meth -> -+ (match get_virtio_win_handle "--inject-blnsvr" meth with -+ | None -> () -+ | Some t -> -+ if not (Inject_virtio_win.inject_blnsvr t) then -+ warning (f_"--inject-blnsvr: blnsvr.exe not found in \ -+ virtio-win source that you specified") -+ ) -+ - | `InjectQemuGA meth -> - (match get_virtio_win_handle "--inject-qemu-ga" meth with - | None -> () diff --git a/0004-Update-common-submodule.patch b/0004-Update-common-submodule.patch deleted file mode 100644 index 3189ae8..0000000 --- a/0004-Update-common-submodule.patch +++ /dev/null @@ -1,344 +0,0 @@ -From f59b4fcf683f449a7dd1cad3c168f536cc10304a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 6 Aug 2024 08:51:29 +0100 -Subject: [PATCH] Update common submodule - -Considerable changes have been made in virt-v2v to how powershell -scripts are run in Windows guests, and to qemu-ga installation (also -for Windows). This pulls in the following commits: - -Richard W.M. Jones (10): - mlcustomize: firstboot: Use Linux path for Powershell script path - mlcustomize: firstboot: Use powershell.exe instead of path - mlcustomize: firstboot: Use Powershell -NoProfile flag - mlcustomize: Revert delay installation of qemu-ga MSI - mldrivers/linux_kernels.ml: Prefix general information with ^info: - mlcustomize: Use Start-Process -Wait to run qemu-ga installer - mlcustomize: Add Firstboot.firstboot_dir function - mlcustomize: Place powershell scripts into \Temp - mlcustomize: Inject qemu-ga & blnsvr into /Temp - mlcustomize: Write qemu-ga log file name to log.txt - -(cherry picked from commit b8d57760ea9c9d3ec7a21ee41d74731ab81173df) ---- - common | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -Submodule common 830cbdcf4..7b84a370e: -diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml -index 5dc012340..3bbba714d 100644 ---- a/common/mlcustomize/firstboot.ml -+++ b/common/mlcustomize/firstboot.ml -@@ -239,7 +239,22 @@ WantedBy=%s - end - - module Windows = struct -- let rec install_service (g : Guestfs.guestfs) root = -+ (* Create and return the firstboot directory. *) -+ let create_firstboot_dir (g : Guestfs.guestfs) = -+ let rec loop firstboot_dir firstboot_dir_win = function -+ | [] -> firstboot_dir, firstboot_dir_win -+ | dir :: path -> -+ let firstboot_dir = -+ if firstboot_dir = "" then "/" ^ dir else firstboot_dir // dir in -+ let firstboot_dir_win = firstboot_dir_win ^ "\\" ^ dir in -+ let firstboot_dir = g#case_sensitive_path firstboot_dir in -+ g#mkdir_p firstboot_dir; -+ loop firstboot_dir firstboot_dir_win path -+ in -+ loop "" "C:" ["Program Files"; "Guestfs"; "Firstboot"] -+ -+ let rec install_service (g : Guestfs.guestfs) root -+ firstboot_dir firstboot_dir_win = - (* Either rhsrvany.exe or pvvxsvc.exe must exist. - * - * (Check also that it's not a dangling symlink but a real file). -@@ -254,20 +269,7 @@ module Windows = struct - error (f_"One of rhsrvany.exe or pvvxsvc.exe is missing in %s. One of them is required in order to install Windows firstboot scripts. You can get one by building rhsrvany (https://github.com/rwmjones/rhsrvany)") - (virt_tools_data_dir ()) in - -- (* Create a directory for firstboot files in the guest. *) -- let firstboot_dir, firstboot_dir_win = -- let rec loop firstboot_dir firstboot_dir_win = function -- | [] -> firstboot_dir, firstboot_dir_win -- | dir :: path -> -- let firstboot_dir = -- if firstboot_dir = "" then "/" ^ dir else firstboot_dir // dir in -- let firstboot_dir_win = firstboot_dir_win ^ "\\" ^ dir in -- let firstboot_dir = g#case_sensitive_path firstboot_dir in -- g#mkdir_p firstboot_dir; -- loop firstboot_dir firstboot_dir_win path -- in -- loop "" "C:" ["Program Files"; "Guestfs"; "Firstboot"] in -- -+ (* Create a directory for firstboot scripts in the guest. *) - g#mkdir_p (firstboot_dir // "scripts"); - - (* Copy pvvxsvc or rhsrvany to the guest. *) -@@ -339,11 +341,25 @@ echo uninstalling firstboot service - "PWD", REG_SZ firstboot_dir_win ]; - ] in - reg_import reg regedits -- ); -- -- firstboot_dir -+ ) - end - -+let firstboot_dir (g : Guestfs.guestfs) root = -+ let typ = g#inspect_get_type root in -+ -+ match typ with -+ | "linux" -> -+ let dir = Linux.firstboot_dir in -+ g#mkdir_p dir; -+ dir, None -+ -+ | "windows" -> -+ let dir, dir_win = Windows.create_firstboot_dir g in -+ dir, Some dir_win -+ -+ | _ -> -+ error (f_"guest type %s is not supported") typ -+ - let script_count = ref 0 - - let add_firstboot_script (g : Guestfs.guestfs) root ?(prio = 5000) name -@@ -363,7 +379,8 @@ let add_firstboot_script (g : Guestfs.guestfs) root ?(prio = 5000) name - g#chmod 0o755 filename - - | "windows", _ -> -- let firstboot_dir = Windows.install_service g root in -+ let firstboot_dir, firstboot_dir_win = Windows.create_firstboot_dir g in -+ Windows.install_service g root firstboot_dir firstboot_dir_win; - let filename = firstboot_dir // "scripts" // filename ^ ".bat" in - g#write filename (String.unix2dos content) - -@@ -382,21 +399,18 @@ let add_firstboot_powershell g root ?prio name code = - *) - assert (g#inspect_get_type root = "windows"); - -- let windows_systemroot = g#inspect_get_windows_systemroot root in -- -- (* Create the temporary directory to put the Powershell file. *) -- let tempdir = sprintf "%s/Temp" windows_systemroot in -+ (* Place the Powershell script into firstboot_dir/Temp *) -+ let firstboot_dir, firstboot_dir_win = Windows.create_firstboot_dir g in -+ let tempdir = sprintf "%s/Temp" firstboot_dir in - g#mkdir_p tempdir; -+ -+ let ps_path = sprintf "%s/%s.ps1" tempdir name in -+ let ps_path_win = sprintf "%s\\Temp\\%s.ps1" firstboot_dir_win name in - let code = String.concat "\r\n" code ^ "\r\n" in -- g#write (sprintf "%s/%s" tempdir name) code; -+ g#write ps_path code; - -- (* Powershell interpreter. Should we check this exists? XXX *) -- let ps_exe = -- windows_systemroot ^ -- "\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" in -- -- (* Windows path to the Powershell script. *) -- let ps_path = windows_systemroot ^ "\\Temp\\" ^ name in -- -- let fb = sprintf "%s -ExecutionPolicy ByPass -file %s" ps_exe ps_path in -+ (* Create a regular firstboot bat that just invokes powershell *) -+ let fb = -+ sprintf "powershell.exe -ExecutionPolicy ByPass -NoProfile -file \"%s\"" -+ ps_path_win in - add_firstboot_script g root ?prio name fb -diff --git a/common/mlcustomize/firstboot.mli b/common/mlcustomize/firstboot.mli -index 8231af658..34ff06901 100644 ---- a/common/mlcustomize/firstboot.mli -+++ b/common/mlcustomize/firstboot.mli -@@ -16,6 +16,23 @@ - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - -+val firstboot_dir : Guestfs.guestfs -> string -> string * string option -+(** [firstboot_dir g root] -+ returns the path of the firstboot directory, creating it in -+ the guest if necessary. -+ -+ This returns the name of the directory as a guestfs path, and -+ optionally the name as a Windows path (only for Windows guests). -+ -+ For Linux this could be [/usr/lib/virt-sysprep, None] -+ -+ For Windows this could be ["/Program Files/Guestfs/Firstboot", -+ Some "C:\Program Files\Guestfs\Firstboot"] -+ -+ Additional files that are used during firstboot can be placed -+ in this directory, but be careful not to conflict with files -+ and scripts added by the firstboot process itself. *) -+ - val add_firstboot_script : Guestfs.guestfs -> string -> ?prio:int -> string -> - string -> unit - (** [add_firstboot_script g root prio name content] adds a firstboot -diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml -index 4e0ed0e0e..afec1e456 100644 ---- a/common/mlcustomize/inject_virtio_win.ml -+++ b/common/mlcustomize/inject_virtio_win.ml -@@ -263,14 +263,28 @@ let rec inject_virtio_win_drivers ({ g } as t) reg = - } - ) - --and inject_qemu_ga t = -- let msi_files = copy_qemu_ga t in -+and inject_qemu_ga ({ g; root } as t) = -+ (* Copy the qemu-ga MSI(s) to the guest. *) -+ let dir, dir_win = Firstboot.firstboot_dir g root in -+ let dir_win = Option.value dir_win ~default:dir in -+ let tempdir = sprintf "%s/Temp" dir in -+ let tempdir_win = sprintf "%s\\Temp" dir_win in -+ g#mkdir_p tempdir; -+ -+ let msi_files = copy_qemu_ga t tempdir in - if msi_files <> [] then -- configure_qemu_ga t msi_files; -+ configure_qemu_ga t tempdir_win msi_files; - msi_files <> [] (* return true if we found some qemu-ga MSI files *) - --and inject_blnsvr t = -- let files = copy_blnsvr t in -+and inject_blnsvr ({ g; root } as t) = -+ (* Copy the files to the guest. *) -+ let dir, dir_win = Firstboot.firstboot_dir g root in -+ let dir_win = Option.value dir_win ~default:dir in -+ let tempdir = sprintf "%s/Temp" dir in -+ let tempdir_win = sprintf "%s\\Temp" dir_win in -+ g#mkdir_p tempdir; -+ -+ let files = copy_blnsvr t tempdir in - match files with - | [] -> false (* Didn't find or install anything. *) - -@@ -278,7 +292,7 @@ and inject_blnsvr t = - * drivers/by-driver). Pick the first. - *) - | blnsvr :: _ -> -- configure_blnsvr t blnsvr; -+ configure_blnsvr t tempdir_win blnsvr; - true - - and add_guestor_to_registry t ((g, root) as reg) drv_name drv_pciid = -@@ -360,13 +374,13 @@ and copy_drivers t driverdir = - (fun () -> - error (f_"root directory ‘/’ is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log.")) - --and copy_qemu_ga t = -- copy_from_virtio_win t "/" "/" (virtio_iso_path_matches_qemu_ga t) -+and copy_qemu_ga t tempdir = -+ copy_from_virtio_win t "/" tempdir (virtio_iso_path_matches_qemu_ga t) - (fun () -> - error (f_"root directory ‘/’ is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log.")) - --and copy_blnsvr t = -- copy_from_virtio_win t "/" "/" (virtio_iso_path_matches_blnsvr t) -+and copy_blnsvr t tempdir = -+ copy_from_virtio_win t "/" tempdir (virtio_iso_path_matches_blnsvr t) - (fun () -> - error (f_"root directory ‘/’ is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log.")) - -@@ -575,44 +589,35 @@ and copy_from_libosinfo { g; i_osinfo; i_arch } destdir = - ) driver.Libosinfo.files - with Not_found -> [] - --and configure_qemu_ga t files = -+(* Install qemu-ga. [files] is the non-empty list of possible qemu-ga -+ * installers we detected. -+ *) -+and configure_qemu_ga t tempdir_win files = -+ let script = ref [] in -+ let add = List.push_back script in -+ -+ add "# Virt-v2v script which installs QEMU Guest Agent"; -+ add ""; -+ add "# Uncomment this line for lots of debug output."; -+ add "# Set-PSDebug -Trace 2"; -+ add ""; -+ add "Write-Host Installing QEMU Guest Agent"; -+ add ""; -+ add "# Run qemu-ga installers"; - List.iter ( -- fun msi_path -> -- (* Windows is a trashfire. -- * https://stackoverflow.com/a/18730884 -- * https://bugzilla.redhat.com/show_bug.cgi?id=1895323 -- *) -- let psh_script = ref [] in -- let add = List.push_back psh_script in -+ fun msi -> -+ add (sprintf "Write-Host \"Writing log to %s\\%s.log\"" -+ tempdir_win msi); -+ (* [`] is an escape char for quotes *) -+ add (sprintf "Start-Process -Wait -FilePath \"%s\\%s\" -ArgumentList \"/norestart\",\"/qn\",\"/l+*vx\",\"`\"%s\\%s.log`\"\"" -+ tempdir_win msi tempdir_win msi) -+ ) files; - -- add "# Uncomment this line for lots of debug output."; -- add "# Set-PSDebug -Trace 2"; -- add ""; -- add "Write-Host Removing any previously scheduled qemu-ga installation"; -- add "schtasks.exe /Delete /TN Firstboot-qemu-ga /F"; -- add ""; -- add (sprintf -- "Write-Host Scheduling delayed installation of qemu-ga from %s" -- msi_path); -- add "$d = (get-date).AddSeconds(120)"; -- add "$dtfinfo = [System.Globalization.DateTimeFormatInfo]::CurrentInfo"; -- add "$sdp = $dtfinfo.ShortDatePattern"; -- add "$sdp = $sdp -replace 'y+', 'yyyy'"; -- add "$sdp = $sdp -replace 'M+', 'MM'"; -- add "$sdp = $sdp -replace 'd+', 'dd'"; -- add "schtasks.exe /Create /SC ONCE `"; -- add " /ST $d.ToString('HH:mm') /SD $d.ToString($sdp) `"; -- add " /RU SYSTEM /TN Firstboot-qemu-ga `"; -- add (sprintf " /TR \"C:\\%s /forcerestart /qn /l+*vx C:\\%s.log\"" -- msi_path msi_path); -+ Firstboot.add_firstboot_powershell t.g t.root "install-qemu-ga" !script - -- Firstboot.add_firstboot_powershell t.g t.root -- (sprintf "install-%s.ps1" msi_path) !psh_script; -- ) files -- --and configure_blnsvr t blnsvr = -+and configure_blnsvr t tempdir_win blnsvr = - let cmd = sprintf "\ - @echo off\n\ - echo Installing %s\n\ -- c:\\%s -i\n" blnsvr blnsvr in -- Firstboot.add_firstboot_script t.g t.root (sprintf "install-%s" blnsvr) cmd -+ \"%s\\%s\" -i\n" blnsvr tempdir_win blnsvr in -+ Firstboot.add_firstboot_script t.g t.root "install-blnsvr" cmd -diff --git a/common/mldrivers/linux_kernels.ml b/common/mldrivers/linux_kernels.ml -index 23ff76a55..e0b6b8a00 100644 ---- a/common/mldrivers/linux_kernels.ml -+++ b/common/mldrivers/linux_kernels.ml -@@ -102,7 +102,7 @@ let detect_kernels (g : G.guestfs) root bootloader apps = - ) apps in - if verbose () then ( - let names = List.map (fun { G.app2_name = name } -> name) kernel_pkgs in -- eprintf "candidate kernel packages in this guest: %s%!\n" -+ eprintf "info: candidate kernel packages in this guest: %s%!\n" - (String.concat " " names) - ); - List.filter_map ( -@@ -306,7 +306,7 @@ let detect_kernels (g : G.guestfs) root bootloader apps = - ) kernel_pkgs in - - if verbose () then ( -- eprintf "installed kernel packages in this guest:\n"; -+ eprintf "info: installed kernel packages in this guest:\n"; - List.iter (print_kernel_info stderr "\t") installed_kernels; - flush stderr - ); -@@ -343,7 +343,7 @@ let detect_kernels (g : G.guestfs) root bootloader apps = - ) vmlinuzes in - - if verbose () then ( -- eprintf "kernels offered by the bootloader in this guest (first in list is default):\n"; -+ eprintf "info: kernels offered by the bootloader in this guest (first in list is default):\n"; - List.iter (print_kernel_info stderr "\t") bootloader_kernels; - flush stderr - ); diff --git a/0004-customize-Fixes-for-selinux-relabelling-and-Windows-.patch b/0004-customize-Fixes-for-selinux-relabelling-and-Windows-.patch new file mode 100644 index 0000000..88bb660 --- /dev/null +++ b/0004-customize-Fixes-for-selinux-relabelling-and-Windows-.patch @@ -0,0 +1,143 @@ +From 6a1e751d4b10ae1833ee18c0796306711e842e76 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 13 Aug 2025 16:51:39 +0100 +Subject: [PATCH] customize: Fixes for selinux relabelling and Windows + firstboot + +This updates the common submodule to add the fixes below. These +changes allow SELinux relabelling to work correctly on Linux split- +/usr configurations, and allow Windows firstboot scripts to be +deferred until after a reboot. + +The SELinux relabelling change requires libguestfs >= 1.57.1 (for the +new guestfs_setfiles API). + + Richard W.M. Jones (4): + mlstdutils: Add List.combine4 function + mlcustomize/SELinux_relabel.ml: Add comment + mlcustomize/SELinux_relabel.ml: Use new guestfs_setfiles API + mlcustomize/SELinux_relabel.ml: Relabel every mountpoint + + Vadim Rozenfeld (1): + Modify the firstboot script to check the scripts execution return status + +Fixes: https://issues.redhat.com/browse/RHEL-108174 +Related: https://issues.redhat.com/browse/RHEL-100682 +(cherry picked from commit ea0f9cf0743c3e50a996a9d7ec488d58a9312b11) +--- + common | 2 +- + m4/guestfs-libraries.m4 | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +Submodule common d4a81e9dd..89f1eb2d3: +diff --git a/common/mlcustomize/SELinux_relabel.ml b/common/mlcustomize/SELinux_relabel.ml +index 2f3a09bf7..f1729e3f4 100644 +--- a/common/mlcustomize/SELinux_relabel.ml ++++ b/common/mlcustomize/SELinux_relabel.ml +@@ -1,5 +1,5 @@ + (* virt-customize +- * Copyright (C) 2016 Red Hat Inc. ++ * Copyright (C) 2016-2025 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -24,6 +24,10 @@ open Printf + + module G = Guestfs + ++(* XXX A lot of this code could usefully be moved into ++ * [libguestfs.git/daemon/selinux.ml]. ++ *) ++ + let rec relabel (g : G.guestfs) = + (* Is the guest using SELinux? (Otherwise this is a no-op). *) + if is_selinux_guest g then ( +@@ -109,5 +113,13 @@ and use_setfiles g = + g#copy_attributes ~all:true old_specfile specfile + ); + ++ (* Get the list of mountpoints, since setfiles does not cross ++ * filesystems (RHEL-108174). ++ *) ++ let mps = g#mountpoints () |> ++ List.map snd |> (* the list of directories *) ++ List.sort compare |> (* sort them for consistency *) ++ Array.of_list in ++ + (* Relabel everything. *) +- g#selinux_relabel ~force:true specfile "/" ++ g#setfiles ~force:true specfile mps +diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml +index 6aca4c34a..5f2642b06 100644 +--- a/common/mlcustomize/firstboot.ml ++++ b/common/mlcustomize/firstboot.ml +@@ -305,13 +305,19 @@ if not exist \"%%scripts_done%%\" ( + :: Pick the next script to run. + for %%%%f in (\"%%scripts%%\"\\*.bat) do ( + echo running \"%%%%f\" +- move \"%%%%f\" \"%%scripts_done%%\" +- pushd \"%%scripts_done%%\" ++ pushd \"%%scripts%%\" + call \"%%%%~nf\" + set elvl=!errorlevel! + echo .... exit code !elvl! + popd + ++ if !elvl! NEQ 249 ( ++ echo Script succeeded, moving to scripts-done ++ move \"%%%%f\" \"%%scripts_done%%\" ++ ) else ( ++ echo Script failed, will retry on next boot ++ ) ++ + :: Reboot the computer. This is necessary to free any locked + :: files which may prevent later scripts from running. + shutdown /r /t 0 /y +diff --git a/common/mlstdutils/std_utils.ml b/common/mlstdutils/std_utils.ml +index 4850a5598..16032d992 100644 +--- a/common/mlstdutils/std_utils.ml ++++ b/common/mlstdutils/std_utils.ml +@@ -80,6 +80,12 @@ module List = struct + | x::xs, y::ys, z::zs -> (x, y, z) :: combine3 xs ys zs + | _ -> invalid_arg "combine3" + ++ let rec combine4 ws xs ys zs = ++ match ws, xs, ys, zs with ++ | [], [], [], [] -> [] ++ | w::ws, x::xs, y::ys, z::zs -> (w, x, y, z) :: combine4 ws xs ys zs ++ | _ -> invalid_arg "combine4" ++ + let rec assoc_lbl ?(cmp = Stdlib.compare) ~default x = function + | [] -> default + | (y, y') :: _ when cmp x y = 0 -> y' +diff --git a/common/mlstdutils/std_utils.mli b/common/mlstdutils/std_utils.mli +index fe6bf1a7c..a20e720c2 100644 +--- a/common/mlstdutils/std_utils.mli ++++ b/common/mlstdutils/std_utils.mli +@@ -106,6 +106,11 @@ module List : sig + (** Like {!List.combine} but for triples. + All lists must be the same length. *) + ++ val combine4 : 'a list -> 'b list -> 'c list -> 'd list -> ++ ('a * 'b * 'c * 'd) list ++ (** Like {!List.combine} but for 4-tuples. ++ All lists must be the same length. *) ++ + val assoc_lbl : ?cmp:('a -> 'a -> int) -> default:'b -> 'a -> ('a * 'b) list -> 'b + (** Like {!assoc} but with a user-defined comparison function, and + instead of raising [Not_found], it returns the [~default] value. *) +diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4 +index c9fbf58b2..82e62d54f 100644 +--- a/m4/guestfs-libraries.m4 ++++ b/m4/guestfs-libraries.m4 +@@ -19,8 +19,8 @@ dnl Any C libraries required by the libguestfs C library (not the daemon). + + dnl Of course we need libguestfs. + dnl +-dnl We need libguestfs 1.55.6 for guestfs_sh_out. +-PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.55.6]) ++dnl We need libguestfs 1.57.1 for guestfs_setfiles. ++PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.57.1]) + printf "libguestfs version is "; $PKG_CONFIG --modversion libguestfs + + dnl Test if it's GNU or XSI strerror_r. diff --git a/0005-Update-common-submodule.patch b/0005-Update-common-submodule.patch index e536917..a4f49aa 100644 --- a/0005-Update-common-submodule.patch +++ b/0005-Update-common-submodule.patch @@ -1,57 +1,122 @@ -From 7cffcb71c393da2ee636eb8bc9360bf83f5066f5 Mon Sep 17 00:00:00 2001 +From a01095308d22a5ab4d5858dfe0ee46f0b1bec28c Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" -Date: Sat, 10 Aug 2024 14:17:51 +0100 +Date: Wed, 20 Aug 2025 10:34:24 +0100 Subject: [PATCH] Update common submodule -Further refinements to Windows firstboot code. +Pulls in this fix which should have no effect: -Richard W.M. Jones (2): - mlcustomize: Add some comments to firstboot batch file - mlcustomize: Reboot Windows between each firstboot script + Richard W.M. Jones (1): + mlcustomize/firstboot.ml: Use quoted string literals for firstboot -(cherry picked from commit d7719d6954f48c3a395da7486bcf55fbac66ea07) +(cherry picked from virt-v2v commit b7aadeac02ef326d542cd83e441b5a9d99ced793) + +(cherry picked from commit 038b30fb08107487cdba4bc0dbabb33dbf75f4c3) --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -Submodule common 7b84a370e..a78839676: +Submodule common 89f1eb2d3..7ecf3992b: diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml -index 3bbba714d..52e76401e 100644 +index 5f2642b06..360c33d67 100644 --- a/common/mlcustomize/firstboot.ml +++ b/common/mlcustomize/firstboot.ml -@@ -278,6 +278,9 @@ module Windows = struct - (* Write a firstboot.bat control script which just runs the other - * scripts in the directory. Note we need to use CRLF line endings - * in this script. -+ * -+ * XXX It would be better to use powershell here. For some ideas see -+ * https://github.com/HCK-CI/HLK-Setup-Scripts/ +@@ -35,8 +35,7 @@ let sanitize_name = + module Linux = struct + let firstboot_dir = "/usr/lib/virt-sysprep" + +- let firstboot_sh = sprintf "\ +-#!/bin/sh - ++ let firstboot_sh = sprintf {|#!/bin/sh - + + ### BEGIN INIT INFO + # Provides: virt-sysprep +@@ -57,14 +56,14 @@ d=%s/scripts + d_done=%s/scripts-done + logfile=~root/virt-sysprep-firstboot.log + +-echo \"$0\" \"$@\" 2>&1 | tee -a $logfile +-echo \"Scripts dir: $d\" 2>&1 | tee -a $logfile ++echo "$0" "$@" 2>&1 | tee -a $logfile ++echo "Scripts dir: $d" 2>&1 | tee -a $logfile + +-if test \"$1\" = \"start\" ++if test "$1" = "start" + then + mkdir -p $d_done + for f in $d/* ; do +- if test -x \"$f\" ++ if test -x "$f" + then + # move the script to the 'scripts-done' directory, so it is not + # executed again at the next boot +@@ -75,7 +74,7 @@ then + done + rm -f $d_done/* + fi +-" firstboot_dir firstboot_dir ++|} firstboot_dir firstboot_dir + + let systemd_target = "multi-user.target" + +@@ -282,38 +281,37 @@ module Windows = struct + * XXX It would be better to use powershell here. For some ideas see + * https://github.com/HCK-CI/HLK-Setup-Scripts/ *) - let firstboot_script = sprintf "\ - @echo off -@@ -299,6 +302,7 @@ if not exist \"%%scripts_done%%\" ( - mkdir \"%%scripts_done%%\" +- let firstboot_script = sprintf "\ +-@echo off ++ let firstboot_script = sprintf {|@echo off + + setlocal EnableDelayedExpansion + set firstboot=%s +-set log=%%firstboot%%\\log.txt ++set log=%%firstboot%%\log.txt + +-set scripts=%%firstboot%%\\scripts +-set scripts_done=%%firstboot%%\\scripts-done ++set scripts=%%firstboot%%\scripts ++set scripts_done=%%firstboot%%\scripts-done + +-call :main >> \"%%log%%\" 2>&1 ++call :main >> "%%log%%" 2>&1 + exit /b + + :main + echo starting firstboot service + +-if not exist \"%%scripts_done%%\" ( +- mkdir \"%%scripts_done%%\" ++if not exist "%%scripts_done%%" ( ++ mkdir "%%scripts_done%%" ) -+:: Pick the next script to run. - for %%%%f in (\"%%scripts%%\"\\*.bat) do ( - echo running \"%%%%f\" - move \"%%%%f\" \"%%scripts_done%%\" -@@ -307,8 +311,17 @@ for %%%%f in (\"%%scripts%%\"\\*.bat) do ( + :: Pick the next script to run. +-for %%%%f in (\"%%scripts%%\"\\*.bat) do ( +- echo running \"%%%%f\" +- pushd \"%%scripts%%\" +- call \"%%%%~nf\" ++for %%%%f in ("%%scripts%%"\*.bat) do ( ++ echo running "%%%%f" ++ pushd "%%scripts%%" ++ call "%%%%~nf" set elvl=!errorlevel! echo .... exit code !elvl! popd -+ -+ :: Reboot the computer. This is necessary to free any locked -+ :: files which may prevent later scripts from running. -+ shutdown /r /t 0 /y -+ -+ :: Exit the script (in case shutdown returns before rebooting). -+ :: On next boot, the whole firstboot service will be called again. -+ exit /b - ) -+:: Fallthrough here if there are no scripts. + if !elvl! NEQ 249 ( + echo Script succeeded, moving to scripts-done +- move \"%%%%f\" \"%%scripts_done%%\" ++ move "%%%%f" "%%scripts_done%%" + ) else ( + echo Script failed, will retry on next boot + ) +@@ -329,8 +327,8 @@ for %%%%f in (\"%%scripts%%\"\\*.bat) do ( + + :: Fallthrough here if there are no scripts. echo uninstalling firstboot service - \"%%firstboot%%\\%s\" -s firstboot uninstall - " firstboot_dir_win srvany in +-\"%%firstboot%%\\%s\" -s firstboot uninstall +-" firstboot_dir_win srvany in ++"%%firstboot%%\%s" -s firstboot uninstall ++|} firstboot_dir_win srvany in + + g#write (firstboot_dir // "firstboot.bat") + (String.unix2dos firstboot_script); diff --git a/0006-.gitignore-Ignore-.bak-files.patch b/0006-.gitignore-Ignore-.bak-files.patch new file mode 100644 index 0000000..60acd93 --- /dev/null +++ b/0006-.gitignore-Ignore-.bak-files.patch @@ -0,0 +1,22 @@ +From 9ee5fdf8146231087a461f4cddc0280db762c2f4 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 1 Sep 2025 17:33:07 +0100 +Subject: [PATCH] .gitignore: Ignore *.bak files + +(cherry picked from commit cd5ea5cd63a11bc85077e6296021bd25b3c84662) +--- + .gitignore | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.gitignore b/.gitignore +index 9c2e200e6..94f77ac74 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -2,6 +2,7 @@ + *.1 + *.a + *.annot ++*.bak + *.cmi + *.cmo + *.cmx diff --git a/0007-builder-sysprep-Use-quoted-string-literals-in-a-few-.patch b/0007-builder-sysprep-Use-quoted-string-literals-in-a-few-.patch new file mode 100644 index 0000000..1aac5de --- /dev/null +++ b/0007-builder-sysprep-Use-quoted-string-literals-in-a-few-.patch @@ -0,0 +1,206 @@ +From 0074de5f6eccb75dad814527813eba3524bb22e0 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 1 Sep 2025 18:41:24 +0100 +Subject: [PATCH] builder, sysprep: Use quoted string literals in a few places + +This change was automated using the script in: +https://github.com/libguestfs/libguestfs/commit/02b64d5cec1ac0a6f7627d5489996de4474a67f6 + +However I manually only picked a few of the changes suggested +by the script. + +(cherry picked from commit 624df48b3d14d2e5420d758a425bcae509cfe318) +--- + builder/templates/make-template.ml | 62 ++++++++++++++--------------- + sysprep/sysprep_operation_script.ml | 5 ++- + 2 files changed, 33 insertions(+), 34 deletions(-) + +diff --git a/builder/templates/make-template.ml b/builder/templates/make-template.ml +index 73a55bd45..515c3da8b 100755 +--- a/builder/templates/make-template.ml ++++ b/builder/templates/make-template.ml +@@ -535,8 +535,7 @@ and make_kickstart_common ks_filename os arch = + | _ -> bpf "install\n"; + ); + +- bpf "\ +-text ++ bpf {|text + reboot + lang en_US.UTF-8 + keyboard us +@@ -544,7 +543,7 @@ network --bootproto dhcp + rootpw builder + firewall --enabled --ssh + timezone --utc America/New_York +-"; ++|}; + + (match os with + | RHEL (ver, _) when ver <= 4 -> +@@ -586,19 +585,19 @@ mouse generic + | CentOS ((3|4|5|6) as major, _) | RHEL ((3|4|5|6) as major, _) -> + let bootfs = if major <= 5 then "ext2" else "ext4" in + let rootfs = if major <= 4 then "ext3" else "ext4" in +- bpf "\ ++ bpf {| + zerombr + clearpart --all --initlabel + part /boot --fstype=%s --size=512 --asprimary + part swap --size=1024 --asprimary + part / --fstype=%s --size=1024 --grow --asprimary +-" bootfs rootfs; ++|} bootfs rootfs; + | Alma _ | CentOS _ | CentOSStream _ | RHEL _ | Fedora _ -> +- bpf "\ ++ bpf {| + zerombr + clearpart --all --initlabel --disklabel=gpt + autopart --type=plain +-"; ++|}; + | _ -> assert false (* cannot happen, see caller *) + ); + bpf "\n"; +@@ -753,16 +752,16 @@ and make_unattend_iso os arch = + * file called \Windows\Panther\Setupact.log (NB: + * not \Windows\Setupact.log) + *) +- fprintf chan " +- +- +- ++ fprintf chan {| ++ ++ ++ + + true + +@@ -772,18 +771,18 @@ and make_unattend_iso os arch = + + + +- ++ + 0 + true + + +- ++ + 1 + Primary + 300 + + +- ++ + 2 + Primary + true +@@ -791,7 +790,7 @@ and make_unattend_iso os arch = + + + +- ++ + 1 + 1 + +@@ -799,7 +798,7 @@ and make_unattend_iso os arch = + true + + +- ++ + 2 + 2 + +@@ -828,11 +827,11 @@ and make_unattend_iso os arch = + + + +- ++ + + en-US + +@@ -841,7 +840,7 @@ and make_unattend_iso os arch = + en-US + + +-" ++|} + arch product_key arch; + close_out chan; + +@@ -1411,14 +1410,13 @@ baseurl=%s + enabled=0 + gpgcheck=0 + keepcache=0 +-" major major baseurl major major srpms; ++|} major major baseurl major major srpms; + + (match optional with + | None -> () + | Some (name, optionalbaseurl, optionalsrpms) -> + let lc_name = String.lowercase_ascii name in +- bpf "\ +- ++ bpf {| + [rhel%d-%s] + name=RHEL %d Server %s + baseurl=%s +@@ -1432,7 +1430,7 @@ baseurl=%s + enabled=0 + gpgcheck=0 + keepcache=0 +-" major lc_name major lc_name optionalbaseurl ++|} major lc_name major lc_name optionalbaseurl + major lc_name major lc_name optionalsrpms + ) + ) else ( +diff --git a/sysprep/sysprep_operation_script.ml b/sysprep/sysprep_operation_script.ml +index fff5e4d51..a91cea26b 100644 +--- a/sysprep/sysprep_operation_script.ml ++++ b/sysprep/sysprep_operation_script.ml +@@ -81,7 +81,7 @@ let rec script_perform (g : Guestfs.guestfs) root side_effects = + and run_scripts mp scripts = + let sh = "/bin/bash" in + let cmd = +- sprintf "\ ++ sprintf {| + set -e + #set -x + cleanup () +@@ -91,7 +91,8 @@ cleanup () + guestunmount %s ||: + exit $status + } +-trap cleanup INT TERM QUIT EXIT ERR\n" ++trap cleanup INT TERM QUIT EXIT ERR ++|} + (Filename.quote mp) ^ + String.concat "\n" scripts in + let args = [| sh; "-c"; cmd |] in diff --git a/0008-builder-templates-make-template.ml-Fix-quoting.patch b/0008-builder-templates-make-template.ml-Fix-quoting.patch new file mode 100644 index 0000000..88ef43e --- /dev/null +++ b/0008-builder-templates-make-template.ml-Fix-quoting.patch @@ -0,0 +1,26 @@ +From cde27ebd4775cfa9a23a53a48b47303557bcb537 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 2 Sep 2025 09:05:27 +0100 +Subject: [PATCH] builder/templates/make-template.ml: Fix quoting + +Fix mistake introduced by manual editing of the previous commit. + +Fixes: commit 624df48b3d14d2e5420d758a425bcae509cfe318 +(cherry picked from commit 7e63b2142682582ec87bdd8c0d98bb22fcc0dabf) +--- + builder/templates/make-template.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/builder/templates/make-template.ml b/builder/templates/make-template.ml +index 515c3da8b..a69d3ad3f 100755 +--- a/builder/templates/make-template.ml ++++ b/builder/templates/make-template.ml +@@ -1394,7 +1394,7 @@ and make_rhel_yum_conf major minor arch = + sprintf "%s/AppStream/source/tree" topurl) + | _ -> assert false in + +- bpf "\ ++ bpf {| + # Yum configuration pointing to Red Hat servers. + + [rhel%d] diff --git a/0009-builder-templates-make-template.ml-Use-quoted-string.patch b/0009-builder-templates-make-template.ml-Use-quoted-string.patch new file mode 100644 index 0000000..eab0843 --- /dev/null +++ b/0009-builder-templates-make-template.ml-Use-quoted-string.patch @@ -0,0 +1,33 @@ +From 1fca99c9bed60cd9a9c62826d4e6995052d0c5dd Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 2 Sep 2025 09:06:33 +0100 +Subject: [PATCH] builder/templates/make-template.ml: Use quoted string + literals for regexps + +(cherry picked from commit aafb271e8ffd961c529f90ef65df75a70102f0fc) +--- + builder/templates/make-template.ml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/builder/templates/make-template.ml b/builder/templates/make-template.ml +index a69d3ad3f..f8b41209e 100755 +--- a/builder/templates/make-template.ml ++++ b/builder/templates/make-template.ml +@@ -374,7 +374,7 @@ and os_of_string os ver = + eprintf "%s: unknown or unsupported OS (%s, %s)\n" prog os ver; exit 1 + + and parse_major_minor ver = +- let rex = Str.regexp "^\\([0-9]+\\)\\.\\([0-9]+\\)$" in ++ let rex = Str.regexp {|^\([0-9]+\)\.\([0-9]+\)$|} in + if Str.string_match rex ver 0 then ( + int_of_string (Str.matched_group 1 ver), + int_of_string (Str.matched_group 2 ver) +@@ -1631,7 +1631,7 @@ and read_revision filename = + | None -> `No_file + | Some chan -> + let r = ref `No_revision in +- let rex = Str.regexp "^revision=\\([0-9]+\\)$" in ++ let rex = Str.regexp {|^revision=\([0-9]+\)$|} in + (try + let rec loop () = + let line = input_line chan in diff --git a/0010-builder-templates-make-template.ml-Add-str-and-unix-.patch b/0010-builder-templates-make-template.ml-Add-str-and-unix-.patch new file mode 100644 index 0000000..5e109e2 --- /dev/null +++ b/0010-builder-templates-make-template.ml-Add-str-and-unix-.patch @@ -0,0 +1,43 @@ +From 7b2125b42535e6768d8f162d19463af4c4e8df1b Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 2 Sep 2025 09:07:34 +0100 +Subject: [PATCH] builder/templates/make-template.ml: Add +str and +unix for + OCaml 5 + +Removes these warnings: + +File "_none_", line 1: +Alert ocaml_deprecated_auto_include: +OCaml's lib directory layout changed in 5.0. The str subdirectory has been +automatically added to the search path, but you should add -I +str to the +command-line to silence this alert (e.g. by adding str to the list of +libraries in your dune file, or adding use_str to your _tags file for +ocamlbuild, or using -package str for ocamlfind). + +File "_none_", line 1: +Alert ocaml_deprecated_auto_include: +OCaml's lib directory layout changed in 5.0. The unix subdirectory has been +automatically added to the search path, but you should add -I +unix to the +command-line to silence this alert (e.g. by adding unix to the list of +libraries in your dune file, or adding use_unix to your _tags file for +ocamlbuild, or using -package unix for ocamlfind). + +(cherry picked from commit 046309b31c22da5ac64feac12bcf4501377a8b3f) +--- + builder/templates/make-template.ml | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/builder/templates/make-template.ml b/builder/templates/make-template.ml +index f8b41209e..2ce803e2b 100755 +--- a/builder/templates/make-template.ml ++++ b/builder/templates/make-template.ml +@@ -24,7 +24,9 @@ + * shell scripts located in libguestfs.git/builder/website. + *) + ++#directory "+str";; + #load "str.cma";; ++#directory "+unix";; + #load "unix.cma";; + #directory "+guestfs";; (* use globally installed guestfs *) + #load "mlguestfs.cma";; diff --git a/0011-daemon-generator-Use-power-of-2-for-initial-size-of-.patch b/0011-daemon-generator-Use-power-of-2-for-initial-size-of-.patch new file mode 100644 index 0000000..e4bcfa7 --- /dev/null +++ b/0011-daemon-generator-Use-power-of-2-for-initial-size-of-.patch @@ -0,0 +1,76 @@ +From 68a3719888f36719cef8bcd7817ed634c4524012 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 12 Sep 2025 08:37:58 +0100 +Subject: [PATCH] daemon, generator: Use power of 2 for initial size of + Hashtbl.create + +Before 2011 it was recommended to use a prime number for the initial +size. In 2011 the OCaml hash table was reimplemented using a hash +function based on Murmur 3. Hashtbl.create now adjusts the initial +size to the next power of 2 (minimum 16). So replace obsolete +'Hashtbl.create 13' with 'Hashtbl.create 16'. + +(cherry picked from commit 51f7dfa8612e8e273e3ef15eddd7a5714122cc57) +--- + builder/builder.ml | 2 +- + builder/index_parser.ml | 4 ++-- + resize/resize.ml | 4 ++-- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/builder/builder.ml b/builder/builder.ml +index bbe2808f5..2df2fa5c7 100644 +--- a/builder/builder.ml ++++ b/builder/builder.ml +@@ -46,7 +46,7 @@ let remove_duplicates index = + * (name, arch) tuples, so it possible to ignore duplicates, + * and versions with a lower revision. + *) +- let nseen = Hashtbl.create 13 in ++ let nseen = Hashtbl.create 16 in + List.iter ( + fun (name, { Index.arch; revision }) -> + let id = name, arch in +diff --git a/builder/index_parser.ml b/builder/index_parser.ml +index 3e19e489e..2cb89488f 100644 +--- a/builder/index_parser.ml ++++ b/builder/index_parser.ml +@@ -55,7 +55,7 @@ let get_index ~downloader ~sigchecker ?(template = false) + in + n, (find_arch fields) + ) sections in +- let nseen = Hashtbl.create 13 in ++ let nseen = Hashtbl.create 16 in + List.iter ( + fun (n, arch) -> + let id = n, arch in +@@ -71,7 +71,7 @@ let get_index ~downloader ~sigchecker ?(template = false) + (* Check for repeated fields. *) + List.iter ( + fun (n, fields) -> +- let fseen = Hashtbl.create 13 in ++ let fseen = Hashtbl.create 16 in + List.iter ( + fun (field, subkey, _) -> + let hashkey = (field, subkey) in +diff --git a/resize/resize.ml b/resize/resize.ml +index fffe2de77..707def8e9 100644 +--- a/resize/resize.ml ++++ b/resize/resize.ml +@@ -630,7 +630,7 @@ read the man page virt-resize(1). + * that the user has asked to be ignored or deleted. + *) + let find_partition = +- let hash = Hashtbl.create 13 in ++ let hash = Hashtbl.create 16 in + List.iter (fun ({ p_name = name } as p) -> Hashtbl.add hash name p) + partitions; + fun ~option name -> +@@ -881,7 +881,7 @@ read the man page virt-resize(1). + surplus in + + (* Mark the --lv-expand LVs. *) +- let hash = Hashtbl.create 13 in ++ let hash = Hashtbl.create 16 in + List.iter (fun ({ lv_name = name } as lv) -> Hashtbl.add hash name lv) lvs; + + List.iter ( diff --git a/0012-builder-Build-fedora-42-template.patch b/0012-builder-Build-fedora-42-template.patch new file mode 100644 index 0000000..dfc7ed4 --- /dev/null +++ b/0012-builder-Build-fedora-42-template.patch @@ -0,0 +1,123 @@ +From abb56223e0a35c3e5d1158f32789c44c28bacf40 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sat, 24 May 2025 13:27:00 +0100 +Subject: [PATCH] builder: Build fedora-42 template + +Thanks: Jeff Layton +--- + builder/templates/fedora-42.index-fragment | 22 +++++++++ + builder/templates/fedora-42.ks | 48 ++++++++++++++++++++ + builder/templates/fedora-42.virt-install-cmd | 20 ++++++++ + 3 files changed, 90 insertions(+) + create mode 100644 builder/templates/fedora-42.index-fragment + create mode 100644 builder/templates/fedora-42.ks + create mode 100644 builder/templates/fedora-42.virt-install-cmd + +diff --git a/builder/templates/fedora-42.index-fragment b/builder/templates/fedora-42.index-fragment +new file mode 100644 +index 000000000..6d21b742c +--- /dev/null ++++ b/builder/templates/fedora-42.index-fragment +@@ -0,0 +1,22 @@ ++[fedora-42] ++name=Fedora® 42 Server ++osinfo=fedora42 ++arch=x86_64 ++file=fedora-42.xz ++checksum[sha512]=dda921f3c522da8d8a67e31948260f52a9aa5bdeca4382a5c557635d77ad91d11b9aded70a225f59503b268ec73815ceac2eac5b70c1d47f22056febdd9da6bb ++format=raw ++size=6442450944 ++compressed_size=927728896 ++expand=/dev/sda3 ++notes=Fedora® 42 Server ++ ++ This Fedora image contains only unmodified @Core group packages. ++ ++ Fedora and the Infinity design logo are trademarks of Red Hat, Inc. ++ Source and further information is available from http://fedoraproject.org/ ++ ++ This template was generated by a script in the libguestfs source tree: ++ builder/templates/make-template.ml ++ Associated files used to prepare this template can be found in the ++ same directory. ++ +diff --git a/builder/templates/fedora-42.ks b/builder/templates/fedora-42.ks +new file mode 100644 +index 000000000..17e2e3f15 +--- /dev/null ++++ b/builder/templates/fedora-42.ks +@@ -0,0 +1,48 @@ ++# Kickstart file for fedora-42 ++# Generated by libguestfs.git/builder/templates/make-template.ml ++ ++text ++reboot ++lang en_US.UTF-8 ++keyboard us ++network --bootproto dhcp ++rootpw builder ++firewall --enabled --ssh ++timezone --utc America/New_York ++selinux --enforcing ++ ++bootloader --location=mbr --append="console=tty0 console=ttyS0,115200 rd_NO_PLYMOUTH" ++ ++ ++zerombr ++clearpart --all --initlabel --disklabel=gpt ++autopart --type=plain ++ ++# Halt the system once configuration has finished. ++poweroff ++ ++%packages ++@core ++%end ++ ++%post ++# Ensure the installation is up-to-date. ++dnf -y --best upgrade ++# This required otherwise the kernel will not be bootable, see ++# https://bugzilla.redhat.com/show_bug.cgi?id=1911177 ++# https://bugzilla.redhat.com/show_bug.cgi?id=1945835#c24 ++grub2-mkconfig -o '/etc/grub2.cfg' ++# Enable Xen domU support. ++pushd /etc/dracut.conf.d ++echo 'add_drivers+=" xen:vbd xen:vif "' > virt-builder-xen-drivers.conf ++popd ++# To make dracut config changes permanent, we need to rerun dracut. ++# Rerun dracut for the installed kernel (not the running kernel). ++# See commit 0fa52e4e45d80874bc5ea5f112f74be1d3f3472f and ++# https://www.redhat.com/archives/libguestfs/2014-June/thread.html#00045 ++KERNEL_VERSION="$(rpm -q kernel --qf '%{version}-%{release}.%{arch}\n' | ++ sort -V | tail -1)" ++dracut -f /boot/initramfs-$KERNEL_VERSION.img $KERNEL_VERSION ++%end ++ ++# EOF +diff --git a/builder/templates/fedora-42.virt-install-cmd b/builder/templates/fedora-42.virt-install-cmd +new file mode 100644 +index 000000000..2a3256bbd +--- /dev/null ++++ b/builder/templates/fedora-42.virt-install-cmd +@@ -0,0 +1,20 @@ ++# This is the virt-install command which was used to create ++# the virt-builder template 'fedora-42' ++# NB: This file is generated for documentation purposes ONLY! ++# This script was never run, and is not intended to be run. ++ ++'virt-install' \ ++ '--transient' \ ++ '--name=tmp-oeg15xnl' \ ++ '--ram=4096' \ ++ '--arch=x86_64' \ ++ '--cpu=host' \ ++ '--vcpus=4' \ ++ '--os-variant=fedora34' \ ++ '--initrd-inject=fedora-42.ks' \ ++ '--extra-args=inst.ks=file:/fedora-42.ks console=tty0 console=ttyS0,115200 rd_NO_PLYMOUTH' \ ++ '--disk=/home/rjones/d/guestfs-tools/builder/templates/tmp-oeg15xnl.img,size=6,format=raw' \ ++ '--location=https://lon.mirror.rackspace.com/fedora/releases/42/Server/x86_64/os/' \ ++ '--serial=pty' \ ++ '--nographics' ++ diff --git a/0013-Update-common-submodule.patch b/0013-Update-common-submodule.patch new file mode 100644 index 0000000..6840853 --- /dev/null +++ b/0013-Update-common-submodule.patch @@ -0,0 +1,61 @@ +From 2d808c89eee6369df62b3afe16681a41ca42e0b9 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sat, 20 Sep 2025 17:20:25 +0100 +Subject: [PATCH] Update common submodule + +Richard W.M. Jones (3): + mlstdutils: Export List.find_opt + daemon, generator: Use power of 2 for initial size of Hashtbl.create + mlcustomize/inject_virtio_win.ml: Use viostor.inf instead of guestor + +See-also: https://github.com/libguestfs/libguestfs-common/pull/17 +(cherry picked from commit 13bcff3c2ca3e7ad355527a13b3aa2941ec1ff5b) +--- + common | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Submodule common 7ecf3992b..da55dc4d7: +diff --git a/common/mlcustomize/customize_run.ml b/common/mlcustomize/customize_run.ml +index ff719f4ec..64afd3ab5 100644 +--- a/common/mlcustomize/customize_run.ml ++++ b/common/mlcustomize/customize_run.ml +@@ -97,7 +97,7 @@ let run (g : G.guestfs) root (ops : ops) = + ) in + + (* Store the passwords and set them all at the end. *) +- let passwords = Hashtbl.create 13 in ++ let passwords = Hashtbl.create 16 in + let set_password user pw = + if Hashtbl.mem passwords user then + error (f_"multiple --root-password/--password options set the \ +diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml +index b26b14d34..114df0641 100644 +--- a/common/mlcustomize/inject_virtio_win.ml ++++ b/common/mlcustomize/inject_virtio_win.ml +@@ -310,8 +310,13 @@ and ddb_regedits inspect drv_name drv_pciid = + * one must add keys into the DriverDatabase. + *) + ++ let winarch = ++ match inspect.i_arch with ++ | "i386" -> "x86" | "x86_64" -> "amd64" ++ | _ -> assert false in ++ + let drv_inf = "guestor.inf" in +- let drv_inf_label = drv_inf ^ "_tmp" in ++ let drv_inf_label = sprintf "%s_%s_0000000000000000" drv_inf winarch in + let drv_config = "guestor_conf" in + + [ +diff --git a/common/mlstdutils/std_utils.mli b/common/mlstdutils/std_utils.mli +index a20e720c2..6c1911da8 100644 +--- a/common/mlstdutils/std_utils.mli ++++ b/common/mlstdutils/std_utils.mli +@@ -46,6 +46,7 @@ module List : sig + val mem : 'a -> 'a list -> bool + val memq : 'a -> 'a list -> bool + val find : ('a -> bool) -> 'a list -> 'a ++ val find_opt : ('a -> bool) -> 'a list -> 'a option + val filter : ('a -> bool) -> 'a list -> 'a list + val find_all : ('a -> bool) -> 'a list -> 'a list + val partition : ('a -> bool) -> 'a list -> 'a list * 'a list diff --git a/0014-common-update-submodule.patch b/0014-common-update-submodule.patch new file mode 100644 index 0000000..ea8e00e --- /dev/null +++ b/0014-common-update-submodule.patch @@ -0,0 +1,427 @@ +From 5ed99959b689fc6fa287d9c6100e92a18bc1c9be Mon Sep 17 00:00:00 2001 +From: Cole Robinson +Date: Tue, 14 Oct 2025 14:07:40 -0400 +Subject: [PATCH] common: update submodule + +Cole Robinson (1): + mlcustomize: deprecate and remove --sm-* options + +Signed-off-by: Cole Robinson +(cherry picked from commit 57b225d8d324d15d79fab2ccc6944868c1168a42) +--- + common | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Submodule common da55dc4d7..90399dd18: +diff --git a/common/mlcustomize/Makefile.am b/common/mlcustomize/Makefile.am +index 6e03bfea3..351524c80 100644 +--- a/common/mlcustomize/Makefile.am ++++ b/common/mlcustomize/Makefile.am +@@ -47,7 +47,6 @@ SOURCES_MLI = \ + random_seed.mli \ + SELinux_relabel.mli \ + ssh_key.mli \ +- subscription_manager.mli \ + timezone.mli + + # This list must be in dependency order. +@@ -58,7 +57,6 @@ SOURCES_ML = \ + perl_edit.ml \ + random_seed.ml \ + ssh_key.ml \ +- subscription_manager.ml \ + timezone.ml \ + crypt.ml \ + password.ml \ +diff --git a/common/mlcustomize/customize-options.pod b/common/mlcustomize/customize-options.pod +index 157145ebc..c8de3953c 100644 +--- a/common/mlcustomize/customize-options.pod ++++ b/common/mlcustomize/customize-options.pod +@@ -392,35 +392,6 @@ It cannot delete directories, only regular files. + + This is a compatibility option that does nothing. + +-=item B<--sm-attach> SELECTOR +- +-Attach to a pool using C. +- +-See L for the format of +-the C field. +- +-=item B<--sm-credentials> SELECTOR +- +-Set the credentials for C. +- +-See L for the format of +-the C field. +- +-=item B<--sm-register> +- +-Register the guest using C. +- +-This requires credentials being set using I<--sm-credentials>. +- +-=item B<--sm-remove> +- +-Remove all the subscriptions from the guest using +-C. +- +-=item B<--sm-unregister> +- +-Unregister the guest using C. +- + =item B<--ssh-inject> USER[:SELECTOR] + + Inject an ssh key so the given C will be able to log in over +diff --git a/common/mlcustomize/customize-synopsis.pod b/common/mlcustomize/customize-synopsis.pod +index 957de8cf2..f5eeb69dd 100644 +--- a/common/mlcustomize/customize-synopsis.pod ++++ b/common/mlcustomize/customize-synopsis.pod +@@ -8,11 +8,10 @@ + [--install PKG,PKG..] [--link TARGET:LINK[:LINK..]] [--mkdir DIR] + [--move SOURCE:DEST] [--password USER:SELECTOR] + [--root-password SELECTOR] [--run SCRIPT] +- [--run-command 'CMD+ARGS'] [--scrub FILE] [--sm-attach SELECTOR] +- [--sm-register] [--sm-remove] [--sm-unregister] ++ [--run-command 'CMD+ARGS'] [--scrub FILE] + [--ssh-inject USER[:SELECTOR]] [--tar-in TARFILE:REMOTEDIR] + [--timezone TIMEZONE] [--touch FILE] [--truncate FILE] + [--truncate-recursive PATH] [--uninstall PKG,PKG..] [--update] + [--upload FILE:DEST] [--write FILE:CONTENT] [--no-logfile] + [--password-crypto md5|sha256|sha512] [--no-selinux-relabel] +- [--selinux-relabel] [--sm-credentials SELECTOR] ++ [--selinux-relabel] +diff --git a/common/mlcustomize/customize_cmdline.ml b/common/mlcustomize/customize_cmdline.ml +index 7451f1325..786f4ee49 100644 +--- a/common/mlcustomize/customize_cmdline.ml ++++ b/common/mlcustomize/customize_cmdline.ml +@@ -85,14 +85,6 @@ and op = [ + (* --run-command 'CMD+ARGS' *) + | `Scrub of string + (* --scrub FILE *) +- | `SMAttach of Subscription_manager.sm_pool +- (* --sm-attach SELECTOR *) +- | `SMRegister +- (* --sm-register *) +- | `SMRemove +- (* --sm-remove *) +- | `SMUnregister +- (* --sm-unregister *) + | `SSHInject of string * Ssh_key.ssh_key_selector + (* --ssh-inject USER[:SELECTOR] *) + | `TarIn of string * string +@@ -123,8 +115,6 @@ and flags = { + (* --no-selinux-relabel *) + selinux_relabel_ignored : bool; + (* --selinux-relabel *) +- sm_credentials : Subscription_manager.sm_credentials option; +- (* --sm-credentials SELECTOR *) + } + + type argspec = Getopt.keys * Getopt.spec * Getopt.doc +@@ -135,7 +125,6 @@ let rec argspec ?(v2v = false) () = + let password_crypto = ref None in + let no_selinux_relabel = ref false in + let selinux_relabel_ignored = ref false in +- let sm_credentials = ref None in + + let rec get_ops () = { + ops = List.rev !ops; +@@ -146,7 +135,6 @@ let rec argspec ?(v2v = false) () = + password_crypto = !password_crypto; + no_selinux_relabel = !no_selinux_relabel; + selinux_relabel_ignored = !selinux_relabel_ignored; +- sm_credentials = !sm_credentials; + } + in + +@@ -386,35 +374,6 @@ let rec argspec ?(v2v = false) () = + s_"Scrub a file" + ), + Some "FILE", "Scrub a file from the guest. This is like I<--delete> except that:\n\n=over 4\n\n=item *\n\nIt scrubs the data so a guest could not recover it.\n\n=item *\n\nIt cannot delete directories, only regular files.\n\n=back", false; +- ( +- [ L"sm-attach" ], +- Getopt.String ( +- s_"SELECTOR", +- fun s -> +- let sel = Subscription_manager.parse_pool_selector s in +- List.push_front (`SMAttach sel) ops +- ), +- s_"Attach to a subscription-manager pool" +- ), +- Some "SELECTOR", "Attach to a pool using C.\n\nSee L for the format of\nthe C field.", false; +- ( +- [ L"sm-register" ], +- Getopt.Unit (fun () -> List.push_front `SMRegister ops), +- s_"Register using subscription-manager" +- ), +- None, "Register the guest using C.\n\nThis requires credentials being set using I<--sm-credentials>.", false; +- ( +- [ L"sm-remove" ], +- Getopt.Unit (fun () -> List.push_front `SMRemove ops), +- s_"Remove all the subscriptions" +- ), +- None, "Remove all the subscriptions from the guest using\nC.", false; +- ( +- [ L"sm-unregister" ], +- Getopt.Unit (fun () -> List.push_front `SMUnregister ops), +- s_"Unregister using subscription-manager" +- ), +- None, "Unregister the guest using C.", false; + ( + [ L"ssh-inject" ], + Getopt.String ( +@@ -529,16 +488,6 @@ let rec argspec ?(v2v = false) () = + s_"Compatibility option doing nothing" + ), + None, "This is a compatibility option that does nothing.", false; +- ( +- [ L"sm-credentials" ], +- Getopt.String ( +- s_"SELECTOR", +- fun s -> +- sm_credentials := Some (Subscription_manager.parse_credentials_selector s) +- ), +- s_"Credentials for subscription-manager" +- ), +- Some "SELECTOR", "Set the credentials for C.\n\nSee L for the format of\nthe C field.", false; + ] + and customize_read_from_file filename = + let forbidden_commands = [ +diff --git a/common/mlcustomize/customize_cmdline.mli b/common/mlcustomize/customize_cmdline.mli +index cc32f3af4..baacda9d3 100644 +--- a/common/mlcustomize/customize_cmdline.mli ++++ b/common/mlcustomize/customize_cmdline.mli +@@ -77,14 +77,6 @@ and op = [ + (* --run-command 'CMD+ARGS' *) + | `Scrub of string + (* --scrub FILE *) +- | `SMAttach of Subscription_manager.sm_pool +- (* --sm-attach SELECTOR *) +- | `SMRegister +- (* --sm-register *) +- | `SMRemove +- (* --sm-remove *) +- | `SMUnregister +- (* --sm-unregister *) + | `SSHInject of string * Ssh_key.ssh_key_selector + (* --ssh-inject USER[:SELECTOR] *) + | `TarIn of string * string +@@ -115,8 +107,6 @@ and flags = { + (* --no-selinux-relabel *) + selinux_relabel_ignored : bool; + (* --selinux-relabel *) +- sm_credentials : Subscription_manager.sm_credentials option; +- (* --sm-credentials SELECTOR *) + } + + type argspec = Getopt.keys * Getopt.spec * Getopt.doc +diff --git a/common/mlcustomize/customize_run.ml b/common/mlcustomize/customize_run.ml +index 64afd3ab5..1baf0f3cf 100644 +--- a/common/mlcustomize/customize_run.ml ++++ b/common/mlcustomize/customize_run.ml +@@ -279,43 +279,6 @@ let run (g : G.guestfs) root (ops : ops) = + message (f_"Scrubbing: %s") path; + g#scrub_file path + +- | `SMAttach pool -> +- (match pool with +- | Subscription_manager.PoolAuto -> +- message (f_"Attaching to compatible subscriptions"); +- let cmd = "subscription-manager attach --auto" in +- do_run ~display:cmd ~warn_failed_no_network:true cmd +- | Subscription_manager.PoolId id -> +- message (f_"Attaching to the pool %s") id; +- let cmd = sprintf "subscription-manager attach --pool=%s" (quote id) in +- do_run ~display:cmd ~warn_failed_no_network:true cmd +- ) +- +- | `SMRegister -> +- message (f_"Registering with subscription-manager"); +- let creds = +- match ops.flags.sm_credentials with +- | None -> +- error (f_"subscription-manager credentials required for \ +- --sm-register") +- | Some c -> c in +- let cmd = sprintf "subscription-manager register \ +- --username=%s --password=%s" +- (quote creds.Subscription_manager.sm_username) +- (quote creds.Subscription_manager.sm_password) in +- do_run ~display:"subscription-manager register" +- ~warn_failed_no_network:true cmd +- +- | `SMRemove -> +- message (f_"Removing all the subscriptions"); +- let cmd = "subscription-manager remove --all" in +- do_run ~display:cmd ~warn_failed_no_network:true cmd +- +- | `SMUnregister -> +- message (f_"Unregistering with subscription-manager"); +- let cmd = "subscription-manager unregister" in +- do_run ~display:cmd ~warn_failed_no_network:true cmd +- + | `SSHInject (user, selector) -> + if unix_like (g#inspect_get_type root) then ( + message (f_"SSH key inject: %s") user; +diff --git a/common/mlcustomize/subscription_manager.ml b/common/mlcustomize/subscription_manager.ml +deleted file mode 100644 +index 104602462..000000000 +--- a/common/mlcustomize/subscription_manager.ml ++++ /dev/null +@@ -1,54 +0,0 @@ +-(* virt-customize +- * Copyright (C) 2015 Red Hat Inc. +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +- *) +- +-open Std_utils +-open Tools_utils +-open Common_gettext.Gettext +- +-type sm_credentials = { +- sm_username : string; +- sm_password : string; +-} +- +-type sm_pool = +-| PoolAuto +-| PoolId of string +- +-let rec parse_credentials_selector arg = +- parse_credentials_selector_list arg (String.nsplit ":" arg) +- +-and parse_credentials_selector_list orig_arg = function +- | [ username; "password"; password ] -> +- { sm_username = username; sm_password = password } +- | [ username; "file"; filename ] -> +- { sm_username = username; sm_password = read_first_line_from_file filename } +- | _ -> +- error (f_"invalid sm-credentials selector ‘%s’; see the man page") orig_arg +- +-let rec parse_pool_selector arg = +- parse_pool_selector_list arg (String.nsplit ":" arg) +- +-and parse_pool_selector_list orig_arg = function +- | [ "auto" ] -> +- PoolAuto +- | [ "pool"; pool ] -> +- PoolId pool +- | [ "file"; filename ] -> +- PoolId (read_first_line_from_file filename) +- | _ -> +- error (f_"invalid sm-attach selector ‘%s’; see the man page") orig_arg +diff --git a/common/mlcustomize/subscription_manager.mli b/common/mlcustomize/subscription_manager.mli +deleted file mode 100644 +index bb6b92014..000000000 +--- a/common/mlcustomize/subscription_manager.mli ++++ /dev/null +@@ -1,34 +0,0 @@ +-(* virt-customize +- * Copyright (C) 2015 Red Hat Inc. +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +- *) +- +-type sm_credentials = { +- sm_username : string; +- sm_password : string; +-} +- +-type sm_pool = +-| PoolAuto (** Automatic entitlements. *) +-| PoolId of string (** Specific pool. *) +- +-val parse_credentials_selector : string -> sm_credentials +-(** Parse the selector field in --sm-credentials. Exits if the format +- is not valid. *) +- +-val parse_pool_selector : string -> sm_pool +-(** Parse the selector field in --sm-attach. Exits if the format +- is not valid. *) +diff --git a/common/mlcustomize/v2v-customize-options.pod b/common/mlcustomize/v2v-customize-options.pod +index 0974f4592..f02f05dac 100644 +--- a/common/mlcustomize/v2v-customize-options.pod ++++ b/common/mlcustomize/v2v-customize-options.pod +@@ -338,35 +338,6 @@ It cannot delete directories, only regular files. + + This is a compatibility option that does nothing. + +-=item B<--sm-attach> SELECTOR +- +-Attach to a pool using C. +- +-See L for the format of +-the C field. +- +-=item B<--sm-credentials> SELECTOR +- +-Set the credentials for C. +- +-See L for the format of +-the C field. +- +-=item B<--sm-register> +- +-Register the guest using C. +- +-This requires credentials being set using I<--sm-credentials>. +- +-=item B<--sm-remove> +- +-Remove all the subscriptions from the guest using +-C. +- +-=item B<--sm-unregister> +- +-Unregister the guest using C. +- + =item B<--ssh-inject> USER[:SELECTOR] + + Inject an ssh key so the given C will be able to log in over +diff --git a/common/mlcustomize/v2v-customize-synopsis.pod b/common/mlcustomize/v2v-customize-synopsis.pod +index 7eb0a941c..4c1a1547b 100644 +--- a/common/mlcustomize/v2v-customize-synopsis.pod ++++ b/common/mlcustomize/v2v-customize-synopsis.pod +@@ -7,11 +7,9 @@ + [--link TARGET:LINK[:LINK..]] [--mkdir DIR] [--move SOURCE:DEST] + [--password USER:SELECTOR] [--root-password SELECTOR] + [--run SCRIPT] [--run-command 'CMD+ARGS'] [--scrub FILE] +- [--sm-attach SELECTOR] [--sm-register] [--sm-remove] +- [--sm-unregister] [--ssh-inject USER[:SELECTOR]] +- [--tar-in TARFILE:REMOTEDIR] [--timezone TIMEZONE] [--touch FILE] +- [--truncate FILE] [--truncate-recursive PATH] +- [--uninstall PKG,PKG..] [--update] [--upload FILE:DEST] +- [--write FILE:CONTENT] [--no-logfile] ++ [--ssh-inject USER[:SELECTOR]] [--tar-in TARFILE:REMOTEDIR] ++ [--timezone TIMEZONE] [--touch FILE] [--truncate FILE] ++ [--truncate-recursive PATH] [--uninstall PKG,PKG..] [--update] ++ [--upload FILE:DEST] [--write FILE:CONTENT] [--no-logfile] + [--password-crypto md5|sha256|sha512] [--no-selinux-relabel] +- [--selinux-relabel] [--sm-credentials SELECTOR] ++ [--selinux-relabel] diff --git a/0015-pod-Document-removal-of-sm-options.patch b/0015-pod-Document-removal-of-sm-options.patch new file mode 100644 index 0000000..c2448a6 --- /dev/null +++ b/0015-pod-Document-removal-of-sm-options.patch @@ -0,0 +1,150 @@ +From de70086dbe2eb8a6ec023ebbd0c84489a8719ba1 Mon Sep 17 00:00:00 2001 +From: Cole Robinson +Date: Tue, 14 Oct 2025 14:16:19 -0400 +Subject: [PATCH] pod: Document removal of --sm-* options + +Update podcheck.pl to allow for still documenting these +in virt-builder.pod + +Signed-off-by: Cole Robinson +(cherry picked from commit 7bad703d724cd976cc3b7760b09af353aab46ff0) +--- + builder/virt-builder.pod | 73 +++++++++++++----------------------- + customize/virt-customize.pod | 8 ++++ + podcheck.pl | 13 ++++++- + 3 files changed, 46 insertions(+), 48 deletions(-) + +diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod +index ff0ec250c..f043939ca 100644 +--- a/builder/virt-builder.pod ++++ b/builder/virt-builder.pod +@@ -878,53 +878,6 @@ F. + + =back + +-=head2 SUBSCRIPTION-MANAGER +- +-It is possible to automate the registration and attaching of the +-system using C. This is typical on +-Red Hat Enterprise Linux guests. There are few options which ease +-this process, avoid executing commands manually and exposing +-passwords on command line. +- +-I<--sm-register> starts the registration process, and requires +-I<--sm-credentials> to be specified; the format of the C +-of I<--sm-credentials> is one of the following formats: +- +-=over 4 +- +-=item B<--sm-credentials> USER:file:FILENAME +- +-Read the password for the specified C from F. +- +-=item B<--sm-credentials> USER:password:PASSWORD +- +-Use the literal string C for the specified C. +- +-=back +- +-I<--sm-attach> attaches the system to subscriptions; the format +-of its C is one of the following: +- +-=over 4 +- +-=item B<--sm-attach> auto +- +-C attaches to the best-fitting subscriptions +-for the system. +- +-=item B<--sm-attach> file:FILENAME +- +-Read the pool ID from F. +- +-=item B<--sm-attach> pool:POOL +- +-Use the literal string C as pool ID. +- +-=back +- +-I<--sm-remove> removes all the subscriptions from the guest, while +-I<--sm-unregister> completely unregister the system. +- + =head2 INSTALLATION PROCESS + + When you invoke virt-builder, installation proceeds as follows: +@@ -1764,6 +1717,32 @@ them, which is normal and harmless. + + =back + ++=head2 DEPRECATED OPTIONS ++ ++In version 1.56 the subscription-manager options were removed. ++ ++=over 4 ++ ++=item B<--sm-credentials> ++ ++=item B<--sm-register> ++ ++Use --run='subscription-manager register --username=USER --password=PASS' ++ ++=item B<--sm-unregister> ++ ++Use --run='subscription-manager unregister' ++ ++=item B<--sm-attach> ++ ++Use --run='subscription-manager attach ...' ++ ++=item B<--sm-remove> ++ ++Use --run='subscription-manager remove --all' ++ ++=back ++ + =head1 MACHINE READABLE OUTPUT + + The I<--machine-readable> option can be used to make the output more +diff --git a/customize/virt-customize.pod b/customize/virt-customize.pod +index fb3d65665..9fee64ebc 100644 +--- a/customize/virt-customize.pod ++++ b/customize/virt-customize.pod +@@ -248,6 +248,14 @@ existing ones. + + For further details, see L. + ++=head1 DEPRECATED OPTIONS ++ ++In version 1.56 the subscription-manager options were removed: ++B<--sm-credentials>, B<--sm-register>, B<--sm-unregister>, ++B<--sm-attach>, B<--sm-remove> ++ ++For further details, see L. ++ + =head1 EXIT STATUS + + This program returns 0 on success, or 1 if there was an error. +diff --git a/podcheck.pl b/podcheck.pl +index 795fe0e9b..047bbf8da 100755 +--- a/podcheck.pl ++++ b/podcheck.pl +@@ -203,7 +203,18 @@ my $pod_options_checked = 0; + + my %pod_options = (); + $pod_options{$_} = 1 foreach ( $content =~ /^=item.*B<(-[-\w]+)(?:=.*)?>/gm ); +-foreach (sort keys %pod_options) { ++ ++my %pod_option_exists = (); ++$pod_option_exists{$_} = 1 foreach keys %pod_options; ++ ++# Removed from the tool but we still document them ++delete $pod_option_exists{"--sm-credentials"}; ++delete $pod_option_exists{"--sm-register"}; ++delete $pod_option_exists{"--sm-unregister"}; ++delete $pod_option_exists{"--sm-remove"}; ++delete $pod_option_exists{"--sm-attach"}; ++ ++foreach (sort keys %pod_option_exists) { + unless ($ignore{$_}) { + $pod_options_checked++; + unless (exists $tool_option_exists{$_}) { diff --git a/0016-test-data-phony-guests-Increase-size-of-Windows-imag.patch b/0016-test-data-phony-guests-Increase-size-of-Windows-imag.patch new file mode 100644 index 0000000..438b686 --- /dev/null +++ b/0016-test-data-phony-guests-Increase-size-of-Windows-imag.patch @@ -0,0 +1,31 @@ +From 269302e1a500d3cba94194faa258f6b47fef88fb Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 4 Nov 2025 13:04:12 +0000 +Subject: [PATCH] test-data/phony-guests: Increase size of Windows image + +For testing I tried to upload a very large Windows registry to the +phony Windows image. However because of the 256M limit on the size of +the second partition (and NTFS overhead?) this was not possible. + +There's no real penalty to increasing the size of this image since +it's just virtual space, so increase the virtual size to 2G (256M/1.7G +split). + +(cherry picked from commit a39ae0b898825970549876738bd465f6a110de7c) +--- + test-data/phony-guests/make-windows-img.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh +index 0ec6b4851..e72013c3d 100755 +--- a/test-data/phony-guests/make-windows-img.sh ++++ b/test-data/phony-guests/make-windows-img.sh +@@ -37,7 +37,7 @@ fi + + # Create a disk image. + guestfish < +Date: Mon, 3 Nov 2025 15:26:19 +0000 +Subject: [PATCH] inspector: Add new field to output of virt-inspector + +Rebase common submodule to pick up: + + Richard W.M. Jones (1): + structs/structs-print.c: Update this generated file + +Fixes: https://issues.redhat.com/browse/RHEL-125955 +(cherry picked from commit 53e59d0189dc71d78559478c4924f1a1a994c455) +--- + common | 2 +- + inspector/inspector.c | 2 ++ + inspector/virt-inspector.rng | 1 + + m4/guestfs-libraries.m4 | 3 ++- + 4 files changed, 6 insertions(+), 2 deletions(-) + +Submodule common 90399dd18..b54ba2031: +diff --git a/common/structs/structs-print.c b/common/structs/structs-print.c +index bfe007cde..8c376b0ee 100644 +--- a/common/structs/structs-print.c ++++ b/common/structs/structs-print.c +@@ -63,7 +63,7 @@ guestfs_int_print_application2_indent (struct guestfs_application2 *application2 + fprintf (dest, "%sapp2_source_package: %s%s", indent, application2->app2_source_package, linesep); + fprintf (dest, "%sapp2_summary: %s%s", indent, application2->app2_summary, linesep); + fprintf (dest, "%sapp2_description: %s%s", indent, application2->app2_description, linesep); +- fprintf (dest, "%sapp2_spare1: %s%s", indent, application2->app2_spare1, linesep); ++ fprintf (dest, "%sapp2_class: %s%s", indent, application2->app2_class, linesep); + fprintf (dest, "%sapp2_spare2: %s%s", indent, application2->app2_spare2, linesep); + fprintf (dest, "%sapp2_spare3: %s%s", indent, application2->app2_spare3, linesep); + fprintf (dest, "%sapp2_spare4: %s%s", indent, application2->app2_spare4, linesep); +diff --git a/inspector/inspector.c b/inspector/inspector.c +index 1177f44a4..cccc209d0 100644 +--- a/inspector/inspector.c ++++ b/inspector/inspector.c +@@ -697,6 +697,8 @@ output_applications (xmlTextWriterPtr xo, char *root) + single_element ("summary", apps->val[i].app2_summary); + if (apps->val[i].app2_description && apps->val[i].app2_description[0]) + single_element ("description", apps->val[i].app2_description); ++ if (apps->val[i].app2_class && apps->val[i].app2_class[0]) ++ single_element ("class", apps->val[i].app2_class); + } end_element (); + } + } end_element (); +diff --git a/inspector/virt-inspector.rng b/inspector/virt-inspector.rng +index 29c5798e1..e30686d4f 100644 +--- a/inspector/virt-inspector.rng ++++ b/inspector/virt-inspector.rng +@@ -212,6 +212,7 @@ + + + ++ + + + +diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4 +index 82e62d54f..4ca86161c 100644 +--- a/m4/guestfs-libraries.m4 ++++ b/m4/guestfs-libraries.m4 +@@ -20,7 +20,8 @@ dnl Any C libraries required by the libguestfs C library (not the daemon). + dnl Of course we need libguestfs. + dnl + dnl We need libguestfs 1.57.1 for guestfs_setfiles. +-PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.57.1]) ++dnl We need libguestfs 1.57.6 for guestfs_inspect_get_applications2 app2_class. ++PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.57.6]) + printf "libguestfs version is "; $PKG_CONFIG --modversion libguestfs + + dnl Test if it's GNU or XSI strerror_r. diff --git a/0018-inspector-Add-windows_group_policy-is-Windows-GPOs-d.patch b/0018-inspector-Add-windows_group_policy-is-Windows-GPOs-d.patch new file mode 100644 index 0000000..0a162c0 --- /dev/null +++ b/0018-inspector-Add-windows_group_policy-is-Windows-GPOs-d.patch @@ -0,0 +1,52 @@ +From c715ed2a3b82ce6cfcd44fbb8a29476621ebe049 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 3 Nov 2025 15:56:56 +0000 +Subject: [PATCH] inspector: Add is Windows GPOs + detected in guest + +Fixes: https://issues.redhat.com/browse/RHEL-125955 +(cherry picked from commit d56129cfccedd26739ee5b813060e7547d977c53) +--- + inspector/inspector.c | 3 +++ + inspector/virt-inspector.rng | 1 + + m4/guestfs-libraries.m4 | 1 + + 3 files changed, 5 insertions(+) + +diff --git a/inspector/inspector.c b/inspector/inspector.c +index cccc209d0..6b5d50157 100644 +--- a/inspector/inspector.c ++++ b/inspector/inspector.c +@@ -439,6 +439,9 @@ output_root (xmlTextWriterPtr xo, char *root) + if (str) + single_element ("windows_current_control_set", str); + free (str); ++ i = guestfs_inspect_get_windows_group_policy (g, root); ++ if (i > 0) ++ empty_element ("windows_group_policy"); + guestfs_pop_error_handler (g); + + str = guestfs_inspect_get_hostname (g, root); +diff --git a/inspector/virt-inspector.rng b/inspector/virt-inspector.rng +index e30686d4f..90f74cf78 100644 +--- a/inspector/virt-inspector.rng ++++ b/inspector/virt-inspector.rng +@@ -35,6 +35,7 @@ + + + ++ + + + +diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4 +index 4ca86161c..02f2281f8 100644 +--- a/m4/guestfs-libraries.m4 ++++ b/m4/guestfs-libraries.m4 +@@ -21,6 +21,7 @@ dnl Of course we need libguestfs. + dnl + dnl We need libguestfs 1.57.1 for guestfs_setfiles. + dnl We need libguestfs 1.57.6 for guestfs_inspect_get_applications2 app2_class. ++dnl We need libguestfs 1.57.6 for guestfs_inspect_get_windows_group_policy + PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.57.6]) + printf "libguestfs version is "; $PKG_CONFIG --modversion libguestfs + diff --git a/0001-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch b/0019-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch similarity index 84% rename from 0001-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch rename to 0019-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch index 801f617..0bf950c 100644 --- a/0001-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch +++ b/0019-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch @@ -1,4 +1,4 @@ -From e827be5bb317f3d50086e2987ee88cd931e1f1b1 Mon Sep 17 00:00:00 2001 +From 185264d510814eb1e14c770aa826c82d6a747bb3 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 7 Jul 2015 09:28:03 -0400 Subject: [PATCH] RHEL: Reject use of libguestfs-winsupport features except for @@ -11,7 +11,7 @@ edits. 1 file changed, 1 insertion(+) diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh -index 16debd129..1c13ddac3 100755 +index e72013c3d..ac661f180 100755 --- a/test-data/phony-guests/make-windows-img.sh +++ b/test-data/phony-guests/make-windows-img.sh @@ -37,6 +37,7 @@ fi @@ -19,6 +19,6 @@ index 16debd129..1c13ddac3 100755 # Create a disk image. guestfish < Date: Mon, 21 Nov 2022 13:03:22 +0000 Subject: [PATCH] RHEL: builder: Disable opensuse repository diff --git a/0021-inspector-For-xfs-try-to-find-and-print-the-filesyst.patch b/0021-inspector-For-xfs-try-to-find-and-print-the-filesyst.patch new file mode 100644 index 0000000..c570698 --- /dev/null +++ b/0021-inspector-For-xfs-try-to-find-and-print-the-filesyst.patch @@ -0,0 +1,139 @@ +From 6c1ea9c15b78274ea0907aa6a1214c294101aa6a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 26 Jan 2026 15:26:23 +0000 +Subject: [PATCH] inspector: For xfs, try to find and print the filesystem + version + +RHEL 7.0, 7.1 and (possibly*) 7.2 used XFS version 4. New versions of +RHEL use XFS v5. + +Support even for opening version 4 filesystems was removed in RHEL 10 +(and will be removed altogether from the Linux kernel in 2030). This +prevents virt-v2v conversions or libguestfs in general from accessing +those filesystems. + +Therefore it's a good idea to be able to tell the XFS filesystem +version and print that in virt-inspector output. + +The new output will look like: + + + + xfs + 35904e42-4e3d-40c7-a4ef-213786c18339 + + +To work this requires libguestfs >= 1.59.2 (with guestfs_xfs_info2). +Older versions of libguestfs, or if we cannot tell the version, will +not have the version attribute. + +* = The virt-builder rhel-7.2 image definitely uses XFS v4, but it may +have been built from an early (pre-)release of 7.2. Later RHEL 7.2 +seems to use XFS v5. + +Fixes: https://issues.redhat.com/browse/RHEL-144074 +(cherry picked from commit bb210ca4330bc307d972201faf713d4c3c49fc6a) +--- + inspector/inspector.c | 54 ++++++++++++++++++++++++++++++++---- + inspector/virt-inspector.rng | 9 +++++- + 2 files changed, 56 insertions(+), 7 deletions(-) + +diff --git a/inspector/inspector.c b/inspector/inspector.c +index 6b5d50157..fc6b9f0d0 100644 +--- a/inspector/inspector.c ++++ b/inspector/inspector.c +@@ -569,6 +569,42 @@ output_mountpoints (xmlTextWriterPtr xo, char *root) + } end_element (); + } + ++static const char * ++get_filesystem_version (const char *dev, const char *fs_type) ++{ ++ const char *version = NULL; ++ ++#ifdef GUESTFS_HAVE_XFS_INFO2 ++ /* For type=xfs, try to guess the filesystem version. */ ++ if (STREQ (fs_type, "xfs")) { ++ CLEANUP_FREE_STRING_LIST char **hash = NULL; ++ size_t i; ++ ++ guestfs_push_error_handler (g, NULL, NULL); ++ ++ hash = guestfs_xfs_info2 (g, dev); ++ if (hash) { ++ for (i = 0; hash[i] != NULL; i += 2) { ++ if (STREQ (hash[i], "meta-data.crc")) { ++ if (STREQ (hash[i+1], "0")) ++ version = "4"; ++ else if (STREQ (hash[i+1], "1")) ++ version = "5"; ++ break; ++ } ++ /* If new XFS versions are added in future then we can test ++ * for new fields here ... ++ */ ++ } ++ } ++ ++ guestfs_pop_error_handler (g); ++ } ++#endif /* GUESTFS_HAVE_XFS_INFO2 */ ++ ++ return version; ++} ++ + static void + output_filesystems (xmlTextWriterPtr xo, char *root) + { +@@ -586,19 +622,25 @@ output_filesystems (xmlTextWriterPtr xo, char *root) + + start_element ("filesystems") { + for (i = 0; filesystems[i] != NULL; ++i) { +- str = guestfs_canonical_device_name (g, filesystems[i]); +- if (!str) ++ CLEANUP_FREE char *dev = ++ guestfs_canonical_device_name (g, filesystems[i]); ++ if (!dev) + exit (EXIT_FAILURE); + + start_element ("filesystem") { +- attribute ("dev", str); +- free (str); ++ attribute ("dev", dev); + + guestfs_push_error_handler (g, NULL, NULL); + + str = guestfs_vfs_type (g, filesystems[i]); +- if (str && str[0]) +- single_element ("type", str); ++ if (str && str[0]) { ++ const char *version = get_filesystem_version (dev, str); ++ start_element ("type") { ++ if (version) ++ attribute ("version", version); ++ string (str); ++ } end_element (); ++ } + free (str); + + str = guestfs_vfs_label (g, filesystems[i]); +diff --git a/inspector/virt-inspector.rng b/inspector/virt-inspector.rng +index 90f74cf78..aeec082ff 100644 +--- a/inspector/virt-inspector.rng ++++ b/inspector/virt-inspector.rng +@@ -175,7 +175,14 @@ + + + +- ++ ++ ++ ++ ++ ++ ++ ++ + + + diff --git a/0022-Sort-some-entries-in-.gitignore-into-order.patch b/0022-Sort-some-entries-in-.gitignore-into-order.patch new file mode 100644 index 0000000..8524eb5 --- /dev/null +++ b/0022-Sort-some-entries-in-.gitignore-into-order.patch @@ -0,0 +1,35 @@ +From 706d6dfd2a36d1b176f2a64d897b249eeec4d80f Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 5 Feb 2026 11:57:33 +0000 +Subject: [PATCH] Sort some entries in .gitignore into order + +(cherry picked from commit 9d7161da76160b2e5d1f3488b3f0a652554d2077) +--- + .gitignore | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/.gitignore b/.gitignore +index 94f77ac74..023686435 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -81,9 +81,9 @@ Makefile.in + /cat/virt-ls + /cat/virt-tail + /config.cache +-/config.log + /config.h + /config.h.in ++/config.log + /config.sh + /config.status + /configure +@@ -112,8 +112,8 @@ Makefile.in + /ocaml-dep.sh + /ocaml-link.sh + /po-docs/*/*.pod +-/podwrapper.pl + /po/*.gmo ++/podwrapper.pl + /resize/.depend + /resize/virt-resize + /run diff --git a/0023-build-Add-NULL-as-a-convenient-list-terminator.patch b/0023-build-Add-NULL-as-a-convenient-list-terminator.patch new file mode 100644 index 0000000..53a67c8 --- /dev/null +++ b/0023-build-Add-NULL-as-a-convenient-list-terminator.patch @@ -0,0 +1,35 @@ +From c9022d24dbfb5d715668fd810716753d096648f0 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 22 Sep 2025 10:58:29 +0100 +Subject: [PATCH] build: Add $(NULL) as a convenient list terminator + +When building lists of things in Makefiles it's convenient to have a +list terminator to avoid hanging backslash problems. eg: + + EXTRA_DIST = \ + thing1 \ + thing2 \ + $(NULL) + +Cherry picked from virt-v2v commit 09b86c07bf19beba9ccb8fcca0ebfae34dd56406 + +(cherry picked from commit dad8c0d3803dcbc91e22ca35c630d9e8a01df81b) +--- + common-rules.mk | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/common-rules.mk b/common-rules.mk +index 4df1e33f1..7a116c827 100644 +--- a/common-rules.mk ++++ b/common-rules.mk +@@ -20,6 +20,10 @@ + + -include $(top_builddir)/localenv + ++# Convenient way to terminate lists in Makefiles, so that we avoid ++# problems with dangling backslashes. ++NULL = ++ + # Files that should universally be removed by 'make clean'. Note if + # there is any case in any subdirectory where a file should not be + # removed by 'make clean', it should not be listed here! diff --git a/0024-Move-virt-filesystems-virt-log-virt-ls-virt-tail-to-.patch b/0024-Move-virt-filesystems-virt-log-virt-ls-virt-tail-to-.patch new file mode 100644 index 0000000..5b38e35 --- /dev/null +++ b/0024-Move-virt-filesystems-virt-log-virt-ls-virt-tail-to-.patch @@ -0,0 +1,1032 @@ +From fb38dacf4992404401e31535761bbf7f465a10b7 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 5 Feb 2026 11:56:40 +0000 +Subject: [PATCH] Move virt-filesystems, virt-log, virt-ls, virt-tail to new + directories + +For historical reasons these unrelated tools were all placed into the +cat/ subdirectory (with virt-cat). As this makes no sense, move them +to their own directories. + +(cherry picked from commit 291cc520ffbe2b5986067b2ce754c3a532066d85) +--- + .gitignore | 10 +- + Makefile.am | 3 +- + cat/Makefile.am | 205 +----------------- + cat/test-docs.sh | 9 - + configure.ac | 4 + + filesystems/Makefile.am | 88 ++++++++ + {cat => filesystems}/filesystems.c | 0 + filesystems/test-docs.sh | 26 +++ + {cat => filesystems}/test-virt-filesystems.sh | 0 + {cat => filesystems}/virt-filesystems.pod | 0 + log/Makefile.am | 83 +++++++ + {cat => log}/log.c | 0 + log/test-docs.sh | 26 +++ + {cat => log}/test-virt-log.sh | 0 + {cat => log}/virt-log.pod | 0 + ls/Makefile.am | 85 ++++++++ + {cat => ls}/ls.c | 0 + ls/test-docs.sh | 27 +++ + {cat => ls}/test-virt-ls.sh | 0 + {cat => ls}/virt-ls.pod | 0 + po-docs/podfiles | 8 +- + po/POTFILES | 8 +- + run.in | 4 + + tail/Makefile.am | 84 +++++++ + {cat => tail}/tail.c | 0 + tail/test-docs.sh | 26 +++ + {cat => tail}/test-virt-tail.sh | 0 + {cat => tail}/virt-tail.pod | 0 + 28 files changed, 476 insertions(+), 220 deletions(-) + create mode 100644 filesystems/Makefile.am + rename {cat => filesystems}/filesystems.c (100%) + create mode 100755 filesystems/test-docs.sh + rename {cat => filesystems}/test-virt-filesystems.sh (100%) + rename {cat => filesystems}/virt-filesystems.pod (100%) + create mode 100644 log/Makefile.am + rename {cat => log}/log.c (100%) + create mode 100755 log/test-docs.sh + rename {cat => log}/test-virt-log.sh (100%) + rename {cat => log}/virt-log.pod (100%) + create mode 100644 ls/Makefile.am + rename {cat => ls}/ls.c (100%) + create mode 100755 ls/test-docs.sh + rename {cat => ls}/test-virt-ls.sh (100%) + rename {cat => ls}/virt-ls.pod (100%) + create mode 100644 tail/Makefile.am + rename {cat => tail}/tail.c (100%) + create mode 100755 tail/test-docs.sh + rename {cat => tail}/test-virt-tail.sh (100%) + rename {cat => tail}/virt-tail.pod (100%) + +diff --git a/.gitignore b/.gitignore +index 023686435..ed850a20f 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -76,10 +76,6 @@ Makefile.in + /builder/virt-index-validate + /builder/*.xz + /cat/virt-cat +-/cat/virt-filesystems +-/cat/virt-log +-/cat/virt-ls +-/cat/virt-tail + /config.cache + /config.h + /config.h.in +@@ -92,17 +88,20 @@ Makefile.in + /customize/test-settings-*.sh + /customize/virt-customize + /df/virt-df ++/diff/virt-diff + /drivers/.depend + /drivers/hwdata_config.ml + /drivers/virt-drivers +-/diff/virt-diff + /edit/virt-edit ++/filesystems/virt-filesystems + /format/virt-format + /get-kernel/.depend + /get-kernel/virt-get-kernel + /inspector/actual-*.xml + /inspector/virt-inspector + /libtool ++/log/virt-log ++/ls/virt-ls + /m4/libtool.m4 + /m4/ltoptions.m4 + /m4/ltsugar.m4 +@@ -128,6 +127,7 @@ Makefile.in + /sysprep/sysprep-operations.pod + /sysprep/sysprep_operation_*.mli + /sysprep/virt-sysprep ++/tail/virt-tail + /test-data/blank-disks/blank-disk-* + /test-data/fake-virtio-win/fake-virtio-win.iso + /test-data/phony-guests/archlinux.img +diff --git a/Makefile.am b/Makefile.am +index b831ce7fe..7be3c1496 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -51,7 +51,8 @@ SUBDIRS += test-data + SUBDIRS += tests + + # virt-tools in C. +-SUBDIRS += align cat diff df edit format inspector make-fs ++SUBDIRS += align cat diff df edit filesystems format inspector ++SUBDIRS += log ls make-fs tail + + if HAVE_OCAML + # OCaml tools. Note 'common/ml*' and 'customize' contain shared code +diff --git a/cat/Makefile.am b/cat/Makefile.am +index 5569da185..483bf0913 100644 +--- a/cat/Makefile.am ++++ b/cat/Makefile.am +@@ -1,5 +1,5 @@ +-# libguestfs virt-cat, virt-filesystems, virt-log, virt-ls and virt-tail. +-# Copyright (C) 2010-2025 Red Hat Inc. ++# libguestfs virt-cat ++# Copyright (C) 2010-2026 Red Hat Inc. + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -21,19 +21,11 @@ EXTRA_DIST = \ + test-docs.sh \ + test-virt-cat.sh \ + virt-cat.pod \ +- test-virt-filesystems.sh \ +- virt-filesystems.pod \ +- test-virt-log.sh \ +- virt-log.pod \ +- test-virt-ls.sh \ +- virt-ls.pod \ +- test-virt-tail.sh \ +- virt-tail.pod ++ $(NULL) + +-bin_PROGRAMS = virt-cat virt-filesystems virt-log virt-ls virt-tail ++bin_PROGRAMS = virt-cat + +-virt_cat_SOURCES = \ +- cat.c ++virt_cat_SOURCES = cat.c + + virt_cat_CPPFLAGS = \ + -DGUESTFS_NO_DEPRECATED=1 \ +@@ -62,135 +54,10 @@ virt_cat_LDADD = \ + $(LTLIBINTL) \ + ../gnulib/lib/libgnu.la + +-virt_filesystems_SOURCES = \ +- filesystems.c +- +-virt_filesystems_CPPFLAGS = \ +- -DGUESTFS_NO_DEPRECATED=1 \ +- -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ +- -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ +- -I$(top_srcdir)/common/structs -I$(top_builddir)/common/structs \ +- -I$(top_srcdir)/lib -I$(top_builddir)/lib \ +- -I$(top_srcdir)/include \ +- -I$(top_srcdir)/common/options -I$(top_builddir)/common/options \ +- -I$(top_srcdir)/common/windows -I$(top_builddir)/common/windows \ +- -I$(srcdir)/../gnulib/lib -I../gnulib/lib +- +-virt_filesystems_CFLAGS = \ +- $(WARN_CFLAGS) $(WERROR_CFLAGS) \ +- $(LIBXML2_CFLAGS) \ +- $(LIBGUESTFS_CFLAGS) +- +-virt_filesystems_LDADD = \ +- $(top_builddir)/common/options/liboptions.la \ +- $(top_builddir)/common/windows/libwindows.la \ +- $(top_builddir)/common/structs/libstructs.la \ +- $(top_builddir)/common/utils/libutils.la \ +- $(LIBGUESTFS_LIBS) \ +- $(LIBXML2_LIBS) \ +- $(LIBVIRT_LIBS) \ +- $(LTLIBINTL) \ +- ../gnulib/lib/libgnu.la +- +-virt_log_SOURCES = \ +- log.c +- +-virt_log_CPPFLAGS = \ +- -DGUESTFS_NO_DEPRECATED=1 \ +- -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ +- -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ +- -I$(top_srcdir)/common/structs -I$(top_builddir)/common/structs \ +- -I$(top_srcdir)/lib -I$(top_builddir)/lib \ +- -I$(top_srcdir)/include \ +- -I$(top_srcdir)/common/options -I$(top_builddir)/common/options \ +- -I$(top_srcdir)/common/windows -I$(top_builddir)/common/windows \ +- -I$(srcdir)/../gnulib/lib -I../gnulib/lib +- +-virt_log_CFLAGS = \ +- $(WARN_CFLAGS) $(WERROR_CFLAGS) \ +- $(LIBXML2_CFLAGS) \ +- $(LIBGUESTFS_CFLAGS) +- +-virt_log_LDADD = \ +- $(top_builddir)/common/options/liboptions.la \ +- $(top_builddir)/common/structs/libstructs.la \ +- $(top_builddir)/common/utils/libutils.la \ +- $(LIBGUESTFS_LIBS) \ +- $(LIBXML2_LIBS) \ +- $(LIBVIRT_LIBS) \ +- $(LTLIBINTL) \ +- ../gnulib/lib/libgnu.la +- +-virt_ls_SOURCES = \ +- ls.c +- +-virt_ls_CPPFLAGS = \ +- -DGUESTFS_NO_DEPRECATED=1 \ +- -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ +- -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ +- -I$(top_srcdir)/common/structs -I$(top_builddir)/common/structs \ +- -I$(top_srcdir)/lib -I$(top_builddir)/lib \ +- -I$(top_srcdir)/include \ +- -I$(top_srcdir)/common/visit \ +- -I$(top_srcdir)/common/options -I$(top_builddir)/common/options \ +- -I$(top_srcdir)/common/windows -I$(top_builddir)/common/windows \ +- -I$(srcdir)/../gnulib/lib -I../gnulib/lib +- +-virt_ls_CFLAGS = \ +- $(WARN_CFLAGS) $(WERROR_CFLAGS) \ +- $(LIBXML2_CFLAGS) \ +- $(LIBGUESTFS_CFLAGS) +- +-virt_ls_LDADD = \ +- $(top_builddir)/common/options/liboptions.la \ +- $(top_builddir)/common/visit/libvisit.la \ +- $(top_builddir)/common/structs/libstructs.la \ +- $(top_builddir)/common/utils/libutils.la \ +- $(LIBGUESTFS_LIBS) \ +- $(LIBXML2_LIBS) \ +- $(LIBVIRT_LIBS) \ +- $(LTLIBINTL) \ +- ../gnulib/lib/libgnu.la +- +-virt_tail_SOURCES = \ +- tail.c +- +-virt_tail_CPPFLAGS = \ +- -DGUESTFS_NO_DEPRECATED=1 \ +- -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ +- -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ +- -I$(top_srcdir)/common/structs -I$(top_builddir)/common/structs \ +- -I$(top_srcdir)/lib -I$(top_builddir)/lib \ +- -I$(top_srcdir)/include \ +- -I$(top_srcdir)/common/options -I$(top_builddir)/common/options \ +- -I$(top_srcdir)/common/windows -I$(top_builddir)/common/windows \ +- -I$(srcdir)/../gnulib/lib -I../gnulib/lib +- +-virt_tail_CFLAGS = \ +- $(WARN_CFLAGS) $(WERROR_CFLAGS) \ +- $(LIBXML2_CFLAGS) \ +- $(LIBGUESTFS_CFLAGS) +- +-virt_tail_LDADD = \ +- $(top_builddir)/common/options/liboptions.la \ +- $(top_builddir)/common/windows/libwindows.la \ +- $(top_builddir)/common/structs/libstructs.la \ +- $(top_builddir)/common/utils/libutils.la \ +- $(LIBGUESTFS_LIBS) \ +- $(LIBXML2_LIBS) \ +- $(LIBVIRT_LIBS) \ +- $(LTLIBINTL) \ +- ../gnulib/lib/libgnu.la +- + # Manual pages and HTML files for the website. +-man_MANS = virt-cat.1 virt-filesystems.1 virt-log.1 virt-ls.1 virt-tail.1 ++man_MANS = virt-cat.1 + +-noinst_DATA = \ +- $(top_builddir)/website/virt-cat.1.html \ +- $(top_builddir)/website/virt-filesystems.1.html \ +- $(top_builddir)/website/virt-log.1.html \ +- $(top_builddir)/website/virt-ls.1.html \ +- $(top_builddir)/website/virt-tail.1.html ++noinst_DATA = $(top_builddir)/website/virt-cat.1.html + + virt-cat.1 $(top_builddir)/website/virt-cat.1.html: stamp-virt-cat.pod + +@@ -204,54 +71,6 @@ stamp-virt-cat.pod: virt-cat.pod + $< + touch $@ + +-virt-filesystems.1 $(top_builddir)/website/virt-filesystems.1.html: stamp-virt-filesystems.pod +- +-stamp-virt-filesystems.pod: virt-filesystems.pod +- $(PODWRAPPER) \ +- --man virt-filesystems.1 \ +- --html $(top_builddir)/website/virt-filesystems.1.html \ +- --path $(top_srcdir)/common/options \ +- --license GPLv2+ \ +- --warning safe \ +- $< +- touch $@ +- +-virt-log.1 $(top_builddir)/website/virt-log.1.html: stamp-virt-log.pod +- +-stamp-virt-log.pod: virt-log.pod +- $(PODWRAPPER) \ +- --man virt-log.1 \ +- --html $(top_builddir)/website/virt-log.1.html \ +- --path $(top_srcdir)/common/options \ +- --license GPLv2+ \ +- --warning safe \ +- $< +- touch $@ +- +-virt-ls.1 $(top_builddir)/website/virt-ls.1.html: stamp-virt-ls.pod +- +-stamp-virt-ls.pod: virt-ls.pod +- $(PODWRAPPER) \ +- --man virt-ls.1 \ +- --html $(top_builddir)/website/virt-ls.1.html \ +- --path $(top_srcdir)/common/options \ +- --license GPLv2+ \ +- --warning safe \ +- $< +- touch $@ +- +-virt-tail.1 $(top_builddir)/website/virt-tail.1.html: stamp-virt-tail.pod +- +-stamp-virt-tail.pod: virt-tail.pod +- $(PODWRAPPER) \ +- --man virt-tail.1 \ +- --html $(top_builddir)/website/virt-tail.1.html \ +- --path $(top_srcdir)/common/options \ +- --license GPLv2+ \ +- --warning safe \ +- $< +- touch $@ +- + # Tests. + + TESTS_ENVIRONMENT = $(top_builddir)/run --test +@@ -259,15 +78,7 @@ TESTS_ENVIRONMENT = $(top_builddir)/run --test + TESTS = \ + test-docs.sh \ + test-virt-cat.sh \ +- test-virt-filesystems.sh \ +- test-virt-log.sh \ +- test-virt-ls.sh \ +- test-virt-tail.sh ++ $(NULL) + + check-valgrind: + $(MAKE) VG="@VG@" check +- +-check-valgrind-local-guests: +- for g in $(GUESTS); do \ +- $(top_builddir)/run --test @VG@ virt-filesystems -c "$(libvirt_ro_uri)" -d "$$g" --all --long -h --uuid || exit $$?; \ +- done +diff --git a/cat/test-docs.sh b/cat/test-docs.sh +index bca349b52..31a17f31a 100755 +--- a/cat/test-docs.sh ++++ b/cat/test-docs.sh +@@ -24,12 +24,3 @@ skip_if_skipped + + $top_srcdir/podcheck.pl "$srcdir/virt-cat.pod" virt-cat \ + --path $top_srcdir/common/options +-$top_srcdir/podcheck.pl "$srcdir/virt-filesystems.pod" virt-filesystems \ +- --path $top_srcdir/common/options +-$top_srcdir/podcheck.pl "$srcdir/virt-log.pod" virt-log \ +- --path $top_srcdir/common/options +-$top_srcdir/podcheck.pl "$srcdir/virt-ls.pod" virt-ls \ +- --path $top_srcdir/common/options \ +- --ignore=--checksums,--extra-stat,--time,--uid +-$top_srcdir/podcheck.pl "$srcdir/virt-tail.pod" virt-tail \ +- --path $top_srcdir/common/options +diff --git a/configure.ac b/configure.ac +index 015c16823..998be7b9f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -157,10 +157,13 @@ AC_CONFIG_FILES([Makefile + drivers/Makefile + drivers/hwdata_config.ml + edit/Makefile ++ filesystems/Makefile + format/Makefile + get-kernel/Makefile + gnulib/lib/Makefile + inspector/Makefile ++ log/Makefile ++ ls/Makefile + make-fs/Makefile + po-docs/Makefile + po-docs/ja/Makefile +@@ -169,6 +172,7 @@ AC_CONFIG_FILES([Makefile + resize/Makefile + sparsify/Makefile + sysprep/Makefile ++ tail/Makefile + test-data/Makefile + test-data/binaries/Makefile + test-data/blank-disks/Makefile +diff --git a/filesystems/Makefile.am b/filesystems/Makefile.am +new file mode 100644 +index 000000000..17e3b9c6f +--- /dev/null ++++ b/filesystems/Makefile.am +@@ -0,0 +1,88 @@ ++# libguestfs virt-filesystems ++# Copyright (C) 2010-2026 Red Hat Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ ++include $(top_srcdir)/subdir-rules.mk ++ ++EXTRA_DIST = \ ++ test-docs.sh \ ++ test-virt-filesystems.sh \ ++ virt-filesystems.pod \ ++ $(NULL) ++ ++bin_PROGRAMS = virt-filesystems ++ ++virt_filesystems_SOURCES = filesystems.c ++ ++virt_filesystems_CPPFLAGS = \ ++ -DGUESTFS_NO_DEPRECATED=1 \ ++ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ ++ -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ ++ -I$(top_srcdir)/common/structs -I$(top_builddir)/common/structs \ ++ -I$(top_srcdir)/lib -I$(top_builddir)/lib \ ++ -I$(top_srcdir)/include \ ++ -I$(top_srcdir)/common/options -I$(top_builddir)/common/options \ ++ -I$(top_srcdir)/common/windows -I$(top_builddir)/common/windows \ ++ -I$(srcdir)/../gnulib/lib -I../gnulib/lib ++ ++virt_filesystems_CFLAGS = \ ++ $(WARN_CFLAGS) $(WERROR_CFLAGS) \ ++ $(LIBXML2_CFLAGS) \ ++ $(LIBGUESTFS_CFLAGS) ++ ++virt_filesystems_LDADD = \ ++ $(top_builddir)/common/options/liboptions.la \ ++ $(top_builddir)/common/windows/libwindows.la \ ++ $(top_builddir)/common/structs/libstructs.la \ ++ $(top_builddir)/common/utils/libutils.la \ ++ $(LIBGUESTFS_LIBS) \ ++ $(LIBXML2_LIBS) \ ++ $(LIBVIRT_LIBS) \ ++ $(LTLIBINTL) \ ++ ../gnulib/lib/libgnu.la ++ ++# Manual pages and HTML files for the website. ++man_MANS = virt-filesystems.1 ++ ++noinst_DATA = $(top_builddir)/website/virt-filesystems.1.html ++ ++virt-filesystems.1 $(top_builddir)/website/virt-filesystems.1.html: stamp-virt-filesystems.pod ++ ++stamp-virt-filesystems.pod: virt-filesystems.pod ++ $(PODWRAPPER) \ ++ --man virt-filesystems.1 \ ++ --html $(top_builddir)/website/virt-filesystems.1.html \ ++ --path $(top_srcdir)/common/options \ ++ --license GPLv2+ \ ++ --warning safe \ ++ $< ++ touch $@ ++# Tests. ++ ++TESTS_ENVIRONMENT = $(top_builddir)/run --test ++ ++TESTS = \ ++ test-docs.sh \ ++ test-virt-filesystems.sh \ ++ $(NULL) ++ ++check-valgrind: ++ $(MAKE) VG="@VG@" check ++ ++check-valgrind-local-guests: ++ for g in $(GUESTS); do \ ++ $(top_builddir)/run --test @VG@ virt-filesystems -c "$(libvirt_ro_uri)" -d "$$g" --all --long -h --uuid || exit $$?; \ ++ done +diff --git a/cat/filesystems.c b/filesystems/filesystems.c +similarity index 100% +rename from cat/filesystems.c +rename to filesystems/filesystems.c +diff --git a/filesystems/test-docs.sh b/filesystems/test-docs.sh +new file mode 100755 +index 000000000..03c37dbb8 +--- /dev/null ++++ b/filesystems/test-docs.sh +@@ -0,0 +1,26 @@ ++#!/bin/bash - ++# libguestfs ++# Copyright (C) 2016 Red Hat Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ ++source ../tests/functions.sh ++set -e ++set -x ++ ++skip_if_skipped ++ ++$top_srcdir/podcheck.pl "$srcdir/virt-filesystems.pod" virt-filesystems \ ++ --path $top_srcdir/common/options +diff --git a/cat/test-virt-filesystems.sh b/filesystems/test-virt-filesystems.sh +similarity index 100% +rename from cat/test-virt-filesystems.sh +rename to filesystems/test-virt-filesystems.sh +diff --git a/cat/virt-filesystems.pod b/filesystems/virt-filesystems.pod +similarity index 100% +rename from cat/virt-filesystems.pod +rename to filesystems/virt-filesystems.pod +diff --git a/log/Makefile.am b/log/Makefile.am +new file mode 100644 +index 000000000..790dcbf98 +--- /dev/null ++++ b/log/Makefile.am +@@ -0,0 +1,83 @@ ++# libguestfs virt-log ++# Copyright (C) 2010-2026 Red Hat Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ ++include $(top_srcdir)/subdir-rules.mk ++ ++EXTRA_DIST = \ ++ test-docs.sh \ ++ test-virt-log.sh \ ++ virt-log.pod \ ++ $(NULL) ++ ++bin_PROGRAMS = virt-log ++ ++virt_log_SOURCES = log.c ++ ++virt_log_CPPFLAGS = \ ++ -DGUESTFS_NO_DEPRECATED=1 \ ++ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ ++ -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ ++ -I$(top_srcdir)/common/structs -I$(top_builddir)/common/structs \ ++ -I$(top_srcdir)/lib -I$(top_builddir)/lib \ ++ -I$(top_srcdir)/include \ ++ -I$(top_srcdir)/common/options -I$(top_builddir)/common/options \ ++ -I$(top_srcdir)/common/windows -I$(top_builddir)/common/windows \ ++ -I$(srcdir)/../gnulib/lib -I../gnulib/lib ++ ++virt_log_CFLAGS = \ ++ $(WARN_CFLAGS) $(WERROR_CFLAGS) \ ++ $(LIBXML2_CFLAGS) \ ++ $(LIBGUESTFS_CFLAGS) ++ ++virt_log_LDADD = \ ++ $(top_builddir)/common/options/liboptions.la \ ++ $(top_builddir)/common/structs/libstructs.la \ ++ $(top_builddir)/common/utils/libutils.la \ ++ $(LIBGUESTFS_LIBS) \ ++ $(LIBXML2_LIBS) \ ++ $(LIBVIRT_LIBS) \ ++ $(LTLIBINTL) \ ++ ../gnulib/lib/libgnu.la ++ ++# Manual pages and HTML files for the website. ++man_MANS = virt-log.1 ++ ++noinst_DATA = $(top_builddir)/website/virt-log.1.html ++ ++virt-log.1 $(top_builddir)/website/virt-log.1.html: stamp-virt-log.pod ++ ++stamp-virt-log.pod: virt-log.pod ++ $(PODWRAPPER) \ ++ --man virt-log.1 \ ++ --html $(top_builddir)/website/virt-log.1.html \ ++ --path $(top_srcdir)/common/options \ ++ --license GPLv2+ \ ++ --warning safe \ ++ $< ++ touch $@ ++ ++# Tests. ++ ++TESTS_ENVIRONMENT = $(top_builddir)/run --test ++ ++TESTS = \ ++ test-docs.sh \ ++ test-virt-log.sh \ ++ $(NULL) ++ ++check-valgrind: ++ $(MAKE) VG="@VG@" check +diff --git a/cat/log.c b/log/log.c +similarity index 100% +rename from cat/log.c +rename to log/log.c +diff --git a/log/test-docs.sh b/log/test-docs.sh +new file mode 100755 +index 000000000..fff8ccf30 +--- /dev/null ++++ b/log/test-docs.sh +@@ -0,0 +1,26 @@ ++#!/bin/bash - ++# libguestfs ++# Copyright (C) 2016 Red Hat Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ ++source ../tests/functions.sh ++set -e ++set -x ++ ++skip_if_skipped ++ ++$top_srcdir/podcheck.pl "$srcdir/virt-log.pod" virt-log \ ++ --path $top_srcdir/common/options +diff --git a/cat/test-virt-log.sh b/log/test-virt-log.sh +similarity index 100% +rename from cat/test-virt-log.sh +rename to log/test-virt-log.sh +diff --git a/cat/virt-log.pod b/log/virt-log.pod +similarity index 100% +rename from cat/virt-log.pod +rename to log/virt-log.pod +diff --git a/ls/Makefile.am b/ls/Makefile.am +new file mode 100644 +index 000000000..c4b64b912 +--- /dev/null ++++ b/ls/Makefile.am +@@ -0,0 +1,85 @@ ++# libguestfs virt-log ++# Copyright (C) 2010-2026 Red Hat Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ ++include $(top_srcdir)/subdir-rules.mk ++ ++EXTRA_DIST = \ ++ test-docs.sh \ ++ test-virt-ls.sh \ ++ virt-ls.pod \ ++ $(NULL) ++ ++bin_PROGRAMS = virt-ls ++ ++virt_ls_SOURCES = ls.c ++ ++virt_ls_CPPFLAGS = \ ++ -DGUESTFS_NO_DEPRECATED=1 \ ++ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ ++ -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ ++ -I$(top_srcdir)/common/structs -I$(top_builddir)/common/structs \ ++ -I$(top_srcdir)/lib -I$(top_builddir)/lib \ ++ -I$(top_srcdir)/include \ ++ -I$(top_srcdir)/common/visit \ ++ -I$(top_srcdir)/common/options -I$(top_builddir)/common/options \ ++ -I$(top_srcdir)/common/windows -I$(top_builddir)/common/windows \ ++ -I$(srcdir)/../gnulib/lib -I../gnulib/lib ++ ++virt_ls_CFLAGS = \ ++ $(WARN_CFLAGS) $(WERROR_CFLAGS) \ ++ $(LIBXML2_CFLAGS) \ ++ $(LIBGUESTFS_CFLAGS) ++ ++virt_ls_LDADD = \ ++ $(top_builddir)/common/options/liboptions.la \ ++ $(top_builddir)/common/visit/libvisit.la \ ++ $(top_builddir)/common/structs/libstructs.la \ ++ $(top_builddir)/common/utils/libutils.la \ ++ $(LIBGUESTFS_LIBS) \ ++ $(LIBXML2_LIBS) \ ++ $(LIBVIRT_LIBS) \ ++ $(LTLIBINTL) \ ++ ../gnulib/lib/libgnu.la ++ ++# Manual pages and HTML files for the website. ++man_MANS = virt-ls.1 ++ ++noinst_DATA = $(top_builddir)/website/virt-ls.1.html ++ ++virt-ls.1 $(top_builddir)/website/virt-ls.1.html: stamp-virt-ls.pod ++ ++stamp-virt-ls.pod: virt-ls.pod ++ $(PODWRAPPER) \ ++ --man virt-ls.1 \ ++ --html $(top_builddir)/website/virt-ls.1.html \ ++ --path $(top_srcdir)/common/options \ ++ --license GPLv2+ \ ++ --warning safe \ ++ $< ++ touch $@ ++ ++# Tests. ++ ++TESTS_ENVIRONMENT = $(top_builddir)/run --test ++ ++TESTS = \ ++ test-docs.sh \ ++ test-virt-ls.sh \ ++ $(NULL) ++ ++check-valgrind: ++ $(MAKE) VG="@VG@" check +diff --git a/cat/ls.c b/ls/ls.c +similarity index 100% +rename from cat/ls.c +rename to ls/ls.c +diff --git a/ls/test-docs.sh b/ls/test-docs.sh +new file mode 100755 +index 000000000..e5e398368 +--- /dev/null ++++ b/ls/test-docs.sh +@@ -0,0 +1,27 @@ ++#!/bin/bash - ++# libguestfs ++# Copyright (C) 2016 Red Hat Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ ++source ../tests/functions.sh ++set -e ++set -x ++ ++skip_if_skipped ++ ++$top_srcdir/podcheck.pl "$srcdir/virt-ls.pod" virt-ls \ ++ --path $top_srcdir/common/options \ ++ --ignore=--checksums,--extra-stat,--time,--uid +diff --git a/cat/test-virt-ls.sh b/ls/test-virt-ls.sh +similarity index 100% +rename from cat/test-virt-ls.sh +rename to ls/test-virt-ls.sh +diff --git a/cat/virt-ls.pod b/ls/virt-ls.pod +similarity index 100% +rename from cat/virt-ls.pod +rename to ls/virt-ls.pod +diff --git a/po-docs/podfiles b/po-docs/podfiles +index 69ad52768..7fb4162dc 100644 +--- a/po-docs/podfiles ++++ b/po-docs/podfiles +@@ -3,10 +3,6 @@ builder/virt-builder-repository.pod + builder/virt-builder.pod + builder/virt-index-validate.pod + cat/virt-cat.pod +-cat/virt-filesystems.pod +-cat/virt-log.pod +-cat/virt-ls.pod +-cat/virt-tail.pod + common/mlcustomize/customize-options.pod + common/mlcustomize/customize-synopsis.pod + common/mlcustomize/v2v-customize-options.pod +@@ -23,13 +19,17 @@ docs/guestfs-tools-release-notes-1.52.pod + docs/guestfs-tools-release-notes-1.54.pod + drivers/virt-drivers.pod + edit/virt-edit.pod ++filesystems/virt-filesystems.pod + format/virt-format.pod + get-kernel/virt-get-kernel.pod + inspector/virt-inspector.pod ++log/virt-log.pod ++ls/virt-ls.pod + make-fs/virt-make-fs.pod + resize/virt-resize.pod + sparsify/virt-sparsify.pod + sysprep/sysprep-extra-options.pod + sysprep/sysprep-operations.pod + sysprep/virt-sysprep.pod ++tail/virt-tail.pod + win-reg/virt-win-reg.in +diff --git a/po/POTFILES b/po/POTFILES +index 396729c30..c540c4e29 100644 +--- a/po/POTFILES ++++ b/po/POTFILES +@@ -7,10 +7,6 @@ builder/index-validate.c + builder/pxzcat-c.c + builder/setlocale-c.c + cat/cat.c +-cat/filesystems.c +-cat/log.c +-cat/ls.c +-cat/tail.c + common/edit/file-edit.c + common/mlcustomize/crypt-c.c + common/mlcustomize/perl_edit-c.c +@@ -53,6 +49,10 @@ df/main.c + df/output.c + diff/diff.c + edit/edit.c ++filesystems/filesystems.c + format/format.c + inspector/inspector.c ++log/log.c ++ls/ls.c + make-fs/make-fs.c ++tail/tail.c +diff --git a/run.in b/run.in +index 741434a5a..e52d66c97 100755 +--- a/run.in ++++ b/run.in +@@ -78,14 +78,18 @@ prepend PATH "$b/diff" + prepend PATH "$b/drivers" + prepend PATH "$b/edit" + prepend PATH "$b/erlang" ++prepend PATH "$b/filesystems" + prepend PATH "$b/format" + prepend PATH "$b/fuse" + prepend PATH "$b/get-kernel" + prepend PATH "$b/inspector" ++prepend PATH "$b/log" ++prepend PATH "$b/ls" + prepend PATH "$b/make-fs" + prepend PATH "$b/resize" + prepend PATH "$b/sparsify" + prepend PATH "$b/sysprep" ++prepend PATH "$b/tail" + prepend PATH "$b/win-reg" + export PATH + +diff --git a/tail/Makefile.am b/tail/Makefile.am +new file mode 100644 +index 000000000..ac822b841 +--- /dev/null ++++ b/tail/Makefile.am +@@ -0,0 +1,84 @@ ++# libguestfs virt-tail. ++# Copyright (C) 2010-2026 Red Hat Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ ++include $(top_srcdir)/subdir-rules.mk ++ ++EXTRA_DIST = \ ++ test-docs.sh \ ++ test-virt-tail.sh \ ++ virt-tail.pod \ ++ $(NULL) ++ ++bin_PROGRAMS = virt-tail ++ ++virt_tail_SOURCES = tail.c ++ ++virt_tail_CPPFLAGS = \ ++ -DGUESTFS_NO_DEPRECATED=1 \ ++ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ ++ -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ ++ -I$(top_srcdir)/common/structs -I$(top_builddir)/common/structs \ ++ -I$(top_srcdir)/lib -I$(top_builddir)/lib \ ++ -I$(top_srcdir)/include \ ++ -I$(top_srcdir)/common/options -I$(top_builddir)/common/options \ ++ -I$(top_srcdir)/common/windows -I$(top_builddir)/common/windows \ ++ -I$(srcdir)/../gnulib/lib -I../gnulib/lib ++ ++virt_tail_CFLAGS = \ ++ $(WARN_CFLAGS) $(WERROR_CFLAGS) \ ++ $(LIBXML2_CFLAGS) \ ++ $(LIBGUESTFS_CFLAGS) ++ ++virt_tail_LDADD = \ ++ $(top_builddir)/common/options/liboptions.la \ ++ $(top_builddir)/common/windows/libwindows.la \ ++ $(top_builddir)/common/structs/libstructs.la \ ++ $(top_builddir)/common/utils/libutils.la \ ++ $(LIBGUESTFS_LIBS) \ ++ $(LIBXML2_LIBS) \ ++ $(LIBVIRT_LIBS) \ ++ $(LTLIBINTL) \ ++ ../gnulib/lib/libgnu.la ++ ++# Manual pages and HTML files for the website. ++man_MANS = virt-tail.1 ++ ++noinst_DATA = $(top_builddir)/website/virt-tail.1.html ++ ++virt-tail.1 $(top_builddir)/website/virt-tail.1.html: stamp-virt-tail.pod ++ ++stamp-virt-tail.pod: virt-tail.pod ++ $(PODWRAPPER) \ ++ --man virt-tail.1 \ ++ --html $(top_builddir)/website/virt-tail.1.html \ ++ --path $(top_srcdir)/common/options \ ++ --license GPLv2+ \ ++ --warning safe \ ++ $< ++ touch $@ ++ ++# Tests. ++ ++TESTS_ENVIRONMENT = $(top_builddir)/run --test ++ ++TESTS = \ ++ test-docs.sh \ ++ test-virt-tail.sh \ ++ $(NULL) ++ ++check-valgrind: ++ $(MAKE) VG="@VG@" check +diff --git a/cat/tail.c b/tail/tail.c +similarity index 100% +rename from cat/tail.c +rename to tail/tail.c +diff --git a/tail/test-docs.sh b/tail/test-docs.sh +new file mode 100755 +index 000000000..ffa114be6 +--- /dev/null ++++ b/tail/test-docs.sh +@@ -0,0 +1,26 @@ ++#!/bin/bash - ++# libguestfs ++# Copyright (C) 2016 Red Hat Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ ++source ../tests/functions.sh ++set -e ++set -x ++ ++skip_if_skipped ++ ++$top_srcdir/podcheck.pl "$srcdir/virt-tail.pod" virt-tail \ ++ --path $top_srcdir/common/options +diff --git a/cat/test-virt-tail.sh b/tail/test-virt-tail.sh +similarity index 100% +rename from cat/test-virt-tail.sh +rename to tail/test-virt-tail.sh +diff --git a/cat/virt-tail.pod b/tail/virt-tail.pod +similarity index 100% +rename from cat/virt-tail.pod +rename to tail/virt-tail.pod diff --git a/0025-filesystems-Optionally-display-filesystem-version.patch b/0025-filesystems-Optionally-display-filesystem-version.patch new file mode 100644 index 0000000..67f7da4 --- /dev/null +++ b/0025-filesystems-Optionally-display-filesystem-version.patch @@ -0,0 +1,473 @@ +From fb60205807bf7d8ccd7847abdfd532ed54f6614a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 5 Feb 2026 13:17:38 +0000 +Subject: [PATCH] filesystems: Optionally display filesystem version + +Unlike the recent change to virt-inspector (commit bb210ca433 +("inspector: For xfs, try to find and print the filesystem version")) +this does not require the ability to mount the XFS v4 filesystem so it +will work on RHEL 10. + + $ virt-filesystems -a rhel-7.0.img --long --fs-version + Name Type VFS Label Size Parent FSVersion + /dev/sda1 filesystem ext4 - 510873600 - - + /dev/sda3 filesystem xfs - 4820303872 - 4 + + $ virt-filesystems -a rhel-7.3.img --long --fs-version + Name Type VFS Label Size Parent FSVersion + /dev/sda1 filesystem ext4 - 510873600 - - + /dev/sda3 filesystem xfs - 4820303872 - 5 + +Fixes: https://issues.redhat.com/browse/RHEL-144074 +(cherry picked from commit fc61c9439d84fdaab71e1628eb5b95f18ff40ce1) +--- + .gitignore | 1 + + filesystems/Makefile.am | 6 +++- + filesystems/filesystems.c | 46 ++++++++++++++++++------ + filesystems/utils.c | 60 ++++++++++++++++++++++++++++++++ + filesystems/utils.h | 30 ++++++++++++++++ + filesystems/virt-filesystems.pod | 12 ++++++- + inspector/Makefile.am | 6 +++- + inspector/inspector.c | 39 ++------------------- + 8 files changed, 150 insertions(+), 50 deletions(-) + create mode 100644 filesystems/utils.c + create mode 100644 filesystems/utils.h + +diff --git a/.gitignore b/.gitignore +index ed850a20f..0b26da37b 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -18,6 +18,7 @@ + stamp-*.pod + + .deps ++.dirstamp + .libs + Makefile + Makefile.in +diff --git a/filesystems/Makefile.am b/filesystems/Makefile.am +index 17e3b9c6f..625592ff3 100644 +--- a/filesystems/Makefile.am ++++ b/filesystems/Makefile.am +@@ -25,7 +25,11 @@ EXTRA_DIST = \ + + bin_PROGRAMS = virt-filesystems + +-virt_filesystems_SOURCES = filesystems.c ++virt_filesystems_SOURCES = \ ++ filesystems.c \ ++ utils.c \ ++ utils.h \ ++ $(NULL) + + virt_filesystems_CPPFLAGS = \ + -DGUESTFS_NO_DEPRECATED=1 \ +diff --git a/filesystems/filesystems.c b/filesystems/filesystems.c +index ecaeb0bb2..e86d92be0 100644 +--- a/filesystems/filesystems.c ++++ b/filesystems/filesystems.c +@@ -39,6 +39,7 @@ + #include "structs-cleanups.h" + #include "options.h" + #include "display-options.h" ++#include "utils.h" + + /* These globals are shared with options.c. */ + guestfs_h *g; +@@ -75,7 +76,8 @@ static int output = 0; + #define COLUMN_SIZE 32 /* bytes, or human-readable if -h */ + #define COLUMN_PARENTS 64 + #define COLUMN_UUID 128 /* if --uuid */ +-#define NR_COLUMNS 8 ++#define COLUMN_FS_VERSION 256 /* if --fs-version */ ++#define NR_COLUMNS 9 + static int columns; + + static void do_output_title (void); +@@ -111,6 +113,8 @@ usage (int status) + " --extra Display swap and data filesystems\n" + " --filesystems Display mountable filesystems\n" + " --format[=raw|..] Force disk format for -a option\n" ++ " --fs-version|--fs-versions\n" ++ " Add filesystem version to --long output\n" + " -h|--human-readable Human-readable sizes in --long output\n" + " --help Display brief help\n" + " --keys-from-stdin Read passphrases from stdin\n" +@@ -157,6 +161,8 @@ main (int argc, char *argv[]) + { "extra", 0, 0, 0 }, + { "filesystems", 0, 0, 0 }, + { "format", 2, 0, 0 }, ++ { "fs-version", 0, 0, 0 }, ++ { "fs-versions", 0, 0, 0 }, + { "help", 0, 0, HELP_OPTION }, + { "human-readable", 0, 0, 'h' }, + { "keys-from-stdin", 0, 0, 0 }, +@@ -191,6 +197,7 @@ main (int argc, char *argv[]) + int no_title = 0; /* --no-title */ + int long_mode = 0; /* --long|-l */ + int uuid = 0; /* --uuid */ ++ int fs_version = 0; /* --fs-version */ + int title; + + g = guestfs_create (); +@@ -227,6 +234,9 @@ main (int argc, char *argv[]) + output |= OUTPUT_FILESYSTEMS_EXTRA; + } else if (STREQ (long_options[option_index].name, "filesystems")) { + output |= OUTPUT_FILESYSTEMS; ++ } else if (STREQ (long_options[option_index].name, "fs-version") || ++ STREQ (long_options[option_index].name, "fs-versions")) { ++ fs_version = 1; + } else if (STREQ (long_options[option_index].name, "logical-volumes") || + STREQ (long_options[option_index].name, "logvols") || + STREQ (long_options[option_index].name, "lvs")) { +@@ -337,6 +347,8 @@ main (int argc, char *argv[]) + columns |= COLUMN_MBR; + if (uuid) + columns |= COLUMN_UUID; ++ if (fs_version) ++ columns |= COLUMN_FS_VERSION; + } + + /* Display title by default only in long mode. */ +@@ -379,7 +391,7 @@ static void do_output_pvs (void); + static void do_output_partitions (void); + static void do_output_blockdevs (void); + +-static void write_row (const char *name, const char *type, const char *vfs_type, const char *vfs_label, int mbr_id, int64_t size, char **parents, const char *uuid); ++static void write_row (const char *name, const char *type, const char *vfs_type, const char *vfs_label, int mbr_id, int64_t size, char **parents, const char *uuid, const char *fs_version); + static void write_row_strings (char **strings, size_t len); + + static char **no_parents (void); +@@ -410,6 +422,8 @@ do_output_title (void) + headings[len++] = "Parent"; + if ((columns & COLUMN_UUID)) + headings[len++] = "UUID"; ++ if ((columns & COLUMN_FS_VERSION)) ++ headings[len++] = "FSVersion"; + assert (len <= NR_COLUMNS); + + write_row_strings ((char **) headings, len); +@@ -450,13 +464,15 @@ do_output_filesystems (void) + exit (EXIT_FAILURE); + + for (i = 0; fses[i] != NULL; i += 2) { ++ const char *fs_type = fses[i+1]; + CLEANUP_FREE char *dev = NULL, *vfs_label = NULL, *vfs_uuid = NULL; ++ CLEANUP_FREE char *fs_version = NULL; + CLEANUP_FREE_STRING_LIST char **parents = NULL; + int64_t size = -1; + + /* Skip swap and unknown, unless --extra flag was given. */ + if (!(output & OUTPUT_FILESYSTEMS_EXTRA) && +- (STREQ (fses[i+1], "swap") || STREQ (fses[i+1], "unknown"))) ++ (STREQ (fs_type, "swap") || STREQ (fs_type, "unknown"))) + continue; + + dev = guestfs_canonical_device_name (g, fses[i]); +@@ -486,6 +502,12 @@ do_output_filesystems (void) + error (EXIT_FAILURE, errno, "strdup"); + } + } ++ if ((columns & COLUMN_FS_VERSION)) { ++ const char *version = get_filesystem_version (g, fses[i], fs_type); ++ fs_version = strdup (version ? version : ""); ++ if (fs_version == NULL) ++ error (EXIT_FAILURE, errno, "strdup"); ++ } + if ((columns & COLUMN_SIZE)) { + CLEANUP_FREE char *device = guestfs_mountable_device (g, fses[i]); + CLEANUP_FREE char *subvolume = NULL; +@@ -533,7 +555,7 @@ do_output_filesystems (void) + parents = no_parents (); + + write_row (dev, "filesystem", +- fses[i+1], vfs_label, -1, size, parents, vfs_uuid); ++ fs_type, vfs_label, -1, size, parents, vfs_uuid, fs_version); + } + } + +@@ -573,7 +595,7 @@ do_output_lvs (void) + } + + write_row (lvs[i], "lv", +- NULL, NULL, -1, size, (char **) parents, uuid); ++ NULL, NULL, -1, size, (char **) parents, uuid, NULL); + } + } + +@@ -601,7 +623,8 @@ do_output_vgs (void) + parents = parents_of_vg (vgs->val[i].vg_name); + + write_row (name, "vg", +- NULL, NULL, -1, (int64_t) vgs->val[i].vg_size, parents, uuid); ++ NULL, NULL, -1, (int64_t) vgs->val[i].vg_size, parents, uuid, ++ NULL); + } + } + +@@ -649,7 +672,7 @@ do_output_pvs (void) + uuid[32] = '\0'; + write_row (dev, "pv", + NULL, NULL, -1, (int64_t) pvs->val[i].pv_size, +- (char **) parents, uuid); ++ (char **) parents, uuid, NULL); + } + } + +@@ -715,7 +738,7 @@ do_output_partitions (void) + } + + write_row (dev, "partition", +- NULL, NULL, mbr_id, size, (char **) parents, NULL); ++ NULL, NULL, mbr_id, size, (char **) parents, NULL, NULL); + } + } + +@@ -749,7 +772,7 @@ do_output_blockdevs (void) + parents = no_parents (); + + write_row (dev, "device", +- NULL, NULL, -1, size, parents, NULL); ++ NULL, NULL, -1, size, parents, NULL, NULL); + } + } + +@@ -882,7 +905,8 @@ parents_of_vg (char *vg) + static void + write_row (const char *name, const char *type, + const char *vfs_type, const char *vfs_label, int mbr_id, +- int64_t size, char **parents, const char *uuid) ++ int64_t size, char **parents, const char *uuid, ++ const char *fs_version) + { + const char *strings[NR_COLUMNS]; + CLEANUP_FREE char *parents_str = NULL; +@@ -930,6 +954,8 @@ write_row (const char *name, const char *type, + } + if ((columns & COLUMN_UUID)) + strings[len++] = uuid; ++ if ((columns & COLUMN_FS_VERSION)) ++ strings[len++] = fs_version; + assert (len <= NR_COLUMNS); + + write_row_strings ((char **) strings, len); +diff --git a/filesystems/utils.c b/filesystems/utils.c +new file mode 100644 +index 000000000..9de32f1bd +--- /dev/null ++++ b/filesystems/utils.c +@@ -0,0 +1,60 @@ ++/* Utility function used by virt-filesystems and virrt-inspector ++ * Copyright (C) 2026 Red Hat Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include ++ ++#include "guestfs.h" ++ ++#include "guestfs-utils.h" ++#include "utils.h" ++ ++const char * ++get_filesystem_version (guestfs_h *g, const char *dev, const char *fs_type) ++{ ++ const char *version = NULL; ++ ++#ifdef GUESTFS_HAVE_XFS_INFO2 ++ /* For type=xfs, try to guess the filesystem version. */ ++ if (STREQ (fs_type, "xfs")) { ++ CLEANUP_FREE_STRING_LIST char **hash = NULL; ++ size_t i; ++ ++ guestfs_push_error_handler (g, NULL, NULL); ++ ++ hash = guestfs_xfs_info2 (g, dev); ++ if (hash) { ++ for (i = 0; hash[i] != NULL; i += 2) { ++ if (STREQ (hash[i], "meta-data.crc")) { ++ if (STREQ (hash[i+1], "0")) ++ version = "4"; ++ else if (STREQ (hash[i+1], "1")) ++ version = "5"; ++ break; ++ } ++ /* If new XFS versions are added in future then we can test ++ * for new fields here ... ++ */ ++ } ++ } ++ ++ guestfs_pop_error_handler (g); ++ } ++#endif /* GUESTFS_HAVE_XFS_INFO2 */ ++ ++ return version; ++} +diff --git a/filesystems/utils.h b/filesystems/utils.h +new file mode 100644 +index 000000000..284f8e1ac +--- /dev/null ++++ b/filesystems/utils.h +@@ -0,0 +1,30 @@ ++/* Utility function used by virt-filesystems and virrt-inspector ++ * Copyright (C) 2026 Red Hat Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#ifndef GUESTFS_FILESYSTEMS_UTILS_H ++#define GUESTFS_FILESYSTEMS_UTILS_H ++ ++#include "guestfs.h" ++ ++/* For XFS, return the filesystem version (eg. "4" or "5"). This may ++ * return NULL if no filesystem version is known. ++ */ ++const char *get_filesystem_version (guestfs_h *g, ++ const char *dev, const char *fs_type); ++ ++#endif /* GUESTFS_FILESYSTEMS_UTILS_H */ +diff --git a/filesystems/virt-filesystems.pod b/filesystems/virt-filesystems.pod +index 7955d6a84..c72ae3cf7 100644 +--- a/filesystems/virt-filesystems.pod ++++ b/filesystems/virt-filesystems.pod +@@ -197,6 +197,14 @@ If you have untrusted raw-format guest disk images, you should use + this option to specify the disk format. This avoids a possible + security problem with malicious guests (CVE-2010-3851). + ++=item B<--fs-version> ++ ++=item B<--fs-versions> ++ ++In I<--long> mode, display the filesystem version. Currently this ++only has any effect for XFS, displaying either C<4> (for XFS v4) or ++C<5> (for XFS v5). XFS v4 support will be removed from Linux in 2030. ++ + =item B<-h> + + =item B<--human-readable> +@@ -221,7 +229,9 @@ external programs. + Use I<-h> if you want sizes to be displayed in human-readable format. + The default is to show raw numbers of I. + +-Use I<--uuid> to display UUIDs too. ++Use I<--fs-version> to display filesystem versions. ++ ++Use I<--uuid> to display UUIDs. + + =item B<--lvs> + +diff --git a/inspector/Makefile.am b/inspector/Makefile.am +index 04c608f44..637a10415 100644 +--- a/inspector/Makefile.am ++++ b/inspector/Makefile.am +@@ -48,7 +48,10 @@ dist_doc_DATA = \ + bin_PROGRAMS = virt-inspector + + virt_inspector_SOURCES = \ +- inspector.c ++ ../filesystems/utils.c \ ++ ../filesystems/utils.h \ ++ inspector.c \ ++ $(NULL) + + virt_inspector_CPPFLAGS = \ + -DGUESTFS_NO_DEPRECATED=1 \ +@@ -56,6 +59,7 @@ virt_inspector_CPPFLAGS = \ + -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ + -I$(top_srcdir)/common/structs -I$(top_builddir)/common/structs \ + -I$(top_srcdir)/lib -I$(top_builddir)/lib \ ++ -I$(top_srcdir)/filesystems -I$(top_builddir)/filesystems \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/common/options -I$(top_builddir)/common/options \ + -I$(top_srcdir)/fish \ +diff --git a/inspector/inspector.c b/inspector/inspector.c +index fc6b9f0d0..be34e8794 100644 +--- a/inspector/inspector.c ++++ b/inspector/inspector.c +@@ -44,6 +44,7 @@ + #include "options.h" + #include "display-options.h" + #include "libxml2-writer-macros.h" ++#include "utils.h" + + /* Currently open libguestfs handle. */ + guestfs_h *g; +@@ -569,42 +570,6 @@ output_mountpoints (xmlTextWriterPtr xo, char *root) + } end_element (); + } + +-static const char * +-get_filesystem_version (const char *dev, const char *fs_type) +-{ +- const char *version = NULL; +- +-#ifdef GUESTFS_HAVE_XFS_INFO2 +- /* For type=xfs, try to guess the filesystem version. */ +- if (STREQ (fs_type, "xfs")) { +- CLEANUP_FREE_STRING_LIST char **hash = NULL; +- size_t i; +- +- guestfs_push_error_handler (g, NULL, NULL); +- +- hash = guestfs_xfs_info2 (g, dev); +- if (hash) { +- for (i = 0; hash[i] != NULL; i += 2) { +- if (STREQ (hash[i], "meta-data.crc")) { +- if (STREQ (hash[i+1], "0")) +- version = "4"; +- else if (STREQ (hash[i+1], "1")) +- version = "5"; +- break; +- } +- /* If new XFS versions are added in future then we can test +- * for new fields here ... +- */ +- } +- } +- +- guestfs_pop_error_handler (g); +- } +-#endif /* GUESTFS_HAVE_XFS_INFO2 */ +- +- return version; +-} +- + static void + output_filesystems (xmlTextWriterPtr xo, char *root) + { +@@ -634,7 +599,7 @@ output_filesystems (xmlTextWriterPtr xo, char *root) + + str = guestfs_vfs_type (g, filesystems[i]); + if (str && str[0]) { +- const char *version = get_filesystem_version (dev, str); ++ const char *version = get_filesystem_version (g, dev, str); + start_element ("type") { + if (version) + attribute ("version", version); diff --git a/copy-patches.sh b/copy-patches.sh index 57ccf1f..041b67b 100755 --- a/copy-patches.sh +++ b/copy-patches.sh @@ -7,7 +7,7 @@ set -e # ./copy-patches.sh project=guestfs-tools -rhel_version=10.0 +rhel_version=10.2 # Check we're in the right directory. if [ ! -f $project.spec ]; then diff --git a/guestfs-tools-1.52.1.tar.gz.sig b/guestfs-tools-1.52.1.tar.gz.sig deleted file mode 100644 index d6c741b..0000000 --- a/guestfs-tools-1.52.1.tar.gz.sig +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAmbOSloRHHJpY2hAYW5u -ZXhpYS5vcmcACgkQkXOPc+G3aKDJJg/8Du104+cALOWOzI9MHz0LuHZ7U1umcOTy -uvJHKTpzfanzVXzd3gHQD7fKaQla9pp+m6nguYVfmw6sk0YGP6rKkS23WJpl3ubt -hqt2ozsoBcLnwtcO5OZiBLCxaw12HqTYBGXROvAu7iTsiHwQcXAoqJ0wVGFY2lyf -uBEVxYhLzSZ9k7yK6nQut7wE/GfXRG5uOBOnTz6pAZBMYed4/cOyjiQ+xgSkcdaJ -uJd5JYqwBRfdBFFKufUg691HN/Zqr+qFIIhdGC/1Jt7JAvVx+PvwZGjpU+erJLuV -/B4rghY5NoB5yrc8+8Mun2Juxnq0mQwqLFCFGGc/4qcBBW02jzwERxoBi80LRdqo -Ifikf1qgiDRPqpYrSRKQfjxtGAix2DJhHRAs3U4JXTlY4EE0ZPSqmo+Nd7cvtf16 -Y7BT/fZ8egRXGi5wRHfCghnLdLNDgt8bjPriEezYOxwH+YwhB9tAdVDN+wBpDyC9 -fTXoHHVFxMPaee0yMh+qlbD6BswivzPzDm6lRekI55d+IuPMdr8fcFUqZK/ZhC8V -izBI4JW8+ZPwfvONAbv3h+jg2g67KhBvrZdZRLcjlzS6x4NBKI2tnqCrxGksjoYg -Yxd/UCKrBR0O1+aXkYMkcbyCgO/IhKlPvrnmOEFRLHdRY0AE+8pI/ULtJXcCYaZt -gVLJpe2gPzs= -=yepi ------END PGP SIGNATURE----- diff --git a/guestfs-tools-1.54.0.tar.gz.sig b/guestfs-tools-1.54.0.tar.gz.sig new file mode 100644 index 0000000..a51e6a4 --- /dev/null +++ b/guestfs-tools-1.54.0.tar.gz.sig @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJFBAABCgAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAmgs7icRHHJpY2hAYW5u +ZXhpYS5vcmcACgkQkXOPc+G3aKAPvg/+K1KSQ7VrdxRkaUhXTVeiuSGGpdF8T+Rs +eROR6WivkbOet0E++EcOHL5fXneQUkXEI0t2tWSG9KRw236xDDsHsQAeA4eLjDJ3 +Tl0QaPho8uH4zOOHpw1IWflycJjrvMhdgPxeiI++PfeADPyDfzXTlPMQpJ+WjnJn +y+vousuCZfn4c1SStphMNXCDMoh4XEOKktpICg3DeswwdVb8FVFi4gNr+iI/0QuY +jQUbpZCZnxtgAvAHe7epttxRKQDz2HosHIED0rRYqh9cNtlk34awm6LtQnhPk3Hp +QF3nUy126uISohyd48TWiqCXnzK3+eJmnvxSv0xvTFKm/bXKTidXH25Na/R9o0Df +eE0M1boCuwTaXeO5kOuheJmFcd5NTJHHDF1uSpLtKxABszePYewLwyCTQg/qT2r6 +pab4VaLeSdJDJzvDXUwgZlfZflMg49eKMpa87ub0i7MuHkQgddURlkYchfmq/dvR +K1AHYZxRQn8VjYEVEBKIUJDC7q4b54CnOfpwngnGRPTycj/sYOOteFPi3dDL4Wnk +hfosTlGAPlF6g3mT4Jjpev1OzKO6gUBpBIv0e/V2Fow5n9oBRV7fYpWO96KSZXkb +sK2abDZPkvXcZf6gWrWb9ZkELBFgX7vI7DiG19/vO/J70kbjolbzgHUVEvp6i5RU +Q2j56e6XWG0= +=GfAw +-----END PGP SIGNATURE----- diff --git a/guestfs-tools.spec b/guestfs-tools.spec index b398490..f1cbb60 100644 --- a/guestfs-tools.spec +++ b/guestfs-tools.spec @@ -7,19 +7,16 @@ # Verify tarball signature with GPGv2. %global verify_tarball_signature 1 -# If there are patches which touch autotools files, set this to 1. -%global patches_touch_autotools %{nil} - # The source directory. -%global source_directory 1.52-stable +%global source_directory 1.54-stable # Filter perl provides. %{?perl_default_filter} Summary: Tools to access and modify virtual machine disk images Name: guestfs-tools -Version: 1.52.1 -Release: 1%{?dist} +Version: 1.54.0 +Release: 9%{?dist} License: GPL-2.0-or-later AND LGPL-2.0-or-later # Build only for architectures that have a kernel @@ -45,23 +42,41 @@ Source2: libguestfs.keyring Source3: copy-patches.sh # Patches are maintained in the following repository: -# https://github.com/rwmjones/guestfs-tools/commits/rhel-10.0 +# https://github.com/rwmjones/guestfs-tools/commits/rhel-10.2 # Patches. -Patch0001: 0001-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch -Patch0002: 0002-RHEL-builder-Disable-opensuse-repository.patch -Patch0003: 0003-customize-Implement-inject-blnsvr-operation.patch -Patch0004: 0004-Update-common-submodule.patch +Patch0001: 0001-docs-Move-release-note-about-GNU-gettext-to-build-se.patch +Patch0002: 0002-builder-Update-link-to-templates-to-use-https.patch +Patch0003: 0003-builder-Replace-cpu-host-with-cpu-max-in-example.patch +Patch0004: 0004-customize-Fixes-for-selinux-relabelling-and-Windows-.patch Patch0005: 0005-Update-common-submodule.patch - -%if 0%{patches_touch_autotools} -BuildRequires: autoconf, automake, libtool, gettext-devel -%endif +Patch0006: 0006-.gitignore-Ignore-.bak-files.patch +Patch0007: 0007-builder-sysprep-Use-quoted-string-literals-in-a-few-.patch +Patch0008: 0008-builder-templates-make-template.ml-Fix-quoting.patch +Patch0009: 0009-builder-templates-make-template.ml-Use-quoted-string.patch +Patch0010: 0010-builder-templates-make-template.ml-Add-str-and-unix-.patch +Patch0011: 0011-daemon-generator-Use-power-of-2-for-initial-size-of-.patch +Patch0012: 0012-builder-Build-fedora-42-template.patch +Patch0013: 0013-Update-common-submodule.patch +Patch0014: 0014-common-update-submodule.patch +Patch0015: 0015-pod-Document-removal-of-sm-options.patch +Patch0016: 0016-test-data-phony-guests-Increase-size-of-Windows-imag.patch +Patch0017: 0017-inspector-Add-new-class-field-to-output-of-virt-insp.patch +Patch0018: 0018-inspector-Add-windows_group_policy-is-Windows-GPOs-d.patch +Patch0019: 0019-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch +Patch0020: 0020-RHEL-builder-Disable-opensuse-repository.patch +Patch0021: 0021-inspector-For-xfs-try-to-find-and-print-the-filesyst.patch +Patch0022: 0022-Sort-some-entries-in-.gitignore-into-order.patch +Patch0023: 0023-build-Add-NULL-as-a-convenient-list-terminator.patch +Patch0024: 0024-Move-virt-filesystems-virt-log-virt-ls-virt-tail-to-.patch +Patch0025: 0025-filesystems-Optionally-display-filesystem-version.patch # Basic build requirements. +BuildRequires: autoconf, automake, libtool, gettext-devel BuildRequires: gcc, gcc-c++ BuildRequires: make -BuildRequires: libguestfs-devel >= 1:1.49.8-1 +BuildRequires: glibc-utils +BuildRequires: libguestfs-devel >= 1:1.58.1-2 BuildRequires: libguestfs-xfs BuildRequires: perl(Pod::Simple) BuildRequires: perl(Pod::Man) @@ -71,7 +86,7 @@ BuildRequires: /usr/bin/pod2text BuildRequires: po4a BuildRequires: pcre2-devel BuildRequires: libxml2-devel -BuildRequires: jansson-devel +BuildRequires: json-c-devel BuildRequires: libvirt-devel BuildRequires: libosinfo-devel BuildRequires: libxcrypt-devel @@ -79,12 +94,10 @@ BuildRequires: ncurses-devel %ifarch x86_64 BuildRequires: glibc-static %endif +BuildRequires: ocaml >= 4.08 BuildRequires: ocaml-libguestfs-devel BuildRequires: ocaml-findlib-devel BuildRequires: ocaml-gettext-devel -%if !0%{?rhel} -BuildRequires: ocaml-ounit-devel -%endif BuildRequires: flex BuildRequires: bison BuildRequires: xz-devel @@ -109,10 +122,8 @@ BuildRequires: perl-generators BuildRequires: gnupg2 %endif -# Ensure a minimum version of libguestfs is installed. This contains -# a workaround for openssl bug RHBZ#2133884 and the hang where we -# called setenv between fork and exec. -Requires: libguestfs >= 1.49.6-1 +# Ensure a minimum version of libguestfs is installed. +Requires: libguestfs%{?_isa} >= 1:1.58.1-2 # For virt-builder: Requires: curl @@ -257,13 +268,12 @@ for %{name}. %setup -q %autopatch -p1 -%if 0%{patches_touch_autotools} -autoreconf -i -%endif - - %build -%{configure} +autoreconf -fiv + +# Preserve timestamps when copying files. Otherwise, the time of the +# build ends up in the header added by gzip when it compresses files. +%{configure} INSTALL='/usr/bin/install -p' # Building index-parse.c by hand works around a race condition in the # autotools cruft, where two or more copies of yacc race with each @@ -411,6 +421,38 @@ end %changelog +* Wed Feb 05 2026 Richard W.M. Jones - 1.54.0-9 +- Synchronize spec file with Fedora +- Fix pnputils after virt-customize --inject-virtio-win + resolves: RHEL-116537 +- Unify spec files between Fedora and RHEL. +- Ensure a minimum version of libguestfs is installed at build and run time. + resolves: RHEL-116716 +- Remove virt-customize subscription-manager options + resolves: RHEL-122307 +- Add AV and GPOs to virt-inspector output + resolves: RHEL-125955 +- Expose XFS version in virt-filesystems + resolves: RHEL-144074 + +* Wed Aug 13 2025 Richard W.M. Jones - 1.54.0-3 +- Rebase to guestfs-tools 1.54.0 + resolves: RHEL-81734 +- virt-builder, virt-v2v & other tools with -v and --install causes dnf5 error + resolves: RHEL-83201 +- virt-drivers fails on opensuse guest if kernel-source is installed + resolves: RHEL-92604 +- builder: Update link to templates to use https + resolves: RHEL-94873 +- Fix SELinux relabelling in Linux split-/usr + resolves: RHEL-109129 + +* Wed Oct 30 2024 Richard W.M. Jones - 1.52.2-2 +- Rebase to guestfs-tools 1.52.2 + resolves: RHEL-56812 +- Replace Jansson with json-c + resolves: RHEL-65295 + * Tue Aug 27 2024 Richard W.M. Jones - 1.52.1-1 - New stable version 1.52.1 - Rebase on top of patches from RHEL 9.5 diff --git a/sources b/sources index 5d9e15f..a91a71e 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (guestfs-tools-1.52.1.tar.gz) = 0db4b6cc49b18d26cb9a3a1e8f76fcb16127d41fac65b2e6e40e823b697a5581be0b85d54d2a36dbf4e45aea72ecddfc2cf6d198093c8cc52ce1a2712cc26d25 +SHA512 (guestfs-tools-1.54.0.tar.gz) = db76a1cbfaa8b53b5c4609030f545b9d043161cebf54379da6418800086855f11cb3a0e5d135184c2a885094a6a7120155774377a6641a2d7fbd45206ff9ec87 SHA512 (libguestfs.keyring) = 297a15edc7c220222b9f650e0a9361ae132d3f0fed04aeb2237a1d9c3f6dac6f336846434f66480faed72635a33f659e849b052e74b88d1508aeff03f8c9a2ac