Merge lp:~harlowja/cloud-init/pkg-up-install-goodies into lp:~cloud-init-dev/cloud-init/trunk

Proposed by Joshua Harlow
Status: Merged
Merged at revision: 699
Proposed branch: lp:~harlowja/cloud-init/pkg-up-install-goodies
Merge into: lp:~cloud-init-dev/cloud-init/trunk
Diff against target: 220 lines (+115/-51)
3 files modified
cloudinit/config/cc_apt_configure.py (+4/-51)
cloudinit/config/cc_package_update_upgrade_install.py (+99/-0)
cloudinit/log.py (+12/-0)
To merge this branch: bzr merge lp:~harlowja/cloud-init/pkg-up-install-goodies
Reviewer Review Type Date Requested Status
cloud-init Commiters Pending
Review via email: mp+130019@code.launchpad.net
To post a comment you must log in.
689. By Joshua Harlow

Move the recursive flushing to the log module.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== 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 04:17:17 +0000
@@ -20,7 +20,6 @@
2020
21import glob21import glob
22import os22import os
23import time
2423
25from cloudinit import templater24from cloudinit import templater
26from cloudinit import util25from cloudinit import util
@@ -47,9 +46,6 @@
4746
4847
49def handle(name, cfg, cloud, log, _args):48def handle(name, cfg, cloud, log, _args):
50 update = util.get_cfg_option_bool(cfg, 'apt_update', False)
51 upgrade = util.get_cfg_option_bool(cfg, 'apt_upgrade', False)
52
53 release = get_release()49 release = get_release()
54 mirrors = find_apt_mirror_info(cloud, cfg)50 mirrors = find_apt_mirror_info(cloud, cfg)
55 if not mirrors or "primary" not in mirrors:51 if not mirrors or "primary" not in mirrors:
@@ -61,7 +57,7 @@
61 mirror = mirrors["primary"]57 mirror = mirrors["primary"]
62 mirrors["mirror"] = mirror58 mirrors["mirror"] = mirror
6359
64 log.debug("mirror info: %s" % mirrors)60 log.debug("Mirror info: %s" % mirrors)
6561
66 if not util.get_cfg_option_bool(cfg,62 if not util.get_cfg_option_bool(cfg,
67 'apt_preserve_sources_list', False):63 'apt_preserve_sources_list', False):
@@ -92,59 +88,16 @@
92 params['MIRROR'] = mirror88 params['MIRROR'] = mirror
93 errors = add_sources(cloud, cfg['apt_sources'], params)89 errors = add_sources(cloud, cfg['apt_sources'], params)
94 for e in errors:90 for e in errors:
95 log.warn("Source Error: %s", ':'.join(e))91 log.warn("Add source error: %s", ':'.join(e))
9692
97 dconf_sel = util.get_cfg_option_str(cfg, 'debconf_selections', False)93 dconf_sel = util.get_cfg_option_str(cfg, 'debconf_selections', False)
98 if dconf_sel:94 if dconf_sel:
99 log.debug("setting debconf selections per cloud config")95 log.debug("Setting debconf selections per cloud config")
100 try:96 try:
101 util.subp(('debconf-set-selections', '-'), dconf_sel)97 util.subp(('debconf-set-selections', '-'), dconf_sel)
102 except:98 except Exception:
103 util.logexc(log, "Failed to run debconf-set-selections")99 util.logexc(log, "Failed to run debconf-set-selections")
104100
105 pkglist = util.get_cfg_option_list(cfg, 'packages', [])
106
107 errors = []
108 if update or len(pkglist) or upgrade:
109 try:
110 cloud.distro.update_package_sources()
111 except Exception as e:
112 util.logexc(log, "Package update failed")
113 errors.append(e)
114
115 if upgrade:
116 try:
117 cloud.distro.package_command("upgrade")
118 except Exception as e:
119 util.logexc(log, "Package upgrade failed")
120 errors.append(e)
121
122 if len(pkglist):
123 try:
124 cloud.distro.install_packages(pkglist)
125 except Exception as e:
126 util.logexc(log, "Failed to install packages: %s ", pkglist)
127 errors.append(e)
128
129 # kernel and openssl (possibly some other packages)
130 # write a file /var/run/reboot-required after upgrading.
131 # if that file exists and configured, then just stop right now and reboot
132 # TODO(smoser): handle this less voilently
133 reboot_file = "/var/run/reboot-required"
134 if ((upgrade or pkglist) and cfg.get("apt_reboot_if_required", False) and
135 os.path.isfile(reboot_file)):
136 log.warn("rebooting after upgrade or install per %s" % reboot_file)
137 time.sleep(1) # give the warning time to get out
138 util.subp(["/sbin/reboot"])
139 time.sleep(60)
140 log.warn("requested reboot did not happen!")
141 errors.append(Exception("requested reboot did not happen!"))
142
143 if len(errors):
144 log.warn("%s failed with exceptions, re-raising the last one",
145 len(errors))
146 raise errors[-1]
147
148101
149# get gpg keyid from keyserver102# get gpg keyid from keyserver
150def getkeybyid(keyid, keyserver):103def getkeybyid(keyid, keyserver):
151104
=== 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 04:17:17 +0000
@@ -0,0 +1,99 @@
1# vi: ts=4 expandtab
2#
3# Copyright (C) 2012 Yahoo! Inc.
4#
5# Author: Joshua Harlow <harlowja@yahoo-inc.com>
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 3, as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19import os
20import time
21
22from cloudinit import log as logging
23from cloudinit import util
24
25REBOOT_FILE = "/var/run/reboot-required"
26REBOOT_CMD = ["/sbin/reboot"]
27
28
29def _multi_cfg_bool_get(cfg, *keys):
30 for k in keys:
31 if util.get_cfg_option_bool(cfg, k, False):
32 return True
33 return False
34
35
36def _fire_reboot(log, wait_attempts=6, initial_sleep=1, backoff=2):
37 util.subp(REBOOT_CMD)
38 start = time.time()
39 wait_time = initial_sleep
40 for _i in range(0, wait_attempts):
41 time.sleep(wait_time)
42 wait_time *= backoff
43 elapsed = time.time() - start
44 log.debug("Rebooted, but still running after %s seconds", int(elapsed))
45 # If we got here, not good
46 elapsed = time.time() - start
47 raise RuntimeError(("Reboot did not happen"
48 " after %s seconds!") % (int(elapsed)))
49
50
51def handle(_name, cfg, cloud, log, _args):
52 # Handle the old style + new config names
53 update = _multi_cfg_bool_get(cfg, 'apt_update', 'package_update')
54 upgrade = _multi_cfg_bool_get(cfg, 'package_upgrade', 'apt_upgrade')
55 reboot_if_required = _multi_cfg_bool_get(cfg, 'apt_reboot_if_required',
56 'package_reboot_if_required')
57 pkglist = util.get_cfg_option_list(cfg, 'packages', [])
58
59 errors = []
60 if update or len(pkglist) or upgrade:
61 try:
62 cloud.distro.update_package_sources()
63 except Exception as e:
64 util.logexc(log, "Package update failed")
65 errors.append(e)
66
67 if upgrade:
68 try:
69 cloud.distro.package_command("upgrade")
70 except Exception as e:
71 util.logexc(log, "Package upgrade failed")
72 errors.append(e)
73
74 if len(pkglist):
75 try:
76 cloud.distro.install_packages(pkglist)
77 except Exception as e:
78 util.logexc(log, "Failed to install packages: %s", pkglist)
79 errors.append(e)
80
81 # TODO(smoser): handle this less violently
82 # kernel and openssl (possibly some other packages)
83 # write a file /var/run/reboot-required after upgrading.
84 # if that file exists and configured, then just stop right now and reboot
85 reboot_fn_exists = os.path.isfile(REBOOT_FILE)
86 if (upgrade or pkglist) and reboot_if_required and reboot_fn_exists:
87 try:
88 log.warn("Rebooting after upgrade or install per %s", REBOOT_FILE)
89 # Flush the above warning + anything else out...
90 logging.flushLoggers(log)
91 _fire_reboot(log)
92 except Exception as e:
93 util.logexc(log, "Requested reboot did not happen!")
94 errors.append(e)
95
96 if len(errors):
97 log.warn("%s failed with exceptions, re-raising the last one",
98 len(errors))
99 raise errors[-1]
0100
=== modified file 'cloudinit/log.py'
--- cloudinit/log.py 2012-08-22 18:12:32 +0000
+++ cloudinit/log.py 2012-10-17 04:17:17 +0000
@@ -53,6 +53,18 @@
53 root.setLevel(DEBUG)53 root.setLevel(DEBUG)
5454
5555
56def flushLoggers(root):
57 if not root:
58 return
59 for h in root.handlers:
60 if isinstance(h, (logging.StreamHandler)):
61 try:
62 h.flush()
63 except IOError:
64 pass
65 flushLoggers(root.parent)
66
67
56def setupLogging(cfg=None):68def setupLogging(cfg=None):
57 # See if the config provides any logging conf...69 # See if the config provides any logging conf...
58 if not cfg:70 if not cfg: