Blame cloudinit/config/cc_runcmd.py

Packit Service a04d08
# Copyright (C) 2009-2010 Canonical Ltd.
Packit Service a04d08
# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
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
#
Packit Service a04d08
# This file is part of cloud-init. See LICENSE file for license information.
Packit Service a04d08
Packit Service a04d08
"""Runcmd: run arbitrary commands at rc.local with output to the console"""
Packit Service a04d08
Packit Service a04d08
from cloudinit.config.schema import (
Packit Service a04d08
    get_schema_doc, validate_cloudconfig_schema)
Packit Service a04d08
from cloudinit.distros import ALL_DISTROS
Packit Service a04d08
from cloudinit.settings import PER_INSTANCE
Packit Service a04d08
from cloudinit import util
Packit Service a04d08
Packit Service a04d08
import os
Packit Service a04d08
from textwrap import dedent
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
# The schema definition for each cloud-config module is a strict contract for
Packit Service a04d08
# describing supported configuration parameters for each cloud-config section.
Packit Service a04d08
# It allows cloud-config to validate and alert users to invalid or ignored
Packit Service a04d08
# configuration options before actually attempting to deploy with said
Packit Service a04d08
# configuration.
Packit Service a04d08
Packit Service a04d08
distros = [ALL_DISTROS]
Packit Service a04d08
Packit Service a04d08
schema = {
Packit Service a04d08
    'id': 'cc_runcmd',
Packit Service a04d08
    'name': 'Runcmd',
Packit Service a04d08
    'title': 'Run arbitrary commands',
Packit Service a04d08
    'description': dedent("""\
Packit Service a04d08
        Run arbitrary commands at a rc.local like level with output to the
Packit Service a04d08
        console. Each item can be either a list or a string. If the item is a
Packit Service a04d08
        list, it will be properly executed as if passed to ``execve()`` (with
Packit Service a04d08
        the first arg as the command). If the item is a string, it will be
Packit Service a04d08
        written to a file and interpreted
Packit Service a04d08
        using ``sh``.
Packit Service a04d08
Packit Service a04d08
        .. note::
Packit Service a04d08
Packit Service a04d08
          all commands must be proper yaml, so you have to quote any characters
Packit Service a04d08
          yaml would eat (':' can be problematic)
Packit Service a04d08
Packit Service a04d08
        .. note::
Packit Service a04d08
Packit Service a04d08
          when writing files, do not use /tmp dir as it races with
Packit Service a04d08
          systemd-tmpfiles-clean LP: #1707222. Use /run/somedir instead.
Packit Service a04d08
    """),
Packit Service a04d08
    'distros': distros,
Packit Service a04d08
    'examples': [dedent("""\
Packit Service a04d08
        runcmd:
Packit Service a04d08
            - [ ls, -l, / ]
Packit Service a04d08
            - [ sh, -xc, "echo $(date) ': hello world!'" ]
Packit Service a04d08
            - [ sh, -c, echo "=========hello world'=========" ]
Packit Service a04d08
            - ls -l /root
Packit Service a04d08
            - [ wget, "http://example.org", -O, /tmp/index.html ]
Packit Service a04d08
    """)],
Packit Service a04d08
    'frequency': PER_INSTANCE,
Packit Service a04d08
    'type': 'object',
Packit Service a04d08
    'properties': {
Packit Service a04d08
        'runcmd': {
Packit Service a04d08
            'type': 'array',
Packit Service a04d08
            'items': {
Packit Service a04d08
                'oneOf': [
Packit Service a04d08
                    {'type': 'array', 'items': {'type': 'string'}},
Packit Service a04d08
                    {'type': 'string'}]
Packit Service a04d08
            },
Packit Service a04d08
            'additionalItems': False,  # Reject items of non-string non-list
Packit Service a04d08
            'additionalProperties': False,
Packit Service a04d08
            'minItems': 1,
Packit Service a04d08
            'required': [],
Packit Service a04d08
        }
Packit Service a04d08
    }
Packit Service a04d08
}
Packit Service a04d08
Packit Service a04d08
__doc__ = get_schema_doc(schema)  # Supplement python help()
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def handle(name, cfg, cloud, log, _args):
Packit Service a04d08
    if "runcmd" not in cfg:
Packit Service a04d08
        log.debug(("Skipping module named %s,"
Packit Service a04d08
                   " no 'runcmd' key in configuration"), name)
Packit Service a04d08
        return
Packit Service a04d08
Packit Service a04d08
    validate_cloudconfig_schema(cfg, schema)
Packit Service a04d08
    out_fn = os.path.join(cloud.get_ipath('scripts'), "runcmd")
Packit Service a04d08
    cmd = cfg["runcmd"]
Packit Service a04d08
    try:
Packit Service a04d08
        content = util.shellify(cmd)
Packit Service a04d08
        util.write_file(out_fn, content, 0o700)
Packit Service a04d08
    except Exception:
Packit Service a04d08
        util.logexc(log, "Failed to shellify %s into file %s", cmd, out_fn)
Packit Service a04d08
Packit Service a04d08
# vi: ts=4 expandtab