RPC handler for DeleteIBPImagesTask

Add remove_images_resp handler to deal with DeleteIBPImagesTask
separetely from ClusterDeletionTask. Until now, because of the fix
of #1454781 we used only one Task instance to those two tasks
which was causing that (on astute response) the second one was already
cleaned up from db.

Change-Id: Ic686dd1da48b3b4cd679220d9c1ca05df05d105d
Closes-Bug: #1488467
This commit is contained in:
Sylwester Brzeczkowski 2015-08-28 14:43:29 +02:00
parent b564ae2011
commit 8de1595b7a
5 changed files with 76 additions and 10 deletions

View File

@ -95,7 +95,7 @@ class Task(NailgunObject):
@classmethod
def update_verify_networks(cls, instance, status,
progress, msg, result):
#TODO(dshulyak) move network tests into ostf
# TODO(dshulyak) move network tests into ostf
previous_status = instance.status
statuses = [sub.status for sub in instance.subtasks]

View File

@ -203,6 +203,23 @@ class NailgunReceiver(object):
cluster.id
)
@classmethod
def remove_images_resp(cls, **kwargs):
logger.info(
"RPC method remove_images_resp received: %s",
jsonutils.dumps(kwargs)
)
status = kwargs.get('status')
task_uuid = kwargs['task_uuid']
task = objects.Task.get_by_uuid(task_uuid)
if status == consts.TASK_STATUSES.ready:
logger.info("IBP images from deleted cluster have been removed")
elif status == consts.TASK_STATUSES.error:
logger.error("Removing IBP images failed: task_uuid %s", task_uuid)
objects.Task.update(task, {'status': status})
@classmethod
def deploy_resp(cls, **kwargs):
logger.info(

View File

@ -36,6 +36,7 @@ from nailgun.db import db
from nailgun.db.sqlalchemy.models import CapacityLog
from nailgun.db.sqlalchemy.models import Cluster
from nailgun.db.sqlalchemy.models import Node
from nailgun.db.sqlalchemy.models import Task
from nailgun.errors import errors
from nailgun.logger import logger
from nailgun.network.checker import NetworkCheck
@ -157,7 +158,7 @@ class DeploymentTask(object):
orchestrator_graph = deployment_graph.AstuteGraph(task.cluster)
orchestrator_graph.only_tasks(deployment_tasks)
#NOTE(dshulyak) At this point parts of the orchestration can be empty,
# NOTE(dshulyak) At this point parts of the orchestration can be empty,
# it should not cause any issues with deployment/progress and was
# done by design
serialized_cluster = deployment_serializers.serialize(
@ -508,7 +509,7 @@ class DeleteIBPImagesTask(object):
rpc_message = make_astute_message(
task,
'execute_tasks',
'remove_cluster_resp',
'remove_images_resp',
{
'tasks': [tasks_templates.make_shell_task([consts.MASTER_ROLE],
task_params),
@ -518,7 +519,10 @@ class DeleteIBPImagesTask(object):
return rpc_message
@classmethod
def execute(cls, task, image_data):
def execute(cls, cluster, image_data):
task = Task(name=consts.TASK_NAMES.remove_images, cluster=cluster)
db().add(task)
db().flush()
rpc.cast('naily', cls.message(task, image_data))
@ -614,10 +618,6 @@ class ClusterDeletionTask(object):
@classmethod
def execute(cls, task):
logger.debug("Cluster deletion task is running")
DeletionTask.execute(
task,
nodes=DeletionTask.get_task_nodes_for_cluster(task.cluster),
respond_to='remove_cluster_resp')
attrs = objects.Attributes.merged_attrs_values(task.cluster.attributes)
if attrs.get('provision'):
if (task.cluster.release.operating_system ==
@ -626,9 +626,14 @@ class ClusterDeletionTask(object):
consts.PROVISION_METHODS.image):
logger.debug("Delete IBP images task is running")
DeleteIBPImagesTask.execute(
task, attrs['provision']['image_data'])
task.cluster, attrs['provision']['image_data'])
else:
logger.debug("Skipping IBP images deletion task")
DeletionTask.execute(
task,
nodes=DeletionTask.get_task_nodes_for_cluster(task.cluster),
respond_to='remove_cluster_resp'
)
class BaseNetworkVerification(object):

View File

@ -1347,6 +1347,50 @@ class TestConsumer(BaseReciverTestCase):
cluster_db = self.db.query(Cluster).get(cluster_id)
self.assertIsNone(cluster_db)
def test_remove_images_resp(self):
self.env.create()
cluster_db = self.env.clusters[0]
task = Task(
name=consts.TASK_NAMES.remove_images,
cluster_id=cluster_db.id
)
self.db.add(task)
self.db.flush()
kwargs = {
'task_uuid': task.uuid,
'progress': 100,
'status': consts.TASK_STATUSES.ready,
}
self.receiver.remove_images_resp(**kwargs)
self.db().refresh(task)
self.assertEqual(consts.TASK_STATUSES.ready, task.status)
def test_remove_images_resp_failed(self):
self.env.create()
cluster_db = self.env.clusters[0]
task = Task(
name=consts.TASK_NAMES.remove_images,
cluster_id=cluster_db.id
)
self.db.add(task)
self.db.flush()
kwargs = {
'task_uuid': task.uuid,
'progress': 100,
'status': consts.TASK_STATUSES.error,
}
self.receiver.remove_images_resp(**kwargs)
self.db().refresh(task)
self.assertEqual(consts.TASK_STATUSES.error, task.status)
def test_remove_cluster_resp_failed(self):
self.env.create(
cluster_kwargs={},

View File

@ -106,7 +106,7 @@ class TestDeleteIBPImagesTask(BaseTestCase):
'/boot': {'uri': 'http://c.d/fake-boot.img'}}
task.DeleteIBPImagesTask.message(task_mock, fake_image_data)
mock_astute.assert_called_once_with(
mock.ANY, 'execute_tasks', 'remove_cluster_resp', {
mock.ANY, 'execute_tasks', 'remove_images_resp', {
'tasks': [{
'type': 'shell',
'uids': [consts.MASTER_ROLE],