def _update_version_control(self, name): if self._is_component: self._vc.add(FILEPATH_MANAGER.get_component_path(name)) else: self._vc.add(FILEPATH_MANAGER.get_config_path(name)) self._vc.commit("%s modified by client" % name)
def main(): """ Parse the command line arguments and run the remote IOC server. """ parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter, description="Runs a remote IOC server.", ) parser.add_argument("--ioc_name", required=True, type=six.text_type) parser.add_argument("--pv_prefix", required=True, type=six.text_type, help="The PV prefix of this instrument.") args = parser.parse_args() FILEPATH_MANAGER.initialise(os.path.normpath(os.getenv("ICPCONFIGROOT")), "", "") print("IOC started") macros = get_macro_values() serve_forever( args.ioc_name, args.pv_prefix, macros )
def setUp(self): # Find the schema directory dir = os.path.join(".") while SCHEMA_FOLDER not in os.listdir(dir): dir = os.path.join(dir, "..") self.path = os.path.abspath(CONFIG_PATH) FILEPATH_MANAGER.initialise(self.path, os.path.join(dir, SCHEMA_FOLDER))
def setUp(self): # Find the schema directory dir = os.path.join(".") while SCHEMA_FOLDER not in os.listdir(dir): dir = os.path.join(dir, "..") self.schema_dir = os.path.join(dir, SCHEMA_FOLDER) FILEPATH_MANAGER.initialise(TEST_DIRECTORY, self.schema_dir) self.cs = ActiveConfigHolder(MACROS, ArchiverManager(None, None, MockArchiverWrapper()), MockVersionControl(), MockConfigurationFileManager(), MockIocControl(""))
def setUp(self): # Make directory and fill with fake content FILEPATH_MANAGER.initialise(os.path.abspath(CONFIG_PATH), os.path.abspath(SCHEMA_PATH)) # Find the schema directory dir = os.path.join(".") while SCHEMA_FOLDER not in os.listdir(dir): dir = os.path.join(dir, "..") self.bs = MockBlockServer() self.file_io = MockDevicesFileIO() self.dm = DevicesManager(self.bs, os.path.join(dir, SCHEMA_FOLDER), MockVersionControl(), self.file_io)
def save_config(self, configuration, is_component): """Saves the current configuration with the specified name. Args: configuration (Configuration): The actual configuration to save is_component (bool): Is it a component? """ if is_component: path = os.path.abspath(FILEPATH_MANAGER.get_component_path(configuration.get_name())) else: path = os.path.abspath(FILEPATH_MANAGER.get_config_path(configuration.get_name())) if not os.path.isdir(path): # Create the directory os.makedirs(path) blocks_xml = ConfigurationXmlConverter.blocks_to_xml(configuration.blocks, configuration.macros) groups_xml = ConfigurationXmlConverter.groups_to_xml(configuration.groups) iocs_xml = ConfigurationXmlConverter.iocs_to_xml(configuration.iocs) meta_xml = ConfigurationXmlConverter.meta_to_xml(configuration.meta) try: components_xml = ConfigurationXmlConverter.components_to_xml(configuration.components) except: # Is a component, so no components components_xml = ConfigurationXmlConverter.components_to_xml(dict()) # Save blocks with open(path + "/" + FILENAME_BLOCKS, "w") as f: f.write(blocks_xml) # Save groups with open(path + "/" + FILENAME_GROUPS, "w") as f: f.write(groups_xml) # Save IOCs with open(path + "/" + FILENAME_IOCS, "w") as f: f.write(iocs_xml) # Save components with open(path + "/" + FILENAME_COMPONENTS, "w") as f: f.write(components_xml) # Save meta with open(path + "/" + FILENAME_META, "w") as f: f.write(meta_xml)
def _add_to_version_control(self, synoptic_name, commit_message=None): # Add to version control try: self._vc.add(FILEPATH_MANAGER.get_synoptic_path(synoptic_name)) except Exception as err: raise AddToVersionControlException(err) if commit_message is not None: try: self._vc.commit(commit_message) except Exception as err: raise CommitToVersionControlException(err)
def _import_configs(self, schema_folder): # Create the pvs and get meta data config_list = self._get_config_names() comp_list = self._get_component_names() # Must load components first for them all to be known in dependencies for comp_name in comp_list: try: path = FILEPATH_MANAGER.get_component_path(comp_name) # load_config checks the schema config = self.load_config(comp_name, True) self.update_a_config_in_list(config, True) try: self._vc.add(path) except Exception as err: print_and_log("Unable to add component to version control: " + str(err), "MINOR") except Exception as err: print_and_log("Error in loading component: " + str(err), "MINOR") # Create default if it does not exist if DEFAULT_COMPONENT.lower() not in comp_list: self.file_manager.copy_default(self._comp_path) for config_name in config_list: try: path = FILEPATH_MANAGER.get_config_path(config_name) # load_config checks the schema config = self.load_config(config_name) self.update_a_config_in_list(config) try: self._vc.add(path) except Exception as err: print_and_log("Unable to add configuration to version control: " + str(err), "MINOR") except Exception as err: print_and_log("Error in loading config: " + str(err), "MINOR") # Add files to version control self._vc.commit("Blockserver started, configs updated")
def save_synoptic_xml(self, xml_data): """Saves the xml under the filename taken from the xml name tag. Args: xml_data (string): The XML to be saved """ try: # Check against schema ConfigurationSchemaChecker.check_xml_matches_schema(os.path.join(self._schema_folder, SYNOPTIC_SCHEMA_FILE), xml_data, "Synoptic") # Update PVs self._create_pv(xml_data) except Exception as err: print_and_log(err) raise name = self._get_synoptic_name_from_xml(xml_data) save_path = FILEPATH_MANAGER.get_synoptic_path(name) self._file_io.write_synoptic_file(name, save_path, xml_data) self._add_to_version_control(name, "%s modified by client" % name) print_and_log("Synoptic saved: " + name)
def setUp(self): FILEPATH_MANAGER.initialise(TEST_DIRECTORY, SCHEMA_DIR) self.file_manager = MockConfigurationFileManager() self.config_list_manager = MagicMock() self.is_component = False self.eh = ConfigFileEventHandler(RLock(), self.config_list_manager, self.is_component)
def __init__(self, ca_server): """Constructor. Args: ca_server (CAServer): The CA server used for generating PVs on the fly """ super(BlockServer, self).__init__() # Threading stuff self.monitor_lock = RLock() self.write_lock = RLock() self.write_queue = list() FILEPATH_MANAGER.initialise(CONFIG_DIR, SCHEMA_DIR) self._cas = ca_server self._gateway = Gateway(GATEWAY_PREFIX, BLOCK_PREFIX, PVLIST_FILE, MACROS["$(MYPVPREFIX)"]) self._active_configserver = None self._run_control = None self._block_cache = None self._syn = None self._devices = None self._filewatcher = None self.on_the_fly_handlers = list() self._ioc_control = IocControl(MACROS["$(MYPVPREFIX)"]) self._db_client = DatabaseServerClient(BLOCKSERVER_PREFIX + "BLOCKSERVER:") self.bumpstrip = "No" self.block_rules = BlockRules(self) self.group_rules = GroupRules(self) self.config_desc = ConfigurationDescriptionRules(self) # Connect to version control try: self._vc = GitVersionControl(CONFIG_DIR, RepoFactory.get_repo(CONFIG_DIR)) self._vc.setup() except NotUnderVersionControl as err: print_and_log("Warning: Configurations not under version control", "MINOR") self._vc = MockVersionControl() except Exception as err: print_and_log("Unable to start version control. Modifications to the instrument setup will not be " "tracked: " + str(err), "MINOR") self._vc = MockVersionControl() # Create banner object self.banner = Banner(MACROS["$(MYPVPREFIX)"]) # Import data about all configs try: self._config_list = ConfigListManager(self, SCHEMA_DIR, self._vc, ConfigurationFileManager()) except Exception as err: print_and_log( "Error creating inactive config list. Configuration list changes will not be stored " + "in version control: %s " % str(err), "MINOR") self._config_list = ConfigListManager(self, SCHEMA_DIR, MockVersionControl(), ConfigurationFileManager()) # Start a background thread for handling write commands write_thread = Thread(target=self.consume_write_queue, args=()) write_thread.daemon = True # Daemonise thread write_thread.start() with self.write_lock: self.write_queue.append((self.initialise_configserver, (FACILITY,), "INITIALISING")) # Starts the Web Server self.server = Server() self.server.start()
def setUp(self): FILEPATH_MANAGER.initialise(TEST_DIRECTORY, SCHEMA_DIR) self.file_manager = MockConfigurationFileManager() self.synoptic_manager = MagicMock() self.eh = SynopticFileEventHandler(SCHEMA_DIR, RLock(), self.synoptic_manager)
def test_synoptic_file_path_correct(self): synoptic = "test" self.assertEqual(os.path.join(self.path, SYNOPTIC_DIRECTORY, synoptic) + ".xml", FILEPATH_MANAGER.get_synoptic_path(synoptic))
def test_component_folder_path_correct(self): component = "test" self.assertEqual(os.path.join(self.path, COMPONENT_DIRECTORY, component) + os.sep, FILEPATH_MANAGER.get_component_path(component))
def test_config_folder_path_correct(self): config = "test" self.assertEqual(os.path.join(self.path, CONFIG_DIRECTORY, config) + os.sep, FILEPATH_MANAGER.get_config_path(config))
def load_config(self, name, macros, is_component): """Loads the configuration from the specified folder. Args: name (string): The name of the configuration macros (dict): The BlockServer macros is_component (bool): Is it a component? """ configuration = Configuration(macros) if is_component: path = os.path.abspath(FILEPATH_MANAGER.get_component_path(name)) else: path = os.path.abspath(FILEPATH_MANAGER.get_config_path(name)) if not os.path.isdir(path): raise IOError("Configuration could not be found: " + name) # Create empty containers blocks = OrderedDict() groups = OrderedDict() components = OrderedDict() iocs = OrderedDict() # Make sure NONE group exists groups[GRP_NONE.lower()] = Group(GRP_NONE) config_files_missing = list() # Open the block file first blocks_path = os.path.join(path, FILENAME_BLOCKS) if os.path.isfile(blocks_path): root = ElementTree.parse(blocks_path).getroot() # Check against the schema - raises if incorrect self._check_againgst_schema(ElementTree.tostring(root, encoding="utf8"), FILENAME_BLOCKS) ConfigurationXmlConverter.blocks_from_xml(root, blocks, groups) else: config_files_missing.append(FILENAME_BLOCKS) # Import the groups groups_path = os.path.join(path, FILENAME_GROUPS) if os.path.isfile(groups_path): root = ElementTree.parse(groups_path).getroot() # Check against the schema - raises if incorrect self._check_againgst_schema(ElementTree.tostring(root, encoding="utf8"), FILENAME_GROUPS) ConfigurationXmlConverter.groups_from_xml(root, groups, blocks) else: config_files_missing.append(FILENAME_GROUPS) # Import the IOCs iocs_path = os.path.join(path, FILENAME_IOCS) if os.path.isfile(iocs_path): root = ElementTree.parse(iocs_path).getroot() # There was a historic bug where the simlevel was saved as 'None' rather than "none". # Correct that here correct_xml = ElementTree.tostring(root, encoding="utf8").replace('simlevel="None"', 'simlevel="none"') # Check against the schema - raises if incorrect self._check_againgst_schema(correct_xml, FILENAME_IOCS) ConfigurationXmlConverter.ioc_from_xml(root, iocs) else: config_files_missing.append(FILENAME_IOCS) # Import the components component_path = os.path.join(path, FILENAME_COMPONENTS) if os.path.isfile(component_path): root = ElementTree.parse(component_path).getroot() # Check against the schema - raises if incorrect self._check_againgst_schema(ElementTree.tostring(root, encoding="utf8"), FILENAME_COMPONENTS) ConfigurationXmlConverter.components_from_xml(root, components) elif not is_component: # It should be missing for a component config_files_missing.append(FILENAME_COMPONENTS) # Import the metadata meta = MetaData(name) meta_path = os.path.join(path, FILENAME_META) if os.path.isfile(meta_path): root = ElementTree.parse(meta_path).getroot() # Check against the schema - raises if incorrect self._check_againgst_schema(ElementTree.tostring(root, encoding="utf8"), FILENAME_META) ConfigurationXmlConverter.meta_from_xml(root, meta) else: config_files_missing.append(FILENAME_META) if len(config_files_missing) > 0: raise ConfigurationIncompleteException( "Files missing in " + name + " (%s)" % ",".join(list(config_files_missing)) ) # Set properties in the config configuration.blocks = blocks configuration.groups = groups configuration.iocs = iocs configuration.components = components configuration.meta = meta return configuration
def _update_version_control_post_delete(self, files): for synoptic in files: self._vc.remove(FILEPATH_MANAGER.get_synoptic_path(synoptic)) self._vc.commit("Deleted %s" % ', '.join(list(files)))