Blame cloudinit/cmd/main.py

Packit Service a04d08
#!/usr/bin/python
Packit Service a04d08
#
Packit Service a04d08
# Copyright (C) 2012 Canonical Ltd.
Packit Service a04d08
# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
Packit Service a04d08
# Copyright (C) 2012 Yahoo! Inc.
Packit Service a04d08
# Copyright (C) 2017 Amazon.com, Inc. or its affiliates
Packit Service a04d08
#
Packit Service a04d08
# Author: Scott Moser <scott.moser@canonical.com>
Packit Service a04d08
# Author: Juerg Haefliger <juerg.haefliger@hp.com>
Packit Service a04d08
# Author: Joshua Harlow <harlowja@yahoo-inc.com>
Packit Service a04d08
# Author: Andrew Jorgensen <ajorgens@amazon.com>
Packit Service a04d08
#
Packit Service a04d08
# This file is part of cloud-init. See LICENSE file for license information.
Packit Service a04d08
Packit Service a04d08
import argparse
Packit Service a04d08
import json
Packit Service a04d08
import os
Packit Service a04d08
import sys
Packit Service a04d08
import time
Packit Service a04d08
import traceback
Packit Service a04d08
Packit Service a04d08
from cloudinit import patcher
Packit Service a04d08
patcher.patch()  # noqa
Packit Service a04d08
Packit Service a04d08
from cloudinit import log as logging
Packit Service a04d08
from cloudinit import netinfo
Packit Service a04d08
from cloudinit import signal_handler
Packit Service a04d08
from cloudinit import sources
Packit Service a04d08
from cloudinit import stages
Packit Service a04d08
from cloudinit import url_helper
Packit Service a04d08
from cloudinit import util
Packit Service a04d08
from cloudinit import version
Packit Service a04d08
from cloudinit import warnings
Packit Service a04d08
Packit Service a04d08
from cloudinit import reporting
Packit Service a04d08
from cloudinit.reporting import events
Packit Service a04d08
Packit Service a04d08
from cloudinit.settings import (PER_INSTANCE, PER_ALWAYS, PER_ONCE,
Packit Service a04d08
                                CLOUD_CONFIG)
Packit Service a04d08
Packit Service a04d08
from cloudinit import atomic_helper
Packit Service a04d08
Packit Service a04d08
from cloudinit.config import cc_set_hostname
Packit Service a04d08
from cloudinit import dhclient_hook
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
# Welcome message template
Packit Service a04d08
WELCOME_MSG_TPL = ("Cloud-init v. {version} running '{action}' at "
Packit Service a04d08
                   "{timestamp}. Up {uptime} seconds.")
Packit Service a04d08
Packit Service a04d08
# Module section template
Packit Service a04d08
MOD_SECTION_TPL = "cloud_%s_modules"
Packit Service a04d08
Packit Service a04d08
# Frequency shortname to full name
Packit Service a04d08
# (so users don't have to remember the full name...)
Packit Service a04d08
FREQ_SHORT_NAMES = {
Packit Service a04d08
    'instance': PER_INSTANCE,
Packit Service a04d08
    'always': PER_ALWAYS,
Packit Service a04d08
    'once': PER_ONCE,
Packit Service a04d08
}
Packit Service a04d08
Packit Service a04d08
LOG = logging.getLogger()
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
# Used for when a logger may not be active
Packit Service a04d08
# and we still want to print exceptions...
Packit Service a04d08
def print_exc(msg=''):
Packit Service a04d08
    if msg:
Packit Service a04d08
        sys.stderr.write("%s\n" % (msg))
Packit Service a04d08
    sys.stderr.write('-' * 60)
Packit Service a04d08
    sys.stderr.write("\n")
Packit Service a04d08
    traceback.print_exc(file=sys.stderr)
Packit Service a04d08
    sys.stderr.write('-' * 60)
Packit Service a04d08
    sys.stderr.write("\n")
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def welcome(action, msg=None):
Packit Service a04d08
    if not msg:
Packit Service a04d08
        msg = welcome_format(action)
Packit Service a04d08
    util.multi_log("%s\n" % (msg),
Packit Service a04d08
                   console=False, stderr=True, log=LOG)
Packit Service a04d08
    return msg
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def welcome_format(action):
Packit Service a04d08
    return WELCOME_MSG_TPL.format(
Packit Service a04d08
        version=version.version_string(),
Packit Service a04d08
        uptime=util.uptime(),
Packit Service a04d08
        timestamp=util.time_rfc2822(),
Packit Service a04d08
        action=action)
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def extract_fns(args):
Packit Service a04d08
    # Files are already opened so lets just pass that along
Packit Service a04d08
    # since it would of broke if it couldn't have
Packit Service a04d08
    # read that file already...
Packit Service a04d08
    fn_cfgs = []
Packit Service a04d08
    if args.files:
Packit Service a04d08
        for fh in args.files:
Packit Service a04d08
            # The realpath is more useful in logging
Packit Service a04d08
            # so lets resolve to that...
Packit Service a04d08
            fn_cfgs.append(os.path.realpath(fh.name))
Packit Service a04d08
    return fn_cfgs
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def run_module_section(mods, action_name, section):
Packit Service a04d08
    full_section_name = MOD_SECTION_TPL % (section)
Packit Service a04d08
    (which_ran, failures) = mods.run_section(full_section_name)
Packit Service a04d08
    total_attempted = len(which_ran) + len(failures)
Packit Service a04d08
    if total_attempted == 0:
Packit Service a04d08
        msg = ("No '%s' modules to run"
Packit Service a04d08
               " under section '%s'") % (action_name, full_section_name)
Packit Service a04d08
        sys.stderr.write("%s\n" % (msg))
Packit Service a04d08
        LOG.debug(msg)
Packit Service a04d08
        return []
Packit Service a04d08
    else:
Packit Service a04d08
        LOG.debug("Ran %s modules with %s failures",
Packit Service a04d08
                  len(which_ran), len(failures))
Packit Service a04d08
        return failures
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def apply_reporting_cfg(cfg):
Packit Service a04d08
    if cfg.get('reporting'):
Packit Service a04d08
        reporting.update_configuration(cfg.get('reporting'))
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def parse_cmdline_url(cmdline, names=('cloud-config-url', 'url')):
Packit Service a04d08
    data = util.keyval_str_to_dict(cmdline)
Packit Service a04d08
    for key in names:
Packit Service a04d08
        if key in data:
Packit Service a04d08
            return key, data[key]
Packit Service a04d08
    raise KeyError("No keys (%s) found in string '%s'" %
Packit Service a04d08
                   (cmdline, names))
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def attempt_cmdline_url(path, network=True, cmdline=None):
Packit Service a04d08
    """Write data from url referenced in command line to path.
Packit Service a04d08
Packit Service a04d08
    path: a file to write content to if downloaded.
Packit Service a04d08
    network: should network access be assumed.
Packit Service a04d08
    cmdline: the cmdline to parse for cloud-config-url.
Packit Service a04d08
Packit Service a04d08
    This is used in MAAS datasource, in "ephemeral" (read-only root)
Packit Service a04d08
    environment where the instance netboots to iscsi ro root.
Packit Service a04d08
    and the entity that controls the pxe config has to configure
Packit Service a04d08
    the maas datasource.
Packit Service a04d08
Packit Service a04d08
    An attempt is made on network urls even in local datasource
Packit Service a04d08
    for case of network set up in initramfs.
Packit Service a04d08
Packit Service a04d08
    Return value is a tuple of a logger function (logging.DEBUG)
Packit Service a04d08
    and a message indicating what happened.
Packit Service a04d08
    """
Packit Service a04d08
Packit Service a04d08
    if cmdline is None:
Packit Service a04d08
        cmdline = util.get_cmdline()
Packit Service a04d08
Packit Service a04d08
    try:
Packit Service a04d08
        cmdline_name, url = parse_cmdline_url(cmdline)
Packit Service a04d08
    except KeyError:
Packit Service a04d08
        return (logging.DEBUG, "No kernel command line url found.")
Packit Service a04d08
Packit Service a04d08
    path_is_local = url.startswith("file://") or url.startswith("/")
Packit Service a04d08
Packit Service a04d08
    if path_is_local and os.path.exists(path):
Packit Service a04d08
        if network:
Packit Service a04d08
            m = ("file '%s' existed, possibly from local stage download"
Packit Service a04d08
                 " of command line url '%s'. Not re-writing." % (path, url))
Packit Service a04d08
            level = logging.INFO
Packit Service a04d08
            if path_is_local:
Packit Service a04d08
                level = logging.DEBUG
Packit Service a04d08
        else:
Packit Service a04d08
            m = ("file '%s' existed, possibly from previous boot download"
Packit Service a04d08
                 " of command line url '%s'. Not re-writing." % (path, url))
Packit Service a04d08
            level = logging.WARN
Packit Service a04d08
Packit Service a04d08
        return (level, m)
Packit Service a04d08
Packit Service a04d08
    kwargs = {'url': url, 'timeout': 10, 'retries': 2}
Packit Service a04d08
    if network or path_is_local:
Packit Service a04d08
        level = logging.WARN
Packit Service a04d08
        kwargs['sec_between'] = 1
Packit Service a04d08
    else:
Packit Service a04d08
        level = logging.DEBUG
Packit Service a04d08
        kwargs['sec_between'] = .1
Packit Service a04d08
Packit Service a04d08
    data = None
Packit Service a04d08
    header = b'#cloud-config'
Packit Service a04d08
    try:
Packit Service a04d08
        resp = url_helper.read_file_or_url(**kwargs)
Packit Service a04d08
        if resp.ok():
Packit Service a04d08
            data = resp.contents
Packit Service a04d08
            if not resp.contents.startswith(header):
Packit Service a04d08
                if cmdline_name == 'cloud-config-url':
Packit Service a04d08
                    level = logging.WARN
Packit Service a04d08
                else:
Packit Service a04d08
                    level = logging.INFO
Packit Service a04d08
                return (
Packit Service a04d08
                    level,
Packit Service a04d08
                    "contents of '%s' did not start with %s" % (url, header))
Packit Service a04d08
        else:
Packit Service a04d08
            return (level,
Packit Service a04d08
                    "url '%s' returned code %s. Ignoring." % (url, resp.code))
Packit Service a04d08
Packit Service a04d08
    except url_helper.UrlError as e:
Packit Service a04d08
        return (level, "retrieving url '%s' failed: %s" % (url, e))
Packit Service a04d08
Packit Service a04d08
    util.write_file(path, data, mode=0o600)
Packit Service a04d08
    return (logging.INFO,
Packit Service a04d08
            "wrote cloud-config data from %s='%s' to %s" %
Packit Service a04d08
            (cmdline_name, url, path))
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def main_init(name, args):
Packit Service a04d08
    deps = [sources.DEP_FILESYSTEM, sources.DEP_NETWORK]
Packit Service a04d08
    if args.local:
Packit Service a04d08
        deps = [sources.DEP_FILESYSTEM]
Packit Service a04d08
Packit Service a04d08
    early_logs = [attempt_cmdline_url(
Packit Service a04d08
        path=os.path.join("%s.d" % CLOUD_CONFIG,
Packit Service a04d08
                          "91_kernel_cmdline_url.cfg"),
Packit Service a04d08
        network=not args.local)]
Packit Service a04d08
Packit Service a04d08
    # Cloud-init 'init' stage is broken up into the following sub-stages
Packit Service a04d08
    # 1. Ensure that the init object fetches its config without errors
Packit Service a04d08
    # 2. Setup logging/output redirections with resultant config (if any)
Packit Service a04d08
    # 3. Initialize the cloud-init filesystem
Packit Service a04d08
    # 4. Check if we can stop early by looking for various files
Packit Service a04d08
    # 5. Fetch the datasource
Packit Service a04d08
    # 6. Connect to the current instance location + update the cache
Packit Service a04d08
    # 7. Consume the userdata (handlers get activated here)
Packit Service a04d08
    # 8. Construct the modules object
Packit Service a04d08
    # 9. Adjust any subsequent logging/output redirections using the modules
Packit Service a04d08
    #    objects config as it may be different from init object
Packit Service a04d08
    # 10. Run the modules for the 'init' stage
Packit Service a04d08
    # 11. Done!
Packit Service a04d08
    if not args.local:
Packit Service a04d08
        w_msg = welcome_format(name)
Packit Service a04d08
    else:
Packit Service a04d08
        w_msg = welcome_format("%s-local" % (name))
Packit Service a04d08
    init = stages.Init(ds_deps=deps, reporter=args.reporter)
Packit Service a04d08
    # Stage 1
Packit Service a04d08
    init.read_cfg(extract_fns(args))
Packit Service a04d08
    # Stage 2
Packit Service a04d08
    outfmt = None
Packit Service a04d08
    errfmt = None
Packit Service a04d08
    try:
Packit Service a04d08
        early_logs.append((logging.DEBUG, "Closing stdin."))
Packit Service a04d08
        util.close_stdin()
Packit Service a04d08
        (outfmt, errfmt) = util.fixup_output(init.cfg, name)
Packit Service a04d08
    except Exception:
Packit Service a04d08
        msg = "Failed to setup output redirection!"
Packit Service a04d08
        util.logexc(LOG, msg)
Packit Service a04d08
        print_exc(msg)
Packit Service a04d08
        early_logs.append((logging.WARN, msg))
Packit Service a04d08
    if args.debug:
Packit Service a04d08
        # Reset so that all the debug handlers are closed out
Packit Service a04d08
        LOG.debug(("Logging being reset, this logger may no"
Packit Service a04d08
                   " longer be active shortly"))
Packit Service a04d08
        logging.resetLogging()
Packit Service a04d08
    logging.setupLogging(init.cfg)
Packit Service a04d08
    apply_reporting_cfg(init.cfg)
Packit Service a04d08
Packit Service a04d08
    # Any log usage prior to setupLogging above did not have local user log
Packit Service a04d08
    # config applied.  We send the welcome message now, as stderr/out have
Packit Service a04d08
    # been redirected and log now configured.
Packit Service a04d08
    welcome(name, msg=w_msg)
Packit Service a04d08
Packit Service a04d08
    # re-play early log messages before logging was setup
Packit Service a04d08
    for lvl, msg in early_logs:
Packit Service a04d08
        LOG.log(lvl, msg)
Packit Service a04d08
Packit Service a04d08
    # Stage 3
Packit Service a04d08
    try:
Packit Service a04d08
        init.initialize()
Packit Service a04d08
    except Exception:
Packit Service a04d08
        util.logexc(LOG, "Failed to initialize, likely bad things to come!")
Packit Service a04d08
    # Stage 4
Packit Service a04d08
    path_helper = init.paths
Packit Service a04d08
    mode = sources.DSMODE_LOCAL if args.local else sources.DSMODE_NETWORK
Packit Service a04d08
Packit Service a04d08
    if mode == sources.DSMODE_NETWORK:
Packit Service a04d08
        existing = "trust"
Packit Service a04d08
        sys.stderr.write("%s\n" % (netinfo.debug_info()))
Packit Service a04d08
        LOG.debug(("Checking to see if files that we need already"
Packit Service a04d08
                   " exist from a previous run that would allow us"
Packit Service a04d08
                   " to stop early."))
Packit Service a04d08
        # no-net is written by upstart cloud-init-nonet when network failed
Packit Service a04d08
        # to come up
Packit Service a04d08
        stop_files = [
Packit Service a04d08
            os.path.join(path_helper.get_cpath("data"), "no-net"),
Packit Service a04d08
        ]
Packit Service a04d08
        existing_files = []
Packit Service a04d08
        for fn in stop_files:
Packit Service a04d08
            if os.path.isfile(fn):
Packit Service a04d08
                existing_files.append(fn)
Packit Service a04d08
Packit Service a04d08
        if existing_files:
Packit Service a04d08
            LOG.debug("[%s] Exiting. stop file %s existed",
Packit Service a04d08
                      mode, existing_files)
Packit Service a04d08
            return (None, [])
Packit Service a04d08
        else:
Packit Service a04d08
            LOG.debug("Execution continuing, no previous run detected that"
Packit Service a04d08
                      " would allow us to stop early.")
Packit Service a04d08
    else:
Packit Service a04d08
        existing = "check"
Packit Service a04d08
        mcfg = util.get_cfg_option_bool(init.cfg, 'manual_cache_clean', False)
Packit Service a04d08
        if mcfg:
Packit Service a04d08
            LOG.debug("manual cache clean set from config")
Packit Service a04d08
            existing = "trust"
Packit Service a04d08
        else:
Packit Service a04d08
            mfile = path_helper.get_ipath_cur("manual_clean_marker")
Packit Service a04d08
            if os.path.exists(mfile):
Packit Service a04d08
                LOG.debug("manual cache clean found from marker: %s", mfile)
Packit Service a04d08
                existing = "trust"
Packit Service a04d08
Packit Service a04d08
        init.purge_cache()
Packit Service a04d08
        # Delete the no-net file as well
Packit Service a04d08
        util.del_file(os.path.join(path_helper.get_cpath("data"), "no-net"))
Packit Service a04d08
Packit Service a04d08
    # Stage 5
Packit Service a04d08
    try:
Packit Service a04d08
        init.fetch(existing=existing)
Packit Service a04d08
        # if in network mode, and the datasource is local
Packit Service a04d08
        # then work was done at that stage.
Packit Service a04d08
        if mode == sources.DSMODE_NETWORK and init.datasource.dsmode != mode:
Packit Service a04d08
            LOG.debug("[%s] Exiting. datasource %s in local mode",
Packit Service a04d08
                      mode, init.datasource)
Packit Service a04d08
            return (None, [])
Packit Service a04d08
    except sources.DataSourceNotFoundException:
Packit Service a04d08
        # In the case of 'cloud-init init' without '--local' it is a bit
Packit Service a04d08
        # more likely that the user would consider it failure if nothing was
Packit Service a04d08
        # found. When using upstart it will also mentions job failure
Packit Service a04d08
        # in console log if exit code is != 0.
Packit Service a04d08
        if mode == sources.DSMODE_LOCAL:
Packit Service a04d08
            LOG.debug("No local datasource found")
Packit Service a04d08
        else:
Packit Service a04d08
            util.logexc(LOG, ("No instance datasource found!"
Packit Service a04d08
                              " Likely bad things to come!"))
Packit Service a04d08
        if not args.force:
Packit Service a04d08
            init.apply_network_config(bring_up=not args.local)
Packit Service a04d08
            LOG.debug("[%s] Exiting without datasource", mode)
Packit Service a04d08
            if mode == sources.DSMODE_LOCAL:
Packit Service a04d08
                return (None, [])
Packit Service a04d08
            else:
Packit Service a04d08
                return (None, ["No instance datasource found."])
Packit Service a04d08
        else:
Packit Service a04d08
            LOG.debug("[%s] barreling on in force mode without datasource",
Packit Service a04d08
                      mode)
Packit Service a04d08
Packit Service a04d08
    _maybe_persist_instance_data(init)
Packit Service a04d08
    # Stage 6
Packit Service a04d08
    iid = init.instancify()
Packit Service a04d08
    LOG.debug("[%s] %s will now be targeting instance id: %s. new=%s",
Packit Service a04d08
              mode, name, iid, init.is_new_instance())
Packit Service a04d08
Packit Service a04d08
    if mode == sources.DSMODE_LOCAL:
Packit Service a04d08
        # Before network comes up, set any configured hostname to allow
Packit Service a04d08
        # dhcp clients to advertize this hostname to any DDNS services
Packit Service a04d08
        # LP: #1746455.
Packit Service a04d08
        _maybe_set_hostname(init, stage='local', retry_stage='network')
Packit Service a04d08
    init.apply_network_config(bring_up=bool(mode != sources.DSMODE_LOCAL))
Packit Service a04d08
Packit Service a04d08
    if mode == sources.DSMODE_LOCAL:
Packit Service a04d08
        if init.datasource.dsmode != mode:
Packit Service a04d08
            LOG.debug("[%s] Exiting. datasource %s not in local mode.",
Packit Service a04d08
                      mode, init.datasource)
Packit Service a04d08
            return (init.datasource, [])
Packit Service a04d08
        else:
Packit Service a04d08
            LOG.debug("[%s] %s is in local mode, will apply init modules now.",
Packit Service a04d08
                      mode, init.datasource)
Packit Service a04d08
Packit Service a04d08
    # Give the datasource a chance to use network resources.
Packit Service a04d08
    # This is used on Azure to communicate with the fabric over network.
Packit Service a04d08
    init.setup_datasource()
Packit Service a04d08
    # update fully realizes user-data (pulling in #include if necessary)
Packit Service a04d08
    init.update()
Packit Service a04d08
    _maybe_set_hostname(init, stage='init-net', retry_stage='modules:config')
Packit Service a04d08
    # Stage 7
Packit Service a04d08
    try:
Packit Service a04d08
        # Attempt to consume the data per instance.
Packit Service a04d08
        # This may run user-data handlers and/or perform
Packit Service a04d08
        # url downloads and such as needed.
Packit Service a04d08
        (ran, _results) = init.cloudify().run('consume_data',
Packit Service a04d08
                                              init.consume_data,
Packit Service a04d08
                                              args=[PER_INSTANCE],
Packit Service a04d08
                                              freq=PER_INSTANCE)
Packit Service a04d08
        if not ran:
Packit Service a04d08
            # Just consume anything that is set to run per-always
Packit Service a04d08
            # if nothing ran in the per-instance code
Packit Service a04d08
            #
Packit Service a04d08
            # See: https://bugs.launchpad.net/bugs/819507 for a little
Packit Service a04d08
            # reason behind this...
Packit Service a04d08
            init.consume_data(PER_ALWAYS)
Packit Service a04d08
    except Exception:
Packit Service a04d08
        util.logexc(LOG, "Consuming user data failed!")
Packit Service a04d08
        return (init.datasource, ["Consuming user data failed!"])
Packit Service a04d08
Packit Service a04d08
    apply_reporting_cfg(init.cfg)
Packit Service a04d08
Packit Service a04d08
    # Stage 8 - re-read and apply relevant cloud-config to include user-data
Packit Service a04d08
    mods = stages.Modules(init, extract_fns(args), reporter=args.reporter)
Packit Service a04d08
    # Stage 9
Packit Service a04d08
    try:
Packit Service a04d08
        outfmt_orig = outfmt
Packit Service a04d08
        errfmt_orig = errfmt
Packit Service a04d08
        (outfmt, errfmt) = util.get_output_cfg(mods.cfg, name)
Packit Service a04d08
        if outfmt_orig != outfmt or errfmt_orig != errfmt:
Packit Service a04d08
            LOG.warning("Stdout, stderr changing to (%s, %s)",
Packit Service a04d08
                        outfmt, errfmt)
Packit Service a04d08
            (outfmt, errfmt) = util.fixup_output(mods.cfg, name)
Packit Service a04d08
    except Exception:
Packit Service a04d08
        util.logexc(LOG, "Failed to re-adjust output redirection!")
Packit Service a04d08
    logging.setupLogging(mods.cfg)
Packit Service a04d08
Packit Service a04d08
    # give the activated datasource a chance to adjust
Packit Service a04d08
    init.activate_datasource()
Packit Service a04d08
Packit Service a04d08
    di_report_warn(datasource=init.datasource, cfg=init.cfg)
Packit Service a04d08
Packit Service a04d08
    # Stage 10
Packit Service a04d08
    return (init.datasource, run_module_section(mods, name, name))
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def di_report_warn(datasource, cfg):
Packit Service a04d08
    if 'di_report' not in cfg:
Packit Service a04d08
        LOG.debug("no di_report found in config.")
Packit Service a04d08
        return
Packit Service a04d08
Packit Service a04d08
    dicfg = cfg['di_report']
Packit Service a04d08
    if dicfg is None:
Packit Service a04d08
        # ds-identify may write 'di_report:\n #comment\n'
Packit Service a04d08
        # which reads as {'di_report': None}
Packit Service a04d08
        LOG.debug("di_report was None.")
Packit Service a04d08
        return
Packit Service a04d08
Packit Service a04d08
    if not isinstance(dicfg, dict):
Packit Service a04d08
        LOG.warning("di_report config not a dictionary: %s", dicfg)
Packit Service a04d08
        return
Packit Service a04d08
Packit Service a04d08
    dslist = dicfg.get('datasource_list')
Packit Service a04d08
    if dslist is None:
Packit Service a04d08
        LOG.warning("no 'datasource_list' found in di_report.")
Packit Service a04d08
        return
Packit Service a04d08
    elif not isinstance(dslist, list):
Packit Service a04d08
        LOG.warning("di_report/datasource_list not a list: %s", dslist)
Packit Service a04d08
        return
Packit Service a04d08
Packit Service a04d08
    # ds.__module__ is like cloudinit.sources.DataSourceName
Packit Service a04d08
    # where Name is the thing that shows up in datasource_list.
Packit Service a04d08
    modname = datasource.__module__.rpartition(".")[2]
Packit Service a04d08
    if modname.startswith(sources.DS_PREFIX):
Packit Service a04d08
        modname = modname[len(sources.DS_PREFIX):]
Packit Service a04d08
    else:
Packit Service a04d08
        LOG.warning("Datasource '%s' came from unexpected module '%s'.",
Packit Service a04d08
                    datasource, modname)
Packit Service a04d08
Packit Service a04d08
    if modname in dslist:
Packit Service a04d08
        LOG.debug("used datasource '%s' from '%s' was in di_report's list: %s",
Packit Service a04d08
                  datasource, modname, dslist)
Packit Service a04d08
        return
Packit Service a04d08
Packit Service a04d08
    warnings.show_warning('dsid_missing_source', cfg,
Packit Service a04d08
                          source=modname, dslist=str(dslist))
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def main_modules(action_name, args):
Packit Service a04d08
    name = args.mode
Packit Service a04d08
    # Cloud-init 'modules' stages are broken up into the following sub-stages
Packit Service a04d08
    # 1. Ensure that the init object fetches its config without errors
Packit Service a04d08
    # 2. Get the datasource from the init object, if it does
Packit Service a04d08
    #    not exist then that means the main_init stage never
Packit Service a04d08
    #    worked, and thus this stage can not run.
Packit Service a04d08
    # 3. Construct the modules object
Packit Service a04d08
    # 4. Adjust any subsequent logging/output redirections using
Packit Service a04d08
    #    the modules objects configuration
Packit Service a04d08
    # 5. Run the modules for the given stage name
Packit Service a04d08
    # 6. Done!
Packit Service a04d08
    w_msg = welcome_format("%s:%s" % (action_name, name))
Packit Service a04d08
    init = stages.Init(ds_deps=[], reporter=args.reporter)
Packit Service a04d08
    # Stage 1
Packit Service a04d08
    init.read_cfg(extract_fns(args))
Packit Service a04d08
    # Stage 2
Packit Service a04d08
    try:
Packit Service a04d08
        init.fetch(existing="trust")
Packit Service a04d08
    except sources.DataSourceNotFoundException:
Packit Service a04d08
        # There was no datasource found, theres nothing to do
Packit Service a04d08
        msg = ('Can not apply stage %s, no datasource found! Likely bad '
Packit Service a04d08
               'things to come!' % name)
Packit Service a04d08
        util.logexc(LOG, msg)
Packit Service a04d08
        print_exc(msg)
Packit Service a04d08
        if not args.force:
Packit Service a04d08
            return [(msg)]
Packit Service a04d08
    _maybe_persist_instance_data(init)
Packit Service a04d08
    # Stage 3
Packit Service a04d08
    mods = stages.Modules(init, extract_fns(args), reporter=args.reporter)
Packit Service a04d08
    # Stage 4
Packit Service a04d08
    try:
Packit Service a04d08
        LOG.debug("Closing stdin")
Packit Service a04d08
        util.close_stdin()
Packit Service a04d08
        util.fixup_output(mods.cfg, name)
Packit Service a04d08
    except Exception:
Packit Service a04d08
        util.logexc(LOG, "Failed to setup output redirection!")
Packit Service a04d08
    if args.debug:
Packit Service a04d08
        # Reset so that all the debug handlers are closed out
Packit Service a04d08
        LOG.debug(("Logging being reset, this logger may no"
Packit Service a04d08
                   " longer be active shortly"))
Packit Service a04d08
        logging.resetLogging()
Packit Service a04d08
    logging.setupLogging(mods.cfg)
Packit Service a04d08
    apply_reporting_cfg(init.cfg)
Packit Service a04d08
Packit Service a04d08
    # now that logging is setup and stdout redirected, send welcome
Packit Service a04d08
    welcome(name, msg=w_msg)
Packit Service a04d08
Packit Service a04d08
    # Stage 5
Packit Service a04d08
    return run_module_section(mods, name, name)
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def main_single(name, args):
Packit Service a04d08
    # Cloud-init single stage is broken up into the following sub-stages
Packit Service a04d08
    # 1. Ensure that the init object fetches its config without errors
Packit Service a04d08
    # 2. Attempt to fetch the datasource (warn if it doesn't work)
Packit Service a04d08
    # 3. Construct the modules object
Packit Service a04d08
    # 4. Adjust any subsequent logging/output redirections using
Packit Service a04d08
    #    the modules objects configuration
Packit Service a04d08
    # 5. Run the single module
Packit Service a04d08
    # 6. Done!
Packit Service a04d08
    mod_name = args.name
Packit Service a04d08
    w_msg = welcome_format(name)
Packit Service a04d08
    init = stages.Init(ds_deps=[], reporter=args.reporter)
Packit Service a04d08
    # Stage 1
Packit Service a04d08
    init.read_cfg(extract_fns(args))
Packit Service a04d08
    # Stage 2
Packit Service a04d08
    try:
Packit Service a04d08
        init.fetch(existing="trust")
Packit Service a04d08
    except sources.DataSourceNotFoundException:
Packit Service a04d08
        # There was no datasource found,
Packit Service a04d08
        # that might be bad (or ok) depending on
Packit Service a04d08
        # the module being ran (so continue on)
Packit Service a04d08
        util.logexc(LOG, ("Failed to fetch your datasource,"
Packit Service a04d08
                          " likely bad things to come!"))
Packit Service a04d08
        print_exc(("Failed to fetch your datasource,"
Packit Service a04d08
                   " likely bad things to come!"))
Packit Service a04d08
        if not args.force:
Packit Service a04d08
            return 1
Packit Service a04d08
    _maybe_persist_instance_data(init)
Packit Service a04d08
    # Stage 3
Packit Service a04d08
    mods = stages.Modules(init, extract_fns(args), reporter=args.reporter)
Packit Service a04d08
    mod_args = args.module_args
Packit Service a04d08
    if mod_args:
Packit Service a04d08
        LOG.debug("Using passed in arguments %s", mod_args)
Packit Service a04d08
    mod_freq = args.frequency
Packit Service a04d08
    if mod_freq:
Packit Service a04d08
        LOG.debug("Using passed in frequency %s", mod_freq)
Packit Service a04d08
        mod_freq = FREQ_SHORT_NAMES.get(mod_freq)
Packit Service a04d08
    # Stage 4
Packit Service a04d08
    try:
Packit Service a04d08
        LOG.debug("Closing stdin")
Packit Service a04d08
        util.close_stdin()
Packit Service a04d08
        util.fixup_output(mods.cfg, None)
Packit Service a04d08
    except Exception:
Packit Service a04d08
        util.logexc(LOG, "Failed to setup output redirection!")
Packit Service a04d08
    if args.debug:
Packit Service a04d08
        # Reset so that all the debug handlers are closed out
Packit Service a04d08
        LOG.debug(("Logging being reset, this logger may no"
Packit Service a04d08
                   " longer be active shortly"))
Packit Service a04d08
        logging.resetLogging()
Packit Service a04d08
    logging.setupLogging(mods.cfg)
Packit Service a04d08
    apply_reporting_cfg(init.cfg)
Packit Service a04d08
Packit Service a04d08
    # now that logging is setup and stdout redirected, send welcome
Packit Service a04d08
    welcome(name, msg=w_msg)
Packit Service a04d08
Packit Service a04d08
    # Stage 5
Packit Service a04d08
    (which_ran, failures) = mods.run_single(mod_name,
Packit Service a04d08
                                            mod_args,
Packit Service a04d08
                                            mod_freq)
Packit Service a04d08
    if failures:
Packit Service a04d08
        LOG.warning("Ran %s but it failed!", mod_name)
Packit Service a04d08
        return 1
Packit Service a04d08
    elif not which_ran:
Packit Service a04d08
        LOG.warning("Did not run %s, does it exist?", mod_name)
Packit Service a04d08
        return 1
Packit Service a04d08
    else:
Packit Service a04d08
        # Guess it worked
Packit Service a04d08
        return 0
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def status_wrapper(name, args, data_d=None, link_d=None):
Packit Service a04d08
    if data_d is None:
Packit Service a04d08
        data_d = os.path.normpath("/var/lib/cloud/data")
Packit Service a04d08
    if link_d is None:
Packit Service a04d08
        link_d = os.path.normpath("/run/cloud-init")
Packit Service a04d08
Packit Service a04d08
    status_path = os.path.join(data_d, "status.json")
Packit Service a04d08
    status_link = os.path.join(link_d, "status.json")
Packit Service a04d08
    result_path = os.path.join(data_d, "result.json")
Packit Service a04d08
    result_link = os.path.join(link_d, "result.json")
Packit Service a04d08
Packit Service a04d08
    util.ensure_dirs((data_d, link_d,))
Packit Service a04d08
Packit Service a04d08
    (_name, functor) = args.action
Packit Service a04d08
Packit Service a04d08
    if name == "init":
Packit Service a04d08
        if args.local:
Packit Service a04d08
            mode = "init-local"
Packit Service a04d08
        else:
Packit Service a04d08
            mode = "init"
Packit Service a04d08
    elif name == "modules":
Packit Service a04d08
        mode = "modules-%s" % args.mode
Packit Service a04d08
    else:
Packit Service a04d08
        raise ValueError("unknown name: %s" % name)
Packit Service a04d08
Packit Service a04d08
    modes = ('init', 'init-local', 'modules-init', 'modules-config',
Packit Service a04d08
             'modules-final')
Packit Service a04d08
    if mode not in modes:
Packit Service a04d08
        raise ValueError(
Packit Service a04d08
            "Invalid cloud init mode specified '{0}'".format(mode))
Packit Service a04d08
Packit Service a04d08
    status = None
Packit Service a04d08
    if mode == 'init-local':
Packit Service a04d08
        for f in (status_link, result_link, status_path, result_path):
Packit Service a04d08
            util.del_file(f)
Packit Service a04d08
    else:
Packit Service a04d08
        try:
Packit Service a04d08
            status = json.loads(util.load_file(status_path))
Packit Service a04d08
        except Exception:
Packit Service a04d08
            pass
Packit Service a04d08
Packit Service a04d08
    nullstatus = {
Packit Service a04d08
        'errors': [],
Packit Service a04d08
        'start': None,
Packit Service a04d08
        'finished': None,
Packit Service a04d08
    }
Packit Service a04d08
Packit Service a04d08
    if status is None:
Packit Service a04d08
        status = {'v1': {}}
Packit Service a04d08
        status['v1']['datasource'] = None
Packit Service a04d08
Packit Service a04d08
    for m in modes:
Packit Service a04d08
        if m not in status['v1']:
Packit Service a04d08
            status['v1'][m] = nullstatus.copy()
Packit Service a04d08
Packit Service a04d08
    v1 = status['v1']
Packit Service a04d08
    v1['stage'] = mode
Packit Service a04d08
    v1[mode]['start'] = time.time()
Packit Service a04d08
Packit Service a04d08
    atomic_helper.write_json(status_path, status)
Packit Service a04d08
    util.sym_link(os.path.relpath(status_path, link_d), status_link,
Packit Service a04d08
                  force=True)
Packit Service a04d08
Packit Service a04d08
    try:
Packit Service a04d08
        ret = functor(name, args)
Packit Service a04d08
        if mode in ('init', 'init-local'):
Packit Service a04d08
            (datasource, errors) = ret
Packit Service a04d08
            if datasource is not None:
Packit Service a04d08
                v1['datasource'] = str(datasource)
Packit Service a04d08
        else:
Packit Service a04d08
            errors = ret
Packit Service a04d08
Packit Service a04d08
        v1[mode]['errors'] = [str(e) for e in errors]
Packit Service a04d08
Packit Service a04d08
    except Exception as e:
Packit Service a04d08
        util.logexc(LOG, "failed stage %s", mode)
Packit Service a04d08
        print_exc("failed run of stage %s" % mode)
Packit Service a04d08
        v1[mode]['errors'] = [str(e)]
Packit Service a04d08
Packit Service a04d08
    v1[mode]['finished'] = time.time()
Packit Service a04d08
    v1['stage'] = None
Packit Service a04d08
Packit Service a04d08
    atomic_helper.write_json(status_path, status)
Packit Service a04d08
Packit Service a04d08
    if mode == "modules-final":
Packit Service a04d08
        # write the 'finished' file
Packit Service a04d08
        errors = []
Packit Service a04d08
        for m in modes:
Packit Service a04d08
            if v1[m]['errors']:
Packit Service a04d08
                errors.extend(v1[m].get('errors', []))
Packit Service a04d08
Packit Service a04d08
        atomic_helper.write_json(
Packit Service a04d08
            result_path, {'v1': {'datasource': v1['datasource'],
Packit Service a04d08
                          'errors': errors}})
Packit Service a04d08
        util.sym_link(os.path.relpath(result_path, link_d), result_link,
Packit Service a04d08
                      force=True)
Packit Service a04d08
Packit Service a04d08
    return len(v1[mode]['errors'])
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def _maybe_persist_instance_data(init):
Packit Service a04d08
    """Write instance-data.json file if absent and datasource is restored."""
Packit Service a04d08
    if init.ds_restored:
Packit Service a04d08
        instance_data_file = os.path.join(
Packit Service a04d08
            init.paths.run_dir, sources.INSTANCE_JSON_FILE)
Packit Service a04d08
        if not os.path.exists(instance_data_file):
Packit Service a04d08
            init.datasource.persist_instance_data()
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def _maybe_set_hostname(init, stage, retry_stage):
Packit Service a04d08
    """Call set-hostname if metadata, vendordata or userdata provides it.
Packit Service a04d08
Packit Service a04d08
    @param stage: String representing current stage in which we are running.
Packit Service a04d08
    @param retry_stage: String represented logs upon error setting hostname.
Packit Service a04d08
    """
Packit Service a04d08
    cloud = init.cloudify()
Packit Service a04d08
    (hostname, _fqdn) = util.get_hostname_fqdn(
Packit Service a04d08
        init.cfg, cloud, metadata_only=True)
Packit Service a04d08
    if hostname:  # meta-data or user-data hostname content
Packit Service a04d08
        try:
Packit Service a04d08
            cc_set_hostname.handle('set-hostname', init.cfg, cloud, LOG, None)
Packit Service a04d08
        except cc_set_hostname.SetHostnameError as e:
Packit Service a04d08
            LOG.debug(
Packit Service a04d08
                'Failed setting hostname in %s stage. Will'
Packit Service a04d08
                ' retry in %s stage. Error: %s.', stage, retry_stage, str(e))
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def main_features(name, args):
Packit Service a04d08
    sys.stdout.write('\n'.join(sorted(version.FEATURES)) + '\n')
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def main(sysv_args=None):
Packit Service a04d08
    if not sysv_args:
Packit Service a04d08
        sysv_args = sys.argv
Packit Service a04d08
    parser = argparse.ArgumentParser(prog=sysv_args[0])
Packit Service a04d08
    sysv_args = sysv_args[1:]
Packit Service a04d08
Packit Service a04d08
    # Top level args
Packit Service a04d08
    parser.add_argument('--version', '-v', action='version',
Packit Service a04d08
                        version='%(prog)s ' + (version.version_string()))
Packit Service a04d08
    parser.add_argument('--file', '-f', action='append',
Packit Service a04d08
                        dest='files',
Packit Service a04d08
                        help=('additional yaml configuration'
Packit Service a04d08
                              ' files to use'),
Packit Service a04d08
                        type=argparse.FileType('rb'))
Packit Service a04d08
    parser.add_argument('--debug', '-d', action='store_true',
Packit Service a04d08
                        help=('show additional pre-action'
Packit Service a04d08
                              ' logging (default: %(default)s)'),
Packit Service a04d08
                        default=False)
Packit Service a04d08
    parser.add_argument('--force', action='store_true',
Packit Service a04d08
                        help=('force running even if no datasource is'
Packit Service a04d08
                              ' found (use at your own risk)'),
Packit Service a04d08
                        dest='force',
Packit Service a04d08
                        default=False)
Packit Service a04d08
Packit Service a04d08
    parser.set_defaults(reporter=None)
Packit Service a04d08
    subparsers = parser.add_subparsers(title='Subcommands', dest='subcommand')
Packit Service a04d08
    subparsers.required = True
Packit Service a04d08
Packit Service a04d08
    # Each action and its sub-options (if any)
Packit Service a04d08
    parser_init = subparsers.add_parser('init',
Packit Service a04d08
                                        help=('initializes cloud-init and'
Packit Service a04d08
                                              ' performs initial modules'))
Packit Service a04d08
    parser_init.add_argument("--local", '-l', action='store_true',
Packit Service a04d08
                             help="start in local mode (default: %(default)s)",
Packit Service a04d08
                             default=False)
Packit Service a04d08
    # This is used so that we can know which action is selected +
Packit Service a04d08
    # the functor to use to run this subcommand
Packit Service a04d08
    parser_init.set_defaults(action=('init', main_init))
Packit Service a04d08
Packit Service a04d08
    # These settings are used for the 'config' and 'final' stages
Packit Service a04d08
    parser_mod = subparsers.add_parser('modules',
Packit Service a04d08
                                       help=('activates modules using '
Packit Service a04d08
                                             'a given configuration key'))
Packit Service a04d08
    parser_mod.add_argument("--mode", '-m', action='store',
Packit Service a04d08
                            help=("module configuration name "
Packit Service a04d08
                                  "to use (default: %(default)s)"),
Packit Service a04d08
                            default='config',
Packit Service a04d08
                            choices=('init', 'config', 'final'))
Packit Service a04d08
    parser_mod.set_defaults(action=('modules', main_modules))
Packit Service a04d08
Packit Service a04d08
    # This subcommand allows you to run a single module
Packit Service a04d08
    parser_single = subparsers.add_parser('single',
Packit Service a04d08
                                          help=('run a single module '))
Packit Service a04d08
    parser_single.add_argument("--name", '-n', action="store",
Packit Service a04d08
                               help="module name to run",
Packit Service a04d08
                               required=True)
Packit Service a04d08
    parser_single.add_argument("--frequency", action="store",
Packit Service a04d08
                               help=("frequency of the module"),
Packit Service a04d08
                               required=False,
Packit Service a04d08
                               choices=list(FREQ_SHORT_NAMES.keys()))
Packit Service a04d08
    parser_single.add_argument("--report", action="store_true",
Packit Service a04d08
                               help="enable reporting",
Packit Service a04d08
                               required=False)
Packit Service a04d08
    parser_single.add_argument("module_args", nargs="*",
Packit Service a04d08
                               metavar='argument',
Packit Service a04d08
                               help=('any additional arguments to'
Packit Service a04d08
                                     ' pass to this module'))
Packit Service a04d08
    parser_single.set_defaults(action=('single', main_single))
Packit Service a04d08
Packit Service a04d08
    parser_query = subparsers.add_parser(
Packit Service a04d08
        'query',
Packit Service a04d08
        help='Query standardized instance metadata from the command line.')
Packit Service a04d08
Packit Service a04d08
    parser_dhclient = subparsers.add_parser(
Packit Service a04d08
        dhclient_hook.NAME, help=dhclient_hook.__doc__)
Packit Service a04d08
    dhclient_hook.get_parser(parser_dhclient)
Packit Service a04d08
Packit Service a04d08
    parser_features = subparsers.add_parser('features',
Packit Service a04d08
                                            help=('list defined features'))
Packit Service a04d08
    parser_features.set_defaults(action=('features', main_features))
Packit Service a04d08
Packit Service a04d08
    parser_analyze = subparsers.add_parser(
Packit Service a04d08
        'analyze', help='Devel tool: Analyze cloud-init logs and data')
Packit Service a04d08
Packit Service a04d08
    parser_devel = subparsers.add_parser(
Packit Service a04d08
        'devel', help='Run development tools')
Packit Service a04d08
Packit Service a04d08
    parser_collect_logs = subparsers.add_parser(
Packit Service a04d08
        'collect-logs', help='Collect and tar all cloud-init debug info')
Packit Service a04d08
Packit Service a04d08
    parser_clean = subparsers.add_parser(
Packit Service a04d08
        'clean', help='Remove logs and artifacts so cloud-init can re-run.')
Packit Service a04d08
Packit Service a04d08
    parser_status = subparsers.add_parser(
Packit Service a04d08
        'status', help='Report cloud-init status or wait on completion.')
Packit Service a04d08
Packit Service a04d08
    if sysv_args:
Packit Service a04d08
        # Only load subparsers if subcommand is specified to avoid load cost
Packit Service a04d08
        if sysv_args[0] == 'analyze':
Packit Service a04d08
            from cloudinit.analyze.__main__ import get_parser as analyze_parser
Packit Service a04d08
            # Construct analyze subcommand parser
Packit Service a04d08
            analyze_parser(parser_analyze)
Packit Service a04d08
        elif sysv_args[0] == 'devel':
Packit Service a04d08
            from cloudinit.cmd.devel.parser import get_parser as devel_parser
Packit Service a04d08
            # Construct devel subcommand parser
Packit Service a04d08
            devel_parser(parser_devel)
Packit Service a04d08
        elif sysv_args[0] == 'collect-logs':
Packit Service a04d08
            from cloudinit.cmd.devel.logs import (
Packit Service a04d08
                get_parser as logs_parser, handle_collect_logs_args)
Packit Service a04d08
            logs_parser(parser_collect_logs)
Packit Service a04d08
            parser_collect_logs.set_defaults(
Packit Service a04d08
                action=('collect-logs', handle_collect_logs_args))
Packit Service a04d08
        elif sysv_args[0] == 'clean':
Packit Service a04d08
            from cloudinit.cmd.clean import (
Packit Service a04d08
                get_parser as clean_parser, handle_clean_args)
Packit Service a04d08
            clean_parser(parser_clean)
Packit Service a04d08
            parser_clean.set_defaults(
Packit Service a04d08
                action=('clean', handle_clean_args))
Packit Service a04d08
        elif sysv_args[0] == 'query':
Packit Service a04d08
            from cloudinit.cmd.query import (
Packit Service a04d08
                get_parser as query_parser, handle_args as handle_query_args)
Packit Service a04d08
            query_parser(parser_query)
Packit Service a04d08
            parser_query.set_defaults(
Packit Service a04d08
                action=('render', handle_query_args))
Packit Service a04d08
        elif sysv_args[0] == 'status':
Packit Service a04d08
            from cloudinit.cmd.status import (
Packit Service a04d08
                get_parser as status_parser, handle_status_args)
Packit Service a04d08
            status_parser(parser_status)
Packit Service a04d08
            parser_status.set_defaults(
Packit Service a04d08
                action=('status', handle_status_args))
Packit Service a04d08
Packit Service a04d08
    args = parser.parse_args(args=sysv_args)
Packit Service a04d08
Packit Service a04d08
    # Subparsers.required = True and each subparser sets action=(name, functor)
Packit Service a04d08
    (name, functor) = args.action
Packit Service a04d08
Packit Service a04d08
    # Setup basic logging to start (until reinitialized)
Packit Service a04d08
    # iff in debug mode.
Packit Service a04d08
    if args.debug:
Packit Service a04d08
        logging.setupBasicLogging()
Packit Service a04d08
Packit Service a04d08
    # Setup signal handlers before running
Packit Service a04d08
    signal_handler.attach_handlers()
Packit Service a04d08
Packit Service a04d08
    if name in ("modules", "init"):
Packit Service a04d08
        functor = status_wrapper
Packit Service a04d08
Packit Service a04d08
    rname = None
Packit Service a04d08
    report_on = True
Packit Service a04d08
    if name == "init":
Packit Service a04d08
        if args.local:
Packit Service a04d08
            rname, rdesc = ("init-local", "searching for local datasources")
Packit Service a04d08
        else:
Packit Service a04d08
            rname, rdesc = ("init-network",
Packit Service a04d08
                            "searching for network datasources")
Packit Service a04d08
    elif name == "modules":
Packit Service a04d08
        rname, rdesc = ("modules-%s" % args.mode,
Packit Service a04d08
                        "running modules for %s" % args.mode)
Packit Service a04d08
    elif name == "single":
Packit Service a04d08
        rname, rdesc = ("single/%s" % args.name,
Packit Service a04d08
                        "running single module %s" % args.name)
Packit Service a04d08
        report_on = args.report
Packit Service a04d08
    else:
Packit Service a04d08
        rname = name
Packit Service a04d08
        rdesc = "running 'cloud-init %s'" % name
Packit Service a04d08
        report_on = False
Packit Service a04d08
Packit Service a04d08
    args.reporter = events.ReportEventStack(
Packit Service a04d08
        rname, rdesc, reporting_enabled=report_on)
Packit Service a04d08
Packit Service a04d08
    with args.reporter:
Packit Service a04d08
        retval = util.log_time(
Packit Service a04d08
            logfunc=LOG.debug, msg="cloud-init mode '%s'" % name,
Packit Service a04d08
            get_uptime=True, func=functor, args=(name, args))
Packit Service a04d08
        reporting.flush_events()
Packit Service a04d08
        return retval
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
if __name__ == '__main__':
Packit Service a04d08
    if 'TZ' not in os.environ:
Packit Service a04d08
        os.environ['TZ'] = ":/etc/localtime"
Packit Service a04d08
    return_value = main(sys.argv)
Packit Service a04d08
    if return_value:
Packit Service a04d08
        sys.exit(return_value)
Packit Service a04d08
Packit Service a04d08
# vi: ts=4 expandtab