psss / rpms / libguestfs

Forked from rpms/libguestfs 5 years ago
Clone
Blob Blame History Raw
From a7a1577b86da7b90de88d39431035fa92cc022f9 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 19 Dec 2013 11:17:43 +0000
Subject: [PATCH] builder: Add --update option to update template/core
 packages.

(cherry picked from commit b46a5511b3a98c0d811353b1bc0c7745fa972dc6)
---
 builder/builder.ml       | 40 ++++++++++++++++++++++++++++-
 builder/cmdline.ml       |  5 +++-
 builder/virt-builder.pod | 67 +++++++++++++++++++++++++++++++++---------------
 3 files changed, 90 insertions(+), 22 deletions(-)

diff --git a/builder/builder.ml b/builder/builder.ml
index 1551b72..1cd007f 100644
--- a/builder/builder.ml
+++ b/builder/builder.ml
@@ -41,7 +41,7 @@ let main () =
     attach, cache, check_signature, curl, debug, delete, edit,
     firstboot, run, format, gpg, hostname, install, list_long, memsize, mkdirs,
     network, output, password_crypto, quiet, root_password, scrub,
-    scrub_logfile, size, smp, sources, sync, upload, writes =
+    scrub_logfile, size, smp, sources, sync, update, upload, writes =
     parse_cmdline () in
 
   (* Timestamped messages in ordinary, non-debug non-quiet mode. *)
@@ -669,6 +669,7 @@ exec >>%s 2>&1
         exit 1
   in
 
+  (* http://distrowatch.com/dwres.php?resource=package-management *)
   let guest_install_command packages =
     let quoted_args = String.concat " " (List.map quote packages) in
     match g#inspect_get_package_management root with
@@ -699,8 +700,45 @@ exec >>%s 2>&1
       eprintf (f_"%s: sorry, don't know how to use --install with the '%s' package manager\n")
         prog pm;
       exit 1
+
+  and guest_update_command () =
+    match g#inspect_get_package_management root with
+    | "apt" ->
+      (* http://unix.stackexchange.com/questions/22820 *)
+      sprintf "
+        export DEBIAN_FRONTEND=noninteractive
+        apt_opts='-q -y -o Dpkg::Options::=--force-confnew'
+        apt-get $apt_opts update
+        apt-get $apt_opts upgrade
+      "
+    | "pisi" ->
+      sprintf "pisi upgrade"
+    | "pacman" ->
+      sprintf "pacman -Su"
+    | "urpmi" ->
+      sprintf "urpmi --auto-select"
+    | "yum" ->
+      sprintf "yum -y update"
+    | "zypper" ->
+      sprintf "zypper update"
+    | "unknown" ->
+      eprintf (f_"%s: --update is not supported for this guest operating system\n")
+        prog;
+      exit 1
+    | pm ->
+      eprintf (f_"%s: sorry, don't know how to use --update with the '%s' package manager\n")
+        prog pm;
+      exit 1
   in
 
+  (* Update core/template packages. *)
+  if update then (
+    msg (f_"Updating core packages");
+
+    let cmd = guest_update_command () in
+    do_run ~display:cmd cmd
+  );
+
   (* Install packages. *)
   if install <> [] then (
     msg (f_"Installing packages: %s") (String.concat " " install);
diff --git a/builder/cmdline.ml b/builder/cmdline.ml
index b4e21fc..f25280c 100644
--- a/builder/cmdline.ml
+++ b/builder/cmdline.ml
@@ -169,6 +169,7 @@ let parse_cmdline () =
   let add_source arg = sources := arg :: !sources in
 
   let sync = ref true in
+  let update = ref false in
 
   let upload = ref [] in
   let add_upload arg =
@@ -259,6 +260,7 @@ let parse_cmdline () =
     "--smp",     Arg.Int set_smp,           "vcpus" ^ " " ^ s_"Set number of vCPUs";
     "--source",  Arg.String add_source,     "URL" ^ " " ^ s_"Set source URL";
     "--no-sync", Arg.Clear sync,            " " ^ s_"Do not fsync output file on exit";
+    "--update",  Arg.Set update,            " " ^ s_"Update core packages";
     "--upload",  Arg.String add_upload,     "file:dest" ^ " " ^ s_"Upload file to dest";
     "-v",        Arg.Set debug,             " " ^ s_"Enable debugging messages";
     "--verbose", Arg.Set debug,             ditto;
@@ -319,6 +321,7 @@ read the man page virt-builder(1).
   let smp = !smp in
   let sources = List.rev !sources in
   let sync = !sync in
+  let update = !update in
   let upload = List.rev !upload in
   let writes = List.rev !writes in
 
@@ -418,4 +421,4 @@ read the man page virt-builder(1).
   attach, cache, check_signature, curl, debug, delete, edit,
   firstboot, run, format, gpg, hostname, install, list_long, memsize, mkdirs,
   network, output, password_crypto, quiet, root_password, scrub,
-  scrub_logfile, size, smp, sources, sync, upload, writes
+  scrub_logfile, size, smp, sources, sync, update, upload, writes
diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod
index 817ddd4..094f028 100644
--- a/builder/virt-builder.pod
+++ b/builder/virt-builder.pod
@@ -18,6 +18,7 @@ virt-builder - Build virtual machine images quickly
     [--attach ISOFILE]
     [--root-password SELECTOR]
     [--hostname HOSTNAME]
+    [--update]
     [--install PKG,[PKG...]]
     [--mkdir DIR]
     [--write FILE:CONTENT]
@@ -215,7 +216,7 @@ I<--no-cache> disables template caching.
 Download all templates to the cache and then exit.  See L</CACHING>.
 
 Note this doesn't cache everything.  More templates might be uploaded.
-Also this doesn't cache packages (the I<--install> option).
+Also this doesn't cache packages (the I<--install>, I<--update> options).
 
 =item B<--check-signature>
 
@@ -349,6 +350,8 @@ installed during the image build using the guest's package manager
 For an overview on the different ways to install packages, see
 L</INSTALLING PACKAGES>.
 
+See also I<--update>.
+
 =item B<-l>
 
 =item B<--list>
@@ -580,6 +583,14 @@ Note that you should not point I<--source> to sources that you don't
 trust (unless the source is signed by someone you do trust).  See also
 the I<--no-network> option.
 
+=item B<--update>
+
+Do the equivalent of C<yum update>, C<apt-get upgrade>, or whatever
+command is required to update the packages already installed in the
+template to their latest versions.
+
+See also I<--install>.
+
 =item B<--upload> FILE:DEST
 
 Upload local file C<FILE> to destination C<DEST> in the disk image.
@@ -634,6 +645,18 @@ you can use I<--install> to install packages like this:
 This uses the guest's package manager and the host's network
 connection.
 
+=head3 Updating packages at build time
+
+To update the core set of packages in the template at build time:
+
+ virt-builder fedora-20 --update
+
+Most of the templates that ship with virt-builder come with a very
+minimal selection of packages (known as a "JEOS" or "Just Enough
+Operating System"), which are up to date at the time the template is
+created, but could be out of date by the time you come to install an
+OS from the template.  This option updates those template packages.
+
 =head3 Installing packages at first boot
 
 Another option is to install the packages when the guest first boots:
@@ -757,8 +780,8 @@ are other ways to manage passwords, see L<useradd(8)> for details.
 =head2 LOG FILE
 
 Scripts and package installation that runs at build time (I<--run>,
-I<--run-command>, I<--install>, but I<not> firstboot) is logged in one
-of the following locations:
+I<--run-command>, I<--install>, I<--update>, but I<not> firstboot) is
+logged in one of the following locations:
 
 =over 4
 
@@ -823,6 +846,10 @@ The root password is changed (I<--root-password>).
 
 =item *
 
+Core packages are updated (I<--update>).
+
+=item *
+
 Packages are installed (I<--install>).
 
 =item *
@@ -1342,9 +1369,9 @@ are not cached.
 
 Virt-builder uses L<curl(1)> to download files and it also uses the
 current C<http_proxy> (etc) settings when installing packages
-(I<--install>).  You may therefore want to set those environment
-variables in order to maximize the amount of local caching that
-happens.  See L</ENVIRONMENT VARIABLES> and L<curl(1)>.
+(I<--install>, I<--update>).  You may therefore want to set those
+environment variables in order to maximize the amount of local caching
+that happens.  See L</ENVIRONMENT VARIABLES> and L<curl(1)>.
 
 =head2 DIGITAL SIGNATURES
 
@@ -1379,8 +1406,8 @@ host architecture is.  For example an x86-64 guest on an ARM host.
 
 However certain options may not work correctly, specifically options
 that require running commands in the guest during the build process:
-I<--install>, I<--run>, I<--run-command>.  You may need to replace
-these with their firstboot-equivalents.
+I<--install>, I<--update>, I<--run>, I<--run-command>.  You may need
+to replace these with their firstboot-equivalents.
 
 An x86-64 host building 32 bit i686 guests should work without any
 special steps.
@@ -1390,11 +1417,11 @@ special steps.
 Virt-builder does not need to run as root (in fact, should not be run
 as root), and doesn't use setuid, C<sudo> or any similar mechanism.
 
-I<--install>, I<--run> and I<--run-command> are implemented using an
-appliance (a small virtual machine) so these commands do not run on
-the host.  If you are using the libguestfs libvirt backend and have
-SELinux enabled then the virtual machine is additionally encapsulated
-in an SELinux container (sVirt).
+I<--install>, I<--update>, I<--run> and I<--run-command> are
+implemented using an appliance (a small virtual machine) so these
+commands do not run on the host.  If you are using the libguestfs
+libvirt backend and have SELinux enabled then the virtual machine is
+additionally encapsulated in an SELinux container (sVirt).
 
 However these options will have access to the host's network and since
 the template may contain untrusted code, the code might try to access
@@ -1435,13 +1462,13 @@ Templates gets downloaded into the cache the first time they are used,
 or if you use the I<--cache-all-templates> option.  See L</CACHING>
 above for further information.
 
-Packages required for the I<--install> option are downloaded using the
-host network connection.  Setting the C<http_proxy>, C<https_proxy>
-and C<ftp_proxy> environment variables to point to a local web cache
-may ensure they only need to be downloaded once.  You can also try
-using a local package repository, although this can be complex to set
-up and varies according to which Linux distro you are trying to
-install.
+Packages required for the I<--install> and I<--update> options are
+downloaded using the host network connection.  Setting the
+C<http_proxy>, C<https_proxy> and C<ftp_proxy> environment variables
+to point to a local web cache may ensure they only need to be
+downloaded once.  You can also try using a local package repository,
+although this can be complex to set up and varies according to which
+Linux distro you are trying to install.
 
 =head3 Skipping virt-resize
 
-- 
1.8.4.2