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 _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 do_add_nodes(self): """Handler for the CLUSTER_ADD_NODES action. :returns: A tuple containing the result and the corresponding reason. """ node_ids = self.inputs.get('nodes') # TODO(anyone): handle placement data errors = [] nodes = [] for node_id in node_ids: try: node = node_mod.Node.load(self.context, node_id) except exception.NodeNotFound: errors.append(_('Node [%s] is not found.') % node_id) continue if node.cluster_id is not None: errors.append(_('Node [%(n)s] is already owned by cluster ' '[%(c)s].') % {'n': node_id, 'c': node.cluster_id}) continue if node.status != node.ACTIVE: errors.append(_('Node [%s] is not in ACTIVE status.' ) % node_id) continue nodes.append(node) if len(errors) > 0: return self.RES_ERROR, ''.join(errors) reason = _('Completed adding nodes.') for node in nodes: kwargs = { 'name': 'node_join_%s' % node.id[:8], 'cause': base.CAUSE_DERIVED, 'inputs': {'cluster_id': self.target}, 'user': self.context.user, 'project': self.context.project, 'domain': self.context.domain, } action = base.Action(node.id, 'NODE_JOIN', **kwargs) action.store(self.context) db_api.action_add_dependency(self.context, action.id, self.id) action.set_status(self.READY) dispatcher.start_action(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 else: self.outputs['nodes_added'] = [node.id for node in nodes] for node in nodes: self.cluster.add_node(node) return result, reason
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 do_update(self): """Handler for CLUSTER_UPDATE action. :returns: A tuple consisting the result and the corresponding reason. """ res = self.cluster.do_update(self.context) if not res: reason = _('Cluster update failed.') self.cluster.set_status(self.context, self.cluster.ERROR, reason) return self.RES_ERROR, reason profile_id = self.inputs.get('new_profile_id') for node in self.cluster.nodes: kwargs = { 'name': 'node_update_%s' % node.id[:8], 'cause': base.CAUSE_DERIVED, 'inputs': { 'new_profile_id': profile_id, }, 'user': self.context.user, 'project': self.context.project, 'domain': self.context.domain, } action = base.Action(node.id, 'NODE_UPDATE', **kwargs) action.store(self.context) db_api.action_add_dependency(self.context, action.id, self.id) action.set_status(action.READY) dispatcher.start_action(action_id=action.id) # Wait for nodes to complete update if len(self.cluster.nodes) > 0: result, new_reason = self._wait_for_dependents() if result != self.RES_OK: self.cluster.set_status(self.context, self.cluster.WARNING, new_reason) return result, new_reason reason = _('Cluster update completed.') self.cluster.set_status(self.context, self.cluster.ACTIVE, reason, profile_id=profile_id) return self.RES_OK, reason
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 _delete_nodes(self, nodes): action_name = consts.NODE_DELETE pd = self.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: kwargs = { 'user': self.context.user, 'project': self.context.project, 'domain': self.context.domain, 'name': 'node_delete_%s' % node_id[:8], 'cause': base.CAUSE_DERIVED } action = base.Action(node_id, action_name, **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(action.READY) dispatcher.start_action(action_id=action.id) if len(nodes) > 0: res, reason = self._wait_for_dependents() if res == self.RES_OK: # TODO(anyone): avoid passing nodes in this way. self.data['nodes'] = nodes for node_id in nodes: self.cluster.remove_node(node_id) return res, reason return self.RES_OK, ''
def do_update(self): profile_id = self.inputs.get('new_profile_id') for node in self.cluster.nodes: kwargs = { 'user': self.context.user, 'project': self.context.project, 'domain': self.context.domain, 'name': 'node_update_%s' % node.id[:8], 'cause': base.CAUSE_DERIVED, 'inputs': { 'new_profile_id': profile_id, } } action = base.Action(node.id, 'NODE_UPDATE', **kwargs) action.store(self.context) db_api.action_add_dependency(self.context, action.id, self.id) action.set_status(action.READY) dispatcher.start_action(action_id=action.id) # Wait for nodes to complete update result = self.RES_OK reason = _('Cluster update completed.') if len(self.cluster.nodes) > 0: result, new_reason = self._wait_for_dependents() if result != self.RES_OK: return result, new_reason # TODO(anyone): this seems an overhead self.cluster.profile_id = profile_id self.cluster.store(self.context) self.cluster.set_status(self.context, self.cluster.ACTIVE, reason) return self.RES_OK, reason
def _delete_nodes(self, node_ids): action_name = consts.NODE_DELETE pd = self.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 node_ids: kwargs = { 'name': 'node_delete_%s' % node_id[:8], 'cause': base.CAUSE_DERIVED, 'user': self.context.user, 'project': self.context.project, 'domain': self.context.domain, } action = base.Action(node_id, action_name, **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(action.READY) dispatcher.start_action(action_id=action.id) if len(node_ids) > 0: res, reason = self._wait_for_dependents() if res == self.RES_OK: self.outputs['nodes_removed'] = node_ids for node_id in node_ids: self.cluster.remove_node(node_id) return res, reason return self.RES_OK, ''
def _create_nodes(self, count): """Utility method for node creation. :param count: Number of nodes to create. :returns: A tuple comprised of the result and reason. """ if count == 0: return self.RES_OK, '' placement = self.data.get('placement', None) nodes = [] for m in range(count): index = db_api.cluster_next_index(self.context, self.cluster.id) kwargs = { 'index': index, 'metadata': {}, 'user': self.cluster.user, 'project': self.cluster.project, 'domain': self.cluster.domain, } if placement is not None: # We assume placement is a list kwargs['data'] = {'placement': placement[m]} name = 'node-%s-%003d' % (self.cluster.id[:8], index) node = node_mod.Node(name, self.cluster.profile_id, self.cluster.id, context=self.context, **kwargs) node.store(self.context) nodes.append(node) kwargs = { 'name': 'node_create_%s' % node.id[:8], 'cause': base.CAUSE_DERIVED, 'user': self.context.user, 'project': self.context.project, 'domain': self.context.domain, } action = base.Action(node.id, '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(action.READY) dispatcher.start_action(action_id=action.id) if count > 0: # Wait for cluster creation to complete res, reason = self._wait_for_dependents() if res == self.RES_OK: self.outputs['nodes_added'] = [n.id for n in nodes] for node in nodes: self.cluster.add_node(node) return res, reason return self.RES_OK, ''
def do_add_nodes(self): """Handler for the CLUSTER_ADD_NODES action. :returns: A tuple containing the result and the corresponding reason. """ node_ids = self.inputs.get('nodes') # TODO(anyone): handle placement data errors = [] nodes = [] for node_id in node_ids: try: node = node_mod.Node.load(self.context, node_id) except exception.NodeNotFound: errors.append(_('Node [%s] is not found.') % node_id) continue if node.cluster_id == self.cluster.id: node_ids.remove(node_id) continue if node.cluster_id is not None: errors.append( _('Node [%(n)s] is already owned by cluster ' '[%(c)s].') % { 'n': node_id, 'c': node.cluster_id }) continue if node.status != node.ACTIVE: errors.append( _('Node [%s] is not in ACTIVE status.') % node_id) continue nodes.append(node) if len(errors) > 0: return self.RES_ERROR, ''.join(errors) reason = _('Completed adding nodes.') if len(node_ids) == 0: return self.RES_OK, reason for node_id in node_ids: kwargs = { 'name': 'node_join_%s' % node_id[:8], 'cause': base.CAUSE_DERIVED, 'inputs': { 'cluster_id': self.target }, 'user': self.context.user, 'project': self.context.project, 'domain': self.context.domain, } action = base.Action(node_id, 'NODE_JOIN', **kwargs) action.store(self.context) db_api.action_add_dependency(self.context, action.id, self.id) action.set_status(self.READY) dispatcher.start_action(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 else: self.outputs['nodes_added'] = node_ids for node in nodes: self.cluster.add_node(node) return result, reason