def do_create_profile(options): '''Run System Configuration Interactive Tool in order to create System Configuration profile''' try: _prepare_engine(options) # insert sysconfig CLI options into DOC doc_options = SysConfigOptions(options) doc = InstallEngine.get_instance().doc.persistent doc.insert_children(doc_options) # Navigate user through the set of configuration screens. Generate # resulting profile only if user went through the complete set of # sysconfig screens. if _show_screens(options): # First set the umask read-only by user (root). # Then let the ManifestWriter generate resulting SC profile. # Finally, reset umask to the original value. orig_umask = os.umask(0377) eng = InstallEngine.get_instance() (status, failed_cps) = eng.execute_checkpoints() os.umask(orig_umask) # If ManifestWriter failed to create SC profile, inform user # and exit with error. if status != InstallEngine.EXEC_SUCCESS: print _("Failed to generate SC profile.") _exit(options.logname, errcode=1) else: print _("SC profile successfully generated.") _exit(options.logname, errcode=0) except SystemExit: raise except: if LOGGER is None: # Error occurred before logging is setup; no place to # dump the traceback raise LOGGER.exception(_("An unhandled exception occurred.")) exc_type, exc_value = sys.exc_info()[:2] try: doc = InstallEngine.get_instance().doc.persistent sc_prof = doc.get_first_child(name="sysconfig") LOGGER.error("Sysconfig profile:\n%s", sc_prof) except: # Ignore any errors to avoid masking the original exception pass print _("An unhandled exception occurred.") if exc_value: print '\t%s: "%s"' % (exc_type.__name__, exc_value) else: print "\t%s" % exc_type.__name__ print _("Full traceback data is in the log") _exit(options.logname, errcode=1)
def setUp(self): InstallEngine._instance = None InstallEngine() self.engine = InstallEngine.get_instance() self.doc = self.engine.data_object_cache.volatile self.soft_node = Software("CPIO_Transfer", "CPIO") self.tr_node = CPIOSpec() self.soft_node.insert_children([self.tr_node]) self.doc.insert_children([self.soft_node]) self.tr_cpio = TransferCPIO("CPIO_Transfer")
def setUp(self): InstallEngine._instance = None InstallEngine() self.engine = InstallEngine.get_instance() self.doc = self.engine.data_object_cache.volatile self.soft_node = Software("P5I transfer") self.tr_node = P5ISpec() dst = Destination() self.ips_image = Image(IPS_IMG_DIR, "create") dst.insert_children([self.ips_image]) self.soft_node.insert_children([self.tr_node, dst]) self.doc.insert_children([self.soft_node])
def setUp(self): InstallEngine._instance = None InstallEngine() self.engine = InstallEngine.get_instance() self.doc = self.engine.data_object_cache.volatile self.soft_node = Software("IPS transfer") self.tr_node = IPSSpec() dst = Destination() self.ips_image = Image(self.IPS_IMG_DIR, "create") ips_im_type = ImType("full") self.ips_image.insert_children([ips_im_type]) dst.insert_children([self.ips_image]) self.soft_node.insert_children([self.tr_node, dst]) self.doc.insert_children([self.soft_node]) self.tr_ips = TransferIPS("IPS transfer")
def setUp(self): InstallEngine._instance = None InstallEngine() self.engine = InstallEngine.get_instance() self.doc = self.engine.data_object_cache.volatile self.soft_node = Software("SVR4Transfer", "SVR4") self.tr_node = SVR4Spec() self.soft_node.insert_children([self.tr_node]) self.doc.insert_children([self.soft_node]) self.tr_svr4 = TransferSVR4("SVR4Transfer") self.make_dummy_pkg(self.TEST_SRC_DIR + "/SUNWpkg1") self.make_dummy_pkg(self.TEST_SRC_DIR + "/SUNWpkg2") self.make_dummy_pkg(self.TEST_SRC_DIR + "/SUNWpkg3") if not os.path.isdir(AbstractSVR4.ADMIN_FILE_DIR): os.makedirs(AbstractSVR4.ADMIN_FILE_DIR, 0755)
def exit_text_installer(logname=None, errcode=0): '''Teardown any existing iSCSI objects, Close out the logger and exit with errcode''' # get the Iscsi object from the DOC, if present. doc = InstallEngine.get_instance().doc iscsi = doc.volatile.get_first_child(name=ISCSI_LABEL, class_type=Iscsi) if iscsi: # The user exited prematurely, so try to tear down the Iscsi object try: LOGGER.debug("User has exited installer. Tearing down " "Iscsi object") iscsi.teardown() except CalledProcessError as err: # only print something to the screen if the errcode is nonzero if errcode != 0: print _("Unable to tear down iSCSI initiator:\n%s" % err) else: LOGGER.debug("Tearing down Iscsi object failed: %s" % err) LOGGER.info("**** END ****") LOGGER.close() if logname is not None: print _("Exiting Text Installer. Log is available at:\n%s") % logname if isinstance(errcode, unicode): errcode = errcode.encode(get_encoding()) sys.exit(errcode)
def on_change_screen(self): """ save the user's choice in case they return to this screen """ choice = self.center_win.get_active_object().item_key LOGGER.debug("discovery selection: %s", choice) eng = InstallEngine.get_instance() if choice == "iscsi": # remove any existing Iscsi DOC objects so there are no duplicates prev_iscsi = eng.doc.volatile.get_first_child(name=ISCSI_LABEL, class_type=Iscsi) if prev_iscsi: prev_iscsi.delete() # create an empty Iscsi DOC object iscsi_doc_obj = Iscsi(ISCSI_LABEL) # add the object to the DOC eng.doc.volatile.insert_children(iscsi_doc_obj) else: # look for an existing iSCSI object in the DOC. If there is one, # remove it iscsi_doc_obj = eng.doc.volatile.get_first_child(class_type=Iscsi, name=ISCSI_LABEL) if iscsi_doc_obj is not None: iscsi_doc_obj.delete() self.current_selection = self.center_win.active_object
def report_status(self): '''Update the install status. Also checks the quit_event to see if the installation should be aborted. ''' try: processing_quit = False while self.prog_handler.server_up: if not processing_quit: ready_to_read = select([self.prog_handler.engine_skt], [], [], 0.25)[0] if len(ready_to_read) > 0: percent, msg = self.prog_handler.parseProgressMsg(\ ready_to_read[0]) LOGGER.debug("message = %s", msg) LOGGER.debug("percent = %s", percent) self.update_status_func(float(percent), msg) # check whether F9 is pressed input_key = self.screen.main_win.getch() if input_key == curses.KEY_F9: LOGGER.info("User selected Quit") really_quit = self.screen.confirm_quit() if really_quit: LOGGER.info("User confirmed Quit") engine = InstallEngine.get_instance() engine.cancel_checkpoints() processing_quit = True except Exception, e: LOGGER.exception("progressServer Error")
def update_doc_paths(build_data_mp): """ function to replace placeholder strings in the DOC with actual paths build_data_mp - mountpoint of the build_data dataset """ eng = InstallEngine.get_instance() doc = eng.data_object_cache # find all of the Software nodes software_list = doc.volatile.get_descendants(class_type=Software) # iterate over each node, looking for Dir and/or Image nodes for software_node in software_list: for dir_node in software_node.get_descendants(class_type=Dir): path = dir_node.dir_path path = path.replace("{BUILD_DATA}", build_data_mp) path = path.replace("{BOOT_ARCHIVE}", os.path.join(build_data_mp, "boot_archive")) path = path.replace("{PKG_IMAGE_PATH}", os.path.join(build_data_mp, "pkg_image")) dir_node.dir_path = path for image_node in software_node.get_descendants(class_type=Image): path = image_node.img_root path = path.replace("{BUILD_DATA}", build_data_mp) path = path.replace("{BOOT_ARCHIVE}", os.path.join(build_data_mp, "boot_archive")) path = path.replace("{PKG_IMAGE_PATH}", os.path.join(build_data_mp, "pkg_image")) image_node.img_root = path
def parse_doc(self): """ class method for parsing the data object cache (DOC) objects for use by this checkpoint """ self.engine = InstallEngine.get_instance() self.doc = self.engine.data_object_cache # Get a reference to ApplicationData object self.app_data = self.doc.persistent.get_first_child( \ class_type=ApplicationData) if self.app_data: # Get the installation service list file self.service_list_file = \ self.app_data.data_dict.get(AI_SERVICE_LIST_FILE) # See if an alternate pool dataset is set. self.alt_pool_dataset = \ self.app_data.data_dict.get(ALT_POOL_DATASET) if not self.service_list_file: self.logger.debug("No service list provided.") # Get all configuration components from the DOC self.conf_list = self.doc.get_descendants(class_type=Configuration)
def test_mp_engine_load_good(self): ''' test_mp_engine_load_good - test manifest_parser succeeds parsing manifest stored in DOC ''' # Store manifest in DOC doc = InstallEngine.get_instance().data_object_cache if doc is not None: mp_data = doc.volatile.get_first_child(name=MANIFEST_PARSER_DATA) if mp_data is None: mp_data = ManifestParserData(MANIFEST_PARSER_DATA) doc.volatile.insert_children(mp_data) mp_data.manifest = common.MANIFEST_DC my_args = None my_kwargs = {} my_kwargs["validate_from_docinfo"] = False self.engine.register_checkpoint("manifest_parser", "solaris_install/manifest/parser", "ManifestParser", args=my_args, kwargs=my_kwargs) status = self.engine.execute_checkpoints()[0] self.assertEqual(status, InstallEngine.EXEC_SUCCESS, "ManifestParser checkpoint should have succeeded")
def parse_doc(self): """ class method for parsing data object cache (DOC) objects for use by the checkpoint. """ self.doc = InstallEngine.get_instance().data_object_cache try: self.dc_dict = self.doc.volatile.get_children(name=DC_LABEL, class_type=DataObjectDict)[0].data_dict self.ba_build = self.dc_dict["ba_build"] self.pkg_img_path = self.dc_dict["pkg_img_path"] # path to the save directory self.save_path = os.path.join(self.pkg_img_path, "save") self.img_info_path = os.path.join(self.pkg_img_path, ".image_info") self.tmp_dir = self.dc_dict.get("tmp_dir") svc_profile_list = self.doc.volatile.get_descendants(self.name, class_type=Configuration) dc_pers_dict = self.doc.persistent.get_children(name=DC_PERS_LABEL, class_type=DataObjectDict) if dc_pers_dict: self.dc_pers_dict = dc_pers_dict[0].data_dict except KeyError, msg: raise RuntimeError("Error retrieving a value from the DOC: " + str(msg))
def execute(self, dry_run=False): ''' Abstract method defined in AbstractCheckpoint class. Loads the specified Manifest and does the requested validation. Imports resulting data into DOC. Parameters: - the dry_run keyword paramater, specified in AbstractCheckpoint, is ignored in this method. Returns: - Nothing On success, this method returns; on error it raises an exception. Raises: - ManifestError is raised if unable to fetch DOC reference or if an error occurs in parse(). ''' self.logger.debug("ManifestParser.execute(dry_run=%s) called", dry_run) engine = InstallEngine.get_instance() doc = engine.data_object_cache if doc is None: raise ManifestError("Cannot get DOC reference from InstallEngine") self.parse(doc=doc)
def reset(self, dummy=None): '''Reset ui_obj to value found from Target Discovery. Meaningful only for editable DiskWindows ''' if not self.editable: return doc = InstallEngine.get_instance().doc # "reset" the desired target reset_obj = None if isinstance(self.ui_obj, UIDisk): reset_obj = (self.tc.reset_layout(disk=self.ui_obj.doc_obj))[0] else: # reset the partition by removing the modified Partition, and # resetting it with the partition found during target discovery. discovered_obj = self.ui_obj.discovered_doc_obj desired_disk = get_desired_target_disk(doc) desired_part = get_solaris_partition(doc) desired_disk.delete_partition(desired_part) part_copy = deepcopy(discovered_obj) desired_disk.insert_children(part_copy) # get the updated reference reset_obj = get_solaris_partition(doc) dump_doc("After doing reset") self.set_disk_info(disk_info=reset_obj) self.activate_solaris_data()
def setUp(self): """ Common unit test setup method for all subclasses """ self.engine = get_new_engine_instance() self.doc = InstallEngine.get_instance().data_object_cache if not os.path.exists(TMP_TEST_DIR): os.makedirs(TMP_TEST_DIR)
def execute(self, dry_run=False): ''' Abstract method defined in AbstractCheckpoint class. Exports data from InstallEngine's DataObjectCache to the file named in self._manifest. Parameters: - dry_run is used to control what actions are taken if self._manifest already exists. If dry_run is False, the file will be overwritten if it exists. if dry_run is True, the output will be written to a similarly-named, but non-existing file. Returns: - Nothing On success, this method returns; on error it raises an exception. Raises: - ManifestError is raised if unable to fetch DOC reference or if an error occurs in write(). ''' self.logger.debug("ManifestWriter.execute(dry_run=%s) called", dry_run) engine = InstallEngine.get_instance() doc = engine.data_object_cache if doc is None: raise ManifestError("Cannot get DOC reference from InstallEngine") if dry_run and os.path.exists(self._manifest): self._manifest = _create_unique_variant(self._manifest) self.write(doc)
def exit_gui_install(logname=None, errcode=0): '''Teardown any existing iSCSI objects, Close out the logger and exit with errcode''' logger = logging.getLogger(INSTALL_LOGGER_NAME) # get the Iscsi object from the DOC, if present. doc = InstallEngine.get_instance().doc iscsi = doc.volatile.get_first_child(name=ISCSI_LABEL, class_type=Iscsi) if iscsi: logger.debug("User has exited installer. Tearing down Iscsi object") try: iscsi.teardown() except CalledProcessError as error: # Not a fatal error logger.warn("Iscsi.teardown failed: " + str(error)) logger.info("**** END ****") logger.close() del_pid_file() if logname is not None: print _("Exiting GUI Installer. Log is available at:\n%s") % logname if isinstance(errcode, unicode): errcode = errcode.encode(get_encoding()) sys.exit(errcode)
def __init__(self, name, search_name=None, search_type=None): super(TargetDiscovery, self).__init__(name) self.dry_run = False self.eng = InstallEngine.get_instance() self.doc = self.eng.data_object_cache # create a root node to insert all discovered objects into self.root = Target(Target.DISCOVERED) # user specified search criteria self.search_name = search_name self.search_type = search_type # list of discovered swap and dump zvols self.swap_list = list() self.dump_list = list() # eeprom diag mode and bootdisk value self.sparc_diag_mode = False self.bootdisk = None # kernel architecture self.arch = platform.processor()
def execute_checkpoint(log=DEFAULTLOG, resume_checkpoint=None, pause_checkpoint=None): """ wrapper to the execute_checkpoints (and friends) methods """ eng = InstallEngine.get_instance() if resume_checkpoint is not None: (status, failed_cps) = eng.resume_execute_checkpoints( start_from=resume_checkpoint, pause_before=pause_checkpoint, dry_run=False, callback=None) else: (status, failed_cps) = eng.execute_checkpoints(start_from=None, pause_before=pause_checkpoint, dry_run=False, callback=None) if status != InstallEngine.EXEC_SUCCESS: for failed_cp in failed_cps: for err in errsvc.get_errors_by_mod_id(failed_cp): DC_LOGGER.info("'%s' checkpoint failed" % failed_cp) DC_LOGGER.info(err.error_data[ES_DATA_EXCEPTION]) # if a CalledProcessError is raised during execution of a # checkpoint, make sure the strerror() is also logged to give # the user additional feedback if isinstance(err.error_data[ES_DATA_EXCEPTION], CalledProcessError): DC_LOGGER.debug(os.strerror( err.error_data[ES_DATA_EXCEPTION].returncode)) raise RuntimeError("Please check the log for additional error " "messages. \nLog: " + log)
def register_checkpoint(sc_profile=SC_FILE, xslt=XSLT_FILE): '''Registers the GENERATE_SC_PROFILE_CHKPOINT checkpoint with the engine. Also adds config_profile to InstallEngine.doc.persistent''' eng = InstallEngine.get_instance() sc_kwargs = {'xslt_file': xslt} sc_args = [sc_profile] eng.register_checkpoint(GENERATE_SC_PROFILE_CHKPOINT, "solaris_install/manifest/writer", "ManifestWriter", args=sc_args, kwargs=sc_kwargs) # Add profile location to the ApplySysconfig checkpoint's data dict. # Try to find the ApplySysconfig data dict from the DOC in case it # already exists. as_doc_dict = None as_doc_dict = eng.doc.volatile.get_first_child(name=APPLY_SYSCONFIG_DICT) if as_doc_dict is None: # Initialize new dictionary in DOC as_dict = {APPLY_SYSCONFIG_PROFILE_KEY: sc_profile} as_doc_dict = DataObjectDict(APPLY_SYSCONFIG_DICT, as_dict) eng.doc.volatile.insert_children(as_doc_dict) else: # Add to existing dictionary in DOC as_doc_dict.data_dict[APPLY_SYSCONFIG_PROFILE_KEY] = sc_profile eng.doc.persistent.insert_children([ConfigProfile()])
def report_status(self): '''Update the install status. Also checks the quit_event to see if the installation should be aborted. ''' try: processing_quit = False while self.prog_handler.server_up: if not processing_quit: ready_to_read = select([self.prog_handler.engine_skt], [], [], 0.25)[0] if len(ready_to_read) > 0: percent, msg = self.prog_handler.parseProgressMsg(\ ready_to_read[0]) LOGGER.debug("message = %s", msg) LOGGER.debug("percent = %s", percent) self.update_status_func(float(percent), msg) # check whether F9 is pressed input_key = self.screen.main_win.getch() if input_key == curses.KEY_F9: LOGGER.info("User selected Quit") really_quit = self.screen.confirm_quit() if really_quit: LOGGER.info("User confirmed Quit") engine = InstallEngine.get_instance() engine.cancel_checkpoints() processing_quit = True except Exception: LOGGER.exception("progressServer Error")
def __init__(self, main_win, target_controller, x86_slice_mode=False): super(PartEditScreen, self).__init__(main_win) global LOGGER LOGGER = logging.getLogger(INSTALL_LOGGER_NAME) self.x86_slice_mode = x86_slice_mode self.is_x86 = platform.processor() == "i386" self.doc = InstallEngine.get_instance().doc if self.x86_slice_mode: # x86, Slice within a partition self.instance = ".slice" self.header_text = PartEditScreen.HEADER_x86_SLICE self.paragraph_text = PartEditScreen.SLICE_PARAGRAPH self.destroy_text = PartEditScreen.SLICE_DESTROY_TEXT self.help_data = PartEditScreen.X86_SLICE_HELP elif self.is_x86: # x86, Partition on disk self.header_text = PartEditScreen.HEADER_x86_PART self.paragraph_text = PartEditScreen.PARTITION_PARAGRAPH self.destroy_text = PartEditScreen.PART_DESTROY_TEXT self.help_data = PartEditScreen.X86_PART_HELP else: # SPARC (Slice on disk) self.header_text = PartEditScreen.HEADER_SPARC_SLICE self.paragraph_text = PartEditScreen.SLICE_PARAGRAPH self.destroy_text = PartEditScreen.SLICE_DESTROY_TEXT self.help_data = PartEditScreen.SPARC_HELP self.help_format = " %s" self.disk_win = None self.tc = target_controller
def parse_doc(self): """ class method for parsing data object cache (DOC) objects for use by the checkpoint. """ self.doc = InstallEngine.get_instance().data_object_cache try: self.dc_dict = self.doc.volatile.get_children( name=DC_LABEL, class_type=DataObjectDict)[0].data_dict self.ba_build = self.dc_dict["ba_build"] self.pkg_img_path = self.dc_dict["pkg_img_path"] # path to the save directory self.save_path = os.path.join(self.pkg_img_path, "save") self.img_info_path = os.path.join(self.pkg_img_path, ".image_info") self.tmp_dir = self.dc_dict.get("tmp_dir") svc_profile_list = self.doc.volatile.get_descendants( self.name, class_type=Configuration) dc_pers_dict = self.doc.persistent.get_children( name=DC_PERS_LABEL, class_type=DataObjectDict) if dc_pers_dict: self.dc_pers_dict = dc_pers_dict[0].data_dict except KeyError, msg: raise RuntimeError("Error retrieving a value from the DOC: " + str(msg))
def execute_checkpoint(log=DEFAULTLOG, resume_checkpoint=None, pause_checkpoint=None): """ wrapper to the execute_checkpoints (and friends) methods """ eng = InstallEngine.get_instance() if resume_checkpoint is not None: (status, failed_cps) = eng.resume_execute_checkpoints( start_from=resume_checkpoint, pause_before=pause_checkpoint, dry_run=False, callback=None) else: (status, failed_cps) = eng.execute_checkpoints(start_from=None, pause_before=pause_checkpoint, dry_run=False, callback=None) if status != InstallEngine.EXEC_SUCCESS: for failed_cp in failed_cps: for err in errsvc.get_errors_by_mod_id(failed_cp): DC_LOGGER.info("'%s' checkpoint failed" % failed_cp) DC_LOGGER.info(err.error_data[ES_DATA_EXCEPTION]) # if a CalledProcessError is raised during execution of a # checkpoint, make sure the strerror() is also logged to give # the user additional feedback if isinstance(err.error_data[ES_DATA_EXCEPTION], CalledProcessError): DC_LOGGER.debug( os.strerror( err.error_data[ES_DATA_EXCEPTION].returncode)) raise RuntimeError("Please check the log for additional error " "messages. \nLog: " + log)
def validate(self): ''' Deals with the Reboot button being pressed. Defines abstract method from superclass. ''' eng = InstallEngine.get_instance() profile = eng.data_object_cache.volatile.get_first_child( name="GUI Install", class_type=InstallProfile) dest = os.path.join('/a', profile.log_final) if os.path.exists(os.path.dirname(dest)): self.logger.info("Rebooting...") self.logger.info("**** END ****") self.logger.close() shutil.copyfile(profile.log_location, dest) try: cmd = REBOOT.split() Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=self.logger) except (CalledProcessError, StderrCalledProcessError): self.logger.warn("Reboot failed:\n\t'%s'", " ".join(cmd)) else: self.logger.warn( "Reboot failed:\n\t'%s'.\nWill attempt" " standard reboot", " ".join([REBOOT])) self.logger.close()
def validate_target(): """ validate_target() - function to validate the target element specified in the manifest. """ eng = InstallEngine.get_instance() doc = eng.data_object_cache # retrieve the build dataset build_datasets = doc.get_descendants(class_type=Filesystem) if len(build_datasets) > 1: raise RuntimeError("More than one dataset specified as the build " "dataset") base_dataset = build_datasets[0].name base_action = build_datasets[0].action base_mountpoint = build_datasets[0].mountpoint # verify the base_action is not "delete" for the Filesystem if base_action == "delete": raise RuntimeError("distro_const: 'delete' action not supported " "for Filesystems") # get the zpool name and action build_zpool = doc.get_descendants(class_type=Zpool) if len(build_zpool) > 1: raise RuntimeError("More than one zpool specified") zpool_name = build_zpool[0].name zpool_action = build_zpool[0].action zpool_mountpoint = build_zpool[0].mountpoint if zpool_action == "delete": raise RuntimeError("distro_const: 'delete' action not supported " "for Zpools") # if the user has selected "create" for the action, verify the zpool is # not the bootfs zpool since there is an implied "delete" before any # "create" actions in TI elif zpool_action == "create": if is_root_pool(zpool_name): raise RuntimeError("distro_const: 'create' action not allowed " "on a build dataset that is also a root " "pool: " + zpool_name) # since the zpool_action is "create", unless the mountpoint of the # base_dataset is explictly set, it will be set to None. if base_mountpoint is None: # let ZFS figure out the mountpoint if zpool_mountpoint is None: base_mountpoint = os.path.join("/", base_dataset) else: # if the mountpoint has been specified, strip the zpool name # from the dataset name. fixed_name = "/".join(base_dataset.split("/")[1:]) base_mountpoint = os.path.join(zpool_mountpoint, fixed_name) return(zpool_name, base_dataset, base_action, base_mountpoint)
def validate_target(): """ validate_target() - function to validate the target element specified in the manifest. """ eng = InstallEngine.get_instance() doc = eng.data_object_cache # retrieve the build dataset build_datasets = doc.get_descendants(class_type=Filesystem) if len(build_datasets) > 1: raise RuntimeError("More than one dataset specified as the build " "dataset") base_dataset = build_datasets[0].name base_action = build_datasets[0].action base_mountpoint = build_datasets[0].mountpoint # verify the base_action is not "delete" for the Filesystem if base_action == "delete": raise RuntimeError("distro_const: 'delete' action not supported " "for Filesystems") # get the zpool name and action build_zpool = doc.get_descendants(class_type=Zpool) if len(build_zpool) > 1: raise RuntimeError("More than one zpool specified") zpool_name = build_zpool[0].name zpool_action = build_zpool[0].action zpool_mountpoint = build_zpool[0].mountpoint if zpool_action == "delete": raise RuntimeError("distro_const: 'delete' action not supported " "for Zpools") # if the user has selected "create" for the action, verify the zpool is # not the bootfs zpool since there is an implied "delete" before any # "create" actions in TI elif zpool_action == "create": if is_root_pool(zpool_name): raise RuntimeError("distro_const: 'create' action not allowed " "on a build dataset that is also a root " "pool: " + zpool_name) # since the zpool_action is "create", unless the mountpoint of the # base_dataset is explictly set, it will be set to None. if base_mountpoint is None: # let ZFS figure out the mountpoint if zpool_mountpoint is None: base_mountpoint = os.path.join("/", base_dataset) else: # if the mountpoint has been specified, strip the zpool name # from the dataset name. fixed_name = "/".join(base_dataset.split("/")[1:]) base_mountpoint = os.path.join(zpool_mountpoint, fixed_name) return (zpool_name, base_dataset, base_action, base_mountpoint)
def get_sc_options_from_doc(): '''Obtains list of sysconfig CLI options from Data Object Cache''' doc = InstallEngine.get_instance().doc.persistent sc_options = doc.get_first_child(name=SC_OPTIONS_LABEL) if sc_options is not None: return sc_options.options else: return None
def dump_doc(msg): if not LOGGER.isEnabledFor(logging.DEBUG): return LOGGER.debug(msg) doc = InstallEngine.get_instance().doc disk = get_desired_target_disk(doc) LOGGER.debug(str(disk))
def discovered_doc_obj(self): ''' Search for the same disk found during Target Discovery Returns the object in the discovered target tree of the DOC. Raise RuntimeError() if disk is not found in discovered target. ''' doc = InstallEngine.get_instance().doc return(find_discovered_disk(self.doc_obj, doc))
def parse_manifest(manifest): """ function to parse the manifest """ eng = InstallEngine.get_instance() kwargs = dict() kwargs["call_xinclude"] = True args = [manifest] eng.register_checkpoint(MP_DICT["name"], MP_DICT["mod_path"], MP_DICT["class"], args=args, kwargs=kwargs) execute_checkpoint()
def td_iscsi_callback(status, failed_cps): ''' This is the callback registered with the InstallEngine to be called when TargetDiscovery (for iSCSI disks) completes. Logs any Checkpoint errors and sets TD_ISCSI_COMPLETE to True. If TD(iSCSI) has been queued, then run it. ''' global TD_ISCSI_COMPLETE, WAIT_FOR_TD_ISCSI, QUEUE_TD_ISCSI logger = logging.getLogger(INSTALL_LOGGER_NAME) # Ensure that the checkpoint did not record any errors if status != InstallEngine.EXEC_SUCCESS: # Log the errors, but then attempt to proceed anyway logger.error("ERROR: TargetDiscovery (iSCSI disks) FAILED") for failed_cp in failed_cps: err_data_list = errsvc.get_errors_by_mod_id(failed_cp) if len(err_data_list): err_data = err_data_list[0] err = err_data.error_data[liberrsvc.ES_DATA_EXCEPTION] else: err = "Unknown error" logger.error("Checkpoint [%s] logged error: [%s]" % \ (failed_cp, err)) # fetch Iscsi from DOC and unconfig and delete it engine = InstallEngine.get_instance() iscsis = engine.doc.volatile.get_children(name=ISCSI_LABEL, class_type=Iscsi) for iscsi in iscsis: try: logger.debug("teardown previous iSCSI: %s", iscsi) iscsi.teardown() except CalledProcessError as error: # Not a fatal error logger.warn("Iscsi.teardown failed: " + str(error)) logger.debug("Removing old Iscsi object from DOC: %s", iscsi) iscsi.delete() TD_ISCSI_COMPLETE = True WAIT_FOR_TD_ISCSI = False if QUEUE_TD_ISCSI: # We cannot directly register the next checkpoint from # this callback function, as the Engine is still executing, # so we do so via idle_add (which runs function in main loop # when it gets an opportunity) logger.debug("Kicking off TD(iSCSI) indirectly") gobject.idle_add(start_td_iscsi_deferred) QUEUE_TD_ISCSI = False
def from_engine(): '''Convenience function for getting the ConfigProfile from the engine's DOC instance. ''' doc = InstallEngine.get_instance().doc sysconfig = doc.get_descendants(class_type=ConfigProfile) if sysconfig: return sysconfig[0] else: return None
def __init__(self, name, command): super(CustomScript, self).__init__(name) self.doc = InstallEngine.get_instance().data_object_cache self.dc_dict = self.doc.volatile.get_children( name=DC_LABEL, class_type=DataObjectDict)[0].data_dict self.pkg_img_path = self.dc_dict["pkg_img_path"] self.ba_build = self.dc_dict["ba_build"] # If command is over multiple lines, join with spaces, and then strip # any spaces at the ends. self.command = " ".join(command.splitlines()).strip()
def __init__(self, name, command): super(CustomScript, self).__init__(name) self.doc = InstallEngine.get_instance().data_object_cache self.dc_dict = self.doc.volatile.get_children(name=DC_LABEL, class_type=DataObjectDict)[0].data_dict self.pkg_img_path = self.dc_dict["pkg_img_path"] self.ba_build = self.dc_dict["ba_build"] # If command is over multiple lines, join with spaces, and then strip # any spaces at the ends. self.command = " ".join(command.splitlines()).strip()
def to_engine(profile, override=True): '''Convenience function for putting a ConfigProfile into the engine's DOC instance. By default, removes any existing ConfigProfiles - set override=False to bypass that behavior. ''' parent = InstallEngine.get_instance().doc.persistent if override: remove = parent.get_children(name=profile.name) parent.delete_children(children=remove) parent.insert_children(profile)
def __init__(self, name, be_mountpoint="/a"): super(TargetSelectionZone, self).__init__(name, be_mountpoint) # instance attributes self.be_mountpoint = be_mountpoint self.doc = InstallEngine.get_instance().data_object_cache # set the zone's alternate pool dataset self.selected_dataset = None # set the platform self.arch = platform.processor()
def register_checkpoints(DC_LOGGER): """ register each checkpoint in the execution section of the manifest with the InstallEngine. Also set the stop_on_error property of the InstallEngine based on what that property is set to in the manifest. """ eng = InstallEngine.get_instance() doc = eng.data_object_cache # get the execution object from the DOC that contains all of the # checkpoint objects as the children # get the execution_list from the Distro object distro_obj = doc.volatile.get_first_child(class_type=Distro) execution_obj = distro_obj.get_first_child(class_type=Execution) if execution_obj is None: raise RuntimeError("No Execution section found in the manifest") # get_children, with no parameters, will return an empty list if there are # no children checkpoints = execution_obj.get_children() if len(checkpoints) == 0: raise RuntimeError("No checkpoints found in the Execution section " "of the manifest") # set stop_on_error commensurate with what's specified in the manifest eng.stop_on_error = (execution_obj.stop_on_error.capitalize() == "True") # register the checkpoints with the engine registered_checkpoints = [] for checkpoint in checkpoints: try: DC_LOGGER.debug("Registering Checkpoint: " + checkpoint.name) eng.register_checkpoint(checkpoint.name, checkpoint.mod_path, checkpoint.checkpoint_class, insert_before=None, loglevel=checkpoint.log_level, args=checkpoint.args, kwargs=checkpoint.kwargs) except ImportError as err: DC_LOGGER.exception("Error registering checkpoint " "'%s'\n" % checkpoint.name + \ "Check the 'mod_path' and 'checkpoint_class' " "specified for this checkpoint") raise registered_checkpoints.append((checkpoint.name, checkpoint.desc)) return registered_checkpoints
def parse_doc(self): """ class method for parsing data object cache (DOC) objects for use by the checkpoint. """ self.doc = InstallEngine.get_instance().data_object_cache self.dc_dict = self.doc.volatile.get_children(name=DC_LABEL, class_type=DataObjectDict)[0].data_dict try: self.pkg_img_path = self.dc_dict["pkg_img_path"] self.ba_build = self.dc_dict["ba_build"] except KeyError: raise RuntimeError("Error retrieving a value from the DOC")
def __init__(self, name): super(TransferSVR4, self).__init__(name) # Holds the list of transfer dictionaries self._transfer_list = [] # Get the reference to the data object cache self.doc = InstallEngine.get_instance().data_object_cache # Get the checkpoint info from the DOC self.soft_list = self.doc.get_descendants(name=self.name, class_type=Software) # Check that the soft_list only has one entry if len(self.soft_list) != 1: raise ValueError("Only one value for Software node must be " "specified with name " + self.name)
def get_manifest_from_doc(self): ''' Read the location of the manifest to be parsed from Data Object Cache from the element MANIFEST_PARSER_DATA. ''' ret_manifest = None # Attempt to read from DOC under MANIFEST_PARSER_DATA doc = InstallEngine.get_instance().data_object_cache if doc is not None: pm = doc.volatile.get_first_child(name=MANIFEST_PARSER_DATA) if pm is not None: ret_manifest = pm.manifest return ret_manifest
def setup_doc_content(manifest_name, media_source): '''Loads the content of media manifest into a SEPARATE DOC instance. Then, copy the data into the DOC that's used by the application, engine and other checkpoints. ''' # create a separate DOC another_doc = DataObjectCache() # load the transfer manifest into the separate DOC manifest_parser = ManifestParser("manifest-parser", manifest_name, validate_from_docinfo=False) manifest_parser.parse(doc=another_doc) software_nodes = another_doc.get_descendants(class_type=Software) if len(software_nodes) != 3: raise RuntimeError("3 software nodes expected. Only %d found" % len(software_nodes)) # Modify the install target values and the media mountpoint for software in software_nodes: # get the destination object dst_node = software.get_children(class_type=Destination, not_found_is_err=True)[0] dir_node = dst_node.get_children(class_type=Dir, not_found_is_err=True)[0] path = dir_node.dir_path path = path.replace(INSTALL_TARGET_VAR, INSTALL_TARGET) dir_node.dir_path = path # if this is the media transfer software node, also update the # value for source if software._name == TRANSFER_MEDIA: src_node = software.get_children(class_type=Source, not_found_is_err=True)[0] dir_node = src_node.get_children(class_type=Dir, not_found_is_err=True)[0] path = dir_node.dir_path path = path.replace(MEDIA_DIR_VAR, media_source) dir_node.dir_path = path # copy the Software classes into the common DOC doc = InstallEngine.get_instance().data_object_cache doc.volatile.insert_children(software_nodes)
def dc_set_http_proxy(DC_LOGGER): """ set the http_proxy and HTTP_PROXY environment variables if an http_proxy is specified in the manifest. """ eng = InstallEngine.get_instance() doc = eng.data_object_cache # get the Distro object from the DOC that contains all of the # checkpoint objects as the children distro = doc.volatile.get_descendants(class_type=Distro) if len(distro) == 0: return if distro[0].http_proxy is not None: DC_LOGGER.debug("Setting http_proxy to %s" % distro[0].http_proxy) set_http_proxy(distro[0].http_proxy) else: DC_LOGGER.debug("No http_proxy specified in the manifest")
def _show_screens(options): '''Navigate user through the set of configuration screens. Return True if user went through the complete set of screens, otherwise return False.''' with terminalui as initscr: win_size_y, win_size_x = initscr.getmaxyx() if win_size_y < 24 or win_size_x < 80: msg = _(" Terminal too small. Min size is 80x24." " Current size is %(x)ix%(y)i.") % \ {'x': win_size_x, 'y': win_size_y} sys.exit(msg) screen_list = ScreenList() actions = [Action(curses.KEY_F2, _("Continue"), screen_list.get_next), Action(curses.KEY_F3, _("Back"), screen_list.previous_screen), Action(curses.KEY_F6, _("Help"), screen_list.show_help), Action(curses.KEY_F9, _("Quit"), screen_list.quit)] main_win = MainWindow(initscr, screen_list, actions, force_bw=options.force_bw) screen_list.help = HelpScreen(main_win, _("Help Topics"), _("Help Index"), _("Select a topic and press Continue.")) win_list = _make_screen_list(main_win) screen_list.help.setup_help_data(win_list) screen_list.screen_list = win_list screen = screen_list.get_next() signal.signal(signal.SIGINT, signal.SIG_IGN) try: while screen is not None: eng = InstallEngine.get_instance() sc_prof = eng.doc.persistent.get_first_child(name="sysconfig") LOGGER.debug("Sysconfig profile:\n%s", sc_prof) LOGGER.debug("Displaying screen: %s", type(screen)) screen = screen.show() except QuitException: LOGGER.info("User quit the application prematurely.") return False else: return True