Blame cloudinit/sources/DataSourceOpenNebula.py

Packit Service a04d08
# Copyright (C) 2012 Canonical Ltd.
Packit Service a04d08
# Copyright (C) 2012 Yahoo! Inc.
Packit Service a04d08
# Copyright (C) 2012-2013 CERIT Scientific Cloud
Packit Service a04d08
# Copyright (C) 2012-2013 OpenNebula.org
Packit Service a04d08
# Copyright (C) 2014 Consejo Superior de Investigaciones Cientificas
Packit Service a04d08
#
Packit Service a04d08
# Author: Scott Moser <scott.moser@canonical.com>
Packit Service a04d08
# Author: Joshua Harlow <harlowja@yahoo-inc.com>
Packit Service a04d08
# Author: Vlastimil Holer <xholer@mail.muni.cz>
Packit Service a04d08
# Author: Javier Fontan <jfontan@opennebula.org>
Packit Service a04d08
# Author: Enol Fernandez <enolfc@ifca.unican.es>
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 collections
Packit Service a04d08
import functools
Packit Service a04d08
import os
Packit Service a04d08
import pwd
Packit Service a04d08
import re
Packit Service a04d08
import string
Packit Service a04d08
Packit Service a04d08
from cloudinit import log as logging
Packit Service a04d08
from cloudinit import net
Packit Service a04d08
from cloudinit import sources
Packit Service a04d08
from cloudinit import subp
Packit Service a04d08
from cloudinit import util
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
LOG = logging.getLogger(__name__)
Packit Service a04d08
Packit Service a04d08
DEFAULT_IID = "iid-dsopennebula"
Packit Service a04d08
DEFAULT_PARSEUSER = 'nobody'
Packit Service a04d08
CONTEXT_DISK_FILES = ["context.sh"]
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
class DataSourceOpenNebula(sources.DataSource):
Packit Service a04d08
Packit Service a04d08
    dsname = "OpenNebula"
Packit Service a04d08
Packit Service a04d08
    def __init__(self, sys_cfg, distro, paths):
Packit Service a04d08
        sources.DataSource.__init__(self, sys_cfg, distro, paths)
Packit Service a04d08
        self.seed = None
Packit Service a04d08
        self.seed_dir = os.path.join(paths.seed_dir, 'opennebula')
Packit Service a04d08
Packit Service a04d08
    def __str__(self):
Packit Service a04d08
        root = sources.DataSource.__str__(self)
Packit Service a04d08
        return "%s [seed=%s][dsmode=%s]" % (root, self.seed, self.dsmode)
Packit Service a04d08
Packit Service a04d08
    def _get_data(self):
Packit Service a04d08
        defaults = {"instance-id": DEFAULT_IID}
Packit Service a04d08
        results = None
Packit Service a04d08
        seed = None
Packit Service a04d08
Packit Service a04d08
        # decide parseuser for context.sh shell reader
Packit Service a04d08
        parseuser = DEFAULT_PARSEUSER
Packit Service a04d08
        if 'parseuser' in self.ds_cfg:
Packit Service a04d08
            parseuser = self.ds_cfg.get('parseuser')
Packit Service a04d08
Packit Service a04d08
        candidates = [self.seed_dir]
Packit Service a04d08
        candidates.extend(find_candidate_devs())
Packit Service a04d08
        for cdev in candidates:
Packit Service a04d08
            try:
Packit Service a04d08
                if os.path.isdir(self.seed_dir):
Packit Service a04d08
                    results = read_context_disk_dir(
Packit Service a04d08
                        cdev, self.distro, asuser=parseuser
Packit Service a04d08
                    )
Packit Service a04d08
                elif cdev.startswith("/dev"):
Packit Service a04d08
                    # util.mount_cb only handles passing a single argument
Packit Service a04d08
                    # through to the wrapped function, so we have to partially
Packit Service a04d08
                    # apply the function to pass in `distro`.  See LP: #1884979
Packit Service a04d08
                    partially_applied_func = functools.partial(
Packit Service a04d08
                        read_context_disk_dir,
Packit Service a04d08
                        asuser=parseuser,
Packit Service a04d08
                        distro=self.distro,
Packit Service a04d08
                    )
Packit Service a04d08
                    results = util.mount_cb(cdev, partially_applied_func)
Packit Service a04d08
            except NonContextDiskDir:
Packit Service a04d08
                continue
Packit Service a04d08
            except BrokenContextDiskDir as exc:
Packit Service a04d08
                raise exc
Packit Service a04d08
            except util.MountFailedError:
Packit Service a04d08
                LOG.warning("%s was not mountable", cdev)
Packit Service a04d08
Packit Service a04d08
            if results:
Packit Service a04d08
                seed = cdev
Packit Service a04d08
                LOG.debug("found datasource in %s", cdev)
Packit Service a04d08
                break
Packit Service a04d08
Packit Service a04d08
        if not seed:
Packit Service a04d08
            return False
Packit Service a04d08
Packit Service a04d08
        # merge fetched metadata with datasource defaults
Packit Service a04d08
        md = results['metadata']
Packit Service a04d08
        md = util.mergemanydict([md, defaults])
Packit Service a04d08
Packit Service a04d08
        # check for valid user specified dsmode
Packit Service a04d08
        self.dsmode = self._determine_dsmode(
Packit Service a04d08
            [results.get('DSMODE'), self.ds_cfg.get('dsmode')])
Packit Service a04d08
Packit Service a04d08
        if self.dsmode == sources.DSMODE_DISABLED:
Packit Service a04d08
            return False
Packit Service a04d08
Packit Service a04d08
        self.seed = seed
Packit Service a04d08
        self.network = results.get('network-interfaces')
Packit Service a04d08
        self.metadata = md
Packit Service a04d08
        self.userdata_raw = results.get('userdata')
Packit Service a04d08
        return True
Packit Service a04d08
Packit Service a04d08
    def _get_subplatform(self):
Packit Service a04d08
        """Return the subplatform metadata source details."""
Packit Service a04d08
        if self.seed_dir in self.seed:
Packit Service a04d08
            subplatform_type = 'seed-dir'
Packit Service a04d08
        else:
Packit Service a04d08
            subplatform_type = 'config-disk'
Packit Service a04d08
        return '%s (%s)' % (subplatform_type, self.seed)
Packit Service a04d08
Packit Service a04d08
    @property
Packit Service a04d08
    def network_config(self):
Packit Service a04d08
        if self.network is not None:
Packit Service a04d08
            return self.network
Packit Service a04d08
        else:
Packit Service a04d08
            return None
Packit Service a04d08
Packit Service a04d08
    def get_hostname(self, fqdn=False, resolve_ip=False, metadata_only=False):
Packit Service a04d08
        if resolve_ip is None:
Packit Service a04d08
            if self.dsmode == sources.DSMODE_NETWORK:
Packit Service a04d08
                resolve_ip = True
Packit Service a04d08
            else:
Packit Service a04d08
                resolve_ip = False
Packit Service a04d08
        return sources.DataSource.get_hostname(self, fqdn, resolve_ip)
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
class NonContextDiskDir(Exception):
Packit Service a04d08
    pass
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
class BrokenContextDiskDir(Exception):
Packit Service a04d08
    pass
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
class OpenNebulaNetwork(object):
Packit Service a04d08
    def __init__(self, context, distro, system_nics_by_mac=None):
Packit Service a04d08
        self.context = context
Packit Service a04d08
        if system_nics_by_mac is None:
Packit Service a04d08
            system_nics_by_mac = get_physical_nics_by_mac(distro)
Packit Service a04d08
        self.ifaces = collections.OrderedDict(
Packit Service a04d08
            [k for k in sorted(system_nics_by_mac.items(),
Packit Service a04d08
                               key=lambda k: net.natural_sort_key(k[1]))])
Packit Service a04d08
Packit Service a04d08
        # OpenNebula 4.14+ provide macaddr for ETHX in variable ETH_MAC.
Packit Service a04d08
        # context_devname provides {mac.lower():ETHX, mac2.lower():ETHX}
Packit Service a04d08
        self.context_devname = {}
Packit Service a04d08
        for k, v in context.items():
Packit Service a04d08
            m = re.match(r'^(.+)_MAC$', k)
Packit Service a04d08
            if m:
Packit Service a04d08
                self.context_devname[v.lower()] = m.group(1)
Packit Service a04d08
Packit Service a04d08
    def mac2ip(self, mac):
Packit Service a04d08
        return '.'.join([str(int(c, 16)) for c in mac.split(':')[2:]])
Packit Service a04d08
Packit Service a04d08
    def mac2network(self, mac):
Packit Service a04d08
        return self.mac2ip(mac).rpartition(".")[0] + ".0"
Packit Service a04d08
Packit Service a04d08
    def get_nameservers(self, dev):
Packit Service a04d08
        nameservers = {}
Packit Service a04d08
        dns = self.get_field(dev, "dns", "").split()
Packit Service a04d08
        dns.extend(self.context.get('DNS', "").split())
Packit Service a04d08
        if dns:
Packit Service a04d08
            nameservers['addresses'] = dns
Packit Service a04d08
        search_domain = self.get_field(dev, "search_domain", "").split()
Packit Service a04d08
        if search_domain:
Packit Service a04d08
            nameservers['search'] = search_domain
Packit Service a04d08
        return nameservers
Packit Service a04d08
Packit Service a04d08
    def get_mtu(self, dev):
Packit Service a04d08
        return self.get_field(dev, "mtu")
Packit Service a04d08
Packit Service a04d08
    def get_ip(self, dev, mac):
Packit Service a04d08
        return self.get_field(dev, "ip", self.mac2ip(mac))
Packit Service a04d08
Packit Service a04d08
    def get_ip6(self, dev):
Packit Service a04d08
        addresses6 = []
Packit Service a04d08
        ip6 = self.get_field(dev, "ip6")
Packit Service a04d08
        if ip6:
Packit Service a04d08
            addresses6.append(ip6)
Packit Service a04d08
        ip6_ula = self.get_field(dev, "ip6_ula")
Packit Service a04d08
        if ip6_ula:
Packit Service a04d08
            addresses6.append(ip6_ula)
Packit Service a04d08
        return addresses6
Packit Service a04d08
Packit Service a04d08
    def get_ip6_prefix(self, dev):
Packit Service a04d08
        return self.get_field(dev, "ip6_prefix_length", "64")
Packit Service a04d08
Packit Service a04d08
    def get_gateway(self, dev):
Packit Service a04d08
        return self.get_field(dev, "gateway")
Packit Service a04d08
Packit Service a04d08
    def get_gateway6(self, dev):
Packit Service a04d08
        return self.get_field(dev, "gateway6")
Packit Service a04d08
Packit Service a04d08
    def get_mask(self, dev):
Packit Service a04d08
        return self.get_field(dev, "mask", "255.255.255.0")
Packit Service a04d08
Packit Service a04d08
    def get_network(self, dev, mac):
Packit Service a04d08
        return self.get_field(dev, "network", self.mac2network(mac))
Packit Service a04d08
Packit Service a04d08
    def get_field(self, dev, name, default=None):
Packit Service a04d08
        """return the field name in context for device dev.
Packit Service a04d08
Packit Service a04d08
        context stores <dev>_<NAME> (example: eth0_DOMAIN).
Packit Service a04d08
        an empty string for value will return default."""
Packit Service a04d08
        val = self.context.get('_'.join((dev, name,)).upper())
Packit Service a04d08
        # allow empty string to return the default.
Packit Service a04d08
        return default if val in (None, "") else val
Packit Service a04d08
Packit Service a04d08
    def gen_conf(self):
Packit Service a04d08
        netconf = {}
Packit Service a04d08
        netconf['version'] = 2
Packit Service a04d08
        netconf['ethernets'] = {}
Packit Service a04d08
Packit Service a04d08
        ethernets = {}
Packit Service a04d08
        for mac, dev in self.ifaces.items():
Packit Service a04d08
            mac = mac.lower()
Packit Service a04d08
Packit Service a04d08
            # c_dev stores name in context 'ETHX' for this device.
Packit Service a04d08
            # dev stores the current system name.
Packit Service a04d08
            c_dev = self.context_devname.get(mac, dev)
Packit Service a04d08
Packit Service a04d08
            devconf = {}
Packit Service a04d08
Packit Service a04d08
            # Set MAC address
Packit Service a04d08
            devconf['match'] = {'macaddress': mac}
Packit Service a04d08
Packit Service a04d08
            # Set IPv4 address
Packit Service a04d08
            devconf['addresses'] = []
Packit Service a04d08
            mask = self.get_mask(c_dev)
Packit Service a04d08
            prefix = str(net.mask_to_net_prefix(mask))
Packit Service a04d08
            devconf['addresses'].append(
Packit Service a04d08
                self.get_ip(c_dev, mac) + '/' + prefix)
Packit Service a04d08
Packit Service a04d08
            # Set IPv6 Global and ULA address
Packit Service a04d08
            addresses6 = self.get_ip6(c_dev)
Packit Service a04d08
            if addresses6:
Packit Service a04d08
                prefix6 = self.get_ip6_prefix(c_dev)
Packit Service a04d08
                devconf['addresses'].extend(
Packit Service a04d08
                    [i + '/' + prefix6 for i in addresses6])
Packit Service a04d08
Packit Service a04d08
            # Set IPv4 default gateway
Packit Service a04d08
            gateway = self.get_gateway(c_dev)
Packit Service a04d08
            if gateway:
Packit Service a04d08
                devconf['gateway4'] = gateway
Packit Service a04d08
Packit Service a04d08
            # Set IPv6 default gateway
Packit Service a04d08
            gateway6 = self.get_gateway6(c_dev)
Packit Service a04d08
            if gateway6:
Packit Service a04d08
                devconf['gateway6'] = gateway6
Packit Service a04d08
Packit Service a04d08
            # Set DNS servers and search domains
Packit Service a04d08
            nameservers = self.get_nameservers(c_dev)
Packit Service a04d08
            if nameservers:
Packit Service a04d08
                devconf['nameservers'] = nameservers
Packit Service a04d08
Packit Service a04d08
            # Set MTU size
Packit Service a04d08
            mtu = self.get_mtu(c_dev)
Packit Service a04d08
            if mtu:
Packit Service a04d08
                devconf['mtu'] = mtu
Packit Service a04d08
Packit Service a04d08
            ethernets[dev] = devconf
Packit Service a04d08
Packit Service a04d08
        netconf['ethernets'] = ethernets
Packit Service a04d08
        return(netconf)
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def find_candidate_devs():
Packit Service a04d08
    """
Packit Service a04d08
    Return a list of devices that may contain the context disk.
Packit Service a04d08
    """
Packit Service a04d08
    combined = []
Packit Service a04d08
    for f in ('LABEL=CONTEXT', 'LABEL=CDROM', 'TYPE=iso9660'):
Packit Service a04d08
        devs = util.find_devs_with(f)
Packit Service a04d08
        devs.sort()
Packit Service a04d08
        for d in devs:
Packit Service a04d08
            if d not in combined:
Packit Service a04d08
                combined.append(d)
Packit Service a04d08
Packit Service a04d08
    return combined
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def switch_user_cmd(user):
Packit Service a04d08
    return ['sudo', '-u', user]
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def parse_shell_config(content, keylist=None, bash=None, asuser=None,
Packit Service a04d08
                       switch_user_cb=None):
Packit Service a04d08
Packit Service a04d08
    if isinstance(bash, str):
Packit Service a04d08
        bash = [bash]
Packit Service a04d08
    elif bash is None:
Packit Service a04d08
        bash = ['bash', '-e']
Packit Service a04d08
Packit Service a04d08
    if switch_user_cb is None:
Packit Service a04d08
        switch_user_cb = switch_user_cmd
Packit Service a04d08
Packit Service a04d08
    # allvars expands to all existing variables by using '${!x*}' notation
Packit Service a04d08
    # where x is lower or upper case letters or '_'
Packit Service a04d08
    allvars = ["${!%s*}" % x for x in string.ascii_letters + "_"]
Packit Service a04d08
Packit Service a04d08
    keylist_in = keylist
Packit Service a04d08
    if keylist is None:
Packit Service a04d08
        keylist = allvars
Packit Service a04d08
        keylist_in = []
Packit Service a04d08
Packit Service a04d08
    setup = '\n'.join(('__v="";', '',))
Packit Service a04d08
Packit Service a04d08
    def varprinter(vlist):
Packit Service a04d08
        # output '\0'.join(['_start_', key=value NULL for vars in vlist]
Packit Service a04d08
        return '\n'.join((
Packit Service a04d08
            'printf "%s\\0" _start_',
Packit Service a04d08
            'for __v in %s; do' % ' '.join(vlist),
Packit Service a04d08
            '   printf "%s=%s\\0" "$__v" "${!__v}";',
Packit Service a04d08
            'done',
Packit Service a04d08
            ''
Packit Service a04d08
        ))
Packit Service a04d08
Packit Service a04d08
    # the rendered 'bcmd' is bash syntax that does
Packit Service a04d08
    # setup: declare variables we use (so they show up in 'all')
Packit Service a04d08
    # varprinter(allvars): print all variables known at beginning
Packit Service a04d08
    # content: execute the provided content
Packit Service a04d08
    # varprinter(keylist): print all variables known after content
Packit Service a04d08
    #
Packit Service a04d08
    # output is then a null terminated array of:
Packit Service a04d08
    #   literal '_start_'
Packit Service a04d08
    #   key=value (for each preset variable)
Packit Service a04d08
    #   literal '_start_'
Packit Service a04d08
    #   key=value (for each post set variable)
Packit Service a04d08
    bcmd = ('unset IFS\n' +
Packit Service a04d08
            setup +
Packit Service a04d08
            varprinter(allvars) +
Packit Service a04d08
            '{\n%s\n\n:\n} > /dev/null\n' % content +
Packit Service a04d08
            'unset IFS\n' +
Packit Service a04d08
            varprinter(keylist) + "\n")
Packit Service a04d08
Packit Service a04d08
    cmd = []
Packit Service a04d08
    if asuser is not None:
Packit Service a04d08
        cmd = switch_user_cb(asuser)
Packit Service a04d08
Packit Service a04d08
    cmd.extend(bash)
Packit Service a04d08
Packit Service a04d08
    (output, _error) = subp.subp(cmd, data=bcmd)
Packit Service a04d08
Packit Service a04d08
    # exclude vars in bash that change on their own or that we used
Packit Service a04d08
    excluded = (
Packit Service a04d08
        "EPOCHREALTIME", "EPOCHSECONDS", "RANDOM", "LINENO", "SECONDS", "_",
Packit Service a04d08
        "__v")
Packit Service a04d08
    preset = {}
Packit Service a04d08
    ret = {}
Packit Service a04d08
    target = None
Packit Service a04d08
    output = output[0:-1]  # remove trailing null
Packit Service a04d08
Packit Service a04d08
    # go through output.  First _start_ is for 'preset', second for 'target'.
Packit Service a04d08
    # Add to ret only things were changed and not in excluded.
Packit Service a04d08
    for line in output.split("\x00"):
Packit Service a04d08
        try:
Packit Service a04d08
            (key, val) = line.split("=", 1)
Packit Service a04d08
            if target is preset:
Packit Service a04d08
                preset[key] = val
Packit Service a04d08
            elif (key not in excluded and
Packit Service a04d08
                  (key in keylist_in or preset.get(key) != val)):
Packit Service a04d08
                ret[key] = val
Packit Service a04d08
        except ValueError:
Packit Service a04d08
            if line != "_start_":
Packit Service a04d08
                raise
Packit Service a04d08
            if target is None:
Packit Service a04d08
                target = preset
Packit Service a04d08
            elif target is preset:
Packit Service a04d08
                target = ret
Packit Service a04d08
Packit Service a04d08
    return ret
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def read_context_disk_dir(source_dir, distro, asuser=None):
Packit Service a04d08
    """
Packit Service a04d08
    read_context_disk_dir(source_dir):
Packit Service a04d08
    read source_dir and return a tuple with metadata dict and user-data
Packit Service a04d08
    string populated.  If not a valid dir, raise a NonContextDiskDir
Packit Service a04d08
    """
Packit Service a04d08
    found = {}
Packit Service a04d08
    for af in CONTEXT_DISK_FILES:
Packit Service a04d08
        fn = os.path.join(source_dir, af)
Packit Service a04d08
        if os.path.isfile(fn):
Packit Service a04d08
            found[af] = fn
Packit Service a04d08
Packit Service a04d08
    if not found:
Packit Service a04d08
        raise NonContextDiskDir("%s: %s" % (source_dir, "no files found"))
Packit Service a04d08
Packit Service a04d08
    context = {}
Packit Service a04d08
    results = {'userdata': None, 'metadata': {}}
Packit Service a04d08
Packit Service a04d08
    if "context.sh" in found:
Packit Service a04d08
        if asuser is not None:
Packit Service a04d08
            try:
Packit Service a04d08
                pwd.getpwnam(asuser)
Packit Service a04d08
            except KeyError as e:
Packit Service a04d08
                raise BrokenContextDiskDir(
Packit Service a04d08
                    "configured user '{user}' does not exist".format(
Packit Service a04d08
                        user=asuser)
Packit Service a04d08
                ) from e
Packit Service a04d08
        try:
Packit Service a04d08
            path = os.path.join(source_dir, 'context.sh')
Packit Service a04d08
            content = util.load_file(path)
Packit Service a04d08
            context = parse_shell_config(content, asuser=asuser)
Packit Service a04d08
        except subp.ProcessExecutionError as e:
Packit Service a04d08
            raise BrokenContextDiskDir(
Packit Service a04d08
                "Error processing context.sh: %s" % (e)
Packit Service a04d08
            ) from e
Packit Service a04d08
        except IOError as e:
Packit Service a04d08
            raise NonContextDiskDir(
Packit Service a04d08
                "Error reading context.sh: %s" % (e)
Packit Service a04d08
            ) from e
Packit Service a04d08
    else:
Packit Service a04d08
        raise NonContextDiskDir("Missing context.sh")
Packit Service a04d08
Packit Service a04d08
    if not context:
Packit Service a04d08
        return results
Packit Service a04d08
Packit Service a04d08
    results['metadata'] = context
Packit Service a04d08
Packit Service a04d08
    # process single or multiple SSH keys
Packit Service a04d08
    ssh_key_var = None
Packit Service a04d08
    if "SSH_KEY" in context:
Packit Service a04d08
        ssh_key_var = "SSH_KEY"
Packit Service a04d08
    elif "SSH_PUBLIC_KEY" in context:
Packit Service a04d08
        ssh_key_var = "SSH_PUBLIC_KEY"
Packit Service a04d08
Packit Service a04d08
    if ssh_key_var:
Packit Service a04d08
        lines = context.get(ssh_key_var).splitlines()
Packit Service a04d08
        results['metadata']['public-keys'] = [
Packit Service a04d08
            line for line in lines if len(line) and not line.startswith("#")
Packit Service a04d08
        ]
Packit Service a04d08
Packit Service a04d08
    # custom hostname -- try hostname or leave cloud-init
Packit Service a04d08
    # itself create hostname from IP address later
Packit Service a04d08
    for k in ('HOSTNAME', 'PUBLIC_IP', 'IP_PUBLIC', 'ETH0_IP'):
Packit Service a04d08
        if k in context:
Packit Service a04d08
            results['metadata']['local-hostname'] = context[k]
Packit Service a04d08
            break
Packit Service a04d08
Packit Service a04d08
    # raw user data
Packit Service a04d08
    if "USER_DATA" in context:
Packit Service a04d08
        results['userdata'] = context["USER_DATA"]
Packit Service a04d08
    elif "USERDATA" in context:
Packit Service a04d08
        results['userdata'] = context["USERDATA"]
Packit Service a04d08
Packit Service a04d08
    # b64decode user data if necessary (default)
Packit Service a04d08
    if 'userdata' in results:
Packit Service a04d08
        encoding = context.get('USERDATA_ENCODING',
Packit Service a04d08
                               context.get('USER_DATA_ENCODING'))
Packit Service a04d08
        if encoding == "base64":
Packit Service a04d08
            try:
Packit Service a04d08
                results['userdata'] = util.b64d(results['userdata'])
Packit Service a04d08
            except TypeError:
Packit Service a04d08
                LOG.warning("Failed base64 decoding of userdata")
Packit Service a04d08
Packit Service a04d08
    # generate Network Configuration v2
Packit Service a04d08
    # only if there are any required context variables
Packit Service a04d08
    # http://docs.opennebula.org/5.4/operation/references/template.html#context-section
Packit Service a04d08
    ipaddr_keys = [k for k in context if re.match(r'^ETH\d+_IP.*$', k)]
Packit Service a04d08
    if ipaddr_keys:
Packit Service a04d08
        onet = OpenNebulaNetwork(context, distro)
Packit Service a04d08
        results['network-interfaces'] = onet.gen_conf()
Packit Service a04d08
Packit Service a04d08
    return results
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
def get_physical_nics_by_mac(distro):
Packit Service a04d08
    devs = net.get_interfaces_by_mac()
Packit Service a04d08
    return dict(
Packit Service a04d08
        [(m, n) for m, n in devs.items() if distro.networking.is_physical(n)]
Packit Service a04d08
    )
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
# Legacy: Must be present in case we load an old pkl object
Packit Service a04d08
DataSourceOpenNebulaNet = DataSourceOpenNebula
Packit Service a04d08
Packit Service a04d08
# Used to match classes to dependencies
Packit Service a04d08
datasources = [
Packit Service a04d08
    (DataSourceOpenNebula, (sources.DEP_FILESYSTEM, )),
Packit Service a04d08
]
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
# Return a list of data sources that match this set of dependencies
Packit Service a04d08
def get_datasource_list(depends):
Packit Service a04d08
    return sources.list_from_depends(depends, datasources)
Packit Service a04d08
Packit Service a04d08
# vi: ts=4 expandtab