blob: c5d799824bd07f655fa9596dadd77fcd78a497f5 [file] [log] [blame]
# vi: ts=4 expandtab
#
# Copyright (C) 2017 VMware Inc.
#
# Author: Anish Swaminathan <anishs@vmware.com>
#
import os
import base64
from cloudinit import log as logging
from cloudinit import sources
from cloudinit import util
from distutils.spawn import find_executable
LOG = logging.getLogger(__name__)
class DataSourceVmxGuestinfo(sources.DataSource):
def __init__(self, sys_cfg, distro, paths, ud_proc=None):
sources.DataSource.__init__(self, sys_cfg, distro, paths, ud_proc)
self.metadata = {}
self.userdata_raw = ''
self.vmtoolsd = find_executable("vmtoolsd")
if not self.vmtoolsd:
LOG.error("Failed to find vmtoolsd")
def get_data(self):
if not self.vmtoolsd:
LOG.error("vmtoolsd is required to fetch guestinfo value")
return False
hostname = self._get_guestinfo_value('hostname')
if hostname:
self.distro.set_hostname(hostname)
ud = self._get_guestinfo_value('userdata')
if ud:
LOG.debug("Decoding base64 format guestinfo.userdata")
self.userdata_raw = base64.b64decode(ud)
found = True
dev_index = 0
network_settings = ''
while found:
key_begin = 'interface.' + str(dev_index)
key_iname = key_begin + '.name'
interface_name = self._get_guestinfo_value(key_iname)
if interface_name:
network_settings += 'auto ' + interface_name + '\n'
network_settings += 'iface ' + interface_name
key_proto = key_begin + '.dhcp'
dhcp_enabled = self._get_guestinfo_value(key_proto)
key_address = key_begin + '.address'
address = self._get_guestinfo_value(key_address)
bootproto = 'dhcp'
if dhcp_enabled:
if dhcp_enabled == 'yes':
network_settings += ' dhcp\n'
elif dhcp_enabled == 'no':
network_settings += ' static\n'
bootproto = 'static'
else:
LOG.warning("Invalid value for yes/no parameter for %s, setting to dhcp", key_proto)
elif address:
bootproto = 'static'
dhcp_enabled == 'no'
network_settings += ' static\n'
else:
dhcp_enabled == 'yes'
network_settings += ' dhcp\n'
LOG.debug("Setting network bootproto to dhcp by default")
key_mac = key_begin + '.mac'
mac = self._get_guestinfo_value(key_mac)
if address:
network_settings += 'address ' + address + '\n'
if mac:
network_settings += 'hwaddress ' + mac + '\n'
key_netmask = key_begin + '.netmask'
netmask = self._get_guestinfo_value(key_netmask)
if netmask:
network_settings += 'netmask ' + netmask + '\n'
key_dnsserver = 'dns.servers'
dnsserver = self._get_guestinfo_value(key_dnsserver)
if dnsserver:
network_settings += 'dns-nameservers '
dnsserver = dnsserver.split(',')
for d in dnsserver:
network_settings += d + ' '
network_settings += '\n'
key_dnsdomain = 'dns.domains'
dnsdomain = self._get_guestinfo_value(key_dnsdomain)
if dnsdomain:
network_settings += 'dns-search '
dnsdomain = dnsdomain.split(',')
for d in dnsdomain:
network_settings += d + ' '
network_settings += '\n'
route_index = 0
default_destination_set = False
while True:
key_route = key_begin + '.route.' + str(route_index)
route = self._get_guestinfo_value(key_route)
if route:
network_settings += "routes.%s " % (route_index)
route = route.split(',')
if len(route) > 2:
LOG.debug("Route information for %s route in %s device incorrect - ",
"expected 2 values", route_index, dev_index)
continue
elif len(route) == 2:
network_settings += route[0] + ' ' + route[1] + '\n'# Gateway Destination
else: #length = 1
if not default_destination_set:
network_settings += route[0] + ' 0.0.0.0/0' + '\n'
default_destination_set = True
else:
LOG.debug("Default destination set previously, not setting route %s", route_index)
else:
break
route_index += 1
else:
found = False
dev_index += 1
self.distro.apply_network(network_settings, False)
return True
def _get_guestinfo_value(self, key):
LOG.debug("Getting guestinfo value for key %s", key)
value = ''
try:
(value, _err) = util.subp([self.vmtoolsd, "--cmd", "info-get guestinfo." + key])
if _err:
LOG.error("Failed to get guestinfo value for key %s", key)
except util.ProcessExecutionError as error:
util.logexc(LOG,"Failed to get guestinfo value for key %s: %s", key, error)
except Exception:
util.logexc(LOG,"Unexpected error while trying to get guestinfo value for key %s", key)
return value.rstrip()
def get_instance_id(self):
with open('/sys/class/dmi/id/product_uuid', 'r') as id_file:
return str(id_file.read()).rstrip()
def get_datasource_list(depends):
"""
Return a list of data sources that match this set of dependencies
"""
return [DataSourceVmxGuestinfo]