コード例 #1
0
    def test_unset_for_nonexisting_file(self, mock_logging, mock_os):
        mock_os.path = mock.MagicMock()
        mock_os.path.exists = mock.MagicMock()
        mock_os.path.exists.return_value = False

        flagfile = CMFlagFile('foo')
        self.assertFalse(flagfile)

        flagfile.unset()

        mock_os.remove.assert_not_called()
コード例 #2
0
    def test_unset_for_existing_file(self, mock_logging, mock_os):
        mock_os.path = mock.MagicMock()
        mock_os.path.exists = mock.MagicMock()
        mock_os.path.exists.return_value = True

        flagfile = CMFlagFile('foo')
        self.assertTrue(flagfile)

        flagfile.unset()

        mock_os.remove.assert_called_once_with('/mnt/config-manager/foo')
コード例 #3
0
    def test_set_for_existing_file(self, mock_logging, mock_os, mock_file):
        mock_os.path = mock.MagicMock()
        mock_os.path.exists = mock.MagicMock()
        mock_os.path.exists.return_value = True

        flagfile = CMFlagFile('foo')
        self.assertTrue(flagfile)

        flagfile.set()

        mock_file.assert_not_called()
コード例 #4
0
    def test_set_io_failure(self, mock_logging, mock_os, mock_file):
        mock_os.path = mock.MagicMock()
        mock_os.path.exists = mock.MagicMock()
        mock_os.path.exists.return_value = False

        mock_file.return_value.write.side_effect = IOError()

        flagfile = CMFlagFile('foo')
        self.assertFalse(flagfile)

        with self.assertRaises(CMError) as context:
            flagfile.set()
コード例 #5
0
    def test_set_for_nonexisting_file(self, mock_logging, mock_os, mock_file):
        mock_os.path = mock.MagicMock()
        mock_os.path.exists = mock.MagicMock()
        mock_os.path.exists.return_value = False

        flagfile = CMFlagFile('foo')
        self.assertFalse(flagfile)

        flagfile.set()

        mock_file.assert_called_with('/mnt/config-manager/foo', 'w')
        mock_file.return_value.write.assert_called_once()
コード例 #6
0
    def test_unset_io_failure(self, mock_logging, mock_os):
        mock_os.path = mock.MagicMock()
        mock_os.path.exists = mock.MagicMock()
        mock_os.path.exists.return_value = True

        flagfile = CMFlagFile('foo')
        self.assertTrue(flagfile)

        mock_os.remove.side_effect = IOError()

        with self.assertRaises(CMError) as context:
            flagfile.unset()
コード例 #7
0
    def __init__(self, backend_handler, validator, activator, changemonitor,
                 activationstate_handler, snapshot_handler):
        logging.debug('CMProcessor constructed')

        self.backend_handler = backend_handler
        self.lock = cmeventletrwlock.CMEventletRWLock()
        self.csn = cmcsn.CMCSN(self.backend_handler)
        self.validator = validator
        self.activator = activator
        self.reboot_requests = set()
        self.automatic_activation_disabled = CMFlagFile(
            'automatic_activation_disabled')
        self.changemonitor = changemonitor
        self.activationstate_handler = activationstate_handler
        self.snapshot = cmsnapshot.CMSnapshot(snapshot_handler)
コード例 #8
0
    def test_is_set_for_non_existing_file(self, mock_logging, mock_os):
        mock_os.path = mock.MagicMock()
        mock_os.path.exists = mock.MagicMock()
        mock_os.path.exists.return_value = False

        flagfile = CMFlagFile('foo')
        self.assertFalse(flagfile)
コード例 #9
0
class CMProcessor(object):
    SERVICE_GROUP_NAME = 'config-manager'

    def __init__(self, backend_handler, validator, activator, changemonitor,
                 activationstate_handler, snapshot_handler):
        logging.debug('CMProcessor constructed')

        self.backend_handler = backend_handler
        self.lock = cmeventletrwlock.CMEventletRWLock()
        self.csn = cmcsn.CMCSN(self.backend_handler)
        self.validator = validator
        self.activator = activator
        self.reboot_requests = set()
        self.automatic_activation_disabled = CMFlagFile(
            'automatic_activation_disabled')
        self.changemonitor = changemonitor
        self.activationstate_handler = activationstate_handler
        self.snapshot = cmsnapshot.CMSnapshot(snapshot_handler)

    def reboot_request(self, node_name):
        logging.debug('reboot_request called for %s', node_name)

        self.reboot_requests.add(node_name)

    def _clear_reboot_requests(self):
        logging.debug('_clear_reboot_requests called')

        self.reboot_requests.clear()

    def _raise_reboot_alarms(self):
        logging.debug('_raise_reboot_alarms called')

        reboot_request_alarm = cmalarm.CMRebootRequestAlarm()

        for node_name in self.reboot_requests:
            reboot_request_alarm.raise_alarm_for_node(node_name)

    def get_property(self, prop_name, snapshot_name=None):
        logging.debug('get_property called for %s', prop_name)

        with self.lock.reader():
            if snapshot_name:
                self.snapshot.load(snapshot_name)

                return self.snapshot.get_property(prop_name)

            return self.backend_handler.get_property(prop_name)

    def get_properties(self, prop_filter, snapshot_name=None):
        logging.debug('get_properties  called with filter %s', prop_filter)

        with self.lock.reader():
            if snapshot_name:
                self.snapshot.load(snapshot_name)

                return self.snapshot.get_properties(prop_filter)

            return self.backend_handler.get_properties(prop_filter)

    def set_property(self, prop_name, prop_value):
        logging.debug('set_property called %s=%s', prop_name, prop_value)

        props = {}
        props[prop_name] = prop_value
        return self.set_properties(props)

    def set_properties(self, props, overwrite=False):
        logging.debug('set_properties called for %s', str(props))

        with self.lock.writer():
            self._validate_set(props)
            if overwrite:
                logging.debug('Deleting old configuration data as requested')
                orig_props = self.backend_handler.get_properties('.*')
                self.backend_handler.delete_properties(orig_props.keys())
            self.backend_handler.set_properties(props)
            self.csn.increment()

        if not self.automatic_activation_disabled:
            return self._activate_set(props)

        return "0"

    def delete_property(self, prop_name):
        logging.debug('delete_property called for %s', prop_name)

        props = []
        props.append(prop_name)
        return self._delete_properties(props, None)

    def delete_properties(self, arg):
        logging.debug('delete_properties called with arg %r', arg)

        keys = []
        prop_filter = None
        if isinstance(arg, str):
            prop_filter = arg
            props = self.get_properties(prop_filter)
            keys = props.keys()
        else:
            keys = arg
        return self._delete_properties(keys, prop_filter)

    def _delete_properties(self, props, props_filter):
        logging.debug('_delete_properties called with props %s filter %s',
                      props, props_filter)

        with self.lock.writer():
            self._validate_delete(props)
            if props_filter:
                self.backend_handler.delete_properties(props_filter)
            else:
                if len(props) == 1:
                    self.backend_handler.delete_property(props[0])
                else:
                    self.backend_handler.delete_properties(props)
            self.csn.increment()

        if not self.automatic_activation_disabled:
            return self._activate_delete(props)

        return "0"

    def _validate_set(self, props):
        logging.debug('_validate_set called for %s', str(props))

        self.validator.validate_set(props)

    def _activate_set_no_lock(self, props):
        logging.debug('_activate_set_no_lock called for %s', str(props))

        uuid_value = self.changemonitor.start_change()

        work = cmactivationwork.CMActivationWork(
            cmactivationwork.CMActivationWork.OPER_SET, self.csn.get(), props)
        work.uuid_value = uuid_value
        self.activator.add_work(work)
        return uuid_value

    def _activate_set(self, props):
        logging.debug('_activate_set called')

        with self.lock.reader():
            return self._activate_set_no_lock(props)

    def _validate_delete(self, props):
        logging.debug('_validate_delete called for %s', str(props))

        self.validator.validate_delete(props)

    def _activate_delete(self, props):
        logging.debug('_activate_delete called for %s', str(props))

        with self.lock.reader():
            uuid_value = self.changemonitor.start_change()
            work = cmactivationwork.CMActivationWork(
                cmactivationwork.CMActivationWork.OPER_DELETE, self.csn.get(),
                props)
            work.uuid_value = uuid_value
            self.activator.add_work(work)
            return uuid_value

    def create_snapshot(self, snapshot_name):
        logging.debug('create_snapshot called, snapshot name is %s',
                      snapshot_name)

        with self.lock.writer():
            self.snapshot.create(snapshot_name, self.backend_handler)

    def restore_snapshot(self, snapshot_name):
        logging.debug('restore_snapshot called, snapshot name is %s',
                      snapshot_name)

        with self.lock.writer():
            self.snapshot.load(snapshot_name)

            self._validate_set(self.snapshot.get_properties())

            self.snapshot.restore(self.backend_handler)

            self.csn = cmcsn.CMCSN(self.backend_handler)

            self._activate_set_no_lock(self.snapshot.get_properties())

    def list_snapshots(self):
        logging.debug('list_snapshots called')

        snapshots = []
        with self.lock.writer():
            snapshots = self.snapshot.list()

        return snapshots

    def delete_snapshot(self, snapshot_name):
        logging.debug('delete_snapshot called, snapshot name is %s',
                      snapshot_name)

        with self.lock.writer():
            self.snapshot.delete(snapshot_name)

    def activate(self, node_name=None, startup_activation=False):
        logging.debug('activate called, node is %s', node_name)

        activation_alarm = cmalarm.CMActivationFailedAlarm()
        if node_name:
            activation_alarm.cancel_alarm_for_node(node_name)
        else:
            activation_alarm.cancel_alarm_for_sg(
                CMProcessor.SERVICE_GROUP_NAME)

        with self.lock.reader():
            uuid_value = self.changemonitor.start_change()
            if not node_name:
                work = cmactivationwork.CMActivationWork(
                    cmactivationwork.CMActivationWork.OPER_FULL,
                    self.csn.get(), {}, None, startup_activation)
            else:
                work = cmactivationwork.CMActivationWork(
                    cmactivationwork.CMActivationWork.OPER_FULL,
                    self.csn.get(), {}, node_name)
            work.uuid_value = uuid_value
            self.activator.add_work(work)

        logging.debug('activation work added, going to wait for result')
        failures = work.get_result()
        logging.debug('got activation result')

        if self.reboot_requests:
            self._raise_reboot_alarms()

        if not node_name:
            self.activationstate_handler.clear_full_failed()

        if failures:
            logging.warning('Activation failed: %s', failures)

            failed_activators = [
                activator for handler in failures.keys()
                for activator in failures[handler]
            ]

            supplementary_info = {'failed activators': failed_activators}

            if node_name:
                activation_alarm.raise_alarm_for_node(node_name,
                                                      supplementary_info)
            else:
                self.activationstate_handler.set_full_failed(failed_activators)

                activation_alarm.raise_alarm_for_sg(
                    CMProcessor.SERVICE_GROUP_NAME, supplementary_info)
        return uuid_value

    def activate_node(self, node_name):
        logging.debug('activate_node called, node name is %s', node_name)

        if self.automatic_activation_disabled:
            return False

        with self.lock.reader():
            node_csn = self.csn.get_node_csn(node_name)

            if self.csn.get() == node_csn:
                logging.info(
                    'No change in data since last translation, last csn %d',
                    self.csn.get())
                return False

            self._clear_reboot_requests()
            work = cmactivationwork.CMActivationWork(
                cmactivationwork.CMActivationWork.OPER_NODE, self.csn.get(),
                {}, node_name)
            self.activator.add_work(work)

        activation_alarm = cmalarm.CMActivationFailedAlarm()
        activation_alarm.cancel_alarm_for_node(node_name)

        failures = work.get_result()
        if failures:
            logging.warning('Activation failed: %s', failures)

            failed_activators = [
                activator for handler in failures.keys()
                for activator in failures[handler]
            ]
            supplementary_info = {'failed activators': failed_activators}
            activation_alarm.raise_alarm_for_node(node_name,
                                                  supplementary_info)

        else:
            with self.lock.writer():
                self.csn.sync_node_csn(node_name)

        return node_name in self.reboot_requests

    def set_automatic_activation_state(self, state):
        logging.debug('set_automatic_activation_state called, state is %s',
                      state)

        with self.lock.writer():
            if state:
                self.automatic_activation_disabled.unset()
            else:
                self.automatic_activation_disabled.set()