diff options
Diffstat (limited to 'cloudinit/sources/DataSourceOVF.py')
-rw-r--r-- | cloudinit/sources/DataSourceOVF.py | 554 |
1 files changed, 0 insertions, 554 deletions
diff --git a/cloudinit/sources/DataSourceOVF.py b/cloudinit/sources/DataSourceOVF.py index 05bf84c2..7baef3a5 100644 --- a/cloudinit/sources/DataSourceOVF.py +++ b/cloudinit/sources/DataSourceOVF.py @@ -11,49 +11,13 @@ import base64 import os import re -import time from xml.dom import minidom -from cloudinit import dmi from cloudinit import log as logging from cloudinit import safeyaml, sources, subp, util -from cloudinit.sources.helpers.vmware.imc.config import Config -from cloudinit.sources.helpers.vmware.imc.config_custom_script import ( - PostCustomScript, - PreCustomScript, -) -from cloudinit.sources.helpers.vmware.imc.config_file import ConfigFile -from cloudinit.sources.helpers.vmware.imc.config_nic import NicConfigurator -from cloudinit.sources.helpers.vmware.imc.config_passwd import ( - PasswordConfigurator, -) -from cloudinit.sources.helpers.vmware.imc.guestcust_error import ( - GuestCustErrorEnum, -) -from cloudinit.sources.helpers.vmware.imc.guestcust_event import ( - GuestCustEventEnum as GuestCustEvent, -) -from cloudinit.sources.helpers.vmware.imc.guestcust_state import ( - GuestCustStateEnum, -) -from cloudinit.sources.helpers.vmware.imc.guestcust_util import ( - enable_nics, - get_nics_to_enable, - get_tools_config, - set_customization_status, - set_gc_status, -) LOG = logging.getLogger(__name__) -CONFGROUPNAME_GUESTCUSTOMIZATION = "deployPkg" -GUESTCUSTOMIZATION_ENABLE_CUST_SCRIPTS = "enable-custom-scripts" -VMWARE_IMC_DIR = "/var/run/vmware-imc" - - -class GuestCustScriptDisabled(Exception): - pass - class DataSourceOVF(sources.DataSource): @@ -66,11 +30,7 @@ class DataSourceOVF(sources.DataSource): self.environment = None self.cfg = {} self.supported_seed_starts = ("/", "file://") - self.vmware_customization_supported = True self._network_config = None - self._vmware_nics_to_enable = None - self._vmware_cust_conf = None - self._vmware_cust_found = False def __str__(self): root = sources.DataSource.__str__(self) @@ -81,8 +41,6 @@ class DataSourceOVF(sources.DataSource): md = {} ud = "" vd = "" - vmwareImcConfigFilePath = None - nicspath = None defaults = { "instance-id": "iid-dsovf", @@ -90,305 +48,12 @@ class DataSourceOVF(sources.DataSource): (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") - allow_vmware_cust = False - allow_raw_data = False - if not self.vmware_customization_supported: - LOG.debug( - "Skipping the check for VMware Customization support" - ) - else: - allow_vmware_cust = not util.get_cfg_option_bool( - self.sys_cfg, "disable_vmware_customization", True - ) - allow_raw_data = util.get_cfg_option_bool( - self.ds_cfg, "allow_raw_data", True - ) - - if not (allow_vmware_cust or allow_raw_data): - LOG.debug("Customization for VMware platform is disabled.") - else: - search_paths = ( - "/usr/lib/vmware-tools", - "/usr/lib64/vmware-tools", - "/usr/lib/open-vm-tools", - "/usr/lib64/open-vm-tools", - "/usr/lib/x86_64-linux-gnu/open-vm-tools", - "/usr/lib/aarch64-linux-gnu/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, - ) - # Don't handle the customization for below 2 cases: - # 1. meta data is found, allow_raw_data is False. - # 2. no meta data is found, allow_vmware_cust is False. - if md_path and not allow_raw_data: - LOG.debug("Customization using raw data is disabled.") - # reset vmwareImcConfigFilePath to None to avoid - # customization for VMware platform - vmwareImcConfigFilePath = None - if md_path is None and not allow_vmware_cust: - LOG.debug( - "Customization using VMware config is disabled." - ) - vmwareImcConfigFilePath = None - else: - LOG.debug("Did not find VMware Customization Config File") - - 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 GuestCustScriptDisabled(msg) - - ccScriptsDir = os.path.join( - self.paths.get_cpath("scripts"), "per-instance" - ) - except GuestCustScriptDisabled as e: - LOG.debug("GuestCustScriptDisabled") - _raise_error_status( - "Error parsing the customization Config File", - e, - GuestCustErrorEnum.GUESTCUST_ERROR_SCRIPT_DISABLED, - vmwareImcConfigFilePath, - self._vmware_cust_conf, - ) - 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), @@ -438,9 +103,6 @@ class DataSourceOVF(sources.DataSource): return True def _get_subplatform(self): - system_type = dmi.read_dmi_data("system-product-name").lower() - if system_type == "vmware": - return "vmware (%s)" % self.seed return "ovf (%s)" % self.seed def get_public_ssh_keys(self): @@ -468,94 +130,6 @@ class DataSourceOVFNet(DataSourceOVF): DataSourceOVF.__init__(self, sys_cfg, distro, paths) self.seed_dir = os.path.join(paths.seed_dir, "ovf-net") self.supported_seed_starts = ("http://", "https://") - self.vmware_customization_supported = False - - -def get_max_wait_from_cfg(cfg): - default_max_wait = 15 - max_wait_cfg_option = "vmware_cust_file_max_wait" - max_wait = default_max_wait - - if not cfg: - return max_wait - - try: - max_wait = int(cfg.get(max_wait_cfg_option, default_max_wait)) - except ValueError: - LOG.warning( - "Failed to get '%s', using %s", - max_wait_cfg_option, - default_max_wait, - ) - - if max_wait < 0: - LOG.warning( - "Invalid value '%s' for '%s', using '%s' instead", - max_wait, - max_wait_cfg_option, - default_max_wait, - ) - max_wait = default_max_wait - - return max_wait - - -def wait_for_imc_cfg_file( - filename, maxwait=180, naplen=5, dirpath="/var/run/vmware-imc" -): - waited = 0 - if maxwait <= naplen: - naplen = 1 - - while waited < maxwait: - fileFullPath = os.path.join(dirpath, filename) - if os.path.isfile(fileFullPath): - return fileFullPath - LOG.debug("Waiting for VMware Customization Config File") - time.sleep(naplen) - waited += naplen - return None - - -def get_network_config_from_conf( - config, use_system_devices=True, configure=False, osfamily=None -): - nicConfigurator = NicConfigurator(config.nics, use_system_devices) - nics_cfg_list = nicConfigurator.generate(configure, osfamily) - - return get_network_config( - nics_cfg_list, config.name_servers, config.dns_suffixes - ) - - -def get_network_config(nics=None, nameservers=None, search=None): - config_list = nics - - if nameservers or search: - config_list.append( - {"type": "nameserver", "address": nameservers, "search": search} - ) - - return {"version": 1, "config": config_list} - - -# This will return a dict with some content -# meta-data, user-data, some config -def read_vmware_imc(config): - md = {} - cfg = {} - ud = None - if config.host_name: - if config.domain_name: - md["local-hostname"] = config.host_name + "." + config.domain_name - else: - md["local-hostname"] = config.host_name - - if config.timezone: - cfg["timezone"] = config.timezone - - md["instance-id"] = "iid-vmware-imc" - return (md, ud, cfg) # This will return a dict with some content @@ -745,17 +319,6 @@ def get_properties(contents): return props -def search_file(dirpath, filename): - if not dirpath or not filename: - return None - - for root, _dirs, files in os.walk(dirpath): - if filename in files: - return os.path.join(root, filename) - - return None - - class XmlError(Exception): pass @@ -772,80 +335,6 @@ def get_datasource_list(depends): return sources.list_from_depends(depends, datasources) -# To check if marker file exists -def check_marker_exists(markerid, marker_dir): - """ - Check the existence of a marker file. - Presence of marker file determines whether a certain code path is to be - executed. It is needed for partial guest customization in VMware. - @param markerid: is an unique string representing a particular product - marker. - @param: marker_dir: The directory in which markers exist. - """ - if not markerid: - return False - markerfile = os.path.join(marker_dir, ".markerfile-" + markerid + ".txt") - if os.path.exists(markerfile): - return True - return False - - -# Create a marker file -def setup_marker_files(markerid, marker_dir): - """ - Create a new marker file. - Marker files are unique to a full customization workflow in VMware - environment. - @param markerid: is an unique string representing a particular product - marker. - @param: marker_dir: The directory in which markers exist. - - """ - LOG.debug("Handle marker creation") - markerfile = os.path.join(marker_dir, ".markerfile-" + markerid + ".txt") - for fname in os.listdir(marker_dir): - if fname.startswith(".markerfile"): - util.del_file(os.path.join(marker_dir, fname)) - open(markerfile, "w").close() - - -def _raise_error_status(prefix, error, event, config_file, conf): - """ - Raise error and send customization status to the underlying VMware - Virtualization Platform. Also, cleanup the imc directory. - """ - LOG.debug("%s: %s", prefix, error) - set_customization_status(GuestCustStateEnum.GUESTCUST_STATE_RUNNING, event) - set_gc_status(conf, prefix) - util.del_dir(os.path.dirname(config_file)) - raise error - - -def load_cloudinit_data(md_path, ud_path): - """ - Load the cloud-init meta data, user data, cfg and network from the - given files - - @return: 4-tuple of configuration - metadata, userdata, cfg={}, network - - @raises: FileNotFoundError if md_path or ud_path are absent - """ - LOG.debug("load meta data from: %s: user data from: %s", md_path, ud_path) - md = {} - ud = None - network = None - - md = safeload_yaml_or_dict(util.load_file(md_path)) - - if "network" in md: - network = md["network"] - - if ud_path: - ud = util.load_file(ud_path).replace("\r", "") - return md, ud, {}, network - - def safeload_yaml_or_dict(data): """ The meta data could be JSON or YAML. Since YAML is a strict superset of @@ -857,47 +346,4 @@ def safeload_yaml_or_dict(data): return safeyaml.load(data) -def collect_imc_file_paths(cust_conf): - """ - collect all the other imc files. - - metadata is preferred to nics.txt configuration data. - - If metadata file exists because it is specified in customization - configuration, then metadata is required and userdata is optional. - - @return a 3-tuple containing desired configuration file paths if present - Expected returns: - 1. user provided metadata and userdata (md_path, ud_path, None) - 2. user provided metadata (md_path, None, None) - 3. user-provided network config (None, None, nics_path) - 4. No config found (None, None, None) - """ - md_path = None - ud_path = None - nics_path = None - md_file = cust_conf.meta_data_name - if md_file: - md_path = os.path.join(VMWARE_IMC_DIR, md_file) - if not os.path.exists(md_path): - raise FileNotFoundError( - "meta data file is not found: %s" % md_path - ) - - ud_file = cust_conf.user_data_name - if ud_file: - ud_path = os.path.join(VMWARE_IMC_DIR, ud_file) - if not os.path.exists(ud_path): - raise FileNotFoundError( - "user data file is not found: %s" % ud_path - ) - else: - nics_path = os.path.join(VMWARE_IMC_DIR, "nics.txt") - if not os.path.exists(nics_path): - LOG.debug("%s does not exist.", nics_path) - nics_path = None - - return md_path, ud_path, nics_path - - # vi: ts=4 expandtab |