summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Leafe <ed@leafe.com>2011-08-02 19:30:03 +0000
committerEd Leafe <ed@leafe.com>2011-08-02 19:30:03 +0000
commit200b6b980aada1d38014e620e025ee61c38915da (patch)
tree216b4ba5675e94c10451911c6b51ec4af234583a
parent0bd6bf4a791e03e2c1ad1715aeae3e4413705414 (diff)
parent65ba8bda43aa79080f6fec9c396f412c294718b8 (diff)
downloadnova-200b6b980aada1d38014e620e025ee61c38915da.tar.gz
nova-200b6b980aada1d38014e620e025ee61c38915da.tar.xz
nova-200b6b980aada1d38014e620e025ee61c38915da.zip
Merged trunk
-rwxr-xr-xbin/nova-instancemonitor59
-rw-r--r--bin/nova-logspool1
-rwxr-xr-xbin/nova-objectstore2
-rwxr-xr-xcontrib/nova.sh2
-rw-r--r--doc/source/api/autoindex.rst3
-rw-r--r--doc/source/api/nova..compute.monitor.rst6
-rw-r--r--doc/source/api/nova..tests.test_twistd.rst6
-rw-r--r--doc/source/api/nova..twistd.rst6
-rw-r--r--doc/source/code.rst3
-rw-r--r--doc/source/devref/architecture.rst2
-rw-r--r--doc/source/devref/compute.rst13
-rw-r--r--doc/source/devref/development.environment.rst2
-rw-r--r--doc/source/devref/nova.rst20
-rw-r--r--nova/api/openstack/create_instance_helper.py31
-rw-r--r--nova/api/openstack/images.py131
-rw-r--r--nova/api/openstack/servers.py127
-rw-r--r--nova/compute/monitor.py435
-rw-r--r--nova/tests/api/openstack/test_images.py256
-rw-r--r--nova/tests/api/openstack/test_servers.py275
-rw-r--r--nova/tests/test_twistd.py53
-rw-r--r--nova/twistd.py267
-rw-r--r--nova/virt/fake.py12
-rw-r--r--nova/virt/libvirt/connection.py12
-rw-r--r--po/ast.po59
-rw-r--r--po/cs.po59
-rw-r--r--po/da.po59
-rw-r--r--po/de.po59
-rw-r--r--po/en_AU.po59
-rw-r--r--po/en_GB.po59
-rw-r--r--po/es.po59
-rw-r--r--po/fr.po61
-rw-r--r--po/it.po60
-rw-r--r--po/ja.po59
-rw-r--r--po/nova.pot59
-rw-r--r--po/pt_BR.po60
-rw-r--r--po/ru.po59
-rw-r--r--po/tl.po59
-rw-r--r--po/uk.po59
-rw-r--r--po/zh_CN.po59
-rw-r--r--po/zh_TW.po59
-rw-r--r--setup.py1
-rw-r--r--tools/eventlet-patch24
-rw-r--r--tools/install_venv.py9
-rw-r--r--tools/pip-requires4
44 files changed, 462 insertions, 2307 deletions
diff --git a/bin/nova-instancemonitor b/bin/nova-instancemonitor
deleted file mode 100755
index b9d4e49d7..000000000
--- a/bin/nova-instancemonitor
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env python
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# 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.
-
-"""
- Daemon for Nova RRD based instance resource monitoring.
-"""
-
-import gettext
-import os
-import sys
-from twisted.application import service
-
-# If ../nova/__init__.py exists, add ../ to Python search path, so that
-# it will override what happens to be installed in /usr/(local/)lib/python...
-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
- os.pardir,
- os.pardir))
-if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
- sys.path.insert(0, possible_topdir)
-
-gettext.install('nova', unicode=1)
-
-from nova import log as logging
-from nova import utils
-from nova import twistd
-from nova.compute import monitor
-
-LOG = logging.getLogger('nova.instancemonitor')
-
-
-if __name__ == '__main__':
- utils.default_flagfile()
- twistd.serve(__file__)
-
-if __name__ == '__builtin__':
- LOG.warn(_('Starting instance monitor'))
- # pylint: disable=C0103
- monitor = monitor.InstanceMonitor()
-
- # This is the parent service that twistd will be looking for when it
- # parses this file, return it so that we can get it into globals below
- application = service.Application('nova-instancemonitor')
- monitor.setServiceParent(application)
diff --git a/bin/nova-logspool b/bin/nova-logspool
index 097459b12..a876f4c71 100644
--- a/bin/nova-logspool
+++ b/bin/nova-logspool
@@ -81,7 +81,6 @@ class LogReader(object):
if level == 'ERROR':
self.handle_logged_error(line)
elif level == '[-]' and self.last_error:
- # twisted stack trace line
clean_line = " ".join(line.split(" ")[6:])
self.last_error.trace = self.last_error.trace + clean_line
else:
diff --git a/bin/nova-objectstore b/bin/nova-objectstore
index 1aef3a255..4d5aec445 100755
--- a/bin/nova-objectstore
+++ b/bin/nova-objectstore
@@ -18,7 +18,7 @@
# under the License.
"""
- Twisted daemon for nova objectstore. Supports S3 API.
+ Daemon for nova objectstore. Supports S3 API.
"""
import gettext
diff --git a/contrib/nova.sh b/contrib/nova.sh
index eab680580..7994e5133 100755
--- a/contrib/nova.sh
+++ b/contrib/nova.sh
@@ -75,7 +75,7 @@ if [ "$CMD" == "install" ]; then
sudo modprobe kvm
sudo /etc/init.d/libvirt-bin restart
sudo modprobe nbd
- sudo apt-get install -y python-twisted python-mox python-ipy python-paste
+ sudo apt-get install -y python-mox python-ipy python-paste
sudo apt-get install -y python-migrate python-gflags python-greenlet
sudo apt-get install -y python-libvirt python-libxml2 python-routes
sudo apt-get install -y python-netaddr python-pastedeploy python-eventlet
diff --git a/doc/source/api/autoindex.rst b/doc/source/api/autoindex.rst
index 329a465db..d99d16eaa 100644
--- a/doc/source/api/autoindex.rst
+++ b/doc/source/api/autoindex.rst
@@ -26,7 +26,6 @@
nova..compute.api.rst
nova..compute.instance_types.rst
nova..compute.manager.rst
- nova..compute.monitor.rst
nova..compute.power_state.rst
nova..console.api.rst
nova..console.fake.rst
@@ -115,13 +114,11 @@
nova..tests.test_scheduler.rst
nova..tests.test_service.rst
nova..tests.test_test.rst
- nova..tests.test_twistd.rst
nova..tests.test_utils.rst
nova..tests.test_virt.rst
nova..tests.test_volume.rst
nova..tests.test_xenapi.rst
nova..tests.xenapi.stubs.rst
- nova..twistd.rst
nova..utils.rst
nova..version.rst
nova..virt.connection.rst
diff --git a/doc/source/api/nova..compute.monitor.rst b/doc/source/api/nova..compute.monitor.rst
deleted file mode 100644
index a91169ecd..000000000
--- a/doc/source/api/nova..compute.monitor.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-The :mod:`nova..compute.monitor` Module
-==============================================================================
-.. automodule:: nova..compute.monitor
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/doc/source/api/nova..tests.test_twistd.rst b/doc/source/api/nova..tests.test_twistd.rst
deleted file mode 100644
index cae0c0a28..000000000
--- a/doc/source/api/nova..tests.test_twistd.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-The :mod:`nova..tests.test_twistd` Module
-==============================================================================
-.. automodule:: nova..tests.test_twistd
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/doc/source/api/nova..twistd.rst b/doc/source/api/nova..twistd.rst
deleted file mode 100644
index d4145396d..000000000
--- a/doc/source/api/nova..twistd.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-The :mod:`nova..twistd` Module
-==============================================================================
-.. automodule:: nova..twistd
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/doc/source/code.rst b/doc/source/code.rst
index 6b8d5661f..73fc31e1a 100644
--- a/doc/source/code.rst
+++ b/doc/source/code.rst
@@ -21,7 +21,6 @@ Generating source/api/nova..cloudpipe.pipelib.rst
Generating source/api/nova..compute.disk.rst
Generating source/api/nova..compute.instance_types.rst
Generating source/api/nova..compute.manager.rst
-Generating source/api/nova..compute.monitor.rst
Generating source/api/nova..compute.power_state.rst
Generating source/api/nova..context.rst
Generating source/api/nova..crypto.rst
@@ -79,11 +78,9 @@ Generating source/api/nova..tests.rpc_unittest.rst
Generating source/api/nova..tests.runtime_flags.rst
Generating source/api/nova..tests.scheduler_unittest.rst
Generating source/api/nova..tests.service_unittest.rst
-Generating source/api/nova..tests.twistd_unittest.rst
Generating source/api/nova..tests.validator_unittest.rst
Generating source/api/nova..tests.virt_unittest.rst
Generating source/api/nova..tests.volume_unittest.rst
-Generating source/api/nova..twistd.rst
Generating source/api/nova..utils.rst
Generating source/api/nova..validate.rst
Generating source/api/nova..virt.connection.rst
diff --git a/doc/source/devref/architecture.rst b/doc/source/devref/architecture.rst
index 233cd6f08..7f44ecdf2 100644
--- a/doc/source/devref/architecture.rst
+++ b/doc/source/devref/architecture.rst
@@ -45,7 +45,7 @@ Below you will find a helpful explanation of the different components.
* Web Dashboard: potential external component that talks to the api
* api: component that receives http requests, converts commands and communicates with other components via the queue or http (in the case of objectstore)
* Auth Manager: component responsible for users/projects/and roles. Can backend to DB or LDAP. This is not a separate binary, but rather a python class that is used by most components in the system.
-* objectstore: twisted http server that replicates s3 api and allows storage and retrieval of images
+* objectstore: http server that replicates s3 api and allows storage and retrieval of images
* scheduler: decides which host gets each vm and volume
* volume: manages dynamically attachable block devices.
* network: manages ip forwarding, bridges, and vlans
diff --git a/doc/source/devref/compute.rst b/doc/source/devref/compute.rst
index 31cc2037f..50397cbec 100644
--- a/doc/source/devref/compute.rst
+++ b/doc/source/devref/compute.rst
@@ -118,19 +118,6 @@ The :mod:`nova.virt.fake` Driver
:show-inheritance:
-Monitoring
-----------
-
-The :mod:`nova.compute.monitor` Module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nova.compute.monitor
- :noindex:
- :members:
- :undoc-members:
- :show-inheritance:
-
-
Tests
-----
diff --git a/doc/source/devref/development.environment.rst b/doc/source/devref/development.environment.rst
index f3c454d64..09f1eb2c2 100644
--- a/doc/source/devref/development.environment.rst
+++ b/doc/source/devref/development.environment.rst
@@ -51,7 +51,7 @@ To activate the Nova virtualenv for the extent of your current shell session
Also, make test will automatically use the virtualenv.
-If you don't want to create a virtualenv every time you branch (which takes a while as long as we have the large Twisted project as a dependency) you can reuse a single virtualenv for all branches.
+If you don't want to create a virtualenv every time you branch you can reuse a single virtualenv for all branches.
#. If you don't have a nova/ directory containing trunk/ and other branches, do so now.
#. Go into nova/trunk and install a virtualenv.
diff --git a/doc/source/devref/nova.rst b/doc/source/devref/nova.rst
index 093fbb3ee..beca99ecd 100644
--- a/doc/source/devref/nova.rst
+++ b/doc/source/devref/nova.rst
@@ -102,16 +102,6 @@ The :mod:`nova.test` Module
:show-inheritance:
-The :mod:`nova.twistd` Module
------------------------------
-
-.. automodule:: nova.twistd
- :noindex:
- :members:
- :undoc-members:
- :show-inheritance:
-
-
The :mod:`nova.utils` Module
----------------------------
@@ -215,16 +205,6 @@ The :mod:`runtime_flags` Module
:show-inheritance:
-The :mod:`twistd_unittest` Module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nova.tests.twistd_unittest
- :noindex:
- :members:
- :undoc-members:
- :show-inheritance:
-
-
The :mod:`validator_unittest` Module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/nova/api/openstack/create_instance_helper.py b/nova/api/openstack/create_instance_helper.py
index 9199c193d..53e814cd5 100644
--- a/nova/api/openstack/create_instance_helper.py
+++ b/nova/api/openstack/create_instance_helper.py
@@ -296,6 +296,37 @@ class ServerXMLDeserializer(wsgi.MetadataXMLDeserializer):
and personality attributes
"""
+ def action(self, string):
+ dom = minidom.parseString(string)
+ action_node = dom.childNodes[0]
+ action_name = action_node.tagName
+
+ action_deserializer = {
+ 'createImage': self._action_create_image,
+ 'createBackup': self._action_create_backup,
+ }.get(action_name, self.default)
+
+ action_data = action_deserializer(action_node)
+
+ return {'body': {action_name: action_data}}
+
+ def _action_create_image(self, node):
+ return self._deserialize_image_action(node, ('name',))
+
+ def _action_create_backup(self, node):
+ attributes = ('name', 'backup_type', 'rotation')
+ return self._deserialize_image_action(node, attributes)
+
+ def _deserialize_image_action(self, node, allowed_attributes):
+ data = {}
+ for attribute in allowed_attributes:
+ value = node.getAttribute(attribute)
+ if value:
+ data[attribute] = value
+ metadata_node = self.find_first_child_named(node, 'metadata')
+ data['metadata'] = self.extract_metadata(metadata_node)
+ return data
+
def create(self, string):
"""Deserialize an xml-formatted server create request"""
dom = minidom.parseString(string)
diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py
index 9ba8b639e..0834adfa5 100644
--- a/nova/api/openstack/images.py
+++ b/nova/api/openstack/images.py
@@ -98,79 +98,34 @@ class Controller(object):
self._image_service.delete(context, id)
return webob.exc.HTTPNoContent()
- def create(self, req, body):
- """Snapshot or backup a server instance and save the image.
-
- Images now have an `image_type` associated with them, which can be
- 'snapshot' or the backup type, like 'daily' or 'weekly'.
-
- If the image_type is backup-like, then the rotation factor can be
- included and that will cause the oldest backups that exceed the
- rotation factor to be deleted.
-
- :param req: `wsgi.Request` object
- """
- def get_param(param):
- try:
- return body["image"][param]
- except KeyError:
- raise webob.exc.HTTPBadRequest(explanation="Missing required "
- "param: %s" % param)
-
- context = req.environ['nova.context']
- content_type = req.get_content_type()
-
- if not body:
- raise webob.exc.HTTPBadRequest()
-
- image_type = body["image"].get("image_type", "snapshot")
-
- try:
- server_id = self._server_id_from_req(req, body)
- except KeyError:
- raise webob.exc.HTTPBadRequest()
-
- image_name = get_param("name")
- props = self._get_extra_properties(req, body)
-
- if image_type == "snapshot":
- image = self._compute_service.snapshot(
- context, server_id, image_name,
- extra_properties=props)
- elif image_type == "backup":
- # NOTE(sirp): Unlike snapshot, backup is not a customer facing
- # API call; rather, it's used by the internal backup scheduler
- if not FLAGS.allow_admin_api:
- raise webob.exc.HTTPBadRequest(
- explanation="Admin API Required")
-
- backup_type = get_param("backup_type")
- rotation = int(get_param("rotation"))
-
- image = self._compute_service.backup(
- context, server_id, image_name,
- backup_type, rotation, extra_properties=props)
- else:
- LOG.error(_("Invalid image_type '%s' passed") % image_type)
- raise webob.exc.HTTPBadRequest(explanation="Invalue image_type: "
- "%s" % image_type)
-
- return dict(image=self.get_builder(req).build(image, detail=True))
-
def get_builder(self, request):
"""Indicates that you must use a Controller subclass."""
raise NotImplementedError()
- def _server_id_from_req(self, req, data):
- raise NotImplementedError()
-
- def _get_extra_properties(self, req, data):
- return {}
-
class ControllerV10(Controller):
"""Version 1.0 specific controller logic."""
+ def create(self, req, body):
+ """Snapshot a server instance and save the image."""
+ try:
+ image = body["image"]
+ except (KeyError, TypeError):
+ msg = _("Invalid image entity")
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+
+ try:
+ image_name = image["name"]
+ server_id = image["serverId"]
+ except KeyError as missing_key:
+ msg = _("Image entity requires %s") % missing_key
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+
+ context = req.environ["nova.context"]
+ image = self._compute_service.snapshot(context, server_id, image_name)
+
+ return dict(image=self.get_builder(req).build(image, detail=True))
+
def get_builder(self, request):
"""Property to get the ViewBuilder class we need to use."""
base_url = request.application_url
@@ -202,13 +157,6 @@ class ControllerV10(Controller):
builder = self.get_builder(req).build
return dict(images=[builder(image, detail=True) for image in images])
- def _server_id_from_req(self, req, data):
- try:
- return data['image']['serverId']
- except KeyError:
- msg = _("Expected serverId attribute on server entity.")
- raise webob.exc.HTTPBadRequest(explanation=msg)
-
class ControllerV11(Controller):
"""Version 1.1 specific controller logic."""
@@ -246,37 +194,8 @@ class ControllerV11(Controller):
builder = self.get_builder(req).build
return dict(images=[builder(image, detail=True) for image in images])
- def _server_id_from_req(self, req, data):
- try:
- server_ref = data['image']['serverRef']
- except KeyError:
- msg = _("Expected serverRef attribute on server entity.")
- raise webob.exc.HTTPBadRequest(explanation=msg)
-
- if not server_ref.startswith('http'):
- return server_ref
-
- passed = urlparse.urlparse(server_ref)
- expected = urlparse.urlparse(req.application_url)
- version = expected.path.split('/')[1]
- expected_prefix = "/%s/servers/" % version
- _empty, _sep, server_id = passed.path.partition(expected_prefix)
- scheme_ok = passed.scheme == expected.scheme
- host_ok = passed.hostname == expected.hostname
- port_ok = (passed.port == expected.port or
- passed.port == FLAGS.osapi_port)
- if not (scheme_ok and port_ok and host_ok and server_id):
- msg = _("serverRef must match request url")
- raise webob.exc.HTTPBadRequest(explanation=msg)
-
- return server_id
-
- def _get_extra_properties(self, req, data):
- server_ref = data['image']['serverRef']
- if not server_ref.startswith('http'):
- server_ref = os.path.join(req.application_url, 'servers',
- server_ref)
- return {'instance_ref': server_ref}
+ def create(self, *args, **kwargs):
+ raise webob.exc.HTTPMethodNotAllowed()
class ImageXMLSerializer(wsgi.XMLDictSerializer):
@@ -369,12 +288,6 @@ class ImageXMLSerializer(wsgi.XMLDictSerializer):
image_dict['image'])
return self.to_xml_string(node, True)
- def create(self, image_dict):
- xml_doc = minidom.Document()
- node = self._image_to_xml_detailed(xml_doc,
- image_dict['image'])
- return self.to_xml_string(node, True)
-
def create_resource(version='1.0'):
controller = {
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index 8d2ccc2ad..7b757143d 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -14,6 +14,7 @@
# under the License.
import base64
+import os
import traceback
from webob import exc
@@ -154,23 +155,95 @@ class Controller(object):
@scheduler_api.redirect_handler
def action(self, req, id, body):
- """Multi-purpose method used to reboot, rebuild, or
- resize a server"""
+ """Multi-purpose method used to take actions on a server"""
- actions = {
+ self.actions = {
'changePassword': self._action_change_password,
'reboot': self._action_reboot,
'resize': self._action_resize,
'confirmResize': self._action_confirm_resize,
'revertResize': self._action_revert_resize,
'rebuild': self._action_rebuild,
- 'migrate': self._action_migrate}
+ 'migrate': self._action_migrate,
+ 'createImage': self._action_create_image,
+ }
- for key in actions.keys():
+ if FLAGS.allow_admin_api:
+ admin_actions = {
+ 'createBackup': self._action_create_backup,
+ }
+ self.actions.update(admin_actions)
+
+ for key in self.actions.keys():
if key in body:
- return actions[key](body, req, id)
+ return self.actions[key](body, req, id)
+
raise exc.HTTPNotImplemented()
+ def _action_create_backup(self, input_dict, req, instance_id):
+ """Backup a server instance.
+
+ Images now have an `image_type` associated with them, which can be
+ 'snapshot' or the backup type, like 'daily' or 'weekly'.
+
+ If the image_type is backup-like, then the rotation factor can be
+ included and that will cause the oldest backups that exceed the
+ rotation factor to be deleted.
+
+ """
+ entity = input_dict["createBackup"]
+
+ try:
+ image_name = entity["name"]
+ backup_type = entity["backup_type"]
+ rotation = entity["rotation"]
+
+ except KeyError as missing_key:
+ msg = _("createBackup entity requires %s attribute") % missing_key
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+
+ except TypeError:
+ msg = _("Malformed createBackup entity")
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+
+ try:
+ rotation = int(rotation)
+ except ValueError:
+ msg = _("createBackup attribute 'rotation' must be an integer")
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+
+ # preserve link to server in image properties
+ server_ref = os.path.join(req.application_url,
+ 'servers',
+ str(instance_id))
+ props = {'instance_ref': server_ref}
+
+ metadata = entity.get('metadata', {})
+ try:
+ props.update(metadata)
+ except ValueError:
+ msg = _("Invalid metadata")
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+
+ context = req.environ["nova.context"]
+ image = self.compute_api.backup(context,
+ instance_id,
+ image_name,
+ backup_type,
+ rotation,
+ extra_properties=props)
+
+ # build location of newly-created image entity
+ image_id = str(image['id'])
+ image_ref = os.path.join(req.application_url, 'images', image_id)
+
+ resp = webob.Response(status_int=202)
+ resp.headers['Location'] = image_ref
+ return resp
+
+ def _action_create_image(self, input_dict, req, id):
+ return exc.HTTPNotImplemented()
+
def _action_change_password(self, input_dict, req, id):
return exc.HTTPNotImplemented()
@@ -607,6 +680,48 @@ class ControllerV11(Controller):
return webob.Response(status_int=202)
+ def _action_create_image(self, input_dict, req, instance_id):
+ """Snapshot a server instance."""
+ entity = input_dict.get("createImage", {})
+
+ try:
+ image_name = entity["name"]
+
+ except KeyError:
+ msg = _("createImage entity requires name attribute")
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+
+ except TypeError:
+ msg = _("Malformed createImage entity")
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+
+ # preserve link to server in image properties
+ server_ref = os.path.join(req.application_url,
+ 'servers',
+ str(instance_id))
+ props = {'instance_ref': server_ref}
+
+ metadata = entity.get('metadata', {})
+ try:
+ props.update(metadata)
+ except ValueError:
+ msg = _("Invalid metadata")
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+
+ context = req.environ['nova.context']
+ image = self.compute_api.snapshot(context,
+ instance_id,
+ image_name,
+ extra_properties=props)
+
+ # build location of newly-created image entity
+ image_id = str(image['id'])
+ image_ref = os.path.join(req.application_url, 'images', image_id)
+
+ resp = webob.Response(status_int=202)
+ resp.headers['Location'] = image_ref
+ return resp
+
def get_default_xmlns(self, req):
return common.XML_NS_V11
diff --git a/nova/compute/monitor.py b/nova/compute/monitor.py
deleted file mode 100644
index 9d8e2a25d..000000000
--- a/nova/compute/monitor.py
+++ /dev/null
@@ -1,435 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# 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.
-
-"""
-Instance Monitoring:
-
- Optionally may be run on each compute node. Provides RRD
- based statistics and graphs and makes them internally available
- in the object store.
-"""
-
-import datetime
-import os
-import time
-
-import boto
-import boto.s3
-import rrdtool
-from twisted.internet import task
-from twisted.application import service
-
-from nova import flags
-from nova import log as logging
-from nova import utils
-from nova.virt import connection as virt_connection
-
-
-FLAGS = flags.FLAGS
-flags.DEFINE_integer('monitoring_instances_delay', 5,
- 'Sleep time between updates')
-flags.DEFINE_integer('monitoring_instances_step', 300,
- 'Interval of RRD updates')
-flags.DEFINE_string('monitoring_rrd_path', '$state_path/monitor/instances',
- 'Location of RRD files')
-
-
-RRD_VALUES = {
- 'cpu': [
- 'DS:cpu:GAUGE:600:0:100',
- 'RRA:AVERAGE:0.5:1:800',
- 'RRA:AVERAGE:0.5:6:800',
- 'RRA:AVERAGE:0.5:24:800',
- 'RRA:AVERAGE:0.5:288:800',
- 'RRA:MAX:0.5:1:800',
- 'RRA:MAX:0.5:6:800',
- 'RRA:MAX:0.5:24:800',
- 'RRA:MAX:0.5:288:800',
- ],
- 'net': [
- 'DS:rx:COUNTER:600:0:1250000',
- 'DS:tx:COUNTER:600:0:1250000',
- 'RRA:AVERAGE:0.5:1:800',
- 'RRA:AVERAGE:0.5:6:800',
- 'RRA:AVERAGE:0.5:24:800',
- 'RRA:AVERAGE:0.5:288:800',
- 'RRA:MAX:0.5:1:800',
- 'RRA:MAX:0.5:6:800',
- 'RRA:MAX:0.5:24:800',
- 'RRA:MAX:0.5:288:800',
- ],
- 'disk': [
- 'DS:rd:COUNTER:600:U:U',
- 'DS:wr:COUNTER:600:U:U',
- 'RRA:AVERAGE:0.5:1:800',
- 'RRA:AVERAGE:0.5:6:800',
- 'RRA:AVERAGE:0.5:24:800',
- 'RRA:AVERAGE:0.5:288:800',
- 'RRA:MAX:0.5:1:800',
- 'RRA:MAX:0.5:6:800',
- 'RRA:MAX:0.5:24:800',
- 'RRA:MAX:0.5:444:800',
- ]}
-
-
-utcnow = utils.utcnow
-
-
-LOG = logging.getLogger('nova.compute.monitor')
-
-
-def update_rrd(instance, name, data):
- """
- Updates the specified RRD file.
- """
- filename = os.path.join(instance.get_rrd_path(), '%s.rrd' % name)
-
- if not os.path.exists(filename):
- init_rrd(instance, name)
-
- timestamp = int(time.mktime(utcnow().timetuple()))
- rrdtool.update(filename, '%d:%s' % (timestamp, data))
-
-
-def init_rrd(instance, name):
- """
- Initializes the specified RRD file.
- """
- path = os.path.join(FLAGS.monitoring_rrd_path, instance.instance_id)
-
- if not os.path.exists(path):
- os.makedirs(path)
-
- filename = os.path.join(path, '%s.rrd' % name)
-
- if not os.path.exists(filename):
- rrdtool.create(
- filename,
- '--step', '%d' % FLAGS.monitoring_instances_step,
- '--start', '0',
- *RRD_VALUES[name])
-
-
-def graph_cpu(instance, duration):
- """
- Creates a graph of cpu usage for the specified instance and duration.
- """
- path = instance.get_rrd_path()
- filename = os.path.join(path, 'cpu-%s.png' % duration)
-
- rrdtool.graph(
- filename,
- '--disable-rrdtool-tag',
- '--imgformat', 'PNG',
- '--width', '400',
- '--height', '120',
- '--start', 'now-%s' % duration,
- '--vertical-label', '% cpu used',
- '-l', '0',
- '-u', '100',
- 'DEF:cpu=%s:cpu:AVERAGE' % os.path.join(path, 'cpu.rrd'),
- 'AREA:cpu#eacc00:% CPU',)
-
- store_graph(instance.instance_id, filename)
-
-
-def graph_net(instance, duration):
- """
- Creates a graph of network usage for the specified instance and duration.
- """
- path = instance.get_rrd_path()
- filename = os.path.join(path, 'net-%s.png' % duration)
-
- rrdtool.graph(
- filename,
- '--disable-rrdtool-tag',
- '--imgformat', 'PNG',
- '--width', '400',
- '--height', '120',
- '--start', 'now-%s' % duration,
- '--vertical-label', 'bytes/s',
- '--logarithmic',
- '--units', 'si',
- '--lower-limit', '1000',
- '--rigid',
- 'DEF:rx=%s:rx:AVERAGE' % os.path.join(path, 'net.rrd'),
- 'DEF:tx=%s:tx:AVERAGE' % os.path.join(path, 'net.rrd'),
- 'AREA:rx#00FF00:In traffic',
- 'LINE1:tx#0000FF:Out traffic',)
-
- store_graph(instance.instance_id, filename)
-
-
-def graph_disk(instance, duration):
- """
- Creates a graph of disk usage for the specified duration.
- """
- path = instance.get_rrd_path()
- filename = os.path.join(path, 'disk-%s.png' % duration)
-
- rrdtool.graph(
- filename,
- '--disable-rrdtool-tag',
- '--imgformat', 'PNG',
- '--width', '400',
- '--height', '120',
- '--start', 'now-%s' % duration,
- '--vertical-label', 'bytes/s',
- '--logarithmic',
- '--units', 'si',
- '--lower-limit', '1000',
- '--rigid',
- 'DEF:rd=%s:rd:AVERAGE' % os.path.join(path, 'disk.rrd'),
- 'DEF:wr=%s:wr:AVERAGE' % os.path.join(path, 'disk.rrd'),
- 'AREA:rd#00FF00:Read',
- 'LINE1:wr#0000FF:Write',)
-
- store_graph(instance.instance_id, filename)
-
-
-def store_graph(instance_id, filename):
- """
- Transmits the specified graph file to internal object store on cloud
- controller.
- """
- # TODO(devcamcar): Need to use an asynchronous method to make this
- # connection. If boto has some separate method that generates
- # the request it would like to make and another method to parse
- # the response we can make our own client that does the actual
- # request and hands it off to the response parser.
- s3 = boto.s3.connection.S3Connection(
- aws_access_key_id=FLAGS.aws_access_key_id,
- aws_secret_access_key=FLAGS.aws_secret_access_key,
- is_secure=False,
- calling_format=boto.s3.connection.OrdinaryCallingFormat(),
- port=FLAGS.s3_port,
- host=FLAGS.s3_host)
- bucket_name = '_%s.monitor' % instance_id
-
- # Object store isn't creating the bucket like it should currently
- # when it is first requested, so have to catch and create manually.
- try:
- bucket = s3.get_bucket(bucket_name)
- except Exception:
- bucket = s3.create_bucket(bucket_name)
-
- key = boto.s3.Key(bucket)
- key.key = os.path.basename(filename)
- key.set_contents_from_filename(filename)
-
-
-class Instance(object):
- def __init__(self, conn, instance_id):
- self.conn = conn
- self.instance_id = instance_id
- self.last_updated = datetime.datetime.min
- self.cputime = 0
- self.cputime_last_updated = None
-
- init_rrd(self, 'cpu')
- init_rrd(self, 'net')
- init_rrd(self, 'disk')
-
- def needs_update(self):
- """
- Indicates whether this instance is due to have its statistics updated.
- """
- delta = utcnow() - self.last_updated
- return delta.seconds >= FLAGS.monitoring_instances_step
-
- def update(self):
- """
- Updates the instances statistics and stores the resulting graphs
- in the internal object store on the cloud controller.
- """
- LOG.debug(_('updating %s...'), self.instance_id)
-
- try:
- data = self.fetch_cpu_stats()
- if data is not None:
- LOG.debug('CPU: %s', data)
- update_rrd(self, 'cpu', data)
-
- data = self.fetch_net_stats()
- LOG.debug('NET: %s', data)
- update_rrd(self, 'net', data)
-
- data = self.fetch_disk_stats()
- LOG.debug('DISK: %s', data)
- update_rrd(self, 'disk', data)
-
- # TODO(devcamcar): Turn these into pool.ProcessPool.execute() calls
- # and make the methods @defer.inlineCallbacks.
- graph_cpu(self, '1d')
- graph_cpu(self, '1w')
- graph_cpu(self, '1m')
-
- graph_net(self, '1d')
- graph_net(self, '1w')
- graph_net(self, '1m')
-
- graph_disk(self, '1d')
- graph_disk(self, '1w')
- graph_disk(self, '1m')
- except Exception:
- LOG.exception(_('unexpected error during update'))
-
- self.last_updated = utcnow()
-
- def get_rrd_path(self):
- """
- Returns the path to where RRD files are stored.
- """
- return os.path.join(FLAGS.monitoring_rrd_path, self.instance_id)
-
- def fetch_cpu_stats(self):
- """
- Returns cpu usage statistics for this instance.
- """
- info = self.conn.get_info(self.instance_id)
-
- # Get the previous values.
- cputime_last = self.cputime
- cputime_last_updated = self.cputime_last_updated
-
- # Get the raw CPU time used in nanoseconds.
- self.cputime = float(info['cpu_time'])
- self.cputime_last_updated = utcnow()
-
- LOG.debug('CPU: %d', self.cputime)
-
- # Skip calculation on first pass. Need delta to get a meaningful value.
- if cputime_last_updated is None:
- return None
-
- # Calculate the number of seconds between samples.
- d = self.cputime_last_updated - cputime_last_updated
- t = d.days * 86400 + d.seconds
-
- LOG.debug('t = %d', t)
-
- # Calculate change over time in number of nanoseconds of CPU time used.
- cputime_delta = self.cputime - cputime_last
-
- LOG.debug('cputime_delta = %s', cputime_delta)
-
- # Get the number of virtual cpus in this domain.
- vcpus = int(info['num_cpu'])
-
- LOG.debug('vcpus = %d', vcpus)
-
- # Calculate CPU % used and cap at 100.
- return min(cputime_delta / (t * vcpus * 1.0e9) * 100, 100)
-
- def fetch_disk_stats(self):
- """
- Returns disk usage statistics for this instance.
- """
- rd = 0
- wr = 0
-
- disks = self.conn.get_disks(self.instance_id)
-
- # Aggregate the read and write totals.
- for disk in disks:
- try:
- rd_req, rd_bytes, wr_req, wr_bytes, errs = \
- self.conn.block_stats(self.instance_id, disk)
- rd += rd_bytes
- wr += wr_bytes
- except TypeError:
- iid = self.instance_id
- LOG.error(_('Cannot get blockstats for "%(disk)s"'
- ' on "%(iid)s"') % locals())
- raise
-
- return '%d:%d' % (rd, wr)
-
- def fetch_net_stats(self):
- """
- Returns network usage statistics for this instance.
- """
- rx = 0
- tx = 0
-
- interfaces = self.conn.get_interfaces(self.instance_id)
-
- # Aggregate the in and out totals.
- for interface in interfaces:
- try:
- stats = self.conn.interface_stats(self.instance_id, interface)
- rx += stats[0]
- tx += stats[4]
- except TypeError:
- iid = self.instance_id
- LOG.error(_('Cannot get ifstats for "%(interface)s"'
- ' on "%(iid)s"') % locals())
- raise
-
- return '%d:%d' % (rx, tx)
-
-
-class InstanceMonitor(object, service.Service):
- """
- Monitors the running instances of the current machine.
- """
-
- def __init__(self):
- """
- Initialize the monitoring loop.
- """
- self._instances = {}
- self._loop = task.LoopingCall(self.updateInstances)
-
- def startService(self):
- self._instances = {}
- self._loop.start(interval=FLAGS.monitoring_instances_delay)
- service.Service.startService(self)
-
- def stopService(self):
- self._loop.stop()
- service.Service.stopService(self)
-
- def updateInstances(self):
- """
- Update resource usage for all running instances.
- """
- try:
- conn = virt_connection.get_connection(read_only=True)
- except Exception, exn:
- LOG.exception(_('unexpected exception getting connection'))
- time.sleep(FLAGS.monitoring_instances_delay)
- return
-
- domain_ids = conn.list_instances()
- try:
- self.updateInstances_(conn, domain_ids)
- except Exception, exn:
- LOG.exception('updateInstances_')
-
- def updateInstances_(self, conn, domain_ids):
- for domain_id in domain_ids:
- if not domain_id in self._instances:
- instance = Instance(conn, domain_id)
- self._instances[domain_id] = instance
- LOG.debug(_('Found instance: %s'), domain_id)
-
- for key in self._instances.keys():
- instance = self._instances[key]
- if instance.needs_update():
- instance.update()
diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py
index 8c5ad7f8d..942c0b333 100644
--- a/nova/tests/api/openstack/test_images.py
+++ b/nova/tests/api/openstack/test_images.py
@@ -1042,82 +1042,6 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
response = req.get_response(fakes.wsgi_app())
self.assertEqual(400, response.status_int)
- def test_create_backup_no_name(self):
- """Name is also required for backups"""
- body = dict(image=dict(serverId='123', image_type='backup',
- backup_type='daily', rotation=1))
- req = webob.Request.blank('/v1.0/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
- def test_create_backup_with_rotation_and_backup_type(self):
- """The happy path for creating backups
-
- Creating a backup is an admin-only operation, as opposed to snapshots
- which are available to anybody.
- """
- # FIXME(sirp): teardown needed?
- FLAGS.allow_admin_api = True
-
- # FIXME(sirp): should the fact that backups are admin_only be a FLAG
- body = dict(image=dict(serverId='123', image_type='backup',
- name='Backup 1',
- backup_type='daily', rotation=1))
- req = webob.Request.blank('/v1.0/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(200, response.status_int)
-
- def test_create_backup_no_rotation(self):
- """Rotation is required for backup requests"""
- # FIXME(sirp): teardown needed?
- FLAGS.allow_admin_api = True
-
- # FIXME(sirp): should the fact that backups are admin_only be a FLAG
- body = dict(image=dict(serverId='123', name='daily',
- image_type='backup', backup_type='daily'))
- req = webob.Request.blank('/v1.0/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
- def test_create_backup_no_backup_type(self):
- """Backup Type (daily or weekly) is required for backup requests"""
- # FIXME(sirp): teardown needed?
- FLAGS.allow_admin_api = True
-
- # FIXME(sirp): should the fact that backups are admin_only be a FLAG
- body = dict(image=dict(serverId='123', name='daily',
- image_type='backup', rotation=1))
- req = webob.Request.blank('/v1.0/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
- def test_create_image_with_invalid_image_type(self):
- """Valid image_types are snapshot | daily | weekly"""
- # FIXME(sirp): teardown needed?
- FLAGS.allow_admin_api = True
-
- # FIXME(sirp): should the fact that backups are admin_only be a FLAG
- body = dict(image=dict(serverId='123', image_type='monthly',
- rotation=1))
- req = webob.Request.blank('/v1.0/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
def test_create_image_no_server_id(self):
body = dict(image=dict(name='Snapshot 1'))
@@ -1128,113 +1052,6 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
response = req.get_response(fakes.wsgi_app())
self.assertEqual(400, response.status_int)
- def test_create_image_v1_1(self):
-
- body = dict(image=dict(serverRef='123', name='Snapshot 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(200, response.status_int)
-
- def test_create_image_v1_1_actual_server_ref(self):
-
- serverRef = 'http://localhost/v1.1/servers/1'
- serverBookmark = 'http://localhost/servers/1'
- body = dict(image=dict(serverRef=serverRef, name='Backup 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(200, response.status_int)
- result = json.loads(response.body)
- expected = {
- 'id': 1,
- 'links': [
- {
- 'rel': 'self',
- 'href': serverRef,
- },
- {
- 'rel': 'bookmark',
- 'href': serverBookmark,
- },
- ]
- }
- self.assertEqual(result['image']['server'], expected)
-
- def test_create_image_v1_1_actual_server_ref_port(self):
-
- serverRef = 'http://localhost:8774/v1.1/servers/1'
- serverBookmark = 'http://localhost:8774/servers/1'
- body = dict(image=dict(serverRef=serverRef, name='Backup 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(200, response.status_int)
- result = json.loads(response.body)
- expected = {
- 'id': 1,
- 'links': [
- {
- 'rel': 'self',
- 'href': serverRef,
- },
- {
- 'rel': 'bookmark',
- 'href': serverBookmark,
- },
- ]
- }
- self.assertEqual(result['image']['server'], expected)
-
- def test_create_image_v1_1_server_ref_bad_hostname(self):
-
- serverRef = 'http://asdf/v1.1/servers/1'
- body = dict(image=dict(serverRef=serverRef, name='Backup 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
- def test_create_image_v1_1_no_server_ref(self):
-
- body = dict(image=dict(name='Snapshot 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
- def test_create_image_v1_1_server_ref_missing_version(self):
-
- serverRef = 'http://localhost/servers/1'
- body = dict(image=dict(serverRef=serverRef, name='Backup 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
- def test_create_image_v1_1_server_ref_missing_id(self):
-
- serverRef = 'http://localhost/v1.1/servers'
- body = dict(image=dict(serverRef=serverRef, name='Backup 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
@classmethod
def _make_image_fixtures(cls):
image_id = 123
@@ -1713,76 +1530,3 @@ class ImageXMLSerializationTest(test.TestCase):
""".replace(" ", "") % (locals()))
self.assertEqual(expected.toxml(), actual.toxml())
-
- def test_create(self):
- serializer = images.ImageXMLSerializer()
-
- fixture = {
- 'image': {
- 'id': 1,
- 'name': 'Image1',
- 'created': self.TIMESTAMP,
- 'updated': self.TIMESTAMP,
- 'status': 'SAVING',
- 'progress': 80,
- 'server': {
- 'id': 1,
- 'links': [
- {
- 'href': self.SERVER_HREF,
- 'rel': 'self',
- },
- {
- 'href': self.SERVER_BOOKMARK,
- 'rel': 'bookmark',
- },
- ],
- },
- 'metadata': {
- 'key1': 'value1',
- },
- 'links': [
- {
- 'href': self.IMAGE_HREF % 1,
- 'rel': 'self',
- },
- {
- 'href': self.IMAGE_BOOKMARK % 1,
- 'rel': 'bookmark',
- },
- ],
- },
- }
-
- output = serializer.serialize(fixture, 'create')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected_server_href = self.SERVER_HREF
- expected_server_bookmark = self.SERVER_BOOKMARK
- expected_href = self.IMAGE_HREF % 1
- expected_bookmark = self.IMAGE_BOOKMARK % 1
- expected_now = self.TIMESTAMP
- expected = minidom.parseString("""
- <image id="1"
- xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom"
- name="Image1"
- updated="%(expected_now)s"
- created="%(expected_now)s"
- status="SAVING"
- progress="80">
- <server id="1">
- <atom:link rel="self" href="%(expected_server_href)s"/>
- <atom:link rel="bookmark" href="%(expected_server_bookmark)s"/>
- </server>
- <metadata>
- <meta key="key1">
- value1
- </meta>
- </metadata>
- <atom:link href="%(expected_href)s" rel="self"/>
- <atom:link href="%(expected_bookmark)s" rel="bookmark"/>
- </image>
- """.replace(" ", "") % (locals()))
-
- self.assertEqual(expected.toxml(), actual.toxml())
diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py
index 14ce42837..1871cac96 100644
--- a/nova/tests/api/openstack/test_servers.py
+++ b/nova/tests/api/openstack/test_servers.py
@@ -260,6 +260,17 @@ class ServersTest(test.TestCase):
self.stubs.Set(nova.compute.API, "get_diagnostics", fake_compute_api)
self.stubs.Set(nova.compute.API, "get_actions", fake_compute_api)
+ fakes.stub_out_glance(self.stubs)
+ fakes.stub_out_compute_api_snapshot(self.stubs)
+ service_class = 'nova.image.glance.GlanceImageService'
+ self.service = utils.import_object(service_class)
+ self.context = context.RequestContext(1, None)
+ self.service.delete_all()
+ self.sent_to_glance = {}
+ fakes.stub_out_glance_add_image(self.stubs, self.sent_to_glance)
+
+ self.allow_admin = FLAGS.allow_admin_api
+
self.webreq = common.webob_factory('/v1.0/servers')
def test_get_server_by_id(self):
@@ -2346,6 +2357,268 @@ class ServersTest(test.TestCase):
res_dict = json.loads(res.body)
self.assertEqual(res_dict['server']['status'], 'SHUTOFF')
+ def test_create_image_v1_1(self):
+ body = {
+ 'createImage': {
+ 'name': 'Snapshot 1',
+ },
+ }
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(202, response.status_int)
+ location = response.headers['Location']
+ self.assertEqual('http://localhost/v1.1/images/123', location)
+
+ def test_create_image_v1_1_with_metadata(self):
+ body = {
+ 'createImage': {
+ 'name': 'Snapshot 1',
+ 'metadata': {'key': 'asdf'},
+ },
+ }
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(202, response.status_int)
+ location = response.headers['Location']
+ self.assertEqual('http://localhost/v1.1/images/123', location)
+
+ def test_create_image_v1_1_no_name(self):
+ body = {
+ 'createImage': {},
+ }
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
+ def test_create_image_v1_1_bad_metadata(self):
+ body = {
+ 'createImage': {
+ 'name': 'geoff',
+ 'metadata': 'henry',
+ },
+ }
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
+ def test_create_backup(self):
+ """The happy path for creating backups"""
+ FLAGS.allow_admin_api = True
+
+ body = {
+ 'createBackup': {
+ 'name': 'Backup 1',
+ 'backup_type': 'daily',
+ 'rotation': 1,
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(202, response.status_int)
+ self.assertTrue(response.headers['Location'])
+
+ def test_create_backup_v1_1(self):
+ """The happy path for creating backups through v1.1 api"""
+ FLAGS.allow_admin_api = True
+
+ body = {
+ 'createBackup': {
+ 'name': 'Backup 1',
+ 'backup_type': 'daily',
+ 'rotation': 1,
+ },
+ }
+
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(202, response.status_int)
+ self.assertTrue(response.headers['Location'])
+
+ def test_create_backup_admin_api_off(self):
+ """The happy path for creating backups"""
+ FLAGS.allow_admin_api = False
+
+ body = {
+ 'createBackup': {
+ 'name': 'Backup 1',
+ 'backup_type': 'daily',
+ 'rotation': 1,
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(501, response.status_int)
+
+ def test_create_backup_with_metadata(self):
+ FLAGS.allow_admin_api = True
+
+ body = {
+ 'createBackup': {
+ 'name': 'Backup 1',
+ 'backup_type': 'daily',
+ 'rotation': 1,
+ 'metadata': {'123': 'asdf'},
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(202, response.status_int)
+ self.assertTrue(response.headers['Location'])
+
+ def test_create_backup_no_name(self):
+ """Name is required for backups"""
+ FLAGS.allow_admin_api = True
+
+ body = {
+ 'createBackup': {
+ 'backup_type': 'daily',
+ 'rotation': 1,
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/images')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
+ def test_create_backup_no_rotation(self):
+ """Rotation is required for backup requests"""
+ FLAGS.allow_admin_api = True
+
+ body = {
+ 'createBackup': {
+ 'name': 'Backup 1',
+ 'backup_type': 'daily',
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/images')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
+ def test_create_backup_no_backup_type(self):
+ """Backup Type (daily or weekly) is required for backup requests"""
+ FLAGS.allow_admin_api = True
+
+ body = {
+ 'createBackup': {
+ 'name': 'Backup 1',
+ 'rotation': 1,
+ },
+ }
+ req = webob.Request.blank('/v1.0/images')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
+ def test_create_backup_bad_entity(self):
+ FLAGS.allow_admin_api = True
+
+ body = {'createBackup': 'go'}
+ req = webob.Request.blank('/v1.0/images')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
+
+class TestServerActionXMLDeserializer(test.TestCase):
+
+ def setUp(self):
+ self.deserializer = create_instance_helper.ServerXMLDeserializer()
+
+ def tearDown(self):
+ pass
+
+ def test_create_image(self):
+ serial_request = """
+<createImage xmlns="http://docs.openstack.org/compute/api/v1.1"
+ name="new-server-test"/>"""
+ request = self.deserializer.deserialize(serial_request, 'action')
+ expected = {
+ "createImage": {
+ "name": "new-server-test",
+ "metadata": {},
+ },
+ }
+ self.assertEquals(request['body'], expected)
+
+ def test_create_image_with_metadata(self):
+ serial_request = """
+<createImage xmlns="http://docs.openstack.org/compute/api/v1.1"
+ name="new-server-test">
+ <metadata>
+ <meta key="key1">value1</meta>
+ </metadata>
+</createImage>"""
+ request = self.deserializer.deserialize(serial_request, 'action')
+ expected = {
+ "createImage": {
+ "name": "new-server-test",
+ "metadata": {"key1": "value1"},
+ },
+ }
+ self.assertEquals(request['body'], expected)
+
+ def test_create_backup_with_metadata(self):
+ serial_request = """
+<createBackup xmlns="http://docs.openstack.org/compute/api/v1.1"
+ name="new-server-test"
+ rotation="12"
+ backup_type="daily">
+ <metadata>
+ <meta key="key1">value1</meta>
+ </metadata>
+</createBackup>"""
+ request = self.deserializer.deserialize(serial_request, 'action')
+ expected = {
+ "createBackup": {
+ "name": "new-server-test",
+ "rotation": "12",
+ "backup_type": "daily",
+ "metadata": {"key1": "value1"},
+ },
+ }
+ self.assertEquals(request['body'], expected)
+
class TestServerCreateRequestXMLDeserializerV10(unittest.TestCase):
@@ -2815,7 +3088,7 @@ class TestServerCreateRequestXMLDeserializerV11(unittest.TestCase):
self.assertEquals(request['body'], expected)
-class TextAddressesXMLSerialization(test.TestCase):
+class TestAddressesXMLSerialization(test.TestCase):
serializer = nova.api.openstack.ips.IPXMLSerializer()
diff --git a/nova/tests/test_twistd.py b/nova/tests/test_twistd.py
deleted file mode 100644
index ff8627c3b..000000000
--- a/nova/tests/test_twistd.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# 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 StringIO
-import sys
-
-from nova import twistd
-from nova import exception
-from nova import flags
-from nova import test
-
-
-FLAGS = flags.FLAGS
-
-
-class TwistdTestCase(test.TestCase):
- def setUp(self):
- super(TwistdTestCase, self).setUp()
- self.Options = twistd.WrapTwistedOptions(twistd.TwistdServerOptions)
- sys.stdout = StringIO.StringIO()
-
- def tearDown(self):
- super(TwistdTestCase, self).tearDown()
- sys.stdout = sys.__stdout__
-
- def test_basic(self):
- options = self.Options()
- argv = options.parseOptions()
-
- def test_logfile(self):
- options = self.Options()
- argv = options.parseOptions(['--logfile=foo'])
- self.assertEqual(FLAGS.logfile, 'foo')
-
- def test_help(self):
- options = self.Options()
- self.assertRaises(SystemExit, options.parseOptions, ['--help'])
- self.assert_('pidfile' in sys.stdout.getvalue())
diff --git a/nova/twistd.py b/nova/twistd.py
deleted file mode 100644
index 15cf67825..000000000
--- a/nova/twistd.py
+++ /dev/null
@@ -1,267 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# 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.
-
-"""
-Twisted daemon helpers, specifically to parse out gFlags from twisted flags,
-manage pid files and support syslogging.
-"""
-
-import gflags
-import os
-import signal
-import sys
-import time
-from twisted.scripts import twistd
-from twisted.python import log
-from twisted.python import reflect
-from twisted.python import runtime
-from twisted.python import usage
-
-from nova import flags
-from nova import log as logging
-
-
-if runtime.platformType == "win32":
- from twisted.scripts._twistw import ServerOptions
-else:
- from twisted.scripts._twistd_unix import ServerOptions
-
-
-FLAGS = flags.FLAGS
-
-
-class TwistdServerOptions(ServerOptions):
- def parseArgs(self, *args):
- return
-
-
-class FlagParser(object):
- # this is a required attribute for gflags
- syntactic_help = ''
-
- def __init__(self, parser):
- self.parser = parser
-
- def Parse(self, s):
- return self.parser(s)
-
-
-def WrapTwistedOptions(wrapped):
- class TwistedOptionsToFlags(wrapped):
- subCommands = None
-
- def __init__(self):
- # NOTE(termie): _data exists because Twisted stuff expects
- # to be able to set arbitrary things that are
- # not actual flags
- self._data = {}
- self._flagHandlers = {}
- self._paramHandlers = {}
-
- # Absorb the twistd flags into our FLAGS
- self._absorbFlags()
- self._absorbParameters()
- self._absorbHandlers()
-
- wrapped.__init__(self)
-
- def _absorbFlags(self):
- twistd_flags = []
- reflect.accumulateClassList(self.__class__, 'optFlags',
- twistd_flags)
- for flag in twistd_flags:
- key = flag[0].replace('-', '_')
- if hasattr(FLAGS, key):
- continue
- flags.DEFINE_boolean(key, None, str(flag[-1]))
-
- def _absorbParameters(self):
- twistd_params = []
- reflect.accumulateClassList(self.__class__, 'optParameters',
- twistd_params)
- for param in twistd_params:
- key = param[0].replace('-', '_')
- if hasattr(FLAGS, key):
- continue
- if len(param) > 4:
- flags.DEFINE(FlagParser(param[4]),
- key, param[2], str(param[3]),
- serializer=gflags.ArgumentSerializer())
- else:
- flags.DEFINE_string(key, param[2], str(param[3]))
-
- def _absorbHandlers(self):
- twistd_handlers = {}
- reflect.addMethodNamesToDict(self.__class__, twistd_handlers,
- "opt_")
-
- # NOTE(termie): Much of the following is derived/copied from
- # twisted.python.usage with the express purpose of
- # providing compatibility
- for name in twistd_handlers.keys():
- method = getattr(self, 'opt_' + name)
-
- takesArg = not usage.flagFunction(method, name)
- doc = getattr(method, '__doc__', None)
- if not doc:
- doc = 'undocumented'
-
- if not takesArg:
- if name not in FLAGS:
- flags.DEFINE_boolean(name, None, doc)
- self._flagHandlers[name] = method
- else:
- if name not in FLAGS:
- flags.DEFINE_string(name, None, doc)
- self._paramHandlers[name] = method
-
- def _doHandlers(self):
- for flag, handler in self._flagHandlers.iteritems():
- if self[flag]:
- handler()
- for param, handler in self._paramHandlers.iteritems():
- if self[param] is not None:
- handler(self[param])
-
- def __str__(self):
- return str(FLAGS)
-
- def parseOptions(self, options=None):
- if options is None:
- options = sys.argv
- else:
- options.insert(0, '')
-
- args = FLAGS(options)
- logging.setup()
- argv = args[1:]
- # ignore subcommands
-
- try:
- self.parseArgs(*argv)
- except TypeError:
- raise usage.UsageError(_("Wrong number of arguments."))
-
- self.postOptions()
- return args
-
- def parseArgs(self, *args):
- # TODO(termie): figure out a decent way of dealing with args
- #return
- wrapped.parseArgs(self, *args)
-
- def postOptions(self):
- self._doHandlers()
-
- wrapped.postOptions(self)
-
- def __getitem__(self, key):
- key = key.replace('-', '_')
- try:
- return getattr(FLAGS, key)
- except (AttributeError, KeyError):
- return self._data[key]
-
- def __setitem__(self, key, value):
- key = key.replace('-', '_')
- try:
- return setattr(FLAGS, key, value)
- except (AttributeError, KeyError):
- self._data[key] = value
-
- def get(self, key, default):
- key = key.replace('-', '_')
- try:
- return getattr(FLAGS, key)
- except (AttributeError, KeyError):
- self._data.get(key, default)
-
- return TwistedOptionsToFlags
-
-
-def stop(pidfile):
- """
- Stop the daemon
- """
- # Get the pid from the pidfile
- try:
- pf = file(pidfile, 'r')
- pid = int(pf.read().strip())
- pf.close()
- except IOError:
- pid = None
-
- if not pid:
- message = _("pidfile %s does not exist. Daemon not running?\n")
- sys.stderr.write(message % pidfile)
- # Not an error in a restart
- return
-
- # Try killing the daemon process
- try:
- while 1:
- os.kill(pid, signal.SIGKILL)
- time.sleep(0.1)
- except OSError, err:
- err = str(err)
- if err.find(_("No such process")) > 0:
- if os.path.exists(pidfile):
- os.remove(pidfile)
- else:
- print str(err)
- sys.exit(1)
-
-
-def serve(filename):
- logging.debug(_("Serving %s") % filename)
- name = os.path.basename(filename)
- OptionsClass = WrapTwistedOptions(TwistdServerOptions)
- options = OptionsClass()
- argv = options.parseOptions()
- FLAGS.python = filename
- FLAGS.no_save = True
- if not FLAGS.pidfile:
- FLAGS.pidfile = '%s.pid' % name
- elif FLAGS.pidfile.endswith('twistd.pid'):
- FLAGS.pidfile = FLAGS.pidfile.replace('twistd.pid', '%s.pid' % name)
- if not FLAGS.prefix:
- FLAGS.prefix = name
- elif FLAGS.prefix.endswith('twisted'):
- FLAGS.prefix = FLAGS.prefix.replace('twisted', name)
-
- action = 'start'
- if len(argv) > 1:
- action = argv.pop()
-
- if action == 'stop':
- stop(FLAGS.pidfile)
- sys.exit()
- elif action == 'restart':
- stop(FLAGS.pidfile)
- elif action == 'start':
- pass
- else:
- print 'usage: %s [options] [start|stop|restart]' % argv[0]
- sys.exit(1)
-
- logging.debug(_("Full set of FLAGS:"))
- for flag in FLAGS:
- logging.debug("%s : %s" % (flag, FLAGS.get(flag, None)))
-
- logging.audit(_("Starting %s"), name)
- twistd.runApp(options)
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index 83b33a0ad..135b88ab8 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -340,8 +340,7 @@ class FakeConnection(driver.ComputeDriver):
only useful for giving back to this layer as a parameter to
disk_stats). These IDs only need to be unique for a given instance.
- Note that this function takes an instance ID, not a
- compute.service.Instance, so that it can be called by compute.monitor.
+ Note that this function takes an instance ID.
"""
return ['A_DISK']
@@ -353,8 +352,7 @@ class FakeConnection(driver.ComputeDriver):
interface_stats). These IDs only need to be unique for a given
instance.
- Note that this function takes an instance ID, not a
- compute.service.Instance, so that it can be called by compute.monitor.
+ Note that this function takes an instance ID.
"""
return ['A_VIF']
@@ -374,8 +372,7 @@ class FakeConnection(driver.ComputeDriver):
having to do the aggregation. On those platforms, this method is
unused.
- Note that this function takes an instance ID, not a
- compute.service.Instance, so that it can be called by compute.monitor.
+ Note that this function takes an instance ID.
"""
return [0L, 0L, 0L, 0L, None]
@@ -395,8 +392,7 @@ class FakeConnection(driver.ComputeDriver):
having to do the aggregation. On those platforms, this method is
unused.
- Note that this function takes an instance ID, not a
- compute.service.Instance, so that it can be called by compute.monitor.
+ Note that this function takes an instance ID.
"""
return [0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L]
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index b73586693..150478edf 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -1087,8 +1087,7 @@ class LibvirtConnection(driver.ComputeDriver):
def get_disks(self, instance_name):
"""
- Note that this function takes an instance name, not an Instance, so
- that it can be called by monitor.
+ Note that this function takes an instance name.
Returns a list of all block devices for this domain.
"""
@@ -1129,8 +1128,7 @@ class LibvirtConnection(driver.ComputeDriver):
def get_interfaces(self, instance_name):
"""
- Note that this function takes an instance name, not an Instance, so
- that it can be called by monitor.
+ Note that this function takes an instance name.
Returns a list of all network interfaces for this instance.
"""
@@ -1345,16 +1343,14 @@ class LibvirtConnection(driver.ComputeDriver):
def block_stats(self, instance_name, disk):
"""
- Note that this function takes an instance name, not an Instance, so
- that it can be called by monitor.
+ Note that this function takes an instance name.
"""
domain = self._lookup_by_name(instance_name)
return domain.blockStats(disk)
def interface_stats(self, instance_name, interface):
"""
- Note that this function takes an instance name, not an Instance, so
- that it can be called by monitor.
+ Note that this function takes an instance name.
"""
domain = self._lookup_by_name(instance_name)
return domain.interfaceStats(interface)
diff --git a/po/ast.po b/po/ast.po
index ac6190424..449cddb07 100644
--- a/po/ast.po
+++ b/po/ast.po
@@ -125,33 +125,6 @@ msgstr ""
msgid "compute.api::resume %s"
msgstr ""
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr ""
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr ""
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr ""
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr ""
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr ""
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr ""
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1778,34 +1751,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2263,10 +2208,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/cs.po b/po/cs.po
index 33f7808a5..2dc763838 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -125,33 +125,6 @@ msgstr ""
msgid "compute.api::resume %s"
msgstr ""
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr ""
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr ""
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr ""
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr ""
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr ""
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr ""
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1778,34 +1751,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2265,10 +2210,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/da.po b/po/da.po
index 5aead53c3..570629119 100644
--- a/po/da.po
+++ b/po/da.po
@@ -125,33 +125,6 @@ msgstr ""
msgid "compute.api::resume %s"
msgstr ""
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr ""
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr ""
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr ""
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr ""
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr ""
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr ""
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1778,34 +1751,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2263,10 +2208,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/de.po b/po/de.po
index cf40a0f5e..772ae236c 100644
--- a/po/de.po
+++ b/po/de.po
@@ -131,33 +131,6 @@ msgstr ""
msgid "compute.api::resume %s"
msgstr ""
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr ""
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr "PID-Datei %s existiert nicht. Läuft der Daemon nicht?\n"
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr "Kein passender Prozess gefunden"
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr "Bedient %s"
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr "Alle vorhandenen FLAGS:"
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr "%s wird gestartet"
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1785,34 +1758,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2270,10 +2215,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/en_AU.po b/po/en_AU.po
index e53f9fc07..3fa62c006 100644
--- a/po/en_AU.po
+++ b/po/en_AU.po
@@ -125,33 +125,6 @@ msgstr ""
msgid "compute.api::resume %s"
msgstr ""
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr ""
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr ""
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr ""
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr ""
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr ""
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr ""
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1778,34 +1751,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2263,10 +2208,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/en_GB.po b/po/en_GB.po
index 601f6170b..b204c93a1 100644
--- a/po/en_GB.po
+++ b/po/en_GB.po
@@ -130,33 +130,6 @@ msgstr "compute.api::suspend %s"
msgid "compute.api::resume %s"
msgstr "compute.api::resume %s"
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr "Wrong number of arguments."
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr "pidfile %s does not exist. Daemon not running?\n"
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr "No such process"
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr "Serving %s"
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr "Full set of FLAGS:"
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr "Starting %s"
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1803,34 +1776,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2288,10 +2233,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/es.po b/po/es.po
index eeaf209a9..f97434041 100644
--- a/po/es.po
+++ b/po/es.po
@@ -130,33 +130,6 @@ msgstr "compute.api::suspend %s"
msgid "compute.api::resume %s"
msgstr "compute.api::resume %s"
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr "Cantidad de argumentos incorrecta"
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr "El \"pidfile\" %s no existe. Quizás el servicio no este corriendo.\n"
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr "No existe el proceso"
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr "Sirviendo %s"
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr "Conjunto completo de opciones (FLAGS):"
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr "Iniciando %s"
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1819,34 +1792,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr "Obtenida excepción %s"
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr "actualizando %s..."
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr "error inesperado durante la actualización"
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr "excepción inexperada al obtener la conexión"
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr "Encontrada interfaz: %s"
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2309,10 +2254,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/fr.po b/po/fr.po
index 9dd789b3c..83e4e7af0 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -133,35 +133,6 @@ msgstr "compute.api::suspend %s"
msgid "compute.api::resume %s"
msgstr "compute.api::resume %s"
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr "Nombre d'arguments incorrect."
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr ""
-"Le fichier pid %s n'existe pas. Est-ce que le processus est en cours "
-"d'exécution ?\n"
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr "Aucun processus de ce type"
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr "En train de servir %s"
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr "Ensemble de propriétés complet :"
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr "Démarrage de %s"
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1865,34 +1836,6 @@ msgstr "Tâche [%(name)s] %(task)s état : %(status)s %(error_info)s"
msgid "Got exception: %s"
msgstr "Reçu exception : %s"
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr "mise à jour %s..."
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr "erreur inopinée pendant la ise à jour"
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr "Ne peut pas récupérer blockstats pour \"%(disk)s\" sur \"%(iid)s\""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr "Ne peut pas récupérer ifstats pour \"%(interface)s\" sur \"%(iid)s\""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr "erreur inopinée pendant la connexion"
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr "Instance trouvée : %s"
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2373,10 +2316,6 @@ msgstr "Démarrage %(arg0)s sur %(host)s:%(port)s"
msgid "You must implement __call__"
msgstr "Vous devez implémenter __call__"
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr "Démarrage du superviseur d'instance"
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr "Allocation IP"
diff --git a/po/it.po b/po/it.po
index 60c3a388a..6bfcf1274 100644
--- a/po/it.po
+++ b/po/it.po
@@ -134,34 +134,6 @@ msgstr "compute.api::suspend %s"
msgid "compute.api::resume %s"
msgstr "compute.api::resume %s"
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr "Numero errato di argomenti"
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr ""
-"Il pidfile %s non esiste. Assicurarsi che il demone é in esecuzione.\n"
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr "Nessun processo trovato"
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr "Servire %s"
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr "Insieme di FLAGS:"
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr "Avvio di %s"
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1791,34 +1763,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2278,10 +2222,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/ja.po b/po/ja.po
index 09d17af3b..a7906ede8 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -130,33 +130,6 @@ msgstr "例外: compute.api::suspend %s"
msgid "compute.api::resume %s"
msgstr "例外: compute.api::resume %s"
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr "引数の数が異なります。"
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr "pidfile %s が存在しません。デーモンは実行中ですか?\n"
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr "そのようなプロセスはありません"
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr "%s サービスの開始"
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr "FLAGSの一覧:"
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr "%s を起動中"
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1808,34 +1781,6 @@ msgstr "タスク [%(name)s] %(task)s 状態: %(status)s %(error_info)s"
msgid "Got exception: %s"
msgstr "例外 %s が発生しました。"
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr "%s の情報の更新…"
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr "更新の最中に予期しないエラーが発生しました。"
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr "\"%(iid)s\" 上の \"%(disk)s\" 用のブロック統計(blockstats)が取得できません"
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr "\"%(iid)s\" 上の %(interface)s\" 用インターフェース統計(ifstats)が取得できません"
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr "接続に際し予期しないエラーが発生しました。"
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr "インスタンス %s が見つかりました。"
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2311,10 +2256,6 @@ msgstr "%(host)s:%(port)s 上で %(arg0)s を開始しています"
msgid "You must implement __call__"
msgstr "__call__ を実装しなければなりません"
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr "インスタンスモニタを開始しています"
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr "IP アドレスをリースしました"
diff --git a/po/nova.pot b/po/nova.pot
index 58140302d..e180ed750 100644
--- a/po/nova.pot
+++ b/po/nova.pot
@@ -125,33 +125,6 @@ msgstr ""
msgid "compute.api::resume %s"
msgstr ""
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr ""
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr ""
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr ""
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr ""
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr ""
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr ""
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1778,34 +1751,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2263,10 +2208,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/pt_BR.po b/po/pt_BR.po
index f067a69e0..b3aefce44 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -126,34 +126,6 @@ msgstr "compute.api::suspend %s"
msgid "compute.api::resume %s"
msgstr "compute.api::resume %s"
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr "Número errado de argumentos."
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr ""
-"Arquivo do id do processo (pidfile) %s não existe. O Daemon está parado?\n"
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr "Processo inexistente"
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr "Servindo %s"
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr "Conjunto completo de FLAGS:"
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr "Iniciando %s"
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1804,34 +1776,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2290,10 +2234,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/ru.po b/po/ru.po
index 5d8532f2e..1bf672fc3 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -125,33 +125,6 @@ msgstr ""
msgid "compute.api::resume %s"
msgstr ""
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr "Неверное число аргументов."
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr "pidfile %s не обнаружен. Демон не запущен?\n"
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr ""
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr ""
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr ""
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr "Запускается %s"
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1779,34 +1752,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr "обновление %s..."
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr "неожиданная ошибка во время обновления"
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2264,10 +2209,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/tl.po b/po/tl.po
index 7f600e8f1..1ae59330b 100644
--- a/po/tl.po
+++ b/po/tl.po
@@ -125,33 +125,6 @@ msgstr ""
msgid "compute.api::resume %s"
msgstr ""
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr ""
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr ""
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr ""
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr ""
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr ""
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr ""
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1778,34 +1751,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2265,10 +2210,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/uk.po b/po/uk.po
index bbd831de9..481851e1c 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -125,33 +125,6 @@ msgstr ""
msgid "compute.api::resume %s"
msgstr ""
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr ""
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr ""
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr ""
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr "Обслуговування %s"
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr ""
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr "Запускається %s"
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1778,34 +1751,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2263,10 +2208,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/zh_CN.po b/po/zh_CN.po
index c3d292a93..d0ddcd2f7 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -17,11 +17,6 @@ msgstr ""
"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
"X-Generator: Launchpad (build 13405)\n"
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr "启动 %s 中"
-
#: ../nova/scheduler/chance.py:37 ../nova/scheduler/zone.py:55
#: ../nova/scheduler/simple.py:75 ../nova/scheduler/simple.py:110
#: ../nova/scheduler/simple.py:122
@@ -135,28 +130,6 @@ msgstr ""
msgid "compute.api::resume %s"
msgstr ""
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr "错误参数个数。"
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr "pidfile %s 不存在,守护进程是否运行?\n"
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr "没有该进程"
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr "正在为 %s 服务"
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr "FLAGS全集:"
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1785,34 +1758,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2270,10 +2215,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/po/zh_TW.po b/po/zh_TW.po
index ad14c0e32..896e69618 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -125,33 +125,6 @@ msgstr ""
msgid "compute.api::resume %s"
msgstr ""
-#: ../nova/twistd.py:157
-msgid "Wrong number of arguments."
-msgstr ""
-
-#: ../nova/twistd.py:209
-#, python-format
-msgid "pidfile %s does not exist. Daemon not running?\n"
-msgstr "pidfile %s 不存在. Daemon未啟動?\n"
-
-#: ../nova/twistd.py:221
-msgid "No such process"
-msgstr "沒有此一程序"
-
-#: ../nova/twistd.py:230 ../nova/service.py:224
-#, python-format
-msgid "Serving %s"
-msgstr ""
-
-#: ../nova/twistd.py:262 ../nova/service.py:225
-msgid "Full set of FLAGS:"
-msgstr ""
-
-#: ../nova/twistd.py:266
-#, python-format
-msgid "Starting %s"
-msgstr "正在啟動 %s"
-
#: ../nova/virt/xenapi/volumeops.py:48 ../nova/virt/xenapi/volumeops.py:101
#: ../nova/db/sqlalchemy/api.py:731 ../nova/virt/libvirt_conn.py:741
#: ../nova/api/ec2/__init__.py:317
@@ -1778,34 +1751,6 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: ../nova/compute/monitor.py:259
-#, python-format
-msgid "updating %s..."
-msgstr ""
-
-#: ../nova/compute/monitor.py:289
-msgid "unexpected error during update"
-msgstr ""
-
-#: ../nova/compute/monitor.py:356
-#, python-format
-msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:379
-#, python-format
-msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
-
-#: ../nova/compute/monitor.py:414
-msgid "unexpected exception getting connection"
-msgstr ""
-
-#: ../nova/compute/monitor.py:429
-#, python-format
-msgid "Found instance: %s"
-msgstr ""
-
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
@@ -2263,10 +2208,6 @@ msgstr ""
msgid "You must implement __call__"
msgstr ""
-#: ../bin/nova-instancemonitor.py:55
-msgid "Starting instance monitor"
-msgstr ""
-
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
msgstr ""
diff --git a/setup.py b/setup.py
index c165f40d7..8121e250b 100644
--- a/setup.py
+++ b/setup.py
@@ -124,7 +124,6 @@ setup(name='nova',
'bin/nova-dhcpbridge',
'bin/nova-direct-api',
'bin/nova-import-canonical-imagestore',
- 'bin/nova-instancemonitor',
'bin/nova-logspool',
'bin/nova-manage',
'bin/nova-network',
diff --git a/tools/eventlet-patch b/tools/eventlet-patch
deleted file mode 100644
index c87c5f279..000000000
--- a/tools/eventlet-patch
+++ /dev/null
@@ -1,24 +0,0 @@
-# HG changeset patch
-# User Soren Hansen <soren@linux2go.dk>
-# Date 1297678255 -3600
-# Node ID 4c846d555010bb5a91ab4da78dfe596451313742
-# Parent 5b7e9946c79f005c028eb63207cf5eb7bb21d1c3
-Don't attempt to wrap GreenPipes in GreenPipe
-
-If the os module is monkeypatched, Python's standard subprocess module
-will return greenio.GreenPipe instances for Popen objects' stdin, stdout,
-and stderr attributes. However, eventlet.green.subprocess tries to wrap
-these attributes in another greenio.GreenPipe, which GreenPipe refuses.
-
-diff -r 5b7e9946c79f -r 4c846d555010 eventlet/green/subprocess.py
---- a/eventlet/green/subprocess.py Sat Feb 05 13:05:05 2011 -0800
-+++ b/eventlet/green/subprocess.py Mon Feb 14 11:10:55 2011 +0100
-@@ -27,7 +27,7 @@
- # eventlet.processes.Process.run() method.
- for attr in "stdin", "stdout", "stderr":
- pipe = getattr(self, attr)
-- if pipe is not None:
-+ if pipe is not None and not type(pipe) == greenio.GreenPipe:
- wrapped_pipe = greenio.GreenPipe(pipe, pipe.mode, bufsize)
- setattr(self, attr, wrapped_pipe)
- __init__.__doc__ = subprocess_orig.Popen.__init__.__doc__
diff --git a/tools/install_venv.py b/tools/install_venv.py
index f4b6583ed..3c2f6979f 100644
--- a/tools/install_venv.py
+++ b/tools/install_venv.py
@@ -31,7 +31,6 @@ import sys
ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
VENV = os.path.join(ROOT, '.nova-venv')
PIP_REQUIRES = os.path.join(ROOT, 'tools', 'pip-requires')
-TWISTED_NOVA = 'http://nova.openstack.org/Twisted-10.0.0Nova.tar.gz'
PY_VERSION = "python%s.%s" % (sys.version_info[0], sys.version_info[1])
@@ -106,20 +105,12 @@ def install_dependencies(venv=VENV):
'greenlet'], redirect_output=False)
run_command(['tools/with_venv.sh', 'pip', 'install', '-E', venv, '-r',
PIP_REQUIRES], redirect_output=False)
- run_command(['tools/with_venv.sh', 'pip', 'install', '-E', venv,
- TWISTED_NOVA], redirect_output=False)
# Tell the virtual env how to "import nova"
pthfile = os.path.join(venv, "lib", PY_VERSION, "site-packages",
"nova.pth")
f = open(pthfile, 'w')
f.write("%s\n" % ROOT)
- # Patch eventlet (see FAQ # 1485)
- patchsrc = os.path.join(ROOT, 'tools', 'eventlet-patch')
- patchfile = os.path.join(venv, "lib", PY_VERSION, "site-packages",
- "eventlet", "green", "subprocess.py")
- patch_cmd = "patch %s %s" % (patchfile, patchsrc)
- os.system(patch_cmd)
def print_help():
diff --git a/tools/pip-requires b/tools/pip-requires
index 1e8f7e1d2..e6ef3996c 100644
--- a/tools/pip-requires
+++ b/tools/pip-requires
@@ -9,7 +9,7 @@ boto==1.9b
carrot==0.10.5
eventlet
lockfile==0.8
-python-novaclient==2.5.7
+python-novaclient==2.5.9
python-daemon==1.5.5
python-gflags==1.3
redis==2.0.0
@@ -20,13 +20,13 @@ mox==0.5.3
greenlet==0.3.1
nose
bzr
-Twisted>=10.1.0
PasteDeploy
paste
sqlalchemy-migrate
netaddr
sphinx
glance
+xattr>=0.6.0
nova-adminclient
suds==0.4
coverage