def test_config_file_dhcp_2nics(self): """Tests Config class for a configuration with two DHCP NICs.""" cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg") conf = Config(cf) nics = conf.nics self.assertEqual(2, len(nics), "nics") self.assertEqual("NIC1", nics[0].name, "nic0") self.assertEqual("00:50:56:a6:8c:08", nics[0].mac, "mac0") self.assertEqual(BootProtoEnum.DHCP, nics[0].bootProto, "bootproto0")
def test_set_gc_status(self): """ This test is designed to verify the behavior of set_gc_status """ # config is None, return None self.assertEqual(set_gc_status(None, 'Successful'), None) # post gc status is NO, return None cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg") conf = Config(cf) self.assertEqual(set_gc_status(conf, 'Successful'), None) # post gc status is YES, subp is called to execute command cf._insertKey("MISC|POST-GC-STATUS", "YES") conf = Config(cf) with mock.patch.object(util, 'subp', return_value=('ok', b'')) as mockobj: self.assertEqual(set_gc_status(conf, 'Successful'), ('ok', b'')) mockobj.assert_called_once_with( ['vmware-rpctool', 'info-set guestinfo.gc.status Successful'], rcs=[0])
def _get_NicConfigurator(self, text): fp = None try: with tempfile.NamedTemporaryFile(mode="w", dir=self.tmp_dir(), delete=False) as fp: fp.write(text) fp.close() cfg = Config(ConfigFile(fp.name)) return NicConfigurator(cfg.nics, use_system_devices=False) finally: if fp: os.unlink(fp.name)
def test_set_gc_status(self): """ This test is designed to verify the behavior of set_gc_status """ # config is None, return None self.assertEqual(set_gc_status(None, "Successful"), None) # post gc status is NO, return None cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg") conf = Config(cf) self.assertEqual(set_gc_status(conf, "Successful"), None) # post gc status is YES, subp is called to execute command cf._insertKey("MISC|POST-GC-STATUS", "YES") conf = Config(cf) with mock.patch.object(subp, "subp", return_value=SubpResult("ok", b"")) as mockobj: self.assertEqual(set_gc_status(conf, "Successful"), ("ok", b"")) mockobj.assert_called_once_with( ["vmware-rpctool", "info-set guestinfo.gc.status Successful"], rcs=[0], )
def test_datasource_instance_id(self): """Tests instance id for the DatasourceOVF""" cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg") instance_id_prefix = 'iid-vmware-' conf = Config(cf) (md1, _, _) = read_vmware_imc(conf) self.assertIn(instance_id_prefix, md1["instance-id"]) self.assertEqual(md1["instance-id"], 'iid-vmware-imc') (md2, _, _) = read_vmware_imc(conf) self.assertIn(instance_id_prefix, md2["instance-id"]) self.assertEqual(md2["instance-id"], 'iid-vmware-imc') self.assertEqual(md2["instance-id"], md1["instance-id"])
def test_config_reset_passwd(self): cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg") cf._insertKey("PASSWORD|-PASS", "test-password") cf._insertKey("PASSWORD|RESET", "random") conf = Config(cf) with self.assertRaises(ValueError): conf.reset_password() cf.clear() cf._insertKey("PASSWORD|RESET", "yes") self.assertEqual(1, len(cf), "insert size") conf = Config(cf) self.assertTrue(conf.reset_password, "reset password")
def test_get_nics_list_dhcp(self): """Tests if NicConfigurator properly calculates network subnets for a configuration with a list of DHCP NICs""" cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg") config = Config(cf) nicConfigurator = NicConfigurator(config.nics, False) nics_cfg_list = nicConfigurator.generate() self.assertEqual(2, len(nics_cfg_list), "number of config elements") nic1 = {'name': 'NIC1'} nic2 = {'name': 'NIC2'} for cfg in nics_cfg_list: if cfg.get('name') == nic1.get('name'): nic1.update(cfg) elif cfg.get('name') == nic2.get('name'): nic2.update(cfg) self.assertEqual('physical', nic1.get('type'), 'type of NIC1') self.assertEqual('NIC1', nic1.get('name'), 'name of NIC1') self.assertEqual('00:50:56:a6:8c:08', nic1.get('mac_address'), 'mac address of NIC1') subnets = nic1.get('subnets') self.assertEqual(1, len(subnets), 'number of subnets for NIC1') subnet = subnets[0] self.assertEqual('dhcp', subnet.get('type'), 'DHCP type for NIC1') self.assertEqual('auto', subnet.get('control'), 'NIC1 Control type') self.assertEqual('physical', nic2.get('type'), 'type of NIC2') self.assertEqual('NIC2', nic2.get('name'), 'name of NIC2') self.assertEqual('00:50:56:a6:5a:de', nic2.get('mac_address'), 'mac address of NIC2') subnets = nic2.get('subnets') self.assertEqual(1, len(subnets), 'number of subnets for NIC2') subnet = subnets[0] self.assertEqual('dhcp', subnet.get('type'), 'DHCP type for NIC2') self.assertEqual('auto', subnet.get('control'), 'NIC2 Control type')
def test_get_nics_list_dhcp(self): """Tests if NicConfigurator properly calculates network subnets for a configuration with a list of DHCP NICs""" cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg") config = Config(cf) nicConfigurator = NicConfigurator(config.nics, False) nics_cfg_list = nicConfigurator.generate() self.assertEqual(2, len(nics_cfg_list), "number of config elements") nic1 = {"name": "NIC1"} nic2 = {"name": "NIC2"} for cfg in nics_cfg_list: if cfg.get("name") == nic1.get("name"): nic1.update(cfg) elif cfg.get("name") == nic2.get("name"): nic2.update(cfg) self.assertEqual("physical", nic1.get("type"), "type of NIC1") self.assertEqual("NIC1", nic1.get("name"), "name of NIC1") self.assertEqual("00:50:56:a6:8c:08", nic1.get("mac_address"), "mac address of NIC1") subnets = nic1.get("subnets") self.assertEqual(1, len(subnets), "number of subnets for NIC1") subnet = subnets[0] self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC1") self.assertEqual("auto", subnet.get("control"), "NIC1 Control type") self.assertEqual("physical", nic2.get("type"), "type of NIC2") self.assertEqual("NIC2", nic2.get("name"), "name of NIC2") self.assertEqual("00:50:56:a6:5a:de", nic2.get("mac_address"), "mac address of NIC2") subnets = nic2.get("subnets") self.assertEqual(1, len(subnets), "number of subnets for NIC2") subnet = subnets[0] self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC2") self.assertEqual("auto", subnet.get("control"), "NIC2 Control type")
def test_get_config_nameservers(self): """Tests DNS and nameserver settings in a configuration.""" cf = ConfigFile("tests/data/vmware/cust-static-2nic.cfg") config = Config(cf) network_config = get_network_config_from_conf(config, False) self.assertEqual(1, network_config.get('version')) config_types = network_config.get('config') name_servers = None dns_suffixes = None for type in config_types: if type.get('type') == 'nameserver': name_servers = type.get('address') dns_suffixes = type.get('search') break self.assertEqual(['10.20.145.1', '10.20.145.2'], name_servers, "dns") self.assertEqual(['eng.vmware.com', 'proxy.vmware.com'], dns_suffixes, "suffixes")
def test_get_config_nameservers(self): """Tests DNS and nameserver settings in a configuration.""" cf = ConfigFile("tests/data/vmware/cust-static-2nic.cfg") config = Config(cf) network_config = get_network_config_from_conf(config, False) self.assertEqual(1, network_config.get("version")) config_types = network_config.get("config") name_servers = None dns_suffixes = None for type in config_types: if type.get("type") == "nameserver": name_servers = type.get("address") dns_suffixes = type.get("search") break self.assertEqual(["10.20.145.1", "10.20.145.2"], name_servers, "dns") self.assertEqual(["eng.vmware.com", "proxy.vmware.com"], dns_suffixes, "suffixes")
def test_configfile_static_2nics(self): """Tests Config class for a configuration with two static NICs.""" cf = ConfigFile("tests/data/vmware/cust-static-2nic.cfg") conf = Config(cf) self.assertEqual("myhost1", conf.host_name, "hostName") self.assertEqual("Africa/Abidjan", conf.timezone, "tz") self.assertTrue(conf.utc, "utc") self.assertEqual(["10.20.145.1", "10.20.145.2"], conf.name_servers, "dns") self.assertEqual( ["eng.vmware.com", "proxy.vmware.com"], conf.dns_suffixes, "suffixes", ) nics = conf.nics ipv40 = nics[0].staticIpv4 self.assertEqual(2, len(nics), "nics") self.assertEqual("NIC1", nics[0].name, "nic0") self.assertEqual("00:50:56:a6:8c:08", nics[0].mac, "mac0") self.assertEqual(BootProtoEnum.STATIC, nics[0].bootProto, "bootproto0") self.assertEqual("10.20.87.154", ipv40[0].ip, "ipv4Addr0") self.assertEqual("255.255.252.0", ipv40[0].netmask, "ipv4Mask0") self.assertEqual(2, len(ipv40[0].gateways), "ipv4Gw0") self.assertEqual("10.20.87.253", ipv40[0].gateways[0], "ipv4Gw0_0") self.assertEqual("10.20.87.105", ipv40[0].gateways[1], "ipv4Gw0_1") self.assertEqual(1, len(nics[0].staticIpv6), "ipv6Cnt0") self.assertEqual("fc00:10:20:87::154", nics[0].staticIpv6[0].ip, "ipv6Addr0") self.assertEqual("NIC2", nics[1].name, "nic1") self.assertTrue(not nics[1].staticIpv6, "ipv61 dhcp")
def test_get_config_dns_suffixes(self): """Tests if get_network_config_from_conf properly generates nameservers and dns settings from a specified configuration""" cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg") config = Config(cf) network_config = get_network_config_from_conf(config, False) self.assertEqual(1, network_config.get('version')) config_types = network_config.get('config') name_servers = None dns_suffixes = None for type in config_types: if type.get('type') == 'nameserver': name_servers = type.get('address') dns_suffixes = type.get('search') break self.assertEqual([], name_servers, "dns") self.assertEqual(['eng.vmware.com'], dns_suffixes, "suffixes")
def test_configfile_static_2nics(self): cf = ConfigFile("tests/data/vmware/cust-static-2nic.cfg") conf = Config(cf) self.assertEqual('myhost1', conf.host_name, "hostName") self.assertEqual('Africa/Abidjan', conf.timezone, "tz") self.assertTrue(conf.utc, "utc") self.assertEqual(['10.20.145.1', '10.20.145.2'], conf.name_servers, "dns") self.assertEqual(['eng.vmware.com', 'proxy.vmware.com'], conf.dns_suffixes, "suffixes") nics = conf.nics ipv40 = nics[0].staticIpv4 self.assertEqual(2, len(nics), "nics") self.assertEqual('NIC1', nics[0].name, "nic0") self.assertEqual('00:50:56:a6:8c:08', nics[0].mac, "mac0") self.assertEqual(BootProtoEnum.STATIC, nics[0].bootProto, "bootproto0") self.assertEqual('10.20.87.154', ipv40[0].ip, "ipv4Addr0") self.assertEqual('255.255.252.0', ipv40[0].netmask, "ipv4Mask0") self.assertEqual(2, len(ipv40[0].gateways), "ipv4Gw0") self.assertEqual('10.20.87.253', ipv40[0].gateways[0], "ipv4Gw0_0") self.assertEqual('10.20.87.105', ipv40[0].gateways[1], "ipv4Gw0_1") self.assertEqual(1, len(nics[0].staticIpv6), "ipv6Cnt0") self.assertEqual('fc00:10:20:87::154', nics[0].staticIpv6[0].ip, "ipv6Addr0") self.assertEqual('NIC2', nics[1].name, "nic1") self.assertTrue(not nics[1].staticIpv6, "ipv61 dhcp")
def test_yes_default_run_post_script(self): cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg") cf._insertKey("MISC|DEFAULT-RUN-POST-CUST-SCRIPT", "yes") conf = Config(cf) self.assertTrue(conf.default_run_post_script)
def test_get_nics_list_static(self): """Tests if NicConfigurator properly calculates network subnets for a configuration with 2 static NICs""" cf = ConfigFile("tests/data/vmware/cust-static-2nic.cfg") config = Config(cf) nicConfigurator = NicConfigurator(config.nics, False) nics_cfg_list = nicConfigurator.generate() self.assertEqual(2, len(nics_cfg_list), "number of elements") nic1 = {'name': 'NIC1'} nic2 = {'name': 'NIC2'} route_list = [] for cfg in nics_cfg_list: cfg_type = cfg.get('type') if cfg_type == 'physical': if cfg.get('name') == nic1.get('name'): nic1.update(cfg) elif cfg.get('name') == nic2.get('name'): nic2.update(cfg) self.assertEqual('physical', nic1.get('type'), 'type of NIC1') self.assertEqual('NIC1', nic1.get('name'), 'name of NIC1') self.assertEqual('00:50:56:a6:8c:08', nic1.get('mac_address'), 'mac address of NIC1') subnets = nic1.get('subnets') self.assertEqual(2, len(subnets), 'Number of subnets') static_subnet = [] static6_subnet = [] for subnet in subnets: subnet_type = subnet.get('type') if subnet_type == 'static': static_subnet.append(subnet) elif subnet_type == 'static6': static6_subnet.append(subnet) else: self.assertEqual(True, False, 'Unknown type') if 'route' in subnet: for route in subnet.get('routes'): route_list.append(route) self.assertEqual(1, len(static_subnet), 'Number of static subnet') self.assertEqual(1, len(static6_subnet), 'Number of static6 subnet') subnet = static_subnet[0] self.assertEqual('10.20.87.154', subnet.get('address'), 'IPv4 address of static subnet') self.assertEqual('255.255.252.0', subnet.get('netmask'), 'NetMask of static subnet') self.assertEqual('auto', subnet.get('control'), 'control for static subnet') subnet = static6_subnet[0] self.assertEqual('fc00:10:20:87::154', subnet.get('address'), 'IPv6 address of static subnet') self.assertEqual('64', subnet.get('netmask'), 'NetMask of static6 subnet') route_set = set(['10.20.87.253', '10.20.87.105', '192.168.0.10']) for route in route_list: self.assertEqual(10000, route.get('metric'), 'metric of route') gateway = route.get('gateway') if gateway in route_set: route_set.discard(gateway) else: self.assertEqual(True, False, 'invalid gateway %s' % (gateway)) self.assertEqual('physical', nic2.get('type'), 'type of NIC2') self.assertEqual('NIC2', nic2.get('name'), 'name of NIC2') self.assertEqual('00:50:56:a6:ef:7d', nic2.get('mac_address'), 'mac address of NIC2') subnets = nic2.get('subnets') self.assertEqual(1, len(subnets), 'Number of subnets for NIC2') subnet = subnets[0] self.assertEqual('static', subnet.get('type'), 'Subnet type') self.assertEqual('192.168.6.102', subnet.get('address'), 'Subnet address') self.assertEqual('255.255.0.0', subnet.get('netmask'), 'Subnet netmask')
def _get_data(self): found = [] md = {} ud = "" vmwareImcConfigFilePath = None nicspath = None defaults = { "instance-id": "iid-dsovf", } (seedfile, contents) = get_ovf_env(self.paths.seed_dir) system_type = util.read_dmi_data("system-product-name") if system_type is None: LOG.debug("No system-product-name found") if seedfile: # Found a seed dir seed = os.path.join(self.paths.seed_dir, seedfile) (md, ud, cfg) = read_ovf_environment(contents) self.environment = contents found.append(seed) elif system_type and 'vmware' in system_type.lower(): LOG.debug("VMware Virtualization Platform found") if not self.vmware_customization_supported: LOG.debug("Skipping the check for " "VMware Customization support") elif not util.get_cfg_option_bool( self.sys_cfg, "disable_vmware_customization", True): deployPkgPluginPath = search_file("/usr/lib/vmware-tools", "libdeployPkgPlugin.so") if not deployPkgPluginPath: deployPkgPluginPath = search_file("/usr/lib/open-vm-tools", "libdeployPkgPlugin.so") if deployPkgPluginPath: # When the VM is powered on, the "VMware Tools" daemon # copies the customization specification file to # /var/run/vmware-imc directory. cloud-init code needs # to search for the file in that directory. max_wait = get_max_wait_from_cfg(self.ds_cfg) vmwareImcConfigFilePath = util.log_time( logfunc=LOG.debug, msg="waiting for configuration file", func=wait_for_imc_cfg_file, args=("cust.cfg", max_wait)) if vmwareImcConfigFilePath: LOG.debug("Found VMware Customization Config File at %s", vmwareImcConfigFilePath) nicspath = wait_for_imc_cfg_file(filename="nics.txt", maxwait=10, naplen=5) else: LOG.debug("Did not find VMware Customization Config File") else: LOG.debug("Customization for VMware platform is disabled.") if vmwareImcConfigFilePath: self._vmware_nics_to_enable = "" try: cf = ConfigFile(vmwareImcConfigFilePath) self._vmware_cust_conf = Config(cf) (md, ud, cfg) = read_vmware_imc(self._vmware_cust_conf) self._vmware_nics_to_enable = get_nics_to_enable(nicspath) imcdirpath = os.path.dirname(vmwareImcConfigFilePath) product_marker = self._vmware_cust_conf.marker_id hasmarkerfile = check_marker_exists( product_marker, os.path.join(self.paths.cloud_dir, 'data')) special_customization = product_marker and not hasmarkerfile customscript = self._vmware_cust_conf.custom_script_name except Exception as e: _raise_error_status( "Error parsing the customization Config File", e, GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED, vmwareImcConfigFilePath) if special_customization: if customscript: try: precust = PreCustomScript(customscript, imcdirpath) precust.execute() except Exception as e: _raise_error_status( "Error executing pre-customization script", e, GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED, vmwareImcConfigFilePath) try: LOG.debug("Preparing the Network configuration") self._network_config = get_network_config_from_conf( self._vmware_cust_conf, True, True, self.distro.osfamily) except Exception as e: _raise_error_status( "Error preparing Network Configuration", e, GuestCustEvent.GUESTCUST_EVENT_NETWORK_SETUP_FAILED, vmwareImcConfigFilePath) if special_customization: LOG.debug("Applying password customization") pwdConfigurator = PasswordConfigurator() adminpwd = self._vmware_cust_conf.admin_password try: resetpwd = self._vmware_cust_conf.reset_password if adminpwd or resetpwd: pwdConfigurator.configure(adminpwd, resetpwd, self.distro) else: LOG.debug("Changing password is not needed") except Exception as e: _raise_error_status( "Error applying Password Configuration", e, GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED, vmwareImcConfigFilePath) if customscript: try: postcust = PostCustomScript(customscript, imcdirpath) postcust.execute() except Exception as e: _raise_error_status( "Error executing post-customization script", e, GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED, vmwareImcConfigFilePath) if product_marker: try: setup_marker_files( product_marker, os.path.join(self.paths.cloud_dir, 'data')) except Exception as e: _raise_error_status( "Error creating marker files", e, GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED, vmwareImcConfigFilePath) self._vmware_cust_found = True found.append('vmware-tools') # TODO: Need to set the status to DONE only when the # customization is done successfully. util.del_dir(os.path.dirname(vmwareImcConfigFilePath)) enable_nics(self._vmware_nics_to_enable) set_customization_status( GuestCustStateEnum.GUESTCUST_STATE_DONE, GuestCustErrorEnum.GUESTCUST_ERROR_SUCCESS) else: np = { 'iso': transport_iso9660, 'vmware-guestd': transport_vmware_guestd, } name = None for (name, transfunc) in np.items(): (contents, _dev, _fname) = transfunc() if contents: break if contents: (md, ud, cfg) = read_ovf_environment(contents) self.environment = contents found.append(name) # There was no OVF transports found if len(found) == 0: return False if 'seedfrom' in md and md['seedfrom']: seedfrom = md['seedfrom'] seedfound = False for proto in self.supported_seed_starts: if seedfrom.startswith(proto): seedfound = proto break if not seedfound: LOG.debug("Seed from %s not supported by %s", seedfrom, self) return False (md_seed, ud) = util.read_seeded(seedfrom, timeout=None) LOG.debug("Using seeded cache data from %s", seedfrom) md = util.mergemanydict([md, md_seed]) found.append(seedfrom) # Now that we have exhausted any other places merge in the defaults md = util.mergemanydict([md, defaults]) self.seed = ",".join(found) self.metadata = md self.userdata_raw = ud self.cfg = cfg return True
def test_get_nics_list_static(self): """Tests if NicConfigurator properly calculates network subnets for a configuration with 2 static NICs""" cf = ConfigFile("tests/data/vmware/cust-static-2nic.cfg") config = Config(cf) nicConfigurator = NicConfigurator(config.nics, False) nics_cfg_list = nicConfigurator.generate() self.assertEqual(2, len(nics_cfg_list), "number of elements") nic1 = {"name": "NIC1"} nic2 = {"name": "NIC2"} route_list = [] for cfg in nics_cfg_list: cfg_type = cfg.get("type") if cfg_type == "physical": if cfg.get("name") == nic1.get("name"): nic1.update(cfg) elif cfg.get("name") == nic2.get("name"): nic2.update(cfg) self.assertEqual("physical", nic1.get("type"), "type of NIC1") self.assertEqual("NIC1", nic1.get("name"), "name of NIC1") self.assertEqual("00:50:56:a6:8c:08", nic1.get("mac_address"), "mac address of NIC1") subnets = nic1.get("subnets") self.assertEqual(2, len(subnets), "Number of subnets") static_subnet = [] static6_subnet = [] for subnet in subnets: subnet_type = subnet.get("type") if subnet_type == "static": static_subnet.append(subnet) elif subnet_type == "static6": static6_subnet.append(subnet) else: self.assertEqual(True, False, "Unknown type") if "route" in subnet: for route in subnet.get("routes"): route_list.append(route) self.assertEqual(1, len(static_subnet), "Number of static subnet") self.assertEqual(1, len(static6_subnet), "Number of static6 subnet") subnet = static_subnet[0] self.assertEqual( "10.20.87.154", subnet.get("address"), "IPv4 address of static subnet", ) self.assertEqual("255.255.252.0", subnet.get("netmask"), "NetMask of static subnet") self.assertEqual("auto", subnet.get("control"), "control for static subnet") subnet = static6_subnet[0] self.assertEqual( "fc00:10:20:87::154", subnet.get("address"), "IPv6 address of static subnet", ) self.assertEqual("64", subnet.get("netmask"), "NetMask of static6 subnet") route_set = set(["10.20.87.253", "10.20.87.105", "192.168.0.10"]) for route in route_list: self.assertEqual(10000, route.get("metric"), "metric of route") gateway = route.get("gateway") if gateway in route_set: route_set.discard(gateway) else: self.assertEqual(True, False, "invalid gateway %s" % (gateway)) self.assertEqual("physical", nic2.get("type"), "type of NIC2") self.assertEqual("NIC2", nic2.get("name"), "name of NIC2") self.assertEqual("00:50:56:a6:ef:7d", nic2.get("mac_address"), "mac address of NIC2") subnets = nic2.get("subnets") self.assertEqual(1, len(subnets), "Number of subnets for NIC2") subnet = subnets[0] self.assertEqual("static", subnet.get("type"), "Subnet type") self.assertEqual("192.168.6.102", subnet.get("address"), "Subnet address") self.assertEqual("255.255.0.0", subnet.get("netmask"), "Subnet netmask")
def _get_data(self): found = [] md = {} ud = "" vd = "" vmwareImcConfigFilePath = None nicspath = None defaults = { "instance-id": "iid-dsovf", } (seedfile, contents) = get_ovf_env(self.paths.seed_dir) system_type = dmi.read_dmi_data("system-product-name") if system_type is None: LOG.debug("No system-product-name found") if seedfile: # Found a seed dir seed = os.path.join(self.paths.seed_dir, seedfile) (md, ud, cfg) = read_ovf_environment(contents) self.environment = contents found.append(seed) elif system_type and 'vmware' in system_type.lower(): LOG.debug("VMware Virtualization Platform found") if not self.vmware_customization_supported: LOG.debug("Skipping the check for " "VMware Customization support") else: search_paths = ( "/usr/lib/vmware-tools", "/usr/lib64/vmware-tools", "/usr/lib/open-vm-tools", "/usr/lib64/open-vm-tools") plugin = "libdeployPkgPlugin.so" deployPkgPluginPath = None for path in search_paths: deployPkgPluginPath = search_file(path, plugin) if deployPkgPluginPath: LOG.debug("Found the customization plugin at %s", deployPkgPluginPath) break if deployPkgPluginPath: # When the VM is powered on, the "VMware Tools" daemon # copies the customization specification file to # /var/run/vmware-imc directory. cloud-init code needs # to search for the file in that directory which indicates # that required metadata and userdata files are now # present. max_wait = get_max_wait_from_cfg(self.ds_cfg) vmwareImcConfigFilePath = util.log_time( logfunc=LOG.debug, msg="waiting for configuration file", func=wait_for_imc_cfg_file, args=("cust.cfg", max_wait)) else: LOG.debug("Did not find the customization plugin.") md_path = None if vmwareImcConfigFilePath: imcdirpath = os.path.dirname(vmwareImcConfigFilePath) cf = ConfigFile(vmwareImcConfigFilePath) self._vmware_cust_conf = Config(cf) LOG.debug("Found VMware Customization Config File at %s", vmwareImcConfigFilePath) try: (md_path, ud_path, nicspath) = collect_imc_file_paths( self._vmware_cust_conf) except FileNotFoundError as e: _raise_error_status( "File(s) missing in directory", e, GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED, vmwareImcConfigFilePath, self._vmware_cust_conf) else: LOG.debug("Did not find VMware Customization Config File") # Honor disable_vmware_customization setting on metadata absent if not md_path: if util.get_cfg_option_bool(self.sys_cfg, "disable_vmware_customization", True): LOG.debug( "Customization for VMware platform is disabled.") # reset vmwareImcConfigFilePath to None to avoid # customization for VMware platform vmwareImcConfigFilePath = None use_raw_data = bool(vmwareImcConfigFilePath and md_path) if use_raw_data: set_gc_status(self._vmware_cust_conf, "Started") LOG.debug("Start to load cloud-init meta data and user data") try: (md, ud, cfg, network) = load_cloudinit_data(md_path, ud_path) if network: self._network_config = network else: self._network_config = ( self.distro.generate_fallback_config() ) except safeyaml.YAMLError as e: _raise_error_status( "Error parsing the cloud-init meta data", e, GuestCustErrorEnum.GUESTCUST_ERROR_WRONG_META_FORMAT, vmwareImcConfigFilePath, self._vmware_cust_conf) except Exception as e: _raise_error_status( "Error loading cloud-init configuration", e, GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED, vmwareImcConfigFilePath, self._vmware_cust_conf) self._vmware_cust_found = True found.append('vmware-tools') util.del_dir(imcdirpath) set_customization_status( GuestCustStateEnum.GUESTCUST_STATE_DONE, GuestCustErrorEnum.GUESTCUST_ERROR_SUCCESS) set_gc_status(self._vmware_cust_conf, "Successful") elif vmwareImcConfigFilePath: # Load configuration from vmware_imc self._vmware_nics_to_enable = "" try: set_gc_status(self._vmware_cust_conf, "Started") (md, ud, cfg) = read_vmware_imc(self._vmware_cust_conf) self._vmware_nics_to_enable = get_nics_to_enable(nicspath) product_marker = self._vmware_cust_conf.marker_id hasmarkerfile = check_marker_exists( product_marker, os.path.join(self.paths.cloud_dir, 'data')) special_customization = product_marker and not hasmarkerfile customscript = self._vmware_cust_conf.custom_script_name # In case there is a custom script, check whether VMware # Tools configuration allow the custom script to run. if special_customization and customscript: defVal = "false" if self._vmware_cust_conf.default_run_post_script: LOG.debug( "Set default value to true due to" " customization configuration." ) defVal = "true" custScriptConfig = get_tools_config( CONFGROUPNAME_GUESTCUSTOMIZATION, GUESTCUSTOMIZATION_ENABLE_CUST_SCRIPTS, defVal) if custScriptConfig.lower() != "true": # Update the customization status if custom script # is disabled msg = "Custom script is disabled by VM Administrator" LOG.debug(msg) set_customization_status( GuestCustStateEnum.GUESTCUST_STATE_RUNNING, GuestCustErrorEnum.GUESTCUST_ERROR_SCRIPT_DISABLED) raise RuntimeError(msg) ccScriptsDir = os.path.join( self.paths.get_cpath("scripts"), "per-instance") except Exception as e: _raise_error_status( "Error parsing the customization Config File", e, GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED, vmwareImcConfigFilePath, self._vmware_cust_conf) if special_customization: if customscript: try: precust = PreCustomScript(customscript, imcdirpath) precust.execute() except Exception as e: _raise_error_status( "Error executing pre-customization script", e, GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED, vmwareImcConfigFilePath, self._vmware_cust_conf) try: LOG.debug("Preparing the Network configuration") self._network_config = get_network_config_from_conf( self._vmware_cust_conf, True, True, self.distro.osfamily) except Exception as e: _raise_error_status( "Error preparing Network Configuration", e, GuestCustEvent.GUESTCUST_EVENT_NETWORK_SETUP_FAILED, vmwareImcConfigFilePath, self._vmware_cust_conf) if special_customization: LOG.debug("Applying password customization") pwdConfigurator = PasswordConfigurator() adminpwd = self._vmware_cust_conf.admin_password try: resetpwd = self._vmware_cust_conf.reset_password if adminpwd or resetpwd: pwdConfigurator.configure(adminpwd, resetpwd, self.distro) else: LOG.debug("Changing password is not needed") except Exception as e: _raise_error_status( "Error applying Password Configuration", e, GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED, vmwareImcConfigFilePath, self._vmware_cust_conf) if customscript: try: postcust = PostCustomScript(customscript, imcdirpath, ccScriptsDir) postcust.execute() except Exception as e: _raise_error_status( "Error executing post-customization script", e, GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED, vmwareImcConfigFilePath, self._vmware_cust_conf) if product_marker: try: setup_marker_files( product_marker, os.path.join(self.paths.cloud_dir, 'data')) except Exception as e: _raise_error_status( "Error creating marker files", e, GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED, vmwareImcConfigFilePath, self._vmware_cust_conf) self._vmware_cust_found = True found.append('vmware-tools') # TODO: Need to set the status to DONE only when the # customization is done successfully. util.del_dir(os.path.dirname(vmwareImcConfigFilePath)) enable_nics(self._vmware_nics_to_enable) set_customization_status( GuestCustStateEnum.GUESTCUST_STATE_DONE, GuestCustErrorEnum.GUESTCUST_ERROR_SUCCESS) set_gc_status(self._vmware_cust_conf, "Successful") else: np = [('com.vmware.guestInfo', transport_vmware_guestinfo), ('iso', transport_iso9660)] name = None for name, transfunc in np: contents = transfunc() if contents: break if contents: (md, ud, cfg) = read_ovf_environment(contents) self.environment = contents found.append(name) # There was no OVF transports found if len(found) == 0: return False if 'seedfrom' in md and md['seedfrom']: seedfrom = md['seedfrom'] seedfound = False for proto in self.supported_seed_starts: if seedfrom.startswith(proto): seedfound = proto break if not seedfound: LOG.debug("Seed from %s not supported by %s", seedfrom, self) return False (md_seed, ud, vd) = util.read_seeded(seedfrom, timeout=None) LOG.debug("Using seeded cache data from %s", seedfrom) md = util.mergemanydict([md, md_seed]) found.append(seedfrom) # Now that we have exhausted any other places merge in the defaults md = util.mergemanydict([md, defaults]) self.seed = ",".join(found) self.metadata = md self.userdata_raw = ud self.vendordata_raw = vd self.cfg = cfg return True
def get_data(self): found = [] md = {} ud = "" vmwarePlatformFound = False vmwareImcConfigFilePath = '' defaults = { "instance-id": "iid-dsovf", } (seedfile, contents) = get_ovf_env(self.paths.seed_dir) system_type = util.read_dmi_data("system-product-name") if system_type is None: LOG.debug("No system-product-name found") if seedfile: # Found a seed dir seed = os.path.join(self.paths.seed_dir, seedfile) (md, ud, cfg) = read_ovf_environment(contents) self.environment = contents found.append(seed) elif system_type and 'vmware' in system_type.lower(): LOG.debug("VMware Virtualization Platform found") if not util.get_cfg_option_bool( self.sys_cfg, "disable_vmware_customization", True): deployPkgPluginPath = search_file("/usr/lib/vmware-tools", "libdeployPkgPlugin.so") if not deployPkgPluginPath: deployPkgPluginPath = search_file("/usr/lib/open-vm-tools", "libdeployPkgPlugin.so") if deployPkgPluginPath: # When the VM is powered on, the "VMware Tools" daemon # copies the customization specification file to # /var/run/vmware-imc directory. cloud-init code needs # to search for the file in that directory. vmwareImcConfigFilePath = util.log_time( logfunc=LOG.debug, msg="waiting for configuration file", func=wait_for_imc_cfg_file, args=("/var/run/vmware-imc", "cust.cfg")) if vmwareImcConfigFilePath: LOG.debug("Found VMware DeployPkg Config File at %s" % vmwareImcConfigFilePath) else: LOG.debug("Did not find VMware DeployPkg Config File Path") else: LOG.debug("Customization for VMware platform is disabled.") if vmwareImcConfigFilePath: nics = "" try: cf = ConfigFile(vmwareImcConfigFilePath) conf = Config(cf) (md, ud, cfg) = read_vmware_imc(conf) dirpath = os.path.dirname(vmwareImcConfigFilePath) nics = get_nics_to_enable(dirpath) except Exception as e: LOG.debug("Error parsing the customization Config File") LOG.exception(e) set_customization_status( GuestCustStateEnum.GUESTCUST_STATE_RUNNING, GuestCustEventEnum.GUESTCUST_EVENT_CUSTOMIZE_FAILED) enable_nics(nics) return False finally: util.del_dir(os.path.dirname(vmwareImcConfigFilePath)) try: LOG.debug("Applying the Network customization") nicConfigurator = NicConfigurator(conf.nics) nicConfigurator.configure() except Exception as e: LOG.debug("Error applying the Network Configuration") LOG.exception(e) set_customization_status( GuestCustStateEnum.GUESTCUST_STATE_RUNNING, GuestCustEventEnum.GUESTCUST_EVENT_NETWORK_SETUP_FAILED) enable_nics(nics) return False vmwarePlatformFound = True set_customization_status( GuestCustStateEnum.GUESTCUST_STATE_DONE, GuestCustErrorEnum.GUESTCUST_ERROR_SUCCESS) enable_nics(nics) else: np = { 'iso': transport_iso9660, 'vmware-guestd': transport_vmware_guestd, } name = None for (name, transfunc) in np.items(): (contents, _dev, _fname) = transfunc() if contents: break if contents: (md, ud, cfg) = read_ovf_environment(contents) self.environment = contents found.append(name) # There was no OVF transports found if len(found) == 0 and not vmwarePlatformFound: return False if 'seedfrom' in md and md['seedfrom']: seedfrom = md['seedfrom'] seedfound = False for proto in self.supported_seed_starts: if seedfrom.startswith(proto): seedfound = proto break if not seedfound: LOG.debug("Seed from %s not supported by %s", seedfrom, self) return False (md_seed, ud) = util.read_seeded(seedfrom, timeout=None) LOG.debug("Using seeded cache data from %s", seedfrom) md = util.mergemanydict([md, md_seed]) found.append(seedfrom) # Now that we have exhausted any other places merge in the defaults md = util.mergemanydict([md, defaults]) self.seed = ",".join(found) self.metadata = md self.userdata_raw = ud self.cfg = cfg return True