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()
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')
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()
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()
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()
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()
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 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)
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()