| # 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] |