diff --git a/reddwarf/common/api.py b/reddwarf/common/api.py index cfbf5becd1..5293abef84 100644 --- a/reddwarf/common/api.py +++ b/reddwarf/common/api.py @@ -19,6 +19,7 @@ from reddwarf.common import wsgi from reddwarf.versions import VersionsController from reddwarf.flavor.service import FlavorController from reddwarf.instance.service import InstanceController +from reddwarf.extensions.mgmt.host.instance.service import HostInstanceController class API(wsgi.Router): @@ -45,6 +46,13 @@ class API(wsgi.Router): path = "/{tenant_id}/flavors" mapper.resource("flavor", path, controller=flavor_resource) + def _host_instance_router(self, mapper): + host_instance_resource = HostInstanceController().create_resource() + path = "/{tenant_id}/mgmt/hosts/{host_id}/instances" + mapper.resource("hostinstance", path, + controller=host_instance_resource, + member={'action': 'POST'}) + def app_factory(global_conf, **local_conf): return API() diff --git a/reddwarf/extensions/mgmt.py b/reddwarf/extensions/mgmt.py index c9104e8be0..de9d31fec3 100644 --- a/reddwarf/extensions/mgmt.py +++ b/reddwarf/extensions/mgmt.py @@ -21,6 +21,7 @@ from reddwarf.common import extensions from reddwarf.common import wsgi from reddwarf.extensions.mgmt.instances.service import MgmtInstanceController from reddwarf.extensions.mgmt.host.service import HostController +from reddwarf.extensions.mgmt.host.instance.service import HostInstanceController from reddwarf.extensions.mgmt.volume.service import StorageController @@ -74,4 +75,14 @@ class Mgmt(extensions.ExtensionsDescriptor): ) resources.append(storage) + host_instances = extensions.ResourceExtension('instances', + HostInstanceController(), + parent={'member_name': 'host', + 'collection_name': '{tenant_id}/mgmt/hosts'}, + deserializer=wsgi.RequestDeserializer(), + serializer=serializer, + collection_actions={'action': 'POST'}, + ) + resources.append(host_instances) + return resources diff --git a/reddwarf/extensions/mgmt/host/instance/__init__.py b/reddwarf/extensions/mgmt/host/instance/__init__.py new file mode 100644 index 0000000000..cbf4a45060 --- /dev/null +++ b/reddwarf/extensions/mgmt/host/instance/__init__.py @@ -0,0 +1,16 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. diff --git a/reddwarf/extensions/mgmt/host/instance/service.py b/reddwarf/extensions/mgmt/host/instance/service.py new file mode 100644 index 0000000000..a68a84e313 --- /dev/null +++ b/reddwarf/extensions/mgmt/host/instance/service.py @@ -0,0 +1,60 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging + +from reddwarf.common import exception +from reddwarf.common import wsgi +from reddwarf.extensions.mgmt.host import models + +LOG = logging.getLogger(__name__) + + +class HostInstanceController(wsgi.Controller): + """Controller for all instances on specific hosts.""" + + def action(self, req, body, tenant_id, host_id): + LOG.info("req : '%s'\n\n" % req) + LOG.info("Committing an ACTION against host %s for tenant '%s'" + % (host_id, tenant_id)) + if not body: + raise exception.BadRequest(_("Invalid request body.")) + context = req.environ[wsgi.CONTEXT_KEY] + host = models.DetailedHost.load(context, host_id) + _actions = { + 'update': self._action_update + } + selected_action = None + for key in body: + if key in _actions: + if selected_action is not None: + msg = _("Only one action can be specified per request.") + raise exception.BadRequest(msg) + selected_action = _actions[key] + else: + msg = _("Invalid host action: %s") % key + raise exception.BadRequest(msg) + + if selected_action: + return selected_action(context, host, body) + else: + raise exception.BadRequest(_("Invalid request body.")) + + def _action_update(self, context, host, body): + LOG.debug("Updating all instances for host: %s" % host.name) + host.update_all(context) + return wsgi.Result(None, 202) diff --git a/reddwarf/extensions/mgmt/host/models.py b/reddwarf/extensions/mgmt/host/models.py index 4087ea8340..2bbbfea5a4 100644 --- a/reddwarf/extensions/mgmt/host/models.py +++ b/reddwarf/extensions/mgmt/host/models.py @@ -77,6 +77,12 @@ class DetailedHost(object): "instance: %s" % instance['server_id']) instance['id'] = None + def update_all(self, context): + num_i = len(self.instances) + LOG.debug("Host %s has %s instances to update" % (self.name, num_i)) + for instance in self.instances: + client = create_guest_client(context, instance['id']) + client.update_guest() @staticmethod def load(context, name): diff --git a/reddwarf/guestagent/api.py b/reddwarf/guestagent/api.py index 18dd19d203..c29d8d01b7 100644 --- a/reddwarf/guestagent/api.py +++ b/reddwarf/guestagent/api.py @@ -177,3 +177,7 @@ class API(object): LOG.debug(_("Check Volume Info on Instance %s"), self.id) return self._call("get_filesystem_stats", AGENT_LOW_TIMEOUT, fs_path="/var/lib/mysql") + + def update_guest(self): + """Make a synchronous call to update the guest agent.""" + self._call("update_guest", AGENT_HIGH_TIMEOUT) diff --git a/reddwarf/tests/fakes/guestagent.py b/reddwarf/tests/fakes/guestagent.py index 387053a4b2..22b139cd51 100644 --- a/reddwarf/tests/fakes/guestagent.py +++ b/reddwarf/tests/fakes/guestagent.py @@ -44,6 +44,10 @@ class FakeGuest(object): 'threads': 2 } + def update_guest(self): + LOG.debug("Updating guest %s" % self.id) + self.version += 1 + def create_database(self, databases): for db in databases: self.dbs[db['_name']] = db