forked from pool/supermin
Olaf Hering
e04d44186c
OBS-URL: https://build.opensuse.org/package/show/Virtualization/supermin?expand=0&rev=5
156 lines
5.2 KiB
Diff
156 lines
5.2 KiB
Diff
From 9750c2e6050d73276699090180dc2e43d87c9663 Mon Sep 17 00:00:00 2001
|
|
From: Olaf Hering <olaf@aepfle.de>
|
|
Date: Thu, 11 Apr 2013 19:07:11 +0200
|
|
Subject: handle --use-installed in zypp driver
|
|
|
|
An attempt to use installed files in zypp driver.
|
|
Add also a comment about the theory of operation.
|
|
Enable set -x in shell only in verbose mode.
|
|
This adds a dependency to xmlstarlet, which is required to parse zypper output.
|
|
|
|
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
|
---
|
|
src/supermin_zypp_rpm.ml | 93 +++++++++++++++++++++++++++++++++++++++++-------
|
|
1 file changed, 80 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/src/supermin_zypp_rpm.ml b/src/supermin_zypp_rpm.ml
|
|
index 2089837..0f3b63a 100644
|
|
--- a/src/supermin_zypp_rpm.ml
|
|
+++ b/src/supermin_zypp_rpm.ml
|
|
@@ -18,6 +18,31 @@
|
|
|
|
(* Zypper and RPM support. *)
|
|
|
|
+(*
|
|
+ * Theory of operation:
|
|
+ * called as root:
|
|
+ * - without --use-installed:
|
|
+ * ->ph_resolve_dependencies_and_download() returns a list of filenames
|
|
+ * Need to download all packages into an empty --root directory so that
|
|
+ * zypper places all dependencies into --pkg-cache-dir
|
|
+ * - with --use-installed:
|
|
+ * ->ph_resolve_dependencies_and_download() returns a list of package names
|
|
+ * Need to work with an empty --root directory so that zypper can list
|
|
+ * all dependencies of "names". This mode assumes that all required packages
|
|
+ * are installed and the system is consistent. Downloading just the missing
|
|
+ * packages is not implemented.
|
|
+ * called as non-root:
|
|
+ * (Due to the usage of --root zypper does not require root permissions.)
|
|
+ * - without --use-installed:
|
|
+ * Same as above.
|
|
+ * - with --use-installed:
|
|
+ * Same as above.
|
|
+ *
|
|
+ * The usage of --packager-config is tricky: If --root is used zypper assumes
|
|
+ * that every config file is below <rootdir>. So the config has to be parsed
|
|
+ * and relevant files/dirs should be copied into <rootdir> so that zypper can
|
|
+ * use the specified config.
|
|
+ *)
|
|
open Unix
|
|
open Printf
|
|
|
|
@@ -34,15 +59,15 @@ let zypp_rpm_detect () =
|
|
Config.zypper <> "no" && Config.rpm <> "no"
|
|
|
|
let zypp_rpm_init () =
|
|
- if use_installed && Unix.getuid() > 0 then
|
|
- failwith "zypp_rpm driver doesn't support --use-installed when called as non-root user"
|
|
+ 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 names =
|
|
+let zypp_rpm_resolve_dependencies_and_download_no_installed names =
|
|
(* Liberate this data from shell. *)
|
|
let tmp_pkg_cache_dir = tmpdir // "pkg_cache_dir" in
|
|
let tmp_root = tmpdir // "root" in
|
|
let sh = sprintf "
|
|
-set -ex
|
|
+%s
|
|
unset LANG ${!LC_*}
|
|
tmpdir=%S
|
|
cache_dir=\"${tmpdir}/cache-dir\"
|
|
@@ -60,6 +85,7 @@ time zypper \
|
|
--download-only \
|
|
$@
|
|
"
|
|
+ (if verbose then "set -x" else "")
|
|
tmpdir
|
|
tmp_pkg_cache_dir
|
|
(if verbose then "--verbose --verbose" else "--quiet")
|
|
@@ -96,10 +122,47 @@ time zypper \
|
|
(* Return list of package filenames. *)
|
|
pkgs
|
|
|
|
+let zypp_rpm_resolve_dependencies_and_download_use_installed names =
|
|
+ let cmd = sprintf "
|
|
+%s
|
|
+unset LANG ${!LC_*}
|
|
+zypper \
|
|
+ %s \
|
|
+ %s \
|
|
+ --root %S --reposd-dir /dev/shm/supermin/zypp/repos.d \
|
|
+ --cache-dir %S \
|
|
+ --gpg-auto-import-keys \
|
|
+ --non-interactive \
|
|
+ --xml \
|
|
+ install \
|
|
+ --auto-agree-with-licenses \
|
|
+ --dry-run \
|
|
+ %s | \
|
|
+ xml sel -t \
|
|
+ -m \"stream/install-summary/to-install/solvable[%@type='package']\" \
|
|
+ -c \"string(%@name)\" -n
|
|
+"
|
|
+ (if verbose then "set -x" else "")
|
|
+ (if verbose then "--verbose --verbose" else "--quiet")
|
|
+ (match packager_config with None -> ""
|
|
+ | Some filename -> sprintf "--config %s" filename)
|
|
+ tmpdir tmpdir (String.concat " " (List.map Filename.quote names)) in
|
|
+ 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 =
|
|
+ if use_installed then
|
|
+ zypp_rpm_resolve_dependencies_and_download_use_installed names
|
|
+ else
|
|
+ zypp_rpm_resolve_dependencies_and_download_no_installed names
|
|
+
|
|
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]' -p %S"
|
|
+ sprintf "rpm -q --qf '[%%{FILENAMES} %%{FILEFLAGS:fflags} %%{FILEMODES} %%{FILESIZES}\\n]' %s %S"
|
|
+ (if use_installed then "" else "-p")
|
|
pkg in
|
|
let lines = run_command_get_lines cmd in
|
|
|
|
@@ -153,14 +216,18 @@ let rec zypp_rpm_list_files pkg =
|
|
files
|
|
|
|
let zypp_rpm_get_file_from_package pkg file =
|
|
- debug "extracting %s from %s ..." file (Filename.basename pkg);
|
|
-
|
|
- let outfile = tmpdir // file in
|
|
- let cmd =
|
|
- sprintf "umask 0000; rpm2cpio %s | (cd %s && cpio --quiet -id .%s)"
|
|
- (Filename.quote pkg) (Filename.quote tmpdir) (Filename.quote file) in
|
|
- run_command cmd;
|
|
- outfile
|
|
+ if use_installed then
|
|
+ file
|
|
+ else (
|
|
+ debug "extracting %s from %s ..." file (Filename.basename pkg);
|
|
+
|
|
+ let outfile = tmpdir // file in
|
|
+ let cmd =
|
|
+ sprintf "umask 0000; rpm2cpio %s | (cd %s && cpio --quiet -id .%s)"
|
|
+ (Filename.quote pkg) (Filename.quote tmpdir) (Filename.quote file) in
|
|
+ run_command cmd;
|
|
+ outfile
|
|
+ )
|
|
|
|
let () =
|
|
let ph = {
|