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