Gabriel de Perthuis
2013-Jun-06 09:27 UTC
[Libguestfs] [supermin PATCH] RFC: Add a --names-only flag.
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
Richard W.M. Jones
2013-Jun-06 11:29 UTC
Re: [Libguestfs] [supermin PATCH] RFC: Add a --names-only flag.
On Thu, Jun 06, 2013 at 11:27:37AM +0200, Gabriel de Perthuis wrote:> zypper wasn't build-tested because I don't have the dependency.It should build on Debian if you install libinifiles-ocaml-dev. Thanks - I pushed this. I made some minor changes, adding comments and printing an error if the --names-only flag is used with backends that don't support it. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW