def delete(self, delete_list, are_comps=False):
        """Takes a list of configurations and removes them from the file system and any relevant PVs.

        Args:
            delete_list (list): The configurations/components to delete
            are_comps (bool): Whether they are components or not
        """
        with self._lock:
            # TODO: clean this up?
            print_and_log("Deleting: " + ", ".join(list(delete_list)), "INFO")
            lower_delete_list = set([x.lower() for x in delete_list])
            unable_to_remove_text = "Unable to remove %s from version control: %s"
            if not are_comps:
                if self.active_config_name.lower() in lower_delete_list:
                    raise InvalidDeleteException("Cannot delete currently active configuration")
                if not lower_delete_list.issubset(self._config_metas.keys()):
                    raise InvalidDeleteException("Delete list contains unknown configurations")
                for config in delete_list:
                    self._delete_pv(BlockserverPVNames.get_config_details_pv(self._config_metas[config.lower()].pv))
                    del self._config_metas[config.lower()]
                    self._remove_config_from_dependencies(config)
                try:
                    self._update_version_control_post_delete(self._conf_path, delete_list)  # Git is case sensitive
                except Exception as err:
                    print_and_log(unable_to_remove_text % ("configuration", str(err)), "MINOR")
            else:
                if DEFAULT_COMPONENT.lower() in lower_delete_list:
                    raise InvalidDeleteException("Cannot delete default component")
                # Only allow comps to be deleted if they appear in no configs
                for comp in lower_delete_list:
                    if self._comp_dependencies.get(comp):
                        raise InvalidDeleteException(
                            comp + " is in use in: " + ", ".join(self._comp_dependencies[comp])
                        )
                if not lower_delete_list.issubset(self._component_metas.keys()):
                    raise InvalidDeleteException("Delete list contains unknown components")
                for comp in lower_delete_list:
                    self._delete_pv(BlockserverPVNames.get_component_details_pv(self._component_metas[comp].pv))
                    self._delete_pv(BlockserverPVNames.get_dependencies_pv(self._component_metas[comp].pv))
                    del self._component_metas[comp]
                try:
                    self._update_version_control_post_delete(self._comp_path, delete_list)
                except Exception as err:
                    print_and_log(unable_to_remove_text % ("component", str(err)), "MINOR")

            self.update_monitors()
 def _update_component_dependencies_pv(self, name):
     # Updates PV with list of configs that depend on a component
     configs = []
     if name in self._comp_dependencies.keys():
         configs = self._comp_dependencies[name]
     if name in self._component_metas.keys():
         # Check just in case component failed to load
         pv_name = BlockserverPVNames.get_dependencies_pv(self._component_metas[name].pv)
         self._update_pv_value(pv_name, compress_and_hex(json.dumps(configs)))
 def _correct_pv_name(self, name):
     return BlockserverPVNames.prepend_blockserver(name)
from BlockServer.core.constants import TAG_RC_LOW, TAG_RC_HIGH, TAG_RC_ENABLE, TAG_RC_OUT_LIST
from BlockServer.core.on_the_fly_pv_interface import OnTheFlyPvInterface
from server_common.utilities import print_and_log, compress_and_hex, check_pv_name_valid, create_pv_name, \
    convert_to_json, ioc_restart_pending
from server_common.channel_access import ChannelAccess
from BlockServer.core.pv_names import BlockserverPVNames

TAG_RC_DICT = {"LOW": TAG_RC_LOW, "HIGH": TAG_RC_HIGH, "ENABLE": TAG_RC_ENABLE}
RC_IOC_PREFIX = "CS:PS:RUNCTRL_01"
RC_START_PV = "CS:IOC:RUNCTRL_01:DEVIOS:STARTTOD"
RUNCONTROL_SETTINGS = "rc_settings.cmd"
AUTOSAVE_DIR = "autosave"
RUNCONTROL_IOC = "RUNCTRL_01"

RUNCONTROL_OUT_PV = BlockserverPVNames.prepend_blockserver('GET_RC_OUT')
RUNCONTROL_GET_PV = BlockserverPVNames.prepend_blockserver('GET_RC_PARS')

# number of loops to wait for assuming the run control is not going to start
MAX_LOOPS_TO_WAIT_FOR_START = 60  # roughly 2 minutes at standard time

class RunControlManager(OnTheFlyPvInterface):
    """A class for taking care of setting up run-control.
    """

    def __init__(self, prefix, config_dir, var_dir, ioc_control, active_configholder, block_server,
                 channel_access=ChannelAccess()):
        """Constructor.

        Args:
            prefix (string): The instrument prefix
 def _update_component_pv(self, name, data):
     # Updates pvs with new data
     pv_name = BlockserverPVNames.get_component_details_pv(self._component_metas[name].pv)
     self._update_pv_value(pv_name, compress_and_hex(json.dumps(data)))