← Back to team overview

cloud-init-dev team mailing list archive

[Merge] lp:~harlowja/cloud-init/pkg-up-install-goodies into lp:cloud-init

 

Joshua Harlow has proposed merging lp:~harlowja/cloud-init/pkg-up-install-goodies into lp:cloud-init.

Requested reviews:
  cloud init development team (cloud-init-dev)

For more details, see:
https://code.launchpad.net/~harlowja/cloud-init/pkg-up-install-goodies/+merge/130019
-- 
https://code.launchpad.net/~harlowja/cloud-init/pkg-up-install-goodies/+merge/130019
Your team cloud init development team is requested to review the proposed merge of lp:~harlowja/cloud-init/pkg-up-install-goodies into lp:cloud-init.
=== renamed file 'cloudinit/config/cc_apt_update_upgrade.py' => 'cloudinit/config/cc_apt_configure.py'
--- cloudinit/config/cc_apt_update_upgrade.py	2012-08-22 21:02:54 +0000
+++ cloudinit/config/cc_apt_configure.py	2012-10-17 02:20:23 +0000
@@ -20,7 +20,6 @@
 
 import glob
 import os
-import time
 
 from cloudinit import templater
 from cloudinit import util
@@ -47,9 +46,6 @@
 
 
 def handle(name, cfg, cloud, log, _args):
-    update = util.get_cfg_option_bool(cfg, 'apt_update', False)
-    upgrade = util.get_cfg_option_bool(cfg, 'apt_upgrade', False)
-
     release = get_release()
     mirrors = find_apt_mirror_info(cloud, cfg)
     if not mirrors or "primary" not in mirrors:
@@ -61,7 +57,7 @@
     mirror = mirrors["primary"]
     mirrors["mirror"] = mirror
 
-    log.debug("mirror info: %s" % mirrors)
+    log.debug("Mirror info: %s" % mirrors)
 
     if not util.get_cfg_option_bool(cfg,
                                     'apt_preserve_sources_list', False):
@@ -92,59 +88,16 @@
         params['MIRROR'] = mirror
         errors = add_sources(cloud, cfg['apt_sources'], params)
         for e in errors:
-            log.warn("Source Error: %s", ':'.join(e))
+            log.warn("Add source error: %s", ':'.join(e))
 
     dconf_sel = util.get_cfg_option_str(cfg, 'debconf_selections', False)
     if dconf_sel:
-        log.debug("setting debconf selections per cloud config")
+        log.debug("Setting debconf selections per cloud config")
         try:
             util.subp(('debconf-set-selections', '-'), dconf_sel)
-        except:
+        except Exception:
             util.logexc(log, "Failed to run debconf-set-selections")
 
-    pkglist = util.get_cfg_option_list(cfg, 'packages', [])
-
-    errors = []
-    if update or len(pkglist) or upgrade:
-        try:
-            cloud.distro.update_package_sources()
-        except Exception as e:
-            util.logexc(log, "Package update failed")
-            errors.append(e)
-
-    if upgrade:
-        try:
-            cloud.distro.package_command("upgrade")
-        except Exception as e:
-            util.logexc(log, "Package upgrade failed")
-            errors.append(e)
-
-    if len(pkglist):
-        try:
-            cloud.distro.install_packages(pkglist)
-        except Exception as e:
-            util.logexc(log, "Failed to install packages: %s ", pkglist)
-            errors.append(e)
-
-    # kernel and openssl (possibly some other packages)
-    # write a file /var/run/reboot-required after upgrading.
-    # if that file exists and configured, then just stop right now and reboot
-    # TODO(smoser): handle this less voilently
-    reboot_file = "/var/run/reboot-required"
-    if ((upgrade or pkglist) and cfg.get("apt_reboot_if_required", False) and
-         os.path.isfile(reboot_file)):
-        log.warn("rebooting after upgrade or install per %s" % reboot_file)
-        time.sleep(1)  # give the warning time to get out
-        util.subp(["/sbin/reboot"])
-        time.sleep(60)
-        log.warn("requested reboot did not happen!")
-        errors.append(Exception("requested reboot did not happen!"))
-
-    if len(errors):
-        log.warn("%s failed with exceptions, re-raising the last one",
-                 len(errors))
-        raise errors[-1]
-
 
 # get gpg keyid from keyserver
 def getkeybyid(keyid, keyserver):

=== added file 'cloudinit/config/cc_package_update_upgrade_install.py'
--- cloudinit/config/cc_package_update_upgrade_install.py	1970-01-01 00:00:00 +0000
+++ cloudinit/config/cc_package_update_upgrade_install.py	2012-10-17 02:20:23 +0000
@@ -0,0 +1,110 @@
+# vi: ts=4 expandtab
+#
+#    Copyright (C) 2012 Yahoo! Inc.
+#
+#    Author: Joshua Harlow <harlowja@xxxxxxxxxxxxx>
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License version 3, as
+#    published by the Free Software Foundation.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from logging import StreamHandler
+import os
+import time
+
+from cloudinit import util
+
+REBOOT_FILE = "/var/run/reboot-required"
+REBOOT_CMD = ["/sbin/reboot"]
+
+
+def _multi_cfg_bool_get(cfg, *keys):
+    for k in keys:
+        if util.get_cfg_option_bool(cfg, k, False):
+            return True
+    return False
+
+
+def _flush_loggers(root):
+    for h in root.handlers:
+        if isinstance(h, (StreamHandler)):
+            try:
+                h.flush()
+            except IOError:
+                pass
+    if root.parent:
+        _flush_loggers(root.parent)
+
+
+def _fire_reboot(log, wait_attempts=6, initial_sleep=1, backoff=2):
+    util.subp(REBOOT_CMD)
+    start = time.time()
+    wait_time = initial_sleep
+    for _i in range(0, wait_attempts):
+        time.sleep(wait_time)
+        wait_time *= backoff
+        elapsed = time.time() - start
+        log.debug("Rebooted, but still running after %s seconds", int(elapsed))
+    # If we got here, not good
+    elapsed = time.time() - start
+    raise RuntimeError(("Reboot did not happen"
+                        " after %s seconds!") % (int(elapsed)))
+
+
+def handle(_name, cfg, cloud, log, _args):
+    # Handle the old style + new config names
+    update = _multi_cfg_bool_get(cfg, 'apt_update', 'package_update')
+    upgrade = _multi_cfg_bool_get(cfg, 'package_upgrade', 'apt_upgrade')
+    reboot_if_required = _multi_cfg_bool_get(cfg, 'apt_reboot_if_required',
+                                             'package_reboot_if_required')
+    pkglist = util.get_cfg_option_list(cfg, 'packages', [])
+
+    errors = []
+    if update or len(pkglist) or upgrade:
+        try:
+            cloud.distro.update_package_sources()
+        except Exception as e:
+            util.logexc(log, "Package update failed")
+            errors.append(e)
+
+    if upgrade:
+        try:
+            cloud.distro.package_command("upgrade")
+        except Exception as e:
+            util.logexc(log, "Package upgrade failed")
+            errors.append(e)
+
+    if len(pkglist):
+        try:
+            cloud.distro.install_packages(pkglist)
+        except Exception as e:
+            util.logexc(log, "Failed to install packages: %s", pkglist)
+            errors.append(e)
+
+    # TODO(smoser): handle this less violently
+    # kernel and openssl (possibly some other packages)
+    # write a file /var/run/reboot-required after upgrading.
+    # if that file exists and configured, then just stop right now and reboot
+    reboot_fn_exists = os.path.isfile(REBOOT_FILE)
+    if (upgrade or pkglist) and reboot_if_required and reboot_fn_exists:
+        try:
+            log.warn("Rebooting after upgrade or install per %s", REBOOT_FILE)
+            # Flush the above warning + anything else out...
+            _flush_loggers(log)
+            _fire_reboot(log)
+        except Exception as e:
+            util.logexc(log, "Requested reboot did not happen!")
+            errors.append(e)
+
+    if len(errors):
+        log.warn("%s failed with exceptions, re-raising the last one",
+                 len(errors))
+        raise errors[-1]


Follow ups