summaryrefslogtreecommitdiff
path: root/nova/api
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-05-21 20:23:40 +0000
committerGerrit Code Review <review@openstack.org>2018-05-21 20:23:40 +0000
commit45331d3ea185d08687e9b24e716f3d5411210874 (patch)
tree5496135b5c00a3f01dc23f77e2a9adb9e8ae3e30 /nova/api
parent75d31a8a4f1a61b63ec4d81aa4d75c527296c9c2 (diff)
parenta817b78dc44cf2cb4157531b2d92b03a4d0ca7d1 (diff)
downloadnova-45331d3ea185d08687e9b24e716f3d5411210874.tar.gz
Merge "Block deleting compute services which are hosting instances" into stable/queens
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/compute/services.py18
1 files changed, 17 insertions, 1 deletions
diff --git a/nova/api/openstack/compute/services.py b/nova/api/openstack/compute/services.py
index 07db925dea..608d783c18 100644
--- a/nova/api/openstack/compute/services.py
+++ b/nova/api/openstack/compute/services.py
@@ -24,6 +24,7 @@ from nova import availability_zones
from nova import compute
from nova import exception
from nova.i18n import _
+from nova import objects
from nova.policies import services as services_policies
from nova import servicegroup
from nova import utils
@@ -189,7 +190,7 @@ class ServiceController(wsgi.Controller):
return action(body, context)
@wsgi.response(204)
- @wsgi.expected_errors((400, 404))
+ @wsgi.expected_errors((400, 404, 409))
def delete(self, req, id):
"""Deletes the specified service."""
context = req.environ['nova.context']
@@ -211,6 +212,21 @@ class ServiceController(wsgi.Controller):
service = self.host_api.service_get_by_id(context, id)
# remove the service from all the aggregates in which it's included
if service.binary == 'nova-compute':
+ # Check to see if there are any instances on this compute host
+ # because if there are, we need to block the service (and
+ # related compute_nodes record) delete since it will impact
+ # resource accounting in Placement and orphan the compute node
+ # resource provider.
+ # TODO(mriedem): Use a COUNT SQL query-based function instead
+ # of InstanceList.get_uuids_by_host for performance.
+ instance_uuids = objects.InstanceList.get_uuids_by_host(
+ context, service['host'])
+ if instance_uuids:
+ raise webob.exc.HTTPConflict(
+ explanation=_('Unable to delete compute service that '
+ 'is hosting instances. Migrate or '
+ 'delete the instances first.'))
+
aggrs = self.aggregate_api.get_aggregates_by_host(context,
service.host)
for ag in aggrs: