Merge "Fix naming of reset tasks and message duplication"
This commit is contained in:
commit
18eaf8718d
|
@ -259,7 +259,12 @@ TASK_NAMES = Enum(
|
||||||
'deployment',
|
'deployment',
|
||||||
'provision',
|
'provision',
|
||||||
'stop_deployment',
|
'stop_deployment',
|
||||||
|
# reset_environment supertask contains three subtasks:
|
||||||
|
# reset_nodes, remove_keys and remove_ironic_bootstrap
|
||||||
'reset_environment',
|
'reset_environment',
|
||||||
|
'reset_nodes',
|
||||||
|
'remove_keys',
|
||||||
|
'remove_ironic_bootstrap',
|
||||||
'update',
|
'update',
|
||||||
'spawn_vms',
|
'spawn_vms',
|
||||||
|
|
||||||
|
|
|
@ -50,9 +50,11 @@ def upgrade():
|
||||||
upgrade_node_nic_attributes()
|
upgrade_node_nic_attributes()
|
||||||
upgrade_node_bond_attributes()
|
upgrade_node_bond_attributes()
|
||||||
upgrade_tags_set()
|
upgrade_tags_set()
|
||||||
|
upgrade_transaction_names()
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
|
downgrade_transaction_names()
|
||||||
downgrade_tags_set()
|
downgrade_tags_set()
|
||||||
downgrade_node_bond_attributes()
|
downgrade_node_bond_attributes()
|
||||||
downgrade_node_nic_attributes()
|
downgrade_node_nic_attributes()
|
||||||
|
@ -250,6 +252,74 @@ FUEL_SECURITY_GROUPS_VERSION = '9.0'
|
||||||
# version of Fuel when DPDK hugepages was introduced
|
# version of Fuel when DPDK hugepages was introduced
|
||||||
FUEL_DPDK_HUGEPAGES_VERSION = '9.0'
|
FUEL_DPDK_HUGEPAGES_VERSION = '9.0'
|
||||||
|
|
||||||
|
TASK_NAMES_OLD = (
|
||||||
|
'super',
|
||||||
|
|
||||||
|
# Cluster changes
|
||||||
|
# For deployment supertask, it contains
|
||||||
|
# two subtasks deployment and provision
|
||||||
|
'deploy',
|
||||||
|
'deployment',
|
||||||
|
'provision',
|
||||||
|
'stop_deployment',
|
||||||
|
'reset_environment',
|
||||||
|
'update',
|
||||||
|
'spawn_vms',
|
||||||
|
|
||||||
|
'node_deletion',
|
||||||
|
'cluster_deletion',
|
||||||
|
'remove_images',
|
||||||
|
'check_before_deployment',
|
||||||
|
|
||||||
|
# network
|
||||||
|
'check_networks',
|
||||||
|
'verify_networks',
|
||||||
|
'check_dhcp',
|
||||||
|
'verify_network_connectivity',
|
||||||
|
'multicast_verification',
|
||||||
|
'check_repo_availability',
|
||||||
|
'check_repo_availability_with_setup',
|
||||||
|
'dry_run_deployment',
|
||||||
|
|
||||||
|
# dump
|
||||||
|
'dump',
|
||||||
|
|
||||||
|
'capacity_log',
|
||||||
|
|
||||||
|
# statistics
|
||||||
|
'create_stats_user',
|
||||||
|
'remove_stats_user',
|
||||||
|
|
||||||
|
# setup dhcp via dnsmasq for multi-node-groups
|
||||||
|
'update_dnsmasq'
|
||||||
|
)
|
||||||
|
|
||||||
|
TASK_NAMES_NEW = TASK_NAMES_OLD + (
|
||||||
|
'reset_nodes',
|
||||||
|
'remove_keys',
|
||||||
|
'remove_ironic_bootstrap',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_transaction_names():
|
||||||
|
migration.upgrade_enum(
|
||||||
|
'tasks',
|
||||||
|
'name',
|
||||||
|
'task_name',
|
||||||
|
TASK_NAMES_OLD,
|
||||||
|
TASK_NAMES_NEW
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade_transaction_names():
|
||||||
|
migration.upgrade_enum(
|
||||||
|
'tasks',
|
||||||
|
'name',
|
||||||
|
'task_name',
|
||||||
|
TASK_NAMES_NEW,
|
||||||
|
TASK_NAMES_OLD
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_vmware_attributes_metadata(upgrade):
|
def update_vmware_attributes_metadata(upgrade):
|
||||||
connection = op.get_bind()
|
connection = op.get_bind()
|
||||||
|
|
|
@ -796,11 +796,35 @@ class NailgunReceiver(object):
|
||||||
process, len(nodes), message)
|
process, len(nodes), message)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def reset_environment_resp(cls, **kwargs):
|
def _restore_pending_changes(cls, nodes, task, ia_nodes):
|
||||||
logger.info(
|
task.cluster.status = consts.CLUSTER_STATUSES.new
|
||||||
"RPC method reset_environment_resp received: %s",
|
objects.Cluster.add_pending_changes(
|
||||||
jsonutils.dumps(kwargs)
|
task.cluster,
|
||||||
|
consts.CLUSTER_CHANGES.attributes
|
||||||
)
|
)
|
||||||
|
objects.Cluster.add_pending_changes(
|
||||||
|
task.cluster,
|
||||||
|
consts.CLUSTER_CHANGES.networks
|
||||||
|
)
|
||||||
|
node_uids = [n["uid"] for n in itertools.chain(nodes, ia_nodes)]
|
||||||
|
q_nodes = objects.NodeCollection.filter_by_id_list(None, node_uids)
|
||||||
|
q_nodes = objects.NodeCollection.filter_by(
|
||||||
|
q_nodes,
|
||||||
|
cluster_id=task.cluster_id
|
||||||
|
)
|
||||||
|
q_nodes = objects.NodeCollection.order_by(q_nodes, 'id')
|
||||||
|
# locking Nodes for update
|
||||||
|
update_nodes = objects.NodeCollection.lock_for_update(
|
||||||
|
q_nodes
|
||||||
|
).all()
|
||||||
|
|
||||||
|
for node in update_nodes:
|
||||||
|
logs_utils.delete_node_logs(node)
|
||||||
|
objects.Node.reset_to_discover(node)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _reset_resp(cls, successful_message, restore_pending_changes=False,
|
||||||
|
**kwargs):
|
||||||
task_uuid = kwargs.get('task_uuid')
|
task_uuid = kwargs.get('task_uuid')
|
||||||
nodes = kwargs.get('nodes', [])
|
nodes = kwargs.get('nodes', [])
|
||||||
ia_nodes = kwargs.get('inaccessible_nodes', [])
|
ia_nodes = kwargs.get('inaccessible_nodes', [])
|
||||||
|
@ -813,59 +837,53 @@ class NailgunReceiver(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
if status == consts.TASK_STATUSES.ready:
|
if status == consts.TASK_STATUSES.ready:
|
||||||
# restoring pending changes
|
if restore_pending_changes:
|
||||||
task.cluster.status = consts.CLUSTER_STATUSES.new
|
cls._restore_pending_changes(nodes, task, ia_nodes)
|
||||||
objects.Cluster.add_pending_changes(
|
|
||||||
task.cluster,
|
|
||||||
consts.CLUSTER_CHANGES.attributes
|
|
||||||
)
|
|
||||||
objects.Cluster.add_pending_changes(
|
|
||||||
task.cluster,
|
|
||||||
consts.CLUSTER_CHANGES.networks
|
|
||||||
)
|
|
||||||
|
|
||||||
node_uids = [n["uid"] for n in itertools.chain(nodes, ia_nodes)]
|
|
||||||
q_nodes = objects.NodeCollection.filter_by_id_list(None, node_uids)
|
|
||||||
q_nodes = objects.NodeCollection.filter_by(
|
|
||||||
q_nodes,
|
|
||||||
cluster_id=task.cluster_id
|
|
||||||
)
|
|
||||||
q_nodes = objects.NodeCollection.order_by(q_nodes, 'id')
|
|
||||||
|
|
||||||
# locking Nodes for update
|
|
||||||
update_nodes = objects.NodeCollection.lock_for_update(
|
|
||||||
q_nodes
|
|
||||||
).all()
|
|
||||||
|
|
||||||
for node in update_nodes:
|
|
||||||
logs_utils.delete_node_logs(node)
|
|
||||||
objects.Node.reset_to_discover(node)
|
|
||||||
|
|
||||||
if ia_nodes:
|
if ia_nodes:
|
||||||
cls._notify_inaccessible(
|
cls._notify_inaccessible(
|
||||||
task.cluster_id,
|
task.cluster_id,
|
||||||
[n["uid"] for n in ia_nodes],
|
[n["uid"] for n in ia_nodes],
|
||||||
u"environment resetting"
|
u"environment resetting"
|
||||||
)
|
)
|
||||||
|
message = successful_message.format(
|
||||||
message = (
|
task.cluster.name or task.cluster_id
|
||||||
u"Environment '{0}' "
|
|
||||||
u"was successfully reset".format(
|
|
||||||
task.cluster.name or task.cluster_id
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
notifier.notify(
|
notifier.notify(
|
||||||
"done",
|
"done",
|
||||||
message,
|
message,
|
||||||
task.cluster_id
|
task.cluster_id
|
||||||
)
|
)
|
||||||
|
|
||||||
data = {'status': status, 'progress': progress, 'message': message}
|
data = {'status': status, 'progress': progress, 'message': message}
|
||||||
objects.Task.update(task, data)
|
objects.Task.update(task, data)
|
||||||
|
|
||||||
cls._update_action_log_entry(status, task.name, task_uuid, nodes)
|
cls._update_action_log_entry(status, task.name, task_uuid, nodes)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def reset_environment_resp(cls, **kwargs):
|
||||||
|
logger.info(
|
||||||
|
"RPC method reset_environment_resp received: %s",
|
||||||
|
jsonutils.dumps(kwargs)
|
||||||
|
)
|
||||||
|
message = u"Environment '{0}' was successfully reset"
|
||||||
|
cls._reset_resp(message, restore_pending_changes=True, **kwargs)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def remove_keys_resp(cls, **kwargs):
|
||||||
|
logger.info(
|
||||||
|
"RPC method remove_keys_resp received: %s",
|
||||||
|
jsonutils.dumps(kwargs)
|
||||||
|
)
|
||||||
|
message = u"Keys were removed from environment '{0}'"
|
||||||
|
cls._reset_resp(message, **kwargs)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def remove_ironic_bootstrap_resp(cls, **kwargs):
|
||||||
|
logger.info(
|
||||||
|
"RPC method remove_ironic_bootstrap_resp received: %s",
|
||||||
|
jsonutils.dumps(kwargs)
|
||||||
|
)
|
||||||
|
message = u"Ironic bootstrap was removed from environment '{0}'"
|
||||||
|
cls._reset_resp(message, **kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _notify_inaccessible(cls, cluster_id, nodes_uids, action):
|
def _notify_inaccessible(cls, cluster_id, nodes_uids, action):
|
||||||
ia_nodes_db = db().query(Node.name).filter(
|
ia_nodes_db = db().query(Node.name).filter(
|
||||||
|
|
|
@ -904,18 +904,22 @@ class ResetEnvironmentTaskManager(ClearTaskHistory):
|
||||||
db().add(supertask)
|
db().add(supertask)
|
||||||
al = TaskHelper.create_action_log(supertask)
|
al = TaskHelper.create_action_log(supertask)
|
||||||
|
|
||||||
|
reset_nodes = supertask.create_subtask(
|
||||||
|
consts.TASK_NAMES.reset_nodes
|
||||||
|
)
|
||||||
|
|
||||||
remove_keys_task = supertask.create_subtask(
|
remove_keys_task = supertask.create_subtask(
|
||||||
consts.TASK_NAMES.reset_environment
|
consts.TASK_NAMES.remove_keys
|
||||||
)
|
)
|
||||||
|
|
||||||
remove_ironic_bootstrap_task = supertask.create_subtask(
|
remove_ironic_bootstrap_task = supertask.create_subtask(
|
||||||
consts.TASK_NAMES.reset_environment
|
consts.TASK_NAMES.remove_ironic_bootstrap
|
||||||
)
|
)
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
rpc.cast('naily', [
|
rpc.cast('naily', [
|
||||||
tasks.ResetEnvironmentTask.message(supertask),
|
tasks.ResetEnvironmentTask.message(reset_nodes),
|
||||||
tasks.RemoveIronicBootstrap.message(remove_ironic_bootstrap_task),
|
tasks.RemoveIronicBootstrap.message(remove_ironic_bootstrap_task),
|
||||||
tasks.RemoveClusterKeys.message(remove_keys_task)
|
tasks.RemoveClusterKeys.message(remove_keys_task)
|
||||||
])
|
])
|
||||||
|
|
|
@ -1009,7 +1009,7 @@ class RemoveClusterKeys(object):
|
||||||
rpc_message = make_astute_message(
|
rpc_message = make_astute_message(
|
||||||
task,
|
task,
|
||||||
"execute_tasks",
|
"execute_tasks",
|
||||||
"reset_environment_resp",
|
"remove_keys_resp",
|
||||||
{
|
{
|
||||||
"tasks": [
|
"tasks": [
|
||||||
tasks_templates.make_shell_task(
|
tasks_templates.make_shell_task(
|
||||||
|
@ -1040,7 +1040,7 @@ class RemoveIronicBootstrap(object):
|
||||||
rpc_message = make_astute_message(
|
rpc_message = make_astute_message(
|
||||||
task,
|
task,
|
||||||
"execute_tasks",
|
"execute_tasks",
|
||||||
"reset_environment_resp",
|
"remove_ironic_bootstrap_resp",
|
||||||
{
|
{
|
||||||
"tasks": [
|
"tasks": [
|
||||||
tasks_templates.make_shell_task(
|
tasks_templates.make_shell_task(
|
||||||
|
|
|
@ -73,7 +73,11 @@ class TestResetEnvironment(BaseIntegrationTest):
|
||||||
cluster_db.id
|
cluster_db.id
|
||||||
)
|
)
|
||||||
tasks_after_reset = list(set([task.name for task in cluster_tasks]))
|
tasks_after_reset = list(set([task.name for task in cluster_tasks]))
|
||||||
self.assertEqual(tasks_after_reset, ['reset_environment'])
|
self.assertItemsEqual(tasks_after_reset,
|
||||||
|
['reset_environment',
|
||||||
|
'reset_nodes',
|
||||||
|
'remove_ironic_bootstrap',
|
||||||
|
'remove_keys'])
|
||||||
|
|
||||||
# FIXME(aroma): remove when stop action will be reworked for ha
|
# FIXME(aroma): remove when stop action will be reworked for ha
|
||||||
# cluster. To get more details, please, refer to [1]
|
# cluster. To get more details, please, refer to [1]
|
||||||
|
|
|
@ -1725,3 +1725,87 @@ class TestResetEnvironment(BaseReciverTestCase):
|
||||||
}
|
}
|
||||||
self.receiver.reset_environment_resp(**resp)
|
self.receiver.reset_environment_resp(**resp)
|
||||||
mock_delete_logs.assert_called_once_with(node)
|
mock_delete_logs.assert_called_once_with(node)
|
||||||
|
|
||||||
|
def test_task_message(self):
|
||||||
|
cluster = self.env.create(
|
||||||
|
cluster_kwargs={},
|
||||||
|
nodes_kwargs=[
|
||||||
|
{"api": False, "status": consts.NODE_STATUSES.ready},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
node = self.env.nodes[0]
|
||||||
|
|
||||||
|
reset_environment = Task(
|
||||||
|
uuid=str(uuid.uuid4()),
|
||||||
|
name=consts.TASK_NAMES.reset_environment,
|
||||||
|
cluster_id=cluster.id)
|
||||||
|
self.db.add(reset_environment)
|
||||||
|
self.db.flush()
|
||||||
|
|
||||||
|
reset_nodes_task = reset_environment.create_subtask(
|
||||||
|
consts.TASK_NAMES.reset_nodes
|
||||||
|
)
|
||||||
|
remove_keys_task = reset_environment.create_subtask(
|
||||||
|
consts.TASK_NAMES.remove_keys
|
||||||
|
)
|
||||||
|
remove_ironic_bootstrap_task = (
|
||||||
|
reset_environment.create_subtask(
|
||||||
|
consts.TASK_NAMES.remove_ironic_bootstrap))
|
||||||
|
self.db.flush()
|
||||||
|
|
||||||
|
reset_nodes_message = (
|
||||||
|
u"Environment '{0}' was successfully reset".format(
|
||||||
|
reset_nodes_task.cluster.name or
|
||||||
|
reset_nodes_task.cluster_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
remove_keys_message = (
|
||||||
|
u"Keys were removed from environment '{0}'").format(
|
||||||
|
remove_keys_task.cluster.name or remove_keys_task.cluster_id)
|
||||||
|
|
||||||
|
remove_ironic_bootstrap_message = (
|
||||||
|
u"Ironic bootstrap was removed from environment '{0}'").format(
|
||||||
|
remove_ironic_bootstrap_task.cluster.name or
|
||||||
|
remove_ironic_bootstrap_task.cluster_id)
|
||||||
|
|
||||||
|
reset_environment_message = (
|
||||||
|
u'\n'.join(
|
||||||
|
(reset_nodes_message, remove_keys_message,
|
||||||
|
remove_ironic_bootstrap_message)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
reset_environment_resp = {
|
||||||
|
'task_uuid': reset_nodes_task.uuid,
|
||||||
|
'status': consts.TASK_STATUSES.ready,
|
||||||
|
'nodes': [
|
||||||
|
{'uid': node.uid},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
remove_keys_resp = {
|
||||||
|
'task_uuid': remove_keys_task.uuid,
|
||||||
|
'status': consts.TASK_STATUSES.ready,
|
||||||
|
'nodes': [
|
||||||
|
{'uid': node.uid},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
remove_ironic_bootstrap_resp = {
|
||||||
|
'task_uuid': remove_ironic_bootstrap_task.uuid,
|
||||||
|
'status': consts.TASK_STATUSES.ready,
|
||||||
|
'nodes': [
|
||||||
|
{'uid': node.uid},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
self.receiver.reset_environment_resp(**reset_environment_resp)
|
||||||
|
self.receiver.remove_keys_resp(**remove_keys_resp)
|
||||||
|
self.receiver.remove_ironic_bootstrap_resp(
|
||||||
|
**remove_ironic_bootstrap_resp
|
||||||
|
)
|
||||||
|
self.assertEqual(reset_nodes_message,
|
||||||
|
reset_nodes_task.message)
|
||||||
|
self.assertEqual(remove_keys_message, remove_keys_task.message)
|
||||||
|
self.assertEqual(remove_ironic_bootstrap_message,
|
||||||
|
remove_ironic_bootstrap_task.message)
|
||||||
|
self.assertEqual(reset_environment_message,
|
||||||
|
reset_environment.message)
|
||||||
|
|
|
@ -904,3 +904,54 @@ class TestNodeNICAndBondAttributesMigration(base.BaseAlembicMigrationTest):
|
||||||
# self.assertNotIn('offloading_modes', bonds_table.c)
|
# self.assertNotIn('offloading_modes', bonds_table.c)
|
||||||
# self.assertNotIn('interface_properties', bonds_table.c)
|
# self.assertNotIn('interface_properties', bonds_table.c)
|
||||||
# self.assertNotIn('bond_properties', bonds_table.c)
|
# self.assertNotIn('bond_properties', bonds_table.c)
|
||||||
|
|
||||||
|
|
||||||
|
class TestTransactionsNames(base.BaseAlembicMigrationTest):
|
||||||
|
|
||||||
|
def test_field_reset_environment_exist(self):
|
||||||
|
db.execute(
|
||||||
|
self.meta.tables['tasks'].insert(),
|
||||||
|
[
|
||||||
|
{
|
||||||
|
'uuid': 'fake_task_uuid_0',
|
||||||
|
'name': 'reset_environment',
|
||||||
|
'status': 'pending'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_field_reset_nodes_exist(self):
|
||||||
|
db.execute(
|
||||||
|
self.meta.tables['tasks'].insert(),
|
||||||
|
[
|
||||||
|
{
|
||||||
|
'uuid': 'fake_task_uuid_0',
|
||||||
|
'name': 'reset_nodes',
|
||||||
|
'status': 'pending'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_field_remove_keys_exist(self):
|
||||||
|
db.execute(
|
||||||
|
self.meta.tables['tasks'].insert(),
|
||||||
|
[
|
||||||
|
{
|
||||||
|
'uuid': 'fake_task_uuid_0',
|
||||||
|
'name': 'remove_keys',
|
||||||
|
'status': 'pending'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_field_remove_ironic_bootstrap_exist(self):
|
||||||
|
db.execute(
|
||||||
|
self.meta.tables['tasks'].insert(),
|
||||||
|
[
|
||||||
|
{
|
||||||
|
'uuid': 'fake_task_uuid_0',
|
||||||
|
'name': 'remove_ironic_bootstrap',
|
||||||
|
'status': 'pending'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue