From 19b7495d4661f46bbb1cc7dee8905ae1efc8d44b Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Tue, 27 Sep 2016 17:48:23 +0200 Subject: [PATCH] v2v: bootloaders: improve detection of Grub2 default method Detect only once which method must be used to get and set the default Grub2 kernel in the guest: this avoids the same checks in list_kernels and set_default_kernel. Also, add a "no method" option as well: Debian/Ubuntu guests do not have neither grubby nor Perl's Bootloader::Tools, so there is no way to know what is the default kernel, nor to change it. In this case, add a warning about this situation. --- v2v/linux_bootloaders.ml | 61 +++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/v2v/linux_bootloaders.ml b/v2v/linux_bootloaders.ml index 4f53f873f..e03d22b56 100644 --- a/v2v/linux_bootloaders.ml +++ b/v2v/linux_bootloaders.ml @@ -184,6 +184,12 @@ object g#aug_save () end +(** The method used to get and set the default kernel in Grub2. *) +type default_kernel_method = + | MethodGrubby (** Use the 'grubby' tool. *) + | MethodPerlBootloader (** Use the 'Bootloader::Tools' Perl module. *) + | MethodNone (** No known way. *) + (* Grub2 representation. *) class bootloader_grub2 (g : G.guestfs) grub_config = @@ -199,6 +205,20 @@ class bootloader_grub2 (g : G.guestfs) grub_config = error (f_"failed to find grub2-mkconfig binary (but Grub2 was detected on guest)") in + let get_default_method = + let has_perl_bootloader () = + try + ignore (g#command [| "/usr/bin/perl"; "-MBootloader::Tools"; "-e1" |]); + true + with G.Error _ -> false + in + if g#exists "/sbin/grubby" then MethodGrubby + else if has_perl_bootloader () then MethodPerlBootloader + else ( + warning (f_"could not determine a way to update the configuration of Grub2"); + MethodNone + ) in + object (self) inherit bootloader @@ -250,18 +270,23 @@ object (self) method list_kernels = let get_default_image () = - let cmd = - if g#exists "/sbin/grubby" then - [| "grubby"; "--default-kernel" |] - else - [| "/usr/bin/perl"; "-MBootloader::Tools"; "-e"; " - InitLibrary(); - my $default = Bootloader::Tools::GetDefaultSection(); - print $default->{image}; - " |] in - match g#command cmd with - | "" -> None - | k -> + let res = + match get_default_method with + | MethodGrubby -> + Some (g#command [| "grubby"; "--default-kernel" |]) + | MethodPerlBootloader -> + let cmd = + [| "/usr/bin/perl"; "-MBootloader::Tools"; "-e"; " + InitLibrary(); + my $default = Bootloader::Tools::GetDefaultSection(); + print $default->{image}; + " |] in + Some (g#command cmd) + | MethodNone -> + None in + match res with + | None -> None + | Some k -> let len = String.length k in let k = if len > 0 && k.[len-1] = '\n' then @@ -285,10 +310,11 @@ object (self) vmlinuzes method set_default_kernel vmlinuz = - let cmd = - if g#exists "/sbin/grubby" then - [| "grubby"; "--set-default"; vmlinuz |] - else + match get_default_method with + | MethodGrubby -> + ignore (g#command [| "grubby"; "--set-default"; vmlinuz |]) + | MethodPerlBootloader -> + let cmd = [| "/usr/bin/perl"; "-MBootloader::Tools"; "-e"; sprintf " InitLibrary(); my @sections = GetSectionList(type=>image, image=>\"%s\"); @@ -296,7 +322,8 @@ object (self) my $newdefault = $section->{name}; SetGlobals(default, \"$newdefault\"); " vmlinuz |] in - ignore (g#command cmd) + ignore (g#command cmd) + | MethodNone -> () method configure_console = self#grub2_update_console ~remove:false