Richard W.M. Jones
2017-Sep-25 12:15 UTC
[Libguestfs] [PATCH] customize: Unconditionally set the machine-id if not set already.
systemd defined an /etc/machine-id file which is supposed to contain a unique, unchanging ID for the host. This file is initially zero-sized and is meant to be set by systemd on the first boot of the system. In virt-builder Fedora templates, the file is empty. Unfortunately the Fedora kernel %post script requires the machine-id to have been set, else the script exits with an error: Running scriptlet: kernel-core-4.12.13-300.fc26.x86_64 209/209 Could not determine your machine ID from /etc/machine-id. Please run 'systemd-machine-id-setup' as root. See man:machine-id(5) warning: %posttrans(kernel-core-4.12.13-300.fc26.x86_64) scriptlet failed, exit status 1 This also leaves the kernel package half-installed. The files are present in the filesystem, but important initialization is not done, in particular the vmlinuz file is not copied into /boot. A simple reproducer for this problem is: $ virt-builder fedora-26 --update which will leave the system with a half-installed kernel. This change makes virt-customize set /etc/machine-id to a random value if it is zero sized. This is done unconditionally at the same time as setting the random seed (a similar issue). --- customize/customize_run.ml | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/customize/customize_run.ml b/customize/customize_run.ml index 5564684b4..3dcf755eb 100644 --- a/customize/customize_run.ml +++ b/customize/customize_run.ml @@ -27,7 +27,9 @@ open Customize_cmdline open Password open Append_line -let run (g : Guestfs.guestfs) root (ops : ops) +module G = Guestfs + +let run (g : G.guestfs) root (ops : ops) (* Is the host_cpu compatible with the guest arch? ie. Can we * run commands in this guest? *) @@ -89,7 +91,7 @@ exec >>%s 2>&1 debug "running command:\n%s" cmd; try ignore (g#sh cmd) with - Guestfs.Error msg -> + G.Error msg -> debug_logfile (); if warn_failed_no_network && not (g#get_network ()) then ( prerr_newline (); @@ -194,6 +196,26 @@ exec >>%s 2>&1 if not (Random_seed.set_random_seed g root) then warning (f_"random seed could not be set for this type of guest"); + (* Set the systemd machine ID. This must be set before performing + * --install/--update since (at least in Fedora) the kernel %post + * script requires a machine ID and will fail if it is not set. + *) + let () + let etc_machine_id = "/etc/machine-id" in + let statbuf + try Some (g#lstatns etc_machine_id) with G.Error _ -> None in + (match statbuf with + | Some { G.st_size = 0L; G.st_mode = mode } + when (Int64.logand mode 0o170000_L) = 0o100000_L -> + message (f_"Setting the machine ID in %s") etc_machine_id; + let id = Urandom.urandom_bytes 16 in + let id = String.map_chars (fun c -> sprintf "%02x" (Char.code c)) id in + let id = String.concat "" id in + let id = id ^ "\n" in + g#write etc_machine_id id + | _ -> () + ) in + (* Store the passwords and set them all at the end. *) let passwords = Hashtbl.create 13 in let set_password user pw @@ -399,8 +421,8 @@ exec >>%s 2>&1 let uid, gid = statbuf.st_uid, statbuf.st_gid in let chown () try g#chown uid gid dest - with Guestfs.Error m as e -> - if g#last_errno () = Guestfs.Errno.errno_EPERM + with G.Error m as e -> + if g#last_errno () = G.Errno.errno_EPERM then warning "%s" m else raise e in chown () -- 2.13.2
Possibly Parallel Threads
- [PATCH v3] customize: fix --upload to FAT partition (RHBZ#1196101)
- [PACTH v2] customize: fix --upload to FAT partition (RHBZ#1196101)
- [PATCH v3] customize: fix --upload to FAT partition (RHBZ#1196101)
- [PATCH v2] sysprep: Add --network to enable the network (RHBZ#1345813).
- [PATCH 1/3] ocaml: dynamically generate the content of Guestfs.Errno