mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
builder: Create an install log file, and dump the full log on error.
This should make debugging much simpler, and also provides a build log in the guest once it's built.
This commit is contained in:
@@ -43,7 +43,7 @@ let mode, arg,
|
||||
firstboot, run,
|
||||
format, gpg, hostname, install, list_long, network, output,
|
||||
password_crypto, quiet, root_password,
|
||||
size, source, upload =
|
||||
size, source, upload, wipe_logfile =
|
||||
let display_version () =
|
||||
let g = new G.guestfs () in
|
||||
let version = g#version () in
|
||||
@@ -163,6 +163,8 @@ let mode, arg,
|
||||
upload := (file, dest) :: !upload
|
||||
in
|
||||
|
||||
let wipe_logfile = ref false in
|
||||
|
||||
let ditto = " -\"-" in
|
||||
let argspec = Arg.align [
|
||||
"--attach", Arg.String attach_disk, "iso" ^ " " ^ s_"Attach data disk/ISO during install";
|
||||
@@ -194,6 +196,7 @@ let mode, arg,
|
||||
"-l", Arg.Unit list_mode, " " ^ s_"List available templates";
|
||||
"--list", Arg.Unit list_mode, ditto;
|
||||
"--long", Arg.Set list_long, ditto;
|
||||
"--no-logfile", Arg.Set wipe_logfile, " " ^ s_"Wipe build log file";
|
||||
"--long-options", Arg.Unit display_long_options, " " ^ s_"List long options";
|
||||
"--network", Arg.Set network, " " ^ s_"Enable appliance network (default)";
|
||||
"--no-network", Arg.Clear network, " " ^ s_"Disable appliance network";
|
||||
@@ -252,6 +255,7 @@ read the man page virt-builder(1).
|
||||
let size = !size in
|
||||
let source = !source in
|
||||
let upload = List.rev !upload in
|
||||
let wipe_logfile = !wipe_logfile in
|
||||
|
||||
(* Check options. *)
|
||||
let arg =
|
||||
@@ -296,7 +300,7 @@ read the man page virt-builder(1).
|
||||
firstboot, run,
|
||||
format, gpg, hostname, install, list_long, network, output,
|
||||
password_crypto, quiet, root_password,
|
||||
size, source, upload
|
||||
size, source, upload, wipe_logfile
|
||||
|
||||
(* Timestamped messages in ordinary, non-debug non-quiet mode. *)
|
||||
let msg fs = make_message_function ~quiet fs
|
||||
@@ -635,11 +639,21 @@ let () =
|
||||
| _ ->
|
||||
eprintf (f_"%s: warning: root password could not be set for this type of guest\n%!") prog
|
||||
|
||||
(* Based on the guest type, choose a log file location. *)
|
||||
let logfile =
|
||||
match g#inspect_get_type root with
|
||||
| "windows" | "dos" ->
|
||||
if g#is_dir "/Temp" then "/Temp/builder.log" else "/builder.log"
|
||||
| _ ->
|
||||
if g#is_dir "/tmp" then "/tmp/builder.log" else "/builder.log"
|
||||
|
||||
(* Useful wrapper for scripts. *)
|
||||
let do_run cmd =
|
||||
let do_run ~display cmd =
|
||||
(* Add a prologue to the scripts:
|
||||
* - Pass environment variables through from the host.
|
||||
* - Send stdout to stderr so we capture all output in error messages.
|
||||
* - Send stdout and stderr to a log file so we capture all output
|
||||
* in error messages.
|
||||
* Also catch errors and dump the log file completely on error.
|
||||
*)
|
||||
let env_vars =
|
||||
filter_map (
|
||||
@@ -650,13 +664,22 @@ let do_run cmd =
|
||||
let env_vars = String.concat "\n" env_vars ^ "\n" in
|
||||
|
||||
let cmd = sprintf "\
|
||||
exec 1>&2
|
||||
exec >>%s 2>&1
|
||||
%s
|
||||
%s
|
||||
" env_vars cmd in
|
||||
" (quote logfile) env_vars cmd in
|
||||
|
||||
if debug then eprintf "running: %s\n%!" cmd;
|
||||
ignore (g#sh cmd)
|
||||
if debug then eprintf "running command:\n%s\n%!" cmd;
|
||||
try ignore (g#sh cmd)
|
||||
with Guestfs.Error msg ->
|
||||
(* Cat the log file. *)
|
||||
(try g#download logfile "/dev/stderr"
|
||||
with exn ->
|
||||
eprintf (f_"%s: internal error: could not display the log file: %s\n")
|
||||
prog (Printexc.to_string exn)
|
||||
);
|
||||
eprintf (f_"%s: %s: command exited with an error\n") prog display;
|
||||
exit 1
|
||||
|
||||
let guest_install_command packages =
|
||||
let quoted_args = String.concat " " (List.map quote packages) in
|
||||
@@ -689,7 +712,7 @@ let () =
|
||||
msg (f_"Installing packages: %s") (String.concat " " install);
|
||||
|
||||
let cmd = guest_install_command install in
|
||||
do_run cmd;
|
||||
do_run ~display:cmd cmd
|
||||
)
|
||||
|
||||
(* Upload files. *)
|
||||
@@ -729,12 +752,22 @@ let () =
|
||||
| `Script script ->
|
||||
msg (f_"Running: %s") script;
|
||||
let cmd = read_whole_file script in
|
||||
do_run cmd
|
||||
do_run ~display:script cmd
|
||||
| `Command cmd ->
|
||||
msg (f_"Running: %s") cmd;
|
||||
do_run cmd
|
||||
do_run ~display:cmd cmd
|
||||
) run
|
||||
|
||||
(* Wipe the log file. *)
|
||||
let () =
|
||||
if wipe_logfile && g#exists logfile then (
|
||||
msg (f_"Wiping the log file");
|
||||
|
||||
(* Try various methods with decreasing complexity. *)
|
||||
try g#scrub_file logfile
|
||||
with _ -> g#rm_f logfile
|
||||
)
|
||||
|
||||
(* Unmount everything and we're done! *)
|
||||
let () =
|
||||
msg (f_"Finishing off");
|
||||
|
||||
@@ -310,6 +310,14 @@ each operating system option.
|
||||
|
||||
See also: I<--source>, L</CREATING YOUR OWN TEMPLATES>.
|
||||
|
||||
=item B<--no-logfile>
|
||||
|
||||
Wipe C<builder.log> (log file from build commands) from the image
|
||||
after building is complete. If you don't want to reveal precisely how
|
||||
the image was built, use this option.
|
||||
|
||||
See also: L</LOG FILE>.
|
||||
|
||||
=item B<--network>
|
||||
|
||||
=item B<--no-network>
|
||||
@@ -569,6 +577,31 @@ The above command will create an C<rjones> account with no password,
|
||||
and force the user to set a password when they first log in. There
|
||||
are other ways to manage passwords, see L<useradd(8)> for details.
|
||||
|
||||
=head2 LOG FILE
|
||||
|
||||
Scripts and package installation that runs at build time (I<--run>,
|
||||
I<--run-command>, I<--install>, but I<not> firstboot) is logged in one
|
||||
of the following locations:
|
||||
|
||||
=over 4
|
||||
|
||||
=item C</tmp/builder.log>
|
||||
|
||||
On Linux, BSD and other guests.
|
||||
|
||||
=item C<C:\Temp\builder.log>
|
||||
|
||||
On Windows, DOS guests.
|
||||
|
||||
=item C</builder.log>
|
||||
|
||||
If C</tmp> or C<C:\Temp> is missing.
|
||||
|
||||
=back
|
||||
|
||||
If you don't want the log file to appear in the final image, then
|
||||
use the I<--no-logfile> command line option.
|
||||
|
||||
=head2 INSTALLATION PROCESS
|
||||
|
||||
When you invoke virt-builder, installation proceeds as follows:
|
||||
|
||||
Reference in New Issue
Block a user