[Libguestfs] [PATCH] builder: Make the interface between cmdline.ml and builder.ml explicit.

Richard W.M. Jones
Wed, 11 Nov 2015 15:25:32 -0000

---
 builder/Makefile.am |  1 +
 builder/builder.ml  | 69 +++++++++++++++++++++++++----------------------------
 builder/cmdline.ml  | 37 ++++++++++++++++++++++++----
 builder/cmdline.mli | 44 ++++++++++++++++++++++++++++++++++
 4 files changed, 110 insertions(+), 41 deletions(-)
 create mode 100644 builder/cmdline.mli

diff --git a/builder/Makefile.am b/builder/Makefile.am
index 6742822..993cc7b 100644
--- a/builder/Makefile.am
+++ b/builder/Makefile.am
@@ -53,6 +53,7 @@ CLEANFILES = \

 SOURCES_MLI = \
 	cache.mli \
+	cmdline.mli \
 	downloader.mli \
 	checksums.mli \
 	index.mli \
diff --git a/builder/builder.ml b/builder/builder.ml
index b0fef48..957bc37 100644
--- a/builder/builder.ml
+++ b/builder/builder.ml
@@ -1,5 +1,5 @@
 (* virt-builder
- * Copyright (C) 2013 Red Hat Inc.
+ * Copyright (C) 2013-2015 Red Hat Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -77,11 +77,7 @@ let remove_duplicates index
 let main ()    (* Command line argument parsing - see cmdline.ml. *)
-  let mode, arg,
-    arch, attach, cache, check_signature, curl,
-    delete_on_failure, format, gpg, list_format, memsize,
-    network, ops, output, size, smp, sources, sync -    parse_cmdline () in
+  let cmdline = parse_cmdline () in

   (* If debugging, echo the command line arguments and the sources. *)
   if verbose () then (
@@ -91,29 +87,29 @@ let main ()      iteri (
       fun i (source, fingerprint) ->
         printf "source[%d] = (%S, %S)\n" i source fingerprint
-    ) sources
+    ) cmdline.sources
   );

   (* Handle some modes here, some later on. *)
   let mode -    match mode with
+    match cmdline.mode with
     | `Get_kernel -> (* --get-kernel is really a different program ... *)
       let cmd          sprintf "virt-get-kernel%s%s%s%s --add %s"
           (if verbose () then " --verbose" else "")
           (if trace () then " -x" else "")
-          (match format with
+          (match cmdline.format with
           | None -> ""
           | Some format -> sprintf " --format %s" (quote format))
-          (match output with
+          (match cmdline.output with
           | None -> ""
           | Some output -> sprintf " --output %s" (quote output))
-          (quote arg) in
+          (quote cmdline.arg) in
       if verbose () then printf "%s\n%!" cmd;
       exit (Sys.command cmd)

     | `Delete_cache ->                  (* --delete-cache *)
-      (match cache with
+      (match cmdline.cache with
       | Some cachedir ->
         message (f_"Deleting: %s") cachedir;
         Cache.clean_cachedir cachedir;
@@ -129,16 +125,16 @@ let main ()    (* Check that gpg is installed.  Optional
as long as the user
    * disables all signature checks.
    *)
-  let cmd = sprintf "%s --help >/dev/null 2>&1" gpg in
+  let cmd = sprintf "%s --help >/dev/null 2>&1" cmdline.gpg
in
   if Sys.command cmd <> 0 then (
-    if check_signature then
+    if cmdline.check_signature then
       error (f_"gpg is not installed (or does not work)\nYou should
install gpg, or use --gpg option, or use --no-check-signature.")
     else if verbose () then
       warning (f_"gpg program is not available")
   );

   (* Check that curl works. *)
-  let cmd = sprintf "%s --help >/dev/null 2>&1" curl in
+  let cmd = sprintf "%s --help >/dev/null 2>&1"
cmdline.curl in
   if Sys.command cmd <> 0 then
     error (f_"curl is not installed (or does not work)");

@@ -149,7 +145,7 @@ let main ()
   (* Create the cache. *)
   let cache -    match cache with
+    match cmdline.cache with
     | None -> None
     | Some dir ->
       try Some (Cache.create ~directory:dir)
@@ -160,7 +156,7 @@ let main ()    in

   (* Download the sources. *)
-  let downloader = Downloader.create ~curl ~cache in
+  let downloader = Downloader.create ~curl:cmdline.curl ~cache in
   let repos = Sources.read_sources () in
   let sources = List.map (
     fun (source, fingerprint) ->
@@ -170,15 +166,16 @@ let main ()          proxy = Downloader.SystemProxy;
         format = Sources.FormatNative;
       }
-  ) sources in
+  ) cmdline.sources in
   let sources = List.append sources repos in
   let index : Index.index      List.concat (
       List.map (
         fun source ->
           let sigchecker -            Sigchecker.create ~gpg ~check_signature
-              ~gpgkey:source.Sources.gpgkey in
+            Sigchecker.create ~gpg:cmdline.gpg
+                              ~check_signature:cmdline.check_signature
+                              ~gpgkey:source.Sources.gpgkey in
           match source.Sources.format with
           | Sources.FormatNative ->
             Index_parser.get_index ~downloader ~sigchecker source
@@ -192,7 +189,7 @@ let main ()    let mode      match mode with
     | `List ->                          (* --list *)
-      List_entries.list_entries ~list_format ~sources index;
+      List_entries.list_entries ~list_format:cmdline.list_format ~sources
index;
       exit 0

     | `Print_cache ->                   (* --print-cache *)
@@ -220,7 +217,7 @@ let main ()            fun (name,
                { Index.revision = revision; file_uri = file_uri;
                  proxy = proxy }) ->
-            let template = name, arch, revision in
+            let template = name, cmdline.arch, revision in
             message (f_"Downloading: %s") file_uri;
             let progress_bar = not (quiet ()) in
             ignore (Downloader.download downloader ~template ~progress_bar
@@ -240,18 +237,18 @@ let main ()            fun (name, { Index.aliases =
aliases }) ->
             match aliases with
             | None -> false
-            | Some l -> List.mem arg l
+            | Some l -> List.mem cmdline.arg l
         ) index in
         fst item
-    with Not_found -> arg in
+    with Not_found -> cmdline.arg in
   let item      try List.find (
       fun (name, { Index.arch = a }) ->
-        name = arg && arch = normalize_arch a
+        name = arg && cmdline.arch = normalize_arch a
     ) index
     with Not_found ->
       error (f_"cannot find os-version '%s' with architecture
'%s'.\nUse --list to list available guest types.")
-        arg arch in
+        arg cmdline.arch in
   let entry = snd item in
   let sigchecker = entry.Index.sigchecker in

@@ -278,7 +275,7 @@ let main ()      let template, delete_on_exit        let {
Index.revision = revision; file_uri = file_uri;
             proxy = proxy } = entry in
-      let template = arg, arch, revision in
+      let template = arg, cmdline.arch, revision in
       message (f_"Downloading: %s") file_uri;
       let progress_bar = not (quiet ()) in
       Downloader.download downloader ~template ~progress_bar ~proxy
@@ -328,7 +325,7 @@ let main ()
   (* Planner: Goal. *)
   let output_filename, output_format -    match output, format with
+    match cmdline.output, cmdline.format with
     | None, None -> sprintf "%s.img" arg, "raw"
     | None, Some "raw" -> sprintf "%s.img" arg,
"raw"
     | None, Some format -> sprintf "%s.%s" arg format, format
@@ -353,7 +350,7 @@ let main ()      let { Index.size = original_image_size } =
entry in

     let size -      match size with
+      match cmdline.size with
       | Some size -> size
       (* --size parameter missing, output to file: use original image size *)
       | None when not output_is_block_dev -> original_image_size
@@ -526,7 +523,7 @@ let main ()     * if it's block device, or if
--no-delete-on-failure is set.
    *)
   let delete_output_file -    ref (delete_on_failure && not
output_is_block_dev) in
+    ref (cmdline.delete_on_failure && not output_is_block_dev) in
   let delete_file ()      if !delete_output_file then
       try unlink output_filename with _ -> ()
@@ -626,9 +623,9 @@ let main ()    let g      let g = open_guestfs () in

-    may g#set_memsize memsize;
-    may g#set_smp smp;
-    g#set_network network;
+    may g#set_memsize cmdline.memsize;
+    may g#set_smp cmdline.smp;
+    g#set_network cmdline.network;

     (* Make sure to turn SELinux off to avoid awkward interactions
      * between the appliance kernel and applications/libraries interacting
@@ -643,7 +640,7 @@ let main ()      List.iter (
       fun (format, file) ->
         g#add_drive_opts ?format ~readonly:true file;
-    ) attach;
+    ) cmdline.attach;

     g#launch ();

@@ -667,7 +664,7 @@ let main ()        error (f_"no guest operating systems
or multiboot OS found in this disk image\nThis is a failure of the source
repository.  Use -v for more information.")
   in

-  Customize_run.run g root ops;
+  Customize_run.run g root cmdline.ops;

   (* Collect some stats about the final output file.
    * Notes:
@@ -721,7 +718,7 @@ let main ()     * and therefore bypasses the host cache).
In general you should not
    * use cache=none.
    *)
-  if sync then
+  if cmdline.sync then
     Fsync.file output_filename;

   (* Now that we've finished the build, don't delete the output file on
diff --git a/builder/cmdline.ml b/builder/cmdline.ml
index 1d0d3ba..e4a45c3 100644
--- a/builder/cmdline.ml
+++ b/builder/cmdline.ml
@@ -1,5 +1,5 @@
 (* virt-builder
- * Copyright (C) 2013 Red Hat Inc.
+ * Copyright (C) 2013-2015 Red Hat Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,6 +30,29 @@ module G = Guestfs
 open Unix
 open Printf

+type cmdline = {
+  mode : [ `Cache_all | `Delete_cache | `Get_kernel | `Install | `List
+           | `Notes | `Print_cache ];
+  arg : string;
+  arch : string;
+  attach : (string option * string) list;
+  cache : string option;
+  check_signature : bool;
+  curl : string;
+  delete_on_failure : bool;
+  format : string option;
+  gpg : string;
+  list_format : [`Short|`Long|`Json];
+  memsize : int option;
+  network : bool;
+  ops : Customize_cmdline.ops;
+  output : string option;
+  size : int64 option;
+  smp : int option;
+  sources : (string * string) list;
+  sync : bool;
+}
+
 let parse_cmdline ()    let mode = ref `Install in
   let list_mode () = mode := `List in
@@ -293,7 +316,11 @@ read the man page virt-builder(1).
       { ops with ops = ops.ops @ [ `RootPassword pw ] }
     ) in

-  mode, arg,
-  arch, attach, cache, check_signature, curl,
-  delete_on_failure, format, gpg, list_format, memsize,
-  network, ops, output, size, smp, sources, sync
+  { mode = mode; arg = arg;
+    arch = arch; attach = attach; cache = cache;
+    check_signature = check_signature; curl = curl;
+    delete_on_failure = delete_on_failure; format = format;
+    gpg = gpg; list_format = list_format; memsize = memsize;
+    network = network; ops = ops; output = output;
+    size = size; smp = smp; sources = sources; sync = sync;
+  }
diff --git a/builder/cmdline.mli b/builder/cmdline.mli
new file mode 100644
index 0000000..35e7c7e
--- /dev/null
+++ b/builder/cmdline.mli
@@ -0,0 +1,44 @@
+(* virt-builder
+ * Copyright (C) 2013-2015 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+(** Command line argument parsing. *)
+
+type cmdline = {
+  mode : [ `Cache_all | `Delete_cache | `Get_kernel | `Install | `List
+           | `Notes | `Print_cache ];
+  arg : string;
+  arch : string;
+  attach : (string option * string) list;
+  cache : string option;
+  check_signature : bool;
+  curl : string;
+  delete_on_failure : bool;
+  format : string option;
+  gpg : string;
+  list_format : [`Short|`Long|`Json];
+  memsize : int option;
+  network : bool;
+  ops : Customize_cmdline.ops;
+  output : string option;
+  size : int64 option;
+  smp : int option;
+  sources : (string * string) list;
+  sync : bool;
+}
+
+val parse_cmdline : unit -> cmdline
--
2.5.0