Pino Toscano
2015-Sep-01 16:06 UTC
[Libguestfs] [PATCH 1/3] get-kernel: split command line handling in own function
Simple refactoring, no actual behaviour changes. --- get-kernel/get_kernel.ml | 188 ++++++++++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 93 deletions(-) diff --git a/get-kernel/get_kernel.ml b/get-kernel/get_kernel.ml index 8ca7ca0..3b27740 100644 --- a/get-kernel/get_kernel.ml +++ b/get-kernel/get_kernel.ml @@ -23,104 +23,106 @@ module G = Guestfs open Printf -(* Main program. *) -let main () - let add, output, unversioned, prefix - let domain = ref None in - let file = ref None in - let libvirturi = ref "" in - let format = ref "" in - let output = ref "" in - let machine_readable = ref false in - let unversioned = ref false in - let prefix = ref None in - - let set_file arg - if !file <> None then - error (f_"--add option can only be given once"); - let uri - try URI.parse_uri arg - with Invalid_argument "URI.parse_uri" -> - error (f_"error parsing URI '%s'. Look for error messages printed above.") arg in - file := Some uri - and set_domain dom - if !domain <> None then - error (f_"--domain option can only be given once"); - domain := Some dom - and set_prefix p - if !prefix <> None then - error (f_"--prefix option can only be given once"); - prefix := Some p in - - let ditto = " -\"-" in - let argspec = [ - "-a", Arg.String set_file, s_"file" ^ " " ^ s_"Add disk image file"; - "--add", Arg.String set_file, s_"file" ^ " " ^ s_"Add disk image file"; - "-c", Arg.Set_string libvirturi, s_"uri" ^ " " ^ s_"Set libvirt URI"; - "--connect", Arg.Set_string libvirturi, s_"uri" ^ " " ^ s_"Set libvirt URI"; - "-d", Arg.String set_domain, s_"domain" ^ " " ^ s_"Set libvirt guest name"; - "--domain", Arg.String set_domain, s_"domain" ^ " " ^ s_"Set libvirt guest name"; - "--format", Arg.Set_string format, s_"format" ^ " " ^ s_"Format of input disk"; - "--machine-readable", Arg.Set machine_readable, " " ^ s_"Make output machine readable"; - "-o", Arg.Set_string output, s_"directory" ^ " " ^ s_"Output directory"; - "--output", Arg.Set_string output, ditto; - "--unversioned-names", Arg.Set unversioned, - " " ^ s_"Use unversioned names for files"; - "--prefix", Arg.String set_prefix, "prefix" ^ " " ^ s_"Prefix for files"; - ] in - let argspec = set_standard_options argspec in - let anon_fun _ = raise (Arg.Bad (s_"extra parameter on the command line")) in - let usage_msg - sprintf (f_"\ +let parse_cmdline () + let domain = ref None in + let file = ref None in + let libvirturi = ref "" in + let format = ref "" in + let output = ref "" in + let machine_readable = ref false in + let unversioned = ref false in + let prefix = ref None in + + let set_file arg + if !file <> None then + error (f_"--add option can only be given once"); + let uri + try URI.parse_uri arg + with Invalid_argument "URI.parse_uri" -> + error (f_"error parsing URI '%s'. Look for error messages printed above.") arg in + file := Some uri + and set_domain dom + if !domain <> None then + error (f_"--domain option can only be given once"); + domain := Some dom + and set_prefix p + if !prefix <> None then + error (f_"--prefix option can only be given once"); + prefix := Some p in + + let ditto = " -\"-" in + let argspec = [ + "-a", Arg.String set_file, s_"file" ^ " " ^ s_"Add disk image file"; + "--add", Arg.String set_file, s_"file" ^ " " ^ s_"Add disk image file"; + "-c", Arg.Set_string libvirturi, s_"uri" ^ " " ^ s_"Set libvirt URI"; + "--connect", Arg.Set_string libvirturi, s_"uri" ^ " " ^ s_"Set libvirt URI"; + "-d", Arg.String set_domain, s_"domain" ^ " " ^ s_"Set libvirt guest name"; + "--domain", Arg.String set_domain, s_"domain" ^ " " ^ s_"Set libvirt guest name"; + "--format", Arg.Set_string format, s_"format" ^ " " ^ s_"Format of input disk"; + "--machine-readable", Arg.Set machine_readable, " " ^ s_"Make output machine readable"; + "-o", Arg.Set_string output, s_"directory" ^ " " ^ s_"Output directory"; + "--output", Arg.Set_string output, ditto; + "--unversioned-names", Arg.Set unversioned, + " " ^ s_"Use unversioned names for files"; + "--prefix", Arg.String set_prefix, "prefix" ^ " " ^ s_"Prefix for files"; + ] in + let argspec = set_standard_options argspec in + let anon_fun _ = raise (Arg.Bad (s_"extra parameter on the command line")) in + let usage_msg + sprintf (f_"\ %s: extract kernel and ramdisk from a guest A short summary of the options is given below. For detailed help please read the man page virt-get-kernel(1). ") - prog in - Arg.parse argspec anon_fun usage_msg; - - (* Machine-readable mode? Print out some facts about what - * this binary supports. - *) - if !machine_readable then ( - printf "virt-get-kernel\n"; - exit 0 - ); - - (* Check -a and -d options. *) - let file = !file in - let domain = !domain in - let libvirturi = match !libvirturi with "" -> None | s -> Some s in - let add - match file, domain with - | None, None -> - error (f_"you must give either -a or -d options. Read virt-get-kernel(1) man page for further information.") - | Some _, Some _ -> - error (f_"you cannot give -a and -d options together. Read virt-get-kernel(1) man page for further information.") - | None, Some dom -> - fun (g : Guestfs.guestfs) -> - let readonlydisk = "ignore" (* ignore CDs, data drives *) in - ignore (g#add_domain - ~readonly:true ~allowuuid:true ~readonlydisk - ?libvirturi dom) - | Some uri, None -> - fun g -> - let { URI.path = path; protocol = protocol; - server = server; username = username; - password = password } = uri in - let format = match !format with "" -> None | s -> Some s in - g#add_drive - ~readonly:true ?format ~protocol ?server ?username ?secret:password - path - in - - (* Dereference the rest of the args. *) - let output = match !output with "" -> None | str -> Some str in - let unversioned = !unversioned in - let prefix = !prefix in - - add, output, unversioned, prefix in + prog in + Arg.parse argspec anon_fun usage_msg; + + (* Machine-readable mode? Print out some facts about what + * this binary supports. + *) + if !machine_readable then ( + printf "virt-get-kernel\n"; + exit 0 + ); + + (* Check -a and -d options. *) + let file = !file in + let domain = !domain in + let libvirturi = match !libvirturi with "" -> None | s -> Some s in + let add + match file, domain with + | None, None -> + error (f_"you must give either -a or -d options. Read virt-get-kernel(1) man page for further information.") + | Some _, Some _ -> + error (f_"you cannot give -a and -d options together. Read virt-get-kernel(1) man page for further information.") + | None, Some dom -> + fun (g : Guestfs.guestfs) -> + let readonlydisk = "ignore" (* ignore CDs, data drives *) in + ignore (g#add_domain + ~readonly:true ~allowuuid:true ~readonlydisk + ?libvirturi dom) + | Some uri, None -> + fun g -> + let { URI.path = path; protocol = protocol; + server = server; username = username; + password = password } = uri in + let format = match !format with "" -> None | s -> Some s in + g#add_drive + ~readonly:true ?format ~protocol ?server ?username ?secret:password + path + in + + (* Dereference the rest of the args. *) + let output = match !output with "" -> None | str -> Some str in + let unversioned = !unversioned in + let prefix = !prefix in + + add, output, unversioned, prefix + +(* Main program. *) +let main () + let add, output, unversioned, prefix = parse_cmdline () in (* Connect to libguestfs. *) let g = new G.guestfs () in -- 2.1.0
Pino Toscano
2015-Sep-01 16:06 UTC
[Libguestfs] [PATCH 2/3] get-kernel: refactor list and download code
Split in an own function the code dong the mounting, the inspection of the kernel files, and the downloading, including a per-OS function for the actual kernel files. This gives few advantages: - the download phease is not repeated for all the files to fetch - it is easier to eventually support multi-root disk images - it is possible to support OSes different than Linux; virt-get-kernel now will just report the unsupported OS, instead of a generic "no kernel found" message This is mostly code refactoring, with (on Linux) no actual behaviour change. --- get-kernel/get_kernel.ml | 80 +++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/get-kernel/get_kernel.ml b/get-kernel/get_kernel.ml index 3b27740..233d459 100644 --- a/get-kernel/get_kernel.ml +++ b/get-kernel/get_kernel.ml @@ -120,24 +120,7 @@ read the man page virt-get-kernel(1). add, output, unversioned, prefix -(* Main program. *) -let main () - let add, output, unversioned, prefix = parse_cmdline () in - - (* Connect to libguestfs. *) - let g = new G.guestfs () in - if trace () then g#set_trace true; - if verbose () then g#set_verbose true; - add g; - g#launch (); - - let roots = g#inspect_os () in - if Array.length roots = 0 then - error (f_"no operating system found"); - if Array.length roots > 1 then - error (f_"dual/multi-boot images are not supported by this tool"); - let root = roots.(0) in - +let rec do_fetch ~transform_fn ~outputdir g root (* Mount up the disks. *) let mps = g#inspect_get_mountpoints root in let cmp (a,_) (b,_) = compare (String.length a) (String.length b) in @@ -148,6 +131,24 @@ let main () with Guestfs.Error msg -> warning (f_"%s (ignored)") msg ) mps; + let files + let typ = g#inspect_get_type root in + match typ with + | "linux" -> pick_kernel_files_linux g root + | typ -> + error (f_"operating system '%s' not supported") typ in + + (* Download the files. *) + List.iter ( + fun f -> + let dest = outputdir // transform_fn f in + printf "download: %s -> %s\n%!" f dest; + g#download f dest; + ) files; + + g#umount_all () + +and pick_kernel_files_linux g root (* Get all kernels and initramfses. *) let glob w = Array.to_list (g#glob_expand w) in let kernels = glob "/boot/vmlinuz-*" in @@ -164,7 +165,34 @@ let main () let initrds = List.rev (List.sort compare_version initrds) in if kernels = [] then - error (f_"no kernel found"); + error (f_"no kernel found in %s") root; + + (* Pick the latest. *) + let kernel = [List.hd kernels] in + let initrd + match initrds with + | [] -> [] + | initrd :: _ -> [initrd] in + + kernel @ initrd + +(* Main program. *) +let main () + let add, output, unversioned, prefix = parse_cmdline () in + + (* Connect to libguestfs. *) + let g = new G.guestfs () in + if trace () then g#set_trace true; + if verbose () then g#set_verbose true; + add g; + g#launch (); + + let roots = g#inspect_os () in + if Array.length roots = 0 then + error (f_"no operating system found"); + if Array.length roots > 1 then + error (f_"dual/multi-boot images are not supported by this tool"); + let root = roots.(0) in let dest_filename fn let fn = Filename.basename fn in @@ -175,22 +203,12 @@ let main () | None -> fn | Some p -> p ^ "-" ^ fn in - (* Download the latest. *) let outputdir match output with | None -> Filename.current_dir_name | Some dir -> dir in - let kernel_in = List.hd kernels in - let kernel_out = outputdir // dest_filename kernel_in in - printf "download: %s -> %s\n%!" kernel_in kernel_out; - g#download kernel_in kernel_out; - - if initrds <> [] then ( - let initrd_in = List.hd initrds in - let initrd_out = outputdir // dest_filename initrd_in in - printf "download: %s -> %s\n%!" initrd_in initrd_out; - g#download initrd_in initrd_out - ); + + do_fetch ~transform_fn:dest_filename ~outputdir g root; (* Shutdown. *) g#shutdown (); -- 2.1.0
Now that virt-get-kernel has -q/--quiet, support it by printing the download messages only if not specified. --- get-kernel/get_kernel.ml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/get-kernel/get_kernel.ml b/get-kernel/get_kernel.ml index 233d459..8786bf3 100644 --- a/get-kernel/get_kernel.ml +++ b/get-kernel/get_kernel.ml @@ -142,7 +142,8 @@ let rec do_fetch ~transform_fn ~outputdir g root List.iter ( fun f -> let dest = outputdir // transform_fn f in - printf "download: %s -> %s\n%!" f dest; + if not (quiet ()) then + printf "download: %s -> %s\n%!" f dest; g#download f dest; ) files; -- 2.1.0
Richard W.M. Jones
2015-Sep-01 20:19 UTC
Re: [Libguestfs] [PATCH 3/3] get-kernel: respect -q
On Tue, Sep 01, 2015 at 06:06:34PM +0200, Pino Toscano wrote:> Now that virt-get-kernel has -q/--quiet, support it by printing the > download messages only if not specified. > --- > get-kernel/get_kernel.ml | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-)ACK series. Thanks, Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v
Apparently Analagous Threads
- [PATCH] mllib: factor out mounting of guest root
- [PATCH 1/3] get-kernel: split command line handling in own function
- Re: [PATCH 1/3] sysprep, get-kernel: explicit the Guestfs parameter
- [PATCH 1/3] sysprep, get-kernel: explicit the Guestfs parameter
- [PATCH 2/3] get-kernel: add --unversioned-names