[Libguestfs] [PATCH 6/6] customize: add basic subscription-manager operations

Pino Toscano ptoscano at redhat.com
Wed Jul 8 14:42:18 UTC 2015


Add simple operations for RHEL guests using subscription-manager, so it
is possible to e.g. install software on them.
---
 customize/Makefile.am      |   8 +++-
 customize/customize_run.ml |  58 ++++++++++++++++++++++++++
 generator/customize.ml     | 101 +++++++++++++++++++++++++++++++++++++++++++++
 sysprep/Makefile.am        |   8 +++-
 4 files changed, 173 insertions(+), 2 deletions(-)

diff --git a/customize/Makefile.am b/customize/Makefile.am
index 8f0a2d8..d664ba4 100644
--- a/customize/Makefile.am
+++ b/customize/Makefile.am
@@ -67,6 +67,10 @@ SOURCES_C = \
 	$(top_srcdir)/fish/file-edit.c \
 	$(top_srcdir)/fish/file-edit.h \
 	$(top_srcdir)/mllib/uri-c.c \
+	$(top_srcdir)/mllib/index-parse.c \
+	$(top_srcdir)/mllib/index-scan.c \
+	$(top_srcdir)/mllib/index-struct.c \
+	$(top_srcdir)/mllib/index-parser-c.c \
 	crypt-c.c \
 	perl_edit-c.c
 
@@ -85,7 +89,8 @@ virt_customize_CPPFLAGS = \
 virt_customize_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS) \
 	$(LIBVIRT_CFLAGS) \
-	$(LIBXML2_CFLAGS)
+	$(LIBXML2_CFLAGS) \
+	-Wno-unused-macros
 
 BOBJECTS = \
 	$(top_builddir)/mllib/config.cmo \
@@ -93,6 +98,7 @@ BOBJECTS = \
 	$(top_builddir)/mllib/common_utils.cmo \
 	$(top_builddir)/mllib/regedit.cmo \
 	$(top_builddir)/mllib/uRI.cmo \
+	$(top_builddir)/mllib/ini_reader.cmo \
 	$(SOURCES_ML:.ml=.cmo)
 XOBJECTS = $(BOBJECTS:.cmo=.cmx)
 
diff --git a/customize/customize_run.ml b/customize/customize_run.ml
index d9547a0..9fb2b14 100644
--- a/customize/customize_run.ml
+++ b/customize/customize_run.ml
@@ -153,6 +153,33 @@ exec >>%s 2>&1
     Hashtbl.replace passwords user pw
   in
 
+  (* Parse the subscription-manager configuration. *)
+  let sm_config =
+    match ops.flags.sm_config with
+    | None -> None
+    | Some c ->
+      try
+        Some (Ini_reader.read_ini ~check_duplicated_sections:true
+                ~check_duplicated_fields:true c)
+      with exn ->
+        error (f_"cannot parse the subscription-manager configuration: %s")
+          (Printexc.to_string exn)
+  in
+  let sm_config_get_value group key =
+    let conf =
+      match sm_config with
+      | None ->
+        error (f_"subscription-manager configuration required for this operation")
+      | Some c -> c in
+    try Ini_reader.ini_get_value conf group key
+    with
+    | Ini_reader.Section_not_found s ->
+      error (f_"subscription-manager configuration lacks the group '%s'") s
+    | Ini_reader.Key_not_found (s, k, _) ->
+      error (f_"subscription-manager configuration lacks the key '%s' in group '%s'")
+        k s
+  in
+
   (* Perform the remaining customizations in command-line order. *)
   List.iter (
     function
@@ -249,6 +276,37 @@ exec >>%s 2>&1
       message (f_"Scrubbing: %s") path;
       g#scrub_file path
 
+    | `SMAttach id ->
+      (match id with
+      | "auto" ->
+        message (f_"Attaching to compatible subscriptions");
+        let cmd = "subscription-manager attach --auto" in
+        do_run ~display:cmd cmd
+      | id ->
+        let pool_id = sm_config_get_value ("attach-" ^ id) "pool" in
+        message (f_"Attaching to the pool %s") pool_id;
+        let cmd = sprintf "subscription-manager attach --pool=%s" pool_id in
+        do_run ~display:cmd cmd
+      )
+
+    | `SMRegister ->
+      message (f_"Registering with subscription-manager");
+      let username = sm_config_get_value "general" "username" in
+      let password = sm_config_get_value "general" "password" in
+      let cmd = sprintf "subscription-manager register --username='%s' --password='%s'"
+                  username password in
+      do_run ~display:"subscription-manager register" cmd
+
+    | `SMRemove ->
+      message (f_"Removing all the subscriptions");
+      let cmd = "subscription-manager remove --all" in
+      do_run ~display:cmd cmd
+
+    | `SMUnregister ->
+      message (f_"Unregistering with subscription-manager");
+      let cmd = "subscription-manager unregister" in
+      do_run ~display:cmd cmd
+
     | `SSHInject (user, selector) ->
       (match g#inspect_get_type root with
       | "linux" | "freebsd" | "netbsd" | "openbsd" | "hurd" ->
diff --git a/generator/customize.ml b/generator/customize.ml
index f57aba6..bb31c25 100644
--- a/generator/customize.ml
+++ b/generator/customize.ml
@@ -327,6 +327,64 @@ It cannot delete directories, only regular files.
 =back";
   };
 
+  { op_name = "sm-attach";
+    op_type = String "ID";
+    op_discrim = "`SMAttach";
+    op_shortdesc = "Attach to a subscription-manager pool";
+    op_pod_longdesc = "\
+Attach to a pool using C<subscription-manager>.  C<ID> can be any of
+the following:
+
+=over 4
+
+=item C<auto>
+
+subscription-manager attaches to the best-fitting subscriptions for
+the system.
+
+=item C<ID>
+
+This requires a configuration file specified with the settings
+(see also I<--sm-config>), containing the following:
+
+ [attach-ID]
+ pool=0123...
+
+That is, a group named after the specified C<ID>, containing a C<pool>
+key with the actual pool ID.
+
+=back";
+  };
+
+  { op_name = "sm-register";
+    op_type = Unit;
+    op_discrim = "`SMRegister";
+    op_shortdesc = "Register using subscription-manager";
+    op_pod_longdesc = "\
+Register the guest using C<subscription-manager>.
+
+This requires a configuration file specified with the settings
+(see also I<--sm-config>), with the C<username> and C<password>
+keys in the C<general> group.";
+  };
+
+  { op_name = "sm-remove";
+    op_type = Unit;
+    op_discrim = "`SMRemove";
+    op_shortdesc = "Remove all the subscriptions";
+    op_pod_longdesc = "\
+Remove all the subscriptions from the guest using
+C<subscription-manager>.";
+  };
+
+  { op_name = "sm-unregister";
+    op_type = Unit;
+    op_discrim = "`SMUnregister";
+    op_shortdesc = "Unregister using subscription-manager";
+    op_pod_longdesc = "\
+Unregister the guest using C<subscription-manager>.";
+  };
+
   { op_name = "ssh-inject";
     op_type = SSHKeySelector "USER[:SELECTOR]";
     op_discrim = "`SSHInject";
@@ -428,6 +486,7 @@ type flag = {
 and flag_type =
 | FlagBool of bool                  (* boolean is the default value *)
 | FlagPasswordCrypto of string
+| FlagSMConfig of string
 
 let flags = [
   { flag_name = "no-logfile";
@@ -477,6 +536,25 @@ Relabel files in the guest so that they have the correct SELinux label.
 
 You should only use this option for guests which support SELinux.";
   };
+
+  { flag_name = "sm-config";
+    flag_type = FlagSMConfig "config";
+    flag_ml_var = "sm_config";
+    flag_shortdesc = "configuration for subscription-manager";
+    flag_pod_longdesc = "\
+Defines a configuration for subscription-manager operations.
+This file has a simple text like the following:
+
+ [general]
+ username=user
+ password=secret
+
+ [attach-0]
+ pool=0123...
+
+Different subscription-manager commands may require different sections.";
+  };
+
 ]
 
 let rec generate_customize_cmdline_mli () =
@@ -532,6 +610,8 @@ let rec argspec () =
       pr "  let %s = ref %b in\n" var default
     | { flag_type = FlagPasswordCrypto _; flag_ml_var = var } ->
       pr "  let %s = ref None in\n" var
+    | { flag_type = FlagSMConfig _; flag_ml_var = var } ->
+      pr "  let %s = ref None in\n" var
   ) flags;
   pr "\
 
@@ -699,6 +779,18 @@ let rec argspec () =
       pr "      \"%s\" ^ \" \" ^ s_\"%s\"\n" v shortdesc;
       pr "    ),\n";
       pr "    Some %S, %S;\n" v longdesc
+    | { flag_type = FlagSMConfig v; flag_ml_var = var;
+        flag_name = name; flag_shortdesc = shortdesc;
+        flag_pod_longdesc = longdesc } ->
+      pr "    (\n";
+      pr "      \"--%s\",\n" name;
+      pr "      Arg.String (\n";
+      pr "        fun s ->\n";
+      pr "          %s := Some s\n" var;
+      pr "      ),\n";
+      pr "      \"%s\" ^ \" \" ^ s_\"%s\"\n" v shortdesc;
+      pr "    ),\n";
+      pr "    Some %S, %S;\n" v longdesc
   ) flags;
 
   pr "  ]
@@ -809,6 +901,10 @@ type ops = {
         flag_name = name } ->
       pr "  %s : Password.password_crypto option;\n      (* --%s %s *)\n"
         var name v
+    | { flag_type = FlagSMConfig v; flag_ml_var = var;
+        flag_name = name } ->
+      pr "  %s : string option;\n      (* --%s %s *)\n"
+        var name v
   ) flags;
   pr "}\n"
 
@@ -832,6 +928,8 @@ let generate_customize_synopsis_pod () =
           n, sprintf "[--%s]" n
         | { flag_type = FlagPasswordCrypto v; flag_name = n } ->
           n, sprintf "[--%s %s]" n v
+        | { flag_type = FlagSMConfig v; flag_name = n } ->
+          n, sprintf "[--%s %s]" n v
       ) flags in
 
   (* Print the option names in the synopsis, line-wrapped. *)
@@ -874,6 +972,9 @@ let generate_customize_options_pod () =
         | { flag_type = FlagPasswordCrypto v;
             flag_name = n; flag_pod_longdesc = ld } ->
           n, sprintf "B<--%s> %s" n v, ld
+        | { flag_type = FlagSMConfig v;
+            flag_name = n; flag_pod_longdesc = ld } ->
+          n, sprintf "B<--%s> %s" n v, ld
       ) flags in
   let cmp (arg1, _, _) (arg2, _, _) =
     compare (String.lowercase arg1) (String.lowercase arg2)
diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am
index c1d1245..e7977bd 100644
--- a/sysprep/Makefile.am
+++ b/sysprep/Makefile.am
@@ -81,6 +81,10 @@ SOURCES_ML = \
 SOURCES_C = \
 	$(top_srcdir)/mllib/uri-c.c \
 	$(top_srcdir)/mllib/mkdtemp-c.c \
+	$(top_srcdir)/mllib/index-parse.c \
+	$(top_srcdir)/mllib/index-scan.c \
+	$(top_srcdir)/mllib/index-struct.c \
+	$(top_srcdir)/mllib/index-parser-c.c \
 	$(top_srcdir)/customize/crypt-c.c \
 	$(top_srcdir)/customize/perl_edit-c.c \
 	$(top_srcdir)/fish/uri.c \
@@ -100,7 +104,8 @@ virt_sysprep_CPPFLAGS = \
 	-I$(top_srcdir)/fish
 virt_sysprep_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS) \
-	$(LIBXML2_CFLAGS)
+	$(LIBXML2_CFLAGS) \
+	-Wno-unused-macros
 
 BOBJECTS = \
 	$(top_builddir)/mllib/config.cmo \
@@ -109,6 +114,7 @@ BOBJECTS = \
 	$(top_builddir)/mllib/uRI.cmo \
 	$(top_builddir)/mllib/mkdtemp.cmo \
 	$(top_builddir)/mllib/regedit.cmo \
+	$(top_builddir)/mllib/ini_reader.cmo \
 	$(top_builddir)/customize/customize_utils.cmo \
 	$(top_builddir)/customize/crypt.cmo \
 	$(top_builddir)/customize/urandom.cmo \
-- 
2.1.0




More information about the Libguestfs mailing list