[Libguestfs] [supermin PATCH] RFC: Add a --names-only flag.

Gabriel de Perthuis g2p.code at gmail.com
Thu Jun 6 09:27:37 UTC 2013


This takes a list of package names, adding them to the image
without pulling any dependencies.

Only implemented for Debian at the moment.
zypper wasn't build-tested because I don't have the dependency.
---
 src/.depend                       |  2 +-
 src/supermin.ml                   |  6 +++---
 src/supermin_cmdline.ml           | 13 ++++++++++---
 src/supermin_cmdline.mli          | 10 +++++++---
 src/supermin_debian.ml            |  7 +++++--
 src/supermin_package_handlers.ml  |  2 +-
 src/supermin_package_handlers.mli |  4 ++--
 src/supermin_pacman.ml            |  2 +-
 src/supermin_yum_rpm.ml           |  2 +-
 src/supermin_zypp_rpm.ml          | 10 +++++-----
 10 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/src/.depend b/src/.depend
index 624191e..8342f31 100644
--- a/src/.depend
+++ b/src/.depend
@@ -5,11 +5,11 @@ supermin_cmdline.cmo: config.cmo supermin_cmdline.cmi
 supermin_cmdline.cmx: config.cmx supermin_cmdline.cmi
 supermin.cmo: supermin_utils.cmi supermin_package_handlers.cmi supermin_cmdline.cmi config.cmo
 supermin.cmx: supermin_utils.cmx supermin_package_handlers.cmx supermin_cmdline.cmx config.cmx
 supermin_debian.cmo: supermin_utils.cmi supermin_package_handlers.cmi supermin_cmdline.cmi config.cmo
 supermin_debian.cmx: supermin_utils.cmx supermin_package_handlers.cmx supermin_cmdline.cmx config.cmx
-supermin_package_handlers.cmi:
+supermin_package_handlers.cmi: supermin_cmdline.cmi
 supermin_package_handlers.cmo: supermin_utils.cmi supermin_cmdline.cmi supermin_package_handlers.cmi
 supermin_package_handlers.cmx: supermin_utils.cmx supermin_cmdline.cmx supermin_package_handlers.cmi
 supermin_pacman.cmo: supermin_utils.cmi supermin_package_handlers.cmi supermin_cmdline.cmi config.cmo
 supermin_pacman.cmx: supermin_utils.cmx supermin_package_handlers.cmx supermin_cmdline.cmx config.cmx
 supermin_utils.cmi:
diff --git a/src/supermin.ml b/src/supermin.ml
index 57189b4..c36d80f 100644
--- a/src/supermin.ml
+++ b/src/supermin.ml
@@ -39,11 +39,11 @@ let () =
   let ph = get_package_handler () in
 
   debug "selected package handler: %s" (get_package_handler_name ());
 
   (* Not --names: check files exist. *)
-  if not names_mode then (
+  if mode == PkgFiles then (
     List.iter (
       fun pkg ->
         if not (file_exists pkg) then (
           eprintf "supermin: %s: no such file (did you miss out the --names option?)\n" pkg;
           exit 1
@@ -53,12 +53,12 @@ let () =
 
   (* --names: resolve the package list to a full list of package names
    * (including dependencies).
    *)
   let packages =
-    if names_mode then (
-      let packages = ph.ph_resolve_dependencies_and_download packages in
+    if mode != PkgFiles then (
+      let packages = ph.ph_resolve_dependencies_and_download packages mode in
       debug "resolved packages: %s" (String.concat " " packages);
       packages
     )
     else packages in
 
diff --git a/src/supermin_cmdline.ml b/src/supermin_cmdline.ml
index 65f6250..8aaac28 100644
--- a/src/supermin_cmdline.ml
+++ b/src/supermin_cmdline.ml
@@ -16,12 +16,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  *)
 
 open Printf
 
+type mode =
+  |PkgFiles
+  |PkgNames
+  |PkgNamesOnly
+
 let excludes = ref []
-let names_mode = ref false
+let mode = ref PkgFiles
 let outputdir = ref "."
 let packages = ref []
 let save_temps = ref false
 let use_installed = ref false
 let verbose = ref false
@@ -50,12 +55,14 @@ let set_packager_config filename =
   packager_config := Some filename
 
 let argspec = Arg.align [
   "--exclude", Arg.String add_exclude,
     "regexp Exclude packages matching regexp";
-  "--names", Arg.Set names_mode,
+  "--names", Arg.Unit (fun () -> mode := PkgNames),
     " Specify set of root package names on command line";
+  "--names-only", Arg.Unit (fun () -> mode := PkgNamesOnly),
+    " Specify exact set of package names on command line";
   "--no-warnings", Arg.Clear warnings,
     " Suppress warnings";
   "-o", Arg.Set_string outputdir,
     "outputdir Set output directory (default: \".\")";
   "--packager-config", Arg.String set_packager_config,
@@ -99,11 +106,11 @@ let () =
     eprintf "supermin: no packages listed on the command line\n";
     exit 1
   )
 
 let excludes = List.rev !excludes
-let names_mode = !names_mode
+let mode = !mode
 let outputdir = !outputdir
 let packages = List.rev !packages
 let save_temps = !save_temps
 let use_installed = !use_installed
 let verbose = !verbose
diff --git a/src/supermin_cmdline.mli b/src/supermin_cmdline.mli
index 54a229c..fbdf4ae 100644
--- a/src/supermin_cmdline.mli
+++ b/src/supermin_cmdline.mli
@@ -20,16 +20,20 @@
 
 val debug : ('a, unit, string, unit) format4 -> 'a
   (** Print string (like printf), but only if --verbose was given on
       the command line. *)
 
+type mode =
+  |PkgFiles
+  |PkgNames
+  |PkgNamesOnly
+
 val excludes : Str.regexp list
   (** List of package regexps to exclude. *)
 
-val names_mode : bool
-  (** True if [--names] was given on the command line (otherwise
-      {!packages} is a list of filenames). *)
+val mode : mode
+  (** How to interpret {!packages} *)
 
 val outputdir : string
   (** Output directory. *)
 
 val packages : string list
diff --git a/src/supermin_debian.ml b/src/supermin_debian.ml
index 08e7d7c..3759f9a 100644
--- a/src/supermin_debian.ml
+++ b/src/supermin_debian.ml
@@ -51,13 +51,16 @@ let get_installed_pkgs () =
  * 'apt-get install'.
  *)
 let which_dependencies = "-i"
 (*let which_dependencies = "--no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances"*)
 
-let rec debian_resolve_dependencies_and_download names =
+let rec debian_resolve_dependencies_and_download names mode =
+  let which_dependencies =
+    if mode == PkgNames then which_dependencies ^ " --recurse"
+    else which_dependencies in
   let cmd =
-    sprintf "%s depends --recurse %s %s | grep -v '^[<[:space:]]' | grep -Ev ':\\w+\\b'"
+    sprintf "%s depends %s %s | grep -v '^[<[:space:]]' | grep -Ev ':\\w+\\b'"
       Config.apt_cache which_dependencies
       (String.concat " " (List.map Filename.quote names)) in
   let pkgs = run_command_get_lines cmd in
   let pkgs =
     if Config.apt_cache_depends_recurse_broken then
diff --git a/src/supermin_package_handlers.ml b/src/supermin_package_handlers.ml
index aea557e..7048f66 100644
--- a/src/supermin_package_handlers.ml
+++ b/src/supermin_package_handlers.ml
@@ -23,11 +23,11 @@ open Supermin_utils
 open Supermin_cmdline
 
 type package_handler = {
   ph_detect : unit -> bool;
   ph_init : unit -> unit;
-  ph_resolve_dependencies_and_download : string list -> string list;
+  ph_resolve_dependencies_and_download : string list -> mode -> string list;
   ph_list_files : string -> (string * file_type) list;
   ph_get_file_from_package : string -> string -> string
 }
 and file_type = {
   ft_dir : bool;
diff --git a/src/supermin_package_handlers.mli b/src/supermin_package_handlers.mli
index 27750e1..8ee12dd 100644
--- a/src/supermin_package_handlers.mli
+++ b/src/supermin_package_handlers.mli
@@ -27,12 +27,12 @@ type package_handler = {
   (** After a package handler is selected, this function is called
       which can optionally do any initialization that is required.
       This is only called on the package handler if it has returned
       [true] from {!ph_detect}. *)
 
-  ph_resolve_dependencies_and_download : string list -> string list;
-  (** [ph_resolve_dependencies_and_download pkgs]
+  ph_resolve_dependencies_and_download : string list -> Supermin_cmdline.mode -> string list;
+  (** [ph_resolve_dependencies_and_download pkgs mode]
       Take a list of package names, and using the package manager
       resolve those to a list of all the packages that are required
       including dependencies.  Download the full list of packages and
       dependencies into a tmpdir.  Return the list of full filenames.
 
diff --git a/src/supermin_pacman.ml b/src/supermin_pacman.ml
index c08a7e3..01d66f9 100644
--- a/src/supermin_pacman.ml
+++ b/src/supermin_pacman.ml
@@ -34,11 +34,11 @@ let pacman_detect () =
 
 let pacman_init () =
   if use_installed then
     failwith "pacman driver doesn't support --use-installed"
 
-let pacman_resolve_dependencies_and_download names =
+let pacman_resolve_dependencies_and_download names mode =
   let cmd =
     sprintf "(for p in %s; do pactree -u $p; done) | awk '{print $1}' | sort -u"
       (String.concat " " (List.map Filename.quote names)) in
   let pkgs = run_command_get_lines cmd in
 
diff --git a/src/supermin_yum_rpm.ml b/src/supermin_yum_rpm.ml
index b242aaf..be83582 100644
--- a/src/supermin_yum_rpm.ml
+++ b/src/supermin_yum_rpm.ml
@@ -34,11 +34,11 @@ let yum_rpm_detect () =
 
 let yum_rpm_init () =
   if use_installed then
     failwith "yum_rpm driver doesn't support --use-installed"
 
-let yum_rpm_resolve_dependencies_and_download names =
+let yum_rpm_resolve_dependencies_and_download names mode =
   (* Liberate this data from python. *)
   let tmpfile = tmpdir // "names.tmp" in
   let py = sprintf "
 import yum
 import yum.misc
diff --git a/src/supermin_zypp_rpm.ml b/src/supermin_zypp_rpm.ml
index 655ba99..ad5a347 100644
--- a/src/supermin_zypp_rpm.ml
+++ b/src/supermin_zypp_rpm.ml
@@ -74,11 +74,11 @@ let zypp_rpm_detect () =
 
 let zypp_rpm_init () =
   if use_installed then
     eprintf "supermin: zypp_rpm driver assumes all packages are already installed when called with option --use-installed.\n%!"
 
-let zypp_rpm_resolve_dependencies_and_download_no_installed names =
+let zypp_rpm_resolve_dependencies_and_download_no_installed names mode =
   (* Liberate this data from shell. *)
   let tmp_pkg_cache_dir = tmpdir // "pkg_cache_dir" in
   let tmp_root = tmpdir // "root" in
   let sh = sprintf "
 %s
@@ -136,11 +136,11 @@ time zypper \
   let pkgs = walk_directory_tree tmp_pkg_cache_dir  ".*\\.rpm" in
 
   (* Return list of package filenames. *)
   pkgs
 
-let zypp_rpm_resolve_dependencies_and_download_use_installed names =
+let zypp_rpm_resolve_dependencies_and_download_use_installed names mode =
   let cmd = sprintf "
 %s
 unset LANG ${!LC_*}
 zypper \
 	%s \
@@ -167,15 +167,15 @@ zypper \
   let pkg_names = run_command_get_lines cmd in
 
   (* Return list of package names, remove empty lines. *)
   List.filter (fun s -> s <> "") pkg_names
 
-let zypp_rpm_resolve_dependencies_and_download names =
+let zypp_rpm_resolve_dependencies_and_download names mode =
   if use_installed then
-    zypp_rpm_resolve_dependencies_and_download_use_installed names
+    zypp_rpm_resolve_dependencies_and_download_use_installed names mode
   else
-    zypp_rpm_resolve_dependencies_and_download_no_installed names
+    zypp_rpm_resolve_dependencies_and_download_no_installed names mode
 
 let rec zypp_rpm_list_files pkg =
   (* Run rpm -qlp with some extra magic. *)
   let cmd =
     sprintf "rpm -q --qf '[%%{FILENAMES} %%{FILEFLAGS:fflags} %%{FILEMODES} %%{FILESIZES}\\n]' %s %S"
-- 
1.8.3.222.g430da9e




More information about the Libguestfs mailing list