[Libguestfs] [PATCH v11 5/8] builder: add a template parameter to get_index

Cédric Bosdonnat cbosdonnat at suse.com
Fri Oct 27 14:08:19 UTC 2017


get_index now gets a new template parameter. Setting it to true will
make the index parsing less picky about missing important data. This
can be used to parse a partial index file.
---
 builder/index_parser.ml  | 46 ++++++++++++++++++++++++++++++++++++++--------
 builder/index_parser.mli |  5 ++++-
 2 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/builder/index_parser.ml b/builder/index_parser.ml
index c715ccac7..7f64d0d98 100644
--- a/builder/index_parser.ml
+++ b/builder/index_parser.ml
@@ -25,7 +25,7 @@ open Utils
 open Printf
 open Unix
 
-let get_index ~downloader ~sigchecker { Sources.uri; proxy } =
+let get_index ~downloader ~sigchecker ?(template = false) { Sources.uri; proxy } =
   let corrupt_file () =
     error (f_"The index file downloaded from ‘%s’ is corrupt.\nYou need to ask the supplier of this file to fix it and upload a fixed version.") uri
   in
@@ -99,8 +99,25 @@ let get_index ~downloader ~sigchecker { Sources.uri; proxy } =
           let arch =
             try Either (List.assoc ("arch", None) fields)
             with Not_found ->
-              eprintf (f_"%s: no ‘arch’ entry for ‘%s’\n") prog n;
-            corrupt_file () in
+              if template then
+                try
+                  let g = new Guestfs.guestfs () in
+                  g#add_drive_ro file_uri;
+                  g#launch ();
+                  let roots = g#inspect_os () in
+                  let nroots = Array.length roots in
+                  if nroots <> 1 then (
+                    eprintf (f_"%s: no ‘arch’ entry for %s and failed to guess it\n") prog n;
+                    corrupt_file ()
+                  );
+                  let inspected_arch = g#inspect_get_arch (Array.get roots 0) in
+                  g#close();
+                  Or (Some inspected_arch)
+                with exn -> Or None
+              else (
+                eprintf (f_"%s: no ‘arch’ entry for ‘%s’\n") prog n;
+                corrupt_file ()
+              ) in
           let signature_uri =
             try Some (make_absolute_uri (List.assoc ("sig", None) fields))
             with Not_found -> None in
@@ -112,21 +129,34 @@ let get_index ~downloader ~sigchecker { Sources.uri; proxy } =
           let revision =
             try Rev_int (int_of_string (List.assoc ("revision", None) fields))
             with
-            | Not_found -> Rev_int 1
+            | Not_found -> if template then Rev_int 0 else Rev_int 1
             | Failure _ ->
               eprintf (f_"%s: cannot parse ‘revision’ field for ‘%s’\n") prog n;
               corrupt_file () in
           let format =
             try Some (List.assoc ("format", None) fields) with Not_found -> None in
           let size =
+            let get_image_size filepath =
+              (* If a compressed image manages to reach this code, qemu-img just
+                 returns a virtual-size equal to actual-size *)
+              let infos = Utils.get_image_infos filepath in
+              Yajl.object_get_number "virtual-size" infos in
             try Int64.of_string (List.assoc ("size", None) fields)
             with
             | Not_found ->
-              eprintf (f_"%s: no ‘size’ field for ‘%s’\n") prog n;
-              corrupt_file ()
+              if template then
+                get_image_size file_uri
+              else (
+                eprintf (f_"%s: no ‘size’ field for ‘%s’\n") prog n;
+                corrupt_file ()
+              )
             | Failure _ ->
-              eprintf (f_"%s: cannot parse ‘size’ field for ‘%s’\n") prog n;
-              corrupt_file () in
+              if template then
+                get_image_size file_uri
+              else (
+                eprintf (f_"%s: cannot parse ‘size’ field for ‘%s’\n") prog n;
+                corrupt_file ()
+              ) in
           let compressed_size =
             try Some (Int64.of_string (List.assoc ("compressed_size", None) fields))
             with
diff --git a/builder/index_parser.mli b/builder/index_parser.mli
index b8d8ddf3d..324f4fc5a 100644
--- a/builder/index_parser.mli
+++ b/builder/index_parser.mli
@@ -16,4 +16,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *)
 
-val get_index : downloader:Downloader.t -> sigchecker:Sigchecker.t -> Sources.source -> Index.index
+val get_index : downloader:Downloader.t -> sigchecker:Sigchecker.t -> ?template:bool -> Sources.source -> Index.index
+(** [get_index download sigchecker template source] will parse the source
+    index file into an index entry list. If the template flag is set to
+    true, the parser will be less picky about missing values. *)
-- 
2.13.2




More information about the Libguestfs mailing list