def _create_nodes(self, cluster, count, policy_data): '''Utility method for node creation.''' placement = policy_data.get('placement', None) for m in range(count): name = 'node-%s-%003d' % (cluster.id[:8], cluster.size + m + 1) node = node_mod.Node(name, cluster.profile_id, cluster.id, context=self.context) if placement is not None: # We assume placement is a list node.data['placement'] = placement[m] node.store(self.context) kwargs = { 'name': 'node_create_%s' % node.id[:8], 'target': node.id, 'cause': base.CAUSE_DERIVED, } action = base.Action(self.context, 'NODE_CREATE', **kwargs) action.store(self.context) # Build dependency and make the new action ready db_api.action_add_dependency(self.context, action.id, self.id) action.set_status(self.READY) dispatcher.notify(self.context, dispatcher.Dispatcher.NEW_ACTION, None, action_id=action.id) if count > 0: # Wait for cluster creation to complete return self._wait_for_dependents() return self.RES_OK, ''
def _delete_nodes(self, cluster, nodes, policy_data): action_name = consts.NODE_DELETE pd = policy_data.get('deletion', None) if pd is not None: destroy = pd.get('destroy_after_delete', True) if not destroy: action_name = consts.NODE_LEAVE for node_id in nodes: action = base.Action(self.context, action_name, name='node_delete_%s' % node_id[:8], target=node_id, cause=base.CAUSE_DERIVED) action.store(self.context) # Build dependency and make the new action ready db_api.action_add_dependency(self.context, action.id, self.id) action.set_status(self.READY) dispatcher.notify(self.context, dispatcher.Dispatcher.NEW_ACTION, None, action_id=action.id) if len(nodes) > 0: return self._wait_for_dependents() return self.RES_OK, ''
def do_add_nodes(self, cluster, policy_data): nodes = self.inputs.get('nodes') # NOTE: node states might have changed before we lock the cluster failures = {} for node_id in nodes: try: node = node_mod.Node.load(self.context, node_id) except exception.NodeNotFound: failures[node_id] = 'Node not found' continue if node.cluster_id == cluster.id: nodes.remove(node_id) continue if node.cluster_id is not None: failures[node_id] = _('Node already owned by cluster ' '%s') % node.cluster_id continue if node.status != node_mod.Node.ACTIVE: failures[node_id] = _('Node not in ACTIVE status') continue # check profile type matching node_profile_type = node.rt['profile'].type cluster_profile_type = cluster.rt['profile'].type if node_profile_type != cluster_profile_type: failures[node.id] = 'Profile type does not match' continue if len(failures) > 0: return self.RES_ERROR, str(failures) reason = 'Completed adding nodes' if len(nodes) == 0: return self.RES_OK, reason for node_id in nodes: action = base.Action(self.context, 'NODE_JOIN', name='node_join_%s' % node.id[:8], target=node.id, cause=base.CAUSE_DERIVED, inputs={'cluster_id': cluster.id}) action.store(self.context) db_api.action_add_dependency(self.context, action.id, self.id) action.set_status(self.READY) dispatcher.notify(self.context, dispatcher.Dispatcher.NEW_ACTION, None, action_id=action.id) # Wait for dependent action if any result, new_reason = self._wait_for_dependents() if result != self.RES_OK: reason = new_reason return result, reason
def test_notify_broadcast(self, mock_rpc, mock_get_current): cfg.CONF.set_override('host', 'HOSTNAME', enforce_type=True) fake_ctx = mock.Mock() mock_get_current.return_value = fake_ctx mock_rpc.return_value = mock.Mock() dispatcher.notify('METHOD') mock_rpc.assert_called_once_with(consts.DISPATCHER_TOPIC, 'HOSTNAME') mock_client = mock_rpc.return_value mock_client.prepare.assert_called_once_with(fanout=True) mock_context = mock_client.prepare.return_value mock_context.cast.assert_called_once_with(fake_ctx, 'METHOD')
def test_notify_broadcast(self, mock_rpc, mock_get_current): fake_ctx = mock.Mock() mock_get_current.return_value = fake_ctx mock_rpc.return_value = mock.Mock() dispatcher.notify('METHOD') mock_rpc.assert_called_once_with(version=consts.RPC_API_VERSION) mock_client = mock_rpc.return_value mock_client.prepare.assert_called_once_with( version=consts.RPC_API_VERSION, topic=consts.ENGINE_DISPATCHER_TOPIC) mock_context = mock_client.prepare.return_value mock_context.call.assert_called_once_with(fake_ctx, 'METHOD')
def do_update(self, cluster, policy_data): reason = 'Cluster update succeeded' new_profile_id = self.inputs.get('new_profile_id') res = cluster.do_update(self.context, profile_id=new_profile_id) if not res: reason = 'Cluster object cannot be updated.' # Reset status to active cluster.set_status(cluster.ACTIVE, reason) return self.RES_ERROR # Create NodeActions for all nodes node_list = cluster.get_nodes() for node_id in node_list: kwargs = { 'name': 'node_update_%s' % node_id[:8], 'target': node_id, 'cause': base.CAUSE_DERIVED, 'inputs': { 'new_profile_id': new_profile_id, } } action = base.Action(self.context, 'NODE_UPDATE', **kwargs) action.store(self.context) db_api.action_add_dependency(action, self) action.set_status(self.READY) dispatcher.notify(self.context, dispatcher.Dispatcher.NEW_ACTION, None, action_id=action.id) # Wait for cluster updating complete result = self.RES_OK if cluster.size > 0: result, reason = self._wait_for_dependents() if result == self.RES_OK: cluster.set_status(self.context, cluster.ACTIVE, reason) return result, reason
def test_notify_timeout(self, mock_rpc): cfg.CONF.set_override('host', 'HOSTNAME', enforce_type=True) mock_rpc.return_value = mock.Mock() mock_client = mock_rpc.return_value mock_context = mock_client.prepare.return_value mock_context.cast.side_effect = oslo_messaging.MessagingTimeout result = dispatcher.notify('METHOD') self.assertFalse(result) mock_rpc.assert_called_once_with(consts.DISPATCHER_TOPIC, 'HOSTNAME') mock_client.prepare.assert_called_once_with(fanout=True) mock_context.cast.assert_called_once_with(mock.ANY, 'METHOD')
def test_notify_single_server(self, mock_rpc, mock_get_current): cfg.CONF.set_override('host', 'HOSTNAME', enforce_type=True) fake_ctx = mock.Mock() mock_get_current.return_value = fake_ctx mock_rpc.return_value = mock.Mock() result = dispatcher.notify('METHOD', 'FAKE_ENGINE') self.assertTrue(result) mock_rpc.assert_called_once_with(consts.DISPATCHER_TOPIC, 'HOSTNAME') mock_client = mock_rpc.return_value mock_client.prepare.assert_called_once_with(server='FAKE_ENGINE') mock_context = mock_client.prepare.return_value mock_context.cast.assert_called_once_with(fake_ctx, 'METHOD')
def test_notify_timeout(self, mock_rpc): mock_rpc.return_value = mock.Mock() mock_client = mock_rpc.return_value mock_context = mock_client.prepare.return_value mock_context.call.side_effect = oslo_messaging.MessagingTimeout result = dispatcher.notify('METHOD') self.assertFalse(result) mock_rpc.assert_called_once_with(version=consts.RPC_API_VERSION) mock_client.prepare.assert_called_once_with( version=consts.RPC_API_VERSION, topic=consts.ENGINE_DISPATCHER_TOPIC) mock_context.call.assert_called_once_with(mock.ANY, 'METHOD')
def test_notify_single_server(self, mock_rpc, mock_get_current): fake_ctx = mock.Mock() mock_get_current.return_value = fake_ctx mock_rpc.return_value = mock.Mock() result = dispatcher.notify('METHOD', 'FAKE_ENGINE') self.assertTrue(result) mock_rpc.assert_called_once_with(version=consts.RPC_API_VERSION) mock_client = mock_rpc.return_value mock_client.prepare.assert_called_once_with( version=consts.RPC_API_VERSION, topic=consts.ENGINE_DISPATCHER_TOPIC, server='FAKE_ENGINE') mock_context = mock_client.prepare.return_value mock_context.cast.assert_called_once_with(fake_ctx, 'METHOD')
def check_and_notify_retry(): action = action_mod.Action.load(context, action_id) # This is for actions with RETRY if action.status == action.READY: dispatcher.notify(context, dispatcher.Dispatcher.NEW_ACTION, None, action_id=action_id)