~cloud-init-dev/cloud-init/trunk

« back to all changes in this revision

Viewing changes to cloudinit/config/cc_package_update_upgrade_install.py

  • Committer: Scott Moser
  • Date: 2016-08-10 15:06:15 UTC
  • Revision ID: smoser@ubuntu.com-20160810150615-ma2fv107w3suy1ma
README: Mention move of revision control to git.

cloud-init development has moved its revision control to git.
It is available at 
  https://code.launchpad.net/cloud-init

Clone with 
  git clone https://git.launchpad.net/cloud-init
or
  git clone git+ssh://git.launchpad.net/cloud-init

For more information see
  https://git.launchpad.net/cloud-init/tree/HACKING.rst

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
19
 
import os
20
 
import time
21
 
 
22
 
from cloudinit import log as logging
23
 
from cloudinit import util
24
 
 
25
 
REBOOT_FILE = "/var/run/reboot-required"
26
 
REBOOT_CMD = ["/sbin/reboot"]
27
 
 
28
 
 
29
 
def _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
 
 
36
 
def _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
 
 
51
 
def 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]