mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
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 image with a half-installed kernel. (Add -v -x to see the error above amongst the debug output). This change makes virt-customize set /etc/machine-id to a random value if the file exists and is zero sized. This is done unconditionally at the same time as setting the random seed (a similar issue), and before running any customize options such as installing or updating packages.
This commit is contained in:
@@ -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 ()
|
||||
|
||||
Reference in New Issue
Block a user