Beispiel #1
0
def welcome_format(action):
    tpl_params = {
        'version': version.version_string(),
        'uptime': util.uptime(),
        'timestamp': util.time_rfc2822(),
        'action': action,
    }
    return templater.render_string(WELCOME_MSG_TPL, tpl_params)
Beispiel #2
0
 def _get_incarnation_no(self):
     """
     use the time passed as the incarnation number.
     the incarnation number is the number which are used to
     distinguish the old data stored in kvp and the new data.
     """
     uptime_str = util.uptime()
     try:
         return int(time.time() - float(uptime_str))
     except ValueError:
         LOG.warning("uptime '%s' not in correct format.", uptime_str)
         return 0
Beispiel #3
0
 def _truncate_guest_pool_file(cls, kvp_file):
     """
     Truncate the pool file if it has not been truncated since boot.
     This should be done exactly once for the file indicated by
     KVP_POOL_FILE_GUEST constant above. This method takes a filename
     so that we can use an arbitrary file during unit testing.
     Since KVP is a best-effort telemetry channel we only attempt to
     truncate the file once and only if the file has not been modified
     since boot. Additional truncation can lead to loss of existing
     KVPs.
     """
     if cls._already_truncated_pool_file:
         return
     boot_time = time.time() - float(util.uptime())
     try:
         if os.path.getmtime(kvp_file) < boot_time:
             with open(kvp_file, "w"):
                 pass
     except (OSError, IOError) as e:
         LOG.warning("failed to truncate kvp pool file, %s", e)
     finally:
         cls._already_truncated_pool_file = True
Beispiel #4
0
 def _truncate_guest_pool_file(cls, kvp_file):
     """
     Truncate the pool file if it has not been truncated since boot.
     This should be done exactly once for the file indicated by
     KVP_POOL_FILE_GUEST constant above. This method takes a filename
     so that we can use an arbitrary file during unit testing.
     Since KVP is a best-effort telemetry channel we only attempt to
     truncate the file once and only if the file has not been modified
     since boot. Additional truncation can lead to loss of existing
     KVPs.
     """
     if cls._already_truncated_pool_file:
         return
     boot_time = time.time() - float(util.uptime())
     try:
         if os.path.getmtime(kvp_file) < boot_time:
             with open(kvp_file, "w"):
                 pass
     except (OSError, IOError) as e:
         LOG.warning("failed to truncate kvp pool file, %s", e)
     finally:
         cls._already_truncated_pool_file = True
Beispiel #5
0
def handle(_name, cfg, cloud, log, args):

    msg_in = ''
    if len(args) != 0:
        msg_in = str(args[0])
    else:
        msg_in = util.get_cfg_option_str(cfg, "final_message", "")

    msg_in = msg_in.strip()
    if not msg_in:
        msg_in = FINAL_MESSAGE_DEF

    uptime = util.uptime()
    ts = util.time_rfc2822()
    cver = version.version_string()
    try:
        subs = {
            'uptime': uptime,
            'timestamp': ts,
            'version': cver,
            'datasource': str(cloud.datasource),
        }
        subs.update(dict([(k.upper(), v) for k, v in subs.items()]))
        util.multi_log("%s\n" % (templater.render_string(msg_in, subs)),
                       console=False,
                       stderr=True,
                       log=log)
    except Exception:
        util.logexc(log, "Failed to render final message template")

    boot_fin_fn = cloud.paths.boot_finished
    try:
        contents = "%s - %s - v. %s\n" % (uptime, ts, cver)
        util.write_file(boot_fin_fn, contents)
    except Exception:
        util.logexc(log, "Failed to write boot finished file %s", boot_fin_fn)

    if cloud.datasource.is_disconnected:
        log.warn("Used fallback datasource")
Beispiel #6
0
def handle(_name, cfg, cloud, log, args):

    msg_in = ''
    if len(args) != 0:
        msg_in = str(args[0])
    else:
        msg_in = util.get_cfg_option_str(cfg, "final_message", "")

    msg_in = msg_in.strip()
    if not msg_in:
        msg_in = FINAL_MESSAGE_DEF

    uptime = util.uptime()
    ts = util.time_rfc2822()
    cver = version.version_string()
    try:
        subs = {
            'uptime': uptime,
            'timestamp': ts,
            'version': cver,
            'datasource': str(cloud.datasource),
        }
        subs.update(dict([(k.upper(), v) for k, v in subs.items()]))
        util.multi_log("%s\n" % (templater.render_string(msg_in, subs)),
                       console=False, stderr=True, log=log)
    except Exception:
        util.logexc(log, "Failed to render final message template")

    boot_fin_fn = cloud.paths.boot_finished
    try:
        contents = "%s - %s - v. %s\n" % (uptime, ts, cver)
        util.write_file(boot_fin_fn, contents)
    except Exception:
        util.logexc(log, "Failed to write boot finished file %s", boot_fin_fn)

    if cloud.datasource.is_disconnected:
        log.warn("Used fallback datasource")
Beispiel #7
0
def welcome_format(action):
    return WELCOME_MSG_TPL.format(version=version.version_string(),
                                  uptime=util.uptime(),
                                  timestamp=util.time_rfc2822(),
                                  action=action)
Beispiel #8
0
def get_boot_telemetry():
    """Report timestamps related to kernel initialization and systemd
       activation of cloud-init"""
    if not distros.uses_systemd():
        raise RuntimeError("distro not using systemd, skipping boot telemetry")

    LOG.debug("Collecting boot telemetry")
    try:
        kernel_start = float(time.time()) - float(util.uptime())
    except ValueError:
        raise RuntimeError("Failed to determine kernel start timestamp")

    try:
        out, _ = util.subp(
            ['/bin/systemctl', 'show', '-p', 'UserspaceTimestampMonotonic'],
            capture=True)
        tsm = None
        if out and '=' in out:
            tsm = out.split("=")[1]

        if not tsm:
            raise RuntimeError("Failed to parse "
                               "UserspaceTimestampMonotonic from systemd")

        user_start = kernel_start + (float(tsm) / 1000000)
    except util.ProcessExecutionError as e:
        raise RuntimeError("Failed to get UserspaceTimestampMonotonic: %s" % e)
    except ValueError as e:
        raise RuntimeError("Failed to parse "
                           "UserspaceTimestampMonotonic from systemd: %s" % e)

    try:
        out, _ = util.subp([
            '/bin/systemctl', 'show', 'cloud-init-local', '-p',
            'InactiveExitTimestampMonotonic'
        ],
                           capture=True)
        tsm = None
        if out and '=' in out:
            tsm = out.split("=")[1]
        if not tsm:
            raise RuntimeError("Failed to parse "
                               "InactiveExitTimestampMonotonic from systemd")

        cloudinit_activation = kernel_start + (float(tsm) / 1000000)
    except util.ProcessExecutionError as e:
        raise RuntimeError("Failed to get InactiveExitTimestampMonotonic: %s" %
                           e)
    except ValueError as e:
        raise RuntimeError("Failed to parse "
                           "InactiveExitTimestampMonotonic from systemd: %s" %
                           e)

    evt = events.ReportingEvent(
        BOOT_EVENT_TYPE, 'boot-telemetry',
        "kernel_start=%s user_start=%s cloudinit_activation=%s" %
        (datetime.utcfromtimestamp(kernel_start).isoformat() + 'Z',
         datetime.utcfromtimestamp(user_start).isoformat() + 'Z',
         datetime.utcfromtimestamp(cloudinit_activation).isoformat() + 'Z'),
        events.DEFAULT_EVENT_ORIGIN)
    events.report_event(evt)

    # return the event for unit testing purpose
    return evt
Beispiel #9
0
def welcome_format(action):
    return WELCOME_MSG_TPL.format(
        version=version.version_string(),
        uptime=util.uptime(),
        timestamp=util.time_rfc2822(),
        action=action)