summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Behrens <cbehrens@codestud.com>2011-07-27 17:04:06 -0700
committerChris Behrens <cbehrens@codestud.com>2011-07-27 17:04:06 -0700
commit865b8eba36072de5381a192eccc844573efbaf4d (patch)
tree61e26e54d0abe0685f4cee5b44d0bb4fbe92f01f
parent970b37ff9e9aef987f6e87df7d2c2e73c484e439 (diff)
parent26fd6c3f309a2febd7538684a470d462ab83dab3 (diff)
downloadnova-865b8eba36072de5381a192eccc844573efbaf4d.tar.gz
nova-865b8eba36072de5381a192eccc844573efbaf4d.tar.xz
nova-865b8eba36072de5381a192eccc844573efbaf4d.zip
merged trunk
-rw-r--r--.bzrignore4
-rw-r--r--.mailmap1
-rw-r--r--Authors5
-rwxr-xr-xbin/nova-dhcpbridge2
-rwxr-xr-xbin/nova-manage526
-rw-r--r--nova/api/ec2/cloud.py142
-rw-r--r--nova/api/openstack/__init__.py10
-rw-r--r--nova/api/openstack/accounts.py6
-rw-r--r--nova/api/openstack/backup_schedules.py9
-rw-r--r--nova/api/openstack/common.py44
-rw-r--r--nova/api/openstack/consoles.py10
-rw-r--r--nova/api/openstack/contrib/multinic.py5
-rw-r--r--nova/api/openstack/contrib/volumes.py58
-rw-r--r--nova/api/openstack/create_instance_helper.py85
-rw-r--r--nova/api/openstack/extensions.py51
-rw-r--r--nova/api/openstack/faults.py18
-rw-r--r--nova/api/openstack/flavors.py55
-rw-r--r--nova/api/openstack/image_metadata.py58
-rw-r--r--nova/api/openstack/images.py16
-rw-r--r--nova/api/openstack/ips.py67
-rw-r--r--nova/api/openstack/limits.py61
-rw-r--r--nova/api/openstack/server_metadata.py1
-rw-r--r--nova/api/openstack/servers.py147
-rw-r--r--nova/api/openstack/shared_ip_groups.py13
-rw-r--r--nova/api/openstack/users.py3
-rw-r--r--nova/api/openstack/versions.py147
-rw-r--r--nova/api/openstack/views/addresses.py26
-rw-r--r--nova/api/openstack/views/limits.py6
-rw-r--r--nova/api/openstack/views/servers.py47
-rw-r--r--nova/api/openstack/views/versions.py3
-rw-r--r--nova/api/openstack/wsgi.py68
-rw-r--r--nova/api/openstack/zones.py8
-rw-r--r--nova/compute/api.py48
-rw-r--r--nova/compute/instance_types.py2
-rw-r--r--nova/compute/manager.py155
-rw-r--r--nova/db/api.py28
-rw-r--r--nova/db/sqlalchemy/api.py63
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/033_ha_network.py44
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/034_change_instance_id_in_migrations.py52
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/035_secondary_dns.py38
-rw-r--r--nova/db/sqlalchemy/models.py21
-rw-r--r--nova/exception.py14
-rw-r--r--nova/image/glance.py8
-rw-r--r--nova/image/s3.py2
-rw-r--r--nova/network/api.py25
-rw-r--r--nova/network/linux_net.py41
-rw-r--r--nova/network/manager.py310
-rw-r--r--nova/network/vmwareapi_net.py82
-rw-r--r--nova/network/xenapi_net.py87
-rw-r--r--nova/tests/__init__.py6
-rw-r--r--nova/tests/api/openstack/test_common.py18
-rw-r--r--nova/tests/api/openstack/test_extensions.py197
-rw-r--r--nova/tests/api/openstack/test_faults.py112
-rw-r--r--nova/tests/api/openstack/test_flavors.py374
-rw-r--r--nova/tests/api/openstack/test_image_metadata.py184
-rw-r--r--nova/tests/api/openstack/test_images.py208
-rw-r--r--nova/tests/api/openstack/test_limits.py218
-rw-r--r--nova/tests/api/openstack/test_servers.py816
-rw-r--r--nova/tests/api/openstack/test_versions.py159
-rw-r--r--nova/tests/api/openstack/test_wsgi.py7
-rw-r--r--nova/tests/db/fakes.py8
-rw-r--r--nova/tests/fake_flags.py1
-rw-r--r--nova/tests/test_api.py6
-rw-r--r--nova/tests/test_cloud.py115
-rw-r--r--nova/tests/test_compute.py57
-rw-r--r--nova/tests/test_db_api.py86
-rw-r--r--nova/tests/test_instance_types_extra_specs.py8
-rw-r--r--nova/tests/test_libvirt.py178
-rw-r--r--nova/tests/test_network.py38
-rw-r--r--nova/tests/test_quota.py3
-rw-r--r--nova/tests/test_vmwareapi.py107
-rw-r--r--nova/tests/test_xenapi.py60
-rw-r--r--nova/tests/vmwareapi/db_fakes.py10
-rw-r--r--nova/tests/vmwareapi/stubs.py7
-rw-r--r--nova/virt/driver.py16
-rw-r--r--nova/virt/fake.py10
-rw-r--r--nova/virt/hyperv.py6
-rw-r--r--nova/virt/libvirt.xml.template24
-rw-r--r--nova/virt/libvirt/connection.py107
-rw-r--r--nova/virt/libvirt/firewall.py11
-rw-r--r--nova/virt/libvirt/netutils.py19
-rw-r--r--nova/virt/libvirt/vif.py134
-rw-r--r--nova/virt/vif.py30
-rw-r--r--nova/virt/vmwareapi/fake.py10
-rw-r--r--nova/virt/vmwareapi/network_utils.py29
-rw-r--r--nova/virt/vmwareapi/vif.py95
-rw-r--r--nova/virt/vmwareapi/vm_util.py33
-rw-r--r--nova/virt/vmwareapi/vmops.py48
-rw-r--r--nova/virt/vmwareapi_conn.py16
-rw-r--r--nova/virt/xenapi/vif.py140
-rw-r--r--nova/virt/xenapi/vm_utils.py22
-rw-r--r--nova/virt/xenapi/vmops.py47
-rw-r--r--nova/virt/xenapi_conn.py24
-rw-r--r--nova/volume/api.py2
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/agent4
-rw-r--r--po/ast.po4
-rw-r--r--po/cs.po4
-rw-r--r--po/da.po4
-rw-r--r--po/de.po49
-rw-r--r--po/en_AU.po2848
-rw-r--r--po/en_GB.po2873
-rw-r--r--po/es.po139
-rw-r--r--po/fr.po2992
-rw-r--r--po/it.po4
-rw-r--r--po/ja.po482
-rw-r--r--po/pt_BR.po4
-rw-r--r--po/ru.po22
-rw-r--r--po/tl.po2855
-rw-r--r--po/uk.po4
-rw-r--r--po/zh_CN.po27
-rw-r--r--po/zh_TW.po2848
-rwxr-xr-xrun_tests.sh18
-rw-r--r--smoketests/test_sysadmin.py33
-rw-r--r--tools/esx/guest_tool.py55
114 files changed, 19814 insertions, 1983 deletions
diff --git a/.bzrignore b/.bzrignore
index 14d8028f7..91277d100 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -13,3 +13,7 @@ nova/vcsversion.py
clean.sqlite
run_tests.log
tests.sqlite
+nova/tests/instance-*
+tags
+.coverage
+covhtml
diff --git a/.mailmap b/.mailmap
index ff304c891..76e7bc669 100644
--- a/.mailmap
+++ b/.mailmap
@@ -14,6 +14,7 @@
<code@term.ie> <github@anarkystic.com>
<code@term.ie> <termie@preciousroy.local>
<corywright@gmail.com> <cory.wright@rackspace.com>
+<dan@nicira.com> <danwent@dan-xs3-cs>
<devin.carlen@gmail.com> <devcamcar@illian.local>
<ewan.mellor@citrix.com> <emellor@silver>
<itoumsn@nttdata.co.jp> <itoumsn@shayol>
diff --git a/Authors b/Authors
index 8ffb7d8d4..1a07946bd 100644
--- a/Authors
+++ b/Authors
@@ -1,3 +1,5 @@
+Adam Gandelman <adamg@canonical.com>
+Adam Johnson <adjohn@gmail.com>
Alex Meade <alex.meade@rackspace.com>
Alexander Sakhnov <asakhnov@mirantis.com>
Andrey Brindeyev <abrindeyev@griddynamics.com>
@@ -7,6 +9,7 @@ Anne Gentle <anne@openstack.org>
Anthony Young <sleepsonthefloor@gmail.com>
Antony Messerli <ant@openstack.org>
Armando Migliaccio <Armando.Migliaccio@eu.citrix.com>
+Arvind Somya <asomya@cisco.com>
Bilal Akhtar <bilalakhtar@ubuntu.com>
Brian Lamar <brian.lamar@rackspace.com>
Brian Schott <bschott@isi.edu>
@@ -18,6 +21,7 @@ Christian Berendt <berendt@b1-systems.de>
Chuck Short <zulcss@ubuntu.com>
Cory Wright <corywright@gmail.com>
Dan Prince <dan.prince@rackspace.com>
+Dan Wendlandt <dan@nicira.com>
Dave Walker <DaveWalker@ubuntu.com>
David Pravec <David.Pravec@danix.org>
Dean Troyer <dtroyer@gmail.com>
@@ -82,6 +86,7 @@ Rick Harris <rconradharris@gmail.com>
Rob Kost <kost@isi.edu>
Ryan Lane <rlane@wikimedia.org>
Ryan Lucio <rlucio@internap.com>
+Ryu Ishimoto <ryu@midokura.jp>
Salvatore Orlando <salvatore.orlando@eu.citrix.com>
Sandy Walsh <sandy.walsh@rackspace.com>
Sateesh Chodapuneedi <sateesh.chodapuneedi@citrix.com>
diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge
index 6d9d85896..325642d52 100755
--- a/bin/nova-dhcpbridge
+++ b/bin/nova-dhcpbridge
@@ -91,7 +91,7 @@ def init_leases(interface):
"""Get the list of hosts for an interface."""
ctxt = context.get_admin_context()
network_ref = db.network_get_by_bridge(ctxt, interface)
- return linux_net.get_dhcp_leases(ctxt, network_ref['id'])
+ return linux_net.get_dhcp_leases(ctxt, network_ref)
def main():
diff --git a/bin/nova-manage b/bin/nova-manage
index 2446309e8..75d74903c 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -61,6 +61,7 @@ import os
import sys
import time
+from optparse import OptionParser
# 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...
@@ -103,6 +104,14 @@ flags.DEFINE_flag(flags.HelpshortFlag())
flags.DEFINE_flag(flags.HelpXMLFlag())
+# Decorators for actions
+def args(*args, **kwargs):
+ def _decorator(func):
+ func.__dict__.setdefault('options', []).insert(0, (args, kwargs))
+ return func
+ return _decorator
+
+
def param2id(object_id):
"""Helper function to convert various id types to internal id.
args: [object_id], e.g. 'vol-0000000a' or 'volume-0000000a' or '10'
@@ -120,10 +129,11 @@ class VpnCommands(object):
self.manager = manager.AuthManager()
self.pipe = pipelib.CloudPipe()
+ @args('--project', dest="project", metavar='<Project name>',
+ help='Project name')
def list(self, project=None):
- """Print a listing of the VPN data for one or all projects.
+ """Print a listing of the VPN data for one or all projects."""
- args: [project=all]"""
print "%-12s\t" % 'project',
print "%-20s\t" % 'ip:port',
print "%-20s\t" % 'private_ip',
@@ -165,17 +175,23 @@ class VpnCommands(object):
self.pipe.launch_vpn_instance(p.id)
time.sleep(10)
+ @args('--project', dest="project_id", metavar='<Project name>',
+ help='Project name')
def run(self, project_id):
"""Start the VPN for a given project."""
self.pipe.launch_vpn_instance(project_id)
+ @args('--project', dest="project_id", metavar='<Project name>',
+ help='Project name')
+ @args('--ip', dest="ip", metavar='<IP Address>', help='IP Address')
+ @args('--port', dest="port", metavar='<Port>', help='Port')
def change(self, project_id, ip, port):
"""Change the ip and port for a vpn.
this will update all networks associated with a project
not sure if that's the desired behavior or not, patches accepted
- args: project, ip, port"""
+ """
# TODO(tr3buchet): perhaps this shouldn't update all networks
# associated with a project in the future
project = self.manager.get_project(project_id)
@@ -210,10 +226,10 @@ class ShellCommands(object):
Falls back to Python shell if unavailable"""
self.run('python')
+ @args('--shell', dest="shell", metavar='<bpython|ipython|python >',
+ help='Python shell')
def run(self, shell=None):
- """Runs a Python interactive interpreter.
-
- args: [shell=bpython]"""
+ """Runs a Python interactive interpreter."""
if not shell:
shell = 'bpython'
@@ -247,6 +263,7 @@ class ShellCommands(object):
readline.parse_and_bind("tab:complete")
code.interact()
+ @args('--path', dest='path', metavar='<path>', help='Script path')
def script(self, path):
"""Runs the script from the specifed path with flags set properly.
arguments: path"""
@@ -259,10 +276,13 @@ class RoleCommands(object):
def __init__(self):
self.manager = manager.AuthManager()
+ @args('--user', dest="user", metavar='<user name>', help='User name')
+ @args('--role', dest="role", metavar='<user role>', help='User role')
+ @args('--project', dest="project", metavar='<Project name>',
+ help='Project name')
def add(self, user, role, project=None):
"""adds role to user
- if project is specified, adds project specific role
- arguments: user, role [project]"""
+ if project is specified, adds project specific role"""
if project:
projobj = self.manager.get_project(project)
if not projobj.has_member(user):
@@ -270,17 +290,23 @@ class RoleCommands(object):
return
self.manager.add_role(user, role, project)
+ @args('--user', dest="user", metavar='<user name>', help='User name')
+ @args('--role', dest="role", metavar='<user role>', help='User role')
+ @args('--project', dest="project", metavar='<Project name>',
+ help='Project name')
def has(self, user, role, project=None):
"""checks to see if user has role
if project is specified, returns True if user has
- the global role and the project role
- arguments: user, role [project]"""
+ the global role and the project role"""
print self.manager.has_role(user, role, project)
+ @args('--user', dest="user", metavar='<user name>', help='User name')
+ @args('--role', dest="role", metavar='<user role>', help='User role')
+ @args('--project', dest="project", metavar='<Project name>',
+ help='Project name')
def remove(self, user, role, project=None):
"""removes role from user
- if project is specified, removes project specific role
- arguments: user, role [project]"""
+ if project is specified, removes project specific role"""
self.manager.remove_role(user, role, project)
@@ -304,32 +330,37 @@ class UserCommands(object):
def __init__(self):
self.manager = manager.AuthManager()
+ @args('--name', dest="name", metavar='<admin name>', help='Admin name')
+ @args('--access', dest="access", metavar='<access>', help='Access')
+ @args('--secret', dest="secret", metavar='<secret>', help='Secret')
def admin(self, name, access=None, secret=None):
- """creates a new admin and prints exports
- arguments: name [access] [secret]"""
+ """creates a new admin and prints exports"""
try:
user = self.manager.create_user(name, access, secret, True)
except exception.DBError, e:
_db_error(e)
self._print_export(user)
+ @args('--name', dest="name", metavar='<name>', help='User name')
+ @args('--access', dest="access", metavar='<access>', help='Access')
+ @args('--secret', dest="secret", metavar='<secret>', help='Secret')
def create(self, name, access=None, secret=None):
- """creates a new user and prints exports
- arguments: name [access] [secret]"""
+ """creates a new user and prints exports"""
try:
user = self.manager.create_user(name, access, secret, False)
except exception.DBError, e:
_db_error(e)
self._print_export(user)
+ @args('--name', dest="name", metavar='<name>', help='User name')
def delete(self, name):
"""deletes an existing user
arguments: name"""
self.manager.delete_user(name)
+ @args('--name', dest="name", metavar='<admin name>', help='User name')
def exports(self, name):
- """prints access and secrets for user in export format
- arguments: name"""
+ """prints access and secrets for user in export format"""
user = self.manager.get_user(name)
if user:
self._print_export(user)
@@ -337,11 +368,17 @@ class UserCommands(object):
print "User %s doesn't exist" % name
def list(self):
- """lists all users
- arguments: <none>"""
+ """lists all users"""
for user in self.manager.get_users():
print user.name
+ @args('--name', dest="name", metavar='<name>', help='User name')
+ @args('--access', dest="access_key", metavar='<access>',
+ help='Access key')
+ @args('--secret', dest="secret_key", metavar='<secret>',
+ help='Secret key')
+ @args('--is_admin', dest='is_admin', metavar="<'T'|'F'>",
+ help='Is admin?')
def modify(self, name, access_key, secret_key, is_admin):
"""update a users keys & admin flag
arguments: accesskey secretkey admin
@@ -355,9 +392,11 @@ class UserCommands(object):
is_admin = False
self.manager.modify_user(name, access_key, secret_key, is_admin)
+ @args('--name', dest="user_id", metavar='<name>', help='User name')
+ @args('--project', dest="project_id", metavar='<Project name>',
+ help='Project name')
def revoke(self, user_id, project_id=None):
- """revoke certs for a user
- arguments: user_id [project_id]"""
+ """revoke certs for a user"""
if project_id:
crypto.revoke_certs_by_user_and_project(user_id, project_id)
else:
@@ -370,45 +409,62 @@ class ProjectCommands(object):
def __init__(self):
self.manager = manager.AuthManager()
+ @args('--project', dest="project_id", metavar='<Project name>',
+ help='Project name')
+ @args('--user', dest="user_id", metavar='<name>', help='User name')
def add(self, project_id, user_id):
- """Adds user to project
- arguments: project_id user_id"""
+ """Adds user to project"""
try:
self.manager.add_to_project(user_id, project_id)
except exception.UserNotFound as ex:
print ex
raise
+ @args('--project', dest="name", metavar='<Project name>',
+ help='Project name')
+ @args('--user', dest="project_manager", metavar='<user>',
+ help='Project manager')
+ @args('--desc', dest="description", metavar='<description>',
+ help='Description')
def create(self, name, project_manager, description=None):
- """Creates a new project
- arguments: name project_manager [description]"""
+ """Creates a new project"""
try:
self.manager.create_project(name, project_manager, description)
except exception.UserNotFound as ex:
print ex
raise
+ @args('--project', dest="name", metavar='<Project name>',
+ help='Project name')
+ @args('--user', dest="project_manager", metavar='<user>',
+ help='Project manager')
+ @args('--desc', dest="description", metavar='<description>',
+ help='Description')
def modify(self, name, project_manager, description=None):
- """Modifies a project
- arguments: name project_manager [description]"""
+ """Modifies a project"""
try:
self.manager.modify_project(name, project_manager, description)
except exception.UserNotFound as ex:
print ex
raise
+ @args('--project', dest="name", metavar='<Project name>',
+ help='Project name')
def delete(self, name):
- """Deletes an existing project
- arguments: name"""
+ """Deletes an existing project"""
try:
self.manager.delete_project(name)
except exception.ProjectNotFound as ex:
print ex
raise
+ @args('--project', dest="project_id", metavar='<Project name>',
+ help='Project name')
+ @args('--user', dest="user_id", metavar='<name>', help='User name')
+ @args('--file', dest="filename", metavar='<filename>',
+ help='File name(Default: novarc)')
def environment(self, project_id, user_id, filename='novarc'):
- """Exports environment variables to an sourcable file
- arguments: project_id user_id [filename='novarc]"""
+ """Exports environment variables to an sourcable file"""
try:
rc = self.manager.get_environment_rc(user_id, project_id)
except (exception.UserNotFound, exception.ProjectNotFound) as ex:
@@ -420,15 +476,18 @@ class ProjectCommands(object):
with open(filename, 'w') as f:
f.write(rc)
+ @args('--user', dest="username", metavar='<username>', help='User name')
def list(self, username=None):
- """Lists all projects
- arguments: [username]"""
+ """Lists all projects"""
for project in self.manager.get_projects(username):
print project.name
+ @args('--project', dest="project_id", metavar='<Project name>',
+ help='Project name')
+ @args('--key', dest="key", metavar='<key>', help='Key')
+ @args('--value', dest="value", metavar='<value>', help='Value')
def quota(self, project_id, key=None, value=None):
- """Set or display quotas for project
- arguments: project_id [key] [value]"""
+ """Set or display quotas for project"""
ctxt = context.get_admin_context()
if key:
if value.lower() == 'unlimited':
@@ -443,18 +502,21 @@ class ProjectCommands(object):
value = 'unlimited'
print '%s: %s' % (key, value)
+ @args('--project', dest="project_id", metavar='<Project name>',
+ help='Project name')
+ @args('--user', dest="user_id", metavar='<name>', help='User name')
def remove(self, project_id, user_id):
- """Removes user from project
- arguments: project_id user_id"""
+ """Removes user from project"""
try:
self.manager.remove_from_project(user_id, project_id)
except (exception.UserNotFound, exception.ProjectNotFound) as ex:
print ex
raise
+ @args('--project', dest="project_id", metavar='<Project name>',
+ help='Project name')
def scrub(self, project_id):
- """Deletes data associated with project
- arguments: project_id"""
+ """Deletes data associated with project"""
admin_context = context.get_admin_context()
networks = db.project_get_networks(admin_context, project_id)
for network in networks:
@@ -463,9 +525,13 @@ class ProjectCommands(object):
for group in groups:
db.security_group_destroy(admin_context, group['id'])
+ @args('--project', dest="project_id", metavar='<Project name>',
+ help='Project name')
+ @args('--user', dest="user_id", metavar='<name>', help='User name')
+ @args('--file', dest="filename", metavar='<filename>',
+ help='File name(Default: nova.zip)')
def zipfile(self, project_id, user_id, filename='nova.zip'):
- """Exports credentials for project to a zip file
- arguments: project_id user_id [filename='nova.zip]"""
+ """Exports credentials for project to a zip file"""
try:
zip_file = self.manager.get_credentials(user_id, project_id)
if filename == "-":
@@ -479,12 +545,12 @@ class ProjectCommands(object):
except db.api.NoMoreNetworks:
print _('No more networks available. If this is a new '
'installation, you need\nto call something like this:\n\n'
- ' nova-manage network create 10.0.0.0/8 10 64\n\n')
+ ' nova-manage network create pvt 10.0.0.0/8 10 64\n\n')
except exception.ProcessExecutionError, e:
print e
- print _("The above error may show that the certificate db has not "
- "been created.\nPlease create a database by running a "
- "nova-api server on this host.")
+ print _("The above error may show that the certificate db has "
+ "not been created.\nPlease create a database by running "
+ "a nova-api server on this host.")
AccountCommands = ProjectCommands
@@ -492,15 +558,16 @@ AccountCommands = ProjectCommands
class FixedIpCommands(object):
"""Class for managing fixed ip."""
+ @args('--host', dest="host", metavar='<host>', help='Host')
def list(self, host=None):
- """Lists all fixed ips (optionally by host) arguments: [host]"""
+ """Lists all fixed ips (optionally by host)"""
ctxt = context.get_admin_context()
try:
if host is None:
fixed_ips = db.fixed_ip_get_all(ctxt)
else:
- fixed_ips = db.fixed_ip_get_all_by_host(ctxt, host)
+ fixed_ips = db.fixed_ip_get_all_by_instance_host(ctxt, host)
except exception.NotFound as ex:
print "error: %s" % ex
sys.exit(2)
@@ -528,23 +595,23 @@ class FixedIpCommands(object):
class FloatingIpCommands(object):
"""Class for managing floating ip."""
+ @args('--ip_range', dest="range", metavar='<range>', help='IP range')
def create(self, range):
- """Creates floating ips for zone by range
- arguments: ip_range"""
+ """Creates floating ips for zone by range"""
for address in netaddr.IPNetwork(range):
db.floating_ip_create(context.get_admin_context(),
{'address': str(address)})
+ @args('--ip_range', dest="ip_range", metavar='<range>', help='IP range')
def delete(self, ip_range):
- """Deletes floating ips by range
- arguments: range"""
+ """Deletes floating ips by range"""
for address in netaddr.IPNetwork(ip_range):
db.floating_ip_destroy(context.get_admin_context(),
str(address))
+ @args('--host', dest="host", metavar='<host>', help='Host')
def list(self, host=None):
"""Lists all floating ips (optionally by host)
- arguments: [host]
Note: if host is given, only active floating IPs are returned"""
ctxt = context.get_admin_context()
if host is None:
@@ -563,78 +630,130 @@ class FloatingIpCommands(object):
class NetworkCommands(object):
"""Class for managing networks."""
- def create(self, label=None, fixed_range=None, num_networks=None,
- network_size=None, vlan_start=None,
+ @args('--label', dest="label", metavar='<label>',
+ help='Label for network (ex: public)')
+ @args('--fixed_range_v4', dest="fixed_range_v4", metavar='<x.x.x.x/yy>',
+ help='IPv4 subnet (ex: 10.0.0.0/8)')
+ @args('--num_networks', dest="num_networks", metavar='<number>',
+ help='Number of networks to create')
+ @args('--network_size', dest="network_size", metavar='<number>',
+ help='Number of IPs per network')
+ @args('--vlan', dest="vlan_start", metavar='<vlan id>', help='vlan id')
+ @args('--vpn', dest="vpn_start", help='vpn start')
+ @args('--fixed_range_v6', dest="fixed_range_v6",
+ help='IPv6 subnet (ex: fe80::/64')
+ @args('--gateway_v6', dest="gateway_v6", help='ipv6 gateway')
+ @args('--bridge', dest="bridge",
+ metavar='<bridge>',
+ help='VIFs on this network are connected to this bridge')
+ @args('--bridge_interface', dest="bridge_interface",
+ metavar='<bridge interface>',
+ help='the bridge is connected to this interface')
+ @args('--multi_host', dest="multi_host", metavar="<'T'|'F'>",
+ help='Multi host')
+ @args('--dns1', dest="dns1", metavar="<DNS Address>", help='First DNS')
+ @args('--dns2', dest="dns2", metavar="<DNS Address>", help='Second DNS')
+ def create(self, label=None, fixed_range_v4=None, num_networks=None,
+ network_size=None, multi_host=None, vlan_start=None,
vpn_start=None, fixed_range_v6=None, gateway_v6=None,
- flat_network_bridge=None, bridge_interface=None):
- """Creates fixed ips for host by range
- arguments: label, fixed_range, [num_networks=FLAG],
- [network_size=FLAG], [vlan_start=FLAG],
- [vpn_start=FLAG], [fixed_range_v6=FLAG], [gateway_v6=FLAG],
- [flat_network_bridge=FLAG], [bridge_interface=FLAG]
- If you wish to use a later argument fill in the gaps with 0s
- Ex: network create private 10.0.0.0/8 1 15 0 0 0 0 xenbr1 eth1
- network create private 10.0.0.0/8 1 15
- """
+ bridge=None, bridge_interface=None, dns1=None, dns2=None):
+ """Creates fixed ips for host by range"""
+
+ # check for certain required inputs
if not label:
- msg = _('a label (ex: public) is required to create networks.')
- print msg
- raise TypeError(msg)
- if not fixed_range:
- msg = _('Fixed range in the form of 10.0.0.0/8 is '
- 'required to create networks.')
- print msg
- raise TypeError(msg)
+ raise exception.NetworkNotCreated(req='--label')
+ if not fixed_range_v4:
+ raise exception.NetworkNotCreated(req='--fixed_range_v4')
+
+ bridge = bridge or FLAGS.flat_network_bridge
+ if not bridge:
+ bridge_required = ['nova.network.manager.FlatManager',
+ 'nova.network.manager.FlatDHCPManager']
+ if FLAGS.network_manager in bridge_required:
+ # TODO(tr3buchet) - swap print statement and following line for
+ # raise statement in diablo 4
+ print _('--bridge parameter required or FLAG '
+ 'flat_network_bridge must be set to create networks\n'
+ 'WARNING! ACHTUNG! Setting the bridge to br100 '
+ 'automatically is deprecated and will be removed in '
+ 'Diablo milestone 4. Prepare yourself accordingly.')
+ time.sleep(10)
+ bridge = 'br100'
+ #raise exception.NetworkNotCreated(req='--bridge')
+
+ bridge_interface = bridge_interface or FLAGS.flat_interface or \
+ FLAGS.vlan_interface
+ if not bridge_interface:
+ interface_required = ['nova.network.manager.FlatDHCPManager',
+ 'nova.network.manager.VlanManager']
+ if FLAGS.network_manager in interface_required:
+ raise exception.NetworkNotCreated(req='--bridge_interface')
+
+ if FLAGS.use_ipv6:
+ fixed_range_v6 = fixed_range_v6 or FLAGS.fixed_range_v6
+ if not fixed_range_v6:
+ raise exception.NetworkNotCreated(req='with use_ipv6, '
+ '--fixed_range_v6')
+ gateway_v6 = gateway_v6 or FLAGS.gateway_v6
+ if not gateway_v6:
+ raise exception.NetworkNotCreated(req='with use_ipv6, '
+ '--gateway_v6')
+
+ # sanitize other input using FLAGS if necessary
if not num_networks:
num_networks = FLAGS.num_networks
if not network_size:
network_size = FLAGS.network_size
+ if not multi_host:
+ multi_host = FLAGS.multi_host
+ else:
+ multi_host = multi_host == 'T'
if not vlan_start:
vlan_start = FLAGS.vlan_start
if not vpn_start:
vpn_start = FLAGS.vpn_start
- if not fixed_range_v6:
- fixed_range_v6 = FLAGS.fixed_range_v6
- if not flat_network_bridge:
- flat_network_bridge = FLAGS.flat_network_bridge
- if not bridge_interface:
- bridge_interface = FLAGS.flat_interface or FLAGS.vlan_interface
- if not gateway_v6:
- gateway_v6 = FLAGS.gateway_v6
- net_manager = utils.import_object(FLAGS.network_manager)
+ if not dns1 and FLAGS.flat_network_dns:
+ dns1 = FLAGS.flat_network_dns
- try:
- net_manager.create_networks(context.get_admin_context(),
- label=label,
- cidr=fixed_range,
- num_networks=int(num_networks),
- network_size=int(network_size),
- vlan_start=int(vlan_start),
- vpn_start=int(vpn_start),
- cidr_v6=fixed_range_v6,
- gateway_v6=gateway_v6,
- bridge=flat_network_bridge,
- bridge_interface=bridge_interface)
- except ValueError, e:
- print e
- raise e
+ # create the network
+ net_manager = utils.import_object(FLAGS.network_manager)
+ net_manager.create_networks(context.get_admin_context(),
+ label=label,
+ cidr=fixed_range_v4,
+ multi_host=multi_host,
+ num_networks=int(num_networks),
+ network_size=int(network_size),
+ vlan_start=int(vlan_start),
+ vpn_start=int(vpn_start),
+ cidr_v6=fixed_range_v6,
+ gateway_v6=gateway_v6,
+ bridge=bridge,
+ bridge_interface=bridge_interface,
+ dns1=dns1,
+ dns2=dns2)
def list(self):
"""List all created networks"""
- print "%-18s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s" % (_('network'),
+ print "%-18s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s" % (
+ _('network'),
_('netmask'),
_('start address'),
- _('DNS'),
+ _('DNS1'),
+ _('DNS2'),
_('VlanID'),
'project')
for network in db.network_get_all(context.get_admin_context()):
- print "%-18s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s" % (network.cidr,
+ print "%-18s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s" % (
+ network.cidr,
network.netmask,
network.dhcp_start,
- network.dns,
+ network.dns1,
+ network.dns2,
network.vlan,
network.project_id)
+ @args('--network', dest="fixed_range", metavar='<x.x.x.x/yy>',
+ help='Network to delete')
def delete(self, fixed_range):
"""Deletes a network"""
network = db.network_get_by_cidr(context.get_admin_context(), \
@@ -648,12 +767,10 @@ class NetworkCommands(object):
class VmCommands(object):
"""Class for mangaging VM instances."""
+ @args('--host', dest="host", metavar='<host>', help='Host')
def list(self, host=None):
- """Show a list of all instances
+ """Show a list of all instances"""
- :param host: show all instance on specified host.
- :param instance: show specificed instance.
- """
print "%-10s %-15s %-10s %-10s %-26s %-9s %-9s %-9s" \
" %-10s %-10s %-10s %-5s" % (
_('instance'),
@@ -691,13 +808,11 @@ class VmCommands(object):
instance['availability_zone'],
instance['launch_index'])
+ @args('--ec2_id', dest='ec2_id', metavar='<ec2 id>', help='EC2 ID')
+ @args('--dest', dest='dest', metavar='<Destanation>',
+ help='destanation node')
def live_migration(self, ec2_id, dest):
- """Migrates a running instance to a new machine.
-
- :param ec2_id: instance id which comes from euca-describe-instance.
- :param dest: destination host name.
-
- """
+ """Migrates a running instance to a new machine."""
ctxt = context.get_admin_context()
instance_id = ec2utils.ec2_id_to_id(ec2_id)
@@ -727,9 +842,13 @@ class VmCommands(object):
class ServiceCommands(object):
"""Enable and disable running services"""
+ @args('--host', dest='host', metavar='<host>', help='Host')
+ @args('--service', dest='service', metavar='<service>',
+ help='Nova service')
def list(self, host=None, service=None):
- """Show a list of all running services. Filter by host & service name.
- args: [host] [service]"""
+ """
+ Show a list of all running services. Filter by host & service name.
+ """
ctxt = context.get_admin_context()
now = utils.utcnow()
services = db.service_get_all(ctxt)
@@ -748,9 +867,11 @@ class ServiceCommands(object):
active, art,
svc['updated_at'])
+ @args('--host', dest='host', metavar='<host>', help='Host')
+ @args('--service', dest='service', metavar='<service>',
+ help='Nova service')
def enable(self, host, service):
- """Enable scheduling for a service
- args: host service"""
+ """Enable scheduling for a service"""
ctxt = context.get_admin_context()
svc = db.service_get_by_args(ctxt, host, service)
if not svc:
@@ -758,9 +879,11 @@ class ServiceCommands(object):
return
db.service_update(ctxt, svc['id'], {'disabled': False})
+ @args('--host', dest='host', metavar='<host>', help='Host')
+ @args('--service', dest='service', metavar='<service>',
+ help='Nova service')
def disable(self, host, service):
- """Disable scheduling for a service
- args: host service"""
+ """Disable scheduling for a service"""
ctxt = context.get_admin_context()
svc = db.service_get_by_args(ctxt, host, service)
if not svc:
@@ -768,12 +891,9 @@ class ServiceCommands(object):
return
db.service_update(ctxt, svc['id'], {'disabled': True})
+ @args('--host', dest='host', metavar='<host>', help='Host')
def describe_resource(self, host):
- """Describes cpu/memory/hdd info for host.
-
- :param host: hostname.
-
- """
+ """Describes cpu/memory/hdd info for host."""
result = rpc.call(context.get_admin_context(),
FLAGS.scheduler_topic,
@@ -801,12 +921,9 @@ class ServiceCommands(object):
val['memory_mb'],
val['local_gb'])
+ @args('--host', dest='host', metavar='<host>', help='Host')
def update_resource(self, host):
- """Updates available vcpu/memory/disk info for host.
-
- :param host: hostname.
-
- """
+ """Updates available vcpu/memory/disk info for host."""
ctxt = context.get_admin_context()
service_refs = db.service_get_all_by_host(ctxt, host)
@@ -850,6 +967,8 @@ class DbCommands(object):
def __init__(self):
pass
+ @args('--version', dest='version', metavar='<version>',
+ help='Database version')
def sync(self, version=None):
"""Sync the database up to the most recent version."""
return migration.db_sync(version)
@@ -869,14 +988,18 @@ class VersionCommands(object):
print _("%s (%s)") %\
(version.version_string(), version.version_string_with_vcs())
+ def __call__(self):
+ self.list()
+
class VolumeCommands(object):
"""Methods for dealing with a cloud in an odd state"""
+ @args('--volume', dest='volume_id', metavar='<volume id>',
+ help='Volume ID')
def delete(self, volume_id):
"""Delete a volume, bypassing the check that it
- must be available.
- args: volume_id_id"""
+ must be available."""
ctxt = context.get_admin_context()
volume = db.volume_get(ctxt, param2id(volume_id))
host = volume['host']
@@ -897,11 +1020,12 @@ class VolumeCommands(object):
{"method": "delete_volume",
"args": {"volume_id": volume['id']}})
+ @args('--volume', dest='volume_id', metavar='<volume id>',
+ help='Volume ID')
def reattach(self, volume_id):
"""Re-attach a volume that has previously been attached
to an instance. Typically called after a compute host
- has been rebooted.
- args: volume_id_id"""
+ has been rebooted."""
ctxt = context.get_admin_context()
volume = db.volume_get(ctxt, param2id(volume_id))
if not volume['instance_id']:
@@ -928,12 +1052,23 @@ class InstanceTypeCommands(object):
val["flavorid"], val["swap"], val["rxtx_quota"],
val["rxtx_cap"], deleted)
+ @args('--name', dest='name', metavar='<name>',
+ help='Name of instance type/flavor')
+ @args('--memory', dest='memory', metavar='<memory size>',
+ help='Memory size')
+ @args('--cpu', dest='vcpus', metavar='<num cores>', help='Number cpus')
+ @args('--local_gb', dest='local_gb', metavar='<local_gb>',
+ help='local_gb')
+ @args('--flavor', dest='flavorid', metavar='<flavor id>',
+ help='Flavor ID')
+ @args('--swap', dest='swap', metavar='<swap>', help='Swap')
+ @args('--rxtx_quota', dest='rxtx_quota', metavar='<rxtx_quota>',
+ help='rxtx_quota')
+ @args('--rxtx_cap', dest='rxtx_cap', metavar='<rxtx_cap>',
+ help='rxtx_cap')
def create(self, name, memory, vcpus, local_gb, flavorid,
swap=0, rxtx_quota=0, rxtx_cap=0):
- """Creates instance types / flavors
- arguments: name memory vcpus local_gb flavorid [swap] [rxtx_quota]
- [rxtx_cap]
- """
+ """Creates instance types / flavors"""
try:
instance_types.create(name, memory, vcpus, local_gb,
flavorid, swap, rxtx_quota, rxtx_cap)
@@ -956,9 +1091,10 @@ class InstanceTypeCommands(object):
else:
print "%s created" % name
+ @args('--name', dest='name', metavar='<name>',
+ help='Name of instance type/flavor')
def delete(self, name, purge=None):
- """Marks instance types / flavors as deleted
- arguments: name"""
+ """Marks instance types / flavors as deleted"""
try:
if purge == "--purge":
instance_types.purge(name)
@@ -977,9 +1113,10 @@ class InstanceTypeCommands(object):
else:
print "%s %s" % (name, verb)
+ @args('--name', dest='name', metavar='<name>',
+ help='Name of instance type/flavor')
def list(self, name=None):
- """Lists all active or specific instance types / flavors
- arguments: [name]"""
+ """Lists all active or specific instance types / flavors"""
try:
if name is None:
inst_types = instance_types.get_all_types()
@@ -1027,11 +1164,18 @@ class ImageCommands(object):
except Exception as exc:
print _("Failed to register %(path)s: %(exc)s") % locals()
+ @args('--image', dest='image', metavar='<image>', help='Image')
+ @args('--kernel', dest='kernel', metavar='<kernel>', help='Kernel')
+ @args('--ram', dest='ramdisk', metavar='<ramdisk>', help='RAM disk')
+ @args('--owner', dest='owner', metavar='<owner>', help='Image owner')
+ @args('--name', dest='name', metavar='<name>', help='Image name')
+ @args('--public', dest='is_public', metavar="<'T'|'F'>",
+ help='Image public or not')
+ @args('--arch', dest='architecture', metavar='<arch>',
+ help='Architecture')
def all_register(self, image, kernel, ramdisk, owner, name=None,
is_public='T', architecture='x86_64'):
- """Uploads an image, kernel, and ramdisk into the image_service
- arguments: image kernel ramdisk owner [name] [is_public='T']
- [architecture='x86_64']"""
+ """Uploads an image, kernel, and ramdisk into the image_service"""
kernel_id = self.kernel_register(kernel, owner, None,
is_public, architecture)
ramdisk_id = self.ramdisk_register(ramdisk, owner, None,
@@ -1040,31 +1184,51 @@ class ImageCommands(object):
architecture, 'ami', 'ami',
kernel_id, ramdisk_id)
+ @args('--path', dest='path', metavar='<path>', help='Image path')
+ @args('--owner', dest='owner', metavar='<owner>', help='Image owner')
+ @args('--name', dest='name', metavar='<name>', help='Image name')
+ @args('--public', dest='is_public', metavar="<'T'|'F'>",
+ help='Image public or not')
+ @args('--arch', dest='architecture', metavar='<arch>',
+ help='Architecture')
+ @args('--cont_format', dest='container_format',
+ metavar='<container format>',
+ help='Container format(default bare)')
+ @args('--disk_format', dest='disk_format', metavar='<disk format>',
+ help='Disk format(default: raw)')
+ @args('--kernel', dest='kernel_id', metavar='<kernel>', help='Kernel')
+ @args('--ram', dest='ramdisk_id', metavar='<ramdisk>', help='RAM disk')
def image_register(self, path, owner, name=None, is_public='T',
architecture='x86_64', container_format='bare',
disk_format='raw', kernel_id=None, ramdisk_id=None):
- """Uploads an image into the image_service
- arguments: path owner [name] [is_public='T'] [architecture='x86_64']
- [container_format='bare'] [disk_format='raw']
- [kernel_id=None] [ramdisk_id=None]
- """
+ """Uploads an image into the image_service"""
return self._register(container_format, disk_format, path,
owner, name, is_public, architecture,
kernel_id, ramdisk_id)
+ @args('--path', dest='path', metavar='<path>', help='Image path')
+ @args('--owner', dest='owner', metavar='<owner>', help='Image owner')
+ @args('--name', dest='name', metavar='<name>', help='Image name')
+ @args('--public', dest='is_public', metavar="<'T'|'F'>",
+ help='Image public or not')
+ @args('--arch', dest='architecture', metavar='<arch>',
+ help='Architecture')
def kernel_register(self, path, owner, name=None, is_public='T',
architecture='x86_64'):
- """Uploads a kernel into the image_service
- arguments: path owner [name] [is_public='T'] [architecture='x86_64']
- """
+ """Uploads a kernel into the image_service"""
return self._register('aki', 'aki', path, owner, name,
is_public, architecture)
+ @args('--path', dest='path', metavar='<path>', help='Image path')
+ @args('--owner', dest='owner', metavar='<owner>', help='Image owner')
+ @args('--name', dest='name', metavar='<name>', help='Image name')
+ @args('--public', dest='is_public', metavar="<'T'|'F'>",
+ help='Image public or not')
+ @args('--arch', dest='architecture', metavar='<arch>',
+ help='Architecture')
def ramdisk_register(self, path, owner, name=None, is_public='T',
architecture='x86_64'):
- """Uploads a ramdisk into the image_service
- arguments: path owner [name] [is_public='T'] [architecture='x86_64']
- """
+ """Uploads a ramdisk into the image_service"""
return self._register('ari', 'ari', path, owner, name,
is_public, architecture)
@@ -1113,9 +1277,10 @@ class ImageCommands(object):
except Exception as exc:
print _("Failed to convert %(old)s: %(exc)s") % locals()
+ @args('--dir', dest='directory', metavar='<path>',
+ help='Images directory')
def convert(self, directory):
- """Uploads old objectstore images in directory to new service
- arguments: directory"""
+ """Uploads old objectstore images in directory to new service"""
machine_images = {}
other_images = {}
directory = os.path.abspath(directory)
@@ -1140,8 +1305,7 @@ class AgentBuildCommands(object):
def create(self, os, architecture, version, url, md5hash,
hypervisor='xen'):
- """Creates a new agent build.
- arguments: os architecture version url md5hash [hypervisor='xen']"""
+ """Creates a new agent build."""
ctxt = context.get_admin_context()
agent_build = db.agent_build_create(ctxt,
{'hypervisor': hypervisor,
@@ -1152,8 +1316,7 @@ class AgentBuildCommands(object):
'md5hash': md5hash})
def delete(self, os, architecture, hypervisor='xen'):
- """Deletes an existing agent build.
- arguments: os architecture [hypervisor='xen']"""
+ """Deletes an existing agent build."""
ctxt = context.get_admin_context()
agent_build_ref = db.agent_build_get_by_triple(ctxt,
hypervisor, os, architecture)
@@ -1187,9 +1350,7 @@ class AgentBuildCommands(object):
def modify(self, os, architecture, version, url, md5hash,
hypervisor='xen'):
- """Update an existing agent build.
- arguments: os architecture version url md5hash [hypervisor='xen']
- """
+ """Update an existing agent build."""
ctxt = context.get_admin_context()
agent_build_ref = db.agent_build_get_by_triple(ctxt,
hypervisor, os, architecture)
@@ -1285,21 +1446,42 @@ def main():
command_object = fn()
actions = methods_of(command_object)
if len(argv) < 1:
- print script_name + " category action [<args>]"
- print _("Available actions for %s category:") % category
- for k, _v in actions:
- print "\t%s" % k
- sys.exit(2)
- action = argv.pop(0)
- matches = lazy_match(action, actions)
- action, fn = matches[0]
+ if hasattr(command_object, '__call__'):
+ action = ''
+ fn = command_object.__call__
+ else:
+ print script_name + " category action [<args>]"
+ print _("Available actions for %s category:") % category
+ for k, _v in actions:
+ print "\t%s" % k
+ sys.exit(2)
+ else:
+ action = argv.pop(0)
+ matches = lazy_match(action, actions)
+ action, fn = matches[0]
+
+ # For not decorated methods
+ options = getattr(fn, 'options', [])
+
+ usage = "%%prog %s %s <args> [options]" % (category, action)
+ parser = OptionParser(usage=usage)
+ for ar, kw in options:
+ parser.add_option(*ar, **kw)
+ (opts, fn_args) = parser.parse_args(argv)
+ fn_kwargs = vars(opts)
+
+ for k, v in fn_kwargs.items():
+ if v is None:
+ del fn_kwargs[k]
+
# call the action with the remaining arguments
try:
- fn(*argv)
+ fn(*fn_args, **fn_kwargs)
sys.exit(0)
except TypeError:
print _("Possible wrong number of arguments supplied")
- print "%s %s: %s" % (category, action, fn.__doc__)
+ print fn.__doc__
+ parser.print_help()
raise
except Exception:
print _("Command failed, please check log for more info")
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 100d1179d..966c3a564 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -536,7 +536,55 @@ class CloudController(object):
g['ipPermissions'] += [r]
return g
- def _revoke_rule_args_to_dict(self, context, to_port=None, from_port=None,
+ def _rule_args_to_dict(self, context, kwargs):
+ rules = []
+ if not 'groups' in kwargs and not 'ip_ranges' in kwargs:
+ rule = self._rule_dict_last_step(context, **kwargs)
+ if rule:
+ rules.append(rule)
+ return rules
+ if 'ip_ranges' in kwargs:
+ rules = self._cidr_args_split(kwargs)
+ else:
+ rules = [kwargs]
+ finalset = []
+ for rule in rules:
+ if 'groups' in rule:
+ groups_values = self._groups_args_split(rule)
+ for groups_value in groups_values:
+ final = self._rule_dict_last_step(context, **groups_value)
+ finalset.append(final)
+ else:
+ final = self._rule_dict_last_step(context, **rule)
+ finalset.append(final)
+ return finalset
+
+ def _cidr_args_split(self, kwargs):
+ cidr_args_split = []
+ cidrs = kwargs['ip_ranges']
+ for key, cidr in cidrs.iteritems():
+ mykwargs = kwargs.copy()
+ del mykwargs['ip_ranges']
+ mykwargs['cidr_ip'] = cidr['cidr_ip']
+ cidr_args_split.append(mykwargs)
+ return cidr_args_split
+
+ def _groups_args_split(self, kwargs):
+ groups_args_split = []
+ groups = kwargs['groups']
+ for key, group in groups.iteritems():
+ mykwargs = kwargs.copy()
+ del mykwargs['groups']
+ if 'group_name' in group:
+ mykwargs['source_security_group_name'] = group['group_name']
+ if 'user_id' in group:
+ mykwargs['source_security_group_owner_id'] = group['user_id']
+ if 'group_id' in group:
+ mykwargs['source_security_group_id'] = group['group_id']
+ groups_args_split.append(mykwargs)
+ return groups_args_split
+
+ def _rule_dict_last_step(self, context, to_port=None, from_port=None,
ip_protocol=None, cidr_ip=None, user_id=None,
source_security_group_name=None,
source_security_group_owner_id=None):
@@ -551,6 +599,9 @@ class CloudController(object):
db.security_group_get_by_name(context.elevated(),
source_project_id,
source_security_group_name)
+ notfound = exception.SecurityGroupNotFound
+ if not source_security_group:
+ raise notfound(security_group_id=source_security_group_name)
values['group_id'] = source_security_group['id']
elif cidr_ip:
# If this fails, it throws an exception. This is what we want.
@@ -589,7 +640,7 @@ class CloudController(object):
for rule in security_group.rules:
if 'group_id' in values:
if rule['group_id'] == values['group_id']:
- return True
+ return rule['id']
else:
is_duplicate = True
for key in ('cidr', 'from_port', 'to_port', 'protocol'):
@@ -597,7 +648,7 @@ class CloudController(object):
is_duplicate = False
break
if is_duplicate:
- return True
+ return rule['id']
return False
def revoke_security_group_ingress(self, context, group_name=None,
@@ -620,22 +671,30 @@ class CloudController(object):
msg = "Revoke security group ingress %s"
LOG.audit(_(msg), security_group['name'], context=context)
-
- criteria = self._revoke_rule_args_to_dict(context, **kwargs)
- if criteria is None:
- raise exception.ApiError(_("Not enough parameters to build a "
- "valid rule."))
-
- for rule in security_group.rules:
- match = True
- for (k, v) in criteria.iteritems():
- if getattr(rule, k, False) != v:
- match = False
- if match:
- db.security_group_rule_destroy(context, rule['id'])
- self.compute_api.trigger_security_group_rules_refresh(context,
- security_group_id=security_group['id'])
- return True
+ prevalues = []
+ try:
+ prevalues = kwargs['ip_permissions']
+ except KeyError:
+ prevalues.append(kwargs)
+ rule_id = None
+ for values in prevalues:
+ rulesvalues = self._rule_args_to_dict(context, values)
+ if not rulesvalues:
+ err = "%s Not enough parameters to build a valid rule"
+ raise exception.ApiError(_(err % rulesvalues))
+
+ for values_for_rule in rulesvalues:
+ values_for_rule['parent_group_id'] = security_group.id
+ rule_id = self._security_group_rule_exists(security_group,
+ values_for_rule)
+ if rule_id:
+ db.security_group_rule_destroy(context, rule_id)
+ if rule_id:
+ # NOTE(vish): we removed a rule, so refresh
+ self.compute_api.trigger_security_group_rules_refresh(
+ context,
+ security_group_id=security_group['id'])
+ return True
raise exception.ApiError(_("No rule for the specified parameters."))
# TODO(soren): This has only been tested with Boto as the client.
@@ -662,22 +721,37 @@ class CloudController(object):
msg = "Authorize security group ingress %s"
LOG.audit(_(msg), security_group['name'], context=context)
- values = self._revoke_rule_args_to_dict(context, **kwargs)
- if values is None:
- raise exception.ApiError(_("Not enough parameters to build a "
- "valid rule."))
- values['parent_group_id'] = security_group.id
-
- if self._security_group_rule_exists(security_group, values):
- raise exception.ApiError(_('This rule already exists in group %s')
- % group_name)
-
- security_group_rule = db.security_group_rule_create(context, values)
+ prevalues = []
+ try:
+ prevalues = kwargs['ip_permissions']
+ except KeyError:
+ prevalues.append(kwargs)
+ postvalues = []
+ for values in prevalues:
+ rulesvalues = self._rule_args_to_dict(context, values)
+ if not rulesvalues:
+ err = "%s Not enough parameters to build a valid rule"
+ raise exception.ApiError(_(err % rulesvalues))
+ for values_for_rule in rulesvalues:
+ values_for_rule['parent_group_id'] = security_group.id
+ if self._security_group_rule_exists(security_group,
+ values_for_rule):
+ err = '%s - This rule already exists in group'
+ raise exception.ApiError(_(err) % values_for_rule)
+ postvalues.append(values_for_rule)
+
+ for values_for_rule in postvalues:
+ security_group_rule = db.security_group_rule_create(
+ context,
+ values_for_rule)
- self.compute_api.trigger_security_group_rules_refresh(context,
- security_group_id=security_group['id'])
+ if postvalues:
+ self.compute_api.trigger_security_group_rules_refresh(
+ context,
+ security_group_id=security_group['id'])
+ return True
- return True
+ raise exception.ApiError(_("No rule for the specified parameters."))
def _get_source_project_id(self, context, source_security_group_owner_id):
if source_security_group_owner_id:
@@ -1165,7 +1239,7 @@ class CloudController(object):
def rescue_instance(self, context, instance_id, **kwargs):
"""This is an extension to the normal ec2_api"""
- self._do_instance(self.compute_api.rescue, contect, instnace_id)
+ self._do_instance(self.compute_api.rescue, context, instance_id)
return True
def unrescue_instance(self, context, instance_id, **kwargs):
diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py
index e87d7c754..868b98a31 100644
--- a/nova/api/openstack/__init__.py
+++ b/nova/api/openstack/__init__.py
@@ -164,11 +164,17 @@ class APIRouterV11(APIRouter):
def _setup_routes(self, mapper):
super(APIRouterV11, self)._setup_routes(mapper, '1.1')
- mapper.resource("image_meta", "meta",
- controller=image_metadata.create_resource(),
+ image_metadata_controller = image_metadata.create_resource()
+ mapper.resource("image_meta", "metadata",
+ controller=image_metadata_controller,
parent_resource=dict(member_name='image',
collection_name='images'))
+ mapper.connect("metadata", "/images/{image_id}/metadata",
+ controller=image_metadata_controller,
+ action='update_all',
+ conditions={"method": ['PUT']})
+
mapper.resource("server_meta", "meta",
controller=server_metadata.create_resource(),
parent_resource=dict(member_name='server',
diff --git a/nova/api/openstack/accounts.py b/nova/api/openstack/accounts.py
index e3201b14f..a13a758ab 100644
--- a/nova/api/openstack/accounts.py
+++ b/nova/api/openstack/accounts.py
@@ -47,10 +47,10 @@ class Controller(object):
raise exception.AdminRequired()
def index(self, req):
- raise faults.Fault(webob.exc.HTTPNotImplemented())
+ raise webob.exc.HTTPNotImplemented()
def detail(self, req):
- raise faults.Fault(webob.exc.HTTPNotImplemented())
+ raise webob.exc.HTTPNotImplemented()
def show(self, req, id):
"""Return data about the given account id"""
@@ -65,7 +65,7 @@ class Controller(object):
def create(self, req, body):
"""We use update with create-or-update semantics
because the id comes from an external source"""
- raise faults.Fault(webob.exc.HTTPNotImplemented())
+ raise webob.exc.HTTPNotImplemented()
def update(self, req, id, body):
"""This is really create or update."""
diff --git a/nova/api/openstack/backup_schedules.py b/nova/api/openstack/backup_schedules.py
index 3e95aedf3..7ff0d999e 100644
--- a/nova/api/openstack/backup_schedules.py
+++ b/nova/api/openstack/backup_schedules.py
@@ -19,7 +19,6 @@ import time
from webob import exc
-from nova.api.openstack import faults
from nova.api.openstack import wsgi
@@ -36,20 +35,20 @@ class Controller(object):
def index(self, req, server_id, **kwargs):
""" Returns the list of backup schedules for a given instance """
- return faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def show(self, req, server_id, id, **kwargs):
""" Returns a single backup schedule for a given instance """
- return faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def create(self, req, server_id, **kwargs):
""" No actual update method required, since the existing API allows
both create and update through a POST """
- return faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def delete(self, req, server_id, id, **kwargs):
""" Deletes an existing backup schedule """
- return faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def create_resource():
diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py
index 8e12ce0c0..bd14a1389 100644
--- a/nova/api/openstack/common.py
+++ b/nova/api/openstack/common.py
@@ -53,10 +53,10 @@ def get_pagination_params(request):
params[param] = int(request.GET[param])
except ValueError:
msg = _('%s param must be an integer') % param
- raise webob.exc.HTTPBadRequest(msg)
+ raise webob.exc.HTTPBadRequest(explanation=msg)
if params[param] < 0:
msg = _('%s param must be positive') % param
- raise webob.exc.HTTPBadRequest(msg)
+ raise webob.exc.HTTPBadRequest(explanation=msg)
return params
@@ -77,18 +77,22 @@ def limited(items, request, max_limit=FLAGS.osapi_max_limit):
try:
offset = int(request.GET.get('offset', 0))
except ValueError:
- raise webob.exc.HTTPBadRequest(_('offset param must be an integer'))
+ msg = _('offset param must be an integer')
+ raise webob.exc.HTTPBadRequest(explanation=msg)
try:
limit = int(request.GET.get('limit', max_limit))
except ValueError:
- raise webob.exc.HTTPBadRequest(_('limit param must be an integer'))
+ msg = _('limit param must be an integer')
+ raise webob.exc.HTTPBadRequest(explanation=msg)
if limit < 0:
- raise webob.exc.HTTPBadRequest(_('limit param must be positive'))
+ msg = _('limit param must be positive')
+ raise webob.exc.HTTPBadRequest(explanation=msg)
if offset < 0:
- raise webob.exc.HTTPBadRequest(_('offset param must be positive'))
+ msg = _('offset param must be positive')
+ raise webob.exc.HTTPBadRequest(explanation=msg)
limit = min(max_limit, limit or max_limit)
range_end = offset + limit
@@ -111,7 +115,8 @@ def limited_by_marker(items, request, max_limit=FLAGS.osapi_max_limit):
start_index = i + 1
break
if start_index < 0:
- raise webob.exc.HTTPBadRequest(_('marker [%s] not found' % marker))
+ msg = _('marker [%s] not found') % marker
+ raise webob.exc.HTTPBadRequest(explanation=msg)
range_end = start_index + limit
return items[start_index:range_end]
@@ -162,3 +167,28 @@ def remove_version_from_href(href):
msg = _('href does not contain version')
raise ValueError(msg)
return new_href
+
+
+def get_version_from_href(href):
+ """Returns the api version in the href.
+
+ Returns the api version in the href.
+ If no version is found, 1.0 is returned
+
+ Given: 'http://www.nova.com/123'
+ Returns: '1.0'
+
+ Given: 'http://www.nova.com/v1.1'
+ Returns: '1.1'
+
+ """
+ try:
+ #finds the first instance that matches /v#.#/
+ version = re.findall(r'[/][v][0-9]+\.[0-9]+[/]', href)
+ #if no version was found, try finding /v#.# at the end of the string
+ if not version:
+ version = re.findall(r'[/][v][0-9]+\.[0-9]+$', href)
+ version = re.findall(r'[0-9]+\.[0-9]', version[0])[0]
+ except IndexError:
+ version = '1.0'
+ return version
diff --git a/nova/api/openstack/consoles.py b/nova/api/openstack/consoles.py
index 7a43fba96..d2655acfa 100644
--- a/nova/api/openstack/consoles.py
+++ b/nova/api/openstack/consoles.py
@@ -16,10 +16,10 @@
# under the License.
from webob import exc
+import webob
from nova import console
from nova import exception
-from nova.api.openstack import faults
from nova.api.openstack import wsgi
@@ -71,12 +71,12 @@ class Controller(object):
int(server_id),
int(id))
except exception.NotFound:
- return faults.Fault(exc.HTTPNotFound())
+ raise exc.HTTPNotFound()
return _translate_detail_keys(console)
def update(self, req, server_id, id):
"""You can't update a console"""
- raise faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def delete(self, req, server_id, id):
"""Deletes a console"""
@@ -85,8 +85,8 @@ class Controller(object):
int(server_id),
int(id))
except exception.NotFound:
- return faults.Fault(exc.HTTPNotFound())
- return exc.HTTPAccepted()
+ raise exc.HTTPNotFound()
+ return webob.Response(status_int=202)
def create_resource():
diff --git a/nova/api/openstack/contrib/multinic.py b/nova/api/openstack/contrib/multinic.py
index 841061721..da8dcee5d 100644
--- a/nova/api/openstack/contrib/multinic.py
+++ b/nova/api/openstack/contrib/multinic.py
@@ -16,6 +16,7 @@
"""The multinic extension."""
from webob import exc
+import webob
from nova import compute
from nova import log as logging
@@ -103,7 +104,7 @@ class Multinic(extensions.ExtensionDescriptor):
except Exception, e:
LOG.exception(_("Error in addFixedIp %s"), e)
return faults.Fault(exc.HTTPBadRequest())
- return exc.HTTPAccepted()
+ return webob.Response(status_int=202)
def _remove_fixed_ip(self, input_dict, req, id):
"""Removes an IP from an instance."""
@@ -122,4 +123,4 @@ class Multinic(extensions.ExtensionDescriptor):
except Exception, e:
LOG.exception(_("Error in removeFixedIp %s"), e)
return faults.Fault(exc.HTTPBadRequest())
- return exc.HTTPAccepted()
+ return webob.Response(status_int=202)
diff --git a/nova/api/openstack/contrib/volumes.py b/nova/api/openstack/contrib/volumes.py
index e5e2c5b50..867fe301e 100644
--- a/nova/api/openstack/contrib/volumes.py
+++ b/nova/api/openstack/contrib/volumes.py
@@ -16,15 +16,18 @@
"""The volumes extension."""
from webob import exc
+import webob
from nova import compute
from nova import exception
from nova import flags
from nova import log as logging
+from nova import quota
from nova import volume
from nova.api.openstack import common
from nova.api.openstack import extensions
from nova.api.openstack import faults
+from nova.api.openstack import servers
LOG = logging.getLogger("nova.api.volumes")
@@ -104,7 +107,7 @@ class VolumeController(object):
self.volume_api.delete(context, volume_id=id)
except exception.NotFound:
return faults.Fault(exc.HTTPNotFound())
- return exc.HTTPAccepted()
+ return webob.Response(status_int=202)
def index(self, req):
"""Returns a summary list of volumes."""
@@ -279,7 +282,7 @@ class VolumeAttachmentController(object):
self.compute_api.detach_volume(context,
volume_id=volume_id)
- return exc.HTTPAccepted()
+ return webob.Response(status_int=202)
def _items(self, req, server_id, entity_maker):
"""Returns a list of attachments, transformed through entity_maker."""
@@ -296,6 +299,53 @@ class VolumeAttachmentController(object):
return {'volumeAttachments': res}
+class BootFromVolumeController(servers.ControllerV11):
+ """The boot from volume API controller for the Openstack API."""
+
+ def _create_instance(self, context, instance_type, image_href, **kwargs):
+ try:
+ return self.compute_api.create(context, instance_type,
+ image_href, **kwargs)
+ except quota.QuotaError as error:
+ self.helper._handle_quota_error(error)
+ except exception.ImageNotFound as error:
+ msg = _("Can not find requested image")
+ raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
+
+ def create(self, req, body):
+ """ Creates a new server for a given user """
+ extra_values = None
+ try:
+
+ def get_kwargs(context, instance_type, image_href, **kwargs):
+ kwargs['context'] = context
+ kwargs['instance_type'] = instance_type
+ kwargs['image_href'] = image_href
+ return kwargs
+
+ extra_values, kwargs = self.helper.create_instance(req, body,
+ get_kwargs)
+
+ block_device_mapping = body['server'].get('block_device_mapping')
+ kwargs['block_device_mapping'] = block_device_mapping
+
+ instances = self._create_instance(**kwargs)
+ except faults.Fault, f:
+ return f
+
+ # We can only return 1 instance via the API, if we happen to
+ # build more than one... instances is a list, so we'll just
+ # use the first one..
+ inst = instances[0]
+ for key in ['instance_type', 'image_ref']:
+ inst[key] = extra_values[key]
+
+ builder = self._get_view_builder(req)
+ server = builder.build(inst, is_detail=True)
+ server['server']['adminPass'] = extra_values['password']
+ return server
+
+
class Volumes(extensions.ExtensionDescriptor):
def get_name(self):
return "Volumes"
@@ -329,4 +379,8 @@ class Volumes(extensions.ExtensionDescriptor):
collection_name='servers'))
resources.append(res)
+ res = extensions.ResourceExtension('os-volumes_boot',
+ BootFromVolumeController())
+ resources.append(res)
+
return resources
diff --git a/nova/api/openstack/create_instance_helper.py b/nova/api/openstack/create_instance_helper.py
index 2654e3c40..f8317565e 100644
--- a/nova/api/openstack/create_instance_helper.py
+++ b/nova/api/openstack/create_instance_helper.py
@@ -28,7 +28,6 @@ from nova import quota
from nova import utils
from nova.compute import instance_types
-from nova.api.openstack import faults
from nova.api.openstack import wsgi
from nova.auth import manager as auth_manager
@@ -70,11 +69,14 @@ class CreateInstanceHelper(object):
return type from this method is left to the caller.
"""
if not body:
- raise faults.Fault(exc.HTTPUnprocessableEntity())
+ raise exc.HTTPUnprocessableEntity()
- context = req.environ['nova.context']
+ if not 'server' in body:
+ raise exc.HTTPUnprocessableEntity()
- password = self.controller._get_server_admin_password(body['server'])
+ server_dict = body['server']
+ context = req.environ['nova.context']
+ password = self.controller._get_server_admin_password(server_dict)
key_name = None
key_data = None
@@ -94,28 +96,32 @@ class CreateInstanceHelper(object):
except Exception, e:
msg = _("Cannot find requested image %(image_href)s: %(e)s" %
locals())
- raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
+ raise exc.HTTPBadRequest(explanation=msg)
- personality = body['server'].get('personality')
+ personality = server_dict.get('personality')
injected_files = []
if personality:
injected_files = self._get_injected_files(personality)
- flavor_id = self.controller._flavor_id_from_req_data(body)
+ try:
+ flavor_id = self.controller._flavor_id_from_req_data(body)
+ except ValueError as error:
+ msg = _("Invalid flavorRef provided.")
+ raise exc.HTTPBadRequest(explanation=msg)
- if not 'name' in body['server']:
+ if not 'name' in server_dict:
msg = _("Server name is not defined")
raise exc.HTTPBadRequest(explanation=msg)
- zone_blob = body['server'].get('blob')
- name = body['server']['name']
+ zone_blob = server_dict.get('blob')
+ name = server_dict['name']
self._validate_server_name(name)
name = name.strip()
- reservation_id = body['server'].get('reservation_id')
- min_count = body['server'].get('min_count')
- max_count = body['server'].get('max_count')
+ reservation_id = server_dict.get('reservation_id')
+ min_count = server_dict.get('min_count')
+ max_count = server_dict.get('max_count')
# min_count and max_count are optional. If they exist, they come
# in as strings. We want to default 'min_count' to 1, and default
# 'max_count' to be 'min_count'.
@@ -142,7 +148,7 @@ class CreateInstanceHelper(object):
display_description=name,
key_name=key_name,
key_data=key_data,
- metadata=body['server'].get('metadata', {}),
+ metadata=server_dict.get('metadata', {}),
injected_files=injected_files,
admin_password=password,
zone_blob=zone_blob,
@@ -153,8 +159,10 @@ class CreateInstanceHelper(object):
self._handle_quota_error(error)
except exception.ImageNotFound as error:
msg = _("Can not find requested image")
- raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
-
+ raise exc.HTTPBadRequest(explanation=msg)
+ except exception.FlavorNotFound as error:
+ msg = _("Invalid flavorRef provided.")
+ raise exc.HTTPBadRequest(explanation=msg)
# Let the caller deal with unhandled exceptions.
def _handle_quota_error(self, error):
@@ -277,7 +285,7 @@ class CreateInstanceHelper(object):
return password
-class ServerXMLDeserializer(wsgi.XMLDeserializer):
+class ServerXMLDeserializer(wsgi.MetadataXMLDeserializer):
"""
Deserializer to handle xml-formatted server create requests.
@@ -294,11 +302,12 @@ class ServerXMLDeserializer(wsgi.XMLDeserializer):
def _extract_server(self, node):
"""Marshal the server attribute of a parsed request"""
server = {}
- server_node = self._find_first_child_named(node, 'server')
+ server_node = self.find_first_child_named(node, 'server')
for attr in ["name", "imageId", "flavorId", "imageRef", "flavorRef"]:
if server_node.getAttribute(attr):
server[attr] = server_node.getAttribute(attr)
- metadata = self._extract_metadata(server_node)
+ metadata_node = self.find_first_child_named(server_node, "metadata")
+ metadata = self.extract_metadata(metadata_node)
if metadata is not None:
server["metadata"] = metadata
personality = self._extract_personality(server_node)
@@ -306,49 +315,17 @@ class ServerXMLDeserializer(wsgi.XMLDeserializer):
server["personality"] = personality
return server
- def _extract_metadata(self, server_node):
- """Marshal the metadata attribute of a parsed request"""
- metadata_node = self._find_first_child_named(server_node, "metadata")
- if metadata_node is None:
- return None
- metadata = {}
- for meta_node in self._find_children_named(metadata_node, "meta"):
- key = meta_node.getAttribute("key")
- metadata[key] = self._extract_text(meta_node)
- return metadata
-
def _extract_personality(self, server_node):
"""Marshal the personality attribute of a parsed request"""
personality_node = \
- self._find_first_child_named(server_node, "personality")
+ self.find_first_child_named(server_node, "personality")
if personality_node is None:
return None
personality = []
- for file_node in self._find_children_named(personality_node, "file"):
+ for file_node in self.find_children_named(personality_node, "file"):
item = {}
if file_node.hasAttribute("path"):
item["path"] = file_node.getAttribute("path")
- item["contents"] = self._extract_text(file_node)
+ item["contents"] = self.extract_text(file_node)
personality.append(item)
return personality
-
- def _find_first_child_named(self, parent, name):
- """Search a nodes children for the first child with a given name"""
- for node in parent.childNodes:
- if node.nodeName == name:
- return node
- return None
-
- def _find_children_named(self, parent, name):
- """Return all of a nodes children who have the given name"""
- for node in parent.childNodes:
- if node.nodeName == name:
- yield node
-
- def _extract_text(self, node):
- """Get the text field contained by the given node"""
- if len(node.childNodes) == 1:
- child = node.childNodes[0]
- if child.nodeType == child.TEXT_NODE:
- return child.nodeValue
- return ""
diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py
index da06ecd15..cc889703e 100644
--- a/nova/api/openstack/extensions.py
+++ b/nova/api/openstack/extensions.py
@@ -23,6 +23,7 @@ import sys
import routes
import webob.dec
import webob.exc
+from xml.etree import ElementTree
from nova import exception
from nova import flags
@@ -194,7 +195,7 @@ class ExtensionsResource(wsgi.Resource):
def show(self, req, id):
# NOTE(dprince): the extensions alias is used as the 'id' for show
ext = self.extension_manager.extensions[id]
- return self._translate(ext)
+ return dict(extension=self._translate(ext))
def delete(self, req, id):
raise faults.Fault(webob.exc.HTTPNotFound())
@@ -258,15 +259,18 @@ class ExtensionMiddleware(base_wsgi.Middleware):
mapper = routes.Mapper()
+ serializer = wsgi.ResponseSerializer(
+ {'application/xml': ExtensionsXMLSerializer()})
# extended resources
for resource in ext_mgr.get_resources():
LOG.debug(_('Extended resource: %s'),
resource.collection)
mapper.resource(resource.collection, resource.collection,
- controller=wsgi.Resource(resource.controller),
- collection=resource.collection_actions,
- member=resource.member_actions,
- parent_resource=resource.parent)
+ controller=wsgi.Resource(
+ resource.controller, serializer=serializer),
+ collection=resource.collection_actions,
+ member=resource.member_actions,
+ parent_resource=resource.parent)
# extended actions
action_resources = self._action_ext_resources(application, ext_mgr,
@@ -462,3 +466,40 @@ class ResourceExtension(object):
self.parent = parent
self.collection_actions = collection_actions
self.member_actions = member_actions
+
+
+class ExtensionsXMLSerializer(wsgi.XMLDictSerializer):
+
+ def show(self, ext_dict):
+ ext = self._create_ext_elem(ext_dict['extension'])
+ return self._to_xml(ext)
+
+ def index(self, exts_dict):
+ exts = ElementTree.Element('extensions')
+ for ext_dict in exts_dict['extensions']:
+ exts.append(self._create_ext_elem(ext_dict))
+ return self._to_xml(exts)
+
+ def _create_ext_elem(self, ext_dict):
+ """Create an extension xml element from a dict."""
+ ext_elem = ElementTree.Element('extension')
+ ext_elem.set('name', ext_dict['name'])
+ ext_elem.set('namespace', ext_dict['namespace'])
+ ext_elem.set('alias', ext_dict['alias'])
+ ext_elem.set('updated', ext_dict['updated'])
+ desc = ElementTree.Element('description')
+ desc.text = ext_dict['description']
+ ext_elem.append(desc)
+ for link in ext_dict.get('links', []):
+ elem = ElementTree.Element('atom:link')
+ elem.set('rel', link['rel'])
+ elem.set('href', link['href'])
+ elem.set('type', link['type'])
+ ext_elem.append(elem)
+ return ext_elem
+
+ def _to_xml(self, root):
+ """Convert the xml tree object to an xml string."""
+ root.set('xmlns', wsgi.XMLNS_V11)
+ root.set('xmlns:atom', wsgi.XMLNS_ATOM)
+ return ElementTree.tostring(root, encoding='UTF-8')
diff --git a/nova/api/openstack/faults.py b/nova/api/openstack/faults.py
index b9a23c126..1ab45d4f1 100644
--- a/nova/api/openstack/faults.py
+++ b/nova/api/openstack/faults.py
@@ -19,6 +19,7 @@
import webob.dec
import webob.exc
+from nova.api.openstack import common
from nova.api.openstack import wsgi
@@ -40,6 +41,7 @@ class Fault(webob.exc.HTTPException):
def __init__(self, exception):
"""Create a Fault for the given webob.exc.exception."""
self.wrapped_exc = exception
+ self.status_int = exception.status_int
@webob.dec.wsgify(RequestClass=wsgi.Request)
def __call__(self, req):
@@ -60,9 +62,13 @@ class Fault(webob.exc.HTTPException):
content_type = req.best_match_content_type()
+ xml_serializer = {
+ '1.0': wsgi.XMLDictSerializer(metadata, wsgi.XMLNS_V10),
+ '1.1': wsgi.XMLDictSerializer(metadata, wsgi.XMLNS_V11),
+ }[common.get_version_from_href(req.url)]
+
serializer = {
- 'application/xml': wsgi.XMLDictSerializer(metadata=metadata,
- xmlns=wsgi.XMLNS_V10),
+ 'application/xml': xml_serializer,
'application/json': wsgi.JSONDictSerializer(),
}[content_type]
@@ -99,9 +105,13 @@ class OverLimitFault(webob.exc.HTTPException):
content_type = request.best_match_content_type()
metadata = {"attributes": {"overLimitFault": "code"}}
+ xml_serializer = {
+ '1.0': wsgi.XMLDictSerializer(metadata, wsgi.XMLNS_V10),
+ '1.1': wsgi.XMLDictSerializer(metadata, wsgi.XMLNS_V11),
+ }[common.get_version_from_href(request.url)]
+
serializer = {
- 'application/xml': wsgi.XMLDictSerializer(metadata=metadata,
- xmlns=wsgi.XMLNS_V10),
+ 'application/xml': xml_serializer,
'application/json': wsgi.JSONDictSerializer(),
}[content_type]
diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py
index 6fab13147..b4bda68d4 100644
--- a/nova/api/openstack/flavors.py
+++ b/nova/api/openstack/flavors.py
@@ -16,6 +16,7 @@
# under the License.
import webob
+import xml.dom.minidom as minidom
from nova import db
from nova import exception
@@ -74,19 +75,65 @@ class ControllerV11(Controller):
return views.flavors.ViewBuilderV11(base_url)
+class FlavorXMLSerializer(wsgi.XMLDictSerializer):
+
+ def __init__(self):
+ super(FlavorXMLSerializer, self).__init__(xmlns=wsgi.XMLNS_V11)
+
+ def _flavor_to_xml(self, xml_doc, flavor, detailed):
+ flavor_node = xml_doc.createElement('flavor')
+ flavor_node.setAttribute('id', str(flavor['id']))
+ flavor_node.setAttribute('name', flavor['name'])
+
+ if detailed:
+ flavor_node.setAttribute('ram', str(flavor['ram']))
+ flavor_node.setAttribute('disk', str(flavor['disk']))
+
+ link_nodes = self._create_link_nodes(xml_doc, flavor['links'])
+ for link_node in link_nodes:
+ flavor_node.appendChild(link_node)
+ return flavor_node
+
+ def _flavors_list_to_xml(self, xml_doc, flavors, detailed):
+ container_node = xml_doc.createElement('flavors')
+
+ for flavor in flavors:
+ item_node = self._flavor_to_xml(xml_doc, flavor, detailed)
+ container_node.appendChild(item_node)
+ return container_node
+
+ def show(self, flavor_container):
+ xml_doc = minidom.Document()
+ flavor = flavor_container['flavor']
+ node = self._flavor_to_xml(xml_doc, flavor, True)
+ return self.to_xml_string(node, True)
+
+ def detail(self, flavors_container):
+ xml_doc = minidom.Document()
+ flavors = flavors_container['flavors']
+ node = self._flavors_list_to_xml(xml_doc, flavors, True)
+ return self.to_xml_string(node, True)
+
+ def index(self, flavors_container):
+ xml_doc = minidom.Document()
+ flavors = flavors_container['flavors']
+ node = self._flavors_list_to_xml(xml_doc, flavors, False)
+ return self.to_xml_string(node, True)
+
+
def create_resource(version='1.0'):
controller = {
'1.0': ControllerV10,
'1.1': ControllerV11,
}[version]()
- xmlns = {
- '1.0': wsgi.XMLNS_V10,
- '1.1': wsgi.XMLNS_V11,
+ xml_serializer = {
+ '1.0': wsgi.XMLDictSerializer(xmlns=wsgi.XMLNS_V10),
+ '1.1': FlavorXMLSerializer(),
}[version]
body_serializers = {
- 'application/xml': wsgi.XMLDictSerializer(xmlns=xmlns),
+ 'application/xml': xml_serializer,
}
serializer = wsgi.ResponseSerializer(body_serializers)
diff --git a/nova/api/openstack/image_metadata.py b/nova/api/openstack/image_metadata.py
index 4f33844fa..ee181c924 100644
--- a/nova/api/openstack/image_metadata.py
+++ b/nova/api/openstack/image_metadata.py
@@ -22,7 +22,6 @@ from nova import flags
from nova import image
from nova import quota
from nova import utils
-from nova.api.openstack import faults
from nova.api.openstack import wsgi
@@ -62,7 +61,7 @@ class Controller(object):
if id in metadata:
return {'meta': {id: metadata[id]}}
else:
- return faults.Fault(exc.HTTPNotFound())
+ raise exc.HTTPNotFound()
def create(self, req, image_id, body):
context = req.environ['nova.context']
@@ -97,20 +96,54 @@ class Controller(object):
self._check_quota_limit(context, metadata)
img['properties'] = metadata
self.image_service.update(context, image_id, img, None)
+ return dict(meta=meta)
- return req.body
+ def update_all(self, req, image_id, body):
+ context = req.environ['nova.context']
+ img = self.image_service.show(context, image_id)
+ metadata = body.get('metadata', {})
+ self._check_quota_limit(context, metadata)
+ img['properties'] = metadata
+ self.image_service.update(context, image_id, img, None)
+ return dict(metadata=metadata)
def delete(self, req, image_id, id):
context = req.environ['nova.context']
img = self.image_service.show(context, image_id)
metadata = self._get_metadata(context, image_id)
if not id in metadata:
- return faults.Fault(exc.HTTPNotFound())
+ raise exc.HTTPNotFound()
metadata.pop(id)
img['properties'] = metadata
self.image_service.update(context, image_id, img, None)
+class ImageMetadataXMLDeserializer(wsgi.MetadataXMLDeserializer):
+
+ def _extract_metadata_container(self, datastring):
+ dom = minidom.parseString(datastring)
+ metadata_node = self.find_first_child_named(dom, "metadata")
+ metadata = self.extract_metadata(metadata_node)
+ return {'body': {'metadata': metadata}}
+
+ def create(self, datastring):
+ return self._extract_metadata_container(datastring)
+
+ def update_all(self, datastring):
+ return self._extract_metadata_container(datastring)
+
+ def update(self, datastring):
+ dom = minidom.parseString(datastring)
+ metadata_item = self.extract_metadata(dom)
+ return {'body': {'meta': metadata_item}}
+
+
+class HeadersSerializer(wsgi.ResponseHeadersSerializer):
+
+ def delete(self, response, data):
+ response.status_int = 204
+
+
class ImageMetadataXMLSerializer(wsgi.XMLDictSerializer):
def __init__(self, xmlns=wsgi.XMLNS_V11):
super(ImageMetadataXMLSerializer, self).__init__(xmlns=xmlns)
@@ -144,6 +177,9 @@ class ImageMetadataXMLSerializer(wsgi.XMLDictSerializer):
def create(self, metadata_dict):
return self._meta_list_to_xml_string(metadata_dict)
+ def update_all(self, metadata_dict):
+ return self._meta_list_to_xml_string(metadata_dict)
+
def _meta_item_to_xml_string(self, meta_item_dict):
xml_doc = minidom.Document()
item_key, item_value = meta_item_dict.items()[0]
@@ -158,11 +194,21 @@ class ImageMetadataXMLSerializer(wsgi.XMLDictSerializer):
def update(self, meta_item_dict):
return self._meta_item_to_xml_string(meta_item_dict['meta'])
+ def default(self, *args, **kwargs):
+ return ''
+
def create_resource():
+ headers_serializer = HeadersSerializer()
+
+ body_deserializers = {
+ 'application/xml': ImageMetadataXMLDeserializer(),
+ }
+
body_serializers = {
'application/xml': ImageMetadataXMLSerializer(),
}
- serializer = wsgi.ResponseSerializer(body_serializers)
+ serializer = wsgi.ResponseSerializer(body_serializers, headers_serializer)
+ deserializer = wsgi.RequestDeserializer(body_deserializers)
- return wsgi.Resource(Controller(), serializer=serializer)
+ return wsgi.Resource(Controller(), deserializer, serializer)
diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py
index d0317583e..30e4fd389 100644
--- a/nova/api/openstack/images.py
+++ b/nova/api/openstack/images.py
@@ -25,7 +25,6 @@ from nova import flags
import nova.image
from nova import log
from nova.api.openstack import common
-from nova.api.openstack import faults
from nova.api.openstack import image_metadata
from nova.api.openstack import servers
from nova.api.openstack.views import images as images_view
@@ -35,7 +34,13 @@ from nova.api.openstack import wsgi
LOG = log.getLogger('nova.api.openstack.images')
FLAGS = flags.FLAGS
-SUPPORTED_FILTERS = ['name', 'status']
+SUPPORTED_FILTERS = {
+ 'name': 'name',
+ 'status': 'status',
+ 'changes-since': 'changes-since',
+ 'server': 'property-instance_ref',
+ 'type': 'property-image_type',
+}
class Controller(object):
@@ -62,8 +67,9 @@ class Controller(object):
filters = {}
for param in req.str_params:
if param in SUPPORTED_FILTERS or param.startswith('property-'):
- filters[param] = req.str_params.get(param)
-
+ # map filter name or carry through if property-*
+ filter_name = SUPPORTED_FILTERS.get(param, param)
+ filters[filter_name] = req.str_params.get(param)
return filters
def show(self, req, id):
@@ -78,7 +84,7 @@ class Controller(object):
image = self._image_service.show(context, id)
except (exception.NotFound, exception.InvalidImageRef):
explanation = _("Image not found.")
- raise faults.Fault(webob.exc.HTTPNotFound(explanation=explanation))
+ raise webob.exc.HTTPNotFound(explanation=explanation)
return dict(image=self.get_builder(req).build(image, detail=True))
diff --git a/nova/api/openstack/ips.py b/nova/api/openstack/ips.py
index 1ebfdb831..a74fae487 100644
--- a/nova/api/openstack/ips.py
+++ b/nova/api/openstack/ips.py
@@ -16,11 +16,11 @@
# under the License.
import time
+from xml.dom import minidom
from webob import exc
import nova
-from nova.api.openstack import faults
import nova.api.openstack.views.addresses
from nova.api.openstack import wsgi
from nova import db
@@ -37,14 +37,14 @@ class Controller(object):
instance = self.compute_api.get(
req.environ['nova.context'], server_id)
except nova.exception.NotFound:
- return faults.Fault(exc.HTTPNotFound())
+ raise exc.HTTPNotFound()
return instance
def create(self, req, server_id, body):
- return faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def delete(self, req, server_id, id):
- return faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
class ControllerV10(Controller):
@@ -63,7 +63,7 @@ class ControllerV10(Controller):
view = builder.build_public_parts(instance)
else:
msg = _("Only private and public networks available")
- return faults.Fault(exc.HTTPNotFound(explanation=msg))
+ raise exc.HTTPNotFound(explanation=msg)
return {id: view}
@@ -86,7 +86,7 @@ class ControllerV11(Controller):
if network is None:
msg = _("Instance is not a member of specified network")
- return faults.Fault(exc.HTTPNotFound(explanation=msg))
+ raise exc.HTTPNotFound(explanation=msg)
return network
@@ -101,17 +101,51 @@ class ControllerV11(Controller):
return nova.api.openstack.views.addresses.ViewBuilderV11()
+class IPXMLSerializer(wsgi.XMLDictSerializer):
+ def __init__(self, xmlns=wsgi.XMLNS_V11):
+ super(IPXMLSerializer, self).__init__(xmlns=xmlns)
+
+ def _ip_to_xml(self, xml_doc, ip_dict):
+ ip_node = xml_doc.createElement('ip')
+ ip_node.setAttribute('addr', ip_dict['addr'])
+ ip_node.setAttribute('version', str(ip_dict['version']))
+ return ip_node
+
+ def _network_to_xml(self, xml_doc, network_id, ip_dicts):
+ network_node = xml_doc.createElement('network')
+ network_node.setAttribute('id', network_id)
+
+ for ip_dict in ip_dicts:
+ ip_node = self._ip_to_xml(xml_doc, ip_dict)
+ network_node.appendChild(ip_node)
+
+ return network_node
+
+ def networks_to_xml(self, xml_doc, networks_container):
+ addresses_node = xml_doc.createElement('addresses')
+ for (network_id, ip_dicts) in networks_container.items():
+ network_node = self._network_to_xml(xml_doc, network_id, ip_dicts)
+ addresses_node.appendChild(network_node)
+ return addresses_node
+
+ def show(self, network_container):
+ (network_id, ip_dicts) = network_container.items()[0]
+ xml_doc = minidom.Document()
+ node = self._network_to_xml(xml_doc, network_id, ip_dicts)
+ return self.to_xml_string(node, False)
+
+ def index(self, addresses_container):
+ xml_doc = minidom.Document()
+ node = self.networks_to_xml(xml_doc, addresses_container['addresses'])
+ return self.to_xml_string(node, False)
+
+
def create_resource(version):
controller = {
'1.0': ControllerV10,
'1.1': ControllerV11,
}[version]()
- xmlns = {
- '1.0': wsgi.XMLNS_V10,
- '1.1': wsgi.XMLNS_V11,
- }[version]
-
metadata = {
'list_collections': {
'public': {'item_name': 'ip', 'item_key': 'addr'},
@@ -119,10 +153,11 @@ def create_resource(version):
},
}
- body_serializers = {
- 'application/xml': wsgi.XMLDictSerializer(metadata=metadata,
- xmlns=xmlns),
- }
- serializer = wsgi.ResponseSerializer(body_serializers)
+ xml_serializer = {
+ '1.0': wsgi.XMLDictSerializer(metadata=metadata, xmlns=wsgi.XMLNS_V11),
+ '1.1': IPXMLSerializer(),
+ }[version]
+
+ serializer = wsgi.ResponseSerializer({'application/xml': xml_serializer})
return wsgi.Resource(controller, serializer=serializer)
diff --git a/nova/api/openstack/limits.py b/nova/api/openstack/limits.py
index bc76547d8..86afa3b62 100644
--- a/nova/api/openstack/limits.py
+++ b/nova/api/openstack/limits.py
@@ -25,6 +25,7 @@ import re
import time
import urllib
import webob.exc
+from xml.dom import minidom
from collections import defaultdict
@@ -76,6 +77,58 @@ class LimitsControllerV11(LimitsController):
return limits_views.ViewBuilderV11()
+class LimitsXMLSerializer(wsgi.XMLDictSerializer):
+
+ xmlns = wsgi.XMLNS_V11
+
+ def __init__(self):
+ pass
+
+ def _create_rates_node(self, xml_doc, rates):
+ rates_node = xml_doc.createElement('rates')
+ for rate in rates:
+ rate_node = xml_doc.createElement('rate')
+ rate_node.setAttribute('uri', rate['uri'])
+ rate_node.setAttribute('regex', rate['regex'])
+
+ for limit in rate['limit']:
+ limit_node = xml_doc.createElement('limit')
+ limit_node.setAttribute('value', str(limit['value']))
+ limit_node.setAttribute('verb', limit['verb'])
+ limit_node.setAttribute('remaining', str(limit['remaining']))
+ limit_node.setAttribute('unit', limit['unit'])
+ limit_node.setAttribute('next-available',
+ str(limit['next-available']))
+ rate_node.appendChild(limit_node)
+
+ rates_node.appendChild(rate_node)
+ return rates_node
+
+ def _create_absolute_node(self, xml_doc, absolutes):
+ absolute_node = xml_doc.createElement('absolute')
+ for key, value in absolutes.iteritems():
+ limit_node = xml_doc.createElement('limit')
+ limit_node.setAttribute('name', key)
+ limit_node.setAttribute('value', str(value))
+ absolute_node.appendChild(limit_node)
+ return absolute_node
+
+ def _limits_to_xml(self, xml_doc, limits):
+ limits_node = xml_doc.createElement('limits')
+ rates_node = self._create_rates_node(xml_doc, limits['rate'])
+ limits_node.appendChild(rates_node)
+
+ absolute_node = self._create_absolute_node(xml_doc, limits['absolute'])
+ limits_node.appendChild(absolute_node)
+
+ return limits_node
+
+ def index(self, limits_dict):
+ xml_doc = minidom.Document()
+ node = self._limits_to_xml(xml_doc, limits_dict['limits'])
+ return self.to_xml_string(node, False)
+
+
def create_resource(version='1.0'):
controller = {
'1.0': LimitsControllerV10,
@@ -97,9 +150,13 @@ def create_resource(version='1.0'):
},
}
+ xml_serializer = {
+ '1.0': wsgi.XMLDictSerializer(xmlns=xmlns, metadata=metadata),
+ '1.1': LimitsXMLSerializer(),
+ }[version]
+
body_serializers = {
- 'application/xml': wsgi.XMLDictSerializer(xmlns=xmlns,
- metadata=metadata),
+ 'application/xml': xml_serializer,
}
serializer = wsgi.ResponseSerializer(body_serializers)
diff --git a/nova/api/openstack/server_metadata.py b/nova/api/openstack/server_metadata.py
index 3b9169f81..d4f42bbf5 100644
--- a/nova/api/openstack/server_metadata.py
+++ b/nova/api/openstack/server_metadata.py
@@ -18,7 +18,6 @@
from webob import exc
from nova import compute
-from nova.api.openstack import faults
from nova.api.openstack import wsgi
from nova import exception
from nova import quota
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index 8ec74b387..2573fc48c 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -17,6 +17,7 @@ import base64
import traceback
from webob import exc
+import webob
from nova import compute
from nova import db
@@ -26,7 +27,6 @@ from nova import log as logging
from nova import utils
from nova.api.openstack import common
from nova.api.openstack import create_instance_helper as helper
-from nova.api.openstack import faults
import nova.api.openstack.views.addresses
import nova.api.openstack.views.flavors
import nova.api.openstack.views.images
@@ -155,17 +155,14 @@ class Controller(object):
req.environ['nova.context'], id)
return self._build_view(req, instance, is_detail=True)
except exception.NotFound:
- return faults.Fault(exc.HTTPNotFound())
+ raise exc.HTTPNotFound()
def create(self, req, body):
""" Creates a new server for a given user """
extra_values = None
result = None
- try:
- extra_values, instances = self.helper.create_instance(
- req, body, self.compute_api.create)
- except faults.Fault, f:
- return f
+ extra_values, instances = self.helper.create_instance(
+ req, body, self.compute_api.create)
# We can only return 1 instance via the API, if we happen to
# build more than one... instances is a list, so we'll just
@@ -185,7 +182,7 @@ class Controller(object):
raise exc.HTTPUnprocessableEntity()
if not body:
- return faults.Fault(exc.HTTPUnprocessableEntity())
+ raise exc.HTTPUnprocessableEntity()
ctxt = req.environ['nova.context']
update_dict = {}
@@ -200,7 +197,7 @@ class Controller(object):
try:
self.compute_api.update(ctxt, id, **update_dict)
except exception.NotFound:
- return faults.Fault(exc.HTTPNotFound())
+ raise exc.HTTPNotFound()
return exc.HTTPNoContent()
@@ -224,7 +221,7 @@ class Controller(object):
for key in actions.keys():
if key in body:
return actions[key](body, req, id)
- return faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def _action_change_password(self, input_dict, req, id):
return exc.HTTPNotImplemented()
@@ -234,7 +231,7 @@ class Controller(object):
self.compute_api.confirm_resize(req.environ['nova.context'], id)
except Exception, e:
LOG.exception(_("Error in confirm-resize %s"), e)
- return faults.Fault(exc.HTTPBadRequest())
+ raise exc.HTTPBadRequest()
return exc.HTTPNoContent()
def _action_revert_resize(self, input_dict, req, id):
@@ -242,8 +239,8 @@ class Controller(object):
self.compute_api.revert_resize(req.environ['nova.context'], id)
except Exception, e:
LOG.exception(_("Error in revert-resize %s"), e)
- return faults.Fault(exc.HTTPBadRequest())
- return exc.HTTPAccepted()
+ raise exc.HTTPBadRequest()
+ return webob.Response(status_int=202)
def _action_resize(self, input_dict, req, id):
return exc.HTTPNotImplemented()
@@ -253,23 +250,23 @@ class Controller(object):
reboot_type = input_dict['reboot']['type']
else:
LOG.exception(_("Missing argument 'type' for reboot"))
- return faults.Fault(exc.HTTPUnprocessableEntity())
+ raise exc.HTTPUnprocessableEntity()
try:
# TODO(gundlach): pass reboot_type, support soft reboot in
# virt driver
self.compute_api.reboot(req.environ['nova.context'], id)
except Exception, e:
LOG.exception(_("Error in reboot %s"), e)
- return faults.Fault(exc.HTTPUnprocessableEntity())
- return exc.HTTPAccepted()
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
def _action_migrate(self, input_dict, req, id):
try:
self.compute_api.resize(req.environ['nova.context'], id)
except Exception, e:
LOG.exception(_("Error in migrate %s"), e)
- return faults.Fault(exc.HTTPBadRequest())
- return exc.HTTPAccepted()
+ raise exc.HTTPBadRequest()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def lock(self, req, id):
@@ -284,8 +281,8 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::lock %s"), readable)
- return faults.Fault(exc.HTTPUnprocessableEntity())
- return exc.HTTPAccepted()
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def unlock(self, req, id):
@@ -300,8 +297,8 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::unlock %s"), readable)
- return faults.Fault(exc.HTTPUnprocessableEntity())
- return exc.HTTPAccepted()
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def get_lock(self, req, id):
@@ -315,8 +312,8 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::get_lock %s"), readable)
- return faults.Fault(exc.HTTPUnprocessableEntity())
- return exc.HTTPAccepted()
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def reset_network(self, req, id, body):
@@ -330,8 +327,8 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::reset_network %s"), readable)
- return faults.Fault(exc.HTTPUnprocessableEntity())
- return exc.HTTPAccepted()
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def inject_network_info(self, req, id, body):
@@ -345,8 +342,8 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::inject_network_info %s"), readable)
- return faults.Fault(exc.HTTPUnprocessableEntity())
- return exc.HTTPAccepted()
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def pause(self, req, id, body):
@@ -357,8 +354,8 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::pause %s"), readable)
- return faults.Fault(exc.HTTPUnprocessableEntity())
- return exc.HTTPAccepted()
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def unpause(self, req, id, body):
@@ -369,8 +366,8 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::unpause %s"), readable)
- return faults.Fault(exc.HTTPUnprocessableEntity())
- return exc.HTTPAccepted()
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def suspend(self, req, id, body):
@@ -381,8 +378,8 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("compute.api::suspend %s"), readable)
- return faults.Fault(exc.HTTPUnprocessableEntity())
- return exc.HTTPAccepted()
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def resume(self, req, id, body):
@@ -393,8 +390,8 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("compute.api::resume %s"), readable)
- return faults.Fault(exc.HTTPUnprocessableEntity())
- return exc.HTTPAccepted()
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def rescue(self, req, id):
@@ -405,8 +402,8 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("compute.api::rescue %s"), readable)
- return faults.Fault(exc.HTTPUnprocessableEntity())
- return exc.HTTPAccepted()
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def unrescue(self, req, id):
@@ -417,8 +414,8 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("compute.api::unrescue %s"), readable)
- return faults.Fault(exc.HTTPUnprocessableEntity())
- return exc.HTTPAccepted()
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def get_ajax_console(self, req, id):
@@ -427,8 +424,8 @@ class Controller(object):
self.compute_api.get_ajax_console(req.environ['nova.context'],
int(id))
except exception.NotFound:
- return faults.Fault(exc.HTTPNotFound())
- return exc.HTTPAccepted()
+ raise exc.HTTPNotFound()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def get_vnc_console(self, req, id):
@@ -437,8 +434,8 @@ class Controller(object):
self.compute_api.get_vnc_console(req.environ['nova.context'],
int(id))
except exception.NotFound:
- return faults.Fault(exc.HTTPNotFound())
- return exc.HTTPAccepted()
+ raise exc.HTTPNotFound()
+ return webob.Response(status_int=202)
@scheduler_api.redirect_handler
def diagnostics(self, req, id):
@@ -469,8 +466,8 @@ class ControllerV10(Controller):
try:
self.compute_api.delete(req.environ['nova.context'], id)
except exception.NotFound:
- return faults.Fault(exc.HTTPNotFound())
- return exc.HTTPAccepted()
+ raise exc.HTTPNotFound()
+ return webob.Response(status_int=202)
def _items(self, req, is_detail):
"""Returns a list of servers based on the request.
@@ -532,40 +529,33 @@ class ControllerV10(Controller):
def _action_resize(self, input_dict, req, id):
""" Resizes a given instance to the flavor size requested """
- try:
- if 'resize' in input_dict and 'flavorId' in input_dict['resize']:
- flavor_id = input_dict['resize']['flavorId']
- self.compute_api.resize(req.environ['nova.context'], id,
- flavor_id)
- else:
- LOG.exception(_("Missing 'flavorId' argument for resize"))
- return faults.Fault(exc.HTTPUnprocessableEntity())
- except Exception, e:
- LOG.exception(_("Error in resize %s"), e)
- return faults.Fault(exc.HTTPBadRequest())
- return exc.HTTPAccepted()
+ if 'resize' in input_dict and 'flavorId' in input_dict['resize']:
+ flavor_id = input_dict['resize']['flavorId']
+ self.compute_api.resize(req.environ['nova.context'], id,
+ flavor_id)
+ else:
+ LOG.exception(_("Missing 'flavorId' argument for resize"))
+ raise exc.HTTPUnprocessableEntity()
+ return webob.Response(status_int=202)
def _action_rebuild(self, info, request, instance_id):
context = request.environ['nova.context']
- instance_id = int(instance_id)
try:
image_id = info["rebuild"]["imageId"]
except (KeyError, TypeError):
msg = _("Could not parse imageId from request.")
LOG.debug(msg)
- return faults.Fault(exc.HTTPBadRequest(explanation=msg))
+ raise exc.HTTPBadRequest(explanation=msg)
try:
self.compute_api.rebuild(context, instance_id, image_id)
except exception.BuildInProgress:
- msg = _("Instance %d is currently being rebuilt.") % instance_id
+ msg = _("Instance %s is currently being rebuilt.") % instance_id
LOG.debug(msg)
- return faults.Fault(exc.HTTPConflict(explanation=msg))
+ raise exc.HTTPConflict(explanation=msg)
- response = exc.HTTPAccepted()
- response.empty_body = True
- return response
+ return webob.Response(status_int=202)
def _get_server_admin_password(self, server):
""" Determine the admin password for a server on creation """
@@ -580,7 +570,7 @@ class ControllerV11(Controller):
try:
self.compute_api.delete(req.environ['nova.context'], id)
except exception.NotFound:
- return faults.Fault(exc.HTTPNotFound())
+ raise exc.HTTPNotFound()
def _items(self, req, is_detail):
"""Returns a list of servers based on the request.
@@ -643,7 +633,7 @@ class ControllerV11(Controller):
msg = _("Invalid adminPass")
return exc.HTTPBadRequest(explanation=msg)
self.compute_api.set_admin_password(context, id, password)
- return exc.HTTPAccepted()
+ return webob.Response(status_int=202)
def _limit_items(self, items, req):
return common.limited_by_marker(items, req)
@@ -655,7 +645,7 @@ class ControllerV11(Controller):
except AttributeError as ex:
msg = _("Unable to parse metadata key/value pairs.")
LOG.debug(msg)
- raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
+ raise exc.HTTPBadRequest(explanation=msg)
def _decode_personalities(self, personalities):
"""Decode the Base64-encoded personalities."""
@@ -666,14 +656,14 @@ class ControllerV11(Controller):
except (KeyError, TypeError):
msg = _("Unable to parse personality path/contents.")
LOG.info(msg)
- raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
+ raise exc.HTTPBadRequest(explanation=msg)
try:
personality["contents"] = base64.b64decode(contents)
except TypeError:
msg = _("Personality content could not be Base64 decoded.")
LOG.info(msg)
- raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
+ raise exc.HTTPBadRequest(explanation=msg)
def _action_resize(self, input_dict, req, id):
""" Resizes a given instance to the flavor size requested """
@@ -685,22 +675,21 @@ class ControllerV11(Controller):
flavor_id)
else:
LOG.exception(_("Missing 'flavorRef' argument for resize"))
- return faults.Fault(exc.HTTPUnprocessableEntity())
+ raise exc.HTTPUnprocessableEntity()
except Exception, e:
LOG.exception(_("Error in resize %s"), e)
- return faults.Fault(exc.HTTPBadRequest())
- return exc.HTTPAccepted()
+ raise exc.HTTPBadRequest()
+ return webob.Response(status_int=202)
def _action_rebuild(self, info, request, instance_id):
context = request.environ['nova.context']
- instance_id = int(instance_id)
try:
image_href = info["rebuild"]["imageRef"]
except (KeyError, TypeError):
msg = _("Could not parse imageRef from request.")
LOG.debug(msg)
- return faults.Fault(exc.HTTPBadRequest(explanation=msg))
+ raise exc.HTTPBadRequest(explanation=msg)
personalities = info["rebuild"].get("personality", [])
metadata = info["rebuild"].get("metadata")
@@ -714,13 +703,11 @@ class ControllerV11(Controller):
self.compute_api.rebuild(context, instance_id, image_href, name,
metadata, personalities)
except exception.BuildInProgress:
- msg = _("Instance %d is currently being rebuilt.") % instance_id
+ msg = _("Instance %s is currently being rebuilt.") % instance_id
LOG.debug(msg)
- return faults.Fault(exc.HTTPConflict(explanation=msg))
+ raise exc.HTTPConflict(explanation=msg)
- response = exc.HTTPAccepted()
- response.empty_body = True
- return response
+ return webob.Response(status_int=202)
def get_default_xmlns(self, req):
return common.XML_NS_V11
diff --git a/nova/api/openstack/shared_ip_groups.py b/nova/api/openstack/shared_ip_groups.py
index cf2ddbabb..54d0a8334 100644
--- a/nova/api/openstack/shared_ip_groups.py
+++ b/nova/api/openstack/shared_ip_groups.py
@@ -17,7 +17,6 @@
from webob import exc
-from nova.api.openstack import faults
from nova.api.openstack import wsgi
@@ -26,27 +25,27 @@ class Controller(object):
def index(self, req, **kwargs):
""" Returns a list of Shared IP Groups for the user """
- raise faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def show(self, req, id, **kwargs):
""" Shows in-depth information on a specific Shared IP Group """
- raise faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def update(self, req, id, **kwargs):
""" You can't update a Shared IP Group """
- raise faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def delete(self, req, id, **kwargs):
""" Deletes a Shared IP Group """
- raise faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def detail(self, req, **kwargs):
""" Returns a complete list of Shared IP Groups """
- raise faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def create(self, req, **kwargs):
""" Creates a new Shared IP group """
- raise faults.Fault(exc.HTTPNotImplemented())
+ raise exc.HTTPNotImplemented()
def create_resource():
diff --git a/nova/api/openstack/users.py b/nova/api/openstack/users.py
index 6ae1eaf2a..8dd72d559 100644
--- a/nova/api/openstack/users.py
+++ b/nova/api/openstack/users.py
@@ -19,7 +19,6 @@ from nova import exception
from nova import flags
from nova import log as logging
from nova.api.openstack import common
-from nova.api.openstack import faults
from nova.api.openstack import wsgi
from nova.auth import manager
@@ -69,7 +68,7 @@ class Controller(object):
user = None
if user is None:
- raise faults.Fault(exc.HTTPNotFound())
+ raise exc.HTTPNotFound()
return dict(user=_translate_keys(user))
diff --git a/nova/api/openstack/versions.py b/nova/api/openstack/versions.py
index a634c3267..df7a94b7e 100644
--- a/nova/api/openstack/versions.py
+++ b/nova/api/openstack/versions.py
@@ -15,13 +15,18 @@
# License for the specific language governing permissions and limitations
# under the License.
+from datetime import datetime
import webob
import webob.dec
+from xml.dom import minidom
import nova.api.openstack.views.versions
from nova.api.openstack import wsgi
+ATOM_XMLNS = "http://www.w3.org/2005/Atom"
+
+
class Versions(wsgi.Resource):
def __init__(self):
metadata = {
@@ -32,11 +37,19 @@ class Versions(wsgi.Resource):
}
body_serializers = {
- 'application/xml': wsgi.XMLDictSerializer(metadata=metadata),
+ 'application/atom+xml': VersionsAtomSerializer(metadata=metadata),
+ 'application/xml': VersionsXMLSerializer(metadata=metadata),
}
serializer = wsgi.ResponseSerializer(body_serializers)
- wsgi.Resource.__init__(self, None, serializer=serializer)
+ supported_content_types = ('application/json',
+ 'application/xml',
+ 'application/atom+xml')
+ deserializer = wsgi.RequestDeserializer(
+ supported_content_types=supported_content_types)
+
+ wsgi.Resource.__init__(self, None, serializer=serializer,
+ deserializer=deserializer)
def dispatch(self, request, *args):
"""Respond to a request for all OpenStack API versions."""
@@ -44,13 +57,143 @@ class Versions(wsgi.Resource):
{
"id": "v1.1",
"status": "CURRENT",
+ #TODO(wwolf) get correct value for these
+ "updated": "2011-07-18T11:30:00Z",
},
{
"id": "v1.0",
"status": "DEPRECATED",
+ #TODO(wwolf) get correct value for these
+ "updated": "2010-10-09T11:30:00Z",
},
]
builder = nova.api.openstack.views.versions.get_view_builder(request)
versions = [builder.build(version) for version in version_objs]
return dict(versions=versions)
+
+
+class VersionsXMLSerializer(wsgi.XMLDictSerializer):
+ def _versions_to_xml(self, versions):
+ root = self._xml_doc.createElement('versions')
+
+ for version in versions:
+ root.appendChild(self._create_version_node(version))
+
+ return root
+
+ def _create_version_node(self, version):
+ version_node = self._xml_doc.createElement('version')
+ version_node.setAttribute('id', version['id'])
+ version_node.setAttribute('status', version['status'])
+ version_node.setAttribute('updated', version['updated'])
+
+ for link in version['links']:
+ link_node = self._xml_doc.createElement('atom:link')
+ link_node.setAttribute('rel', link['rel'])
+ link_node.setAttribute('href', link['href'])
+ version_node.appendChild(link_node)
+
+ return version_node
+
+ def default(self, data):
+ self._xml_doc = minidom.Document()
+ node = self._versions_to_xml(data['versions'])
+
+ return self.to_xml_string(node)
+
+
+class VersionsAtomSerializer(wsgi.XMLDictSerializer):
+ def __init__(self, metadata=None, xmlns=None):
+ if not xmlns:
+ self.xmlns = ATOM_XMLNS
+ else:
+ self.xmlns = xmlns
+
+ def _create_text_elem(self, name, text, type=None):
+ elem = self._xml_doc.createElement(name)
+ if type:
+ elem.setAttribute('type', type)
+ elem_text = self._xml_doc.createTextNode(text)
+ elem.appendChild(elem_text)
+ return elem
+
+ def _get_most_recent_update(self, versions):
+ recent = None
+ for version in versions:
+ updated = datetime.strptime(version['updated'],
+ '%Y-%m-%dT%H:%M:%SZ')
+ if not recent:
+ recent = updated
+ elif updated > recent:
+ recent = updated
+
+ return recent.strftime('%Y-%m-%dT%H:%M:%SZ')
+
+ def _get_base_url(self, link_href):
+ # Make sure no trailing /
+ link_href = link_href.rstrip('/')
+ return link_href.rsplit('/', 1)[0] + '/'
+
+ def _create_meta(self, root, versions):
+ title = self._create_text_elem('title', 'Available API Versions',
+ type='text')
+ # Set this updated to the most recently updated version
+ recent = self._get_most_recent_update(versions)
+ updated = self._create_text_elem('updated', recent)
+
+ base_url = self._get_base_url(versions[0]['links'][0]['href'])
+ id = self._create_text_elem('id', base_url)
+ link = self._xml_doc.createElement('link')
+ link.setAttribute('rel', 'self')
+ link.setAttribute('href', base_url)
+
+ author = self._xml_doc.createElement('author')
+ author_name = self._create_text_elem('name', 'Rackspace')
+ author_uri = self._create_text_elem('uri', 'http://www.rackspace.com/')
+ author.appendChild(author_name)
+ author.appendChild(author_uri)
+
+ root.appendChild(title)
+ root.appendChild(updated)
+ root.appendChild(id)
+ root.appendChild(author)
+ root.appendChild(link)
+
+ def _create_version_entries(self, root, versions):
+ for version in versions:
+ entry = self._xml_doc.createElement('entry')
+
+ id = self._create_text_elem('id', version['links'][0]['href'])
+ title = self._create_text_elem('title',
+ 'Version %s' % version['id'],
+ type='text')
+ updated = self._create_text_elem('updated', version['updated'])
+
+ entry.appendChild(id)
+ entry.appendChild(title)
+ entry.appendChild(updated)
+
+ for link in version['links']:
+ link_node = self._xml_doc.createElement('link')
+ link_node.setAttribute('rel', link['rel'])
+ link_node.setAttribute('href', link['href'])
+ entry.appendChild(link_node)
+
+ content = self._create_text_elem('content',
+ 'Version %s %s (%s)' %
+ (version['id'],
+ version['status'],
+ version['updated']),
+ type='text')
+
+ entry.appendChild(content)
+ root.appendChild(entry)
+
+ def default(self, data):
+ self._xml_doc = minidom.Document()
+ node = self._xml_doc.createElementNS(self.xmlns, 'feed')
+ self._create_meta(node, data['versions'])
+ self._create_version_entries(node, data['versions'])
+
+ return self.to_xml_string(node)
diff --git a/nova/api/openstack/views/addresses.py b/nova/api/openstack/views/addresses.py
index a242efa45..ddbf7a144 100644
--- a/nova/api/openstack/views/addresses.py
+++ b/nova/api/openstack/views/addresses.py
@@ -15,9 +15,12 @@
# License for the specific language governing permissions and limitations
# under the License.
+from nova import flags
from nova import utils
from nova.api.openstack import common
+FLAGS = flags.FLAGS
+
class ViewBuilder(object):
"""Models a server addresses response as a python dictionary."""
@@ -50,22 +53,37 @@ class ViewBuilderV11(ViewBuilder):
if network_label not in networks:
networks[network_label] = []
- networks[network_label].extend(self._extract_ipv4(interface))
+ ip_addresses = list(self._extract_ipv4_addresses(interface))
+
+ if FLAGS.use_ipv6:
+ ipv6_address = self._extract_ipv6_address(interface)
+ if ipv6_address is not None:
+ ip_addresses.append(ipv6_address)
+
+ networks[network_label].extend(ip_addresses)
return networks
def build_network(self, interfaces, network_label):
for interface in interfaces:
if interface['network']['label'] == network_label:
- ips = self._extract_ipv4(interface)
- return {network_label: list(ips)}
+ ips = list(self._extract_ipv4_addresses(interface))
+ ipv6 = self._extract_ipv6_address(interface)
+ if ipv6 is not None:
+ ips.append(ipv6)
+ return {network_label: ips}
return None
- def _extract_ipv4(self, interface):
+ def _extract_ipv4_addresses(self, interface):
for fixed_ip in interface['fixed_ips']:
yield self._build_ip_entity(fixed_ip['address'], 4)
for floating_ip in fixed_ip.get('floating_ips', []):
yield self._build_ip_entity(floating_ip['address'], 4)
+ def _extract_ipv6_address(self, interface):
+ fixed_ipv6 = interface.get('fixed_ipv6')
+ if fixed_ipv6 is not None:
+ return self._build_ip_entity(fixed_ipv6, 6)
+
def _build_ip_entity(self, address, version):
return {'addr': address, 'version': version}
diff --git a/nova/api/openstack/views/limits.py b/nova/api/openstack/views/limits.py
index 934b4921a..f603d7cb4 100644
--- a/nova/api/openstack/views/limits.py
+++ b/nova/api/openstack/views/limits.py
@@ -15,9 +15,11 @@
# License for the specific language governing permissions and limitations
# under the License.
+import datetime
import time
from nova.api.openstack import common
+from nova import utils
class ViewBuilder(object):
@@ -113,10 +115,12 @@ class ViewBuilderV11(ViewBuilder):
return limits
def _build_rate_limit(self, rate_limit):
+ next_avail = \
+ datetime.datetime.utcfromtimestamp(rate_limit["resetTime"])
return {
"verb": rate_limit["verb"],
"value": rate_limit["value"],
"remaining": int(rate_limit["remaining"]),
"unit": rate_limit["unit"],
- "next-available": rate_limit["resetTime"],
+ "next-available": utils.isotime(at=next_avail),
}
diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py
index caa4664ee..c96e14553 100644
--- a/nova/api/openstack/views/servers.py
+++ b/nova/api/openstack/views/servers.py
@@ -50,7 +50,7 @@ class ViewBuilder(object):
else:
server = self._build_simple(inst)
- self._build_extra(server, inst)
+ self._build_extra(server['server'], inst)
return server
@@ -69,7 +69,7 @@ class ViewBuilder(object):
ctxt = nova.context.get_admin_context()
compute_api = nova.compute.API()
- if compute_api.has_finished_migration(ctxt, inst['id']):
+ if compute_api.has_finished_migration(ctxt, inst['uuid']):
inst_dict['status'] = 'RESIZE-CONFIRM'
# Return the metadata as a dictionary
@@ -86,7 +86,6 @@ class ViewBuilder(object):
self._build_flavor(inst_dict, inst)
self._build_addresses(inst_dict, inst)
- inst_dict['uuid'] = inst['uuid']
return dict(server=inst_dict)
def _build_addresses(self, response, inst):
@@ -108,6 +107,9 @@ class ViewBuilder(object):
class ViewBuilderV10(ViewBuilder):
"""Model an Openstack API V1.0 server response."""
+ def _build_extra(self, response, inst):
+ response['uuid'] = inst['uuid']
+
def _build_image(self, response, inst):
if 'image_ref' in dict(inst):
image_ref = inst['image_ref']
@@ -132,18 +134,46 @@ class ViewBuilderV11(ViewBuilder):
self.image_builder = image_builder
self.base_url = base_url
+ def _build_detail(self, inst):
+ response = super(ViewBuilderV11, self)._build_detail(inst)
+ response['server']['created'] = inst['created_at']
+ response['server']['updated'] = inst['updated_at']
+ if 'status' in response['server']:
+ if response['server']['status'] == "ACTIVE":
+ response['server']['progress'] = 100
+ elif response['server']['status'] == "BUILD":
+ response['server']['progress'] = 0
+ return response
+
def _build_image(self, response, inst):
if 'image_ref' in dict(inst):
image_href = inst['image_ref']
- if str(image_href).isdigit():
- image_href = int(image_href)
- response['imageRef'] = image_href
+ image_id = str(common.get_id_from_href(image_href))
+ _bookmark = self.image_builder.generate_bookmark(image_id)
+ response['image'] = {
+ "id": image_id,
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": _bookmark,
+ },
+ ]
+ }
def _build_flavor(self, response, inst):
if "instance_type" in dict(inst):
flavor_id = inst["instance_type"]['flavorid']
flavor_ref = self.flavor_builder.generate_href(flavor_id)
- response["flavorRef"] = flavor_ref
+ flavor_bookmark = self.flavor_builder.generate_bookmark(flavor_id)
+ response["flavor"] = {
+ "id": str(common.get_id_from_href(flavor_ref)),
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": flavor_bookmark,
+ },
+ ]
+ }
def _build_addresses(self, response, inst):
interfaces = inst.get('virtual_interfaces', [])
@@ -151,6 +181,7 @@ class ViewBuilderV11(ViewBuilder):
def _build_extra(self, response, inst):
self._build_links(response, inst)
+ response['uuid'] = inst['uuid']
def _build_links(self, response, inst):
href = self.generate_href(inst["id"])
@@ -167,7 +198,7 @@ class ViewBuilderV11(ViewBuilder):
},
]
- response["server"]["links"] = links
+ response["links"] = links
def generate_href(self, server_id):
"""Create an url that refers to a specific server id."""
diff --git a/nova/api/openstack/views/versions.py b/nova/api/openstack/views/versions.py
index d0145c94a..9fa8f49dc 100644
--- a/nova/api/openstack/views/versions.py
+++ b/nova/api/openstack/views/versions.py
@@ -36,6 +36,7 @@ class ViewBuilder(object):
version = {
"id": version_data["id"],
"status": version_data["status"],
+ "updated": version_data["updated"],
"links": self._build_links(version_data),
}
@@ -56,4 +57,4 @@ class ViewBuilder(object):
def generate_href(self, version_number):
"""Create an url that refers to a specific version_number."""
- return os.path.join(self.base_url, version_number)
+ return os.path.join(self.base_url, version_number) + '/'
diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py
index c3f841aa5..a28443d12 100644
--- a/nova/api/openstack/wsgi.py
+++ b/nova/api/openstack/wsgi.py
@@ -13,6 +13,7 @@ from nova import wsgi
XMLNS_V10 = 'http://docs.rackspacecloud.com/servers/api/v1.0'
XMLNS_V11 = 'http://docs.openstack.org/compute/api/v1.1'
+XMLNS_ATOM = 'http://www.w3.org/2005/Atom'
LOG = logging.getLogger('nova.api.openstack.wsgi')
@@ -20,21 +21,22 @@ LOG = logging.getLogger('nova.api.openstack.wsgi')
class Request(webob.Request):
"""Add some Openstack API-specific logic to the base webob.Request."""
- def best_match_content_type(self):
+ def best_match_content_type(self, supported_content_types=None):
"""Determine the requested response content-type.
Based on the query extension then the Accept header.
"""
- supported = ('application/json', 'application/xml')
+ supported_content_types = supported_content_types or \
+ ('application/json', 'application/xml')
parts = self.path.rsplit('.', 1)
if len(parts) > 1:
ctype = 'application/{0}'.format(parts[1])
- if ctype in supported:
+ if ctype in supported_content_types:
return ctype
- bm = self.accept.best_match(supported)
+ bm = self.accept.best_match(supported_content_types)
# default to application/json if we don't find a preference
return bm or 'application/json'
@@ -134,10 +136,44 @@ class XMLDeserializer(TextDeserializer):
listnames)
return result
+ def find_first_child_named(self, parent, name):
+ """Search a nodes children for the first child with a given name"""
+ for node in parent.childNodes:
+ if node.nodeName == name:
+ return node
+ return None
+
+ def find_children_named(self, parent, name):
+ """Return all of a nodes children who have the given name"""
+ for node in parent.childNodes:
+ if node.nodeName == name:
+ yield node
+
+ def extract_text(self, node):
+ """Get the text field contained by the given node"""
+ if len(node.childNodes) == 1:
+ child = node.childNodes[0]
+ if child.nodeType == child.TEXT_NODE:
+ return child.nodeValue
+ return ""
+
def default(self, datastring):
return {'body': self._from_xml(datastring)}
+class MetadataXMLDeserializer(XMLDeserializer):
+
+ def extract_metadata(self, metadata_node):
+ """Marshal the metadata attribute of a parsed request"""
+ if metadata_node is None:
+ return None
+ metadata = {}
+ for meta_node in self.find_children_named(metadata_node, "meta"):
+ key = meta_node.getAttribute("key")
+ metadata[key] = self.extract_text(meta_node)
+ return metadata
+
+
class RequestHeadersDeserializer(ActionDispatcher):
"""Default request headers deserializer"""
@@ -151,7 +187,12 @@ class RequestHeadersDeserializer(ActionDispatcher):
class RequestDeserializer(object):
"""Break up a Request object into more useful pieces."""
- def __init__(self, body_deserializers=None, headers_deserializer=None):
+ def __init__(self, body_deserializers=None, headers_deserializer=None,
+ supported_content_types=None):
+
+ self.supported_content_types = supported_content_types or \
+ ('application/json', 'application/xml')
+
self.body_deserializers = {
'application/xml': XMLDeserializer(),
'application/json': JSONDeserializer(),
@@ -213,7 +254,7 @@ class RequestDeserializer(object):
raise exception.InvalidContentType(content_type=content_type)
def get_expected_content_type(self, request):
- return request.best_match_content_type()
+ return request.best_match_content_type(self.supported_content_types)
def get_action_args(self, request_environment):
"""Parse dictionary created by routes library."""
@@ -390,8 +431,9 @@ class ResponseSerializer(object):
def serialize_body(self, response, data, content_type, action):
response.headers['Content-Type'] = content_type
- serializer = self.get_body_serializer(content_type)
- response.body = serializer.serialize(data, action)
+ if data is not None:
+ serializer = self.get_body_serializer(content_type)
+ response.body = serializer.serialize(data, action)
def get_body_serializer(self, content_type):
try:
@@ -412,6 +454,7 @@ class Resource(wsgi.Application):
serialized by requested content type.
"""
+
def __init__(self, controller, deserializer=None, serializer=None):
"""
:param controller: object that implement methods created by routes lib
@@ -436,14 +479,17 @@ class Resource(wsgi.Application):
action, args, accept = self.deserializer.deserialize(request)
except exception.InvalidContentType:
msg = _("Unsupported Content-Type")
- return webob.exc.HTTPBadRequest(explanation=msg)
+ return faults.Fault(webob.exc.HTTPBadRequest(explanation=msg))
except exception.MalformedRequestBody:
msg = _("Malformed request body")
return faults.Fault(webob.exc.HTTPBadRequest(explanation=msg))
- action_result = self.dispatch(request, action, args)
+ try:
+ action_result = self.dispatch(request, action, args)
+ except webob.exc.HTTPException as ex:
+ LOG.info(_("HTTP exception thrown: %s"), unicode(ex))
+ action_result = faults.Fault(ex)
- #TODO(bcwaldon): find a more elegant way to pass through non-dict types
if type(action_result) is dict or action_result is None:
response = self.serializer.serialize(action_result,
accept,
diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py
index 2e02ec380..f7fd87bcd 100644
--- a/nova/api/openstack/zones.py
+++ b/nova/api/openstack/zones.py
@@ -27,7 +27,6 @@ from nova.scheduler import api
from nova.api.openstack import create_instance_helper as helper
from nova.api.openstack import common
-from nova.api.openstack import faults
from nova.api.openstack import wsgi
@@ -127,11 +126,8 @@ class Controller(object):
Returns a reservation ID (a UUID).
"""
result = None
- try:
- extra_values, result = self.helper.create_instance(req, body,
- self.compute_api.create_all_at_once)
- except faults.Fault, f:
- return f
+ extra_values, result = self.helper.create_instance(req, body,
+ self.compute_api.create_all_at_once)
reservation_id = result
return {'reservation_id': reservation_id}
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 9a606add2..08cafb8b3 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -128,7 +128,7 @@ class API(base.Base):
quota_metadata = quota.allowed_metadata_items(context, num_metadata)
if quota_metadata < num_metadata:
pid = context.project_id
- msg = _("Quota exceeeded for %(pid)s, tried to set "
+ msg = _("Quota exceeded for %(pid)s, tried to set "
"%(num_metadata)s metadata properties") % locals()
LOG.warn(msg)
raise quota.QuotaError(msg, "MetadataLimitExceeded")
@@ -139,7 +139,7 @@ class API(base.Base):
for k, v in metadata.iteritems():
if len(k) > 255 or len(v) > 255:
pid = context.project_id
- msg = _("Quota exceeeded for %(pid)s, metadata property "
+ msg = _("Quota exceeded for %(pid)s, metadata property "
"key or value too long") % locals()
LOG.warn(msg)
raise quota.QuotaError(msg, "MetadataLimitExceeded")
@@ -166,7 +166,7 @@ class API(base.Base):
instance_type)
if num_instances < min_count:
pid = context.project_id
- LOG.warn(_("Quota exceeeded for %(pid)s,"
+ LOG.warn(_("Quota exceeded for %(pid)s,"
" tried to run %(min_count)s instances") % locals())
if num_instances <= 0:
message = _("Instance quota exceeded. You cannot run any "
@@ -468,10 +468,10 @@ class API(base.Base):
return [dict(x.iteritems()) for x in instances]
- def has_finished_migration(self, context, instance_id):
+ def has_finished_migration(self, context, instance_uuid):
"""Returns true if an instance has a finished migration."""
try:
- db.migration_get_by_instance_and_status(context, instance_id,
+ db.migration_get_by_instance_and_status(context, instance_uuid,
'finished')
return True
except exception.NotFound:
@@ -562,6 +562,7 @@ class API(base.Base):
self.db.queue_get_for(context, FLAGS.compute_topic, host),
{'method': 'refresh_provider_fw_rules', 'args': {}})
+ @scheduler_api.reroute_compute("update")
def update(self, context, instance_id, **kwargs):
"""Updates the instance in the datastore.
@@ -896,6 +897,7 @@ class API(base.Base):
raise exception.Error(_("Unable to find host for Instance %s")
% instance_id)
+ @scheduler_api.reroute_compute("backup")
def backup(self, context, instance_id, name, backup_type, rotation,
extra_properties=None):
"""Backup the given instance
@@ -912,6 +914,7 @@ class API(base.Base):
extra_properties=extra_properties)
return recv_meta
+ @scheduler_api.reroute_compute("snapshot")
def snapshot(self, context, instance_id, name, extra_properties=None):
"""Snapshot the given instance.
@@ -954,10 +957,12 @@ class API(base.Base):
params=params)
return recv_meta
+ @scheduler_api.reroute_compute("reboot")
def reboot(self, context, instance_id):
"""Reboot the given instance."""
self._cast_compute_message('reboot_instance', context, instance_id)
+ @scheduler_api.reroute_compute("rebuild")
def rebuild(self, context, instance_id, image_href, name=None,
metadata=None, files_to_inject=None):
"""Rebuild the given instance with the provided metadata."""
@@ -988,39 +993,50 @@ class API(base.Base):
instance_id,
params=rebuild_params)
+ @scheduler_api.reroute_compute("revert_resize")
def revert_resize(self, context, instance_id):
"""Reverts a resize, deleting the 'new' instance in the process."""
context = context.elevated()
+ instance_ref = self._get_instance(context, instance_id,
+ 'revert_resize')
migration_ref = self.db.migration_get_by_instance_and_status(context,
- instance_id, 'finished')
+ instance_ref['uuid'], 'finished')
if not migration_ref:
raise exception.MigrationNotFoundByStatus(instance_id=instance_id,
status='finished')
params = {'migration_id': migration_ref['id']}
- self._cast_compute_message('revert_resize', context, instance_id,
- migration_ref['dest_compute'], params=params)
+ self._cast_compute_message('revert_resize', context,
+ instance_ref['uuid'],
+ migration_ref['source_compute'],
+ params=params)
+
self.db.migration_update(context, migration_ref['id'],
{'status': 'reverted'})
+ @scheduler_api.reroute_compute("confirm_resize")
def confirm_resize(self, context, instance_id):
"""Confirms a migration/resize and deletes the 'old' instance."""
context = context.elevated()
+ instance_ref = self._get_instance(context, instance_id,
+ 'confirm_resize')
migration_ref = self.db.migration_get_by_instance_and_status(context,
- instance_id, 'finished')
+ instance_ref['uuid'], 'finished')
if not migration_ref:
raise exception.MigrationNotFoundByStatus(instance_id=instance_id,
status='finished')
- instance_ref = self.db.instance_get(context, instance_id)
params = {'migration_id': migration_ref['id']}
- self._cast_compute_message('confirm_resize', context, instance_id,
- migration_ref['source_compute'], params=params)
+ self._cast_compute_message('confirm_resize', context,
+ instance_ref['uuid'],
+ migration_ref['dest_compute'],
+ params=params)
self.db.migration_update(context, migration_ref['id'],
{'status': 'confirmed'})
self.db.instance_update(context, instance_id,
{'host': migration_ref['dest_compute'], })
+ @scheduler_api.reroute_compute("resize")
def resize(self, context, instance_id, flavor_id=None):
"""Resize (ie, migrate) a running instance.
@@ -1028,8 +1044,8 @@ class API(base.Base):
the original flavor_id. If flavor_id is not None, the instance should
be migrated to a new host and resized to the new flavor_id.
"""
- instance = self.db.instance_get(context, instance_id)
- current_instance_type = instance['instance_type']
+ instance_ref = self._get_instance(context, instance_id, 'resize')
+ current_instance_type = instance_ref['instance_type']
# If flavor_id is not provided, only migrate the instance.
if not flavor_id:
@@ -1057,10 +1073,11 @@ class API(base.Base):
raise exception.ApiError(_("Invalid flavor: cannot use"
"the same flavor. "))
+ instance_ref = self._get_instance(context, instance_id, 'resize')
self._cast_scheduler_message(context,
{"method": "prep_resize",
"args": {"topic": FLAGS.compute_topic,
- "instance_id": instance_id,
+ "instance_id": instance_ref['uuid'],
"flavor_id": new_instance_type['id']}})
@scheduler_api.reroute_compute("add_fixed_ip")
@@ -1132,6 +1149,7 @@ class API(base.Base):
"""Unrescue the given instance."""
self._cast_compute_message('unrescue_instance', context, instance_id)
+ @scheduler_api.reroute_compute("set_admin_password")
def set_admin_password(self, context, instance_id, password=None):
"""Set the root/admin password for the given instance."""
host = self._find_host(context, instance_id)
diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py
index 1d246e445..c13a629a9 100644
--- a/nova/compute/instance_types.py
+++ b/nova/compute/instance_types.py
@@ -112,7 +112,7 @@ def get_instance_type(id):
return get_default_instance_type()
try:
ctxt = context.get_admin_context()
- return db.instance_type_get_by_id(ctxt, id)
+ return db.instance_type_get(ctxt, id)
except exception.DBError:
raise exception.ApiError(_("Unknown instance type: %s") % id)
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index eb3996d29..173469bc3 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -77,8 +77,6 @@ flags.DEFINE_integer('live_migration_retry_count', 30,
flags.DEFINE_integer("rescue_timeout", 0,
"Automatically unrescue an instance after N seconds."
" Set to 0 to disable.")
-flags.DEFINE_bool('auto_assign_floating_ip', False,
- 'Autoassigning floating ip to VM')
flags.DEFINE_integer('host_state_interval', 120,
'Interval in seconds for querying the host status')
@@ -93,6 +91,10 @@ def checks_instance_lock(function):
"""Decorator to prevent action against locked instances for non-admins."""
@functools.wraps(function)
def decorated_function(self, context, instance_id, *args, **kwargs):
+ #TODO(anyone): this being called instance_id is forcing a slightly
+ # confusing convention of pushing instance_uuids
+ # through an "instance_id" key in the queue args dict when
+ # casting through the compute API
LOG.info(_("check_instance_lock: decorating: |%s|"), function,
context=context)
LOG.info(_("check_instance_lock: arguments: |%(self)s| |%(context)s|"
@@ -212,6 +214,15 @@ class ComputeManager(manager.SchedulerDependentManager):
"""This call passes straight through to the virtualization driver."""
return self.driver.refresh_provider_fw_rules()
+ def _get_instance_nw_info(self, context, instance):
+ """Get a list of dictionaries of network data of an instance.
+ Returns an empty list if stub_network flag is set."""
+ network_info = []
+ if not FLAGS.stub_network:
+ network_info = self.network_api.get_instance_nw_info(context,
+ instance)
+ return network_info
+
def _setup_block_device_mapping(self, context, instance_id):
"""setup volumes for block device mapping"""
self.db.instance_set_state(context,
@@ -274,16 +285,19 @@ class ComputeManager(manager.SchedulerDependentManager):
"""Launch a new instance with specified options."""
context = context.elevated()
instance = self.db.instance_get(context, instance_id)
- instance.injected_files = kwargs.get('injected_files', [])
- instance.admin_pass = kwargs.get('admin_password', None)
if instance['name'] in self.driver.list_instances():
raise exception.Error(_("Instance has already been created"))
LOG.audit(_("instance %s: starting..."), instance_id,
context=context)
- self.db.instance_update(context,
- instance_id,
- {'host': self.host, 'launched_on': self.host})
-
+ updates = {}
+ updates['host'] = self.host
+ updates['launched_on'] = self.host
+ # NOTE(vish): used by virt but not in database
+ updates['injected_files'] = kwargs.get('injected_files', [])
+ updates['admin_pass'] = kwargs.get('admin_password', None)
+ instance = self.db.instance_update(context,
+ instance_id,
+ updates)
self.db.instance_set_state(context,
instance_id,
power_state.NOSTATE,
@@ -299,8 +313,6 @@ class ComputeManager(manager.SchedulerDependentManager):
network_info = self.network_api.allocate_for_instance(context,
instance, vpn=is_vpn)
LOG.debug(_("instance network_info: |%s|"), network_info)
- self.network_manager.setup_compute_network(context,
- instance_id)
else:
# TODO(tr3buchet) not really sure how this should be handled.
# virt requires network_info to be passed in but stub_network
@@ -354,6 +366,7 @@ class ComputeManager(manager.SchedulerDependentManager):
{'action_str': action_str, 'instance_id': instance_id},
context=context)
+ network_info = self._get_instance_nw_info(context, instance)
if not FLAGS.stub_network:
self.network_api.deallocate_for_instance(context, instance)
@@ -366,7 +379,7 @@ class ComputeManager(manager.SchedulerDependentManager):
self.db.instance_destroy(context, instance_id)
raise exception.Error(_('trying to destroy already destroyed'
' instance: %s') % instance_id)
- self.driver.destroy(instance)
+ self.driver.destroy(instance, network_info)
if action_str == 'Terminating':
terminate_volumes(self.db, context, instance_id)
@@ -411,11 +424,16 @@ class ComputeManager(manager.SchedulerDependentManager):
self._update_state(context, instance_id, power_state.BUILDING)
- self.driver.destroy(instance_ref)
+ network_info = self._get_instance_nw_info(context, instance_ref)
+
+ self.driver.destroy(instance_ref, network_info)
image_ref = kwargs.get('image_ref')
instance_ref.image_ref = image_ref
instance_ref.injected_files = kwargs.get('injected_files', [])
- self.driver.spawn(instance_ref)
+ network_info = self.network_api.get_instance_nw_info(context,
+ instance_ref)
+ bd_mapping = self._setup_block_device_mapping(context, instance_id)
+ self.driver.spawn(instance_ref, network_info, bd_mapping)
self._update_image_ref(context, instance_id, image_ref)
self._update_launched_at(context, instance_id)
@@ -448,8 +466,8 @@ class ComputeManager(manager.SchedulerDependentManager):
instance_id,
power_state.NOSTATE,
'rebooting')
- self.network_manager.setup_compute_network(context, instance_id)
- self.driver.reboot(instance_ref)
+ network_info = self._get_instance_nw_info(context, instance_ref)
+ self.driver.reboot(instance_ref, network_info)
self._update_state(context, instance_id)
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@@ -639,10 +657,10 @@ class ComputeManager(manager.SchedulerDependentManager):
instance_id,
power_state.NOSTATE,
'rescuing')
- self.network_manager.setup_compute_network(context, instance_id)
_update_state = lambda result: self._update_state_callback(
self, context, instance_id, result)
- self.driver.rescue(instance_ref, _update_state)
+ network_info = self._get_instance_nw_info(context, instance_ref)
+ self.driver.rescue(instance_ref, _update_state, network_info)
self._update_state(context, instance_id)
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@@ -658,7 +676,8 @@ class ComputeManager(manager.SchedulerDependentManager):
'unrescuing')
_update_state = lambda result: self._update_state_callback(
self, context, instance_id, result)
- self.driver.unrescue(instance_ref, _update_state)
+ network_info = self._get_instance_nw_info(context, instance_ref)
+ self.driver.unrescue(instance_ref, _update_state, network_info)
self._update_state(context, instance_id)
@staticmethod
@@ -670,9 +689,12 @@ class ComputeManager(manager.SchedulerDependentManager):
@checks_instance_lock
def confirm_resize(self, context, instance_id, migration_id):
"""Destroys the source instance."""
- context = context.elevated()
- instance_ref = self.db.instance_get(context, instance_id)
- self.driver.destroy(instance_ref)
+ migration_ref = self.db.migration_get(context, migration_id)
+ instance_ref = self.db.instance_get_by_uuid(context,
+ migration_ref.instance_uuid)
+
+ network_info = self._get_instance_nw_info(context, instance_ref)
+ self.driver.destroy(instance_ref, network_info)
usage_info = utils.usage_from_instance(instance_ref)
notifier.notify('compute.%s' % self.host,
'compute.instance.resize.confirm',
@@ -688,17 +710,17 @@ class ComputeManager(manager.SchedulerDependentManager):
source machine.
"""
- instance_ref = self.db.instance_get(context, instance_id)
migration_ref = self.db.migration_get(context, migration_id)
+ instance_ref = self.db.instance_get_by_uuid(context,
+ migration_ref.instance_uuid)
- self.driver.destroy(instance_ref)
+ network_info = self._get_instance_nw_info(context, instance_ref)
+ self.driver.destroy(instance_ref, network_info)
topic = self.db.queue_get_for(context, FLAGS.compute_topic,
instance_ref['host'])
rpc.cast(context, topic,
{'method': 'finish_revert_resize',
- 'args': {
- 'migration_id': migration_ref['id'],
- 'instance_id': instance_id, },
+ 'args': {'migration_id': migration_ref['id']},
})
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@@ -710,14 +732,16 @@ class ComputeManager(manager.SchedulerDependentManager):
in the database.
"""
- instance_ref = self.db.instance_get(context, instance_id)
migration_ref = self.db.migration_get(context, migration_id)
+ instance_ref = self.db.instance_get_by_uuid(context,
+ migration_ref.instance_uuid)
+
instance_type = self.db.instance_type_get_by_flavor_id(context,
migration_ref['old_flavor_id'])
# Just roll back the record. There's no need to resize down since
# the 'old' VM already has the preferred attributes
- self.db.instance_update(context, instance_id,
+ self.db.instance_update(context, instance_ref['uuid'],
dict(memory_mb=instance_type['memory_mb'],
vcpus=instance_type['vcpus'],
local_gb=instance_type['local_gb'],
@@ -741,17 +765,23 @@ class ComputeManager(manager.SchedulerDependentManager):
"""
context = context.elevated()
- instance_ref = self.db.instance_get(context, instance_id)
+
+ # Because of checks_instance_lock, this must currently be called
+ # instance_id. However, the compute API is always passing the UUID
+ # of the instance down
+ instance_ref = self.db.instance_get_by_uuid(context, instance_id)
if instance_ref['host'] == FLAGS.host:
raise exception.Error(_(
'Migration error: destination same as source!'))
- old_instance_type = self.db.instance_type_get_by_id(context,
+ old_instance_type = self.db.instance_type_get(context,
instance_ref['instance_type_id'])
+ new_instance_type = self.db.instance_type_get_by_flavor_id(context,
+ flavor_id)
migration_ref = self.db.migration_create(context,
- {'instance_id': instance_id,
+ {'instance_uuid': instance_ref['uuid'],
'source_compute': instance_ref['host'],
'dest_compute': FLAGS.host,
'dest_host': self.driver.get_host_ip_addr(),
@@ -759,22 +789,18 @@ class ComputeManager(manager.SchedulerDependentManager):
'new_flavor_id': flavor_id,
'status': 'pre-migrating'})
- LOG.audit(_('instance %s: migrating to '), instance_id,
+ LOG.audit(_('instance %s: migrating'), instance_ref['uuid'],
context=context)
topic = self.db.queue_get_for(context, FLAGS.compute_topic,
instance_ref['host'])
rpc.cast(context, topic,
{'method': 'resize_instance',
- 'args': {
- 'migration_id': migration_ref['id'],
- 'instance_id': instance_id, },
- })
+ 'args': {'instance_id': instance_ref['uuid'],
+ 'migration_id': migration_ref['id']}})
- instance_type = self.db.instance_type_get_by_flavor_id(context,
- flavor_id)
usage_info = utils.usage_from_instance(instance_ref,
- new_instance_type=instance_type['name'],
- new_instance_type_id=instance_type['id'])
+ new_instance_type=new_instance_type['name'],
+ new_instance_type_id=new_instance_type['id'])
notifier.notify('compute.%s' % self.host,
'compute.instance.resize.prep',
notifier.INFO,
@@ -785,7 +811,9 @@ class ComputeManager(manager.SchedulerDependentManager):
def resize_instance(self, context, instance_id, migration_id):
"""Starts the migration of a running instance to another host."""
migration_ref = self.db.migration_get(context, migration_id)
- instance_ref = self.db.instance_get(context, instance_id)
+ instance_ref = self.db.instance_get_by_uuid(context,
+ migration_ref.instance_uuid)
+
self.db.migration_update(context,
migration_id,
{'status': 'migrating'})
@@ -801,10 +829,11 @@ class ComputeManager(manager.SchedulerDependentManager):
topic = self.db.queue_get_for(context,
FLAGS.compute_topic,
migration_ref['dest_compute'])
+ params = {'migration_id': migration_id,
+ 'disk_info': disk_info,
+ 'instance_id': instance_ref['uuid']}
rpc.cast(context, topic, {'method': 'finish_resize',
- 'args': {'migration_id': migration_id,
- 'instance_id': instance_id,
- 'disk_info': disk_info}})
+ 'args': params})
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@checks_instance_lock
@@ -816,24 +845,20 @@ class ComputeManager(manager.SchedulerDependentManager):
"""
migration_ref = self.db.migration_get(context, migration_id)
- instance_ref = self.db.instance_get(context,
- migration_ref['instance_id'])
- # TODO(mdietz): apply the rest of the instance_type attributes going
- # after they're supported
+ instance_ref = self.db.instance_get_by_uuid(context,
+ migration_ref.instance_uuid)
instance_type = self.db.instance_type_get_by_flavor_id(context,
migration_ref['new_flavor_id'])
- self.db.instance_update(context, instance_id,
+ self.db.instance_update(context, instance_ref.uuid,
dict(instance_type_id=instance_type['id'],
memory_mb=instance_type['memory_mb'],
vcpus=instance_type['vcpus'],
local_gb=instance_type['local_gb']))
- # reload the updated instance ref
- # FIXME(mdietz): is there reload functionality?
- instance = self.db.instance_get(context, instance_id)
- network_info = self.network_api.get_instance_nw_info(context,
- instance)
- self.driver.finish_resize(instance, disk_info, network_info)
+ instance_ref = self.db.instance_get_by_uuid(context,
+ instance_ref.uuid)
+ network_info = self._get_instance_nw_info(context, instance_ref)
+ self.driver.finish_resize(instance_ref, disk_info, network_info)
self.db.migration_update(context, migration_id,
{'status': 'finished', })
@@ -846,7 +871,7 @@ class ComputeManager(manager.SchedulerDependentManager):
"""
self.network_api.add_fixed_ip_to_instance(context, instance_id,
- network_id)
+ self.host, network_id)
self.inject_network_info(context, instance_id)
self.reset_network(context, instance_id)
@@ -965,7 +990,11 @@ class ComputeManager(manager.SchedulerDependentManager):
context = context.elevated()
LOG.debug(_('instance %s: getting locked state'), instance_id,
context=context)
- instance_ref = self.db.instance_get(context, instance_id)
+ if utils.is_uuid_like(instance_id):
+ uuid = instance_id
+ instance_ref = self.db.instance_get_by_uuid(context, uuid)
+ else:
+ instance_ref = self.db.instance_get(context, instance_id)
return instance_ref['locked']
@checks_instance_lock
@@ -982,8 +1011,7 @@ class ComputeManager(manager.SchedulerDependentManager):
LOG.debug(_('instance %s: inject network info'), instance_id,
context=context)
instance = self.db.instance_get(context, instance_id)
- network_info = self.network_api.get_instance_nw_info(context,
- instance)
+ network_info = self._get_instance_nw_info(context, instance)
LOG.debug(_("network_info to inject: |%s|"), network_info)
self.driver.inject_network_info(instance, network_info)
@@ -1201,17 +1229,17 @@ class ComputeManager(manager.SchedulerDependentManager):
#
# Retry operation is necessary because continuously request comes,
# concorrent request occurs to iptables, then it complains.
+ network_info = self._get_instance_nw_info(context, instance_ref)
max_retry = FLAGS.live_migration_retry_count
for cnt in range(max_retry):
try:
- self.network_manager.setup_compute_network(context,
- instance_id)
+ self.driver.plug_vifs(instance_ref, network_info)
break
except exception.ProcessExecutionError:
if cnt == max_retry - 1:
raise
else:
- LOG.warn(_("setup_compute_network() failed %(cnt)d."
+ LOG.warn(_("plug_vifs() failed %(cnt)d."
"Retry up to %(max_retry)d for %(hostname)s.")
% locals())
time.sleep(1)
@@ -1289,8 +1317,9 @@ class ComputeManager(manager.SchedulerDependentManager):
# Releasing vlan.
# (not necessary in current implementation?)
+ network_info = self._get_instance_nw_info(ctxt, instance_ref)
# Releasing security group ingress rule.
- self.driver.unfilter_instance(instance_ref)
+ self.driver.unfilter_instance(instance_ref, network_info)
# Database updating.
i_name = instance_ref.name
diff --git a/nova/db/api.py b/nova/db/api.py
index d36caf939..22dd8a4b4 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -314,9 +314,9 @@ def migration_get(context, migration_id):
return IMPL.migration_get(context, migration_id)
-def migration_get_by_instance_and_status(context, instance_id, status):
- """Finds a migration by the instance id its migrating."""
- return IMPL.migration_get_by_instance_and_status(context, instance_id,
+def migration_get_by_instance_and_status(context, instance_uuid, status):
+ """Finds a migration by the instance uuid its migrating."""
+ return IMPL.migration_get_by_instance_and_status(context, instance_uuid,
status)
@@ -332,13 +332,14 @@ def fixed_ip_associate(context, address, instance_id):
return IMPL.fixed_ip_associate(context, address, instance_id)
-def fixed_ip_associate_pool(context, network_id, instance_id):
- """Find free ip in network and associate it to instance.
+def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None):
+ """Find free ip in network and associate it to instance or host.
Raises if one is not available.
"""
- return IMPL.fixed_ip_associate_pool(context, network_id, instance_id)
+ return IMPL.fixed_ip_associate_pool(context, network_id,
+ instance_id, host)
def fixed_ip_create(context, values):
@@ -361,9 +362,9 @@ def fixed_ip_get_all(context):
return IMPL.fixed_ip_get_all(context)
-def fixed_ip_get_all_by_host(context, host):
- """Get all defined fixed ips used by a host."""
- return IMPL.fixed_ip_get_all_by_host(context, host)
+def fixed_ip_get_all_by_instance_host(context, host):
+ """Get all allocated fixed ips filtered by instance host."""
+ return IMPL.fixed_ip_get_all_instance_by_host(context, host)
def fixed_ip_get_by_address(context, address):
@@ -376,6 +377,11 @@ def fixed_ip_get_by_instance(context, instance_id):
return IMPL.fixed_ip_get_by_instance(context, instance_id)
+def fixed_ip_get_by_network_host(context, network_id, host):
+ """Get fixed ip for a host in a network."""
+ return IMPL.fixed_ip_get_by_network_host(context, network_id, host)
+
+
def fixed_ip_get_by_virtual_interface(context, vif_id):
"""Get fixed ips by virtual interface or raise if none exist."""
return IMPL.fixed_ip_get_by_virtual_interface(context, vif_id)
@@ -1341,9 +1347,9 @@ def instance_type_get_all(context, inactive=False):
return IMPL.instance_type_get_all(context, inactive)
-def instance_type_get_by_id(context, id):
+def instance_type_get(context, id):
"""Get instance type by id."""
- return IMPL.instance_type_get_by_id(context, id)
+ return IMPL.instance_type_get(context, id)
def instance_type_get_by_name(context, name):
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index a3fc6d733..6d0dd4151 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -19,7 +19,6 @@
Implementation of SQLAlchemy backend.
"""
import re
-import traceback
import warnings
from nova import db
@@ -34,7 +33,6 @@ from sqlalchemy import or_
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import joinedload
from sqlalchemy.orm import joinedload_all
-from sqlalchemy.sql import exists
from sqlalchemy.sql import func
from sqlalchemy.sql.expression import literal_column
@@ -673,7 +671,7 @@ def fixed_ip_associate(context, address, instance_id):
@require_admin_context
-def fixed_ip_associate_pool(context, network_id, instance_id):
+def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None):
session = get_session()
with session.begin():
network_or_none = or_(models.FixedIp.network_id == network_id,
@@ -683,6 +681,7 @@ def fixed_ip_associate_pool(context, network_id, instance_id):
filter_by(reserved=False).\
filter_by(deleted=False).\
filter_by(instance=None).\
+ filter_by(host=None).\
with_lockmode('update').\
first()
# NOTE(vish): if with_lockmode isn't supported, as in sqlite,
@@ -693,9 +692,12 @@ def fixed_ip_associate_pool(context, network_id, instance_id):
fixed_ip_ref.network = network_get(context,
network_id,
session=session)
- fixed_ip_ref.instance = instance_get(context,
- instance_id,
- session=session)
+ if instance_id:
+ fixed_ip_ref.instance = instance_get(context,
+ instance_id,
+ session=session)
+ if host:
+ fixed_ip_ref.host = host
session.add(fixed_ip_ref)
return fixed_ip_ref['address']
@@ -751,7 +753,7 @@ def fixed_ip_get_all(context, session=None):
@require_admin_context
-def fixed_ip_get_all_by_host(context, host=None):
+def fixed_ip_get_all_by_instance_host(context, host=None):
session = get_session()
result = session.query(models.FixedIp).\
@@ -801,6 +803,20 @@ def fixed_ip_get_by_instance(context, instance_id):
@require_context
+def fixed_ip_get_by_network_host(context, network_id, host):
+ session = get_session()
+ rv = session.query(models.FixedIp).\
+ filter_by(network_id=network_id).\
+ filter_by(host=host).\
+ filter_by(deleted=False).\
+ first()
+ if not rv:
+ raise exception.FixedIpNotFoundForNetworkHost(network_id=network_id,
+ host=host)
+ return rv
+
+
+@require_context
def fixed_ip_get_by_virtual_interface(context, vif_id):
session = get_session()
rv = session.query(models.FixedIp).\
@@ -1136,9 +1152,9 @@ def instance_get_active_by_window(context, begin, end=None):
"""Return instances that were continuously active over the given window"""
session = get_session()
query = session.query(models.Instance).\
- options(joinedload_all('fixed_ip.floating_ips')).\
+ options(joinedload_all('fixed_ips.floating_ips')).\
options(joinedload('security_groups')).\
- options(joinedload_all('fixed_ip.network')).\
+ options(joinedload_all('fixed_ips.network')).\
options(joinedload('instance_type')).\
filter(models.Instance.launched_at < begin)
if end:
@@ -1476,7 +1492,7 @@ def instance_get_project_vpn(context, project_id):
options(joinedload_all('fixed_ips.floating_ips')).\
options(joinedload('virtual_interfaces')).\
options(joinedload('security_groups')).\
- options(joinedload_all('fixed_ip.network')).\
+ options(joinedload_all('fixed_ips.network')).\
options(joinedload('metadata')).\
options(joinedload('instance_type')).\
filter_by(project_id=project_id).\
@@ -1560,7 +1576,11 @@ def instance_update(context, instance_id, values):
instance_metadata_update_or_create(context, instance_id,
values.pop('metadata'))
with session.begin():
- instance_ref = instance_get(context, instance_id, session=session)
+ if utils.is_uuid_like(instance_id):
+ instance_ref = instance_get_by_uuid(context, instance_id,
+ session=session)
+ else:
+ instance_ref = instance_get(context, instance_id, session=session)
instance_ref.update(values)
instance_ref.save(session=session)
return instance_ref
@@ -1707,8 +1727,6 @@ def network_associate(context, project_id, force=False):
called by project_get_networks under certain conditions
and network manager add_network_to_project()
- only associates projects with networks that have configured hosts
-
only associate if the project doesn't already have a network
or if force is True
@@ -1724,7 +1742,6 @@ def network_associate(context, project_id, force=False):
def network_query(project_filter):
return session.query(models.Network).\
filter_by(deleted=False).\
- filter(models.Network.host != None).\
filter_by(project_id=project_filter).\
with_lockmode('update').\
first()
@@ -1931,9 +1948,16 @@ def network_get_all_by_instance(_context, instance_id):
def network_get_all_by_host(context, host):
session = get_session()
with session.begin():
+ # NOTE(vish): return networks that have host set
+ # or that have a fixed ip with host set
+ host_filter = or_(models.Network.host == host,
+ models.FixedIp.host == host)
+
return session.query(models.Network).\
filter_by(deleted=False).\
- filter_by(host=host).\
+ join(models.Network.fixed_ips).\
+ filter(host_filter).\
+ filter_by(deleted=False).\
all()
@@ -1965,6 +1989,7 @@ def network_update(context, network_id, values):
network_ref = network_get(context, network_id, session=session)
network_ref.update(values)
network_ref.save(session=session)
+ return network_ref
###################
@@ -3025,13 +3050,13 @@ def migration_get(context, id, session=None):
@require_admin_context
-def migration_get_by_instance_and_status(context, instance_id, status):
+def migration_get_by_instance_and_status(context, instance_uuid, status):
session = get_session()
result = session.query(models.Migration).\
- filter_by(instance_id=instance_id).\
+ filter_by(instance_uuid=instance_uuid).\
filter_by(status=status).first()
if not result:
- raise exception.MigrationNotFoundByStatus(instance_id=instance_id,
+ raise exception.MigrationNotFoundByStatus(instance_id=instance_uuid,
status=status)
return result
@@ -3212,7 +3237,7 @@ def instance_type_get_all(context, inactive=False):
@require_context
-def instance_type_get_by_id(context, id):
+def instance_type_get(context, id):
"""Returns a dict describing specific instance_type"""
session = get_session()
inst_type = session.query(models.InstanceTypes).\
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/033_ha_network.py b/nova/db/sqlalchemy/migrate_repo/versions/033_ha_network.py
new file mode 100644
index 000000000..3a5f7eba8
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/033_ha_network.py
@@ -0,0 +1,44 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2011 OpenStack, LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from sqlalchemy import Column, Table, MetaData, Boolean, String
+
+meta = MetaData()
+
+fixed_ips_host = Column('host', String(255))
+
+networks_multi_host = Column('multi_host', Boolean, default=False)
+
+
+def upgrade(migrate_engine):
+ meta.bind = migrate_engine
+
+ fixed_ips = Table('fixed_ips', meta, autoload=True)
+ fixed_ips.create_column(fixed_ips_host)
+
+ networks = Table('networks', meta, autoload=True)
+ networks.create_column(networks_multi_host)
+
+
+def downgrade(migrate_engine):
+ meta.bind = migrate_engine
+
+ fixed_ips = Table('fixed_ips', meta, autoload=True)
+ fixed_ips.drop_column(fixed_ips_host)
+
+ networks = Table('networks', meta, autoload=True)
+ networks.drop_column(networks_multi_host)
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/034_change_instance_id_in_migrations.py b/nova/db/sqlalchemy/migrate_repo/versions/034_change_instance_id_in_migrations.py
new file mode 100644
index 000000000..4e8eaf0fd
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/034_change_instance_id_in_migrations.py
@@ -0,0 +1,52 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.from sqlalchemy import *
+
+from sqlalchemy import Column, Integer, String, MetaData, Table
+
+
+meta = MetaData()
+
+
+#
+# Tables to alter
+#
+#
+
+instance_id = Column('instance_id', Integer())
+instance_uuid = Column('instance_uuid', String(255))
+
+
+def upgrade(migrate_engine):
+ meta.bind = migrate_engine
+ migrations = Table('migrations', meta, autoload=True)
+ migrations.create_column(instance_uuid)
+
+ if migrate_engine.name == "mysql":
+ try:
+ migrate_engine.execute("ALTER TABLE migrations DROP FOREIGN KEY " \
+ "`migrations_ibfk_1`;")
+ except Exception: # Don't care, just fail silently.
+ pass
+
+ migrations.c.instance_id.drop()
+
+
+def downgrade(migrate_engine):
+ meta.bind = migrate_engine
+ migrations = Table('migrations', meta, autoload=True)
+ migrations.c.instance_uuid.drop()
+ migrations.create_column(instance_id)
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/035_secondary_dns.py b/nova/db/sqlalchemy/migrate_repo/versions/035_secondary_dns.py
new file mode 100644
index 000000000..c938eb716
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/035_secondary_dns.py
@@ -0,0 +1,38 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2011 OpenStack, LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from sqlalchemy import Column, Table, MetaData, Boolean, String
+
+meta = MetaData()
+
+dns2 = Column('dns2', String(255))
+
+
+def upgrade(migrate_engine):
+ meta.bind = migrate_engine
+
+ networks = Table('networks', meta, autoload=True)
+ networks.c.dns.alter(Column('dns1', String(255)))
+ networks.create_column(dns2)
+
+
+def downgrade(migrate_engine):
+ meta.bind = migrate_engine
+
+ networks = Table('networks', meta, autoload=True)
+ networks.c.dns1.alter(Column('dns', String(255)))
+ networks.drop_column(dns2)
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index f120b9dd6..f78c442a9 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -31,6 +31,7 @@ from nova.db.sqlalchemy.session import get_session
from nova import auth
from nova import exception
from nova import flags
+from nova import ipv6
from nova import utils
@@ -529,7 +530,8 @@ class Migration(BASE, NovaBase):
dest_host = Column(String(255))
old_flavor_id = Column(Integer())
new_flavor_id = Column(Integer())
- instance_id = Column(Integer, ForeignKey('instances.id'), nullable=True)
+ instance_uuid = Column(String(255), ForeignKey('instances.uuid'),
+ nullable=True)
#TODO(_cerberus_): enum
status = Column(String(255))
@@ -546,6 +548,7 @@ class Network(BASE, NovaBase):
injected = Column(Boolean, default=False)
cidr = Column(String(255), unique=True)
cidr_v6 = Column(String(255), unique=True)
+ multi_host = Column(Boolean, default=False)
gateway_v6 = Column(String(255))
netmask_v6 = Column(String(255))
@@ -554,7 +557,8 @@ class Network(BASE, NovaBase):
bridge_interface = Column(String(255))
gateway = Column(String(255))
broadcast = Column(String(255))
- dns = Column(String(255))
+ dns1 = Column(String(255))
+ dns2 = Column(String(255))
vlan = Column(Integer)
vpn_public_address = Column(String(255))
@@ -578,6 +582,18 @@ class VirtualInterface(BASE, NovaBase):
instance_id = Column(Integer, ForeignKey('instances.id'), nullable=False)
instance = relationship(Instance, backref=backref('virtual_interfaces'))
+ @property
+ def fixed_ipv6(self):
+ cidr_v6 = self.network.cidr_v6
+ if cidr_v6 is None:
+ ipv6_address = None
+ else:
+ project_id = self.instance.project_id
+ mac = self.address
+ ipv6_address = ipv6.to_global(cidr_v6, mac, project_id)
+
+ return ipv6_address
+
# TODO(vish): can these both come from the same baseclass?
class FixedIp(BASE, NovaBase):
@@ -604,6 +620,7 @@ class FixedIp(BASE, NovaBase):
# leased means dhcp bridge has leased the ip
leased = Column(Boolean, default=False)
reserved = Column(Boolean, default=False)
+ host = Column(String(255))
class FloatingIp(BASE, NovaBase):
diff --git a/nova/exception.py b/nova/exception.py
index ad6c005f8..8c9b45a80 100644
--- a/nova/exception.py
+++ b/nova/exception.py
@@ -78,8 +78,8 @@ def wrap_db_error(f):
except Exception, e:
LOG.exception(_('DB exception wrapped.'))
raise DBError(e)
- return _wrap
_wrap.func_name = f.func_name
+ return _wrap
def wrap_exception(notifier=None, publisher_id=None, event_type=None,
@@ -116,7 +116,8 @@ def wrap_exception(notifier=None, publisher_id=None, event_type=None,
notifier.notify(publisher_id, temp_type, temp_level,
payload)
- if not isinstance(e, Error):
+ if (not isinstance(e, Error) and
+ not isinstance(e, NovaException)):
#exc_type, exc_value, exc_traceback = sys.exc_info()
LOG.exception(_('Uncaught exception'))
#logging.error(traceback.extract_stack(exc_traceback))
@@ -372,6 +373,10 @@ class StorageRepositoryNotFound(NotFound):
message = _("Cannot find SR to read/write VDI.")
+class NetworkNotCreated(NovaException):
+ message = _("%(req)s is required to create a network.")
+
+
class NetworkNotFound(NotFound):
message = _("Network %(network_id)s could not be found.")
@@ -408,6 +413,11 @@ class FixedIpNotFoundForInstance(FixedIpNotFound):
message = _("Instance %(instance_id)s has zero fixed ips.")
+class FixedIpNotFoundForNetworkHost(FixedIpNotFound):
+ message = _("Network host %(host)s has zero fixed ips "
+ "in network %(network_id)s.")
+
+
class FixedIpNotFoundForSpecificInstance(FixedIpNotFound):
message = _("Instance %(instance_id)s doesn't have fixed ip '%(ip)s'.")
diff --git a/nova/image/glance.py b/nova/image/glance.py
index 55d948a32..5c2dc957b 100644
--- a/nova/image/glance.py
+++ b/nova/image/glance.py
@@ -89,6 +89,10 @@ class GlanceImageService(service.BaseImageService):
# `get_images` here because we need `is_public` and `properties`
# included so we can filter by user
filtered = []
+ filters = filters or {}
+ if 'is_public' not in filters:
+ # NOTE(vish): don't filter out private images
+ filters['is_public'] = 'none'
image_metas = self.client.get_images_detailed(filters=filters,
marker=marker,
limit=limit)
@@ -101,6 +105,10 @@ class GlanceImageService(service.BaseImageService):
def detail(self, context, filters=None, marker=None, limit=None):
"""Calls out to Glance for a list of detailed image information."""
filtered = []
+ filters = filters or {}
+ if 'is_public' not in filters:
+ # NOTE(vish): don't filter out private images
+ filters['is_public'] = 'none'
image_metas = self.client.get_images_detailed(filters=filters,
marker=marker,
limit=limit)
diff --git a/nova/image/s3.py b/nova/image/s3.py
index 4a3df98ba..c313c7a13 100644
--- a/nova/image/s3.py
+++ b/nova/image/s3.py
@@ -168,7 +168,7 @@ class S3ImageService(service.BaseImageService):
metadata.update({'disk_format': image_format,
'container_format': image_format,
'status': 'queued',
- 'is_public': True,
+ 'is_public': False,
'properties': properties})
metadata['properties']['image_state'] = 'pending'
image = self.service.create(context, metadata)
diff --git a/nova/network/api.py b/nova/network/api.py
index f03081be4..247768722 100644
--- a/nova/network/api.py
+++ b/nova/network/api.py
@@ -18,7 +18,6 @@
"""Handles all requests relating to instances (guest vms)."""
-from nova import db
from nova import exception
from nova import flags
from nova import log as logging
@@ -46,6 +45,10 @@ class API(base.Base):
context.project_id)
return ips
+ def get_vifs_by_instance(self, context, instance_id):
+ vifs = self.db.virtual_interface_get_by_instance(context, instance_id)
+ return vifs
+
def allocate_floating_ip(self, context):
"""Adds a floating ip to a project."""
# NOTE(vish): We don't know which network host should get the ip
@@ -108,7 +111,11 @@ class API(base.Base):
'(%(project)s)') %
{'address': floating_ip['address'],
'project': context.project_id})
- host = fixed_ip['network']['host']
+ # NOTE(vish): if we are multi_host, send to the instances host
+ if fixed_ip['network']['multi_host']:
+ host = fixed_ip['instance']['host']
+ else:
+ host = fixed_ip['network']['host']
rpc.cast(context,
self.db.queue_get_for(context, FLAGS.network_topic, host),
{'method': 'associate_floating_ip',
@@ -123,7 +130,11 @@ class API(base.Base):
return
if not floating_ip.get('fixed_ip'):
raise exception.ApiError('Address is not associated.')
- host = floating_ip['fixed_ip']['network']['host']
+ # NOTE(vish): if we are multi_host, send to the instances host
+ if floating_ip['fixed_ip']['network']['multi_host']:
+ host = floating_ip['fixed_ip']['instance']['host']
+ else:
+ host = floating_ip['fixed_ip']['network']['host']
rpc.call(context,
self.db.queue_get_for(context, FLAGS.network_topic, host),
{'method': 'disassociate_floating_ip',
@@ -137,7 +148,9 @@ class API(base.Base):
args = kwargs
args['instance_id'] = instance['id']
args['project_id'] = instance['project_id']
+ args['host'] = instance['host']
args['instance_type_id'] = instance['instance_type_id']
+
return rpc.call(context, FLAGS.network_topic,
{'method': 'allocate_for_instance',
'args': args})
@@ -151,9 +164,10 @@ class API(base.Base):
{'method': 'deallocate_for_instance',
'args': args})
- def add_fixed_ip_to_instance(self, context, instance_id, network_id):
+ def add_fixed_ip_to_instance(self, context, instance_id, host, network_id):
"""Adds a fixed ip to instance from specified network."""
args = {'instance_id': instance_id,
+ 'host': host,
'network_id': network_id}
rpc.cast(context, FLAGS.network_topic,
{'method': 'add_fixed_ip_to_instance',
@@ -176,7 +190,8 @@ class API(base.Base):
def get_instance_nw_info(self, context, instance):
"""Returns all network info related to an instance."""
args = {'instance_id': instance['id'],
- 'instance_type_id': instance['instance_type_id']}
+ 'instance_type_id': instance['instance_type_id'],
+ 'host': instance['host']}
return rpc.call(context, FLAGS.network_topic,
{'method': 'get_instance_nw_info',
'args': args})
diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py
index 283a5aca1..8ace07884 100644
--- a/nova/network/linux_net.py
+++ b/nova/network/linux_net.py
@@ -455,6 +455,7 @@ def ensure_vlan_bridge(vlan_num, bridge, bridge_interface, net_attrs=None):
"""Create a vlan and bridge unless they already exist."""
interface = ensure_vlan(vlan_num, bridge_interface)
ensure_bridge(bridge, interface, net_attrs)
+ return interface
@utils.synchronized('ensure_vlan', external=True)
@@ -497,7 +498,7 @@ def ensure_bridge(bridge, interface, net_attrs=None):
suffix = net_attrs['cidr'].rpartition('/')[2]
out, err = _execute('sudo', 'ip', 'addr', 'add',
'%s/%s' %
- (net_attrs['gateway'], suffix),
+ (net_attrs['dhcp_server'], suffix),
'brd',
net_attrs['broadcast'],
'dev',
@@ -551,21 +552,27 @@ def ensure_bridge(bridge, interface, net_attrs=None):
bridge)
-def get_dhcp_leases(context, network_id):
+def get_dhcp_leases(context, network_ref):
"""Return a network's hosts config in dnsmasq leasefile format."""
hosts = []
- for fixed_ip_ref in db.network_get_associated_fixed_ips(context,
- network_id):
- hosts.append(_host_lease(fixed_ip_ref))
+ for fixed_ref in db.network_get_associated_fixed_ips(context,
+ network_ref['id']):
+ host = fixed_ref['instance']['host']
+ if network_ref['multi_host'] and FLAGS.host != host:
+ continue
+ hosts.append(_host_lease(fixed_ref))
return '\n'.join(hosts)
-def get_dhcp_hosts(context, network_id):
+def get_dhcp_hosts(context, network_ref):
"""Get network's hosts config in dhcp-host format."""
hosts = []
- for fixed_ip_ref in db.network_get_associated_fixed_ips(context,
- network_id):
- hosts.append(_host_dhcp(fixed_ip_ref))
+ for fixed_ref in db.network_get_associated_fixed_ips(context,
+ network_ref['id']):
+ host = fixed_ref['instance']['host']
+ if network_ref['multi_host'] and FLAGS.host != host:
+ continue
+ hosts.append(_host_dhcp(fixed_ref))
return '\n'.join(hosts)
@@ -573,18 +580,16 @@ def get_dhcp_hosts(context, network_id):
# configuration options (like dchp-range, vlan, ...)
# aren't reloaded.
@utils.synchronized('dnsmasq_start')
-def update_dhcp(context, network_id):
+def update_dhcp(context, network_ref):
"""(Re)starts a dnsmasq server for a given network.
If a dnsmasq instance is already running then send a HUP
signal causing it to reload, otherwise spawn a new instance.
"""
- network_ref = db.network_get(context, network_id)
-
conffile = _dhcp_file(network_ref['bridge'], 'conf')
with open(conffile, 'w') as f:
- f.write(get_dhcp_hosts(context, network_id))
+ f.write(get_dhcp_hosts(context, network_ref))
# Make sure dnsmasq can actually read it (it setuid()s to "nobody")
os.chmod(conffile, 0644)
@@ -612,9 +617,7 @@ def update_dhcp(context, network_id):
@utils.synchronized('radvd_start')
-def update_ra(context, network_id):
- network_ref = db.network_get(context, network_id)
-
+def update_ra(context, network_ref):
conffile = _ra_file(network_ref['bridge'], 'conf')
with open(conffile, 'w') as f:
conf_str = """
@@ -650,9 +653,6 @@ interface %s
LOG.debug(_('Pid %d is stale, relaunching radvd'), pid)
command = _ra_cmd(network_ref)
_execute(*command)
- db.network_update(context, network_id,
- {'gateway_v6':
- utils.get_my_linklocal(network_ref['bridge'])})
def _host_lease(fixed_ip_ref):
@@ -701,10 +701,11 @@ def _dnsmasq_cmd(net):
cmd = ['sudo', '-E', 'dnsmasq',
'--strict-order',
'--bind-interfaces',
+ '--interface=%s' % net['bridge'],
'--conf-file=%s' % FLAGS.dnsmasq_config_file,
'--domain=%s' % FLAGS.dhcp_domain,
'--pid-file=%s' % _dhcp_file(net['bridge'], 'pid'),
- '--listen-address=%s' % net['gateway'],
+ '--listen-address=%s' % net['dhcp_server'],
'--except-interface=lo',
'--dhcp-range=%s,static,120s' % net['dhcp_start'],
'--dhcp-lease-max=%s' % len(netaddr.IPNetwork(net['cidr'])),
diff --git a/nova/network/manager.py b/nova/network/manager.py
index 33cf86e37..4a3791d8a 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -28,7 +28,6 @@ topologies. All of the network commands are issued to a subclass of
:flat_network_bridge: Bridge device for simple network instances
:flat_interface: FlatDhcp will bridge into this interface if set
:flat_network_dns: Dns for simple network
-:flat_network_dhcp_start: Dhcp start for FlatDhcp
:vlan_start: First VLAN for private networks
:vpn_ip: Public IP for the cloudpipe VPN servers
:vpn_start: First Vpn port for private networks
@@ -49,7 +48,6 @@ import datetime
import math
import netaddr
import socket
-import pickle
from eventlet import greenpool
from nova import context
@@ -70,7 +68,7 @@ LOG = logging.getLogger("nova.network.manager")
FLAGS = flags.FLAGS
-flags.DEFINE_string('flat_network_bridge', 'br100',
+flags.DEFINE_string('flat_network_bridge', None,
'Bridge for simple network instances')
flags.DEFINE_string('flat_network_dns', '8.8.4.4',
'Dns for simple network')
@@ -78,8 +76,6 @@ flags.DEFINE_bool('flat_injected', True,
'Whether to attempt to inject network setup into guest')
flags.DEFINE_string('flat_interface', None,
'FlatDhcp will bridge into this interface if set')
-flags.DEFINE_string('flat_network_dhcp_start', '10.0.0.2',
- 'Dhcp start for FlatDhcp')
flags.DEFINE_integer('vlan_start', 100, 'First VLAN for private networks')
flags.DEFINE_string('vlan_interface', None,
'vlans will bridge into this interface if set')
@@ -87,6 +83,8 @@ flags.DEFINE_integer('num_networks', 1, 'Number of networks to support')
flags.DEFINE_string('vpn_ip', '$my_ip',
'Public IP for the cloudpipe VPN servers')
flags.DEFINE_integer('vpn_start', 1000, 'First Vpn port for private networks')
+flags.DEFINE_bool('multi_host', False,
+ 'Default value for multi_host in networks')
flags.DEFINE_integer('network_size', 256,
'Number of addresses in each private subnet')
flags.DEFINE_string('floating_range', '4.4.4.0/24',
@@ -104,7 +102,8 @@ flags.DEFINE_integer('fixed_ip_disassociate_timeout', 600,
'Seconds after which a deallocated ip is disassociated')
flags.DEFINE_integer('create_unique_mac_address_attempts', 5,
'Number of attempts to create unique mac address')
-
+flags.DEFINE_bool('auto_assign_floating_ip', False,
+ 'Autoassigning floating ip to VM')
flags.DEFINE_bool('use_ipv6', False,
'use the ipv6')
flags.DEFINE_string('network_host', socket.gethostname(),
@@ -124,16 +123,26 @@ class RPCAllocateFixedIP(object):
used since they share code to RPC.call allocate_fixed_ip on the
correct network host to configure dnsmasq
"""
- def _allocate_fixed_ips(self, context, instance_id, networks, **kwargs):
+ def _allocate_fixed_ips(self, context, instance_id, host, networks,
+ **kwargs):
"""Calls allocate_fixed_ip once for each network."""
green_pool = greenpool.GreenPool()
vpn = kwargs.pop('vpn')
for network in networks:
- if network['host'] != self.host:
+ # NOTE(vish): if we are not multi_host pass to the network host
+ if not network['multi_host']:
+ host = network['host']
+ # NOTE(vish): if there is no network host, set one
+ if host == None:
+ host = rpc.call(context, FLAGS.network_topic,
+ {'method': 'set_network_host',
+ 'args': {'network_ref': network}})
+ if host != self.host:
# need to call allocate_fixed_ip to correct network host
- topic = self.db.queue_get_for(context, FLAGS.network_topic,
- network['host'])
+ topic = self.db.queue_get_for(context,
+ FLAGS.network_topic,
+ host)
args = {}
args['instance_id'] = instance_id
args['network_id'] = network['id']
@@ -149,12 +158,13 @@ class RPCAllocateFixedIP(object):
# wait for all of the allocates (if any) to finish
green_pool.waitall()
- def _rpc_allocate_fixed_ip(self, context, instance_id, network_id):
+ def _rpc_allocate_fixed_ip(self, context, instance_id, network_id,
+ **kwargs):
"""Sits in between _allocate_fixed_ips and allocate_fixed_ip to
perform network lookup on the far side of rpc.
"""
network = self.db.network_get(context, network_id)
- self.allocate_fixed_ip(context, instance_id, network)
+ self.allocate_fixed_ip(context, instance_id, network, **kwargs)
class FloatingIP(object):
@@ -193,7 +203,7 @@ class FloatingIP(object):
# which is currently the NetworkManager version
# do this first so fixed ip is already allocated
ips = super(FloatingIP, self).allocate_for_instance(context, **kwargs)
- if hasattr(FLAGS, 'auto_assign_floating_ip'):
+ if FLAGS.auto_assign_floating_ip:
# allocate a floating ip (public_ip is just the address string)
public_ip = self.allocate_floating_ip(context, project_id)
# set auto_assigned column to true for the floating ip
@@ -248,7 +258,7 @@ class FloatingIP(object):
# NOTE(tr3buchet): all networks hosts in zone now use the same pool
LOG.debug("QUOTA: %s" % quota.allowed_floating_ips(context, 1))
if quota.allowed_floating_ips(context, 1) < 1:
- LOG.warn(_('Quota exceeeded for %s, tried to allocate '
+ LOG.warn(_('Quota exceeded for %s, tried to allocate '
'address'),
context.project_id)
raise quota.QuotaError(_('Address quota exceeded. You cannot '
@@ -290,6 +300,12 @@ class NetworkManager(manager.SchedulerDependentManager):
The one at a time part is to flatten the layout to help scale
"""
+ # If True, this manager requires VIF to create a bridge.
+ SHOULD_CREATE_BRIDGE = False
+
+ # If True, this manager requires VIF to create VLAN tag.
+ SHOULD_CREATE_VLAN = False
+
timeout_fixed_ips = True
def __init__(self, network_driver=None, *args, **kwargs):
@@ -300,15 +316,36 @@ class NetworkManager(manager.SchedulerDependentManager):
super(NetworkManager, self).__init__(service_name='network',
*args, **kwargs)
+ @utils.synchronized('get_dhcp')
+ def _get_dhcp_ip(self, context, network_ref, host=None):
+ """Get the proper dhcp address to listen on."""
+ # NOTE(vish): this is for compatibility
+ if not network_ref['multi_host']:
+ return network_ref['gateway']
+
+ if not host:
+ host = self.host
+ network_id = network_ref['id']
+ try:
+ fip = self.db.fixed_ip_get_by_network_host(context,
+ network_id,
+ host)
+ return fip['address']
+ except exception.FixedIpNotFoundForNetworkHost:
+ elevated = context.elevated()
+ return self.db.fixed_ip_associate_pool(elevated,
+ network_id,
+ host=host)
+
def init_host(self):
"""Do any initialization that needs to be run if this is a
standalone service.
"""
- # Set up this host for networks in which it's already
- # the designated network host.
+ # NOTE(vish): Set up networks for which this host already has
+ # an ip address.
ctxt = context.get_admin_context()
for network in self.db.network_get_all_by_host(ctxt, self.host):
- self._on_set_network_host(ctxt, network['id'])
+ self._setup_network(ctxt, network)
def periodic_tasks(self, context=None):
"""Tasks to be run at a periodic interval."""
@@ -323,32 +360,13 @@ class NetworkManager(manager.SchedulerDependentManager):
if num:
LOG.debug(_('Dissassociated %s stale fixed ip(s)'), num)
- # setup any new networks which have been created
- self.set_network_hosts(context)
-
- def set_network_host(self, context, network_id):
+ def set_network_host(self, context, network_ref):
"""Safely sets the host of the network."""
LOG.debug(_('setting network host'), context=context)
host = self.db.network_set_host(context,
- network_id,
+ network_ref['id'],
self.host)
- if host == self.host:
- self._on_set_network_host(context, network_id)
-
- def set_network_hosts(self, context):
- """Set the network hosts for any networks which are unset."""
- try:
- networks = self.db.network_get_all(context)
- except exception.NoNetworksFound:
- # no networks found, nothing to do
- return
-
- for network in networks:
- host = network['host']
- if not host:
- # break so worker will only grab 1 (to help scale flatter)
- self.set_network_host(context, network['id'])
- break
+ return host
def _get_networks_for_instance(self, context, instance_id, project_id):
"""Determine & return which networks an instance should connect to."""
@@ -358,12 +376,11 @@ class NetworkManager(manager.SchedulerDependentManager):
try:
networks = self.db.network_get_all(context)
except exception.NoNetworksFound:
- # we don't care if no networks are found
- pass
+ return []
- # return only networks which are not vlan networks and have host set
+ # return only networks which are not vlan networks
return [network for network in networks if
- not network['vlan'] and network['host']]
+ not network['vlan']]
def allocate_for_instance(self, context, **kwargs):
"""Handles allocating the various network resources for an instance.
@@ -371,6 +388,7 @@ class NetworkManager(manager.SchedulerDependentManager):
rpc.called by network_api
"""
instance_id = kwargs.pop('instance_id')
+ host = kwargs.pop('host')
project_id = kwargs.pop('project_id')
type_id = kwargs.pop('instance_type_id')
vpn = kwargs.pop('vpn')
@@ -379,9 +397,11 @@ class NetworkManager(manager.SchedulerDependentManager):
context=context)
networks = self._get_networks_for_instance(admin_context, instance_id,
project_id)
+ LOG.warn(networks)
self._allocate_mac_addresses(context, instance_id, networks)
- self._allocate_fixed_ips(admin_context, instance_id, networks, vpn=vpn)
- return self.get_instance_nw_info(context, instance_id, type_id)
+ self._allocate_fixed_ips(admin_context, instance_id, host, networks,
+ vpn=vpn)
+ return self.get_instance_nw_info(context, instance_id, type_id, host)
def deallocate_for_instance(self, context, **kwargs):
"""Handles deallocating various network resources for an instance.
@@ -401,7 +421,8 @@ class NetworkManager(manager.SchedulerDependentManager):
# deallocate vifs (mac addresses)
self.db.virtual_interface_delete_by_instance(context, instance_id)
- def get_instance_nw_info(self, context, instance_id, instance_type_id):
+ def get_instance_nw_info(self, context, instance_id,
+ instance_type_id, host):
"""Creates network info list for instance.
called by allocate_for_instance and netowrk_api
@@ -411,10 +432,14 @@ class NetworkManager(manager.SchedulerDependentManager):
and info = dict containing pertinent networking data
"""
# TODO(tr3buchet) should handle floating IPs as well?
- fixed_ips = self.db.fixed_ip_get_by_instance(context, instance_id)
+ try:
+ fixed_ips = self.db.fixed_ip_get_by_instance(context, instance_id)
+ except exception.FixedIpNotFoundForInstance:
+ LOG.warn(_('No fixed IPs for instance %s'), instance_id)
+ fixed_ips = []
+
vifs = self.db.virtual_interface_get_by_instance(context, instance_id)
- flavor = self.db.instance_type_get_by_id(context,
- instance_type_id)
+ flavor = self.db.instance_type_get(context, instance_type_id)
network_info = []
# a vif has an address, instance_id, and network_id
# it is also joined to the instance and network given by those IDs
@@ -444,20 +469,38 @@ class NetworkManager(manager.SchedulerDependentManager):
'id': network['id'],
'cidr': network['cidr'],
'cidr_v6': network['cidr_v6'],
- 'injected': network['injected']}
+ 'injected': network['injected'],
+ 'vlan': network['vlan'],
+ 'bridge_interface': network['bridge_interface'],
+ 'multi_host': network['multi_host']}
+ if network['multi_host']:
+ dhcp_server = self._get_dhcp_ip(context, network, host)
+ else:
+ dhcp_server = self._get_dhcp_ip(context,
+ network,
+ network['host'])
info = {
'label': network['label'],
'gateway': network['gateway'],
+ 'dhcp_server': dhcp_server,
'broadcast': network['broadcast'],
'mac': vif['address'],
'rxtx_cap': flavor['rxtx_cap'],
- 'dns': [network['dns']],
- 'ips': [ip_dict(ip) for ip in network_IPs]}
+ 'dns': [],
+ 'ips': [ip_dict(ip) for ip in network_IPs],
+ 'should_create_bridge': self.SHOULD_CREATE_BRIDGE,
+ 'should_create_vlan': self.SHOULD_CREATE_VLAN}
+
if network['cidr_v6']:
info['ip6s'] = [ip6_dict()]
# TODO(tr3buchet): handle ip6 routes here as well
if network['gateway_v6']:
info['gateway6'] = network['gateway_v6']
+ if network['dns1']:
+ info['dns'].append(network['dns1'])
+ if network['dns2']:
+ info['dns'].append(network['dns2'])
+
network_info.append((network_dict, info))
return network_info
@@ -487,10 +530,10 @@ class NetworkManager(manager.SchedulerDependentManager):
random.randint(0x00, 0xff)]
return ':'.join(map(lambda x: "%02x" % x, mac))
- def add_fixed_ip_to_instance(self, context, instance_id, network_id):
+ def add_fixed_ip_to_instance(self, context, instance_id, host, network_id):
"""Adds a fixed ip to an instance from specified network."""
networks = [self.db.network_get(context, network_id)]
- self._allocate_fixed_ips(context, instance_id, networks)
+ self._allocate_fixed_ips(context, instance_id, host, networks)
def remove_fixed_ip_from_instance(self, context, instance_id, address):
"""Removes a fixed ip from an instance from specified network."""
@@ -517,6 +560,7 @@ class NetworkManager(manager.SchedulerDependentManager):
values = {'allocated': True,
'virtual_interface_id': vif['id']}
self.db.fixed_ip_update(context, address, values)
+ self._setup_network(context, network)
return address
def deallocate_fixed_ip(self, context, address, **kwargs):
@@ -562,28 +606,31 @@ class NetworkManager(manager.SchedulerDependentManager):
# means there will stale entries in the conf file
# the code below will update the file if necessary
if FLAGS.update_dhcp_on_disassociate:
- network = self.db.fixed_ip_get_network(context, address)
- self.driver.update_dhcp(context, network['id'])
+ network_ref = self.db.fixed_ip_get_network(context, address)
+ self._setup_network(context, network_ref)
- def create_networks(self, context, label, cidr, num_networks,
+ def create_networks(self, context, label, cidr, multi_host, num_networks,
network_size, cidr_v6, gateway_v6, bridge,
- bridge_interface, **kwargs):
+ bridge_interface, dns1=None, dns2=None, **kwargs):
"""Create networks based on parameters."""
fixed_net = netaddr.IPNetwork(cidr)
- fixed_net_v6 = netaddr.IPNetwork(cidr_v6)
- significant_bits_v6 = 64
- network_size_v6 = 1 << 64
+ if FLAGS.use_ipv6:
+ fixed_net_v6 = netaddr.IPNetwork(cidr_v6)
+ significant_bits_v6 = 64
+ network_size_v6 = 1 << 64
+
for index in range(num_networks):
start = index * network_size
- start_v6 = index * network_size_v6
significant_bits = 32 - int(math.log(network_size, 2))
cidr = '%s/%s' % (fixed_net[start], significant_bits)
project_net = netaddr.IPNetwork(cidr)
net = {}
net['bridge'] = bridge
net['bridge_interface'] = bridge_interface
- net['dns'] = FLAGS.flat_network_dns
+ net['dns1'] = dns1
+ net['dns2'] = dns2
net['cidr'] = cidr
+ net['multi_host'] = multi_host
net['netmask'] = str(project_net.netmask)
net['gateway'] = str(project_net[1])
net['broadcast'] = str(project_net.broadcast)
@@ -594,6 +641,7 @@ class NetworkManager(manager.SchedulerDependentManager):
net['label'] = label
if FLAGS.use_ipv6:
+ start_v6 = index * network_size_v6
cidr_v6 = '%s/%s' % (fixed_net_v6[start_v6],
significant_bits_v6)
net['cidr_v6'] = cidr_v6
@@ -610,7 +658,8 @@ class NetworkManager(manager.SchedulerDependentManager):
if kwargs.get('vpn', False):
# this bit here is for vlan-manager
- del net['dns']
+ del net['dns1']
+ del net['dns2']
vlan = kwargs['vlan_start'] + index
net['vpn_private_address'] = str(project_net[2])
net['dhcp_start'] = str(project_net[3])
@@ -659,20 +708,13 @@ class NetworkManager(manager.SchedulerDependentManager):
'address': address,
'reserved': reserved})
- def _allocate_fixed_ips(self, context, instance_id, networks, **kwargs):
+ def _allocate_fixed_ips(self, context, instance_id, host, networks,
+ **kwargs):
"""Calls allocate_fixed_ip once for each network."""
raise NotImplementedError()
- def _on_set_network_host(self, context, network_id):
- """Called when this host becomes the host for a network."""
- raise NotImplementedError()
-
- def setup_compute_network(self, context, instance_id):
- """Sets up matching network for compute hosts.
-
- this code is run on and by the compute host, not on network
- hosts
- """
+ def _setup_network(self, context, network_ref):
+ """Sets up network on this host."""
raise NotImplementedError()
@@ -680,9 +722,9 @@ class FlatManager(NetworkManager):
"""Basic network where no vlans are used.
FlatManager does not do any bridge or vlan creation. The user is
- responsible for setting up whatever bridge is specified in
- flat_network_bridge (br100 by default). This bridge needs to be created
- on all compute hosts.
+ responsible for setting up whatever bridges are specified when creating
+ networks through nova-manage. This bridge needs to be created on all
+ compute hosts.
The idea is to create a single network for the host with a command like:
nova-manage network create 192.168.0.0/24 1 256. Creating multiple
@@ -706,7 +748,8 @@ class FlatManager(NetworkManager):
timeout_fixed_ips = False
- def _allocate_fixed_ips(self, context, instance_id, networks, **kwargs):
+ def _allocate_fixed_ips(self, context, instance_id, host, networks,
+ **kwargs):
"""Calls allocate_fixed_ip once for each network."""
for network in networks:
self.allocate_fixed_ip(context, instance_id, network)
@@ -717,19 +760,11 @@ class FlatManager(NetworkManager):
**kwargs)
self.db.fixed_ip_disassociate(context, address)
- def setup_compute_network(self, context, instance_id):
- """Network is created manually.
-
- this code is run on and by the compute host, not on network hosts
- """
- pass
-
- def _on_set_network_host(self, context, network_id):
- """Called when this host becomes the host for a network."""
+ def _setup_network(self, context, network_ref):
+ """Setup Network on this host."""
net = {}
net['injected'] = FLAGS.flat_injected
- net['dns'] = FLAGS.flat_network_dns
- self.db.network_update(context, network_id, net)
+ self.db.network_update(context, network_ref['id'], net)
class FlatDHCPManager(FloatingIP, RPCAllocateFixedIP, NetworkManager):
@@ -741,6 +776,8 @@ class FlatDHCPManager(FloatingIP, RPCAllocateFixedIP, NetworkManager):
"""
+ SHOULD_CREATE_BRIDGE = True
+
def init_host(self):
"""Do any initialization that needs to be run if this is a
standalone service.
@@ -753,37 +790,19 @@ class FlatDHCPManager(FloatingIP, RPCAllocateFixedIP, NetworkManager):
self.driver.metadata_forward()
- def setup_compute_network(self, context, instance_id):
- """Sets up matching networks for compute hosts.
-
- this code is run on and by the compute host, not on network hosts
- """
- networks = db.network_get_all_by_instance(context, instance_id)
- for network in networks:
- self.driver.ensure_bridge(network['bridge'],
- network['bridge_interface'])
-
- def allocate_fixed_ip(self, context, instance_id, network, **kwargs):
- """Allocate flat_network fixed_ip, then setup dhcp for this network."""
- address = super(FlatDHCPManager, self).allocate_fixed_ip(context,
- instance_id,
- network)
+ def _setup_network(self, context, network_ref):
+ """Sets up network on this host."""
+ network_ref['dhcp_server'] = self._get_dhcp_ip(context, network_ref)
+ self.driver.ensure_bridge(network_ref['bridge'],
+ network_ref['bridge_interface'],
+ network_ref)
if not FLAGS.fake_network:
- self.driver.update_dhcp(context, network['id'])
-
- def _on_set_network_host(self, context, network_id):
- """Called when this host becomes the host for a project."""
- net = {}
- net['dhcp_start'] = FLAGS.flat_network_dhcp_start
- self.db.network_update(context, network_id, net)
- network = db.network_get(context, network_id)
- self.driver.ensure_bridge(network['bridge'],
- network['bridge_interface'],
- network)
- if not FLAGS.fake_network:
- self.driver.update_dhcp(context, network_id)
+ self.driver.update_dhcp(context, network_ref)
if(FLAGS.use_ipv6):
- self.driver.update_ra(context, network_id)
+ self.driver.update_ra(context, network_ref)
+ gateway = utils.get_my_linklocal(network_ref['bridge'])
+ self.db.network_update(context, network_ref['id'],
+ {'gateway_v6': gateway})
class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):
@@ -801,6 +820,9 @@ class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):
"""
+ SHOULD_CREATE_BRIDGE = True
+ SHOULD_CREATE_VLAN = True
+
def init_host(self):
"""Do any initialization that needs to be run if this is a
standalone service.
@@ -832,30 +854,17 @@ class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):
values = {'allocated': True,
'virtual_interface_id': vif['id']}
self.db.fixed_ip_update(context, address, values)
- if not FLAGS.fake_network:
- self.driver.update_dhcp(context, network['id'])
+ self._setup_network(context, network)
+ return address
def add_network_to_project(self, context, project_id):
"""Force adds another network to a project."""
self.db.network_associate(context, project_id, force=True)
- def setup_compute_network(self, context, instance_id):
- """Sets up matching network for compute hosts.
- this code is run on and by the compute host, not on network hosts
- """
- networks = self.db.network_get_all_by_instance(context, instance_id)
- for network in networks:
- self.driver.ensure_vlan_bridge(network['vlan'],
- network['bridge'],
- network['bridge_interface'])
-
def _get_networks_for_instance(self, context, instance_id, project_id):
"""Determine which networks an instance should connect to."""
# get networks associated with project
- networks = self.db.project_get_networks(context, project_id)
-
- # return only networks which have host set
- return [network for network in networks if network['host']]
+ return self.db.project_get_networks(context, project_id)
def create_networks(self, context, **kwargs):
"""Create networks based on parameters."""
@@ -874,32 +883,35 @@ class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):
NetworkManager.create_networks(self, context, vpn=True, **kwargs)
- def _on_set_network_host(self, context, network_id):
- """Called when this host becomes the host for a network."""
- network = self.db.network_get(context, network_id)
- if not network['vpn_public_address']:
+ def _setup_network(self, context, network_ref):
+ """Sets up network on this host."""
+ if not network_ref['vpn_public_address']:
net = {}
address = FLAGS.vpn_ip
net['vpn_public_address'] = address
- db.network_update(context, network_id, net)
+ network_ref = db.network_update(context, network_ref['id'], net)
else:
- address = network['vpn_public_address']
- self.driver.ensure_vlan_bridge(network['vlan'],
- network['bridge'],
- network['bridge_interface'],
- network)
+ address = network_ref['vpn_public_address']
+ network_ref['dhcp_server'] = self._get_dhcp_ip(context, network_ref)
+ self.driver.ensure_vlan_bridge(network_ref['vlan'],
+ network_ref['bridge'],
+ network_ref['bridge_interface'],
+ network_ref)
# NOTE(vish): only ensure this forward if the address hasn't been set
# manually.
if address == FLAGS.vpn_ip and hasattr(self.driver,
"ensure_vlan_forward"):
self.driver.ensure_vlan_forward(FLAGS.vpn_ip,
- network['vpn_public_port'],
- network['vpn_private_address'])
+ network_ref['vpn_public_port'],
+ network_ref['vpn_private_address'])
if not FLAGS.fake_network:
- self.driver.update_dhcp(context, network_id)
+ self.driver.update_dhcp(context, network_ref)
if(FLAGS.use_ipv6):
- self.driver.update_ra(context, network_id)
+ self.driver.update_ra(context, network_ref)
+ gateway = utils.get_my_linklocal(network_ref['bridge'])
+ self.db.network_update(context, network_ref['id'],
+ {'gateway_v6': gateway})
@property
def _bottom_reserved_ips(self):
diff --git a/nova/network/vmwareapi_net.py b/nova/network/vmwareapi_net.py
deleted file mode 100644
index b32cf3303..000000000
--- a/nova/network/vmwareapi_net.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
-#
-# 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.
-
-"""Implements vlans for vmwareapi."""
-
-from nova import db
-from nova import exception
-from nova import flags
-from nova import log as logging
-from nova import utils
-from nova.virt.vmwareapi_conn import VMWareAPISession
-from nova.virt.vmwareapi import network_utils
-
-
-LOG = logging.getLogger("nova.network.vmwareapi_net")
-
-
-FLAGS = flags.FLAGS
-FLAGS['vlan_interface'].SetDefault('vmnic0')
-
-
-def ensure_vlan_bridge(vlan_num, bridge, bridge_interface, net_attrs=None):
- """Create a vlan and bridge unless they already exist."""
- # Open vmwareapi session
- host_ip = FLAGS.vmwareapi_host_ip
- host_username = FLAGS.vmwareapi_host_username
- host_password = FLAGS.vmwareapi_host_password
- if not host_ip or host_username is None or host_password is None:
- raise Exception(_('Must specify vmwareapi_host_ip, '
- 'vmwareapi_host_username '
- 'and vmwareapi_host_password to use '
- 'connection_type=vmwareapi'))
- session = VMWareAPISession(host_ip, host_username, host_password,
- FLAGS.vmwareapi_api_retry_count)
- vlan_interface = bridge_interface
- # Check if the vlan_interface physical network adapter exists on the host
- if not network_utils.check_if_vlan_interface_exists(session,
- vlan_interface):
- raise exception.NetworkAdapterNotFound(adapter=vlan_interface)
-
- # Get the vSwitch associated with the Physical Adapter
- vswitch_associated = network_utils.get_vswitch_for_vlan_interface(
- session, vlan_interface)
- if vswitch_associated is None:
- raise exception.SwicthNotFoundForNetworkAdapter(adapter=vlan_interface)
- # Check whether bridge already exists and retrieve the the ref of the
- # network whose name_label is "bridge"
- network_ref = network_utils.get_network_with_the_name(session, bridge)
- if network_ref is None:
- # Create a port group on the vSwitch associated with the vlan_interface
- # corresponding physical network adapter on the ESX host
- network_utils.create_port_group(session, bridge, vswitch_associated,
- vlan_num)
- else:
- # Get the vlan id and vswitch corresponding to the port group
- pg_vlanid, pg_vswitch = \
- network_utils.get_vlanid_and_vswitch_for_portgroup(session, bridge)
-
- # Check if the vswitch associated is proper
- if pg_vswitch != vswitch_associated:
- raise exception.InvalidVLANPortGroup(bridge=bridge,
- expected=vswitch_associated,
- actual=pg_vswitch)
-
- # Check if the vlan id is proper for the port group
- if pg_vlanid != vlan_num:
- raise exception.InvalidVLANTag(bridge=bridge, tag=vlan_num,
- pgroup=pg_vlanid)
diff --git a/nova/network/xenapi_net.py b/nova/network/xenapi_net.py
deleted file mode 100644
index e86f4017d..000000000
--- a/nova/network/xenapi_net.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
-#
-# 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.
-
-"""Implements vlans, bridges, and iptables rules using linux utilities."""
-
-import os
-
-from nova import db
-from nova import exception
-from nova import flags
-from nova import log as logging
-from nova import utils
-from nova.virt import xenapi_conn
-from nova.virt.xenapi import network_utils
-
-
-LOG = logging.getLogger("nova.xenapi_net")
-
-
-FLAGS = flags.FLAGS
-
-
-def ensure_vlan_bridge(vlan_num, bridge, bridge_interface, net_attrs=None):
- """Create a vlan and bridge unless they already exist."""
- # Open xenapi session
- LOG.debug('ENTERING ensure_vlan_bridge in xenapi net')
- url = FLAGS.xenapi_connection_url
- username = FLAGS.xenapi_connection_username
- password = FLAGS.xenapi_connection_password
- session = xenapi_conn.XenAPISession(url, username, password)
- # Check whether bridge already exists
- # Retrieve network whose name_label is "bridge"
- network_ref = network_utils.NetworkHelper.find_network_with_name_label(
- session,
- bridge)
- if network_ref is None:
- # If bridge does not exists
- # 1 - create network
- description = 'network for nova bridge %s' % bridge
- network_rec = {'name_label': bridge,
- 'name_description': description,
- 'other_config': {}}
- network_ref = session.call_xenapi('network.create', network_rec)
- # 2 - find PIF for VLAN
- # NOTE(salvatore-orlando): using double quotes inside single quotes
- # as xapi filter only support tokens in double quotes
- expr = 'field "device" = "%s" and \
- field "VLAN" = "-1"' % bridge_interface
- pifs = session.call_xenapi('PIF.get_all_records_where', expr)
- pif_ref = None
- # Multiple PIF are ok: we are dealing with a pool
- if len(pifs) == 0:
- raise Exception(
- _('Found no PIF for device %s') % bridge_interface)
- # 3 - create vlan for network
- for pif_ref in pifs.keys():
- session.call_xenapi('VLAN.create',
- pif_ref,
- str(vlan_num),
- network_ref)
- else:
- # Check VLAN tag is appropriate
- network_rec = session.call_xenapi('network.get_record', network_ref)
- # Retrieve PIFs from network
- for pif_ref in network_rec['PIFs']:
- # Retrieve VLAN from PIF
- pif_rec = session.call_xenapi('PIF.get_record', pif_ref)
- pif_vlan = int(pif_rec['VLAN'])
- # Raise an exception if VLAN != vlan_num
- if pif_vlan != vlan_num:
- raise Exception(_("PIF %(pif_rec['uuid'])s for network "
- "%(bridge)s has VLAN id %(pif_vlan)d. "
- "Expected %(vlan_num)d") % locals())
diff --git a/nova/tests/__init__.py b/nova/tests/__init__.py
index e4ed75d37..720d5b0e6 100644
--- a/nova/tests/__init__.py
+++ b/nova/tests/__init__.py
@@ -59,6 +59,7 @@ def setup():
network.create_networks(ctxt,
label='test',
cidr=FLAGS.fixed_range,
+ multi_host=FLAGS.multi_host,
num_networks=FLAGS.num_networks,
network_size=FLAGS.network_size,
cidr_v6=FLAGS.fixed_range_v6,
@@ -66,9 +67,10 @@ def setup():
bridge=FLAGS.flat_network_bridge,
bridge_interface=bridge_interface,
vpn_start=FLAGS.vpn_start,
- vlan_start=FLAGS.vlan_start)
+ vlan_start=FLAGS.vlan_start,
+ dns1=FLAGS.flat_network_dns)
for net in db.network_get_all(ctxt):
- network.set_network_host(ctxt, net['id'])
+ network.set_network_host(ctxt, net)
cleandb = os.path.join(FLAGS.state_path, FLAGS.sqlite_clean_db)
shutil.copyfile(testdb, cleandb)
diff --git a/nova/tests/api/openstack/test_common.py b/nova/tests/api/openstack/test_common.py
index 4c4d03995..f09270b34 100644
--- a/nova/tests/api/openstack/test_common.py
+++ b/nova/tests/api/openstack/test_common.py
@@ -247,3 +247,21 @@ class MiscFunctionsTest(test.TestCase):
self.assertRaises(ValueError,
common.get_id_from_href,
fixture)
+
+ def test_get_version_from_href(self):
+ fixture = 'http://www.testsite.com/v1.1/images'
+ expected = '1.1'
+ actual = common.get_version_from_href(fixture)
+ self.assertEqual(actual, expected)
+
+ def test_get_version_from_href_2(self):
+ fixture = 'http://www.testsite.com/v1.1'
+ expected = '1.1'
+ actual = common.get_version_from_href(fixture)
+ self.assertEqual(actual, expected)
+
+ def test_get_version_from_href_default(self):
+ fixture = 'http://www.testsite.com/images'
+ expected = '1.0'
+ actual = common.get_version_from_href(fixture)
+ self.assertEqual(actual, expected)
diff --git a/nova/tests/api/openstack/test_extensions.py b/nova/tests/api/openstack/test_extensions.py
index 697c62e5c..d459c694f 100644
--- a/nova/tests/api/openstack/test_extensions.py
+++ b/nova/tests/api/openstack/test_extensions.py
@@ -16,10 +16,11 @@
# under the License.
import json
+import os.path
import stubout
import unittest
import webob
-import os.path
+from xml.etree import ElementTree
from nova import context
from nova import flags
@@ -30,7 +31,8 @@ from nova.api.openstack import wsgi
from nova.tests.api.openstack import fakes
FLAGS = flags.FLAGS
-
+NS = "{http://docs.openstack.org/compute/api/v1.1}"
+ATOMNS = "{http://www.w3.org/2005/Atom}"
response_body = "Try to say this Mr. Knox, sir..."
@@ -80,20 +82,99 @@ class StubExtensionManager(object):
class ExtensionControllerTest(unittest.TestCase):
- def test_index(self):
+ def setUp(self):
+ FLAGS.osapi_extensions_path = os.path.join(
+ os.path.dirname(__file__), "extensions")
+
+ def test_list_extensions_json(self):
app = openstack.APIRouterV11()
ext_midware = extensions.ExtensionMiddleware(app)
request = webob.Request.blank("/extensions")
response = request.get_response(ext_midware)
self.assertEqual(200, response.status_int)
- def test_get_by_alias(self):
+ # Make sure we have all the extensions.
+ data = json.loads(response.body)
+ names = [x['name'] for x in data['extensions']]
+ names.sort()
+ self.assertEqual(names, ["FlavorExtraSpecs", "Floating_ips",
+ "Fox In Socks", "Hosts", "Multinic", "Volumes"])
+
+ # Make sure that at least Fox in Sox is correct.
+ (fox_ext,) = [
+ x for x in data['extensions'] if x['alias'] == 'FOXNSOX']
+ self.assertEqual(fox_ext, {
+ 'namespace': 'http://www.fox.in.socks/api/ext/pie/v1.0',
+ 'name': 'Fox In Socks',
+ 'updated': '2011-01-22T13:25:27-06:00',
+ 'description': 'The Fox In Socks Extension',
+ 'alias': 'FOXNSOX',
+ 'links': []
+ }
+ )
+
+ def test_get_extension_json(self):
app = openstack.APIRouterV11()
ext_midware = extensions.ExtensionMiddleware(app)
request = webob.Request.blank("/extensions/FOXNSOX")
response = request.get_response(ext_midware)
self.assertEqual(200, response.status_int)
+ data = json.loads(response.body)
+ self.assertEqual(data['extension'], {
+ "namespace": "http://www.fox.in.socks/api/ext/pie/v1.0",
+ "name": "Fox In Socks",
+ "updated": "2011-01-22T13:25:27-06:00",
+ "description": "The Fox In Socks Extension",
+ "alias": "FOXNSOX",
+ "links": []
+ }
+ )
+
+ def test_list_extensions_xml(self):
+ app = openstack.APIRouterV11()
+ ext_midware = extensions.ExtensionMiddleware(app)
+ request = webob.Request.blank("/extensions")
+ request.accept = "application/xml"
+ response = request.get_response(ext_midware)
+ self.assertEqual(200, response.status_int)
+ print response.body
+
+ root = ElementTree.XML(response.body)
+ self.assertEqual(root.tag.split('extensions')[0], NS)
+
+ # Make sure we have all the extensions.
+ exts = root.findall('{0}extension'.format(NS))
+ self.assertEqual(len(exts), 6)
+
+ # Make sure that at least Fox in Sox is correct.
+ (fox_ext,) = [x for x in exts if x.get('alias') == 'FOXNSOX']
+ self.assertEqual(fox_ext.get('name'), 'Fox In Socks')
+ self.assertEqual(fox_ext.get('namespace'),
+ 'http://www.fox.in.socks/api/ext/pie/v1.0')
+ self.assertEqual(fox_ext.get('updated'), '2011-01-22T13:25:27-06:00')
+ self.assertEqual(fox_ext.findtext('{0}description'.format(NS)),
+ 'The Fox In Socks Extension')
+
+ def test_get_extension_xml(self):
+ app = openstack.APIRouterV11()
+ ext_midware = extensions.ExtensionMiddleware(app)
+ request = webob.Request.blank("/extensions/FOXNSOX")
+ request.accept = "application/xml"
+ response = request.get_response(ext_midware)
+ self.assertEqual(200, response.status_int)
+ print response.body
+
+ root = ElementTree.XML(response.body)
+ self.assertEqual(root.tag.split('extension')[0], NS)
+ self.assertEqual(root.get('alias'), 'FOXNSOX')
+ self.assertEqual(root.get('name'), 'Fox In Socks')
+ self.assertEqual(root.get('namespace'),
+ 'http://www.fox.in.socks/api/ext/pie/v1.0')
+ self.assertEqual(root.get('updated'), '2011-01-22T13:25:27-06:00')
+ self.assertEqual(root.findtext('{0}description'.format(NS)),
+ 'The Fox In Socks Extension')
+
class ResourceExtensionTest(unittest.TestCase):
@@ -192,7 +273,7 @@ class ActionExtensionTest(unittest.TestCase):
def test_invalid_action(self):
body = dict(blah=dict(name="test"))
- response = self._send_server_action_request("/asdf/1/action", body)
+ response = self._send_server_action_request("/fdsa/1/action", body)
self.assertEqual(404, response.status_int)
@@ -244,3 +325,109 @@ class RequestExtensionTest(unittest.TestCase):
response_data = json.loads(response.body)
self.assertEqual('newblue', response_data['flavor']['googoose'])
self.assertEqual("Pig Bands!", response_data['big_bands'])
+
+
+class ExtensionsXMLSerializerTest(unittest.TestCase):
+
+ def test_serialize_extenstion(self):
+ serializer = extensions.ExtensionsXMLSerializer()
+ data = {
+ 'extension': {
+ 'name': 'ext1',
+ 'namespace': 'http://docs.rack.com/servers/api/ext/pie/v1.0',
+ 'alias': 'RS-PIE',
+ 'updated': '2011-01-22T13:25:27-06:00',
+ 'description': 'Adds the capability to share an image.',
+ 'links': [
+ {
+ 'rel': 'describedby',
+ 'type': 'application/pdf',
+ 'href': 'http://docs.rack.com/servers/api/ext/cs.pdf'
+ },
+ {
+ 'rel': 'describedby',
+ 'type': 'application/vnd.sun.wadl+xml',
+ 'href': 'http://docs.rack.com/servers/api/ext/cs.wadl'
+ }
+ ]
+ }
+ }
+
+ xml = serializer.serialize(data, 'show')
+ root = ElementTree.XML(xml)
+ ext_dict = data['extension']
+ self.assertEqual(root.findtext('{0}description'.format(NS)),
+ ext_dict['description'])
+
+ for key in ['name', 'namespace', 'alias', 'updated']:
+ self.assertEqual(root.get(key), ext_dict[key])
+
+ link_nodes = root.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(ext_dict['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
+
+ def test_serialize_extensions(self):
+ serializer = extensions.ExtensionsXMLSerializer()
+ data = {
+ "extensions": [
+ {
+ "name": "Public Image Extension",
+ "namespace": "http://foo.com/api/ext/pie/v1.0",
+ "alias": "RS-PIE",
+ "updated": "2011-01-22T13:25:27-06:00",
+ "description": "Adds the capability to share an image.",
+ "links": [
+ {
+ "rel": "describedby",
+ "type": "application/pdf",
+ "href": "http://foo.com/api/ext/cs-pie.pdf"
+ },
+ {
+ "rel": "describedby",
+ "type": "application/vnd.sun.wadl+xml",
+ "href": "http://foo.com/api/ext/cs-pie.wadl"
+ }
+ ]
+ },
+ {
+ "name": "Cloud Block Storage",
+ "namespace": "http://foo.com/api/ext/cbs/v1.0",
+ "alias": "RS-CBS",
+ "updated": "2011-01-12T11:22:33-06:00",
+ "description": "Allows mounting cloud block storage.",
+ "links": [
+ {
+ "rel": "describedby",
+ "type": "application/pdf",
+ "href": "http://foo.com/api/ext/cs-cbs.pdf"
+ },
+ {
+ "rel": "describedby",
+ "type": "application/vnd.sun.wadl+xml",
+ "href": "http://foo.com/api/ext/cs-cbs.wadl"
+ }
+ ]
+ }
+ ]
+ }
+
+ xml = serializer.serialize(data, 'index')
+ print xml
+ root = ElementTree.XML(xml)
+ ext_elems = root.findall('{0}extension'.format(NS))
+ self.assertEqual(len(ext_elems), 2)
+ for i, ext_elem in enumerate(ext_elems):
+ ext_dict = data['extensions'][i]
+ self.assertEqual(ext_elem.findtext('{0}description'.format(NS)),
+ ext_dict['description'])
+
+ for key in ['name', 'namespace', 'alias', 'updated']:
+ self.assertEqual(ext_elem.get(key), ext_dict[key])
+
+ link_nodes = ext_elem.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(ext_dict['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
diff --git a/nova/tests/api/openstack/test_faults.py b/nova/tests/api/openstack/test_faults.py
index 4d86ffb26..6da27540a 100644
--- a/nova/tests/api/openstack/test_faults.py
+++ b/nova/tests/api/openstack/test_faults.py
@@ -16,6 +16,7 @@
# under the License.
import json
+from xml.dom import minidom
import webob
import webob.dec
@@ -24,6 +25,7 @@ import webob.exc
from nova import test
from nova.api.openstack import common
from nova.api.openstack import faults
+from nova.api.openstack import wsgi
class TestFaults(test.TestCase):
@@ -139,3 +141,113 @@ class TestFaults(test.TestCase):
self.assertEqual(resp.content_type, "application/xml")
self.assertEqual(resp.status_int, 404)
self.assertTrue('whut?' in resp.body)
+
+ def test_fault_has_status_int(self):
+ """Ensure the status_int is set correctly on faults"""
+ fault = faults.Fault(webob.exc.HTTPBadRequest(explanation='what?'))
+ self.assertEqual(fault.status_int, 400)
+
+ def test_v10_xml_serializer(self):
+ """Ensure that a v1.0 request responds with a v1.0 xmlns"""
+ request = webob.Request.blank('/',
+ headers={"Accept": "application/xml"})
+
+ fault = faults.Fault(webob.exc.HTTPBadRequest(explanation='scram'))
+ response = request.get_response(fault)
+
+ self.assertTrue(common.XML_NS_V10 in response.body)
+ self.assertEqual(response.content_type, "application/xml")
+ self.assertEqual(response.status_int, 400)
+
+ def test_v11_xml_serializer(self):
+ """Ensure that a v1.1 request responds with a v1.1 xmlns"""
+ request = webob.Request.blank('/v1.1',
+ headers={"Accept": "application/xml"})
+
+ fault = faults.Fault(webob.exc.HTTPBadRequest(explanation='scram'))
+ response = request.get_response(fault)
+
+ self.assertTrue(common.XML_NS_V11 in response.body)
+ self.assertEqual(response.content_type, "application/xml")
+ self.assertEqual(response.status_int, 400)
+
+
+class FaultsXMLSerializationTestV11(test.TestCase):
+ """Tests covering `nova.api.openstack.faults:Fault` class."""
+
+ def _prepare_xml(self, xml_string):
+ xml_string = xml_string.replace(" ", "")
+ xml_string = xml_string.replace("\n", "")
+ xml_string = xml_string.replace("\t", "")
+ return xml_string
+
+ def test_400_fault(self):
+ metadata = {'attributes': {"badRequest": 'code'}}
+ serializer = wsgi.XMLDictSerializer(metadata=metadata,
+ xmlns=common.XML_NS_V11)
+
+ fixture = {
+ "badRequest": {
+ "message": "scram",
+ "code": 400,
+ },
+ }
+
+ output = serializer.serialize(fixture)
+ actual = minidom.parseString(self._prepare_xml(output))
+
+ expected = minidom.parseString(self._prepare_xml("""
+ <badRequest code="400" xmlns="%s">
+ <message>scram</message>
+ </badRequest>
+ """) % common.XML_NS_V11)
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_413_fault(self):
+ metadata = {'attributes': {"overLimit": 'code'}}
+ serializer = wsgi.XMLDictSerializer(metadata=metadata,
+ xmlns=common.XML_NS_V11)
+
+ fixture = {
+ "overLimit": {
+ "message": "sorry",
+ "code": 413,
+ "retryAfter": 4,
+ },
+ }
+
+ output = serializer.serialize(fixture)
+ actual = minidom.parseString(self._prepare_xml(output))
+
+ expected = minidom.parseString(self._prepare_xml("""
+ <overLimit code="413" xmlns="%s">
+ <message>sorry</message>
+ <retryAfter>4</retryAfter>
+ </overLimit>
+ """) % common.XML_NS_V11)
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_404_fault(self):
+ metadata = {'attributes': {"itemNotFound": 'code'}}
+ serializer = wsgi.XMLDictSerializer(metadata=metadata,
+ xmlns=common.XML_NS_V11)
+
+ fixture = {
+ "itemNotFound": {
+ "message": "sorry",
+ "code": 404,
+ },
+ }
+
+ output = serializer.serialize(fixture)
+ actual = minidom.parseString(self._prepare_xml(output))
+
+ expected = minidom.parseString(self._prepare_xml("""
+ <itemNotFound code="404" xmlns="%s">
+ <message>sorry</message>
+ </itemNotFound>
+ """) % common.XML_NS_V11)
+
+ self.assertEqual(expected.toxml(), actual.toxml())
diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py
index 689647cc6..4ac35b26b 100644
--- a/nova/tests/api/openstack/test_flavors.py
+++ b/nova/tests/api/openstack/test_flavors.py
@@ -18,12 +18,14 @@
import json
import stubout
import webob
+import xml.dom.minidom as minidom
+from nova.api.openstack import flavors
import nova.db.api
-from nova import context
from nova import exception
from nova import test
from nova.tests.api.openstack import fakes
+from nova import wsgi
def stub_flavor(flavorid, name, memory_mb="256", local_gb="10"):
@@ -64,7 +66,6 @@ class FlavorsTest(test.TestCase):
return_instance_types)
self.stubs.Set(nova.db.api, "instance_type_get_by_flavor_id",
return_instance_type_by_flavor_id)
- self.context = context.get_admin_context()
def tearDown(self):
self.stubs.UnsetAll()
@@ -146,61 +147,65 @@ class FlavorsTest(test.TestCase):
req.environ['api.version'] = '1.1'
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
- flavor = json.loads(res.body)["flavor"]
+ flavor = json.loads(res.body)
expected = {
- "id": "12",
- "name": "flavor 12",
- "ram": "256",
- "disk": "10",
- "links": [
- {
- "rel": "self",
- "href": "http://localhost/v1.1/flavors/12",
- },
- {
- "rel": "bookmark",
- "href": "http://localhost/flavors/12",
- },
- ],
- }
- self.assertEqual(flavor, expected)
-
- def test_get_flavor_list_v1_1(self):
- req = webob.Request.blank('/v1.1/flavors')
- req.environ['api.version'] = '1.1'
- res = req.get_response(fakes.wsgi_app())
- self.assertEqual(res.status_int, 200)
- flavor = json.loads(res.body)["flavors"]
- expected = [
- {
- "id": "1",
- "name": "flavor 1",
- "links": [
- {
- "rel": "self",
- "href": "http://localhost/v1.1/flavors/1",
- },
- {
- "rel": "bookmark",
- "href": "http://localhost/flavors/1",
- },
- ],
- },
- {
- "id": "2",
- "name": "flavor 2",
+ "flavor": {
+ "id": "12",
+ "name": "flavor 12",
+ "ram": "256",
+ "disk": "10",
"links": [
{
"rel": "self",
- "href": "http://localhost/v1.1/flavors/2",
+ "href": "http://localhost/v1.1/flavors/12",
},
{
"rel": "bookmark",
- "href": "http://localhost/flavors/2",
+ "href": "http://localhost/flavors/12",
},
],
},
- ]
+ }
+ self.assertEqual(flavor, expected)
+
+ def test_get_flavor_list_v1_1(self):
+ req = webob.Request.blank('/v1.1/flavors')
+ req.environ['api.version'] = '1.1'
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 200)
+ flavor = json.loads(res.body)
+ expected = {
+ "flavors": [
+ {
+ "id": "1",
+ "name": "flavor 1",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/flavors/1",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/flavors/1",
+ },
+ ],
+ },
+ {
+ "id": "2",
+ "name": "flavor 2",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/flavors/2",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/flavors/2",
+ },
+ ],
+ },
+ ],
+ }
self.assertEqual(flavor, expected)
def test_get_flavor_list_detail_v1_1(self):
@@ -208,52 +213,273 @@ class FlavorsTest(test.TestCase):
req.environ['api.version'] = '1.1'
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
- flavor = json.loads(res.body)["flavors"]
- expected = [
- {
- "id": "1",
- "name": "flavor 1",
+ flavor = json.loads(res.body)
+ expected = {
+ "flavors": [
+ {
+ "id": "1",
+ "name": "flavor 1",
+ "ram": "256",
+ "disk": "10",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/flavors/1",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/flavors/1",
+ },
+ ],
+ },
+ {
+ "id": "2",
+ "name": "flavor 2",
+ "ram": "256",
+ "disk": "10",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/flavors/2",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/flavors/2",
+ },
+ ],
+ },
+ ],
+ }
+ self.assertEqual(flavor, expected)
+
+ def test_get_empty_flavor_list_v1_1(self):
+ def _return_empty(self):
+ return {}
+ self.stubs.Set(nova.db.api, "instance_type_get_all", _return_empty)
+
+ req = webob.Request.blank('/v1.1/flavors')
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 200)
+ flavors = json.loads(res.body)["flavors"]
+ expected = []
+ self.assertEqual(flavors, expected)
+
+
+class FlavorsXMLSerializationTest(test.TestCase):
+
+ def test_show(self):
+ serializer = flavors.FlavorXMLSerializer()
+
+ input = {
+ "flavor": {
+ "id": "12",
+ "name": "asdf",
"ram": "256",
"disk": "10",
"links": [
{
"rel": "self",
- "href": "http://localhost/v1.1/flavors/1",
+ "href": "http://localhost/v1.1/flavors/12",
},
{
"rel": "bookmark",
- "href": "http://localhost/flavors/1",
+ "href": "http://localhost/flavors/12",
},
],
},
- {
- "id": "2",
- "name": "flavor 2",
- "ram": "256",
- "disk": "10",
+ }
+
+ output = serializer.serialize(input, 'show')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <flavor xmlns="http://docs.openstack.org/compute/api/v1.1"
+ xmlns:atom="http://www.w3.org/2005/Atom"
+ id="12"
+ name="asdf"
+ ram="256"
+ disk="10">
+ <atom:link href="http://localhost/v1.1/flavors/12" rel="self"/>
+ <atom:link href="http://localhost/flavors/12" rel="bookmark"/>
+ </flavor>
+ """.replace(" ", ""))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_show_handles_integers(self):
+ serializer = flavors.FlavorXMLSerializer()
+
+ input = {
+ "flavor": {
+ "id": 12,
+ "name": "asdf",
+ "ram": 256,
+ "disk": 10,
"links": [
{
"rel": "self",
- "href": "http://localhost/v1.1/flavors/2",
+ "href": "http://localhost/v1.1/flavors/12",
},
{
"rel": "bookmark",
- "href": "http://localhost/flavors/2",
+ "href": "http://localhost/flavors/12",
},
],
},
- ]
- self.assertEqual(flavor, expected)
+ }
- def test_get_empty_flavor_list_v1_1(self):
- def _return_empty(self):
- return {}
- self.stubs.Set(nova.db.api, "instance_type_get_all",
- _return_empty)
+ output = serializer.serialize(input, 'show')
+ actual = minidom.parseString(output.replace(" ", ""))
- req = webob.Request.blank('/v1.1/flavors')
- res = req.get_response(fakes.wsgi_app())
- self.assertEqual(res.status_int, 200)
- flavors = json.loads(res.body)["flavors"]
- expected = []
- self.assertEqual(flavors, expected)
+ expected = minidom.parseString("""
+ <flavor xmlns="http://docs.openstack.org/compute/api/v1.1"
+ xmlns:atom="http://www.w3.org/2005/Atom"
+ id="12"
+ name="asdf"
+ ram="256"
+ disk="10">
+ <atom:link href="http://localhost/v1.1/flavors/12" rel="self"/>
+ <atom:link href="http://localhost/flavors/12" rel="bookmark"/>
+ </flavor>
+ """.replace(" ", ""))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_detail(self):
+ serializer = flavors.FlavorXMLSerializer()
+
+ input = {
+ "flavors": [
+ {
+ "id": "23",
+ "name": "flavor 23",
+ "ram": "512",
+ "disk": "20",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/flavors/23",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/flavors/23",
+ },
+ ],
+ }, {
+ "id": "13",
+ "name": "flavor 13",
+ "ram": "256",
+ "disk": "10",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/flavors/13",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/flavors/13",
+ },
+ ],
+ },
+ ],
+ }
+
+ output = serializer.serialize(input, 'detail')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <flavors xmlns="http://docs.openstack.org/compute/api/v1.1"
+ xmlns:atom="http://www.w3.org/2005/Atom">
+ <flavor id="23"
+ name="flavor 23"
+ ram="512"
+ disk="20">
+ <atom:link href="http://localhost/v1.1/flavors/23" rel="self"/>
+ <atom:link href="http://localhost/flavors/23" rel="bookmark"/>
+ </flavor>
+ <flavor id="13"
+ name="flavor 13"
+ ram="256"
+ disk="10">
+ <atom:link href="http://localhost/v1.1/flavors/13" rel="self"/>
+ <atom:link href="http://localhost/flavors/13" rel="bookmark"/>
+ </flavor>
+ </flavors>
+ """.replace(" ", "") % locals())
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_index(self):
+ serializer = flavors.FlavorXMLSerializer()
+
+ input = {
+ "flavors": [
+ {
+ "id": "23",
+ "name": "flavor 23",
+ "ram": "512",
+ "disk": "20",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/flavors/23",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/flavors/23",
+ },
+ ],
+ }, {
+ "id": "13",
+ "name": "flavor 13",
+ "ram": "256",
+ "disk": "10",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/flavors/13",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/flavors/13",
+ },
+ ],
+ },
+ ],
+ }
+
+ output = serializer.serialize(input, 'index')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <flavors xmlns="http://docs.openstack.org/compute/api/v1.1"
+ xmlns:atom="http://www.w3.org/2005/Atom">
+ <flavor id="23" name="flavor 23">
+ <atom:link href="http://localhost/v1.1/flavors/23" rel="self"/>
+ <atom:link href="http://localhost/flavors/23" rel="bookmark"/>
+ </flavor>
+ <flavor id="13" name="flavor 13">
+ <atom:link href="http://localhost/v1.1/flavors/13" rel="self"/>
+ <atom:link href="http://localhost/flavors/13" rel="bookmark"/>
+ </flavor>
+ </flavors>
+ """.replace(" ", "") % locals())
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_index_empty(self):
+ serializer = flavors.FlavorXMLSerializer()
+
+ input = {
+ "flavors": [],
+ }
+
+ output = serializer.serialize(input, 'index')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <flavors xmlns="http://docs.openstack.org/compute/api/v1.1"
+ xmlns:atom="http://www.w3.org/2005/Atom" />
+ """.replace(" ", "") % locals())
+
+ self.assertEqual(expected.toxml(), actual.toxml())
diff --git a/nova/tests/api/openstack/test_image_metadata.py b/nova/tests/api/openstack/test_image_metadata.py
index d9fb61e2a..31ca18497 100644
--- a/nova/tests/api/openstack/test_image_metadata.py
+++ b/nova/tests/api/openstack/test_image_metadata.py
@@ -103,8 +103,7 @@ class ImageMetaDataTest(test.TestCase):
super(ImageMetaDataTest, self).tearDown()
def test_index(self):
- req = webob.Request.blank('/v1.1/images/1/meta')
- req.environ['api.version'] = '1.1'
+ req = webob.Request.blank('/v1.1/images/1/metadata')
res = req.get_response(fakes.wsgi_app())
res_dict = json.loads(res.body)
self.assertEqual(200, res.status_int)
@@ -114,8 +113,7 @@ class ImageMetaDataTest(test.TestCase):
self.assertEqual(value, res_dict['metadata'][key])
def test_show(self):
- req = webob.Request.blank('/v1.1/images/1/meta/key1')
- req.environ['api.version'] = '1.1'
+ req = webob.Request.blank('/v1.1/images/1/metadata/key1')
res = req.get_response(fakes.wsgi_app())
res_dict = json.loads(res.body)
self.assertEqual(200, res.status_int)
@@ -124,42 +122,66 @@ class ImageMetaDataTest(test.TestCase):
self.assertEqual('value1', res_dict['meta']['key1'])
def test_show_not_found(self):
- req = webob.Request.blank('/v1.1/images/1/meta/key9')
- req.environ['api.version'] = '1.1'
+ req = webob.Request.blank('/v1.1/images/1/metadata/key9')
res = req.get_response(fakes.wsgi_app())
self.assertEqual(404, res.status_int)
def test_create(self):
- req = webob.Request.blank('/v1.1/images/2/meta')
- req.environ['api.version'] = '1.1'
+ req = webob.Request.blank('/v1.1/images/2/metadata')
req.method = 'POST'
req.body = '{"metadata": {"key9": "value9"}}'
req.headers["content-type"] = "application/json"
res = req.get_response(fakes.wsgi_app())
- res_dict = json.loads(res.body)
+
+ self.assertEqual(200, res.status_int)
+ actual_output = json.loads(res.body)
+
+ expected_output = {
+ 'metadata': {
+ 'key1': 'value1',
+ 'key2': 'value2',
+ 'key9': 'value9',
+ },
+ }
+
+ self.assertEqual(expected_output, actual_output)
+
+ def test_update_all(self):
+ req = webob.Request.blank('/v1.1/images/2/metadata')
+ req.method = 'PUT'
+ req.body = '{"metadata": {"key9": "value9"}}'
+ req.headers["content-type"] = "application/json"
+ res = req.get_response(fakes.wsgi_app())
+
self.assertEqual(200, res.status_int)
- self.assertEqual('value9', res_dict['metadata']['key9'])
- # other items should not be modified
- self.assertEqual('value1', res_dict['metadata']['key1'])
- self.assertEqual('value2', res_dict['metadata']['key2'])
- self.assertEqual(1, len(res_dict))
+ actual_output = json.loads(res.body)
+
+ expected_output = {
+ 'metadata': {
+ 'key9': 'value9',
+ },
+ }
+
+ self.assertEqual(expected_output, actual_output)
def test_update_item(self):
- req = webob.Request.blank('/v1.1/images/1/meta/key1')
- req.environ['api.version'] = '1.1'
+ req = webob.Request.blank('/v1.1/images/1/metadata/key1')
req.method = 'PUT'
req.body = '{"meta": {"key1": "zz"}}'
req.headers["content-type"] = "application/json"
res = req.get_response(fakes.wsgi_app())
+
self.assertEqual(200, res.status_int)
- res_dict = json.loads(res.body)
- self.assertTrue('meta' in res_dict)
- self.assertEqual(len(res_dict['meta']), 1)
- self.assertEqual('zz', res_dict['meta']['key1'])
+ actual_output = json.loads(res.body)
+ expected_output = {
+ 'meta': {
+ 'key1': 'zz',
+ },
+ }
+ self.assertEqual(actual_output, expected_output)
def test_update_item_bad_body(self):
- req = webob.Request.blank('/v1.1/images/1/meta/key1')
- req.environ['api.version'] = '1.1'
+ req = webob.Request.blank('/v1.1/images/1/metadata/key1')
req.method = 'PUT'
req.body = '{"key1": "zz"}'
req.headers["content-type"] = "application/json"
@@ -167,8 +189,7 @@ class ImageMetaDataTest(test.TestCase):
self.assertEqual(400, res.status_int)
def test_update_item_too_many_keys(self):
- req = webob.Request.blank('/v1.1/images/1/meta/key1')
- req.environ['api.version'] = '1.1'
+ req = webob.Request.blank('/v1.1/images/1/metadata/key1')
req.method = 'PUT'
req.body = '{"meta": {"key1": "value1", "key2": "value2"}}'
req.headers["content-type"] = "application/json"
@@ -176,24 +197,38 @@ class ImageMetaDataTest(test.TestCase):
self.assertEqual(400, res.status_int)
def test_update_item_body_uri_mismatch(self):
- req = webob.Request.blank('/v1.1/images/1/meta/bad')
- req.environ['api.version'] = '1.1'
+ req = webob.Request.blank('/v1.1/images/1/metadata/bad')
req.method = 'PUT'
req.body = '{"meta": {"key1": "value1"}}'
req.headers["content-type"] = "application/json"
res = req.get_response(fakes.wsgi_app())
self.assertEqual(400, res.status_int)
+ def test_update_item_xml(self):
+ req = webob.Request.blank('/v1.1/images/1/metadata/key1')
+ req.method = 'PUT'
+ req.body = '<meta key="key1">five</meta>'
+ req.headers["content-type"] = "application/xml"
+ res = req.get_response(fakes.wsgi_app())
+
+ self.assertEqual(200, res.status_int)
+ actual_output = json.loads(res.body)
+ expected_output = {
+ 'meta': {
+ 'key1': 'five',
+ },
+ }
+ self.assertEqual(actual_output, expected_output)
+
def test_delete(self):
- req = webob.Request.blank('/v1.1/images/2/meta/key1')
- req.environ['api.version'] = '1.1'
+ req = webob.Request.blank('/v1.1/images/2/metadata/key1')
req.method = 'DELETE'
res = req.get_response(fakes.wsgi_app())
- self.assertEqual(200, res.status_int)
+ self.assertEqual(204, res.status_int)
+ self.assertEqual('', res.body)
def test_delete_not_found(self):
- req = webob.Request.blank('/v1.1/images/2/meta/blah')
- req.environ['api.version'] = '1.1'
+ req = webob.Request.blank('/v1.1/images/2/metadata/blah')
req.method = 'DELETE'
res = req.get_response(fakes.wsgi_app())
self.assertEqual(404, res.status_int)
@@ -203,8 +238,7 @@ class ImageMetaDataTest(test.TestCase):
for num in range(FLAGS.quota_metadata_items + 1):
data['metadata']['key%i' % num] = "blah"
json_string = str(data).replace("\'", "\"")
- req = webob.Request.blank('/v1.1/images/2/meta')
- req.environ['api.version'] = '1.1'
+ req = webob.Request.blank('/v1.1/images/2/metadata')
req.method = 'POST'
req.body = json_string
req.headers["content-type"] = "application/json"
@@ -212,8 +246,7 @@ class ImageMetaDataTest(test.TestCase):
self.assertEqual(400, res.status_int)
def test_too_many_metadata_items_on_put(self):
- req = webob.Request.blank('/v1.1/images/3/meta/blah')
- req.environ['api.version'] = '1.1'
+ req = webob.Request.blank('/v1.1/images/3/metadata/blah')
req.method = 'PUT'
req.body = '{"meta": {"blah": "blah"}}'
req.headers["content-type"] = "application/json"
@@ -221,9 +254,49 @@ class ImageMetaDataTest(test.TestCase):
self.assertEqual(400, res.status_int)
+class ImageMetadataXMLDeserializationTest(test.TestCase):
+
+ deserializer = openstack.image_metadata.ImageMetadataXMLDeserializer()
+
+ def test_create(self):
+ request_body = """
+ <metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <meta key='123'>asdf</meta>
+ <meta key='567'>jkl;</meta>
+ </metadata>"""
+ output = self.deserializer.deserialize(request_body, 'create')
+ expected = {"body": {"metadata": {"123": "asdf", "567": "jkl;"}}}
+ self.assertEquals(output, expected)
+
+ def test_create_empty(self):
+ request_body = """
+ <metadata xmlns="http://docs.openstack.org/compute/api/v1.1"/>"""
+ output = self.deserializer.deserialize(request_body, 'create')
+ expected = {"body": {"metadata": {}}}
+ self.assertEquals(output, expected)
+
+ def test_update_all(self):
+ request_body = """
+ <metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <meta key='123'>asdf</meta>
+ <meta key='567'>jkl;</meta>
+ </metadata>"""
+ output = self.deserializer.deserialize(request_body, 'update_all')
+ expected = {"body": {"metadata": {"123": "asdf", "567": "jkl;"}}}
+ self.assertEquals(output, expected)
+
+ def test_update(self):
+ request_body = """
+ <meta xmlns="http://docs.openstack.org/compute/api/v1.1"
+ key='123'>asdf</meta>"""
+ output = self.deserializer.deserialize(request_body, 'update')
+ expected = {"body": {"meta": {"123": "asdf"}}}
+ self.assertEquals(output, expected)
+
+
class ImageMetadataXMLSerializationTest(test.TestCase):
- def test_index_xml(self):
+ def test_index(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'metadata': {
@@ -247,7 +320,7 @@ class ImageMetadataXMLSerializationTest(test.TestCase):
self.assertEqual(expected.toxml(), actual.toxml())
- def test_index_xml_null(self):
+ def test_index_null(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'metadata': {
@@ -267,7 +340,7 @@ class ImageMetadataXMLSerializationTest(test.TestCase):
self.assertEqual(expected.toxml(), actual.toxml())
- def test_index_xml_unicode(self):
+ def test_index_unicode(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'metadata': {
@@ -287,7 +360,7 @@ class ImageMetadataXMLSerializationTest(test.TestCase):
self.assertEqual(expected.toxml(), actual.toxml())
- def test_show_xml(self):
+ def test_show(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'meta': {
@@ -305,7 +378,31 @@ class ImageMetadataXMLSerializationTest(test.TestCase):
self.assertEqual(expected.toxml(), actual.toxml())
- def test_update_item_xml(self):
+ def test_update_all(self):
+ serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
+ fixture = {
+ 'metadata': {
+ 'key6': 'value6',
+ 'key4': 'value4',
+ },
+ }
+ output = serializer.serialize(fixture, 'update_all')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <meta key="key6">
+ value6
+ </meta>
+ <meta key="key4">
+ value4
+ </meta>
+ </metadata>
+ """.replace(" ", ""))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_update_item(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'meta': {
@@ -323,7 +420,7 @@ class ImageMetadataXMLSerializationTest(test.TestCase):
self.assertEqual(expected.toxml(), actual.toxml())
- def test_create_xml(self):
+ def test_create(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'metadata': {
@@ -350,3 +447,8 @@ class ImageMetadataXMLSerializationTest(test.TestCase):
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_delete(self):
+ serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
+ output = serializer.serialize(None, 'delete')
+ self.assertEqual(output, '')
diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py
index 534460d46..87a695dde 100644
--- a/nova/tests/api/openstack/test_images.py
+++ b/nova/tests/api/openstack/test_images.py
@@ -538,7 +538,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
# because the element hasn't changed definition
expected = minidom.parseString("""
<itemNotFound code="404"
- xmlns="http://docs.rackspacecloud.com/servers/api/v1.0">
+ xmlns="http://docs.openstack.org/compute/api/v1.1">
<message>
Image not found.
</message>
@@ -803,154 +803,206 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
self.assertDictListMatch(expected, response_list)
def test_image_filter_with_name(self):
- mocker = mox.Mox()
- image_service = mocker.CreateMockAnything()
+ image_service = self.mox.CreateMockAnything()
context = object()
filters = {'name': 'testname'}
- image_service.index(
- context, filters=filters).AndReturn([])
- mocker.ReplayAll()
- request = webob.Request.blank(
- '/v1.1/images?name=testname')
+ image_service.index(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images?name=testname')
request.environ['nova.context'] = context
controller = images.ControllerV11(image_service=image_service)
controller.index(request)
- mocker.VerifyAll()
+ self.mox.VerifyAll()
def test_image_filter_with_status(self):
- mocker = mox.Mox()
- image_service = mocker.CreateMockAnything()
+ image_service = self.mox.CreateMockAnything()
context = object()
filters = {'status': 'ACTIVE'}
- image_service.index(
- context, filters=filters).AndReturn([])
- mocker.ReplayAll()
- request = webob.Request.blank(
- '/v1.1/images?status=ACTIVE')
+ image_service.index(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images?status=ACTIVE')
request.environ['nova.context'] = context
controller = images.ControllerV11(image_service=image_service)
controller.index(request)
- mocker.VerifyAll()
+ self.mox.VerifyAll()
def test_image_filter_with_property(self):
- mocker = mox.Mox()
- image_service = mocker.CreateMockAnything()
+ image_service = self.mox.CreateMockAnything()
context = object()
filters = {'property-test': '3'}
- image_service.index(
- context, filters=filters).AndReturn([])
- mocker.ReplayAll()
- request = webob.Request.blank(
- '/v1.1/images?property-test=3')
+ image_service.index(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images?property-test=3')
+ request.environ['nova.context'] = context
+ controller = images.ControllerV11(image_service=image_service)
+ controller.index(request)
+ self.mox.VerifyAll()
+
+ def test_image_filter_server(self):
+ image_service = self.mox.CreateMockAnything()
+ context = object()
+ # 'server' should be converted to 'property-instance_ref'
+ filters = {'property-instance_ref': 'http://localhost:8774/servers/12'}
+ image_service.index(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images?server='
+ 'http://localhost:8774/servers/12')
+ request.environ['nova.context'] = context
+ controller = images.ControllerV11(image_service=image_service)
+ controller.index(request)
+ self.mox.VerifyAll()
+
+ def test_image_filter_changes_since(self):
+ image_service = self.mox.CreateMockAnything()
+ context = object()
+ filters = {'changes-since': '2011-01-24T17:08Z'}
+ image_service.index(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images?changes-since='
+ '2011-01-24T17:08Z')
+ request.environ['nova.context'] = context
+ controller = images.ControllerV11(image_service=image_service)
+ controller.index(request)
+ self.mox.VerifyAll()
+
+ def test_image_filter_with_type(self):
+ image_service = self.mox.CreateMockAnything()
+ context = object()
+ filters = {'property-image_type': 'BASE'}
+ image_service.index(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images?type=BASE')
request.environ['nova.context'] = context
controller = images.ControllerV11(image_service=image_service)
controller.index(request)
- mocker.VerifyAll()
+ self.mox.VerifyAll()
def test_image_filter_not_supported(self):
- mocker = mox.Mox()
- image_service = mocker.CreateMockAnything()
+ image_service = self.mox.CreateMockAnything()
context = object()
filters = {'status': 'ACTIVE'}
- image_service.index(
- context, filters=filters).AndReturn([])
- mocker.ReplayAll()
- request = webob.Request.blank(
- '/v1.1/images?status=ACTIVE&UNSUPPORTEDFILTER=testname')
+ image_service.detail(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images?status=ACTIVE&'
+ 'UNSUPPORTEDFILTER=testname')
request.environ['nova.context'] = context
controller = images.ControllerV11(image_service=image_service)
- controller.index(request)
- mocker.VerifyAll()
+ controller.detail(request)
+ self.mox.VerifyAll()
def test_image_no_filters(self):
- mocker = mox.Mox()
- image_service = mocker.CreateMockAnything()
+ image_service = self.mox.CreateMockAnything()
context = object()
filters = {}
image_service.index(
context, filters=filters).AndReturn([])
- mocker.ReplayAll()
+ self.mox.ReplayAll()
request = webob.Request.blank(
'/v1.1/images')
request.environ['nova.context'] = context
controller = images.ControllerV11(image_service=image_service)
controller.index(request)
- mocker.VerifyAll()
+ self.mox.VerifyAll()
def test_image_detail_filter_with_name(self):
- mocker = mox.Mox()
- image_service = mocker.CreateMockAnything()
+ image_service = self.mox.CreateMockAnything()
context = object()
filters = {'name': 'testname'}
- image_service.detail(
- context, filters=filters).AndReturn([])
- mocker.ReplayAll()
- request = webob.Request.blank(
- '/v1.1/images/detail?name=testname')
+ image_service.detail(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images/detail?name=testname')
request.environ['nova.context'] = context
controller = images.ControllerV11(image_service=image_service)
controller.detail(request)
- mocker.VerifyAll()
+ self.mox.VerifyAll()
def test_image_detail_filter_with_status(self):
- mocker = mox.Mox()
- image_service = mocker.CreateMockAnything()
+ image_service = self.mox.CreateMockAnything()
context = object()
filters = {'status': 'ACTIVE'}
- image_service.detail(
- context, filters=filters).AndReturn([])
- mocker.ReplayAll()
- request = webob.Request.blank(
- '/v1.1/images/detail?status=ACTIVE')
+ image_service.detail(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images/detail?status=ACTIVE')
request.environ['nova.context'] = context
controller = images.ControllerV11(image_service=image_service)
controller.detail(request)
- mocker.VerifyAll()
+ self.mox.VerifyAll()
def test_image_detail_filter_with_property(self):
- mocker = mox.Mox()
- image_service = mocker.CreateMockAnything()
+ image_service = self.mox.CreateMockAnything()
context = object()
filters = {'property-test': '3'}
- image_service.detail(
- context, filters=filters).AndReturn([])
- mocker.ReplayAll()
- request = webob.Request.blank(
- '/v1.1/images/detail?property-test=3')
+ image_service.detail(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images/detail?property-test=3')
request.environ['nova.context'] = context
controller = images.ControllerV11(image_service=image_service)
controller.detail(request)
- mocker.VerifyAll()
+ self.mox.VerifyAll()
+
+ def test_image_detail_filter_server(self):
+ image_service = self.mox.CreateMockAnything()
+ context = object()
+ # 'server' should be converted to 'property-instance_ref'
+ filters = {'property-instance_ref': 'http://localhost:8774/servers/12'}
+ image_service.index(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images/detail?server='
+ 'http://localhost:8774/servers/12')
+ request.environ['nova.context'] = context
+ controller = images.ControllerV11(image_service=image_service)
+ controller.index(request)
+ self.mox.VerifyAll()
+
+ def test_image_detail_filter_changes_since(self):
+ image_service = self.mox.CreateMockAnything()
+ context = object()
+ filters = {'changes-since': '2011-01-24T17:08Z'}
+ image_service.index(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images/detail?changes-since='
+ '2011-01-24T17:08Z')
+ request.environ['nova.context'] = context
+ controller = images.ControllerV11(image_service=image_service)
+ controller.index(request)
+ self.mox.VerifyAll()
+
+ def test_image_detail_filter_with_type(self):
+ image_service = self.mox.CreateMockAnything()
+ context = object()
+ filters = {'property-image_type': 'BASE'}
+ image_service.index(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images/detail?type=BASE')
+ request.environ['nova.context'] = context
+ controller = images.ControllerV11(image_service=image_service)
+ controller.index(request)
+ self.mox.VerifyAll()
def test_image_detail_filter_not_supported(self):
- mocker = mox.Mox()
- image_service = mocker.CreateMockAnything()
+ image_service = self.mox.CreateMockAnything()
context = object()
filters = {'status': 'ACTIVE'}
- image_service.detail(
- context, filters=filters).AndReturn([])
- mocker.ReplayAll()
- request = webob.Request.blank(
- '/v1.1/images/detail?status=ACTIVE&UNSUPPORTEDFILTER=testname')
+ image_service.detail(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images/detail?status=ACTIVE&'
+ 'UNSUPPORTEDFILTER=testname')
request.environ['nova.context'] = context
controller = images.ControllerV11(image_service=image_service)
controller.detail(request)
- mocker.VerifyAll()
+ self.mox.VerifyAll()
def test_image_detail_no_filters(self):
- mocker = mox.Mox()
- image_service = mocker.CreateMockAnything()
+ image_service = self.mox.CreateMockAnything()
context = object()
filters = {}
- image_service.detail(
- context, filters=filters).AndReturn([])
- mocker.ReplayAll()
- request = webob.Request.blank(
- '/v1.1/images/detail')
+ image_service.detail(context, filters=filters).AndReturn([])
+ self.mox.ReplayAll()
+ request = webob.Request.blank('/v1.1/images/detail')
request.environ['nova.context'] = context
controller = images.ControllerV11(image_service=image_service)
controller.detail(request)
- mocker.VerifyAll()
+ self.mox.VerifyAll()
def test_get_image_found(self):
req = webob.Request.blank('/v1.0/images/123')
diff --git a/nova/tests/api/openstack/test_limits.py b/nova/tests/api/openstack/test_limits.py
index 76363450d..8a3fe681a 100644
--- a/nova/tests/api/openstack/test_limits.py
+++ b/nova/tests/api/openstack/test_limits.py
@@ -24,11 +24,12 @@ import stubout
import time
import unittest
import webob
-
-from xml.dom.minidom import parseString
+from xml.dom import minidom
import nova.context
from nova.api.openstack import limits
+from nova.api.openstack import views
+from nova import test
TEST_LIMITS = [
@@ -166,7 +167,7 @@ class LimitsControllerV10Test(BaseLimitTestSuite):
request = self._get_index_request("application/xml")
response = request.get_response(self.controller)
- expected = parseString("""
+ expected = minidom.parseString("""
<limits
xmlns="http://docs.rackspacecloud.com/servers/api/v1.0">
<rate/>
@@ -174,7 +175,7 @@ class LimitsControllerV10Test(BaseLimitTestSuite):
</limits>
""".replace(" ", ""))
- body = parseString(response.body.replace(" ", ""))
+ body = minidom.parseString(response.body.replace(" ", ""))
self.assertEqual(expected.toxml(), body.toxml())
@@ -184,7 +185,7 @@ class LimitsControllerV10Test(BaseLimitTestSuite):
request = self._populate_limits(request)
response = request.get_response(self.controller)
- expected = parseString("""
+ expected = minidom.parseString("""
<limits
xmlns="http://docs.rackspacecloud.com/servers/api/v1.0">
<rate>
@@ -196,7 +197,7 @@ class LimitsControllerV10Test(BaseLimitTestSuite):
<absolute/>
</limits>
""".replace(" ", ""))
- body = parseString(response.body.replace(" ", ""))
+ body = minidom.parseString(response.body.replace(" ", ""))
self.assertEqual(expected.toxml(), body.toxml())
@@ -210,6 +211,7 @@ class LimitsControllerV11Test(BaseLimitTestSuite):
"""Run before each test."""
BaseLimitTestSuite.setUp(self)
self.controller = limits.create_resource('1.1')
+ self.maxDiff = None
def _get_index_request(self, accept_header="application/json"):
"""Helper to set routing arguments."""
@@ -266,14 +268,14 @@ class LimitsControllerV11Test(BaseLimitTestSuite):
"limit": [
{
"verb": "GET",
- "next-available": 0,
+ "next-available": "1970-01-01T00:00:00Z",
"unit": "MINUTE",
"value": 10,
"remaining": 10,
},
{
"verb": "POST",
- "next-available": 0,
+ "next-available": "1970-01-01T00:00:00Z",
"unit": "HOUR",
"value": 5,
"remaining": 5,
@@ -286,7 +288,7 @@ class LimitsControllerV11Test(BaseLimitTestSuite):
"limit": [
{
"verb": "GET",
- "next-available": 0,
+ "next-available": "1970-01-01T00:00:00Z",
"unit": "MINUTE",
"value": 5,
"remaining": 5,
@@ -328,7 +330,7 @@ class LimitsControllerV11Test(BaseLimitTestSuite):
"limit": [
{
"verb": "GET",
- "next-available": 0,
+ "next-available": "1970-01-01T00:00:00Z",
"unit": "MINUTE",
"value": 10,
"remaining": 10,
@@ -341,7 +343,7 @@ class LimitsControllerV11Test(BaseLimitTestSuite):
"limit": [
{
"verb": "GET",
- "next-available": 0,
+ "next-available": "1970-01-01T00:00:00Z",
"unit": "MINUTE",
"value": 10,
"remaining": 10,
@@ -458,7 +460,7 @@ class LimitMiddlewareTest(BaseLimitTestSuite):
response = request.get_response(self.app)
self.assertEqual(response.status_int, 403)
- root = parseString(response.body).childNodes[0]
+ root = minidom.parseString(response.body).childNodes[0]
expected = "Only 1 GET request(s) can be made to * every minute."
details = root.getElementsByTagName("details")
@@ -904,3 +906,195 @@ class WsgiLimiterProxyTest(BaseLimitTestSuite):
"made to /delayed every minute.")
self.assertEqual((delay, error), expected)
+
+
+class LimitsViewBuilderV11Test(test.TestCase):
+
+ def setUp(self):
+ self.view_builder = views.limits.ViewBuilderV11()
+ self.rate_limits = [
+ {
+ "URI": "*",
+ "regex": ".*",
+ "value": 10,
+ "verb": "POST",
+ "remaining": 2,
+ "unit": "MINUTE",
+ "resetTime": 1311272226
+ },
+ {
+ "URI": "*/servers",
+ "regex": "^/servers",
+ "value": 50,
+ "verb": "POST",
+ "remaining": 10,
+ "unit": "DAY",
+ "resetTime": 1311272226
+ },
+ ]
+ self.absolute_limits = {
+ "metadata_items": 1,
+ "injected_files": 5,
+ "injected_file_content_bytes": 5,
+ }
+
+ def tearDown(self):
+ pass
+
+ def test_build_limits(self):
+ expected_limits = {
+ "limits": {
+ "rate": [
+ {
+ "uri": "*",
+ "regex": ".*",
+ "limit": [
+ {
+ "value": 10,
+ "verb": "POST",
+ "remaining": 2,
+ "unit": "MINUTE",
+ "next-available": "2011-07-21T18:17:06Z"
+ },
+ ]
+ },
+ {
+ "uri": "*/servers",
+ "regex": "^/servers",
+ "limit": [
+ {
+ "value": 50,
+ "verb": "POST",
+ "remaining": 10,
+ "unit": "DAY",
+ "next-available": "2011-07-21T18:17:06Z"
+ },
+ ]
+ },
+ ],
+ "absolute": {
+ "maxServerMeta": 1,
+ "maxImageMeta": 1,
+ "maxPersonality": 5,
+ "maxPersonalitySize": 5
+ }
+ }
+ }
+
+ output = self.view_builder.build(self.rate_limits,
+ self.absolute_limits)
+ self.assertDictMatch(output, expected_limits)
+
+ def test_build_limits_empty_limits(self):
+ expected_limits = {
+ "limits": {
+ "rate": [],
+ "absolute": {}
+ }
+ }
+
+ abs_limits = {}
+ rate_limits = []
+ output = self.view_builder.build(rate_limits, abs_limits)
+ self.assertDictMatch(output, expected_limits)
+
+
+class LimitsXMLSerializationTest(test.TestCase):
+
+ def setUp(self):
+ self.maxDiff = None
+
+ def tearDown(self):
+ pass
+
+ def test_index(self):
+ serializer = limits.LimitsXMLSerializer()
+
+ fixture = {
+ "limits": {
+ "rate": [
+ {
+ "uri": "*",
+ "regex": ".*",
+ "limit": [
+ {
+ "value": 10,
+ "verb": "POST",
+ "remaining": 2,
+ "unit": "MINUTE",
+ "next-available": "2011-12-15T22:42:45Z"
+ },
+ ]
+ },
+ {
+ "uri": "*/servers",
+ "regex": "^/servers",
+ "limit": [
+ {
+ "value": 50,
+ "verb": "POST",
+ "remaining": 10,
+ "unit": "DAY",
+ "next-available": "2011-12-15T22:42:45Z"
+ },
+ ]
+ },
+ ],
+ "absolute": {
+ "maxServerMeta": 1,
+ "maxImageMeta": 1,
+ "maxPersonality": 5,
+ "maxPersonalitySize": 10240
+ }
+ }
+ }
+
+ output = serializer.serialize(fixture, 'index')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <limits xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <rates>
+ <rate uri="*" regex=".*">
+ <limit value="10" verb="POST" remaining="2"
+ unit="MINUTE"
+ next-available="2011-12-15T22:42:45Z"/>
+ </rate>
+ <rate uri="*/servers" regex="^/servers">
+ <limit value="50" verb="POST" remaining="10"
+ unit="DAY"
+ next-available="2011-12-15T22:42:45Z"/>
+ </rate>
+ </rates>
+ <absolute>
+ <limit name="maxServerMeta" value="1"/>
+ <limit name="maxPersonality" value="5"/>
+ <limit name="maxImageMeta" value="1"/>
+ <limit name="maxPersonalitySize" value="10240"/>
+ </absolute>
+ </limits>
+ """.replace(" ", ""))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_index_no_limits(self):
+ serializer = limits.LimitsXMLSerializer()
+
+ fixture = {
+ "limits": {
+ "rate": [],
+ "absolute": {}
+ }
+ }
+
+ output = serializer.serialize(fixture, 'index')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <limits xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <rates />
+ <absolute />
+ </limits>
+ """.replace(" ", ""))
+
+ 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 df951c5a0..821b055c4 100644
--- a/nova/tests/api/openstack/test_servers.py
+++ b/nova/tests/api/openstack/test_servers.py
@@ -30,8 +30,9 @@ from nova import flags
from nova import test
from nova import utils
import nova.api.openstack
-from nova.api.openstack import servers
from nova.api.openstack import create_instance_helper
+from nova.api.openstack import servers
+from nova.api.openstack import wsgi
import nova.compute.api
from nova.compute import instance_types
from nova.compute import power_state
@@ -77,6 +78,12 @@ def return_virtual_interface_instance_nonexistant(interfaces):
return _return_virtual_interface_by_instance
+def return_server_with_attributes(**kwargs):
+ def _return_server(context, id):
+ return stub_instance(id, **kwargs)
+ return _return_server
+
+
def return_server_with_addresses(private, public):
def _return_server(context, id):
return stub_instance(id, private_address=private,
@@ -84,15 +91,15 @@ def return_server_with_addresses(private, public):
return _return_server
-def return_server_with_interfaces(interfaces):
+def return_server_with_power_state(power_state):
def _return_server(context, id):
- return stub_instance(id, interfaces=interfaces)
+ return stub_instance(id, power_state=power_state)
return _return_server
-def return_server_with_power_state(power_state):
+def return_server_with_uuid_and_power_state(power_state):
def _return_server(context, id):
- return stub_instance(id, power_state=power_state)
+ return stub_instance(id, uuid=FAKE_UUID, power_state=power_state)
return _return_server
@@ -142,14 +149,15 @@ def instance_addresses(context, instance_id):
def stub_instance(id, user_id=1, private_address=None, public_addresses=None,
host=None, power_state=0, reservation_id="",
- uuid=FAKE_UUID, interfaces=None):
+ uuid=FAKE_UUID, image_ref="10", flavor_id="1",
+ interfaces=None):
metadata = []
metadata.append(InstanceMetadata(key='seq', value=id))
if interfaces is None:
interfaces = []
- inst_type = instance_types.get_instance_type_by_flavor_id(1)
+ inst_type = instance_types.get_instance_type_by_flavor_id(int(flavor_id))
if public_addresses is None:
public_addresses = list()
@@ -164,10 +172,12 @@ def stub_instance(id, user_id=1, private_address=None, public_addresses=None,
instance = {
"id": int(id),
+ "created_at": "2010-10-10T12:00:00Z",
+ "updated_at": "2010-11-11T11:00:00Z",
"admin_pass": "",
"user_id": user_id,
"project_id": "",
- "image_ref": "10",
+ "image_ref": image_ref,
"kernel_id": "",
"ramdisk_id": "",
"launch_index": 0,
@@ -223,6 +233,7 @@ class MockSetAdminPassword(object):
class ServersTest(test.TestCase):
def setUp(self):
+ self.maxDiff = None
super(ServersTest, self).setUp()
self.stubs = stubout.StubOutForTesting()
fakes.FakeAuthManager.reset_fake_data()
@@ -299,24 +310,274 @@ class ServersTest(test.TestCase):
self.assertEqual(res_dict['server']['name'], 'server1')
def test_get_server_by_id_v1_1(self):
+ image_bookmark = "http://localhost/images/10"
+ flavor_ref = "http://localhost/v1.1/flavors/1"
+ flavor_id = "1"
+ flavor_bookmark = "http://localhost/flavors/1"
+
+ public_ip = '192.168.0.3'
+ private_ip = '172.19.0.1'
+ interfaces = [
+ {
+ 'network': {'label': 'public'},
+ 'fixed_ips': [
+ {'address': public_ip},
+ ],
+ },
+ {
+ 'network': {'label': 'private'},
+ 'fixed_ips': [
+ {'address': private_ip},
+ ],
+ },
+ ]
+ new_return_server = return_server_with_attributes(
+ interfaces=interfaces)
+ self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
+
req = webob.Request.blank('/v1.1/servers/1')
res = req.get_response(fakes.wsgi_app())
res_dict = json.loads(res.body)
- self.assertEqual(res_dict['server']['id'], 1)
- self.assertEqual(res_dict['server']['name'], 'server1')
+ expected_server = {
+ "server": {
+ "id": 1,
+ "uuid": FAKE_UUID,
+ "updated": "2010-11-11T11:00:00Z",
+ "created": "2010-10-10T12:00:00Z",
+ "progress": 0,
+ "name": "server1",
+ "status": "BUILD",
+ "hostId": '',
+ "image": {
+ "id": "10",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": image_bookmark,
+ },
+ ],
+ },
+ "flavor": {
+ "id": "1",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": flavor_bookmark,
+ },
+ ],
+ },
+ "addresses": {
+ "public": [
+ {
+ "version": 4,
+ "addr": public_ip,
+ },
+ ],
+ "private": [
+ {
+ "version": 4,
+ "addr": private_ip,
+ },
+ ],
+ },
+ "metadata": {
+ "seq": "1",
+ },
+ "links": [
+ {
+ "rel": "self",
+ #FIXME(wwolf) Do we want the links to be id or uuid?
+ "href": "http://localhost/v1.1/servers/1",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/servers/1",
+ },
+ ],
+ }
+ }
+
+ self.assertDictMatch(res_dict, expected_server)
+
+ def test_get_server_with_active_status_by_id_v1_1(self):
+ image_bookmark = "http://localhost/images/10"
+ flavor_ref = "http://localhost/v1.1/flavors/1"
+ flavor_id = "1"
+ flavor_bookmark = "http://localhost/flavors/1"
+ private_ip = "192.168.0.3"
+ public_ip = "1.2.3.4"
+
+ interfaces = [
+ {
+ 'network': {'label': 'public'},
+ 'fixed_ips': [
+ {'address': public_ip},
+ ],
+ },
+ {
+ 'network': {'label': 'private'},
+ 'fixed_ips': [
+ {'address': private_ip},
+ ],
+ },
+ ]
+ new_return_server = return_server_with_attributes(
+ interfaces=interfaces, power_state=1)
+ self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
+
+ req = webob.Request.blank('/v1.1/servers/1')
+ res = req.get_response(fakes.wsgi_app())
+ res_dict = json.loads(res.body)
+ expected_server = {
+ "server": {
+ "id": 1,
+ "uuid": FAKE_UUID,
+ "updated": "2010-11-11T11:00:00Z",
+ "created": "2010-10-10T12:00:00Z",
+ "progress": 100,
+ "name": "server1",
+ "status": "ACTIVE",
+ "hostId": '',
+ "image": {
+ "id": "10",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": image_bookmark,
+ },
+ ],
+ },
+ "flavor": {
+ "id": "1",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": flavor_bookmark,
+ },
+ ],
+ },
+ "addresses": {
+ "public": [
+ {
+ "version": 4,
+ "addr": public_ip,
+ },
+ ],
+ "private": [
+ {
+ "version": 4,
+ "addr": private_ip,
+ },
+ ],
+ },
+ "metadata": {
+ "seq": "1",
+ },
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/servers/1",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/servers/1",
+ },
+ ],
+ }
+ }
- expected_links = [
+ self.assertDictMatch(res_dict, expected_server)
+
+ def test_get_server_with_id_image_ref_by_id_v1_1(self):
+ image_ref = "10"
+ image_bookmark = "http://localhost/images/10"
+ flavor_ref = "http://localhost/v1.1/flavors/1"
+ flavor_id = "1"
+ flavor_bookmark = "http://localhost/flavors/1"
+ private_ip = "192.168.0.3"
+ public_ip = "1.2.3.4"
+
+ interfaces = [
{
- "rel": "self",
- "href": "http://localhost/v1.1/servers/1",
+ 'network': {'label': 'public'},
+ 'fixed_ips': [
+ {'address': public_ip},
+ ],
},
{
- "rel": "bookmark",
- "href": "http://localhost/servers/1",
+ 'network': {'label': 'private'},
+ 'fixed_ips': [
+ {'address': private_ip},
+ ],
},
]
+ new_return_server = return_server_with_attributes(
+ interfaces=interfaces, power_state=1, image_ref=image_ref,
+ flavor_id=flavor_id)
+ self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
- self.assertEqual(res_dict['server']['links'], expected_links)
+ req = webob.Request.blank('/v1.1/servers/1')
+ res = req.get_response(fakes.wsgi_app())
+ res_dict = json.loads(res.body)
+ expected_server = {
+ "server": {
+ "id": 1,
+ "uuid": FAKE_UUID,
+ "updated": "2010-11-11T11:00:00Z",
+ "created": "2010-10-10T12:00:00Z",
+ "progress": 100,
+ "name": "server1",
+ "status": "ACTIVE",
+ "hostId": '',
+ "image": {
+ "id": "10",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": image_bookmark,
+ },
+ ],
+ },
+ "flavor": {
+ "id": "1",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": flavor_bookmark,
+ },
+ ],
+ },
+ "addresses": {
+ "public": [
+ {
+ "version": 4,
+ "addr": public_ip,
+ },
+ ],
+ "private": [
+ {
+ "version": 4,
+ "addr": private_ip,
+ },
+ ],
+ },
+ "metadata": {
+ "seq": "1",
+ },
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/servers/1",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/servers/1",
+ },
+ ],
+ }
+ }
+
+ self.assertDictMatch(res_dict, expected_server)
def test_get_server_by_id_with_addresses_xml(self):
private = "192.168.0.3"
@@ -433,6 +694,7 @@ class ServersTest(test.TestCase):
self.assertEquals(ip.getAttribute('addr'), private)
def test_get_server_by_id_with_addresses_v1_1(self):
+ FLAGS.use_ipv6 = True
interfaces = [
{
'network': {'label': 'network_1'},
@@ -447,9 +709,55 @@ class ServersTest(test.TestCase):
{'address': '172.19.0.1'},
{'address': '172.19.0.2'},
],
+ 'fixed_ipv6': '2001:4860::12',
},
]
- new_return_server = return_server_with_interfaces(interfaces)
+ new_return_server = return_server_with_attributes(
+ interfaces=interfaces)
+ self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
+
+ req = webob.Request.blank('/v1.1/servers/1')
+ res = req.get_response(fakes.wsgi_app())
+
+ res_dict = json.loads(res.body)
+ self.assertEqual(res_dict['server']['id'], 1)
+ self.assertEqual(res_dict['server']['name'], 'server1')
+ addresses = res_dict['server']['addresses']
+ expected = {
+ 'network_1': [
+ {'addr': '192.168.0.3', 'version': 4},
+ {'addr': '192.168.0.4', 'version': 4},
+ ],
+ 'network_2': [
+ {'addr': '172.19.0.1', 'version': 4},
+ {'addr': '172.19.0.2', 'version': 4},
+ {'addr': '2001:4860::12', 'version': 6},
+ ],
+ }
+
+ self.assertEqual(addresses, expected)
+
+ def test_get_server_by_id_with_addresses_v1_1_ipv6_disabled(self):
+ FLAGS.use_ipv6 = False
+ interfaces = [
+ {
+ 'network': {'label': 'network_1'},
+ 'fixed_ips': [
+ {'address': '192.168.0.3'},
+ {'address': '192.168.0.4'},
+ ],
+ },
+ {
+ 'network': {'label': 'network_2'},
+ 'fixed_ips': [
+ {'address': '172.19.0.1'},
+ {'address': '172.19.0.2'},
+ ],
+ 'fixed_ipv6': '2001:4860::12',
+ },
+ ]
+ new_return_server = return_server_with_attributes(
+ interfaces=interfaces)
self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
req = webob.Request.blank('/v1.1/servers/1')
@@ -473,6 +781,7 @@ class ServersTest(test.TestCase):
self.assertEqual(addresses, expected)
def test_get_server_addresses_v1_1(self):
+ FLAGS.use_ipv6 = True
interfaces = [
{
'network': {'label': 'network_1'},
@@ -492,6 +801,7 @@ class ServersTest(test.TestCase):
},
{'address': '172.19.0.2'},
],
+ 'fixed_ipv6': '2001:4860::12',
},
]
@@ -514,6 +824,7 @@ class ServersTest(test.TestCase):
{'version': 4, 'addr': '172.19.0.1'},
{'version': 4, 'addr': '1.2.3.4'},
{'version': 4, 'addr': '172.19.0.2'},
+ {'version': 6, 'addr': '2001:4860::12'},
],
},
}
@@ -521,6 +832,7 @@ class ServersTest(test.TestCase):
self.assertEqual(res_dict, expected)
def test_get_server_addresses_single_network_v1_1(self):
+ FLAGS.use_ipv6 = True
interfaces = [
{
'network': {'label': 'network_1'},
@@ -540,6 +852,7 @@ class ServersTest(test.TestCase):
},
{'address': '172.19.0.2'},
],
+ 'fixed_ipv6': '2001:4860::12',
},
]
_return_vifs = return_virtual_interface_by_instance(interfaces)
@@ -556,6 +869,7 @@ class ServersTest(test.TestCase):
{'version': 4, 'addr': '172.19.0.1'},
{'version': 4, 'addr': '1.2.3.4'},
{'version': 4, 'addr': '172.19.0.2'},
+ {'version': 6, 'addr': '2001:4860::12'},
],
}
self.assertEqual(res_dict, expected)
@@ -651,20 +965,20 @@ class ServersTest(test.TestCase):
for i, s in enumerate(res_dict['servers']):
self.assertEqual(s['id'], i)
self.assertEqual(s['name'], 'server%d' % i)
- self.assertEqual(s.get('imageId', None), None)
+ self.assertEqual(s.get('image', None), None)
expected_links = [
- {
- "rel": "self",
- "href": "http://localhost/v1.1/servers/%d" % (i,),
- },
- {
- "rel": "bookmark",
- "href": "http://localhost/servers/%d" % (i,),
- },
- ]
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/servers/%s" % s['id'],
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/servers/%s" % s['id'],
+ },
+ ]
- self.assertEqual(s['links'], expected_links)
+ self.assertEqual(s['links'], expected_links)
def test_get_servers_with_limit(self):
req = webob.Request.blank('/v1.0/servers?limit=3')
@@ -710,13 +1024,13 @@ class ServersTest(test.TestCase):
req = webob.Request.blank('/v1.1/servers?marker=2')
res = req.get_response(fakes.wsgi_app())
servers = json.loads(res.body)['servers']
- self.assertEqual([s['id'] for s in servers], [3, 4])
+ self.assertEqual([s['name'] for s in servers], ["server3", "server4"])
def test_get_servers_with_limit_and_marker(self):
req = webob.Request.blank('/v1.1/servers?limit=2&marker=1')
res = req.get_response(fakes.wsgi_app())
servers = json.loads(res.body)['servers']
- self.assertEqual([s['id'] for s in servers], [2, 3])
+ self.assertEqual([s['name'] for s in servers], ['server2', 'server3'])
def test_get_servers_with_bad_marker(self):
req = webob.Request.blank('/v1.1/servers?limit=2&marker=asdf')
@@ -929,8 +1243,16 @@ class ServersTest(test.TestCase):
def _setup_for_create_instance(self):
"""Shared implementation for tests below that create instance"""
def instance_create(context, inst):
- return {'id': 1, 'display_name': 'server_test',
- 'uuid': FAKE_UUID}
+ inst_type = instance_types.get_instance_type_by_flavor_id(3)
+ image_ref = 'http://localhost/images/2'
+ return {'id': 1,
+ 'display_name': 'server_test',
+ 'uuid': FAKE_UUID,
+ 'instance_type': dict(inst_type),
+ 'image_ref': image_ref,
+ 'created_at': '2010-10-10T12:00:00Z',
+ 'updated_at': '2010-11-11T11:00:00Z',
+ }
def server_update(context, id, params):
return instance_create(context, id)
@@ -1092,6 +1414,18 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)
+ def test_create_instance_no_server_entity(self):
+ self._setup_for_create_instance()
+
+ body = {}
+
+ req = webob.Request.blank('/v1.0/servers')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 422)
+
def test_create_instance_whitespace_name(self):
self._setup_for_create_instance()
@@ -1118,8 +1452,26 @@ class ServersTest(test.TestCase):
def test_create_instance_v1_1(self):
self._setup_for_create_instance()
- image_href = 'http://localhost/v1.1/images/2'
- flavor_ref = 'http://localhost/v1.1/flavors/3'
+ image_href = 'http://localhost/images/2'
+ flavor_ref = 'http://localhost/flavors/3'
+ expected_flavor = {
+ "id": "3",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": 'http://localhost/flavors/3',
+ },
+ ],
+ }
+ expected_image = {
+ "id": "2",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": 'http://localhost/images/2',
+ },
+ ],
+ }
body = {
'server': {
'name': 'server_test',
@@ -1144,9 +1496,42 @@ class ServersTest(test.TestCase):
server = json.loads(res.body)['server']
self.assertEqual(16, len(server['adminPass']))
self.assertEqual('server_test', server['name'])
- self.assertEqual(1, server['id'])
- self.assertEqual(flavor_ref, server['flavorRef'])
- self.assertEqual(image_href, server['imageRef'])
+ self.assertEqual(expected_flavor, server['flavor'])
+ self.assertEqual(expected_image, server['image'])
+ self.assertEqual(res.status_int, 200)
+ #self.assertEqual(1, server['id'])
+
+ def test_create_instance_v1_1_invalid_flavor_href(self):
+ self._setup_for_create_instance()
+
+ image_href = 'http://localhost/v1.1/images/2'
+ flavor_ref = 'http://localhost/v1.1/flavors/asdf'
+ body = dict(server=dict(
+ name='server_test', imageRef=image_href, flavorRef=flavor_ref,
+ metadata={'hello': 'world', 'open': 'stack'},
+ personality={}))
+ req = webob.Request.blank('/v1.1/servers')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 400)
+
+ def test_create_instance_v1_1_bad_flavor_href(self):
+ self._setup_for_create_instance()
+
+ image_href = 'http://localhost/v1.1/images/2'
+ flavor_ref = 'http://localhost/v1.1/flavors/17'
+ body = dict(server=dict(
+ name='server_test', imageRef=image_href, flavorRef=flavor_ref,
+ metadata={'hello': 'world', 'open': 'stack'},
+ personality={}))
+ req = webob.Request.blank('/v1.1/servers')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 400)
def test_create_instance_v1_1_bad_href(self):
self._setup_for_create_instance()
@@ -1167,8 +1552,26 @@ class ServersTest(test.TestCase):
def test_create_instance_v1_1_local_href(self):
self._setup_for_create_instance()
- image_id = 2
- flavor_ref = 'http://localhost/v1.1/flavors/3'
+ image_id = "2"
+ flavor_ref = 'http://localhost/flavors/3'
+ expected_flavor = {
+ "id": "3",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": 'http://localhost/flavors/3',
+ },
+ ],
+ }
+ expected_image = {
+ "id": "2",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": 'http://localhost/images/2',
+ },
+ ],
+ }
body = {
'server': {
'name': 'server_test',
@@ -1185,9 +1588,8 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
server = json.loads(res.body)['server']
- self.assertEqual(1, server['id'])
- self.assertEqual(flavor_ref, server['flavorRef'])
- self.assertEqual(image_id, server['imageRef'])
+ self.assertEqual(expected_flavor, server['flavor'])
+ self.assertEqual(expected_image, server['image'])
self.assertEqual(res.status_int, 200)
def test_create_instance_with_admin_pass_v1_0(self):
@@ -1412,6 +1814,24 @@ class ServersTest(test.TestCase):
self.assertEqual(s['metadata']['seq'], str(i))
def test_get_all_server_details_v1_1(self):
+ expected_flavor = {
+ "id": "1",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": 'http://localhost/flavors/1',
+ },
+ ],
+ }
+ expected_image = {
+ "id": "10",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": 'http://localhost/images/10',
+ },
+ ],
+ }
req = webob.Request.blank('/v1.1/servers/detail')
res = req.get_response(fakes.wsgi_app())
res_dict = json.loads(res.body)
@@ -1420,8 +1840,8 @@ class ServersTest(test.TestCase):
self.assertEqual(s['id'], i)
self.assertEqual(s['hostId'], '')
self.assertEqual(s['name'], 'server%d' % i)
- self.assertEqual(s['imageRef'], 10)
- self.assertEqual(s['flavorRef'], 'http://localhost/v1.1/flavors/1')
+ self.assertEqual(s['image'], expected_image)
+ self.assertEqual(s['flavor'], expected_flavor)
self.assertEqual(s['status'], 'BUILD')
self.assertEqual(s['metadata']['seq'], str(i))
@@ -1642,6 +2062,8 @@ class ServersTest(test.TestCase):
state = power_state.BUILDING
new_return_server = return_server_with_power_state(state)
self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
+ self.stubs.Set(nova.db, 'instance_get_by_uuid',
+ return_server_with_uuid_and_power_state(state))
req = webob.Request.blank('/v1.0/servers/1/action')
req.method = 'POST'
@@ -1690,6 +2112,8 @@ class ServersTest(test.TestCase):
state = power_state.BUILDING
new_return_server = return_server_with_power_state(state)
self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
+ self.stubs.Set(nova.db, 'instance_get_by_uuid',
+ return_server_with_uuid_and_power_state(state))
req = webob.Request.blank('/v1.1/servers/1/action')
req.method = 'POST'
@@ -1909,7 +2333,7 @@ class ServersTest(test.TestCase):
self.stubs.Set(nova.compute.api.API, 'resize', resize_mock)
res = req.get_response(fakes.wsgi_app())
- self.assertEqual(res.status_int, 400)
+ self.assertEqual(res.status_int, 500)
def test_resized_server_has_correct_status(self):
req = self.webreq('/1', 'GET')
@@ -2307,6 +2731,62 @@ b25zLiINCg0KLVJpY2hhcmQgQmFjaA==""",
"http://localhost:8774/v1.1/images/1")
+class TextAddressesXMLSerialization(test.TestCase):
+
+ serializer = nova.api.openstack.ips.IPXMLSerializer()
+
+ def test_show(self):
+ fixture = {
+ 'network_2': [
+ {'addr': '192.168.0.1', 'version': 4},
+ {'addr': 'fe80::beef', 'version': 6},
+ ],
+ }
+ output = self.serializer.serialize(fixture, 'show')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <network xmlns="http://docs.openstack.org/compute/api/v1.1"
+ id="network_2">
+ <ip version="4" addr="192.168.0.1"/>
+ <ip version="6" addr="fe80::beef"/>
+ </network>
+ """.replace(" ", ""))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_index(self):
+ fixture = {
+ 'addresses': {
+ 'network_1': [
+ {'addr': '192.168.0.3', 'version': 4},
+ {'addr': '192.168.0.5', 'version': 4},
+ ],
+ 'network_2': [
+ {'addr': '192.168.0.1', 'version': 4},
+ {'addr': 'fe80::beef', 'version': 6},
+ ],
+ },
+ }
+ output = self.serializer.serialize(fixture, 'index')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <addresses xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <network id="network_2">
+ <ip version="4" addr="192.168.0.1"/>
+ <ip version="6" addr="fe80::beef"/>
+ </network>
+ <network id="network_1">
+ <ip version="4" addr="192.168.0.3"/>
+ <ip version="4" addr="192.168.0.5"/>
+ </network>
+ </addresses>
+ """.replace(" ", ""))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+
class TestServerInstanceCreation(test.TestCase):
def setUp(self):
@@ -2609,3 +3089,249 @@ class TestGetKernelRamdiskFromImage(test.TestCase):
kernel_id, ramdisk_id = create_instance_helper.CreateInstanceHelper. \
_do_get_kernel_ramdisk_from_image(image_meta)
return kernel_id, ramdisk_id
+
+
+class ServersViewBuilderV11Test(test.TestCase):
+
+ def setUp(self):
+ self.instance = self._get_instance()
+ self.view_builder = self._get_view_builder()
+
+ def tearDown(self):
+ pass
+
+ def _get_instance(self):
+ instance = {
+ "id": 1,
+ "created_at": "2010-10-10T12:00:00Z",
+ "updated_at": "2010-11-11T11:00:00Z",
+ "admin_pass": "",
+ "user_id": "",
+ "project_id": "",
+ "image_ref": "5",
+ "kernel_id": "",
+ "ramdisk_id": "",
+ "launch_index": 0,
+ "key_name": "",
+ "key_data": "",
+ "state": 0,
+ "state_description": "",
+ "memory_mb": 0,
+ "vcpus": 0,
+ "local_gb": 0,
+ "hostname": "",
+ "host": "",
+ "instance_type": {
+ "flavorid": 1,
+ },
+ "user_data": "",
+ "reservation_id": "",
+ "mac_address": "",
+ "scheduled_at": utils.utcnow(),
+ "launched_at": utils.utcnow(),
+ "terminated_at": utils.utcnow(),
+ "availability_zone": "",
+ "display_name": "test_server",
+ "display_description": "",
+ "locked": False,
+ "metadata": [],
+ #"address": ,
+ #"floating_ips": [{"address":ip} for ip in public_addresses]}
+ "uuid": "deadbeef-feed-edee-beef-d0ea7beefedd"}
+
+ return instance
+
+ def _get_view_builder(self):
+ base_url = "http://localhost/v1.1"
+ views = nova.api.openstack.views
+ address_builder = views.addresses.ViewBuilderV11()
+ flavor_builder = views.flavors.ViewBuilderV11(base_url)
+ image_builder = views.images.ViewBuilderV11(base_url)
+
+ view_builder = nova.api.openstack.views.servers.ViewBuilderV11(
+ address_builder,
+ flavor_builder,
+ image_builder,
+ base_url
+ )
+ return view_builder
+
+ def test_build_server(self):
+ expected_server = {
+ "server": {
+ "id": 1,
+ "uuid": self.instance['uuid'],
+ "name": "test_server",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/servers/1",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/servers/1",
+ },
+ ],
+ }
+ }
+
+ output = self.view_builder.build(self.instance, False)
+ self.assertDictMatch(output, expected_server)
+
+ def test_build_server_detail(self):
+ image_bookmark = "http://localhost/images/5"
+ flavor_bookmark = "http://localhost/flavors/1"
+ expected_server = {
+ "server": {
+ "id": 1,
+ "uuid": self.instance['uuid'],
+ "updated": "2010-11-11T11:00:00Z",
+ "created": "2010-10-10T12:00:00Z",
+ "progress": 0,
+ "name": "test_server",
+ "status": "BUILD",
+ "hostId": '',
+ "image": {
+ "id": "5",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": image_bookmark,
+ },
+ ],
+ },
+ "flavor": {
+ "id": "1",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": flavor_bookmark,
+ },
+ ],
+ },
+ "addresses": {},
+ "metadata": {},
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/servers/1",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/servers/1",
+ },
+ ],
+ }
+ }
+
+ output = self.view_builder.build(self.instance, True)
+ self.assertDictMatch(output, expected_server)
+
+ def test_build_server_detail_active_status(self):
+ #set the power state of the instance to running
+ self.instance['state'] = 1
+ image_bookmark = "http://localhost/images/5"
+ flavor_bookmark = "http://localhost/flavors/1"
+ expected_server = {
+ "server": {
+ "id": 1,
+ "uuid": self.instance['uuid'],
+ "updated": "2010-11-11T11:00:00Z",
+ "created": "2010-10-10T12:00:00Z",
+ "progress": 100,
+ "name": "test_server",
+ "status": "ACTIVE",
+ "hostId": '',
+ "image": {
+ "id": "5",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": image_bookmark,
+ },
+ ],
+ },
+ "flavor": {
+ "id": "1",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": flavor_bookmark,
+ },
+ ],
+ },
+ "addresses": {},
+ "metadata": {},
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/servers/1",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/servers/1",
+ },
+ ],
+ }
+ }
+
+ output = self.view_builder.build(self.instance, True)
+ self.assertDictMatch(output, expected_server)
+
+ def test_build_server_detail_with_metadata(self):
+
+ metadata = []
+ metadata.append(InstanceMetadata(key="Open", value="Stack"))
+ metadata.append(InstanceMetadata(key="Number", value=1))
+ self.instance['metadata'] = metadata
+
+ image_bookmark = "http://localhost/images/5"
+ flavor_bookmark = "http://localhost/flavors/1"
+ expected_server = {
+ "server": {
+ "id": 1,
+ "uuid": self.instance['uuid'],
+ "updated": "2010-11-11T11:00:00Z",
+ "created": "2010-10-10T12:00:00Z",
+ "progress": 0,
+ "name": "test_server",
+ "status": "BUILD",
+ "hostId": '',
+ "image": {
+ "id": "5",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": image_bookmark,
+ },
+ ],
+ },
+ "flavor": {
+ "id": "1",
+ "links": [
+ {
+ "rel": "bookmark",
+ "href": flavor_bookmark,
+ },
+ ],
+ },
+ "addresses": {},
+ "metadata": {
+ "Open": "Stack",
+ "Number": "1",
+ },
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/servers/1",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/servers/1",
+ },
+ ],
+ }
+ }
+
+ output = self.view_builder.build(self.instance, True)
+ self.assertDictMatch(output, expected_server)
diff --git a/nova/tests/api/openstack/test_versions.py b/nova/tests/api/openstack/test_versions.py
index fd8d50904..da964ee1f 100644
--- a/nova/tests/api/openstack/test_versions.py
+++ b/nova/tests/api/openstack/test_versions.py
@@ -21,6 +21,7 @@ import webob
from nova import context
from nova import test
from nova.tests.api.openstack import fakes
+from nova.api.openstack import versions
from nova.api.openstack import views
@@ -43,19 +44,21 @@ class VersionsTest(test.TestCase):
{
"id": "v1.1",
"status": "CURRENT",
+ "updated": "2011-07-18T11:30:00Z",
"links": [
{
"rel": "self",
- "href": "http://localhost/v1.1",
+ "href": "http://localhost/v1.1/",
}],
},
{
"id": "v1.0",
"status": "DEPRECATED",
+ "updated": "2010-10-09T11:30:00Z",
"links": [
{
"rel": "self",
- "href": "http://localhost/v1.0",
+ "href": "http://localhost/v1.0/",
}],
},
]
@@ -69,15 +72,12 @@ class VersionsTest(test.TestCase):
self.assertEqual(res.content_type, "application/xml")
expected = """<versions>
- <version id="v1.1" status="CURRENT">
- <links>
- <link href="http://localhost/v1.1" rel="self"/>
- </links>
+ <version id="v1.1" status="CURRENT" updated="2011-07-18T11:30:00Z">
+ <atom:link href="http://localhost/v1.1/" rel="self"/>
</version>
- <version id="v1.0" status="DEPRECATED">
- <links>
- <link href="http://localhost/v1.0" rel="self"/>
- </links>
+ <version id="v1.0" status="DEPRECATED"
+ updated="2010-10-09T11:30:00Z">
+ <atom:link href="http://localhost/v1.0/" rel="self"/>
</version>
</versions>""".replace(" ", "").replace("\n", "")
@@ -85,21 +85,64 @@ class VersionsTest(test.TestCase):
self.assertEqual(expected, actual)
+ def test_get_version_list_atom(self):
+ req = webob.Request.blank('/')
+ req.accept = "application/atom+xml"
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 200)
+ self.assertEqual(res.content_type, "application/atom+xml")
+
+ expected = """
+ <feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">Available API Versions</title>
+ <updated>2011-07-18T11:30:00Z</updated>
+ <id>http://localhost/</id>
+ <author>
+ <name>Rackspace</name>
+ <uri>http://www.rackspace.com/</uri>
+ </author>
+ <link href="http://localhost/" rel="self"/>
+ <entry>
+ <id>http://localhost/v1.1/</id>
+ <title type="text">Version v1.1</title>
+ <updated>2011-07-18T11:30:00Z</updated>
+ <link href="http://localhost/v1.1/" rel="self"/>
+ <content type="text">
+ Version v1.1 CURRENT (2011-07-18T11:30:00Z)
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost/v1.0/</id>
+ <title type="text">Version v1.0</title>
+ <updated>2010-10-09T11:30:00Z</updated>
+ <link href="http://localhost/v1.0/" rel="self"/>
+ <content type="text">
+ Version v1.0 DEPRECATED (2010-10-09T11:30:00Z)
+ </content>
+ </entry>
+ </feed>
+ """.replace(" ", "").replace("\n", "")
+
+ actual = res.body.replace(" ", "").replace("\n", "")
+
+ self.assertEqual(expected, actual)
+
def test_view_builder(self):
base_url = "http://example.org/"
version_data = {
"id": "3.2.1",
"status": "CURRENT",
- }
+ "updated": "2011-07-18T11:30:00Z"}
expected = {
"id": "3.2.1",
"status": "CURRENT",
+ "updated": "2011-07-18T11:30:00Z",
"links": [
{
"rel": "self",
- "href": "http://example.org/3.2.1",
+ "href": "http://example.org/3.2.1/",
},
],
}
@@ -113,9 +156,99 @@ class VersionsTest(test.TestCase):
base_url = "http://example.org/app/"
version_number = "v1.4.6"
- expected = "http://example.org/app/v1.4.6"
+ expected = "http://example.org/app/v1.4.6/"
builder = views.versions.ViewBuilder(base_url)
actual = builder.generate_href(version_number)
self.assertEqual(actual, expected)
+
+ def test_xml_serializer(self):
+ versions_data = {
+ 'versions': [
+ {
+ "id": "2.7.1",
+ "updated": "2011-07-18T11:30:00Z",
+ "status": "DEPRECATED",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://test/2.7.1",
+ },
+ ],
+ },
+ ]
+ }
+
+ expected = """
+ <versions>
+ <version id="2.7.1" status="DEPRECATED"
+ updated="2011-07-18T11:30:00Z">
+ <atom:link href="http://test/2.7.1" rel="self"/>
+ </version>
+ </versions>""".replace(" ", "").replace("\n", "")
+
+ serializer = versions.VersionsXMLSerializer()
+ response = serializer.default(versions_data)
+ response = response.replace(" ", "").replace("\n", "")
+ self.assertEqual(expected, response)
+
+ def test_atom_serializer(self):
+ versions_data = {
+ 'versions': [
+ {
+ "id": "2.9.8",
+ "updated": "2011-07-20T11:40:00Z",
+ "status": "CURRENT",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://test/2.9.8",
+ },
+ ],
+ },
+ ]
+ }
+
+ expected = """
+ <feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">
+ Available API Versions
+ </title>
+ <updated>
+ 2011-07-20T11:40:00Z
+ </updated>
+ <id>
+ http://test/
+ </id>
+ <author>
+ <name>
+ Rackspace
+ </name>
+ <uri>
+ http://www.rackspace.com/
+ </uri>
+ </author>
+ <link href="http://test/" rel="self"/>
+ <entry>
+ <id>
+ http://test/2.9.8
+ </id>
+ <title type="text">
+ Version 2.9.8
+ </title>
+ <updated>
+ 2011-07-20T11:40:00Z
+ </updated>
+ <link href="http://test/2.9.8" rel="self"/>
+ <content type="text">
+ Version 2.9.8 CURRENT (2011-07-20T11:40:00Z)
+ </content>
+ </entry>
+ </feed>""".replace(" ", "").replace("\n", "")
+
+ serializer = versions.VersionsAtomSerializer()
+ response = serializer.default(versions_data)
+ print response
+ response = response.replace(" ", "").replace("\n", "")
+ self.assertEqual(expected, response)
diff --git a/nova/tests/api/openstack/test_wsgi.py b/nova/tests/api/openstack/test_wsgi.py
index 5bdda7c7e..6dea78d17 100644
--- a/nova/tests/api/openstack/test_wsgi.py
+++ b/nova/tests/api/openstack/test_wsgi.py
@@ -256,6 +256,13 @@ class ResponseSerializerTest(test.TestCase):
self.assertEqual(response.body, 'pew_json')
self.assertEqual(response.status_int, 404)
+ def test_serialize_response_None(self):
+ response = self.serializer.serialize(None, 'application/json')
+ print response
+ self.assertEqual(response.headers['Content-Type'], 'application/json')
+ self.assertEqual(response.body, '')
+ self.assertEqual(response.status_int, 404)
+
def test_serialize_response_dict_to_unknown_content_type(self):
self.assertRaises(exception.InvalidContentType,
self.serializer.serialize,
diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py
index 7762df41c..19028a451 100644
--- a/nova/tests/db/fakes.py
+++ b/nova/tests/db/fakes.py
@@ -230,7 +230,7 @@ def stub_out_db_network_api(stubs):
continue
fixed_ip_fields['virtual_interface'] = FakeModel(vif[0])
- def fake_instance_type_get_by_id(context, id):
+ def fake_instance_type_get(context, id):
if flavor_fields['id'] == id:
return FakeModel(flavor_fields)
@@ -323,7 +323,7 @@ def stub_out_db_network_api(stubs):
fake_fixed_ip_get_by_address,
fake_fixed_ip_get_network,
fake_fixed_ip_update,
- fake_instance_type_get_by_id,
+ fake_instance_type_get,
fake_virtual_interface_create,
fake_virtual_interface_delete_by_instance,
fake_virtual_interface_get_by_instance,
@@ -415,7 +415,7 @@ def stub_out_db_instance_api(stubs, injected=True):
def fake_instance_type_get_by_name(context, name):
return INSTANCE_TYPES[name]
- def fake_instance_type_get_by_id(context, id):
+ def fake_instance_type_get(context, id):
for name, inst_type in INSTANCE_TYPES.iteritems():
if str(inst_type['id']) == str(id):
return inst_type
@@ -448,7 +448,7 @@ def stub_out_db_instance_api(stubs, injected=True):
fake_network_get_all_by_instance,
fake_instance_type_get_all,
fake_instance_type_get_by_name,
- fake_instance_type_get_by_id,
+ fake_instance_type_get,
fake_instance_get_fixed_addresses,
fake_instance_get_fixed_addresses_v6,
fake_network_get_all_by_instance,
diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py
index 2297d2f0e..073216495 100644
--- a/nova/tests/fake_flags.py
+++ b/nova/tests/fake_flags.py
@@ -42,3 +42,4 @@ FLAGS['iscsi_num_targets'].SetDefault(8)
FLAGS['verbose'].SetDefault(True)
FLAGS['sqlite_db'].SetDefault("tests.sqlite")
FLAGS['use_ipv6'].SetDefault(True)
+FLAGS['flat_network_bridge'].SetDefault('br100')
diff --git a/nova/tests/test_api.py b/nova/tests/test_api.py
index 26ac5ff24..fe7fd8402 100644
--- a/nova/tests/test_api.py
+++ b/nova/tests/test_api.py
@@ -213,7 +213,11 @@ class ApiEc2TestCase(test.TestCase):
self.http = FakeHttplibConnection(
self.app, '%s:8773' % (self.host), False)
# pylint: disable=E1103
- self.ec2.new_http_connection(host, is_secure).AndReturn(self.http)
+ if boto.Version >= '2':
+ self.ec2.new_http_connection(host or '%s:8773' % (self.host),
+ is_secure).AndReturn(self.http)
+ else:
+ self.ec2.new_http_connection(host, is_secure).AndReturn(self.http)
return self.http
def test_return_valid_isoformat(self):
diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py
index 8cdc73a66..e419e7a50 100644
--- a/nova/tests/test_cloud.py
+++ b/nova/tests/test_cloud.py
@@ -121,7 +121,6 @@ class CloudTestCase(test.TestCase):
public_ip=address)
db.floating_ip_destroy(self.context, address)
- @test.skip_test("Skipping this pending future merge")
def test_allocate_address(self):
address = "10.10.10.10"
allocate = self.cloud.allocate_address
@@ -161,13 +160,10 @@ class CloudTestCase(test.TestCase):
# ApiError: Floating ip is in use. Disassociate it before releasing.
self.assertRaises(exception.ApiError, release, self.context, address)
- @test.skip_test("Skipping this pending future merge")
def test_associate_disassociate_address(self):
"""Verifies associate runs cleanly without raising an exception"""
address = "10.10.10.10"
- db.floating_ip_create(self.context,
- {'address': address,
- 'host': self.network.host})
+ db.floating_ip_create(self.context, {'address': address})
self.cloud.allocate_address(self.context)
# TODO(jkoelker) Probably need to query for instance_type_id and
# make sure we get a valid one
@@ -175,11 +171,14 @@ class CloudTestCase(test.TestCase):
'instance_type_id': 1})
networks = db.network_get_all(self.context)
for network in networks:
- self.network.set_network_host(self.context, network['id'])
+ db.network_update(self.context, network['id'],
+ {'host': self.network.host})
project_id = self.context.project_id
type_id = inst['instance_type_id']
ips = self.network.allocate_for_instance(self.context,
instance_id=inst['id'],
+ host=inst['host'],
+ vpn=None,
instance_type_id=type_id,
project_id=project_id)
# TODO(jkoelker) Make this mas bueno
@@ -269,25 +268,81 @@ class CloudTestCase(test.TestCase):
delete = self.cloud.delete_security_group
self.assertRaises(exception.ApiError, delete, self.context)
- def test_authorize_revoke_security_group_ingress(self):
+ def test_authorize_security_group_ingress(self):
kwargs = {'project_id': self.context.project_id, 'name': 'test'}
sec = db.security_group_create(self.context, kwargs)
authz = self.cloud.authorize_security_group_ingress
kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'}
- authz(self.context, group_name=sec['name'], **kwargs)
+ self.assertTrue(authz(self.context, group_name=sec['name'], **kwargs))
+
+ def test_authorize_security_group_ingress_ip_permissions_ip_ranges(self):
+ kwargs = {'project_id': self.context.project_id, 'name': 'test'}
+ sec = db.security_group_create(self.context, kwargs)
+ authz = self.cloud.authorize_security_group_ingress
+ kwargs = {'ip_permissions': [{'to_port': 81, 'from_port': 81,
+ 'ip_ranges':
+ {'1': {'cidr_ip': u'0.0.0.0/0'},
+ '2': {'cidr_ip': u'10.10.10.10/32'}},
+ 'ip_protocol': u'tcp'}]}
+ self.assertTrue(authz(self.context, group_name=sec['name'], **kwargs))
+
+ def test_authorize_security_group_fail_missing_source_group(self):
+ kwargs = {'project_id': self.context.project_id, 'name': 'test'}
+ sec = db.security_group_create(self.context, kwargs)
+ authz = self.cloud.authorize_security_group_ingress
+ kwargs = {'ip_permissions': [{'to_port': 81, 'from_port': 81,
+ 'ip_ranges':{'1': {'cidr_ip': u'0.0.0.0/0'},
+ '2': {'cidr_ip': u'10.10.10.10/32'}},
+ 'groups': {'1': {'user_id': u'someuser',
+ 'group_name': u'somegroup1'}},
+ 'ip_protocol': u'tcp'}]}
+ self.assertRaises(exception.SecurityGroupNotFound, authz,
+ self.context, group_name=sec['name'], **kwargs)
+
+ def test_authorize_security_group_ingress_ip_permissions_groups(self):
+ kwargs = {'project_id': self.context.project_id, 'name': 'test'}
+ sec = db.security_group_create(self.context,
+ {'project_id': 'someuser',
+ 'name': 'somegroup1'})
+ sec = db.security_group_create(self.context,
+ {'project_id': 'someuser',
+ 'name': 'othergroup2'})
+ sec = db.security_group_create(self.context, kwargs)
+ authz = self.cloud.authorize_security_group_ingress
+ kwargs = {'ip_permissions': [{'to_port': 81, 'from_port': 81,
+ 'groups': {'1': {'user_id': u'someuser',
+ 'group_name': u'somegroup1'},
+ '2': {'user_id': u'someuser',
+ 'group_name': u'othergroup2'}},
+ 'ip_protocol': u'tcp'}]}
+ self.assertTrue(authz(self.context, group_name=sec['name'], **kwargs))
+
+ def test_revoke_security_group_ingress(self):
+ kwargs = {'project_id': self.context.project_id, 'name': 'test'}
+ sec = db.security_group_create(self.context, kwargs)
+ authz = self.cloud.authorize_security_group_ingress
+ kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'}
+ authz(self.context, group_id=sec['id'], **kwargs)
revoke = self.cloud.revoke_security_group_ingress
self.assertTrue(revoke(self.context, group_name=sec['name'], **kwargs))
- def test_authorize_revoke_security_group_ingress_by_id(self):
- sec = db.security_group_create(self.context,
- {'project_id': self.context.project_id,
- 'name': 'test'})
+ def test_revoke_security_group_ingress_by_id(self):
+ kwargs = {'project_id': self.context.project_id, 'name': 'test'}
+ sec = db.security_group_create(self.context, kwargs)
authz = self.cloud.authorize_security_group_ingress
kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'}
authz(self.context, group_id=sec['id'], **kwargs)
revoke = self.cloud.revoke_security_group_ingress
self.assertTrue(revoke(self.context, group_id=sec['id'], **kwargs))
+ def test_authorize_security_group_ingress_by_id(self):
+ sec = db.security_group_create(self.context,
+ {'project_id': self.context.project_id,
+ 'name': 'test'})
+ authz = self.cloud.authorize_security_group_ingress
+ kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'}
+ self.assertTrue(authz(self.context, group_id=sec['id'], **kwargs))
+
def test_authorize_security_group_ingress_missing_protocol_params(self):
sec = db.security_group_create(self.context,
{'project_id': self.context.project_id,
@@ -366,8 +421,6 @@ class CloudTestCase(test.TestCase):
db.service_destroy(self.context, service1['id'])
db.service_destroy(self.context, service2['id'])
- # NOTE(jkoelker): this test relies on fixed_ip being in instances
- @test.skip_test("EC2 stuff needs fixed_ip in instance_ref")
def test_describe_snapshots(self):
"""Makes sure describe_snapshots works and filters results."""
vol = db.volume_create(self.context, {})
@@ -908,6 +961,21 @@ class CloudTestCase(test.TestCase):
self._wait_for_running(ec2_instance_id)
return ec2_instance_id
+ def test_rescue_unrescue_instance(self):
+ instance_id = self._run_instance(
+ image_id='ami-1',
+ instance_type=FLAGS.default_instance_type,
+ max_count=1)
+ self.cloud.rescue_instance(context=self.context,
+ instance_id=instance_id)
+ # NOTE(vish): This currently does no validation, it simply makes sure
+ # that the code path doesn't throw an exception.
+ self.cloud.unrescue_instance(context=self.context,
+ instance_id=instance_id)
+ # TODO(soren): We need this until we can stop polling in the rpc code
+ # for unit tests.
+ self.cloud.terminate_instances(self.context, [instance_id])
+
def test_console_output(self):
instance_id = self._run_instance(
image_id='ami-1',
@@ -987,12 +1055,6 @@ class CloudTestCase(test.TestCase):
self.cloud.delete_key_pair(self.context, 'test')
def test_run_instances(self):
- # stub out the rpc call
- def stub_cast(*args, **kwargs):
- pass
-
- self.stubs.Set(rpc, 'cast', stub_cast)
-
kwargs = {'image_id': FLAGS.default_image,
'instance_type': FLAGS.default_instance_type,
'max_count': 1}
@@ -1002,7 +1064,7 @@ class CloudTestCase(test.TestCase):
self.assertEqual(instance['imageId'], 'ami-00000001')
self.assertEqual(instance['displayName'], 'Server 1')
self.assertEqual(instance['instanceId'], 'i-00000001')
- self.assertEqual(instance['instanceState']['name'], 'scheduling')
+ self.assertEqual(instance['instanceState']['name'], 'running')
self.assertEqual(instance['instanceType'], 'm1.small')
def test_run_instances_image_state_none(self):
@@ -1074,16 +1136,15 @@ class CloudTestCase(test.TestCase):
self.assertEqual('c00l 1m4g3', inst['display_name'])
db.instance_destroy(self.context, inst['id'])
- # NOTE(jkoelker): This test relies on mac_address in instance
- @test.skip_test("EC2 stuff needs mac_address in instance_ref")
def test_update_of_instance_wont_update_private_fields(self):
inst = db.instance_create(self.context, {})
+ host = inst['host']
ec2_id = ec2utils.id_to_ec2_id(inst['id'])
self.cloud.update_instance(self.context, ec2_id,
display_name='c00l 1m4g3',
- mac_address='DE:AD:BE:EF')
+ host='otherhost')
inst = db.instance_get(self.context, inst['id'])
- self.assertEqual(None, inst['mac_address'])
+ self.assertEqual(host, inst['host'])
db.instance_destroy(self.context, inst['id'])
def test_update_of_volume_display_fields(self):
@@ -1139,7 +1200,6 @@ class CloudTestCase(test.TestCase):
elevated = self.context.elevated(read_deleted=True)
self._wait_for_state(elevated, instance_id, is_deleted)
- @test.skip_test("skipping, test is hanging with multinic for rpc reasons")
def test_stop_start_instance(self):
"""Makes sure stop/start instance works"""
# enforce periodic tasks run in short time to avoid wait for 60s.
@@ -1197,7 +1257,6 @@ class CloudTestCase(test.TestCase):
self.assertEqual(vol['status'], "available")
self.assertEqual(vol['attach_status'], "detached")
- @test.skip_test("skipping, test is hanging with multinic for rpc reasons")
def test_stop_start_with_volume(self):
"""Make sure run instance with block device mapping works"""
@@ -1266,7 +1325,6 @@ class CloudTestCase(test.TestCase):
self._restart_compute_service()
- @test.skip_test("skipping, test is hanging with multinic for rpc reasons")
def test_stop_with_attached_volume(self):
"""Make sure attach info is reflected to block device mapping"""
# enforce periodic tasks run in short time to avoid wait for 60s.
@@ -1342,7 +1400,6 @@ class CloudTestCase(test.TestCase):
greenthread.sleep(0.3)
return result['snapshotId']
- @test.skip_test("skipping, test is hanging with multinic for rpc reasons")
def test_run_with_snapshot(self):
"""Makes sure run/stop/start instance with snapshot works."""
vol = self._volume_create()
diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py
index b407d77b0..65a6acd29 100644
--- a/nova/tests/test_compute.py
+++ b/nova/tests/test_compute.py
@@ -428,11 +428,12 @@ class ComputeTestCase(test.TestCase):
self.stubs.Set(self.compute.network_api, 'get_instance_nw_info', fake)
context = self.context.elevated()
instance_id = self._create_instance()
- self.compute.prep_resize(context, instance_id, 1)
+ instance_ref = db.instance_get(context, instance_id)
+ self.compute.prep_resize(context, instance_ref['uuid'], 1)
migration_ref = db.migration_get_by_instance_and_status(context,
- instance_id, 'pre-migrating')
+ instance_ref['uuid'], 'pre-migrating')
try:
- self.compute.finish_resize(context, instance_id,
+ self.compute.finish_resize(context, instance_ref['uuid'],
int(migration_ref['id']), {})
except KeyError, e:
# Only catch key errors. We want other reasons for the test to
@@ -445,14 +446,15 @@ class ComputeTestCase(test.TestCase):
"""Ensure notifications on instance migrate/resize"""
instance_id = self._create_instance()
context = self.context.elevated()
+ inst_ref = db.instance_get(context, instance_id)
self.compute.run_instance(self.context, instance_id)
test_notifier.NOTIFICATIONS = []
db.instance_update(self.context, instance_id, {'host': 'foo'})
- self.compute.prep_resize(context, instance_id, 1)
+ self.compute.prep_resize(context, inst_ref['uuid'], 1)
migration_ref = db.migration_get_by_instance_and_status(context,
- instance_id, 'pre-migrating')
+ inst_ref['uuid'], 'pre-migrating')
self.assertEquals(len(test_notifier.NOTIFICATIONS), 1)
msg = test_notifier.NOTIFICATIONS[0]
@@ -475,13 +477,15 @@ class ComputeTestCase(test.TestCase):
"""Ensure instance can be migrated/resized"""
instance_id = self._create_instance()
context = self.context.elevated()
+ inst_ref = db.instance_get(context, instance_id)
self.compute.run_instance(self.context, instance_id)
- db.instance_update(self.context, instance_id, {'host': 'foo'})
- self.compute.prep_resize(context, instance_id, 1)
+ db.instance_update(self.context, inst_ref['uuid'],
+ {'host': 'foo'})
+ self.compute.prep_resize(context, inst_ref['uuid'], 1)
migration_ref = db.migration_get_by_instance_and_status(context,
- instance_id, 'pre-migrating')
- self.compute.resize_instance(context, instance_id,
+ inst_ref['uuid'], 'pre-migrating')
+ self.compute.resize_instance(context, inst_ref['uuid'],
migration_ref['id'])
self.compute.terminate_instance(context, instance_id)
@@ -539,36 +543,36 @@ class ComputeTestCase(test.TestCase):
# Confirm the instance size before the resize starts
inst_ref = db.instance_get(context, instance_id)
- instance_type_ref = db.instance_type_get_by_id(context,
+ instance_type_ref = db.instance_type_get(context,
inst_ref['instance_type_id'])
self.assertEqual(instance_type_ref['flavorid'], 1)
db.instance_update(self.context, instance_id, {'host': 'foo'})
- self.compute.prep_resize(context, instance_id, 3)
+ self.compute.prep_resize(context, inst_ref['uuid'], 3)
migration_ref = db.migration_get_by_instance_and_status(context,
- instance_id, 'pre-migrating')
+ inst_ref['uuid'], 'pre-migrating')
- self.compute.resize_instance(context, instance_id,
+ self.compute.resize_instance(context, inst_ref['uuid'],
migration_ref['id'])
- self.compute.finish_resize(context, instance_id,
+ self.compute.finish_resize(context, inst_ref['uuid'],
int(migration_ref['id']), {})
# Prove that the instance size is now the new size
inst_ref = db.instance_get(context, instance_id)
- instance_type_ref = db.instance_type_get_by_id(context,
+ instance_type_ref = db.instance_type_get(context,
inst_ref['instance_type_id'])
self.assertEqual(instance_type_ref['flavorid'], 3)
# Finally, revert and confirm the old flavor has been applied
- self.compute.revert_resize(context, instance_id,
+ self.compute.revert_resize(context, inst_ref['uuid'],
migration_ref['id'])
- self.compute.finish_revert_resize(context, instance_id,
+ self.compute.finish_revert_resize(context, inst_ref['uuid'],
migration_ref['id'])
inst_ref = db.instance_get(context, instance_id)
- instance_type_ref = db.instance_type_get_by_id(context,
+ instance_type_ref = db.instance_type_get(context,
inst_ref['instance_type_id'])
self.assertEqual(instance_type_ref['flavorid'], 1)
@@ -583,8 +587,9 @@ class ComputeTestCase(test.TestCase):
the same host"""
instance_id = self._create_instance()
self.compute.run_instance(self.context, instance_id)
+ inst_ref = db.instance_get(self.context, instance_id)
self.assertRaises(exception.Error, self.compute.prep_resize,
- self.context, instance_id, 1)
+ self.context, inst_ref['uuid'], 1)
self.compute.terminate_instance(self.context, instance_id)
def test_migrate(self):
@@ -624,7 +629,6 @@ class ComputeTestCase(test.TestCase):
self._setup_other_managers()
dbmock = self.mox.CreateMock(db)
volmock = self.mox.CreateMock(self.volume_manager)
- netmock = self.mox.CreateMock(self.network_manager)
drivermock = self.mox.CreateMock(self.compute_driver)
dbmock.instance_get(c, i_ref['id']).AndReturn(i_ref)
@@ -632,12 +636,11 @@ class ComputeTestCase(test.TestCase):
for i in range(len(i_ref['volumes'])):
vid = i_ref['volumes'][i]['id']
volmock.setup_compute_volume(c, vid).InAnyOrder('g1')
- netmock.setup_compute_network(c, i_ref['id'])
+ drivermock.plug_vifs(i_ref, [])
drivermock.ensure_filtering_rules_for_instance(i_ref)
self.compute.db = dbmock
self.compute.volume_manager = volmock
- self.compute.network_manager = netmock
self.compute.driver = drivermock
self.mox.ReplayAll()
@@ -652,18 +655,16 @@ class ComputeTestCase(test.TestCase):
self._setup_other_managers()
dbmock = self.mox.CreateMock(db)
- netmock = self.mox.CreateMock(self.network_manager)
drivermock = self.mox.CreateMock(self.compute_driver)
dbmock.instance_get(c, i_ref['id']).AndReturn(i_ref)
dbmock.instance_get_fixed_addresses(c, i_ref['id']).AndReturn('dummy')
self.mox.StubOutWithMock(compute_manager.LOG, 'info')
compute_manager.LOG.info(_("%s has no volume."), i_ref['hostname'])
- netmock.setup_compute_network(c, i_ref['id'])
+ drivermock.plug_vifs(i_ref, [])
drivermock.ensure_filtering_rules_for_instance(i_ref)
self.compute.db = dbmock
- self.compute.network_manager = netmock
self.compute.driver = drivermock
self.mox.ReplayAll()
@@ -684,18 +685,20 @@ class ComputeTestCase(test.TestCase):
dbmock = self.mox.CreateMock(db)
netmock = self.mox.CreateMock(self.network_manager)
volmock = self.mox.CreateMock(self.volume_manager)
+ drivermock = self.mox.CreateMock(self.compute_driver)
dbmock.instance_get(c, i_ref['id']).AndReturn(i_ref)
dbmock.instance_get_fixed_addresses(c, i_ref['id']).AndReturn('dummy')
for i in range(len(i_ref['volumes'])):
volmock.setup_compute_volume(c, i_ref['volumes'][i]['id'])
for i in range(FLAGS.live_migration_retry_count):
- netmock.setup_compute_network(c, i_ref['id']).\
+ drivermock.plug_vifs(i_ref, []).\
AndRaise(exception.ProcessExecutionError())
self.compute.db = dbmock
self.compute.network_manager = netmock
self.compute.volume_manager = volmock
+ self.compute.driver = drivermock
self.mox.ReplayAll()
self.assertRaises(exception.ProcessExecutionError,
@@ -830,7 +833,7 @@ class ComputeTestCase(test.TestCase):
for v in i_ref['volumes']:
self.compute.volume_manager.remove_compute_volume(c, v['id'])
self.mox.StubOutWithMock(self.compute.driver, 'unfilter_instance')
- self.compute.driver.unfilter_instance(i_ref)
+ self.compute.driver.unfilter_instance(i_ref, [])
# executing
self.mox.ReplayAll()
diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py
new file mode 100644
index 000000000..107fd03e3
--- /dev/null
+++ b/nova/tests/test_db_api.py
@@ -0,0 +1,86 @@
+# 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.
+
+"""Unit tests for the DB API"""
+
+from nova import test
+from nova import context
+from nova import db
+from nova import flags
+from nova.auth import manager
+
+FLAGS = flags.FLAGS
+
+
+def _setup_networking(instance_id, ip='1.2.3.4', flo_addr='1.2.1.2'):
+ ctxt = context.get_admin_context()
+ network_ref = db.project_get_networks(ctxt,
+ 'fake',
+ associate=True)[0]
+ vif = {'address': '56:12:12:12:12:12',
+ 'network_id': network_ref['id'],
+ 'instance_id': instance_id}
+ vif_ref = db.virtual_interface_create(ctxt, vif)
+
+ fixed_ip = {'address': ip,
+ 'network_id': network_ref['id'],
+ 'virtual_interface_id': vif_ref['id'],
+ 'allocated': True,
+ 'instance_id': instance_id}
+ db.fixed_ip_create(ctxt, fixed_ip)
+ fix_ref = db.fixed_ip_get_by_address(ctxt, ip)
+ db.floating_ip_create(ctxt, {'address': flo_addr,
+ 'fixed_ip_id': fix_ref.id})
+
+
+class DbApiTestCase(test.TestCase):
+ def setUp(self):
+ super(DbApiTestCase, self).setUp()
+ self.manager = manager.AuthManager()
+ self.user = self.manager.create_user('admin', 'admin', 'admin', True)
+ self.project = self.manager.create_project('proj', 'admin', 'proj')
+ self.context = context.RequestContext(user=self.user,
+ project=self.project)
+
+ def tearDown(self):
+ self.manager.delete_project(self.project)
+ self.manager.delete_user(self.user)
+ super(DbApiTestCase, self).tearDown()
+
+ def test_instance_get_project_vpn(self):
+ result = db.fixed_ip_get_all(self.context)
+ values = {'instance_type_id': FLAGS.default_instance_type,
+ 'image_ref': FLAGS.vpn_image_id,
+ 'project_id': self.project.id
+ }
+ instance = db.instance_create(self.context, values)
+ result = db.instance_get_project_vpn(self.context, self.project.id)
+ self.assertEqual(instance.id, result.id)
+
+ def test_instance_get_project_vpn_joins(self):
+ result = db.fixed_ip_get_all(self.context)
+ values = {'instance_type_id': FLAGS.default_instance_type,
+ 'image_ref': FLAGS.vpn_image_id,
+ 'project_id': self.project.id
+ }
+ instance = db.instance_create(self.context, values)
+ _setup_networking(instance.id)
+ result = db.instance_get_project_vpn(self.context, self.project.id)
+ self.assertEqual(instance.id, result.id)
+ self.assertEqual(result['fixed_ips'][0]['floating_ips'][0].address,
+ '1.2.1.2')
diff --git a/nova/tests/test_instance_types_extra_specs.py b/nova/tests/test_instance_types_extra_specs.py
index c26cf82ff..393ed1e36 100644
--- a/nova/tests/test_instance_types_extra_specs.py
+++ b/nova/tests/test_instance_types_extra_specs.py
@@ -105,8 +105,8 @@ class InstanceTypeExtraSpecsTestCase(test.TestCase):
self.instance_type_id)
self.assertEquals(expected_specs, actual_specs)
- def test_instance_type_get_by_id_with_extra_specs(self):
- instance_type = db.api.instance_type_get_by_id(
+ def test_instance_type_get_with_extra_specs(self):
+ instance_type = db.api.instance_type_get(
context.get_admin_context(),
self.instance_type_id)
self.assertEquals(instance_type['extra_specs'],
@@ -115,7 +115,7 @@ class InstanceTypeExtraSpecsTestCase(test.TestCase):
xpu_arch="fermi",
xpus="2",
xpu_model="Tesla 2050"))
- instance_type = db.api.instance_type_get_by_id(
+ instance_type = db.api.instance_type_get(
context.get_admin_context(),
5)
self.assertEquals(instance_type['extra_specs'], {})
@@ -136,7 +136,7 @@ class InstanceTypeExtraSpecsTestCase(test.TestCase):
"m1.small")
self.assertEquals(instance_type['extra_specs'], {})
- def test_instance_type_get_by_id_with_extra_specs(self):
+ def test_instance_type_get_with_extra_specs(self):
instance_type = db.api.instance_type_get_by_flavor_id(
context.get_admin_context(),
105)
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
index f99e1713d..bab4d200b 100644
--- a/nova/tests/test_libvirt.py
+++ b/nova/tests/test_libvirt.py
@@ -54,10 +54,15 @@ def _create_network_info(count=1, ipv6=None):
fake_ip = '0.0.0.0/0'
fake_ip_2 = '0.0.0.1/0'
fake_ip_3 = '0.0.0.1/0'
+ fake_vlan = 100
+ fake_bridge_interface = 'eth0'
network = {'bridge': fake,
'cidr': fake_ip,
- 'cidr_v6': fake_ip}
+ 'cidr_v6': fake_ip,
+ 'vlan': fake_vlan,
+ 'bridge_interface': fake_bridge_interface}
mapping = {'mac': fake,
+ 'dhcp_server': fake,
'gateway': fake,
'gateway6': fake,
'ips': [{'ip': fake_ip}, {'ip': fake_ip}]}
@@ -83,7 +88,7 @@ def _setup_networking(instance_id, ip='1.2.3.4'):
'virtual_interface_id': vif_ref['id']}
db.fixed_ip_create(ctxt, fixed_ip)
db.fixed_ip_update(ctxt, ip, {'allocated': True,
- 'instance_id': instance_id})
+ 'instance_id': instance_id})
class CacheConcurrencyTestCase(test.TestCase):
@@ -172,13 +177,13 @@ class LibvirtConnTestCase(test.TestCase):
self.context = context.get_admin_context()
FLAGS.instances_path = ''
self.call_libvirt_dependant_setup = False
+ self.test_ip = '10.11.12.13'
def tearDown(self):
self.manager.delete_project(self.project)
self.manager.delete_user(self.user)
super(LibvirtConnTestCase, self).tearDown()
- test_ip = '10.11.12.13'
test_instance = {'memory_kb': '1024000',
'basepath': '/some/path',
'bridge_name': 'br100',
@@ -218,9 +223,29 @@ class LibvirtConnTestCase(test.TestCase):
def setattr(self, key, val):
self.__setattr__(key, val)
+ # A fake VIF driver
+ class FakeVIFDriver(object):
+
+ def __init__(self, **kwargs):
+ pass
+
+ def setattr(self, key, val):
+ self.__setattr__(key, val)
+
+ def plug(self, instance, network, mapping):
+ return {
+ 'id': 'fake',
+ 'bridge_name': 'fake',
+ 'mac_address': 'fake',
+ 'ip_address': 'fake',
+ 'dhcp_server': 'fake',
+ 'extra_params': 'fake'
+ }
+
# Creating mocks
fake = FakeLibvirtConnection()
fakeip = FakeIptablesFirewallDriver
+ fakevif = FakeVIFDriver()
# Customizing above fake if necessary
for key, val in kwargs.items():
fake.__setattr__(key, val)
@@ -228,6 +253,8 @@ class LibvirtConnTestCase(test.TestCase):
# Inevitable mocks for connection.LibvirtConnection
self.mox.StubOutWithMock(connection.utils, 'import_class')
connection.utils.import_class(mox.IgnoreArg()).AndReturn(fakeip)
+ self.mox.StubOutWithMock(connection.utils, 'import_object')
+ connection.utils.import_object(mox.IgnoreArg()).AndReturn(fakevif)
self.mox.StubOutWithMock(connection.LibvirtConnection, '_conn')
connection.LibvirtConnection._conn = fake
@@ -263,7 +290,6 @@ class LibvirtConnTestCase(test.TestCase):
return db.service_create(context.get_admin_context(), service_ref)
- @test.skip_test("Please review this test to ensure intent")
def test_preparing_xml_info(self):
conn = connection.LibvirtConnection(True)
instance_ref = db.instance_create(self.context, self.test_instance)
@@ -279,43 +305,23 @@ class LibvirtConnTestCase(test.TestCase):
_create_network_info(2))
self.assertTrue(len(result['nics']) == 2)
- def test_get_nic_for_xml_v4(self):
- conn = connection.LibvirtConnection(True)
- network, mapping = _create_network_info()[0]
- self.flags(use_ipv6=False)
- params = conn._get_nic_for_xml(network, mapping)['extra_params']
- self.assertTrue(params.find('PROJNETV6') == -1)
- self.assertTrue(params.find('PROJMASKV6') == -1)
-
- def test_get_nic_for_xml_v6(self):
- conn = connection.LibvirtConnection(True)
- network, mapping = _create_network_info()[0]
- self.flags(use_ipv6=True)
- params = conn._get_nic_for_xml(network, mapping)['extra_params']
- self.assertTrue(params.find('PROJNETV6') > -1)
- self.assertTrue(params.find('PROJMASKV6') > -1)
-
- @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_xml_and_uri_no_ramdisk_no_kernel(self):
instance_data = dict(self.test_instance)
self._check_xml_and_uri(instance_data,
expect_kernel=False, expect_ramdisk=False)
- @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_xml_and_uri_no_ramdisk(self):
instance_data = dict(self.test_instance)
instance_data['kernel_id'] = 'aki-deadbeef'
self._check_xml_and_uri(instance_data,
expect_kernel=True, expect_ramdisk=False)
- @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_xml_and_uri_no_kernel(self):
instance_data = dict(self.test_instance)
instance_data['ramdisk_id'] = 'ari-deadbeef'
self._check_xml_and_uri(instance_data,
expect_kernel=False, expect_ramdisk=False)
- @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_xml_and_uri(self):
instance_data = dict(self.test_instance)
instance_data['ramdisk_id'] = 'ari-deadbeef'
@@ -323,7 +329,6 @@ class LibvirtConnTestCase(test.TestCase):
self._check_xml_and_uri(instance_data,
expect_kernel=True, expect_ramdisk=True)
- @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_xml_and_uri_rescue(self):
instance_data = dict(self.test_instance)
instance_data['ramdisk_id'] = 'ari-deadbeef'
@@ -331,7 +336,6 @@ class LibvirtConnTestCase(test.TestCase):
self._check_xml_and_uri(instance_data, expect_kernel=True,
expect_ramdisk=True, rescue=True)
- @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_lxc_container_and_uri(self):
instance_data = dict(self.test_instance)
self._check_xml_and_container(instance_data)
@@ -411,6 +415,15 @@ class LibvirtConnTestCase(test.TestCase):
self.assertEquals(snapshot['status'], 'active')
self.assertEquals(snapshot['name'], snapshot_name)
+ def test_attach_invalid_device(self):
+ self.create_fake_libvirt_mock()
+ connection.LibvirtConnection._conn.lookupByName = self.fake_lookup
+ self.mox.ReplayAll()
+ conn = connection.LibvirtConnection(False)
+ self.assertRaises(exception.InvalidDevicePath,
+ conn.attach_volume,
+ "fake", "bad/device/path", "/dev/fake")
+
def test_multi_nic(self):
instance_data = dict(self.test_instance)
network_info = _create_network_info(2)
@@ -431,24 +444,7 @@ class LibvirtConnTestCase(test.TestCase):
user_context = context.RequestContext(project=self.project,
user=self.user)
instance_ref = db.instance_create(user_context, instance)
- # Re-get the instance so it's bound to an actual session
- instance_ref = db.instance_get(user_context, instance_ref['id'])
- network_ref = db.project_get_networks(context.get_admin_context(),
- self.project.id)[0]
-
- vif = {'address': '56:12:12:12:12:12',
- 'network_id': network_ref['id'],
- 'instance_id': instance_ref['id']}
- vif_ref = db.virtual_interface_create(self.context, vif)
- fixed_ip = {'address': self.test_ip,
- 'network_id': network_ref['id'],
- 'virtual_interface_id': vif_ref['id']}
-
- ctxt = context.get_admin_context()
- fixed_ip_ref = db.fixed_ip_create(ctxt, fixed_ip)
- db.fixed_ip_update(ctxt, self.test_ip,
- {'allocated': True,
- 'instance_id': instance_ref['id']})
+ _setup_networking(instance_ref['id'], self.test_ip)
self.flags(libvirt_type='lxc')
conn = connection.LibvirtConnection(True)
@@ -480,7 +476,7 @@ class LibvirtConnTestCase(test.TestCase):
network_ref = db.project_get_networks(context.get_admin_context(),
self.project.id)[0]
- _setup_networking(instance_ref['id'], ip=self.test_ip)
+ _setup_networking(instance_ref['id'], self.test_ip)
type_uri_map = {'qemu': ('qemu:///system',
[(lambda t: t.find('.').get('type'), 'qemu'),
@@ -721,6 +717,9 @@ class LibvirtConnTestCase(test.TestCase):
return vdmock
self.create_fake_libvirt_mock(lookupByName=fake_lookup)
+ self.mox.StubOutWithMock(self.compute, "recover_live_migration")
+ self.compute.recover_live_migration(self.context, instance_ref,
+ dest='dest')
# Start test
self.mox.ReplayAll()
@@ -739,7 +738,6 @@ class LibvirtConnTestCase(test.TestCase):
db.volume_destroy(self.context, volume_ref['id'])
db.instance_destroy(self.context, instance_ref['id'])
- @test.skip_test("test needs rewrite: instance no longer has mac_address")
def test_spawn_with_network_info(self):
# Skip if non-libvirt environment
if not self.lazy_load_library_exists():
@@ -758,17 +756,7 @@ class LibvirtConnTestCase(test.TestCase):
conn.firewall_driver.setattr('setup_basic_filtering', fake_none)
conn.firewall_driver.setattr('prepare_instance_filter', fake_none)
- network = db.project_get_networks(context.get_admin_context(),
- self.project.id)[0]
- ip_dict = {'ip': self.test_ip,
- 'netmask': network['netmask'],
- 'enabled': '1'}
- mapping = {'label': network['label'],
- 'gateway': network['gateway'],
- 'mac': instance['mac_address'],
- 'dns': [network['dns']],
- 'ips': [ip_dict]}
- network_info = [(network, mapping)]
+ network_info = _create_network_info()
try:
conn.spawn(instance, network_info)
@@ -826,6 +814,7 @@ class IptablesFirewallTestCase(test.TestCase):
"""setup_basic_rules in nwfilter calls this."""
pass
self.fake_libvirt_connection = FakeLibvirtConnection()
+ self.test_ip = '10.11.12.13'
self.fw = firewall.IptablesFirewallDriver(
get_connection=lambda: self.fake_libvirt_connection)
@@ -891,27 +880,11 @@ class IptablesFirewallTestCase(test.TestCase):
'project_id': 'fake',
'instance_type_id': 1})
- @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_static_filters(self):
instance_ref = self._create_instance_ref()
- ip = '10.11.12.13'
-
- network_ref = db.project_get_networks(self.context,
- 'fake',
- associate=True)[0]
- vif = {'address': '56:12:12:12:12:12',
- 'network_id': network_ref['id'],
- 'instance_id': instance_ref['id']}
- vif_ref = db.virtual_interface_create(self.context, vif)
-
- fixed_ip = {'address': ip,
- 'network_id': network_ref['id'],
- 'virtual_interface_id': vif_ref['id']}
- admin_ctxt = context.get_admin_context()
- db.fixed_ip_create(admin_ctxt, fixed_ip)
- db.fixed_ip_update(admin_ctxt, ip, {'allocated': True,
- 'instance_id': instance_ref['id']})
+ _setup_networking(instance_ref['id'], self.test_ip)
+ admin_ctxt = context.get_admin_context()
secgroup = db.security_group_create(admin_ctxt,
{'user_id': 'fake',
'project_id': 'fake',
@@ -1043,7 +1016,6 @@ class IptablesFirewallTestCase(test.TestCase):
self.assertEquals(ipv6_network_rules,
ipv6_rules_per_network * networks_count)
- @test.skip_test("skipping libvirt tests")
def test_do_refresh_security_group_rules(self):
instance_ref = self._create_instance_ref()
self.mox.StubOutWithMock(self.fw,
@@ -1054,7 +1026,6 @@ class IptablesFirewallTestCase(test.TestCase):
self.mox.ReplayAll()
self.fw.do_refresh_security_group_rules("fake")
- @test.skip_test("skip libvirt test project_get_network no longer exists")
def test_unfilter_instance_undefines_nwfilter(self):
# Skip if non-libvirt environment
if not self.lazy_load_library_exists():
@@ -1068,38 +1039,24 @@ class IptablesFirewallTestCase(test.TestCase):
self.fw.nwfilter._conn.nwfilterLookupByName =\
fakefilter.nwfilterLookupByName
instance_ref = self._create_instance_ref()
- inst_id = instance_ref['id']
- instance = db.instance_get(self.context, inst_id)
- ip = '10.11.12.13'
- network_ref = db.project_get_network(self.context, 'fake')
- fixed_ip = {'address': ip, 'network_id': network_ref['id']}
- db.fixed_ip_create(admin_ctxt, fixed_ip)
- db.fixed_ip_update(admin_ctxt, ip, {'allocated': True,
- 'instance_id': inst_id})
- self.fw.setup_basic_filtering(instance)
- self.fw.prepare_instance_filter(instance)
- self.fw.apply_instance_filter(instance)
+ _setup_networking(instance_ref['id'], self.test_ip)
+ self.fw.setup_basic_filtering(instance_ref)
+ self.fw.prepare_instance_filter(instance_ref)
+ self.fw.apply_instance_filter(instance_ref)
original_filter_count = len(fakefilter.filters)
- self.fw.unfilter_instance(instance)
+ self.fw.unfilter_instance(instance_ref)
# should undefine just the instance filter
self.assertEqual(original_filter_count - len(fakefilter.filters), 1)
db.instance_destroy(admin_ctxt, instance_ref['id'])
- @test.skip_test("skip libvirt test project_get_network no longer exists")
def test_provider_firewall_rules(self):
# setup basic instance data
instance_ref = self._create_instance_ref()
nw_info = _create_network_info(1)
- ip = '10.11.12.13'
- network_ref = db.project_get_network(self.context, 'fake')
- admin_ctxt = context.get_admin_context()
- fixed_ip = {'address': ip, 'network_id': network_ref['id']}
- db.fixed_ip_create(admin_ctxt, fixed_ip)
- db.fixed_ip_update(admin_ctxt, ip, {'allocated': True,
- 'instance_id': instance_ref['id']})
+ _setup_networking(instance_ref['id'], self.test_ip)
# FRAGILE: peeks at how the firewall names chains
chain_name = 'inst-%s' % instance_ref['id']
@@ -1111,6 +1068,7 @@ class IptablesFirewallTestCase(test.TestCase):
if rule.chain == 'provider']
self.assertEqual(0, len(rules))
+ admin_ctxt = context.get_admin_context()
# add a rule and send the update message, check for 1 rule
provider_fw0 = db.provider_fw_rule_create(admin_ctxt,
{'protocol': 'tcp',
@@ -1169,6 +1127,7 @@ class NWFilterTestCase(test.TestCase):
self.fake_libvirt_connection = Mock()
+ self.test_ip = '10.11.12.13'
self.fw = firewall.NWFilterFirewall(
lambda: self.fake_libvirt_connection)
@@ -1255,7 +1214,6 @@ class NWFilterTestCase(test.TestCase):
inst.update(params)
return db.instance_type_create(context, inst)['id']
- @test.skip_test('Skipping this test')
def test_creates_base_rule_first(self):
# These come pre-defined by libvirt
self.defined_filters = ['no-mac-spoofing',
@@ -1287,21 +1245,11 @@ class NWFilterTestCase(test.TestCase):
instance_ref = self._create_instance()
inst_id = instance_ref['id']
- ip = '10.11.12.13'
-
- #network_ref = db.project_get_networks(self.context, 'fake')[0]
- #fixed_ip = {'address': ip, 'network_id': network_ref['id']}
-
- #admin_ctxt = context.get_admin_context()
- #db.fixed_ip_create(admin_ctxt, fixed_ip)
- #db.fixed_ip_update(admin_ctxt, ip, {'allocated': True,
- # 'instance_id': inst_id})
-
- self._setup_networking(instance_ref['id'], ip=ip)
+ _setup_networking(instance_ref['id'], self.test_ip)
def _ensure_all_called():
instance_filter = 'nova-instance-%s-%s' % (instance_ref['name'],
- '00A0C914C829')
+ '561212121212')
secgroup_filter = 'nova-secgroup-%s' % self.security_group['id']
for required in [secgroup_filter, 'allow-dhcp-server',
'no-arp-spoofing', 'no-ip-spoofing',
@@ -1322,7 +1270,7 @@ class NWFilterTestCase(test.TestCase):
self.fw.apply_instance_filter(instance)
_ensure_all_called()
self.teardown_security_group()
- db.instance_destroy(admin_ctxt, instance_ref['id'])
+ db.instance_destroy(context.get_admin_context(), instance_ref['id'])
def test_create_network_filters(self):
instance_ref = self._create_instance()
@@ -1332,7 +1280,6 @@ class NWFilterTestCase(test.TestCase):
"fake")
self.assertEquals(len(result), 3)
- @test.skip_test("skip libvirt test project_get_network no longer exists")
def test_unfilter_instance_undefines_nwfilters(self):
admin_ctxt = context.get_admin_context()
@@ -1350,12 +1297,7 @@ class NWFilterTestCase(test.TestCase):
instance = db.instance_get(self.context, inst_id)
- ip = '10.11.12.13'
- network_ref = db.project_get_network(self.context, 'fake')
- fixed_ip = {'address': ip, 'network_id': network_ref['id']}
- db.fixed_ip_create(admin_ctxt, fixed_ip)
- db.fixed_ip_update(admin_ctxt, ip, {'allocated': True,
- 'instance_id': inst_id})
+ _setup_networking(instance_ref['id'], self.test_ip)
self.fw.setup_basic_filtering(instance)
self.fw.prepare_instance_filter(instance)
self.fw.apply_instance_filter(instance)
diff --git a/nova/tests/test_network.py b/nova/tests/test_network.py
index b09021e13..28f50d328 100644
--- a/nova/tests/test_network.py
+++ b/nova/tests/test_network.py
@@ -45,6 +45,7 @@ class FakeModel(dict):
networks = [{'id': 0,
'label': 'test0',
'injected': False,
+ 'multi_host': False,
'cidr': '192.168.0.0/24',
'cidr_v6': '2001:db8::/64',
'gateway_v6': '2001:db8::1',
@@ -54,7 +55,8 @@ networks = [{'id': 0,
'bridge_interface': 'fake_fa0',
'gateway': '192.168.0.1',
'broadcast': '192.168.0.255',
- 'dns': '192.168.0.1',
+ 'dns1': '192.168.0.1',
+ 'dns2': '192.168.0.2',
'vlan': None,
'host': None,
'project_id': 'fake_project',
@@ -62,6 +64,7 @@ networks = [{'id': 0,
{'id': 1,
'label': 'test1',
'injected': False,
+ 'multi_host': False,
'cidr': '192.168.1.0/24',
'cidr_v6': '2001:db9::/64',
'gateway_v6': '2001:db9::1',
@@ -71,7 +74,8 @@ networks = [{'id': 0,
'bridge_interface': 'fake_fa1',
'gateway': '192.168.1.1',
'broadcast': '192.168.1.255',
- 'dns': '192.168.0.1',
+ 'dns1': '192.168.0.1',
+ 'dns2': '192.168.0.2',
'vlan': None,
'host': None,
'project_id': 'fake_project',
@@ -122,34 +126,20 @@ class FlatNetworkTestCase(test.TestCase):
self.network = network_manager.FlatManager(host=HOST)
self.network.db = db
- def test_set_network_hosts(self):
- self.mox.StubOutWithMock(db, 'network_get_all')
- self.mox.StubOutWithMock(db, 'network_set_host')
- self.mox.StubOutWithMock(db, 'network_update')
-
- db.network_get_all(mox.IgnoreArg()).AndReturn([networks[0]])
- db.network_set_host(mox.IgnoreArg(),
- networks[0]['id'],
- mox.IgnoreArg()).AndReturn(HOST)
- db.network_update(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
- self.mox.ReplayAll()
-
- self.network.set_network_hosts(None)
-
def test_get_instance_nw_info(self):
self.mox.StubOutWithMock(db, 'fixed_ip_get_by_instance')
self.mox.StubOutWithMock(db, 'virtual_interface_get_by_instance')
- self.mox.StubOutWithMock(db, 'instance_type_get_by_id')
+ self.mox.StubOutWithMock(db, 'instance_type_get')
db.fixed_ip_get_by_instance(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(fixed_ips)
db.virtual_interface_get_by_instance(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(vifs)
- db.instance_type_get_by_id(mox.IgnoreArg(),
+ db.instance_type_get(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(flavor)
self.mox.ReplayAll()
- nw_info = self.network.get_instance_nw_info(None, 0, 0)
+ nw_info = self.network.get_instance_nw_info(None, 0, 0, None)
self.assertTrue(nw_info)
@@ -159,11 +149,15 @@ class FlatNetworkTestCase(test.TestCase):
'cidr': '192.168.%s.0/24' % i,
'cidr_v6': '2001:db%s::/64' % i8,
'id': i,
- 'injected': 'DONTCARE'}
+ 'multi_host': False,
+ 'injected': 'DONTCARE',
+ 'bridge_interface': 'fake_fa%s' % i,
+ 'vlan': None}
self.assertDictMatch(nw[0], check)
check = {'broadcast': '192.168.%s.255' % i,
+ 'dhcp_server': '192.168.%s.1' % i,
'dns': 'DONTCARE',
'gateway': '192.168.%s.1' % i,
'gateway6': '2001:db%s::1' % i8,
@@ -171,7 +165,9 @@ class FlatNetworkTestCase(test.TestCase):
'ips': 'DONTCARE',
'label': 'test%s' % i,
'mac': 'DE:AD:BE:EF:00:0%s' % i,
- 'rxtx_cap': 'DONTCARE'}
+ 'rxtx_cap': 'DONTCARE',
+ 'should_create_vlan': False,
+ 'should_create_bridge': False}
self.assertDictMatch(nw[1], check)
check = [{'enabled': 'DONTCARE',
diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py
index 69d2deafe..a35caadf8 100644
--- a/nova/tests/test_quota.py
+++ b/nova/tests/test_quota.py
@@ -269,11 +269,10 @@ class QuotaTestCase(test.TestCase):
for volume_id in volume_ids:
db.volume_destroy(self.context, volume_id)
- @test.skip_test
def test_too_many_addresses(self):
address = '192.168.0.100'
db.floating_ip_create(context.get_admin_context(),
- {'address': address, 'host': FLAGS.host,
+ {'address': address,
'project_id': self.project.id})
self.assertRaises(quota.QuotaError,
self.network.allocate_floating_ip,
diff --git a/nova/tests/test_vmwareapi.py b/nova/tests/test_vmwareapi.py
index cbf7801cf..7313508a6 100644
--- a/nova/tests/test_vmwareapi.py
+++ b/nova/tests/test_vmwareapi.py
@@ -19,9 +19,6 @@
Test suite for VMWareAPI.
"""
-import stubout
-
-from nova import context
from nova import db
from nova import flags
from nova import test
@@ -41,51 +38,66 @@ FLAGS = flags.FLAGS
class VMWareAPIVMTestCase(test.TestCase):
"""Unit tests for Vmware API connection calls."""
- # NOTE(jkoelker): This is leaking stubs into the db module.
- # Commenting out until updated for multi-nic.
- #def setUp(self):
- # super(VMWareAPIVMTestCase, self).setUp()
- # self.flags(vmwareapi_host_ip='test_url',
- # vmwareapi_host_username='test_username',
- # vmwareapi_host_password='test_pass')
- # self.manager = manager.AuthManager()
- # self.user = self.manager.create_user('fake', 'fake', 'fake',
- # admin=True)
- # self.project = self.manager.create_project('fake', 'fake', 'fake')
- # self.network = utils.import_object(FLAGS.network_manager)
- # self.stubs = stubout.StubOutForTesting()
- # vmwareapi_fake.reset()
- # db_fakes.stub_out_db_instance_api(self.stubs)
- # stubs.set_stubs(self.stubs)
- # glance_stubs.stubout_glance_client(self.stubs,
- # glance_stubs.FakeGlance)
- # self.conn = vmwareapi_conn.get_connection(False)
-
- #def tearDown(self):
- # super(VMWareAPIVMTestCase, self).tearDown()
- # vmwareapi_fake.cleanup()
- # self.manager.delete_project(self.project)
- # self.manager.delete_user(self.user)
- # self.stubs.UnsetAll()
+ def setUp(self):
+ super(VMWareAPIVMTestCase, self).setUp()
+ self.flags(vmwareapi_host_ip='test_url',
+ vmwareapi_host_username='test_username',
+ vmwareapi_host_password='test_pass')
+ self.manager = manager.AuthManager()
+ self.user = self.manager.create_user('fake', 'fake', 'fake',
+ admin=True)
+ self.project = self.manager.create_project('fake', 'fake', 'fake')
+ self.network = utils.import_object(FLAGS.network_manager)
+ vmwareapi_fake.reset()
+ db_fakes.stub_out_db_instance_api(self.stubs)
+ stubs.set_stubs(self.stubs)
+ glance_stubs.stubout_glance_client(self.stubs)
+ self.conn = vmwareapi_conn.get_connection(False)
+ # NOTE(vish): none of the network plugging code is actually
+ # being tested
+ self.network_info = [({'bridge': 'fa0',
+ 'id': 0,
+ 'vlan': None,
+ 'bridge_interface': None,
+ 'injected': True},
+ {'broadcast': '192.168.0.255',
+ 'dns': ['192.168.0.1'],
+ 'gateway': '192.168.0.1',
+ 'gateway6': 'dead:beef::1',
+ 'ip6s': [{'enabled': '1',
+ 'ip': 'dead:beef::dcad:beff:feef:0',
+ 'netmask': '64'}],
+ 'ips': [{'enabled': '1',
+ 'ip': '192.168.0.100',
+ 'netmask': '255.255.255.0'}],
+ 'label': 'fake',
+ 'mac': 'DE:AD:BE:EF:00:00',
+ 'rxtx_cap': 3})]
+
+ def tearDown(self):
+ super(VMWareAPIVMTestCase, self).tearDown()
+ vmwareapi_fake.cleanup()
+ self.manager.delete_project(self.project)
+ self.manager.delete_user(self.user)
def _create_instance_in_the_db(self):
values = {'name': 1,
'id': 1,
'project_id': self.project.id,
'user_id': self.user.id,
- 'image_id': "1",
+ 'image_ref': "1",
'kernel_id': "1",
'ramdisk_id': "1",
+ 'mac_address': "de:ad:be:ef:be:ef",
'instance_type': 'm1.large',
- 'mac_address': 'aa:bb:cc:dd:ee:ff',
}
- self.instance = db.instance_create(values)
+ self.instance = db.instance_create(None, values)
def _create_vm(self):
"""Create and spawn the VM."""
self._create_instance_in_the_db()
self.type_data = db.instance_type_get_by_name(None, 'm1.large')
- self.conn.spawn(self.instance)
+ self.conn.spawn(self.instance, self.network_info)
self._check_vm_record()
def _check_vm_record(self):
@@ -129,24 +141,20 @@ class VMWareAPIVMTestCase(test.TestCase):
self.assertEquals(info["mem"], mem_kib)
self.assertEquals(info["num_cpu"], self.type_data['vcpus'])
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_list_instances(self):
instances = self.conn.list_instances()
self.assertEquals(len(instances), 0)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_list_instances_1(self):
self._create_vm()
instances = self.conn.list_instances()
self.assertEquals(len(instances), 1)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_spawn(self):
self._create_vm()
info = self.conn.get_info(1)
self._check_vm_info(info, power_state.RUNNING)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_snapshot(self):
self._create_vm()
info = self.conn.get_info(1)
@@ -155,27 +163,23 @@ class VMWareAPIVMTestCase(test.TestCase):
info = self.conn.get_info(1)
self._check_vm_info(info, power_state.RUNNING)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_snapshot_non_existent(self):
self._create_instance_in_the_db()
self.assertRaises(Exception, self.conn.snapshot, self.instance,
"Test-Snapshot")
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_reboot(self):
self._create_vm()
info = self.conn.get_info(1)
self._check_vm_info(info, power_state.RUNNING)
- self.conn.reboot(self.instance)
+ self.conn.reboot(self.instance, self.network_info)
info = self.conn.get_info(1)
self._check_vm_info(info, power_state.RUNNING)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_reboot_non_existent(self):
self._create_instance_in_the_db()
self.assertRaises(Exception, self.conn.reboot, self.instance)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_reboot_not_poweredon(self):
self._create_vm()
info = self.conn.get_info(1)
@@ -185,7 +189,6 @@ class VMWareAPIVMTestCase(test.TestCase):
self._check_vm_info(info, power_state.PAUSED)
self.assertRaises(Exception, self.conn.reboot, self.instance)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_suspend(self):
self._create_vm()
info = self.conn.get_info(1)
@@ -194,13 +197,11 @@ class VMWareAPIVMTestCase(test.TestCase):
info = self.conn.get_info(1)
self._check_vm_info(info, power_state.PAUSED)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_suspend_non_existent(self):
self._create_instance_in_the_db()
self.assertRaises(Exception, self.conn.suspend, self.instance,
self.dummy_callback_handler)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_resume(self):
self._create_vm()
info = self.conn.get_info(1)
@@ -212,13 +213,11 @@ class VMWareAPIVMTestCase(test.TestCase):
info = self.conn.get_info(1)
self._check_vm_info(info, power_state.RUNNING)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_resume_non_existent(self):
self._create_instance_in_the_db()
self.assertRaises(Exception, self.conn.resume, self.instance,
self.dummy_callback_handler)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_resume_not_suspended(self):
self._create_vm()
info = self.conn.get_info(1)
@@ -226,49 +225,41 @@ class VMWareAPIVMTestCase(test.TestCase):
self.assertRaises(Exception, self.conn.resume, self.instance,
self.dummy_callback_handler)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_get_info(self):
self._create_vm()
info = self.conn.get_info(1)
self._check_vm_info(info, power_state.RUNNING)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_destroy(self):
self._create_vm()
info = self.conn.get_info(1)
self._check_vm_info(info, power_state.RUNNING)
instances = self.conn.list_instances()
self.assertEquals(len(instances), 1)
- self.conn.destroy(self.instance)
+ self.conn.destroy(self.instance, self.network_info)
instances = self.conn.list_instances()
self.assertEquals(len(instances), 0)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_destroy_non_existent(self):
self._create_instance_in_the_db()
- self.assertEquals(self.conn.destroy(self.instance), None)
+ self.assertEquals(self.conn.destroy(self.instance, self.network_info),
+ None)
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_pause(self):
pass
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_unpause(self):
pass
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_diagnostics(self):
pass
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_get_console_output(self):
pass
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def test_get_ajax_console(self):
pass
- @test.skip_test("DB stubbing not removed, needs updating for multi-nic")
def dummy_callback_handler(self, ret):
"""
Dummy callback function to be passed to suspend, resume, etc., calls.
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index 4cb7447d3..8b3b5fa28 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -396,18 +396,22 @@ class XenAPIVMTestCase(test.TestCase):
def _test_spawn(self, image_ref, kernel_id, ramdisk_id,
instance_type_id="3", os_type="linux",
architecture="x86-64", instance_id=1,
- check_injection=False):
+ check_injection=False,
+ create_record=True):
stubs.stubout_loopingcall_start(self.stubs)
- values = {'id': instance_id,
- 'project_id': self.project.id,
- 'user_id': self.user.id,
- 'image_ref': image_ref,
- 'kernel_id': kernel_id,
- 'ramdisk_id': ramdisk_id,
- 'instance_type_id': instance_type_id,
- 'os_type': os_type,
- 'architecture': architecture}
- instance = db.instance_create(self.context, values)
+ if create_record:
+ values = {'id': instance_id,
+ 'project_id': self.project.id,
+ 'user_id': self.user.id,
+ 'image_ref': image_ref,
+ 'kernel_id': kernel_id,
+ 'ramdisk_id': ramdisk_id,
+ 'instance_type_id': instance_type_id,
+ 'os_type': os_type,
+ 'architecture': architecture}
+ instance = db.instance_create(self.context, values)
+ else:
+ instance = db.instance_get(self.context, instance_id)
network_info = [({'bridge': 'fa0', 'id': 0, 'injected': True},
{'broadcast': '192.168.0.255',
'dns': ['192.168.0.1'],
@@ -599,41 +603,38 @@ class XenAPIVMTestCase(test.TestCase):
# guest agent is detected
self.assertFalse(self._tee_executed)
- @test.skip_test("Never gets an address, not sure why")
def test_spawn_vlanmanager(self):
self.flags(xenapi_image_service='glance',
network_manager='nova.network.manager.VlanManager',
- network_driver='nova.network.xenapi_net',
vlan_interface='fake0')
def dummy(*args, **kwargs):
pass
- self.stubs.Set(VMOps, 'create_vifs', dummy)
+ self.stubs.Set(vmops.VMOps, 'create_vifs', dummy)
# Reset network table
xenapi_fake.reset_table('network')
# Instance id = 2 will use vlan network (see db/fakes.py)
ctxt = self.context.elevated()
- instance_ref = self._create_instance(2)
- network_bk = self.network
- # Ensure we use xenapi_net driver
- self.network = utils.import_object(FLAGS.network_manager)
+ instance = self._create_instance(2, False)
networks = self.network.db.network_get_all(ctxt)
for network in networks:
- self.network.set_network_host(ctxt, network['id'])
-
- self.network.allocate_for_instance(ctxt, instance_id=instance_ref.id,
- instance_type_id=1, project_id=self.project.id)
- self.network.setup_compute_network(ctxt, instance_ref.id)
+ self.network.set_network_host(ctxt, network)
+
+ self.network.allocate_for_instance(ctxt,
+ instance_id=2,
+ host=FLAGS.host,
+ vpn=None,
+ instance_type_id=1,
+ project_id=self.project.id)
self._test_spawn(glance_stubs.FakeGlance.IMAGE_MACHINE,
glance_stubs.FakeGlance.IMAGE_KERNEL,
glance_stubs.FakeGlance.IMAGE_RAMDISK,
- instance_id=instance_ref.id,
+ instance_id=2,
create_record=False)
# TODO(salvatore-orlando): a complete test here would require
# a check for making sure the bridge for the VM's VIF is
# consistent with bridge specified in nova db
- self.network = network_bk
def test_spawn_with_network_qos(self):
self._create_instance()
@@ -644,10 +645,10 @@ class XenAPIVMTestCase(test.TestCase):
str(3 * 1024))
def test_rescue(self):
- self.flags(xenapi_inject_image=False)
+ self.flags(flat_injected=False)
instance = self._create_instance()
conn = xenapi_conn.get_connection(False)
- conn.rescue(instance, None)
+ conn.rescue(instance, None, [])
def test_unrescue(self):
instance = self._create_instance()
@@ -663,7 +664,7 @@ class XenAPIVMTestCase(test.TestCase):
self.vm = None
self.stubs.UnsetAll()
- def _create_instance(self, instance_id=1):
+ def _create_instance(self, instance_id=1, spawn=True):
"""Creates and spawns a test instance."""
stubs.stubout_loopingcall_start(self.stubs)
values = {
@@ -691,7 +692,8 @@ class XenAPIVMTestCase(test.TestCase):
'label': 'fake',
'mac': 'DE:AD:BE:EF:00:00',
'rxtx_cap': 3})]
- self.conn.spawn(instance, network_info)
+ if spawn:
+ self.conn.spawn(instance, network_info)
return instance
diff --git a/nova/tests/vmwareapi/db_fakes.py b/nova/tests/vmwareapi/db_fakes.py
index d4eb87daf..afd672c7a 100644
--- a/nova/tests/vmwareapi/db_fakes.py
+++ b/nova/tests/vmwareapi/db_fakes.py
@@ -70,8 +70,8 @@ def stub_out_db_instance_api(stubs):
'launch_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()),
'instance_type': values['instance_type'],
'memory_mb': type_data['memory_mb'],
- 'mac_address': values['mac_address'],
'vcpus': type_data['vcpus'],
+ 'mac_addresses': [{'address': values['mac_address']}],
'local_gb': type_data['local_gb'],
}
return FakeModel(base_options)
@@ -83,6 +83,8 @@ def stub_out_db_instance_api(stubs):
'bridge': 'vmnet0',
'netmask': '255.255.255.0',
'gateway': '10.10.10.1',
+ 'broadcast': '10.10.10.255',
+ 'dns1': 'fake',
'vlan': 100}
return FakeModel(fields)
@@ -90,7 +92,7 @@ def stub_out_db_instance_api(stubs):
"""Stubs out the db.instance_action_create method."""
pass
- def fake_instance_get_fixed_address(context, instance_id):
+ def fake_instance_get_fixed_addresses(context, instance_id):
"""Stubs out the db.instance_get_fixed_address method."""
return '10.10.10.10'
@@ -103,7 +105,7 @@ def stub_out_db_instance_api(stubs):
stubs.Set(db, 'instance_create', fake_instance_create)
stubs.Set(db, 'network_get_by_instance', fake_network_get_by_instance)
stubs.Set(db, 'instance_action_create', fake_instance_action_create)
- stubs.Set(db, 'instance_get_fixed_address',
- fake_instance_get_fixed_address)
+ stubs.Set(db, 'instance_get_fixed_addresses',
+ fake_instance_get_fixed_addresses)
stubs.Set(db, 'instance_type_get_all', fake_instance_type_get_all)
stubs.Set(db, 'instance_type_get_by_name', fake_instance_type_get_by_name)
diff --git a/nova/tests/vmwareapi/stubs.py b/nova/tests/vmwareapi/stubs.py
index a648efb16..0ed5e9b68 100644
--- a/nova/tests/vmwareapi/stubs.py
+++ b/nova/tests/vmwareapi/stubs.py
@@ -22,6 +22,8 @@ Stubouts for the test suite
from nova.virt import vmwareapi_conn
from nova.virt.vmwareapi import fake
from nova.virt.vmwareapi import vmware_images
+from nova.virt.vmwareapi import vmops
+from nova.virt.vmwareapi import network_utils
def fake_get_vim_object(arg):
@@ -36,11 +38,16 @@ def fake_is_vim_object(arg, module):
def set_stubs(stubs):
"""Set the stubs."""
+ stubs.Set(vmops.VMWareVMOps, 'plug_vifs', fake.fake_plug_vifs)
+ stubs.Set(network_utils, 'get_network_with_the_name',
+ fake.fake_get_network)
stubs.Set(vmware_images, 'fetch_image', fake.fake_fetch_image)
stubs.Set(vmware_images, 'get_vmdk_size_and_properties',
fake.fake_get_vmdk_size_and_properties)
stubs.Set(vmware_images, 'upload_image', fake.fake_upload_image)
stubs.Set(vmwareapi_conn.VMWareAPISession, "_get_vim_object",
fake_get_vim_object)
+ stubs.Set(vmwareapi_conn.VMWareAPISession, "_get_vim_object",
+ fake_get_vim_object)
stubs.Set(vmwareapi_conn.VMWareAPISession, "_is_vim_object",
fake_is_vim_object)
diff --git a/nova/virt/driver.py b/nova/virt/driver.py
index 178279d31..34dc5f544 100644
--- a/nova/virt/driver.py
+++ b/nova/virt/driver.py
@@ -61,11 +61,11 @@ class ComputeDriver(object):
"""Return a list of InstanceInfo for all registered VMs"""
raise NotImplementedError()
- def spawn(self, instance, network_info=None, block_device_mapping=None):
+ def spawn(self, instance, network_info, block_device_mapping=None):
"""Launch a VM for the specified instance"""
raise NotImplementedError()
- def destroy(self, instance, cleanup=True):
+ def destroy(self, instance, network_info, cleanup=True):
"""Destroy (shutdown and delete) the specified instance.
The given parameter is an instance of nova.compute.service.Instance,
@@ -81,7 +81,7 @@ class ComputeDriver(object):
"""
raise NotImplementedError()
- def reboot(self, instance):
+ def reboot(self, instance, network_info):
"""Reboot specified VM"""
raise NotImplementedError()
@@ -146,11 +146,11 @@ class ComputeDriver(object):
"""resume the specified instance"""
raise NotImplementedError()
- def rescue(self, instance, callback):
+ def rescue(self, instance, callback, network_info):
"""Rescue the specified instance"""
raise NotImplementedError()
- def unrescue(self, instance, callback):
+ def unrescue(self, instance, callback, network_info):
"""Unrescue the specified instance"""
raise NotImplementedError()
@@ -224,7 +224,7 @@ class ComputeDriver(object):
"""
raise NotImplementedError()
- def unfilter_instance(self, instance):
+ def unfilter_instance(self, instance, network_info):
"""Stop filtering instance"""
raise NotImplementedError()
@@ -253,3 +253,7 @@ class ComputeDriver(object):
def set_host_enabled(self, host, enabled):
"""Sets the specified host's ability to accept new instances."""
raise NotImplementedError()
+
+ def plug_vifs(self, instance, network_info):
+ """Plugs in VIFs to networks."""
+ raise NotImplementedError()
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index ea0a59f21..26bc421c0 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -167,7 +167,7 @@ class FakeConnection(driver.ComputeDriver):
"""
pass
- def reboot(self, instance):
+ def reboot(self, instance, network_info):
"""
Reboot the specified instance.
@@ -240,13 +240,13 @@ class FakeConnection(driver.ComputeDriver):
"""
pass
- def rescue(self, instance):
+ def rescue(self, instance, callback, network_info):
"""
Rescue the specified instance.
"""
pass
- def unrescue(self, instance):
+ def unrescue(self, instance, callback, network_info):
"""
Unrescue the specified instance.
"""
@@ -293,7 +293,7 @@ class FakeConnection(driver.ComputeDriver):
"""
pass
- def destroy(self, instance):
+ def destroy(self, instance, network_info):
key = instance.name
if key in self.instances:
del self.instances[key]
@@ -499,7 +499,7 @@ class FakeConnection(driver.ComputeDriver):
"""This method is supported only by libvirt."""
return
- def unfilter_instance(self, instance_ref):
+ def unfilter_instance(self, instance_ref, network_info=None):
"""This method is supported only by libvirt."""
raise NotImplementedError('This method is supported only by libvirt.')
diff --git a/nova/virt/hyperv.py b/nova/virt/hyperv.py
index 5c1dc772d..81c7dea58 100644
--- a/nova/virt/hyperv.py
+++ b/nova/virt/hyperv.py
@@ -139,7 +139,7 @@ class HyperVConnection(driver.ComputeDriver):
return instance_infos
- def spawn(self, instance, network_info=None, block_device_mapping=None):
+ def spawn(self, instance, network_info, block_device_mapping=None):
""" Create a new VM and start it."""
vm = self._lookup(instance.name)
if vm is not None:
@@ -368,14 +368,14 @@ class HyperVConnection(driver.ComputeDriver):
wmi_obj.Properties_.Item(prop).Value
return newinst
- def reboot(self, instance):
+ def reboot(self, instance, network_info):
"""Reboot the specified instance."""
vm = self._lookup(instance.name)
if vm is None:
raise exception.InstanceNotFound(instance_id=instance.id)
self._set_vm_state(instance.name, 'Reboot')
- def destroy(self, instance):
+ def destroy(self, instance, network_info):
"""Destroy the VM. Also destroy the associated VHD disk files"""
LOG.debug(_("Got request to destroy vm %s"), instance.name)
vm = self._lookup(instance.name)
diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template
index e1a683da8..a75636390 100644
--- a/nova/virt/libvirt.xml.template
+++ b/nova/virt/libvirt.xml.template
@@ -82,9 +82,13 @@
</disk>
#end if
#for $vol in $volumes
- <disk type='block'>
+ <disk type='${vol.type}'>
<driver type='raw'/>
+ #if $vol.type == 'network'
+ <source protocol='${vol.protocol}' name='${vol.name}'/>
+ #else
<source dev='${vol.device_path}'/>
+ #end if
<target dev='${vol.mount_device}' bus='${disk_bus}'/>
</disk>
#end for
@@ -92,6 +96,22 @@
#end if
#for $nic in $nics
+ #if $vif_type == 'ethernet'
+ <interface type='ethernet'>
+ <target dev='${nic.name}' />
+ <mac address='${nic.mac_address}' />
+ <script path='${nic.script}' />
+ </interface>
+ #else if $vif_type == '802.1Qbh'
+ <interface type='direct'>
+ <mac address='${nic.mac_address}'/>
+ <source dev='${nic.device_name}' mode='private'/>
+ <virtualport type='802.1Qbh'>
+ <parameters profileid='${nic.profile_name}'/>
+ </virtualport>
+ <model type='virtio'/>
+ </interface>
+ #else
<interface type='bridge'>
<source bridge='${nic.bridge_name}'/>
<mac address='${nic.mac_address}'/>
@@ -107,6 +127,8 @@
#end if
</filterref>
</interface>
+ #end if
+
#end for
<!-- The order is significant here. File must be defined first -->
<serial type="file">
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index 4905d931a..c27e92feb 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -123,6 +123,11 @@ flags.DEFINE_string('qemu_img', 'qemu-img',
'binary to use for qemu-img commands')
flags.DEFINE_bool('start_guests_on_host_boot', False,
'Whether to restart guests when the host reboots')
+flags.DEFINE_string('libvirt_vif_type', 'bridge',
+ 'Type of VIF to create.')
+flags.DEFINE_string('libvirt_vif_driver',
+ 'nova.virt.libvirt.vif.LibvirtBridgeDriver',
+ 'The libvirt VIF driver to configure the VIFs.')
def get_connection(read_only):
@@ -165,6 +170,7 @@ class LibvirtConnection(driver.ComputeDriver):
fw_class = utils.import_class(FLAGS.firewall_driver)
self.firewall_driver = fw_class(get_connection=self._get_connection)
+ self.vif_driver = utils.import_object(FLAGS.libvirt_vif_driver)
def init_host(self, host):
# Adopt existing VM's running here
@@ -256,7 +262,12 @@ class LibvirtConnection(driver.ComputeDriver):
infos.append(info)
return infos
- def destroy(self, instance, cleanup=True):
+ def plug_vifs(self, instance, network_info):
+ """Plugin VIFs into networks."""
+ for (network, mapping) in network_info:
+ self.vif_driver.plug(instance, network, mapping)
+
+ def destroy(self, instance, network_info, cleanup=True):
instance_name = instance['name']
try:
@@ -300,6 +311,9 @@ class LibvirtConnection(driver.ComputeDriver):
locals())
raise
+ for (network, mapping) in network_info:
+ self.vif_driver.unplug(instance, network, mapping)
+
def _wait_for_destroy():
"""Called at an interval until the VM is gone."""
instance_name = instance['name']
@@ -314,7 +328,8 @@ class LibvirtConnection(driver.ComputeDriver):
timer = utils.LoopingCall(_wait_for_destroy)
timer.start(interval=0.5, now=True)
- self.firewall_driver.unfilter_instance(instance)
+ self.firewall_driver.unfilter_instance(instance,
+ network_info=network_info)
if cleanup:
self._cleanup(instance)
@@ -335,24 +350,20 @@ class LibvirtConnection(driver.ComputeDriver):
def attach_volume(self, instance_name, device_path, mountpoint):
virt_dom = self._lookup_by_name(instance_name)
mount_device = mountpoint.rpartition("/")[2]
- if device_path.startswith('/dev/'):
+ (type, protocol, name) = \
+ self._get_volume_device_info(device_path)
+ if type == 'block':
xml = """<disk type='block'>
<driver name='qemu' type='raw'/>
<source dev='%s'/>
<target dev='%s' bus='virtio'/>
</disk>""" % (device_path, mount_device)
- elif ':' in device_path:
- (protocol, name) = device_path.split(':')
+ elif type == 'network':
xml = """<disk type='network'>
<driver name='qemu' type='raw'/>
<source protocol='%s' name='%s'/>
<target dev='%s' bus='virtio'/>
- </disk>""" % (protocol,
- name,
- mount_device)
- else:
- raise exception.InvalidDevicePath(path=device_path)
-
+ </disk>""" % (protocol, name, mount_device)
virt_dom.attachDevice(xml)
def _get_disk_xml(self, xml, device):
@@ -461,7 +472,7 @@ class LibvirtConnection(driver.ComputeDriver):
shutil.rmtree(temp_dir)
@exception.wrap_exception()
- def reboot(self, instance):
+ def reboot(self, instance, network_info):
"""Reboot a virtual machine, given an instance reference.
This method actually destroys and re-creates the domain to ensure the
@@ -476,7 +487,8 @@ class LibvirtConnection(driver.ComputeDriver):
# NOTE(itoumsn): self.shutdown() and wait instead of self.destroy() is
# better because we cannot ensure flushing dirty buffers
# in the guest OS. But, in case of KVM, shutdown() does not work...
- self.destroy(instance, False)
+ self.destroy(instance, network_info, cleanup=False)
+ self.plug_vifs(instance, network_info)
self.firewall_driver.setup_basic_filtering(instance)
self.firewall_driver.prepare_instance_filter(instance)
self._create_new_domain(xml)
@@ -526,7 +538,7 @@ class LibvirtConnection(driver.ComputeDriver):
dom.create()
@exception.wrap_exception()
- def rescue(self, instance):
+ def rescue(self, instance, callback, network_info):
"""Loads a VM using rescue images.
A rescue is normally performed when something goes wrong with the
@@ -535,7 +547,7 @@ class LibvirtConnection(driver.ComputeDriver):
data recovery.
"""
- self.destroy(instance, False)
+ self.destroy(instance, network_info, cleanup=False)
xml = self.to_xml(instance, rescue=True)
rescue_images = {'image_id': FLAGS.rescue_image_id,
@@ -564,14 +576,14 @@ class LibvirtConnection(driver.ComputeDriver):
return timer.start(interval=0.5, now=True)
@exception.wrap_exception()
- def unrescue(self, instance):
+ def unrescue(self, instance, network_info):
"""Reboot the VM which is being rescued back into primary images.
Because reboot destroys and re-creates instances, unresue should
simply call reboot.
"""
- self.reboot(instance)
+ self.reboot(instance, network_info)
@exception.wrap_exception()
def poll_rescued_instances(self, timeout):
@@ -580,7 +592,7 @@ class LibvirtConnection(driver.ComputeDriver):
# NOTE(ilyaalekseyev): Implementation like in multinics
# for xenapi(tr3buchet)
@exception.wrap_exception()
- def spawn(self, instance, network_info=None, block_device_mapping=None):
+ def spawn(self, instance, network_info, block_device_mapping=None):
xml = self.to_xml(instance, False, network_info=network_info,
block_device_mapping=block_device_mapping)
block_device_mapping = block_device_mapping or []
@@ -881,9 +893,12 @@ class LibvirtConnection(driver.ComputeDriver):
address = mapping['ips'][0]['ip']
netmask = mapping['ips'][0]['netmask']
address_v6 = None
+ gateway_v6 = None
+ netmask_v6 = None
if FLAGS.use_ipv6:
address_v6 = mapping['ip6s'][0]['ip']
netmask_v6 = mapping['ip6s'][0]['netmask']
+ gateway_v6 = mapping['gateway6']
net_info = {'name': 'eth%d' % ifc_num,
'address': address,
'netmask': netmask,
@@ -891,7 +906,7 @@ class LibvirtConnection(driver.ComputeDriver):
'broadcast': mapping['broadcast'],
'dns': mapping['dns'],
'address_v6': address_v6,
- 'gateway6': mapping['gateway6'],
+ 'gateway6': gateway_v6,
'netmask_v6': netmask_v6}
nets.append(net_info)
@@ -926,40 +941,6 @@ class LibvirtConnection(driver.ComputeDriver):
if FLAGS.libvirt_type == 'uml':
utils.execute('sudo', 'chown', 'root', basepath('disk'))
- def _get_nic_for_xml(self, network, mapping):
- # Assume that the gateway also acts as the dhcp server.
- dhcp_server = mapping['gateway']
- gateway6 = mapping.get('gateway6')
- mac_id = mapping['mac'].replace(':', '')
-
- if FLAGS.allow_project_net_traffic:
- template = "<parameter name=\"%s\"value=\"%s\" />\n"
- net, mask = netutils.get_net_and_mask(network['cidr'])
- values = [("PROJNET", net), ("PROJMASK", mask)]
- if FLAGS.use_ipv6:
- net_v6, prefixlen_v6 = netutils.get_net_and_prefixlen(
- network['cidr_v6'])
- values.extend([("PROJNETV6", net_v6),
- ("PROJMASKV6", prefixlen_v6)])
-
- extra_params = "".join([template % value for value in values])
- else:
- extra_params = "\n"
-
- result = {
- 'id': mac_id,
- 'bridge_name': network['bridge'],
- 'mac_address': mapping['mac'],
- 'ip_address': mapping['ips'][0]['ip'],
- 'dhcp_server': dhcp_server,
- 'extra_params': extra_params,
- }
-
- if gateway6:
- result['gateway6'] = gateway6 + "/128"
-
- return result
-
root_mount_device = 'vda' # FIXME for now. it's hard coded.
local_mount_device = 'vdb' # FIXME for now. it's hard coded.
@@ -971,6 +952,15 @@ class LibvirtConnection(driver.ComputeDriver):
return True
return False
+ def _get_volume_device_info(self, device_path):
+ if device_path.startswith('/dev/'):
+ return ('block', None, None)
+ elif ':' in device_path:
+ (protocol, name) = device_path.split(':')
+ return ('network', protocol, name)
+ else:
+ raise exception.InvalidDevicePath(path=device_path)
+
def _prepare_xml_info(self, instance, rescue=False, network_info=None,
block_device_mapping=None):
block_device_mapping = block_device_mapping or []
@@ -981,7 +971,7 @@ class LibvirtConnection(driver.ComputeDriver):
nics = []
for (network, mapping) in network_info:
- nics.append(self._get_nic_for_xml(network, mapping))
+ nics.append(self.vif_driver.plug(instance, network, mapping))
# FIXME(vish): stick this in db
inst_type_id = instance['instance_type_id']
inst_type = instance_types.get_instance_type(inst_type_id)
@@ -993,6 +983,9 @@ class LibvirtConnection(driver.ComputeDriver):
for vol in block_device_mapping:
vol['mount_device'] = _strip_dev(vol['mount_device'])
+ (vol['type'], vol['protocol'], vol['name']) = \
+ self._get_volume_device_info(vol['device_path'])
+
ebs_root = self._volume_in_mapping(self.root_mount_device,
block_device_mapping)
if self._volume_in_mapping(self.local_mount_device,
@@ -1010,6 +1003,7 @@ class LibvirtConnection(driver.ComputeDriver):
'rescue': rescue,
'local': local_gb,
'driver_type': driver_type,
+ 'vif_type': FLAGS.libvirt_vif_type,
'nics': nics,
'ebs_root': ebs_root,
'volumes': block_device_mapping}
@@ -1579,9 +1573,10 @@ class LibvirtConnection(driver.ComputeDriver):
timer.f = wait_for_live_migration
timer.start(interval=0.5, now=True)
- def unfilter_instance(self, instance_ref):
+ def unfilter_instance(self, instance_ref, network_info):
"""See comments of same method in firewall_driver."""
- self.firewall_driver.unfilter_instance(instance_ref)
+ self.firewall_driver.unfilter_instance(instance_ref,
+ network_info=network_info)
def update_host_status(self):
"""See xenapi_conn.py implementation."""
diff --git a/nova/virt/libvirt/firewall.py b/nova/virt/libvirt/firewall.py
index 379197398..9ce57b6c9 100644
--- a/nova/virt/libvirt/firewall.py
+++ b/nova/virt/libvirt/firewall.py
@@ -46,7 +46,7 @@ class FirewallDriver(object):
At this point, the instance isn't running yet."""
raise NotImplementedError()
- def unfilter_instance(self, instance):
+ def unfilter_instance(self, instance, network_info=None):
"""Stop filtering instance"""
raise NotImplementedError()
@@ -300,9 +300,10 @@ class NWFilterFirewall(FirewallDriver):
# execute in a native thread and block current greenthread until done
tpool.execute(self._conn.nwfilterDefineXML, xml)
- def unfilter_instance(self, instance):
+ def unfilter_instance(self, instance, network_info=None):
"""Clear out the nwfilter rules."""
- network_info = netutils.get_network_info(instance)
+ if not network_info:
+ network_info = netutils.get_network_info(instance)
instance_name = instance.name
for (network, mapping) in network_info:
nic_id = mapping['mac'].replace(':', '')
@@ -542,11 +543,11 @@ class IptablesFirewallDriver(FirewallDriver):
"""No-op. Everything is done in prepare_instance_filter"""
pass
- def unfilter_instance(self, instance):
+ def unfilter_instance(self, instance, network_info=None):
if self.instances.pop(instance['id'], None):
self.remove_filters_for_instance(instance)
self.iptables.apply()
- self.nwfilter.unfilter_instance(instance)
+ self.nwfilter.unfilter_instance(instance, network_info)
else:
LOG.info(_('Attempted to unfilter instance %s which is not '
'filtered'), instance['id'])
diff --git a/nova/virt/libvirt/netutils.py b/nova/virt/libvirt/netutils.py
index e5aaf7cec..a8e88fc07 100644
--- a/nova/virt/libvirt/netutils.py
+++ b/nova/virt/libvirt/netutils.py
@@ -25,6 +25,7 @@ import netaddr
from nova import context
from nova import db
+from nova import exception
from nova import flags
from nova import ipv6
from nova import utils
@@ -55,11 +56,13 @@ def get_network_info(instance):
# we should cache network_info
admin_context = context.get_admin_context()
- fixed_ips = db.fixed_ip_get_by_instance(admin_context, instance['id'])
+ try:
+ fixed_ips = db.fixed_ip_get_by_instance(admin_context, instance['id'])
+ except exception.FixedIpNotFoundForInstance:
+ fixed_ips = []
+
vifs = db.virtual_interface_get_by_instance(admin_context, instance['id'])
- networks = db.network_get_all_by_instance(admin_context,
- instance['id'])
- flavor = db.instance_type_get_by_id(admin_context,
+ flavor = db.instance_type_get(admin_context,
instance['instance_type_id'])
network_info = []
@@ -89,11 +92,17 @@ def get_network_info(instance):
'label': network['label'],
'gateway': network['gateway'],
'broadcast': network['broadcast'],
+ 'dhcp_server': network['gateway'],
'mac': vif['address'],
'rxtx_cap': flavor['rxtx_cap'],
- 'dns': [network['dns']],
+ 'dns': [],
'ips': [ip_dict(ip) for ip in network_ips]}
+ if network['dns1']:
+ mapping['dns'].append(network['dns1'])
+ if network['dns2']:
+ mapping['dns'].append(network['dns2'])
+
if FLAGS.use_ipv6:
mapping['ip6s'] = [ip6_dict()]
mapping['gateway6'] = network['gateway_v6']
diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py
new file mode 100644
index 000000000..eef582fac
--- /dev/null
+++ b/nova/virt/libvirt/vif.py
@@ -0,0 +1,134 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (C) 2011 Midokura KK
+# Copyright (C) 2011 Nicira, Inc
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""VIF drivers for libvirt."""
+
+from nova import flags
+from nova import log as logging
+from nova.network import linux_net
+from nova.virt.libvirt import netutils
+from nova import utils
+from nova.virt.vif import VIFDriver
+
+LOG = logging.getLogger('nova.virt.libvirt.vif')
+
+FLAGS = flags.FLAGS
+
+flags.DEFINE_string('libvirt_ovs_bridge', 'br-int',
+ 'Name of Integration Bridge used by Open vSwitch')
+
+
+class LibvirtBridgeDriver(VIFDriver):
+ """VIF driver for Linux bridge."""
+
+ def _get_configurations(self, network, mapping):
+ """Get a dictionary of VIF configurations for bridge type."""
+ # Assume that the gateway also acts as the dhcp server.
+ gateway6 = mapping.get('gateway6')
+ mac_id = mapping['mac'].replace(':', '')
+
+ if FLAGS.allow_project_net_traffic:
+ template = "<parameter name=\"%s\"value=\"%s\" />\n"
+ net, mask = netutils.get_net_and_mask(network['cidr'])
+ values = [("PROJNET", net), ("PROJMASK", mask)]
+ if FLAGS.use_ipv6:
+ net_v6, prefixlen_v6 = netutils.get_net_and_prefixlen(
+ network['cidr_v6'])
+ values.extend([("PROJNETV6", net_v6),
+ ("PROJMASKV6", prefixlen_v6)])
+
+ extra_params = "".join([template % value for value in values])
+ else:
+ extra_params = "\n"
+
+ result = {
+ 'id': mac_id,
+ 'bridge_name': network['bridge'],
+ 'mac_address': mapping['mac'],
+ 'ip_address': mapping['ips'][0]['ip'],
+ 'dhcp_server': mapping['dhcp_server'],
+ 'extra_params': extra_params,
+ }
+
+ if gateway6:
+ result['gateway6'] = gateway6 + "/128"
+
+ return result
+
+ def plug(self, instance, network, mapping):
+ """Ensure that the bridge exists, and add VIF to it."""
+ if (not network.get('multi_host') and
+ mapping.get('should_create_bridge')):
+ if mapping.get('should_create_vlan'):
+ LOG.debug(_('Ensuring vlan %(vlan)s and bridge %(bridge)s'),
+ {'vlan': network['vlan'],
+ 'bridge': network['bridge']})
+ linux_net.ensure_vlan_bridge(network['vlan'],
+ network['bridge'],
+ network['bridge_interface'])
+ else:
+ LOG.debug(_("Ensuring bridge %s"), network['bridge'])
+ linux_net.ensure_bridge(network['bridge'],
+ network['bridge_interface'])
+
+ return self._get_configurations(network, mapping)
+
+ def unplug(self, instance, network, mapping):
+ """No manual unplugging required."""
+ pass
+
+
+class LibvirtOpenVswitchDriver(VIFDriver):
+ """VIF driver for Open vSwitch."""
+
+ def plug(self, instance, network, mapping):
+ vif_id = str(instance['id']) + "-" + str(network['id'])
+ dev = "tap-%s" % vif_id
+ iface_id = "nova-" + vif_id
+ if not linux_net._device_exists(dev):
+ utils.execute('sudo', 'ip', 'tuntap', 'add', dev, 'mode', 'tap')
+ utils.execute('sudo', 'ip', 'link', 'set', dev, 'up')
+ utils.execute('sudo', 'ovs-vsctl', '--', '--may-exist', 'add-port',
+ FLAGS.libvirt_ovs_bridge, dev,
+ '--', 'set', 'Interface', dev,
+ "external-ids:iface-id=%s" % iface_id,
+ '--', 'set', 'Interface', dev,
+ "external-ids:iface-status=active",
+ '--', 'set', 'Interface', dev,
+ "external-ids:attached-mac=%s" % mapping['mac'])
+
+ result = {
+ 'script': '',
+ 'name': dev,
+ 'mac_address': mapping['mac']}
+ return result
+
+ def unplug(self, instance, network, mapping):
+ """Unplug the VIF from the network by deleting the port from
+ the bridge."""
+ vif_id = str(instance['id']) + "-" + str(network['id'])
+ dev = "tap-%s" % vif_id
+ try:
+ utils.execute('sudo', 'ovs-vsctl', 'del-port',
+ network['bridge'], dev)
+ utils.execute('sudo', 'ip', 'link', 'delete', dev)
+ except:
+ LOG.warning(_("Failed while unplugging vif of instance '%s'"),
+ instance['name'])
+ raise
diff --git a/nova/virt/vif.py b/nova/virt/vif.py
new file mode 100644
index 000000000..b78689957
--- /dev/null
+++ b/nova/virt/vif.py
@@ -0,0 +1,30 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (C) 2011 Midokura KK
+# 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.
+
+"""VIF module common to all virt layers."""
+
+
+class VIFDriver(object):
+ """Abstract class that defines generic interfaces for all VIF drivers."""
+
+ def plug(self, instance, network, mapping):
+ """Plug VIF into network."""
+ raise NotImplementedError()
+
+ def unplug(self, instance, network, mapping):
+ """Unplug VIF from network."""
+ raise NotImplementedError()
diff --git a/nova/virt/vmwareapi/fake.py b/nova/virt/vmwareapi/fake.py
index 7370684bd..4c62d18bb 100644
--- a/nova/virt/vmwareapi/fake.py
+++ b/nova/virt/vmwareapi/fake.py
@@ -402,6 +402,16 @@ def _remove_file(file_path):
lst_files.remove(file)
+def fake_plug_vifs(*args, **kwargs):
+ """Fakes plugging vifs."""
+ pass
+
+
+def fake_get_network(*args, **kwargs):
+ """Fake get network."""
+ return [{'type': 'fake'}]
+
+
def fake_fetch_image(image, instance, **kwargs):
"""Fakes fetch image call. Just adds a reference to the db for the file."""
ds_name = kwargs.get("datastore_name")
diff --git a/nova/virt/vmwareapi/network_utils.py b/nova/virt/vmwareapi/network_utils.py
index e77842535..ec3b93fe7 100644
--- a/nova/virt/vmwareapi/network_utils.py
+++ b/nova/virt/vmwareapi/network_utils.py
@@ -45,10 +45,31 @@ def get_network_with_the_name(session, network_name="vmnet0"):
networks = session._call_method(vim_util,
"get_properties_for_a_collection_of_objects",
"Network", vm_networks, ["summary.name"])
- for network in networks:
- if network.propSet[0].val == network_name:
- return network.obj
- return None
+ network_obj = {}
+ LOG.warn(vm_networks)
+ for network in vm_networks:
+ # Get network properties
+ if network._type == 'DistributedVirtualPortgroup':
+ props = session._call_method(vim_util,
+ "get_dynamic_property", network,
+ "DistributedVirtualPortgroup", "config")
+ # NOTE(asomya): This only works on ESXi if the port binding is
+ # set to ephemeral
+ if props.name == network_name:
+ network_obj['type'] = 'DistributedVirtualPortgroup'
+ network_obj['dvpg'] = props.key
+ network_obj['dvsw'] = props.distributedVirtualSwitch.value
+ else:
+ props = session._call_method(vim_util,
+ "get_dynamic_property", network,
+ "Network", "summary.name")
+ if props == network_name:
+ network_obj['type'] = 'Network'
+ network_obj['name'] = network_name
+ if (len(network_obj) > 0):
+ return network_obj
+ else:
+ return None
def get_vswitch_for_vlan_interface(session, vlan_interface):
diff --git a/nova/virt/vmwareapi/vif.py b/nova/virt/vmwareapi/vif.py
new file mode 100644
index 000000000..b3e43b209
--- /dev/null
+++ b/nova/virt/vmwareapi/vif.py
@@ -0,0 +1,95 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2011 Citrix Systems, Inc.
+# Copyright 2011 OpenStack LLC.
+#
+# 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.
+
+"""VIF drivers for VMWare."""
+
+from nova import db
+from nova import exception
+from nova import flags
+from nova import log as logging
+from nova import utils
+from nova.virt.vif import VIFDriver
+from nova.virt.vmwareapi_conn import VMWareAPISession
+from nova.virt.vmwareapi import network_utils
+
+
+LOG = logging.getLogger("nova.virt.vmwareapi.vif")
+
+FLAGS = flags.FLAGS
+
+
+class VMWareVlanBridgeDriver(VIFDriver):
+ """VIF Driver to setup bridge/VLAN networking using VMWare API."""
+
+ def plug(self, instance, network, mapping):
+ """Create a vlan and bridge unless they already exist."""
+ vlan_num = network['vlan']
+ bridge = network['bridge']
+ bridge_interface = network['bridge_interface']
+
+ # Open vmwareapi session
+ host_ip = FLAGS.vmwareapi_host_ip
+ host_username = FLAGS.vmwareapi_host_username
+ host_password = FLAGS.vmwareapi_host_password
+ if not host_ip or host_username is None or host_password is None:
+ raise Exception(_('Must specify vmwareapi_host_ip, '
+ 'vmwareapi_host_username '
+ 'and vmwareapi_host_password to use '
+ 'connection_type=vmwareapi'))
+ session = VMWareAPISession(host_ip, host_username, host_password,
+ FLAGS.vmwareapi_api_retry_count)
+ vlan_interface = bridge_interface
+ # Check if the vlan_interface physical network adapter exists on the
+ # host.
+ if not network_utils.check_if_vlan_interface_exists(session,
+ vlan_interface):
+ raise exception.NetworkAdapterNotFound(adapter=vlan_interface)
+
+ # Get the vSwitch associated with the Physical Adapter
+ vswitch_associated = network_utils.get_vswitch_for_vlan_interface(
+ session, vlan_interface)
+ if vswitch_associated is None:
+ raise exception.SwicthNotFoundForNetworkAdapter(
+ adapter=vlan_interface)
+ # Check whether bridge already exists and retrieve the the ref of the
+ # network whose name_label is "bridge"
+ network_ref = network_utils.get_network_with_the_name(session, bridge)
+ if network_ref is None:
+ # Create a port group on the vSwitch associated with the
+ # vlan_interface corresponding physical network adapter on the ESX
+ # host.
+ network_utils.create_port_group(session, bridge,
+ vswitch_associated, vlan_num)
+ else:
+ # Get the vlan id and vswitch corresponding to the port group
+ pg_vlanid, pg_vswitch = \
+ network_utils.get_vlanid_and_vswitch_for_portgroup(session,
+ bridge)
+
+ # Check if the vswitch associated is proper
+ if pg_vswitch != vswitch_associated:
+ raise exception.InvalidVLANPortGroup(
+ bridge=bridge, expected=vswitch_associated,
+ actual=pg_vswitch)
+
+ # Check if the vlan id is proper for the port group
+ if pg_vlanid != vlan_num:
+ raise exception.InvalidVLANTag(bridge=bridge, tag=vlan_num,
+ pgroup=pg_vlanid)
+
+ def unplug(self, instance, network, mapping):
+ pass
diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py
index 1638149f1..82b5f7214 100644
--- a/nova/virt/vmwareapi/vm_util.py
+++ b/nova/virt/vmwareapi/vm_util.py
@@ -40,7 +40,7 @@ def split_datastore_path(datastore_path):
def get_vm_create_spec(client_factory, instance, data_store_name,
network_name="vmnet0",
- os_type="otherGuest"):
+ os_type="otherGuest", network_ref=None):
"""Builds the VM Create spec."""
config_spec = client_factory.create('ns0:VirtualMachineConfigSpec')
config_spec.name = instance.name
@@ -93,7 +93,8 @@ def create_controller_spec(client_factory, key):
return virtual_device_config
-def create_network_spec(client_factory, network_name, mac_address):
+def create_network_spec(client_factory, network_name, mac_address,
+ network_ref=None):
"""
Builds a config spec for the addition of a new network
adapter to the VM.
@@ -105,9 +106,25 @@ def create_network_spec(client_factory, network_name, mac_address):
# Get the recommended card type for the VM based on the guest OS of the VM
net_device = client_factory.create('ns0:VirtualPCNet32')
- backing = \
- client_factory.create('ns0:VirtualEthernetCardNetworkBackingInfo')
- backing.deviceName = network_name
+ # NOTE(asomya): Only works on ESXi if the portgroup binding is set to
+ # ephemeral. Invalid configuration if set to static and the NIC does
+ # not come up on boot if set to dynamic.
+ backing = None
+ if (network_ref and
+ network_ref['type'] == "DistributedVirtualPortgroup"):
+ backing_name = \
+ 'ns0:VirtualEthernetCardDistributedVirtualPortBackingInfo'
+ backing = \
+ client_factory.create(backing_name)
+ portgroup = \
+ client_factory.create('ns0:DistributedVirtualSwitchPortConnection')
+ portgroup.switchUuid = network_ref['dvsw']
+ portgroup.portgroupKey = network_ref['dvpg']
+ backing.port = portgroup
+ else:
+ backing = \
+ client_factory.create('ns0:VirtualEthernetCardNetworkBackingInfo')
+ backing.deviceName = network_name
connectable_spec = \
client_factory.create('ns0:VirtualDeviceConnectInfo')
@@ -278,9 +295,11 @@ def get_dummy_vm_create_spec(client_factory, name, data_store_name):
return config_spec
-def get_machine_id_change_spec(client_factory, mac, ip_addr, netmask, gateway):
+def get_machine_id_change_spec(client_factory, mac, ip_addr, netmask,
+ gateway, broadcast, dns):
"""Builds the machine id change config spec."""
- machine_id_str = "%s;%s;%s;%s" % (mac, ip_addr, netmask, gateway)
+ machine_id_str = "%s;%s;%s;%s;%s;%s" % (mac, ip_addr, netmask,
+ gateway, broadcast, dns)
virtual_machine_config_spec = \
client_factory.create('ns0:VirtualMachineConfigSpec')
diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py
index 94d9e6226..1ee8fa1c0 100644
--- a/nova/virt/vmwareapi/vmops.py
+++ b/nova/virt/vmwareapi/vmops.py
@@ -31,6 +31,7 @@ from nova import db
from nova import exception
from nova import flags
from nova import log as logging
+from nova import utils
from nova.compute import power_state
from nova.virt.vmwareapi import vim_util
from nova.virt.vmwareapi import vm_util
@@ -38,6 +39,10 @@ from nova.virt.vmwareapi import vmware_images
from nova.virt.vmwareapi import network_utils
FLAGS = flags.FLAGS
+flags.DEFINE_string('vmware_vif_driver',
+ 'nova.virt.vmwareapi.vif.VMWareVlanBridgeDriver',
+ 'The VMWare VIF driver to configure the VIFs.')
+
LOG = logging.getLogger("nova.virt.vmwareapi.vmops")
VMWARE_POWER_STATES = {
@@ -52,6 +57,7 @@ class VMWareVMOps(object):
def __init__(self, session):
"""Initializer."""
self._session = session
+ self._vif_driver = utils.import_object(FLAGS.vmware_vif_driver)
def _wait_with_callback(self, instance_id, task, callback):
"""Waits for the task to finish and does a callback after."""
@@ -83,7 +89,7 @@ class VMWareVMOps(object):
LOG.debug(_("Got total of %s instances") % str(len(lst_vm_names)))
return lst_vm_names
- def spawn(self, instance):
+ def spawn(self, instance, network_info):
"""
Creates a VM instance.
@@ -116,8 +122,10 @@ class VMWareVMOps(object):
net_name)
if network_ref is None:
raise exception.NetworkNotFoundForBridge(bridge=net_name)
+ return network_ref
- _check_if_network_bridge_exists()
+ self.plug_vifs(instance, network_info)
+ network_obj = _check_if_network_bridge_exists()
def _get_datastore_ref():
"""Get the datastore list and choose the first local storage."""
@@ -175,8 +183,10 @@ class VMWareVMOps(object):
vm_folder_mor, res_pool_mor = _get_vmfolder_and_res_pool_mors()
# Get the create vm config spec
- config_spec = vm_util.get_vm_create_spec(client_factory, instance,
- data_store_name, net_name, os_type)
+ config_spec = vm_util.get_vm_create_spec(
+ client_factory, instance,
+ data_store_name, net_name, os_type,
+ network_obj)
def _execute_create_vm():
"""Create VM on ESX host."""
@@ -472,11 +482,14 @@ class VMWareVMOps(object):
_clean_temp_data()
- def reboot(self, instance):
+ def reboot(self, instance, network_info):
"""Reboot a VM instance."""
vm_ref = self._get_vm_ref_from_the_name(instance.name)
if vm_ref is None:
raise exception.InstanceNotFound(instance_id=instance.id)
+
+ self.plug_vifs(instance, network_info)
+
lst_properties = ["summary.guest.toolsStatus", "runtime.powerState",
"summary.guest.toolsRunningStatus"]
props = self._session._call_method(vim_util, "get_object_properties",
@@ -514,7 +527,7 @@ class VMWareVMOps(object):
self._session._wait_for_task(instance.id, reset_task)
LOG.debug(_("Did hard reboot of VM %s") % instance.name)
- def destroy(self, instance):
+ def destroy(self, instance, network_info):
"""
Destroy a VM instance. Steps followed are:
1. Power off the VM, if it is in poweredOn state.
@@ -560,6 +573,8 @@ class VMWareVMOps(object):
LOG.warn(_("In vmwareapi:vmops:destroy, got this exception"
" while un-registering the VM: %s") % str(excep))
+ self._unplug_vifs(instance, network_info)
+
# Delete the folder holding the VM related content on
# the datastore.
try:
@@ -718,20 +733,25 @@ class VMWareVMOps(object):
net_mask = network["netmask"]
gateway = network["gateway"]
+ broadcast = network["broadcast"]
+ # TODO(vish): add support for dns2
+ dns = network["dns1"]
+
addresses = db.instance_get_fixed_addresses(admin_context,
instance['id'])
ip_addr = addresses[0] if addresses else None
- machine_id_chanfge_spec = \
+ machine_id_change_spec = \
vm_util.get_machine_id_change_spec(client_factory, mac_address,
- ip_addr, net_mask, gateway)
+ ip_addr, net_mask, gateway,
+ broadcast, dns)
LOG.debug(_("Reconfiguring VM instance %(name)s to set the machine id "
"with ip - %(ip_addr)s") %
({'name': instance.name,
'ip_addr': ip_addr}))
reconfig_task = self._session._call_method(self._session._get_vim(),
"ReconfigVM_Task", vm_ref,
- spec=machine_id_chanfge_spec)
+ spec=machine_id_change_spec)
self._session._wait_for_task(instance.id, reconfig_task)
LOG.debug(_("Reconfigured VM instance %(name)s to set the machine id "
"with ip - %(ip_addr)s") %
@@ -784,3 +804,13 @@ class VMWareVMOps(object):
if vm.propSet[0].val == vm_name:
return vm.obj
return None
+
+ def plug_vifs(self, instance, network_info):
+ """Plug VIFs into networks."""
+ for (network, mapping) in network_info:
+ self._vif_driver.plug(instance, network, mapping)
+
+ def _unplug_vifs(self, instance, network_info):
+ """Unplug VIFs from networks."""
+ for (network, mapping) in network_info:
+ self._vif_driver.unplug(instance, network, mapping)
diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py
index d80e14931..ce57847b2 100644
--- a/nova/virt/vmwareapi_conn.py
+++ b/nova/virt/vmwareapi_conn.py
@@ -124,21 +124,21 @@ class VMWareESXConnection(driver.ComputeDriver):
"""List VM instances."""
return self._vmops.list_instances()
- def spawn(self, instance, network_info=None, block_device_mapping=None):
+ def spawn(self, instance, network_info, block_device_mapping=None):
"""Create VM instance."""
- self._vmops.spawn(instance)
+ self._vmops.spawn(instance, network_info)
def snapshot(self, instance, name):
"""Create snapshot from a running VM instance."""
self._vmops.snapshot(instance, name)
- def reboot(self, instance):
+ def reboot(self, instance, network_info):
"""Reboot VM instance."""
- self._vmops.reboot(instance)
+ self._vmops.reboot(instance, network_info)
- def destroy(self, instance):
+ def destroy(self, instance, network_info):
"""Destroy VM instance."""
- self._vmops.destroy(instance)
+ self._vmops.destroy(instance, network_info)
def pause(self, instance, callback):
"""Pause VM instance."""
@@ -194,6 +194,10 @@ class VMWareESXConnection(driver.ComputeDriver):
"""Sets the specified host's ability to accept new instances."""
pass
+ def plug_vifs(self, instance, network_info):
+ """Plugs in VIFs to networks."""
+ self._vmops.plug_vifs(instance, network_info)
+
class VMWareAPISession(object):
"""
diff --git a/nova/virt/xenapi/vif.py b/nova/virt/xenapi/vif.py
new file mode 100644
index 000000000..527602243
--- /dev/null
+++ b/nova/virt/xenapi/vif.py
@@ -0,0 +1,140 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2011 Citrix Systems, Inc.
+# Copyright 2011 OpenStack LLC.
+# Copyright (C) 2011 Nicira, Inc
+# 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.
+
+"""VIF drivers for XenAPI."""
+
+from nova import flags
+from nova import log as logging
+from nova.virt.vif import VIFDriver
+from nova.virt.xenapi.network_utils import NetworkHelper
+
+FLAGS = flags.FLAGS
+flags.DEFINE_string('xenapi_ovs_integration_bridge', 'xapi1',
+ 'Name of Integration Bridge used by Open vSwitch')
+
+LOG = logging.getLogger("nova.virt.xenapi.vif")
+
+
+class XenAPIBridgeDriver(VIFDriver):
+ """VIF Driver for XenAPI that uses XenAPI to create Networks."""
+
+ def plug(self, xenapi_session, vm_ref, instance, device, network,
+ network_mapping):
+ if network_mapping.get('should_create_vlan'):
+ network_ref = self.ensure_vlan_bridge(xenapi_session, network)
+ else:
+ network_ref = NetworkHelper.find_network_with_bridge(
+ xenapi_session, network['bridge'])
+ rxtx_cap = network_mapping.pop('rxtx_cap')
+ vif_rec = {}
+ vif_rec['device'] = str(device)
+ vif_rec['network'] = network_ref
+ vif_rec['VM'] = vm_ref
+ vif_rec['MAC'] = network_mapping['mac']
+ vif_rec['MTU'] = '1500'
+ vif_rec['other_config'] = {}
+ vif_rec['qos_algorithm_type'] = "ratelimit" if rxtx_cap else ''
+ vif_rec['qos_algorithm_params'] = \
+ {"kbps": str(rxtx_cap * 1024)} if rxtx_cap else {}
+ return vif_rec
+
+ def ensure_vlan_bridge(self, xenapi_session, network):
+ """Ensure that a VLAN bridge exists"""
+
+ vlan_num = network['vlan']
+ bridge = network['bridge']
+ bridge_interface = network['bridge_interface']
+ # Check whether bridge already exists
+ # Retrieve network whose name_label is "bridge"
+ network_ref = NetworkHelper.find_network_with_name_label(
+ xenapi_session, bridge)
+ if network_ref is None:
+ # If bridge does not exists
+ # 1 - create network
+ description = 'network for nova bridge %s' % bridge
+ network_rec = {'name_label': bridge,
+ 'name_description': description,
+ 'other_config': {}}
+ network_ref = xenapi_session.call_xenapi('network.create',
+ network_rec)
+ # 2 - find PIF for VLAN NOTE(salvatore-orlando): using double
+ # quotes inside single quotes as xapi filter only support
+ # tokens in double quotes
+ expr = 'field "device" = "%s" and \
+ field "VLAN" = "-1"' % bridge_interface
+ pifs = xenapi_session.call_xenapi('PIF.get_all_records_where',
+ expr)
+ pif_ref = None
+ # Multiple PIF are ok: we are dealing with a pool
+ if len(pifs) == 0:
+ raise Exception(_('Found no PIF for device %s') % \
+ bridge_interface)
+ for pif_ref in pifs.keys():
+ xenapi_session.call_xenapi('VLAN.create',
+ pif_ref,
+ str(vlan_num),
+ network_ref)
+ else:
+ # Check VLAN tag is appropriate
+ network_rec = xenapi_session.call_xenapi('network.get_record',
+ network_ref)
+ # Retrieve PIFs from network
+ for pif_ref in network_rec['PIFs']:
+ # Retrieve VLAN from PIF
+ pif_rec = xenapi_session.call_xenapi('PIF.get_record',
+ pif_ref)
+ pif_vlan = int(pif_rec['VLAN'])
+ # Raise an exception if VLAN != vlan_num
+ if pif_vlan != vlan_num:
+ raise Exception(_(
+ "PIF %(pif_rec['uuid'])s for network "
+ "%(bridge)s has VLAN id %(pif_vlan)d. "
+ "Expected %(vlan_num)d") % locals())
+
+ return network_ref
+
+ def unplug(self, instance, network, mapping):
+ pass
+
+
+class XenAPIOpenVswitchDriver(VIFDriver):
+ """VIF driver for Open vSwitch with XenAPI."""
+
+ def plug(self, xenapi_session, vm_ref, instance, device, network,
+ network_mapping):
+ # with OVS model, always plug into an OVS integration bridge
+ # that is already created
+ network_ref = NetworkHelper.find_network_with_bridge(xenapi_session,
+ FLAGS.xenapi_ovs_integration_bridge)
+ vif_rec = {}
+ vif_rec['device'] = str(device)
+ vif_rec['network'] = network_ref
+ vif_rec['VM'] = vm_ref
+ vif_rec['MAC'] = network_mapping['mac']
+ vif_rec['MTU'] = '1500'
+ vif_id = "nova-" + str(instance['id']) + "-" + str(network['id'])
+ vif_rec['qos_algorithm_type'] = ""
+ vif_rec['qos_algorithm_params'] = {}
+ # OVS on the hypervisor monitors this key and uses it to
+ # set the iface-id attribute
+ vif_rec['other_config'] = {"nicira-iface-id": vif_id}
+ return vif_rec
+
+ def unplug(self, instance, network, mapping):
+ pass
diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py
index 71107aff4..62863c6d8 100644
--- a/nova/virt/xenapi/vm_utils.py
+++ b/nova/virt/xenapi/vm_utils.py
@@ -283,28 +283,6 @@ class VMHelper(HelperBase):
raise StorageError(_('Unable to destroy VDI %s') % vdi_ref)
@classmethod
- def create_vif(cls, session, vm_ref, network_ref, mac_address,
- dev, rxtx_cap=0):
- """Create a VIF record. Returns a Deferred that gives the new
- VIF reference."""
- vif_rec = {}
- vif_rec['device'] = str(dev)
- vif_rec['network'] = network_ref
- vif_rec['VM'] = vm_ref
- vif_rec['MAC'] = mac_address
- vif_rec['MTU'] = '1500'
- vif_rec['other_config'] = {}
- vif_rec['qos_algorithm_type'] = "ratelimit" if rxtx_cap else ''
- vif_rec['qos_algorithm_params'] = \
- {"kbps": str(rxtx_cap * 1024)} if rxtx_cap else {}
- LOG.debug(_('Creating VIF for VM %(vm_ref)s,'
- ' network %(network_ref)s.') % locals())
- vif_ref = session.call_xenapi('VIF.create', vif_rec)
- LOG.debug(_('Created VIF %(vif_ref)s for VM %(vm_ref)s,'
- ' network %(network_ref)s.') % locals())
- return vif_ref
-
- @classmethod
def create_vdi(cls, session, sr_ref, name_label, virtual_size, read_only):
"""Create a VDI record and returns its reference."""
vdi_ref = session.get_xenapi().VDI.create(
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index c332c27b0..2640e1ba2 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -52,6 +52,9 @@ FLAGS = flags.FLAGS
flags.DEFINE_integer('windows_version_timeout', 300,
'number of seconds to wait for windows agent to be '
'fully operational')
+flags.DEFINE_string('xenapi_vif_driver',
+ 'nova.virt.xenapi.vif.XenAPIBridgeDriver',
+ 'The XenAPI VIF driver using XenServer Network APIs.')
def cmp_version(a, b):
@@ -78,6 +81,7 @@ class VMOps(object):
self._session = session
self.poll_rescue_last_ran = None
VMHelper.XenAPI = self.XenAPI
+ self.vif_driver = utils.import_object(FLAGS.xenapi_vif_driver)
def list_instances(self):
"""List VM instances."""
@@ -251,11 +255,11 @@ class VMOps(object):
userdevice += 1
# Alter the image before VM start for, e.g. network injection
- if FLAGS.xenapi_inject_image:
+ if FLAGS.flat_injected:
VMHelper.preconfigure_instance(self._session, instance,
first_vdi_ref, network_info)
- self.create_vifs(vm_ref, network_info)
+ self.create_vifs(vm_ref, instance, network_info)
self.inject_network_info(instance, network_info, vm_ref)
return vm_ref
@@ -340,6 +344,7 @@ class VMOps(object):
_check_agent_version()
_inject_files()
_set_admin_password()
+ self.reset_network(instance, vm_ref)
return True
except Exception, exc:
LOG.warn(exc)
@@ -349,9 +354,6 @@ class VMOps(object):
timer.f = _wait_for_boot
- # call to reset network to configure network from xenstore
- self.reset_network(instance, vm_ref)
-
return timer.start(interval=0.5, now=True)
def _handle_spawn_error(self, vdis, spawn_error):
@@ -469,7 +471,7 @@ class VMOps(object):
self._session, instance, template_vdi_uuids, image_id)
finally:
if template_vm_ref:
- self._destroy(instance, template_vm_ref,
+ self._destroy(instance, template_vm_ref, None,
shutdown=False, destroy_kernel_ramdisk=False)
logging.debug(_("Finished snapshot and upload for VM %s"), instance)
@@ -839,7 +841,7 @@ class VMOps(object):
self._session.call_xenapi("Async.VM.destroy", rescue_vm_ref)
- def destroy(self, instance):
+ def destroy(self, instance, network_info):
"""Destroy VM instance.
This is the method exposed by xenapi_conn.destroy(). The rest of the
@@ -849,9 +851,9 @@ class VMOps(object):
instance_id = instance.id
LOG.info(_("Destroying VM for Instance %(instance_id)s") % locals())
vm_ref = VMHelper.lookup(self._session, instance.name)
- return self._destroy(instance, vm_ref, shutdown=True)
+ return self._destroy(instance, vm_ref, network_info, shutdown=True)
- def _destroy(self, instance, vm_ref, shutdown=True,
+ def _destroy(self, instance, vm_ref, network_info, shutdown=True,
destroy_kernel_ramdisk=True):
"""Destroys VM instance by performing:
@@ -873,6 +875,10 @@ class VMOps(object):
self._destroy_kernel_ramdisk(instance, vm_ref)
self._destroy_vm(instance, vm_ref)
+ if network_info:
+ for (network, mapping) in network_info:
+ self.vif_driver.unplug(instance, network, mapping)
+
def _wait_with_callback(self, instance_id, task, callback):
ret = None
try:
@@ -1068,7 +1074,7 @@ class VMOps(object):
# catch KeyError for domid if instance isn't running
pass
- def create_vifs(self, vm_ref, network_info):
+ def create_vifs(self, vm_ref, instance, network_info):
"""Creates vifs for an instance."""
logging.debug(_("creating vif(s) for vm: |%s|"), vm_ref)
@@ -1077,14 +1083,19 @@ class VMOps(object):
self._session.get_xenapi().VM.get_record(vm_ref)
for device, (network, info) in enumerate(network_info):
- mac_address = info['mac']
- bridge = network['bridge']
- rxtx_cap = info.pop('rxtx_cap')
- network_ref = \
- NetworkHelper.find_network_with_bridge(self._session,
- bridge)
- VMHelper.create_vif(self._session, vm_ref, network_ref,
- mac_address, device, rxtx_cap)
+ vif_rec = self.vif_driver.plug(self._session,
+ vm_ref, instance, device, network, info)
+ network_ref = vif_rec['network']
+ LOG.debug(_('Creating VIF for VM %(vm_ref)s,' \
+ ' network %(network_ref)s.') % locals())
+ vif_ref = self._session.call_xenapi('VIF.create', vif_rec)
+ LOG.debug(_('Created VIF %(vif_ref)s for VM %(vm_ref)s,'
+ ' network %(network_ref)s.') % locals())
+
+ def plug_vifs(self, instance, network_info):
+ """Set up VIF networking on the host."""
+ for (network, mapping) in network_info:
+ self.vif_driver.plug(self._session, instance, network, mapping)
def reset_network(self, instance, vm_ref=None):
"""Creates uuid arg to pass to make_agent_call and calls it."""
diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py
index ec8c44c1c..cddb8203b 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -112,22 +112,15 @@ flags.DEFINE_integer('xenapi_vhd_coalesce_max_attempts',
5,
'Max number of times to poll for VHD to coalesce.'
' Used only if connection_type=xenapi.')
-flags.DEFINE_bool('xenapi_inject_image',
- True,
- 'Specifies whether an attempt to inject network/key'
- ' data into the disk image should be made.'
- ' Used only if connection_type=xenapi.')
flags.DEFINE_string('xenapi_agent_path',
'usr/sbin/xe-update-networking',
'Specifies the path in which the xenapi guest agent'
' should be located. If the agent is present,'
' network configuration is not injected into the image'
' Used only if connection_type=xenapi.'
- ' and xenapi_inject_image=True')
-
+ ' and flat_injected=True')
flags.DEFINE_string('xenapi_sr_base_path', '/var/run/sr-mount',
'Base path to the storage repository')
-
flags.DEFINE_string('target_host',
None,
'iSCSI Target Host')
@@ -210,7 +203,7 @@ class XenAPIConnection(driver.ComputeDriver):
""" Create snapshot from a running VM instance """
self._vmops.snapshot(instance, image_id)
- def reboot(self, instance):
+ def reboot(self, instance, network_info):
"""Reboot VM instance"""
self._vmops.reboot(instance)
@@ -224,9 +217,9 @@ class XenAPIConnection(driver.ComputeDriver):
"""
self._vmops.inject_file(instance, b64_path, b64_contents)
- def destroy(self, instance):
+ def destroy(self, instance, network_info):
"""Destroy VM instance"""
- self._vmops.destroy(instance)
+ self._vmops.destroy(instance, network_info)
def pause(self, instance, callback):
"""Pause VM instance"""
@@ -249,11 +242,11 @@ class XenAPIConnection(driver.ComputeDriver):
"""resume the specified instance"""
self._vmops.resume(instance, callback)
- def rescue(self, instance, callback):
+ def rescue(self, instance, callback, network_info):
"""Rescue the specified instance"""
self._vmops.rescue(instance, callback)
- def unrescue(self, instance, callback):
+ def unrescue(self, instance, callback, network_info):
"""Unrescue the specified instance"""
self._vmops.unrescue(instance, callback)
@@ -269,6 +262,9 @@ class XenAPIConnection(driver.ComputeDriver):
"""inject network info for specified instance"""
self._vmops.inject_network_info(instance, network_info)
+ def plug_vifs(self, instance_ref, network_info):
+ self._vmops.plug_vifs(instance_ref, network_info)
+
def get_info(self, instance_id):
"""Return data about VM instance"""
return self._vmops.get_info(instance_id)
@@ -322,7 +318,7 @@ class XenAPIConnection(driver.ComputeDriver):
"""This method is supported only by libvirt."""
return
- def unfilter_instance(self, instance_ref):
+ def unfilter_instance(self, instance_ref, network_info):
"""This method is supported only by libvirt."""
raise NotImplementedError('This method is supported only by libvirt.')
diff --git a/nova/volume/api.py b/nova/volume/api.py
index cfc274c77..52b3a9fed 100644
--- a/nova/volume/api.py
+++ b/nova/volume/api.py
@@ -52,7 +52,7 @@ class API(base.Base):
if quota.allowed_volumes(context, 1, size) < 1:
pid = context.project_id
- LOG.warn(_("Quota exceeeded for %(pid)s, tried to create"
+ LOG.warn(_("Quota exceeded for %(pid)s, tried to create"
" %(size)sG volume") % locals())
raise quota.QuotaError(_("Volume quota exceeded. You cannot "
"create a volume of size %sG") % size)
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
index 288ccc78a..d609a88ab 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
@@ -72,7 +72,9 @@ def key_init(self, arg_dict):
info to be passed, such as passwords. Returns the shared
secret key value.
"""
- pub = int(arg_dict["pub"])
+ # WARNING: Some older Windows agents will crash if the public key isn't
+ # a string
+ pub = arg_dict["pub"]
arg_dict["value"] = json.dumps({"name": "keyinit", "value": pub})
request_id = arg_dict["id"]
arg_dict["path"] = "data/host/%s" % request_id
diff --git a/po/ast.po b/po/ast.po
index be9910a2c..ac6190424 100644
--- a/po/ast.po
+++ b/po/ast.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-03-19 06:18+0000\n"
-"X-Generator: Launchpad (build 12559)\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:11+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
#: ../nova/scheduler/chance.py:37 ../nova/scheduler/zone.py:55
#: ../nova/scheduler/simple.py:75 ../nova/scheduler/simple.py:110
diff --git a/po/cs.po b/po/cs.po
index 7c69e2f79..33f7808a5 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-03-19 06:18+0000\n"
-"X-Generator: Launchpad (build 12559)\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:11+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
#: ../nova/scheduler/chance.py:37 ../nova/scheduler/zone.py:55
#: ../nova/scheduler/simple.py:75 ../nova/scheduler/simple.py:110
diff --git a/po/da.po b/po/da.po
index d24d89fd9..5aead53c3 100644
--- a/po/da.po
+++ b/po/da.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-03-19 06:18+0000\n"
-"X-Generator: Launchpad (build 12559)\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
#: ../nova/scheduler/chance.py:37 ../nova/scheduler/zone.py:55
#: ../nova/scheduler/simple.py:75 ../nova/scheduler/simple.py:110
diff --git a/po/de.po b/po/de.po
index 8b4a00d72..cf40a0f5e 100644
--- a/po/de.po
+++ b/po/de.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: nova\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-02-21 10:03-0500\n"
-"PO-Revision-Date: 2011-04-03 19:42+0000\n"
-"Last-Translator: Matthias Loidolt <kedapperdrake@googlemail.com>\n"
+"PO-Revision-Date: 2011-06-06 07:58+0000\n"
+"Last-Translator: Christian Berendt <Unknown>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-04-04 05:19+0000\n"
-"X-Generator: Launchpad (build 12559)\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
#: ../nova/scheduler/chance.py:37 ../nova/scheduler/zone.py:55
#: ../nova/scheduler/simple.py:75 ../nova/scheduler/simple.py:110
@@ -85,6 +85,7 @@ msgstr ""
#, python-format
msgid "%(param)s property not found for image %(_image_id)s"
msgstr ""
+"Die Property %(param)s konnte im Image %(_image_id)s nicht gefunden werden"
#: ../nova/api/openstack/servers.py:168
msgid "No keypairs defined"
@@ -141,12 +142,12 @@ msgstr "PID-Datei %s existiert nicht. Läuft der Daemon nicht?\n"
#: ../nova/twistd.py:221
msgid "No such process"
-msgstr ""
+msgstr "Kein passender Prozess gefunden"
#: ../nova/twistd.py:230 ../nova/service.py:224
#, python-format
msgid "Serving %s"
-msgstr ""
+msgstr "Bedient %s"
#: ../nova/twistd.py:262 ../nova/service.py:225
msgid "Full set of FLAGS:"
@@ -183,12 +184,13 @@ msgstr ""
#: ../nova/virt/xenapi/volumeops.py:91
#, python-format
msgid "Unable to attach volume to instance %s"
-msgstr ""
+msgstr "Nicht möglich Volumen zur Instanze %s hinzuzufügen"
#: ../nova/virt/xenapi/volumeops.py:93
#, python-format
msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s"
msgstr ""
+"Einhängepunkt%(mountpoint)s zur Instanze %(instance_name)s hinzugefügt"
#. Detach VBD from VM
#: ../nova/virt/xenapi/volumeops.py:104
@@ -199,7 +201,7 @@ msgstr ""
#: ../nova/virt/xenapi/volumeops.py:112
#, python-format
msgid "Unable to locate volume %s"
-msgstr ""
+msgstr "Nicht möglich volume %s zufinden"
#: ../nova/virt/xenapi/volumeops.py:120
#, python-format
@@ -214,7 +216,7 @@ msgstr ""
#: ../nova/compute/instance_types.py:41
#, python-format
msgid "Unknown instance type: %s"
-msgstr ""
+msgstr "Unbekannter Instanztyp: %s"
#: ../nova/crypto.py:46
msgid "Filename of root CA"
@@ -230,7 +232,7 @@ msgstr "Dateiname der Certificate Revocation List"
#: ../nova/crypto.py:53
msgid "Where we keep our keys"
-msgstr ""
+msgstr "Wo wir unsere Schlüssel aufbewahren"
#: ../nova/crypto.py:55
msgid "Where we keep our root CA"
@@ -298,12 +300,12 @@ msgstr ""
#: ../nova/compute/manager.py:179
msgid "Instance has already been created"
-msgstr ""
+msgstr "Instanz wurde bereits erstellt"
#: ../nova/compute/manager.py:180
#, python-format
msgid "instance %s: starting..."
-msgstr ""
+msgstr "Instanz %s startet..."
#. pylint: disable=W0702
#: ../nova/compute/manager.py:219
@@ -314,7 +316,7 @@ msgstr ""
#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286
#, python-format
msgid "Terminating instance %s"
-msgstr ""
+msgstr "Beende Instanz %s"
#: ../nova/compute/manager.py:255
#, python-format
@@ -377,7 +379,7 @@ msgstr ""
#: ../nova/compute/manager.py:372
#, python-format
msgid "instance %s: rescuing"
-msgstr ""
+msgstr "Instanz %s: Rettung"
#: ../nova/compute/manager.py:387
#, python-format
@@ -387,12 +389,12 @@ msgstr ""
#: ../nova/compute/manager.py:406
#, python-format
msgid "instance %s: pausing"
-msgstr ""
+msgstr "Instanz %s pausiert"
#: ../nova/compute/manager.py:423
#, python-format
msgid "instance %s: unpausing"
-msgstr ""
+msgstr "Instanz %s wird fortgesetzt"
#: ../nova/compute/manager.py:440
#, python-format
@@ -584,7 +586,7 @@ msgstr ""
#: ../nova/virt/connection.py:73
msgid "Failed to open connection to the hypervisor"
-msgstr ""
+msgstr "Konnte Verbindung zum Hypervisor nicht öffnen"
#: ../nova/network/linux_net.py:187
#, python-format
@@ -637,7 +639,7 @@ msgstr "Klasse %s konnte nicht gefunden werden"
#: ../nova/utils.py:118
#, python-format
msgid "Fetching %s"
-msgstr ""
+msgstr "Hole %s"
#: ../nova/utils.py:130
#, python-format
@@ -2562,7 +2564,7 @@ msgstr ""
#: ../nova/auth/manager.py:270
#, python-format
msgid "Using project name = user name (%s)"
-msgstr ""
+msgstr "Verwende Project-Name = User-Name (%s)"
#: ../nova/auth/manager.py:277
#, python-format
@@ -2572,7 +2574,7 @@ msgstr ""
#: ../nova/auth/manager.py:279
#, python-format
msgid "No project called %s could be found"
-msgstr ""
+msgstr "Es konnte kein Projekt mit dem Namen %s gefunden werden"
#: ../nova/auth/manager.py:287
#, python-format
@@ -2696,6 +2698,7 @@ msgstr ""
#: ../nova/service.py:195
msgid "The service database object disappeared, Recreating it."
msgstr ""
+"Das Service-Datenbank-Objekt ist verschwunden, es wird erneut erzeugt."
#: ../nova/service.py:207
msgid "Recovered model server connection!"
@@ -2723,7 +2726,7 @@ msgstr ""
#: ../nova/auth/ldapdriver.py:472
#, python-format
msgid "Group can't be created because group %s already exists"
-msgstr ""
+msgstr "Die Gruppe %s kann nicht angelegt werde, da sie bereits existiert"
#: ../nova/auth/ldapdriver.py:478
#, python-format
@@ -2739,6 +2742,7 @@ msgstr ""
#, python-format
msgid "User %s can't be added to the group because the user doesn't exist"
msgstr ""
+"Der User %s kann nicht zur Gruppe hinzugefügt werde, da er nicht existiert"
#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521
#, python-format
@@ -2755,6 +2759,7 @@ msgstr ""
msgid ""
"User %s can't be removed from the group because the user doesn't exist"
msgstr ""
+"Der User %s kann nicht aus der Gruppe entfernt werden, da er nicht existiert"
#: ../nova/auth/ldapdriver.py:528
#, python-format
@@ -2840,7 +2845,7 @@ msgstr ""
#: ../nova/api/ec2/admin.py:200
#, python-format
msgid "Delete project: %s"
-msgstr ""
+msgstr "Lösche Projekt %s"
#: ../nova/api/ec2/admin.py:214
#, python-format
diff --git a/po/en_AU.po b/po/en_AU.po
new file mode 100644
index 000000000..e53f9fc07
--- /dev/null
+++ b/po/en_AU.po
@@ -0,0 +1,2848 @@
+# English (Australia) translation for nova
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the nova package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: nova\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-02-21 10:03-0500\n"
+"PO-Revision-Date: 2011-06-30 10:30+0000\n"
+"Last-Translator: Benny <Benjamin.Donald.Wilson.K@gmail.com>\n"
+"Language-Team: English (Australia) <en_AU@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
+
+#: ../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
+msgid "No hosts found"
+msgstr "No hosts found"
+
+#: ../nova/exception.py:33
+msgid "Unexpected error while running command."
+msgstr ""
+
+#: ../nova/exception.py:36
+#, python-format
+msgid ""
+"%(description)s\n"
+"Command: %(cmd)s\n"
+"Exit code: %(exit_code)s\n"
+"Stdout: %(stdout)r\n"
+"Stderr: %(stderr)r"
+msgstr ""
+
+#: ../nova/exception.py:107
+msgid "DB exception wrapped"
+msgstr ""
+
+#. exc_type, exc_value, exc_traceback = sys.exc_info()
+#: ../nova/exception.py:120
+msgid "Uncaught exception"
+msgstr ""
+
+#: ../nova/volume/api.py:45
+#, python-format
+msgid "Quota exceeeded for %(pid)s, tried to create %(size)sG volume"
+msgstr ""
+
+#: ../nova/volume/api.py:47
+#, python-format
+msgid "Volume quota exceeded. You cannot create a volume of size %sG"
+msgstr ""
+
+#: ../nova/volume/api.py:71 ../nova/volume/api.py:96
+msgid "Volume status must be available"
+msgstr ""
+
+#: ../nova/volume/api.py:98
+msgid "Volume is already attached"
+msgstr ""
+
+#: ../nova/volume/api.py:104
+msgid "Volume is already detached"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:72
+msgid "Failed to read private ip"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:79
+msgid "Failed to read public ip(s)"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:152
+#, python-format
+msgid "%(param)s property not found for image %(_image_id)s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:168
+msgid "No keypairs defined"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:238
+#, python-format
+msgid "Compute.api::lock %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:253
+#, python-format
+msgid "Compute.api::unlock %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:267
+#, python-format
+msgid "Compute.api::get_lock %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:281
+#, python-format
+msgid "Compute.api::reset_network %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:292
+#, python-format
+msgid "Compute.api::pause %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:303
+#, python-format
+msgid "Compute.api::unpause %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:314
+#, python-format
+msgid "compute.api::suspend %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:325
+#, python-format
+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
+#, python-format
+msgid "Instance %s not found"
+msgstr ""
+
+#. NOTE: No Resource Pool concept so far
+#: ../nova/virt/xenapi/volumeops.py:51
+#, python-format
+msgid "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:69
+#, python-format
+msgid "Unable to create VDI on SR %(sr_ref)s for instance %(instance_name)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:80
+#, python-format
+msgid "Unable to use SR %(sr_ref)s for instance %(instance_name)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:91
+#, python-format
+msgid "Unable to attach volume to instance %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:93
+#, python-format
+msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s"
+msgstr ""
+
+#. Detach VBD from VM
+#: ../nova/virt/xenapi/volumeops.py:104
+#, python-format
+msgid "Detach_volume: %(instance_name)s, %(mountpoint)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:112
+#, python-format
+msgid "Unable to locate volume %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:120
+#, python-format
+msgid "Unable to detach volume %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:127
+#, python-format
+msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s"
+msgstr ""
+
+#: ../nova/compute/instance_types.py:41
+#, python-format
+msgid "Unknown instance type: %s"
+msgstr ""
+
+#: ../nova/crypto.py:46
+msgid "Filename of root CA"
+msgstr ""
+
+#: ../nova/crypto.py:49
+msgid "Filename of private key"
+msgstr ""
+
+#: ../nova/crypto.py:51
+msgid "Filename of root Certificate Revokation List"
+msgstr ""
+
+#: ../nova/crypto.py:53
+msgid "Where we keep our keys"
+msgstr ""
+
+#: ../nova/crypto.py:55
+msgid "Where we keep our root CA"
+msgstr ""
+
+#: ../nova/crypto.py:57
+msgid "Should we use a CA for each project?"
+msgstr ""
+
+#: ../nova/crypto.py:61
+#, python-format
+msgid "Subject for certificate for users, %s for project, user, timestamp"
+msgstr ""
+
+#: ../nova/crypto.py:66
+#, python-format
+msgid "Subject for certificate for projects, %s for project, timestamp"
+msgstr ""
+
+#: ../nova/crypto.py:71
+#, python-format
+msgid "Subject for certificate for vpns, %s for project, timestamp"
+msgstr ""
+
+#: ../nova/crypto.py:258
+#, python-format
+msgid "Flags path: %s"
+msgstr ""
+
+#: ../nova/scheduler/manager.py:69
+#, python-format
+msgid "Casting to %(topic)s %(host)s for %(method)s"
+msgstr ""
+
+#: ../nova/compute/manager.py:78
+#, python-format
+msgid "check_instance_lock: decorating: |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:80
+#, python-format
+msgid ""
+"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:84
+#, python-format
+msgid "check_instance_lock: locked: |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:86
+#, python-format
+msgid "check_instance_lock: admin: |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:91
+#, python-format
+msgid "check_instance_lock: executing: |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:95
+#, python-format
+msgid "check_instance_lock: not executing |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:179
+msgid "Instance has already been created"
+msgstr ""
+
+#: ../nova/compute/manager.py:180
+#, python-format
+msgid "instance %s: starting..."
+msgstr ""
+
+#. pylint: disable=W0702
+#: ../nova/compute/manager.py:219
+#, python-format
+msgid "instance %s: Failed to spawn"
+msgstr ""
+
+#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286
+#, python-format
+msgid "Terminating instance %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:255
+#, python-format
+msgid "Deallocating address %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:268
+#, python-format
+msgid "trying to destroy already destroyed instance: %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:282
+#, python-format
+msgid "Rebooting instance %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:287
+#, python-format
+msgid ""
+"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s "
+"expected: %(running)s)"
+msgstr ""
+
+#: ../nova/compute/manager.py:311
+#, python-format
+msgid "instance %s: snapshotting"
+msgstr ""
+
+#: ../nova/compute/manager.py:316
+#, python-format
+msgid ""
+"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s "
+"expected: %(running)s)"
+msgstr ""
+
+#: ../nova/compute/manager.py:332
+#, python-format
+msgid ""
+"trying to reset the password on a non-running instance: %(instance_id)s "
+"(state: %(instance_state)s expected: %(expected_state)s)"
+msgstr ""
+
+#: ../nova/compute/manager.py:335
+#, python-format
+msgid "instance %s: setting admin password"
+msgstr ""
+
+#: ../nova/compute/manager.py:353
+#, python-format
+msgid ""
+"trying to inject a file into a non-running instance: %(instance_id)s (state: "
+"%(instance_state)s expected: %(expected_state)s)"
+msgstr ""
+
+#: ../nova/compute/manager.py:362
+#, python-format
+msgid "instance %(nm)s: injecting file to %(plain_path)s"
+msgstr ""
+
+#: ../nova/compute/manager.py:372
+#, python-format
+msgid "instance %s: rescuing"
+msgstr ""
+
+#: ../nova/compute/manager.py:387
+#, python-format
+msgid "instance %s: unrescuing"
+msgstr ""
+
+#: ../nova/compute/manager.py:406
+#, python-format
+msgid "instance %s: pausing"
+msgstr ""
+
+#: ../nova/compute/manager.py:423
+#, python-format
+msgid "instance %s: unpausing"
+msgstr ""
+
+#: ../nova/compute/manager.py:440
+#, python-format
+msgid "instance %s: retrieving diagnostics"
+msgstr ""
+
+#: ../nova/compute/manager.py:453
+#, python-format
+msgid "instance %s: suspending"
+msgstr ""
+
+#: ../nova/compute/manager.py:472
+#, python-format
+msgid "instance %s: resuming"
+msgstr ""
+
+#: ../nova/compute/manager.py:491
+#, python-format
+msgid "instance %s: locking"
+msgstr ""
+
+#: ../nova/compute/manager.py:503
+#, python-format
+msgid "instance %s: unlocking"
+msgstr ""
+
+#: ../nova/compute/manager.py:513
+#, python-format
+msgid "instance %s: getting locked state"
+msgstr ""
+
+#: ../nova/compute/manager.py:526
+#, python-format
+msgid "instance %s: reset network"
+msgstr ""
+
+#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515
+#, python-format
+msgid "Get console output for instance %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:543
+#, python-format
+msgid "instance %s: getting ajax console"
+msgstr ""
+
+#: ../nova/compute/manager.py:553
+#, python-format
+msgid ""
+"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s"
+msgstr ""
+
+#. pylint: disable=W0702
+#. NOTE(vish): The inline callback eats the exception info so we
+#. log the traceback here and reraise the same
+#. ecxception below.
+#: ../nova/compute/manager.py:569
+#, python-format
+msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing"
+msgstr ""
+
+#: ../nova/compute/manager.py:585
+#, python-format
+msgid ""
+"Detach volume %(volume_id)s from mountpoint %(mp)s on instance "
+"%(instance_id)s"
+msgstr ""
+
+#: ../nova/compute/manager.py:588
+#, python-format
+msgid "Detaching volume from unknown instance %s"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:53
+#, python-format
+msgid "Host %s is not alive"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:65
+msgid "All hosts have too many cores"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:87
+#, python-format
+msgid "Host %s not available"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:99
+msgid "All hosts have too many gigabytes"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:119
+msgid "All hosts have too many networks"
+msgstr ""
+
+#: ../nova/volume/manager.py:85
+#, python-format
+msgid "Re-exporting %s volumes"
+msgstr ""
+
+#: ../nova/volume/manager.py:90
+#, python-format
+msgid "volume %s: skipping export"
+msgstr ""
+
+#: ../nova/volume/manager.py:96
+#, python-format
+msgid "volume %s: creating"
+msgstr ""
+
+#: ../nova/volume/manager.py:108
+#, python-format
+msgid "volume %(vol_name)s: creating lv of size %(vol_size)sG"
+msgstr ""
+
+#: ../nova/volume/manager.py:112
+#, python-format
+msgid "volume %s: creating export"
+msgstr ""
+
+#: ../nova/volume/manager.py:123
+#, python-format
+msgid "volume %s: created successfully"
+msgstr ""
+
+#: ../nova/volume/manager.py:131
+msgid "Volume is still attached"
+msgstr ""
+
+#: ../nova/volume/manager.py:133
+msgid "Volume is not local to this node"
+msgstr ""
+
+#: ../nova/volume/manager.py:136
+#, python-format
+msgid "volume %s: removing export"
+msgstr ""
+
+#: ../nova/volume/manager.py:138
+#, python-format
+msgid "volume %s: deleting"
+msgstr ""
+
+#: ../nova/volume/manager.py:147
+#, python-format
+msgid "volume %s: deleted successfully"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:74
+#, python-format
+msgid "%(text)s: _db_content => %(content)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:304 ../nova/virt/xenapi/fake.py:404
+#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478
+msgid "Raising NotImplemented"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:306
+#, python-format
+msgid "xenapi.fake does not have an implementation for %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:341
+#, python-format
+msgid "Calling %(localname)s %(impl)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:346
+#, python-format
+msgid "Calling getter %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:406
+#, python-format
+msgid ""
+"xenapi.fake does not have an implementation for %s or it has been called "
+"with the wrong number of arguments"
+msgstr ""
+
+#: ../nova/tests/test_cloud.py:256
+msgid "Can't test instances without a real virtual env."
+msgstr ""
+
+#: ../nova/tests/test_cloud.py:268
+#, python-format
+msgid "Need to watch instance %s until it's running..."
+msgstr ""
+
+#: ../nova/virt/connection.py:73
+msgid "Failed to open connection to the hypervisor"
+msgstr ""
+
+#: ../nova/network/linux_net.py:187
+#, python-format
+msgid "Starting VLAN inteface %s"
+msgstr ""
+
+#: ../nova/network/linux_net.py:208
+#, python-format
+msgid "Starting Bridge interface for %s"
+msgstr ""
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:314
+#, python-format
+msgid "Hupping dnsmasq threw %s"
+msgstr ""
+
+#: ../nova/network/linux_net.py:316
+#, python-format
+msgid "Pid %d is stale, relaunching dnsmasq"
+msgstr ""
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:358
+#, python-format
+msgid "killing radvd threw %s"
+msgstr ""
+
+#: ../nova/network/linux_net.py:360
+#, python-format
+msgid "Pid %d is stale, relaunching radvd"
+msgstr ""
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:449
+#, python-format
+msgid "Killing dnsmasq threw %s"
+msgstr ""
+
+#: ../nova/utils.py:58
+#, python-format
+msgid "Inner Exception: %s"
+msgstr ""
+
+#: ../nova/utils.py:59
+#, python-format
+msgid "Class %s cannot be found"
+msgstr ""
+
+#: ../nova/utils.py:118
+#, python-format
+msgid "Fetching %s"
+msgstr ""
+
+#: ../nova/utils.py:130
+#, python-format
+msgid "Running cmd (subprocess): %s"
+msgstr ""
+
+#: ../nova/utils.py:143 ../nova/utils.py:183
+#, python-format
+msgid "Result was %s"
+msgstr ""
+
+#: ../nova/utils.py:159
+#, python-format
+msgid "Running cmd (SSH): %s"
+msgstr ""
+
+#: ../nova/utils.py:217
+#, python-format
+msgid "debug in callback: %s"
+msgstr ""
+
+#: ../nova/utils.py:222
+#, python-format
+msgid "Running %s"
+msgstr ""
+
+#: ../nova/utils.py:262
+#, python-format
+msgid "Link Local address is not found.:%s"
+msgstr ""
+
+#: ../nova/utils.py:265
+#, python-format
+msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s"
+msgstr ""
+
+#: ../nova/utils.py:363
+#, python-format
+msgid "Invalid backend: %s"
+msgstr ""
+
+#: ../nova/utils.py:374
+#, python-format
+msgid "backend %s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:49
+#, python-format
+msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:54
+#, python-format
+msgid "Publishing to route %s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:84
+#, python-format
+msgid "Declaring queue %s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:90
+#, python-format
+msgid "Declaring exchange %s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:96
+#, python-format
+msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:121
+#, python-format
+msgid "Getting from %(queue)s: %(message)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:135 ../nova/virt/hyperv.py:171
+#, python-format
+msgid "Created VM %s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:138
+#, python-format
+msgid "Created VM %(instance_name)s as %(vm_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:168
+#, python-format
+msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:171
+#, python-format
+msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:187
+#, python-format
+msgid "VBD not found in instance %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:197
+#, python-format
+msgid "Unable to unplug VBD %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:209
+#, python-format
+msgid "Unable to destroy VBD %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:224
+#, python-format
+msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:227
+#, python-format
+msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:246
+#, python-format
+msgid ""
+"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on "
+"%(sr_ref)s."
+msgstr ""
+
+#. TODO(sirp): Add quiesce and VSS locking support when Windows support
+#. is added
+#: ../nova/virt/xenapi/vm_utils.py:258
+#, python-format
+msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:272
+#, python-format
+msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:286
+#, python-format
+msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:327
+#, python-format
+msgid "Size for image %(image)s:%(virtual_size)d"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:332
+#, python-format
+msgid "Glance image %s"
+msgstr ""
+
+#. we need to invoke a plugin for copying VDI's
+#. content into proper path
+#: ../nova/virt/xenapi/vm_utils.py:342
+#, python-format
+msgid "Copying VDI %s to /boot/guest on dom0"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:352
+#, python-format
+msgid "Kernel/Ramdisk VDI %s destroyed"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:361
+#, python-format
+msgid "Asking xapi to fetch %(url)s as %(access)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402
+#, python-format
+msgid "Looking up vdi %s for PV kernel"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:397
+#, python-format
+msgid "PV Kernel in VDI:%s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:405
+#, python-format
+msgid "Running pygrub against %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:411
+#, python-format
+msgid "Found Xen kernel %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:413
+msgid "No Xen kernel found. Booting HVM."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431
+#, python-format
+msgid "duplicate name found: %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:442
+#, python-format
+msgid "VDI %s is still available"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:463
+#, python-format
+msgid "(VM_UTILS) xenserver vm state -> |%s|"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:465
+#, python-format
+msgid "(VM_UTILS) xenapi power_state -> |%s|"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:525
+#, python-format
+msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:542
+#, python-format
+msgid "Re-scanning SR %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:567
+#, python-format
+msgid ""
+"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:574
+#, python-format
+msgid ""
+"Parent %(parent_uuid)s doesn't match original parent "
+"%(original_parent_uuid)s, waiting for coalesce..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:590
+#, python-format
+msgid "No VDIs found for VM %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:594
+#, python-format
+msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:653
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188
+#, python-format
+msgid "Creating VBD for VDI %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:655
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190
+#, python-format
+msgid "Creating VBD for VDI %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:657
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192
+#, python-format
+msgid "Plugging VBD %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:659
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:194
+#, python-format
+msgid "Plugging VBD %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:661
+#, python-format
+msgid "VBD %(vbd)s plugged as %(orig_dev)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:664
+#, python-format
+msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:668
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:197
+#, python-format
+msgid "Destroying VBD for VDI %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:671
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:200
+#, python-format
+msgid "Destroying VBD for VDI %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:683
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211
+msgid "VBD.unplug successful first time."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:688
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216
+msgid "VBD.unplug rejected: retrying..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:692
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220
+msgid "VBD.unplug successful eventually."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:695
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:223
+#, python-format
+msgid "Ignoring XenAPI.Failure in VBD.unplug: %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:704
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:66
+#, python-format
+msgid "Ignoring XenAPI.Failure %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:735
+#, python-format
+msgid ""
+"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:747
+#, python-format
+msgid "Writing partition table %s done."
+msgstr ""
+
+#: ../nova/tests/test_rpc.py:89
+#, python-format
+msgid "Nested received %(queue)s, %(value)s"
+msgstr ""
+
+#: ../nova/tests/test_rpc.py:95
+#, python-format
+msgid "Nested return %s"
+msgstr ""
+
+#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126
+#, python-format
+msgid "Received %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:44
+msgid "Use of empty request context is deprecated"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:133
+#, python-format
+msgid "No service for id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:251
+#, python-format
+msgid "No service for %(host)s, %(binary)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:592
+msgid "No fixed ips defined"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:608
+#, python-format
+msgid "No floating ip for address %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:629
+#, python-format
+msgid "No address for instance %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:961
+#, python-format
+msgid "no keypair for user %(user_id)s, name %(name)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156
+#, python-format
+msgid "No network for id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1086
+msgid "No networks defined"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1115
+#, python-format
+msgid "No network for bridge %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142
+#, python-format
+msgid "No network for instance %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1277
+#, python-format
+msgid "Token %s does not exist"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1302
+#, python-format
+msgid "No quota for project_id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501
+#: ../nova/api/ec2/__init__.py:323
+#, python-format
+msgid "Volume %s not found"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1514
+#, python-format
+msgid "No export device found for volume %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1527
+#, python-format
+msgid "No target id found for volume %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1572
+#, python-format
+msgid "No security group with id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1589
+#, python-format
+msgid "No security group named %(group_name)s for project: %(project_id)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1682
+#, python-format
+msgid "No secuity group rule with id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1756
+#, python-format
+msgid "No user for id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1772
+#, python-format
+msgid "No user for access key %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1834
+#, python-format
+msgid "No project with id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1979
+#, python-format
+msgid "No console pool with id %(pool_id)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1996
+#, python-format
+msgid ""
+"No console pool of type %(console_type)s for compute host %(compute_host)s "
+"on proxy host %(host)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2035
+#, python-format
+msgid "No console for instance %(instance_id)s in pool %(pool_id)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2057
+#, python-format
+msgid "on instance %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2058
+#, python-format
+msgid "No console with id %(console_id)s %(idesc)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097
+#, python-format
+msgid "No zone with id %(zone_id)s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:160
+#, python-format
+msgid "Checking state of %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:165
+#, python-format
+msgid "Current state of %(name)s was %(state)s."
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:183
+#, python-format
+msgid "Connecting to libvirt: %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:196
+msgid "Connection to libvirt broke"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:258
+#, python-format
+msgid "instance %(instance_name)s: deleting instance files %(target)s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:283
+#, python-format
+msgid "Invalid device path %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:313
+#, python-format
+msgid "No disk at %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:320
+msgid "Instance snapshotting is not supported for libvirtat this time"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:336
+#, python-format
+msgid "instance %s: rebooted"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:339
+#, python-format
+msgid "_wait_for_reboot failed: %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:382
+#, python-format
+msgid "instance %s: rescued"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:385
+#, python-format
+msgid "_wait_for_rescue failed: %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:411
+#, python-format
+msgid "instance %s: is running"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:422
+#, python-format
+msgid "instance %s: booted"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186
+#, python-format
+msgid "instance %s: failed to boot"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:436
+#, python-format
+msgid "virsh said: %r"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:440
+msgid "cool, it's a device"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:448
+#, python-format
+msgid "data: %(data)r, fpath: %(fpath)r"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:456
+#, python-format
+msgid "Contents of file %(fpath)s: %(contents)r"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:489
+msgid "Unable to find an open port"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:563
+#, python-format
+msgid "instance %s: Creating image"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:646
+#, python-format
+msgid "instance %(inst_name)s: injecting key into image %(img_id)s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:649
+#, python-format
+msgid "instance %(inst_name)s: injecting net into image %(img_id)s"
+msgstr ""
+
+#. This could be a windows image, or a vmdk format disk
+#: ../nova/virt/libvirt_conn.py:657
+#, python-format
+msgid ""
+"instance %(inst_name)s: ignoring error injecting data into image %(img_id)s "
+"(%(e)s)"
+msgstr ""
+
+#. TODO(termie): cache?
+#: ../nova/virt/libvirt_conn.py:665
+#, python-format
+msgid "instance %s: starting toXML method"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:732
+#, python-format
+msgid "instance %s: finished toXML method"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:751
+msgid "diagnostics are not supported for libvirt"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:1225
+#, python-format
+msgid "Attempted to unfilter instance %s which is not filtered"
+msgstr ""
+
+#: ../nova/api/ec2/metadatarequesthandler.py:76
+#, python-format
+msgid "Failed to get metadata for ip: %s"
+msgstr ""
+
+#: ../nova/auth/fakeldap.py:33
+msgid "Attempted to instantiate singleton"
+msgstr ""
+
+#: ../nova/network/api.py:39
+#, python-format
+msgid "Quota exceeeded for %s, tried to allocate address"
+msgstr ""
+
+#: ../nova/network/api.py:42
+msgid "Address quota exceeded. You cannot allocate any more addresses"
+msgstr ""
+
+#: ../nova/tests/test_volume.py:162
+#, python-format
+msgid "Target %s allocated"
+msgstr ""
+
+#: ../nova/virt/images.py:70
+#, python-format
+msgid "Finished retreving %(url)s -- placed in %(path)s"
+msgstr ""
+
+#: ../nova/scheduler/driver.py:66
+msgid "Must implement a fallback schedule"
+msgstr ""
+
+#: ../nova/console/manager.py:70
+msgid "Adding console"
+msgstr ""
+
+#: ../nova/console/manager.py:90
+#, python-format
+msgid "Tried to remove non-existant console %(console_id)s."
+msgstr ""
+
+#: ../nova/api/direct.py:149
+msgid "not available"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:62
+#, python-format
+msgid "The key_pair %s already exists"
+msgstr ""
+
+#. TODO(vish): Do this with M2Crypto instead
+#: ../nova/api/ec2/cloud.py:118
+#, python-format
+msgid "Generating root CA: %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:303
+#, python-format
+msgid "Create key pair %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:311
+#, python-format
+msgid "Delete key pair %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:386
+#, python-format
+msgid "%s is not a valid ipProtocol"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:390
+msgid "Invalid port range"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:421
+#, python-format
+msgid "Revoke security group ingress %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459
+msgid "Not enough parameters to build a valid rule."
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:443
+msgid "No rule for the specified parameters."
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:450
+#, python-format
+msgid "Authorize security group ingress %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:464
+#, python-format
+msgid "This rule already exists in group %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:492
+#, python-format
+msgid "Create Security Group %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:495
+#, python-format
+msgid "group %s already exists"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:507
+#, python-format
+msgid "Delete security group %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:584
+#, python-format
+msgid "Create volume of %s GB"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:612
+#, python-format
+msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:629
+#, python-format
+msgid "Detach volume %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:761
+msgid "Allocate address"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:766
+#, python-format
+msgid "Release address %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:771
+#, python-format
+msgid "Associate address %(public_ip)s to instance %(instance_id)s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:780
+#, python-format
+msgid "Disassociate address %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:807
+msgid "Going to start terminating instances"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:815
+#, python-format
+msgid "Reboot instance %r"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:867
+#, python-format
+msgid "De-registering image %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:875
+#, python-format
+msgid "Registered image %(image_location)s with id %(image_id)s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900
+#, python-format
+msgid "attribute not supported: %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:890
+#, python-format
+msgid "invalid id: %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:903
+msgid "user or group not specified"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:905
+msgid "only group \"all\" is supported"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:907
+msgid "operation_type must be add or remove"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:908
+#, python-format
+msgid "Updating image %s publicity"
+msgstr ""
+
+#: ../bin/nova-api.py:52
+#, python-format
+msgid "Using paste.deploy config at: %s"
+msgstr ""
+
+#: ../bin/nova-api.py:57
+#, python-format
+msgid "No paste configuration for app: %s"
+msgstr ""
+
+#: ../bin/nova-api.py:59
+#, python-format
+msgid ""
+"App Config: %(api)s\n"
+"%(config)r"
+msgstr ""
+
+#: ../bin/nova-api.py:64
+#, python-format
+msgid "Running %s API"
+msgstr ""
+
+#: ../bin/nova-api.py:69
+#, python-format
+msgid "No known API applications configured in %s."
+msgstr ""
+
+#: ../bin/nova-api.py:83
+#, python-format
+msgid "Starting nova-api node (version %s)"
+msgstr ""
+
+#: ../bin/nova-api.py:89
+#, python-format
+msgid "No paste configuration found for: %s"
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84
+#, python-format
+msgid "Argument %(key)s value %(value)s is too short."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89
+#, python-format
+msgid "Argument %(key)s value %(value)s contains invalid characters."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94
+#, python-format
+msgid "Argument %(key)s value %(value)s starts with a hyphen."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:102
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:130
+#, python-format
+msgid "Argument %s is required."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117
+#, python-format
+msgid ""
+"Argument %(key)s may not take value %(value)s. Valid values are ['true', "
+"'false']."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:163
+#, python-format
+msgid ""
+"Created VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) on %(sr_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:67
+#, python-format
+msgid "Attempted to create non-unique name %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:73
+#, python-format
+msgid "instance %(name)s: not enough free memory"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:148
+#, python-format
+msgid "Starting VM %s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:151
+#, python-format
+msgid "Spawning VM %(instance_name)s created %(vm_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:162
+#, python-format
+msgid "Invalid value for onset_files: '%s'"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:167
+#, python-format
+msgid "Injecting file path: '%s'"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:180
+#, python-format
+msgid "Instance %s: booted"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:232
+#, python-format
+msgid "Instance not present %s"
+msgstr ""
+
+#. TODO(sirp): Add quiesce and VSS locking support when Windows support
+#. is added
+#: ../nova/virt/xenapi/vmops.py:261
+#, python-format
+msgid "Starting snapshot for VM %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:269
+#, python-format
+msgid "Unable to Snapshot %(vm_ref)s: %(exc)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:280
+#, python-format
+msgid "Finished snapshot and upload for VM %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:356
+#, python-format
+msgid "VM %(vm)s already halted, skipping shutdown..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:389
+msgid "Removing kernel/ramdisk files"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:399
+msgid "kernel/ramdisk files removed"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:561
+#, python-format
+msgid ""
+"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; "
+"args=%(strargs)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:564
+#, python-format
+msgid ""
+"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM "
+"id=%(instance_id)s; args=%(strargs)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:569
+#, python-format
+msgid ""
+"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; "
+"args=%(strargs)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:760
+#, python-format
+msgid "OpenSSL error: %s"
+msgstr ""
+
+#: ../nova/tests/test_compute.py:148
+#, python-format
+msgid "Running instances: %s"
+msgstr ""
+
+#: ../nova/tests/test_compute.py:154
+#, python-format
+msgid "After terminating instances: %s"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:45
+msgid "Template for script to run on cloudpipe instance boot"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:48
+msgid "Network to push into openvpn config"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:51
+msgid "Netmask to push into openvpn config"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:97
+#, python-format
+msgid "Launching VPN for %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/migration.py:35
+msgid "python-migrate is not installed. Exiting."
+msgstr ""
+
+#: ../nova/image/s3.py:99
+#, python-format
+msgid "Image %s could not be found"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:121
+msgid "Too many failed authentications."
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:131
+#, python-format
+msgid ""
+"Access key %(access_key)s has had %(failures)d failed authentications and "
+"will be locked out for %(lock_mins)d minutes."
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140
+#, python-format
+msgid "Authentication Failure: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:182
+#, python-format
+msgid "Authenticated Request For %(uname)s:%(pname)s)"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:207
+#, python-format
+msgid "action: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:209
+#, python-format
+msgid "arg: %(key)s\t\tval: %(value)s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:281
+#, python-format
+msgid ""
+"Unauthorized request for controller=%(controller)s and action=%(action)s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:314
+#, python-format
+msgid "InstanceNotFound raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:320
+#, python-format
+msgid "VolumeNotFound raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:326
+#, python-format
+msgid "NotFound raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:329
+#, python-format
+msgid "ApiError raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:338
+#, python-format
+msgid "Unexpected error raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:343
+msgid "An unknown error has occurred. Please try your request again."
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:84
+#, python-format
+msgid "User %s already exists"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232
+#, python-format
+msgid "Project can't be created because manager %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243
+#, python-format
+msgid "Project can't be created because user %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229
+#, python-format
+msgid "Project can't be created because project %s already exists"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268
+#, python-format
+msgid "Project can't be modified because manager %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:245
+#, python-format
+msgid "User \"%s\" not found"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:248
+#, python-format
+msgid "Project \"%s\" not found"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:129
+msgid ""
+"Must specify xenapi_connection_url, xenapi_connection_username (optionally), "
+"and xenapi_connection_password to use connection_type=xenapi"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:311
+#, python-format
+msgid "Task [%(name)s] %(task)s status: success %(result)s"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:317
+#, python-format
+msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344
+#, python-format
+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"
+msgstr ""
+
+#: ../nova/api/ec2/apirequest.py:100
+#, python-format
+msgid ""
+"Unsupported API request: controller = %(controller)s, action = %(action)s"
+msgstr ""
+
+#: ../nova/api/openstack/__init__.py:55
+#, python-format
+msgid "Caught error: %s"
+msgstr ""
+
+#: ../nova/api/openstack/__init__.py:76
+msgid "Including admin operations in API."
+msgstr ""
+
+#: ../nova/console/xvp.py:99
+msgid "Rebuilding xvp conf"
+msgstr ""
+
+#: ../nova/console/xvp.py:116
+#, python-format
+msgid "Re-wrote %s"
+msgstr ""
+
+#: ../nova/console/xvp.py:121
+msgid "Stopping xvp"
+msgstr ""
+
+#: ../nova/console/xvp.py:134
+msgid "Starting xvp"
+msgstr ""
+
+#: ../nova/console/xvp.py:141
+#, python-format
+msgid "Error starting xvp: %s"
+msgstr ""
+
+#: ../nova/console/xvp.py:144
+msgid "Restarting xvp"
+msgstr ""
+
+#: ../nova/console/xvp.py:146
+msgid "xvp not running..."
+msgstr ""
+
+#: ../bin/nova-manage.py:272
+msgid ""
+"The above error may show that the database has not been created.\n"
+"Please create a database using nova-manage sync db before running this "
+"command."
+msgstr ""
+
+#: ../bin/nova-manage.py:426
+msgid ""
+"No more networks available. If this is a new installation, you need\n"
+"to call something like this:\n"
+"\n"
+" nova-manage network create 10.0.0.0/8 10 64\n"
+"\n"
+msgstr ""
+
+#: ../bin/nova-manage.py:431
+msgid ""
+"The above error may show that the certificate db has not been created.\n"
+"Please create a database by running a nova-api server on this host."
+msgstr ""
+
+#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536
+msgid "network"
+msgstr ""
+
+#: ../bin/nova-manage.py:448
+msgid "IP address"
+msgstr ""
+
+#: ../bin/nova-manage.py:449
+msgid "MAC address"
+msgstr ""
+
+#: ../bin/nova-manage.py:450
+msgid "hostname"
+msgstr ""
+
+#: ../bin/nova-manage.py:451
+msgid "host"
+msgstr ""
+
+#: ../bin/nova-manage.py:537
+msgid "netmask"
+msgstr ""
+
+#: ../bin/nova-manage.py:538
+msgid "start address"
+msgstr ""
+
+#: ../nova/virt/disk.py:69
+#, python-format
+msgid "Failed to load partition: %s"
+msgstr ""
+
+#: ../nova/virt/disk.py:91
+#, python-format
+msgid "Failed to mount filesystem: %s"
+msgstr ""
+
+#: ../nova/virt/disk.py:124
+#, python-format
+msgid "nbd device %s did not show up"
+msgstr ""
+
+#: ../nova/virt/disk.py:128
+#, python-format
+msgid "Could not attach image to loopback: %s"
+msgstr ""
+
+#: ../nova/virt/disk.py:151
+msgid "No free nbd devices"
+msgstr ""
+
+#: ../doc/ext/nova_todo.py:46
+#, python-format
+msgid "%(filename)s, line %(line_info)d"
+msgstr ""
+
+#. FIXME(chiradeep): implement this
+#: ../nova/virt/hyperv.py:118
+msgid "In init host"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:131
+#, python-format
+msgid "Attempt to create duplicate vm %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:148
+#, python-format
+msgid "Starting VM %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:150
+#, python-format
+msgid "Started VM %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:152
+#, python-format
+msgid "spawn vm failed: %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:169
+#, python-format
+msgid "Failed to create VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:188
+#, python-format
+msgid "Set memory for vm %s..."
+msgstr ""
+
+#: ../nova/virt/hyperv.py:198
+#, python-format
+msgid "Set vcpus for vm %s..."
+msgstr ""
+
+#: ../nova/virt/hyperv.py:202
+#, python-format
+msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:227
+#, python-format
+msgid "Failed to add diskdrive to VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:230
+#, python-format
+msgid "New disk drive path is %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:247
+#, python-format
+msgid "Failed to add vhd file to VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:249
+#, python-format
+msgid "Created disk for %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:253
+#, python-format
+msgid "Creating nic for %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:272
+msgid "Failed creating a port on the external vswitch"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:273
+#, python-format
+msgid "Failed creating port for %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:276
+#, python-format
+msgid "Created switch port %(vm_name)s on switch %(ext_path)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:286
+#, python-format
+msgid "Failed to add nic to VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:288
+#, python-format
+msgid "Created nic for %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:321
+#, python-format
+msgid "WMI job failed: %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:325
+#, python-format
+msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:361
+#, python-format
+msgid "Got request to destroy vm %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:386
+#, python-format
+msgid "Failed to destroy vm %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:393
+#, python-format
+msgid "Del: disk %(vhdfile)s vm %(instance_name)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:415
+#, python-format
+msgid ""
+"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, "
+"num_cpu=%(numprocs)s, cpu_time=%(uptime)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:451
+#, python-format
+msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:454
+#, python-format
+msgid "Failed to change vm state of %(vm_name)s to %(req_state)s"
+msgstr ""
+
+#: ../nova/compute/api.py:71
+#, python-format
+msgid "Instance %d was not found in get_network_topic"
+msgstr ""
+
+#: ../nova/compute/api.py:77
+#, python-format
+msgid "Instance %d has no host"
+msgstr ""
+
+#: ../nova/compute/api.py:97
+#, python-format
+msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances"
+msgstr ""
+
+#: ../nova/compute/api.py:99
+#, python-format
+msgid ""
+"Instance quota exceeded. You can only run %s more instances of this type."
+msgstr ""
+
+#: ../nova/compute/api.py:112
+msgid "Creating a raw instance"
+msgstr ""
+
+#: ../nova/compute/api.py:160
+#, python-format
+msgid "Going to run %s instances..."
+msgstr ""
+
+#: ../nova/compute/api.py:187
+#, python-format
+msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s"
+msgstr ""
+
+#: ../nova/compute/api.py:292
+#, python-format
+msgid "Going to try to terminate %s"
+msgstr ""
+
+#: ../nova/compute/api.py:296
+#, python-format
+msgid "Instance %d was not found during terminate"
+msgstr ""
+
+#: ../nova/compute/api.py:301
+#, python-format
+msgid "Instance %d is already being terminated"
+msgstr ""
+
+#: ../nova/compute/api.py:481
+#, python-format
+msgid "Invalid device specified: %s. Example device: /dev/vdb"
+msgstr ""
+
+#: ../nova/compute/api.py:496
+msgid "Volume isn't attached to anything!"
+msgstr ""
+
+#: ../nova/rpc.py:98
+#, python-format
+msgid ""
+"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in "
+"%(fl_intv)d seconds."
+msgstr ""
+
+#: ../nova/rpc.py:103
+#, python-format
+msgid "Unable to connect to AMQP server after %d tries. Shutting down."
+msgstr ""
+
+#: ../nova/rpc.py:122
+msgid "Reconnected to queue"
+msgstr ""
+
+#: ../nova/rpc.py:129
+msgid "Failed to fetch message from queue"
+msgstr ""
+
+#: ../nova/rpc.py:159
+#, python-format
+msgid "Initing the Adapter Consumer for %s"
+msgstr ""
+
+#: ../nova/rpc.py:178
+#, python-format
+msgid "received %s"
+msgstr ""
+
+#. NOTE(vish): we may not want to ack here, but that means that bad
+#. messages stay in the queue indefinitely, so for now
+#. we just log the message and send an error string
+#. back to the caller
+#: ../nova/rpc.py:191
+#, python-format
+msgid "no method for message: %s"
+msgstr ""
+
+#: ../nova/rpc.py:192
+#, python-format
+msgid "No method for message: %s"
+msgstr ""
+
+#: ../nova/rpc.py:253
+#, python-format
+msgid "Returning exception %s to caller"
+msgstr ""
+
+#: ../nova/rpc.py:294
+#, python-format
+msgid "unpacked context: %s"
+msgstr ""
+
+#: ../nova/rpc.py:313
+msgid "Making asynchronous call..."
+msgstr ""
+
+#: ../nova/rpc.py:316
+#, python-format
+msgid "MSG_ID is %s"
+msgstr ""
+
+#: ../nova/rpc.py:354
+msgid "Making asynchronous cast..."
+msgstr ""
+
+#: ../nova/rpc.py:364
+#, python-format
+msgid "response %s"
+msgstr ""
+
+#: ../nova/rpc.py:373
+#, python-format
+msgid "topic is %s"
+msgstr ""
+
+#: ../nova/rpc.py:374
+#, python-format
+msgid "message %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:78
+#, python-format
+msgid "Recovering from a failed execute. Try number %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:87
+#, python-format
+msgid "volume group %s doesn't exist"
+msgstr ""
+
+#: ../nova/volume/driver.py:220
+#, python-format
+msgid "FAKE AOE: %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:233
+msgid "Skipping ensure_export. No iscsi_target "
+msgstr ""
+
+#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288
+msgid "Skipping remove_export. No iscsi_target "
+msgstr ""
+
+#: ../nova/volume/driver.py:347
+#, python-format
+msgid "FAKE ISCSI: %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:359
+#, python-format
+msgid "rbd has no pool %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:414
+#, python-format
+msgid "Sheepdog is not working: %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:416
+msgid "Sheepdog is not working"
+msgstr ""
+
+#: ../nova/wsgi.py:68
+#, python-format
+msgid "Starting %(arg0)s on %(host)s:%(port)s"
+msgstr ""
+
+#: ../nova/wsgi.py:147
+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 ""
+
+#: ../bin/nova-dhcpbridge.py:73
+msgid "Adopted old lease or got a change of mac/hostname"
+msgstr ""
+
+#: ../bin/nova-dhcpbridge.py:80
+msgid "releasing ip"
+msgstr ""
+
+#: ../bin/nova-dhcpbridge.py:123
+#, python-format
+msgid ""
+"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s "
+"on interface %(interface)s"
+msgstr ""
+
+#: ../nova/virt/fake.py:239
+#, python-format
+msgid "Instance %s Not Found"
+msgstr ""
+
+#: ../nova/network/manager.py:153
+#, python-format
+msgid "Dissassociated %s stale fixed ip(s)"
+msgstr ""
+
+#: ../nova/network/manager.py:157
+msgid "setting network host"
+msgstr ""
+
+#: ../nova/network/manager.py:212
+#, python-format
+msgid "Leasing IP %s"
+msgstr ""
+
+#: ../nova/network/manager.py:216
+#, python-format
+msgid "IP %s leased that isn't associated"
+msgstr ""
+
+#: ../nova/network/manager.py:220
+#, python-format
+msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s"
+msgstr ""
+
+#: ../nova/network/manager.py:228
+#, python-format
+msgid "IP %s leased that was already deallocated"
+msgstr ""
+
+#: ../nova/network/manager.py:233
+#, python-format
+msgid "Releasing IP %s"
+msgstr ""
+
+#: ../nova/network/manager.py:237
+#, python-format
+msgid "IP %s released that isn't associated"
+msgstr ""
+
+#: ../nova/network/manager.py:241
+#, python-format
+msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s"
+msgstr ""
+
+#: ../nova/network/manager.py:244
+#, python-format
+msgid "IP %s released that was not leased"
+msgstr ""
+
+#: ../nova/network/manager.py:519
+msgid ""
+"The sum between the number of networks and the vlan start cannot be greater "
+"than 4094"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:57
+#, python-format
+msgid "Introducing %s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:74
+#, python-format
+msgid "Introduced %(label)s as %(sr_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:78
+msgid "Unable to create Storage Repository"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:90
+#, python-format
+msgid "Unable to find SR from VBD %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:96
+#, python-format
+msgid "Forgetting SR %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:101
+#, python-format
+msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:107
+#, python-format
+msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:111
+#, python-format
+msgid "Forgetting SR %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:113
+#, python-format
+msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:123
+#, python-format
+msgid "Unable to introduce VDI on SR %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:128
+#, python-format
+msgid "Unable to get record of VDI %s on"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:146
+#, python-format
+msgid "Unable to introduce VDI for SR %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:175
+#, python-format
+msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:197
+#, python-format
+msgid "Mountpoint cannot be translated: %s"
+msgstr ""
+
+#: ../nova/objectstore/image.py:262
+#, python-format
+msgid "Failed to decrypt private key: %s"
+msgstr ""
+
+#: ../nova/objectstore/image.py:269
+#, python-format
+msgid "Failed to decrypt initialization vector: %s"
+msgstr ""
+
+#: ../nova/objectstore/image.py:277
+#, python-format
+msgid "Failed to decrypt image file %(image_file)s: %(err)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:106
+#, python-format
+msgid "Unknown S3 value type %r"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:137
+msgid "Authenticated request"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:182
+msgid "List of buckets requested"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:209
+#, python-format
+msgid "List keys for bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:217
+#, python-format
+msgid "Unauthorized attempt to access bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:235
+#, python-format
+msgid "Creating bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:245
+#, python-format
+msgid "Deleting bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:249
+#, python-format
+msgid "Unauthorized attempt to delete bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:273
+#, python-format
+msgid "Getting object: %(bname)s / %(nm)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:276
+#, python-format
+msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:296
+#, python-format
+msgid "Putting object: %(bname)s / %(nm)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:299
+#, python-format
+msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:318
+#, python-format
+msgid "Deleting object: %(bname)s / %(nm)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:322
+#, python-format
+msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:396
+#, python-format
+msgid "Not authorized to upload image: invalid directory %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:404
+#, python-format
+msgid "Not authorized to upload image: unauthorized bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:409
+#, python-format
+msgid "Starting image upload: %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:423
+#, python-format
+msgid "Not authorized to update attributes of image %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:431
+#, python-format
+msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r"
+msgstr ""
+
+#. other attributes imply update
+#: ../nova/objectstore/handler.py:436
+#, python-format
+msgid "Updating user fields on image %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:450
+#, python-format
+msgid "Unauthorized attempt to delete image %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:455
+#, python-format
+msgid "Deleted image: %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:259
+#, python-format
+msgid "Looking up user: %r"
+msgstr ""
+
+#: ../nova/auth/manager.py:263
+#, python-format
+msgid "Failed authorization for access key %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:264
+#, python-format
+msgid "No user found for access key %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:270
+#, python-format
+msgid "Using project name = user name (%s)"
+msgstr ""
+
+#: ../nova/auth/manager.py:277
+#, python-format
+msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)"
+msgstr ""
+
+#: ../nova/auth/manager.py:279
+#, python-format
+msgid "No project called %s could be found"
+msgstr ""
+
+#: ../nova/auth/manager.py:287
+#, python-format
+msgid ""
+"Failed authorization: user %(uname)s not admin and not member of project "
+"%(pjname)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:289
+#, python-format
+msgid "User %(uid)s is not a member of project %(pjid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309
+#, python-format
+msgid "Invalid signature for user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310
+msgid "Signature does not match"
+msgstr ""
+
+#: ../nova/auth/manager.py:380
+msgid "Must specify project"
+msgstr ""
+
+#: ../nova/auth/manager.py:414
+#, python-format
+msgid "The %s role can not be found"
+msgstr ""
+
+#: ../nova/auth/manager.py:416
+#, python-format
+msgid "The %s role is global only"
+msgstr ""
+
+#: ../nova/auth/manager.py:420
+#, python-format
+msgid "Adding role %(role)s to user %(uid)s in project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:423
+#, python-format
+msgid "Adding sitewide role %(role)s to user %(uid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:448
+#, python-format
+msgid "Removing role %(role)s from user %(uid)s on project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:451
+#, python-format
+msgid "Removing sitewide role %(role)s from user %(uid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:515
+#, python-format
+msgid "Created project %(name)s with manager %(manager_user)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:533
+#, python-format
+msgid "modifying project %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:545
+#, python-format
+msgid "Adding user %(uid)s to project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:566
+#, python-format
+msgid "Remove user %(uid)s from project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:592
+#, python-format
+msgid "Deleting project %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:650
+#, python-format
+msgid "Created user %(rvname)s (admin: %(rvadmin)r)"
+msgstr ""
+
+#: ../nova/auth/manager.py:659
+#, python-format
+msgid "Deleting user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:669
+#, python-format
+msgid "Access Key change for user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:671
+#, python-format
+msgid "Secret Key change for user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:673
+#, python-format
+msgid "Admin status set to %(admin)r for user %(uid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:722
+#, python-format
+msgid "No vpn data for project %s"
+msgstr ""
+
+#: ../nova/service.py:161
+#, python-format
+msgid "Starting %(topic)s node (version %(vcs_string)s)"
+msgstr ""
+
+#: ../nova/service.py:174
+msgid "Service killed that has no database entry"
+msgstr ""
+
+#: ../nova/service.py:195
+msgid "The service database object disappeared, Recreating it."
+msgstr ""
+
+#: ../nova/service.py:207
+msgid "Recovered model server connection!"
+msgstr ""
+
+#: ../nova/service.py:213
+msgid "model server went away"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:174
+#, python-format
+msgid "LDAP user %s already exists"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:205
+#, python-format
+msgid "LDAP object for %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:348
+#, python-format
+msgid "User %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:472
+#, python-format
+msgid "Group can't be created because group %s already exists"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:478
+#, python-format
+msgid "Group can't be created because user %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:495
+#, python-format
+msgid "User %s can't be searched in group because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:507
+#, python-format
+msgid "User %s can't be added to the group because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521
+#, python-format
+msgid "The group at dn %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:513
+#, python-format
+msgid "User %(uid)s is already a member of the group %(group_dn)s"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:524
+#, python-format
+msgid ""
+"User %s can't be removed from the group because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:528
+#, python-format
+msgid "User %s is not a member of the group"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:542
+#, python-format
+msgid ""
+"Attempted to remove the last member of a group. Deleting the group at %s "
+"instead."
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:549
+#, python-format
+msgid "User %s can't be removed from all because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:564
+#, python-format
+msgid "Group at dn %s doesn't exist"
+msgstr ""
+
+#: ../nova/virt/xenapi/network_utils.py:40
+#, python-format
+msgid "Found non-unique network for bridge %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/network_utils.py:43
+#, python-format
+msgid "Found no network for bridge %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:97
+#, python-format
+msgid "Creating new user: %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:105
+#, python-format
+msgid "Deleting user: %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:127
+#, python-format
+msgid "Adding role %(role)s to user %(user)s for project %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:131
+#, python-format
+msgid "Adding sitewide role %(role)s to user %(user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:137
+#, python-format
+msgid "Removing role %(role)s from user %(user)s for project %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:141
+#, python-format
+msgid "Removing sitewide role %(role)s from user %(user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223
+msgid "operation must be add or remove"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:159
+#, python-format
+msgid "Getting x509 for user: %(name)s on project: %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:177
+#, python-format
+msgid "Create project %(name)s managed by %(manager_user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:190
+#, python-format
+msgid "Modify project: %(name)s managed by %(manager_user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:200
+#, python-format
+msgid "Delete project: %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:214
+#, python-format
+msgid "Adding user %(user)s to project %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:218
+#, python-format
+msgid "Removing user %(user)s from project %(project)s"
+msgstr ""
diff --git a/po/en_GB.po b/po/en_GB.po
new file mode 100644
index 000000000..601f6170b
--- /dev/null
+++ b/po/en_GB.po
@@ -0,0 +1,2873 @@
+# English (United Kingdom) translation for nova
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the nova package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: nova\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-02-21 10:03-0500\n"
+"PO-Revision-Date: 2011-06-19 18:14+0000\n"
+"Last-Translator: Dave Walker <davewalker@ubuntu.com>\n"
+"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
+
+#: ../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
+msgid "No hosts found"
+msgstr "No hosts found"
+
+#: ../nova/exception.py:33
+msgid "Unexpected error while running command."
+msgstr "Unexpected error while running command."
+
+#: ../nova/exception.py:36
+#, python-format
+msgid ""
+"%(description)s\n"
+"Command: %(cmd)s\n"
+"Exit code: %(exit_code)s\n"
+"Stdout: %(stdout)r\n"
+"Stderr: %(stderr)r"
+msgstr ""
+"%(description)s\n"
+"Command: %(cmd)s\n"
+"Exit code: %(exit_code)s\n"
+"Stdout: %(stdout)r\n"
+"Stderr: %(stderr)r"
+
+#: ../nova/exception.py:107
+msgid "DB exception wrapped"
+msgstr "DB exception wrapped"
+
+#. exc_type, exc_value, exc_traceback = sys.exc_info()
+#: ../nova/exception.py:120
+msgid "Uncaught exception"
+msgstr "Uncaught exception"
+
+#: ../nova/volume/api.py:45
+#, python-format
+msgid "Quota exceeeded for %(pid)s, tried to create %(size)sG volume"
+msgstr "Quota exceeeded for %(pid)s, tried to create %(size)sG volume"
+
+#: ../nova/volume/api.py:47
+#, python-format
+msgid "Volume quota exceeded. You cannot create a volume of size %sG"
+msgstr "Volume quota exceeded. You cannot create a volume of size %sG"
+
+#: ../nova/volume/api.py:71 ../nova/volume/api.py:96
+msgid "Volume status must be available"
+msgstr "Volume status must be available"
+
+#: ../nova/volume/api.py:98
+msgid "Volume is already attached"
+msgstr "Volume is already attached"
+
+#: ../nova/volume/api.py:104
+msgid "Volume is already detached"
+msgstr "Volume is already detached"
+
+#: ../nova/api/openstack/servers.py:72
+msgid "Failed to read private ip"
+msgstr "Failed to read private ip"
+
+#: ../nova/api/openstack/servers.py:79
+msgid "Failed to read public ip(s)"
+msgstr "Failed to read public ip(s)"
+
+#: ../nova/api/openstack/servers.py:152
+#, python-format
+msgid "%(param)s property not found for image %(_image_id)s"
+msgstr "%(param)s property not found for image %(_image_id)s"
+
+#: ../nova/api/openstack/servers.py:168
+msgid "No keypairs defined"
+msgstr "No keypairs defined"
+
+#: ../nova/api/openstack/servers.py:238
+#, python-format
+msgid "Compute.api::lock %s"
+msgstr "Compute.api::lock %s"
+
+#: ../nova/api/openstack/servers.py:253
+#, python-format
+msgid "Compute.api::unlock %s"
+msgstr "Compute.api::unlock %s"
+
+#: ../nova/api/openstack/servers.py:267
+#, python-format
+msgid "Compute.api::get_lock %s"
+msgstr "Compute.api::get_lock %s"
+
+#: ../nova/api/openstack/servers.py:281
+#, python-format
+msgid "Compute.api::reset_network %s"
+msgstr "Compute.api::reset_network %s"
+
+#: ../nova/api/openstack/servers.py:292
+#, python-format
+msgid "Compute.api::pause %s"
+msgstr "Compute.api::pause %s"
+
+#: ../nova/api/openstack/servers.py:303
+#, python-format
+msgid "Compute.api::unpause %s"
+msgstr "Compute.api::unpause %s"
+
+#: ../nova/api/openstack/servers.py:314
+#, python-format
+msgid "compute.api::suspend %s"
+msgstr "compute.api::suspend %s"
+
+#: ../nova/api/openstack/servers.py:325
+#, python-format
+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
+#, python-format
+msgid "Instance %s not found"
+msgstr "Instance %s not found"
+
+#. NOTE: No Resource Pool concept so far
+#: ../nova/virt/xenapi/volumeops.py:51
+#, python-format
+msgid "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s"
+msgstr "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s"
+
+#: ../nova/virt/xenapi/volumeops.py:69
+#, python-format
+msgid "Unable to create VDI on SR %(sr_ref)s for instance %(instance_name)s"
+msgstr "Unable to create VDI on SR %(sr_ref)s for instance %(instance_name)s"
+
+#: ../nova/virt/xenapi/volumeops.py:80
+#, python-format
+msgid "Unable to use SR %(sr_ref)s for instance %(instance_name)s"
+msgstr "Unable to use SR %(sr_ref)s for instance %(instance_name)s"
+
+#: ../nova/virt/xenapi/volumeops.py:91
+#, python-format
+msgid "Unable to attach volume to instance %s"
+msgstr "Unable to attach volume to instance %s"
+
+#: ../nova/virt/xenapi/volumeops.py:93
+#, python-format
+msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s"
+msgstr "Mountpoint %(mountpoint)s attached to instance %(instance_name)s"
+
+#. Detach VBD from VM
+#: ../nova/virt/xenapi/volumeops.py:104
+#, python-format
+msgid "Detach_volume: %(instance_name)s, %(mountpoint)s"
+msgstr "Detach_volume: %(instance_name)s, %(mountpoint)s"
+
+#: ../nova/virt/xenapi/volumeops.py:112
+#, python-format
+msgid "Unable to locate volume %s"
+msgstr "Unable to locate volume %s"
+
+#: ../nova/virt/xenapi/volumeops.py:120
+#, python-format
+msgid "Unable to detach volume %s"
+msgstr "Unable to detach volume %s"
+
+#: ../nova/virt/xenapi/volumeops.py:127
+#, python-format
+msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s"
+msgstr "Mountpoint %(mountpoint)s detached from instance %(instance_name)s"
+
+#: ../nova/compute/instance_types.py:41
+#, python-format
+msgid "Unknown instance type: %s"
+msgstr "Unknown instance type: %s"
+
+#: ../nova/crypto.py:46
+msgid "Filename of root CA"
+msgstr "Filename of root CA"
+
+#: ../nova/crypto.py:49
+msgid "Filename of private key"
+msgstr "Filename of private key"
+
+#: ../nova/crypto.py:51
+msgid "Filename of root Certificate Revokation List"
+msgstr "Filename of root Certificate Revocation List"
+
+#: ../nova/crypto.py:53
+msgid "Where we keep our keys"
+msgstr "Where we keep our keys"
+
+#: ../nova/crypto.py:55
+msgid "Where we keep our root CA"
+msgstr "Where we keep our root CA"
+
+#: ../nova/crypto.py:57
+msgid "Should we use a CA for each project?"
+msgstr "Should we use a CA for each project?"
+
+#: ../nova/crypto.py:61
+#, python-format
+msgid "Subject for certificate for users, %s for project, user, timestamp"
+msgstr "Subject for certificate for users, %s for project, user, timestamp"
+
+#: ../nova/crypto.py:66
+#, python-format
+msgid "Subject for certificate for projects, %s for project, timestamp"
+msgstr "Subject for certificate for projects, %s for project, timestamp"
+
+#: ../nova/crypto.py:71
+#, python-format
+msgid "Subject for certificate for vpns, %s for project, timestamp"
+msgstr "Subject for certificate for vpns, %s for project, timestamp"
+
+#: ../nova/crypto.py:258
+#, python-format
+msgid "Flags path: %s"
+msgstr "Flags path: %s"
+
+#: ../nova/scheduler/manager.py:69
+#, python-format
+msgid "Casting to %(topic)s %(host)s for %(method)s"
+msgstr "Casting to %(topic)s %(host)s for %(method)s"
+
+#: ../nova/compute/manager.py:78
+#, python-format
+msgid "check_instance_lock: decorating: |%s|"
+msgstr "check_instance_lock: decorating: |%s|"
+
+#: ../nova/compute/manager.py:80
+#, python-format
+msgid ""
+"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|"
+msgstr ""
+"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|"
+
+#: ../nova/compute/manager.py:84
+#, python-format
+msgid "check_instance_lock: locked: |%s|"
+msgstr "check_instance_lock: locked: |%s|"
+
+#: ../nova/compute/manager.py:86
+#, python-format
+msgid "check_instance_lock: admin: |%s|"
+msgstr "check_instance_lock: admin: |%s|"
+
+#: ../nova/compute/manager.py:91
+#, python-format
+msgid "check_instance_lock: executing: |%s|"
+msgstr "check_instance_lock: executing: |%s|"
+
+#: ../nova/compute/manager.py:95
+#, python-format
+msgid "check_instance_lock: not executing |%s|"
+msgstr "check_instance_lock: not executing |%s|"
+
+#: ../nova/compute/manager.py:179
+msgid "Instance has already been created"
+msgstr "Instance has already been created"
+
+#: ../nova/compute/manager.py:180
+#, python-format
+msgid "instance %s: starting..."
+msgstr "instance %s: starting..."
+
+#. pylint: disable=W0702
+#: ../nova/compute/manager.py:219
+#, python-format
+msgid "instance %s: Failed to spawn"
+msgstr "instance %s: Failed to spawn"
+
+#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286
+#, python-format
+msgid "Terminating instance %s"
+msgstr "Terminating instance %s"
+
+#: ../nova/compute/manager.py:255
+#, python-format
+msgid "Deallocating address %s"
+msgstr "Deallocating address %s"
+
+#: ../nova/compute/manager.py:268
+#, python-format
+msgid "trying to destroy already destroyed instance: %s"
+msgstr "trying to destroy already destroyed instance: %s"
+
+#: ../nova/compute/manager.py:282
+#, python-format
+msgid "Rebooting instance %s"
+msgstr "Rebooting instance %s"
+
+#: ../nova/compute/manager.py:287
+#, python-format
+msgid ""
+"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s "
+"expected: %(running)s)"
+msgstr ""
+"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s "
+"expected: %(running)s)"
+
+#: ../nova/compute/manager.py:311
+#, python-format
+msgid "instance %s: snapshotting"
+msgstr "instance %s: snapshotting"
+
+#: ../nova/compute/manager.py:316
+#, python-format
+msgid ""
+"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s "
+"expected: %(running)s)"
+msgstr ""
+"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s "
+"expected: %(running)s)"
+
+#: ../nova/compute/manager.py:332
+#, python-format
+msgid ""
+"trying to reset the password on a non-running instance: %(instance_id)s "
+"(state: %(instance_state)s expected: %(expected_state)s)"
+msgstr ""
+"trying to reset the password on a non-running instance: %(instance_id)s "
+"(state: %(instance_state)s expected: %(expected_state)s)"
+
+#: ../nova/compute/manager.py:335
+#, python-format
+msgid "instance %s: setting admin password"
+msgstr "instance %s: setting admin password"
+
+#: ../nova/compute/manager.py:353
+#, python-format
+msgid ""
+"trying to inject a file into a non-running instance: %(instance_id)s (state: "
+"%(instance_state)s expected: %(expected_state)s)"
+msgstr ""
+"trying to inject a file into a non-running instance: %(instance_id)s (state: "
+"%(instance_state)s expected: %(expected_state)s)"
+
+#: ../nova/compute/manager.py:362
+#, python-format
+msgid "instance %(nm)s: injecting file to %(plain_path)s"
+msgstr "instance %(nm)s: injecting file to %(plain_path)s"
+
+#: ../nova/compute/manager.py:372
+#, python-format
+msgid "instance %s: rescuing"
+msgstr "instance %s: rescuing"
+
+#: ../nova/compute/manager.py:387
+#, python-format
+msgid "instance %s: unrescuing"
+msgstr ""
+
+#: ../nova/compute/manager.py:406
+#, python-format
+msgid "instance %s: pausing"
+msgstr "instance %s: pausing"
+
+#: ../nova/compute/manager.py:423
+#, python-format
+msgid "instance %s: unpausing"
+msgstr ""
+
+#: ../nova/compute/manager.py:440
+#, python-format
+msgid "instance %s: retrieving diagnostics"
+msgstr "instance %s: retrieving diagnostics"
+
+#: ../nova/compute/manager.py:453
+#, python-format
+msgid "instance %s: suspending"
+msgstr "instance %s: suspending"
+
+#: ../nova/compute/manager.py:472
+#, python-format
+msgid "instance %s: resuming"
+msgstr "instance %s: resuming"
+
+#: ../nova/compute/manager.py:491
+#, python-format
+msgid "instance %s: locking"
+msgstr "instance %s: locking"
+
+#: ../nova/compute/manager.py:503
+#, python-format
+msgid "instance %s: unlocking"
+msgstr "instance %s: unlocking"
+
+#: ../nova/compute/manager.py:513
+#, python-format
+msgid "instance %s: getting locked state"
+msgstr "instance %s: getting locked state"
+
+#: ../nova/compute/manager.py:526
+#, python-format
+msgid "instance %s: reset network"
+msgstr "instance %s: reset network"
+
+#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515
+#, python-format
+msgid "Get console output for instance %s"
+msgstr "Get console output for instance %s"
+
+#: ../nova/compute/manager.py:543
+#, python-format
+msgid "instance %s: getting ajax console"
+msgstr "instance %s: getting ajax console"
+
+#: ../nova/compute/manager.py:553
+#, python-format
+msgid ""
+"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s"
+msgstr ""
+"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s"
+
+#. pylint: disable=W0702
+#. NOTE(vish): The inline callback eats the exception info so we
+#. log the traceback here and reraise the same
+#. ecxception below.
+#: ../nova/compute/manager.py:569
+#, python-format
+msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing"
+msgstr "instance %(instance_id)s: attach failed %(mountpoint)s, removing"
+
+#: ../nova/compute/manager.py:585
+#, python-format
+msgid ""
+"Detach volume %(volume_id)s from mountpoint %(mp)s on instance "
+"%(instance_id)s"
+msgstr ""
+"Detach volume %(volume_id)s from mountpoint %(mp)s on instance "
+"%(instance_id)s"
+
+#: ../nova/compute/manager.py:588
+#, python-format
+msgid "Detaching volume from unknown instance %s"
+msgstr "Detaching volume from unknown instance %s"
+
+#: ../nova/scheduler/simple.py:53
+#, python-format
+msgid "Host %s is not alive"
+msgstr "Host %s is not alive"
+
+#: ../nova/scheduler/simple.py:65
+msgid "All hosts have too many cores"
+msgstr "All hosts have too many cores"
+
+#: ../nova/scheduler/simple.py:87
+#, python-format
+msgid "Host %s not available"
+msgstr "Host %s not available"
+
+#: ../nova/scheduler/simple.py:99
+msgid "All hosts have too many gigabytes"
+msgstr "All hosts have too many gigabytes"
+
+#: ../nova/scheduler/simple.py:119
+msgid "All hosts have too many networks"
+msgstr "All hosts have too many networks"
+
+#: ../nova/volume/manager.py:85
+#, python-format
+msgid "Re-exporting %s volumes"
+msgstr "Re-exporting %s volumes"
+
+#: ../nova/volume/manager.py:90
+#, python-format
+msgid "volume %s: skipping export"
+msgstr "volume %s: skipping export"
+
+#: ../nova/volume/manager.py:96
+#, python-format
+msgid "volume %s: creating"
+msgstr "volume %s: creating"
+
+#: ../nova/volume/manager.py:108
+#, python-format
+msgid "volume %(vol_name)s: creating lv of size %(vol_size)sG"
+msgstr "volume %(vol_name)s: creating lv of size %(vol_size)sG"
+
+#: ../nova/volume/manager.py:112
+#, python-format
+msgid "volume %s: creating export"
+msgstr "volume %s: creating export"
+
+#: ../nova/volume/manager.py:123
+#, python-format
+msgid "volume %s: created successfully"
+msgstr "volume %s: created successfully"
+
+#: ../nova/volume/manager.py:131
+msgid "Volume is still attached"
+msgstr "Volume is still attached"
+
+#: ../nova/volume/manager.py:133
+msgid "Volume is not local to this node"
+msgstr "Volume is not local to this node"
+
+#: ../nova/volume/manager.py:136
+#, python-format
+msgid "volume %s: removing export"
+msgstr "volume %s: removing export"
+
+#: ../nova/volume/manager.py:138
+#, python-format
+msgid "volume %s: deleting"
+msgstr "volume %s: deleting"
+
+#: ../nova/volume/manager.py:147
+#, python-format
+msgid "volume %s: deleted successfully"
+msgstr "volume %s: deleted successfully"
+
+#: ../nova/virt/xenapi/fake.py:74
+#, python-format
+msgid "%(text)s: _db_content => %(content)s"
+msgstr "%(text)s: _db_content => %(content)s"
+
+#: ../nova/virt/xenapi/fake.py:304 ../nova/virt/xenapi/fake.py:404
+#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478
+msgid "Raising NotImplemented"
+msgstr "Raising NotImplemented"
+
+#: ../nova/virt/xenapi/fake.py:306
+#, python-format
+msgid "xenapi.fake does not have an implementation for %s"
+msgstr "xenapi.fake does not have an implementation for %s"
+
+#: ../nova/virt/xenapi/fake.py:341
+#, python-format
+msgid "Calling %(localname)s %(impl)s"
+msgstr "Calling %(localname)s %(impl)s"
+
+#: ../nova/virt/xenapi/fake.py:346
+#, python-format
+msgid "Calling getter %s"
+msgstr "Calling getter %s"
+
+#: ../nova/virt/xenapi/fake.py:406
+#, python-format
+msgid ""
+"xenapi.fake does not have an implementation for %s or it has been called "
+"with the wrong number of arguments"
+msgstr ""
+"xenapi.fake does not have an implementation for %s or it has been called "
+"with the wrong number of arguments"
+
+#: ../nova/tests/test_cloud.py:256
+msgid "Can't test instances without a real virtual env."
+msgstr "Can't test instances without a real virtual env."
+
+#: ../nova/tests/test_cloud.py:268
+#, python-format
+msgid "Need to watch instance %s until it's running..."
+msgstr "Need to watch instance %s until it's running..."
+
+#: ../nova/virt/connection.py:73
+msgid "Failed to open connection to the hypervisor"
+msgstr "Failed to open connection to the hypervisor"
+
+#: ../nova/network/linux_net.py:187
+#, python-format
+msgid "Starting VLAN inteface %s"
+msgstr "Starting VLAN inteface %s"
+
+#: ../nova/network/linux_net.py:208
+#, python-format
+msgid "Starting Bridge interface for %s"
+msgstr "Starting Bridge interface for %s"
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:314
+#, python-format
+msgid "Hupping dnsmasq threw %s"
+msgstr "Hupping dnsmasq threw %s"
+
+#: ../nova/network/linux_net.py:316
+#, python-format
+msgid "Pid %d is stale, relaunching dnsmasq"
+msgstr "Pid %d is stale, relaunching dnsmasq"
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:358
+#, python-format
+msgid "killing radvd threw %s"
+msgstr "killing radvd threw %s"
+
+#: ../nova/network/linux_net.py:360
+#, python-format
+msgid "Pid %d is stale, relaunching radvd"
+msgstr "Pid %d is stale, relaunching radvd"
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:449
+#, python-format
+msgid "Killing dnsmasq threw %s"
+msgstr "Killing dnsmasq threw %s"
+
+#: ../nova/utils.py:58
+#, python-format
+msgid "Inner Exception: %s"
+msgstr "Inner Exception: %s"
+
+#: ../nova/utils.py:59
+#, python-format
+msgid "Class %s cannot be found"
+msgstr "Class %s cannot be found"
+
+#: ../nova/utils.py:118
+#, python-format
+msgid "Fetching %s"
+msgstr "Fetching %s"
+
+#: ../nova/utils.py:130
+#, python-format
+msgid "Running cmd (subprocess): %s"
+msgstr "Running cmd (subprocess): %s"
+
+#: ../nova/utils.py:143 ../nova/utils.py:183
+#, python-format
+msgid "Result was %s"
+msgstr "Result was %s"
+
+#: ../nova/utils.py:159
+#, python-format
+msgid "Running cmd (SSH): %s"
+msgstr "Running cmd (SSH): %s"
+
+#: ../nova/utils.py:217
+#, python-format
+msgid "debug in callback: %s"
+msgstr "debug in callback: %s"
+
+#: ../nova/utils.py:222
+#, python-format
+msgid "Running %s"
+msgstr "Running %s"
+
+#: ../nova/utils.py:262
+#, python-format
+msgid "Link Local address is not found.:%s"
+msgstr "Link Local address is not found.:%s"
+
+#: ../nova/utils.py:265
+#, python-format
+msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s"
+msgstr "Couldn't get Link Local IP of %(interface)s :%(ex)s"
+
+#: ../nova/utils.py:363
+#, python-format
+msgid "Invalid backend: %s"
+msgstr "Invalid backend: %s"
+
+#: ../nova/utils.py:374
+#, python-format
+msgid "backend %s"
+msgstr "backend %s"
+
+#: ../nova/fakerabbit.py:49
+#, python-format
+msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s"
+msgstr "(%(nm)s) publish (key: %(routing_key)s) %(message)s"
+
+#: ../nova/fakerabbit.py:54
+#, python-format
+msgid "Publishing to route %s"
+msgstr "Publishing to route %s"
+
+#: ../nova/fakerabbit.py:84
+#, python-format
+msgid "Declaring queue %s"
+msgstr "Declaring queue %s"
+
+#: ../nova/fakerabbit.py:90
+#, python-format
+msgid "Declaring exchange %s"
+msgstr "Declaring exchange %s"
+
+#: ../nova/fakerabbit.py:96
+#, python-format
+msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s"
+msgstr "Binding %(queue)s to %(exchange)s with key %(routing_key)s"
+
+#: ../nova/fakerabbit.py:121
+#, python-format
+msgid "Getting from %(queue)s: %(message)s"
+msgstr "Getting from %(queue)s: %(message)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:135 ../nova/virt/hyperv.py:171
+#, python-format
+msgid "Created VM %s..."
+msgstr "Created VM %s..."
+
+#: ../nova/virt/xenapi/vm_utils.py:138
+#, python-format
+msgid "Created VM %(instance_name)s as %(vm_ref)s."
+msgstr "Created VM %(instance_name)s as %(vm_ref)s."
+
+#: ../nova/virt/xenapi/vm_utils.py:168
+#, python-format
+msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... "
+msgstr "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... "
+
+#: ../nova/virt/xenapi/vm_utils.py:171
+#, python-format
+msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s."
+msgstr "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s."
+
+#: ../nova/virt/xenapi/vm_utils.py:187
+#, python-format
+msgid "VBD not found in instance %s"
+msgstr "VBD not found in instance %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:197
+#, python-format
+msgid "Unable to unplug VBD %s"
+msgstr "Unable to unplug VBD %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:209
+#, python-format
+msgid "Unable to destroy VBD %s"
+msgstr "Unable to destroy VBD %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:224
+#, python-format
+msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s."
+msgstr "Creating VIF for VM %(vm_ref)s, network %(network_ref)s."
+
+#: ../nova/virt/xenapi/vm_utils.py:227
+#, python-format
+msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s."
+msgstr "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s."
+
+#: ../nova/virt/xenapi/vm_utils.py:246
+#, python-format
+msgid ""
+"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on "
+"%(sr_ref)s."
+msgstr ""
+"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on "
+"%(sr_ref)s."
+
+#. TODO(sirp): Add quiesce and VSS locking support when Windows support
+#. is added
+#: ../nova/virt/xenapi/vm_utils.py:258
+#, python-format
+msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..."
+msgstr "Snapshotting VM %(vm_ref)s with label '%(label)s'..."
+
+#: ../nova/virt/xenapi/vm_utils.py:272
+#, python-format
+msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s."
+msgstr "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s."
+
+#: ../nova/virt/xenapi/vm_utils.py:286
+#, python-format
+msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s"
+msgstr "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:327
+#, python-format
+msgid "Size for image %(image)s:%(virtual_size)d"
+msgstr "Size for image %(image)s:%(virtual_size)d"
+
+#: ../nova/virt/xenapi/vm_utils.py:332
+#, python-format
+msgid "Glance image %s"
+msgstr "Glance image %s"
+
+#. we need to invoke a plugin for copying VDI's
+#. content into proper path
+#: ../nova/virt/xenapi/vm_utils.py:342
+#, python-format
+msgid "Copying VDI %s to /boot/guest on dom0"
+msgstr "Copying VDI %s to /boot/guest on dom0"
+
+#: ../nova/virt/xenapi/vm_utils.py:352
+#, python-format
+msgid "Kernel/Ramdisk VDI %s destroyed"
+msgstr "Kernel/Ramdisk VDI %s destroyed"
+
+#: ../nova/virt/xenapi/vm_utils.py:361
+#, python-format
+msgid "Asking xapi to fetch %(url)s as %(access)s"
+msgstr "Asking xapi to fetch %(url)s as %(access)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402
+#, python-format
+msgid "Looking up vdi %s for PV kernel"
+msgstr "Looking up vdi %s for PV kernel"
+
+#: ../nova/virt/xenapi/vm_utils.py:397
+#, python-format
+msgid "PV Kernel in VDI:%s"
+msgstr "PV Kernel in VDI:%s"
+
+#: ../nova/virt/xenapi/vm_utils.py:405
+#, python-format
+msgid "Running pygrub against %s"
+msgstr "Running pygrub against %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:411
+#, python-format
+msgid "Found Xen kernel %s"
+msgstr "Found Xen kernel %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:413
+msgid "No Xen kernel found. Booting HVM."
+msgstr "No Xen kernel found. Booting HVM."
+
+#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431
+#, python-format
+msgid "duplicate name found: %s"
+msgstr "duplicate name found: %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:442
+#, python-format
+msgid "VDI %s is still available"
+msgstr "VDI %s is still available"
+
+#: ../nova/virt/xenapi/vm_utils.py:463
+#, python-format
+msgid "(VM_UTILS) xenserver vm state -> |%s|"
+msgstr "(VM_UTILS) xenserver vm state -> |%s|"
+
+#: ../nova/virt/xenapi/vm_utils.py:465
+#, python-format
+msgid "(VM_UTILS) xenapi power_state -> |%s|"
+msgstr "(VM_UTILS) xenapi power_state -> |%s|"
+
+#: ../nova/virt/xenapi/vm_utils.py:525
+#, python-format
+msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s"
+msgstr "VHD %(vdi_uuid)s has parent %(parent_ref)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:542
+#, python-format
+msgid "Re-scanning SR %s"
+msgstr "Re-scanning SR %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:567
+#, python-format
+msgid ""
+"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..."
+msgstr ""
+"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..."
+
+#: ../nova/virt/xenapi/vm_utils.py:574
+#, python-format
+msgid ""
+"Parent %(parent_uuid)s doesn't match original parent "
+"%(original_parent_uuid)s, waiting for coalesce..."
+msgstr ""
+"Parent %(parent_uuid)s doesn't match original parent "
+"%(original_parent_uuid)s, waiting for coalesce..."
+
+#: ../nova/virt/xenapi/vm_utils.py:590
+#, python-format
+msgid "No VDIs found for VM %s"
+msgstr "No VDIs found for VM %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:594
+#, python-format
+msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s"
+msgstr "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:653
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188
+#, python-format
+msgid "Creating VBD for VDI %s ... "
+msgstr "Creating VBD for VDI %s ... "
+
+#: ../nova/virt/xenapi/vm_utils.py:655
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190
+#, python-format
+msgid "Creating VBD for VDI %s done."
+msgstr "Creating VBD for VDI %s done."
+
+#: ../nova/virt/xenapi/vm_utils.py:657
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192
+#, python-format
+msgid "Plugging VBD %s ... "
+msgstr "Plugging VBD %s ... "
+
+#: ../nova/virt/xenapi/vm_utils.py:659
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:194
+#, python-format
+msgid "Plugging VBD %s done."
+msgstr "Plugging VBD %s done."
+
+#: ../nova/virt/xenapi/vm_utils.py:661
+#, python-format
+msgid "VBD %(vbd)s plugged as %(orig_dev)s"
+msgstr "VBD %(vbd)s plugged as %(orig_dev)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:664
+#, python-format
+msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s"
+msgstr "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:668
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:197
+#, python-format
+msgid "Destroying VBD for VDI %s ... "
+msgstr "Destroying VBD for VDI %s ... "
+
+#: ../nova/virt/xenapi/vm_utils.py:671
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:200
+#, python-format
+msgid "Destroying VBD for VDI %s done."
+msgstr "Destroying VBD for VDI %s done."
+
+#: ../nova/virt/xenapi/vm_utils.py:683
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211
+msgid "VBD.unplug successful first time."
+msgstr "VBD.unplug successful first time."
+
+#: ../nova/virt/xenapi/vm_utils.py:688
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216
+msgid "VBD.unplug rejected: retrying..."
+msgstr "VBD.unplug rejected: retrying..."
+
+#: ../nova/virt/xenapi/vm_utils.py:692
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220
+msgid "VBD.unplug successful eventually."
+msgstr "VBD.unplug successful eventually."
+
+#: ../nova/virt/xenapi/vm_utils.py:695
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:223
+#, python-format
+msgid "Ignoring XenAPI.Failure in VBD.unplug: %s"
+msgstr "Ignoring XenAPI.Failure in VBD.unplug: %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:704
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:66
+#, python-format
+msgid "Ignoring XenAPI.Failure %s"
+msgstr "Ignoring XenAPI.Failure %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:735
+#, python-format
+msgid ""
+"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..."
+msgstr ""
+"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..."
+
+#: ../nova/virt/xenapi/vm_utils.py:747
+#, python-format
+msgid "Writing partition table %s done."
+msgstr "Writing partition table %s done."
+
+#: ../nova/tests/test_rpc.py:89
+#, python-format
+msgid "Nested received %(queue)s, %(value)s"
+msgstr "Nested received %(queue)s, %(value)s"
+
+#: ../nova/tests/test_rpc.py:95
+#, python-format
+msgid "Nested return %s"
+msgstr "Nested return %s"
+
+#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126
+#, python-format
+msgid "Received %s"
+msgstr "Received %s"
+
+#: ../nova/db/sqlalchemy/api.py:44
+msgid "Use of empty request context is deprecated"
+msgstr "Use of empty request context is deprecated"
+
+#: ../nova/db/sqlalchemy/api.py:133
+#, python-format
+msgid "No service for id %s"
+msgstr "No service for id %s"
+
+#: ../nova/db/sqlalchemy/api.py:251
+#, python-format
+msgid "No service for %(host)s, %(binary)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:592
+msgid "No fixed ips defined"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:608
+#, python-format
+msgid "No floating ip for address %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:629
+#, python-format
+msgid "No address for instance %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:961
+#, python-format
+msgid "no keypair for user %(user_id)s, name %(name)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156
+#, python-format
+msgid "No network for id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1086
+msgid "No networks defined"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1115
+#, python-format
+msgid "No network for bridge %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142
+#, python-format
+msgid "No network for instance %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1277
+#, python-format
+msgid "Token %s does not exist"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1302
+#, python-format
+msgid "No quota for project_id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501
+#: ../nova/api/ec2/__init__.py:323
+#, python-format
+msgid "Volume %s not found"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1514
+#, python-format
+msgid "No export device found for volume %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1527
+#, python-format
+msgid "No target id found for volume %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1572
+#, python-format
+msgid "No security group with id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1589
+#, python-format
+msgid "No security group named %(group_name)s for project: %(project_id)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1682
+#, python-format
+msgid "No secuity group rule with id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1756
+#, python-format
+msgid "No user for id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1772
+#, python-format
+msgid "No user for access key %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1834
+#, python-format
+msgid "No project with id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1979
+#, python-format
+msgid "No console pool with id %(pool_id)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1996
+#, python-format
+msgid ""
+"No console pool of type %(console_type)s for compute host %(compute_host)s "
+"on proxy host %(host)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2035
+#, python-format
+msgid "No console for instance %(instance_id)s in pool %(pool_id)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2057
+#, python-format
+msgid "on instance %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2058
+#, python-format
+msgid "No console with id %(console_id)s %(idesc)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097
+#, python-format
+msgid "No zone with id %(zone_id)s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:160
+#, python-format
+msgid "Checking state of %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:165
+#, python-format
+msgid "Current state of %(name)s was %(state)s."
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:183
+#, python-format
+msgid "Connecting to libvirt: %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:196
+msgid "Connection to libvirt broke"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:258
+#, python-format
+msgid "instance %(instance_name)s: deleting instance files %(target)s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:283
+#, python-format
+msgid "Invalid device path %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:313
+#, python-format
+msgid "No disk at %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:320
+msgid "Instance snapshotting is not supported for libvirtat this time"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:336
+#, python-format
+msgid "instance %s: rebooted"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:339
+#, python-format
+msgid "_wait_for_reboot failed: %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:382
+#, python-format
+msgid "instance %s: rescued"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:385
+#, python-format
+msgid "_wait_for_rescue failed: %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:411
+#, python-format
+msgid "instance %s: is running"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:422
+#, python-format
+msgid "instance %s: booted"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186
+#, python-format
+msgid "instance %s: failed to boot"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:436
+#, python-format
+msgid "virsh said: %r"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:440
+msgid "cool, it's a device"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:448
+#, python-format
+msgid "data: %(data)r, fpath: %(fpath)r"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:456
+#, python-format
+msgid "Contents of file %(fpath)s: %(contents)r"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:489
+msgid "Unable to find an open port"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:563
+#, python-format
+msgid "instance %s: Creating image"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:646
+#, python-format
+msgid "instance %(inst_name)s: injecting key into image %(img_id)s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:649
+#, python-format
+msgid "instance %(inst_name)s: injecting net into image %(img_id)s"
+msgstr ""
+
+#. This could be a windows image, or a vmdk format disk
+#: ../nova/virt/libvirt_conn.py:657
+#, python-format
+msgid ""
+"instance %(inst_name)s: ignoring error injecting data into image %(img_id)s "
+"(%(e)s)"
+msgstr ""
+
+#. TODO(termie): cache?
+#: ../nova/virt/libvirt_conn.py:665
+#, python-format
+msgid "instance %s: starting toXML method"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:732
+#, python-format
+msgid "instance %s: finished toXML method"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:751
+msgid "diagnostics are not supported for libvirt"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:1225
+#, python-format
+msgid "Attempted to unfilter instance %s which is not filtered"
+msgstr ""
+
+#: ../nova/api/ec2/metadatarequesthandler.py:76
+#, python-format
+msgid "Failed to get metadata for ip: %s"
+msgstr ""
+
+#: ../nova/auth/fakeldap.py:33
+msgid "Attempted to instantiate singleton"
+msgstr ""
+
+#: ../nova/network/api.py:39
+#, python-format
+msgid "Quota exceeeded for %s, tried to allocate address"
+msgstr ""
+
+#: ../nova/network/api.py:42
+msgid "Address quota exceeded. You cannot allocate any more addresses"
+msgstr ""
+
+#: ../nova/tests/test_volume.py:162
+#, python-format
+msgid "Target %s allocated"
+msgstr ""
+
+#: ../nova/virt/images.py:70
+#, python-format
+msgid "Finished retreving %(url)s -- placed in %(path)s"
+msgstr ""
+
+#: ../nova/scheduler/driver.py:66
+msgid "Must implement a fallback schedule"
+msgstr ""
+
+#: ../nova/console/manager.py:70
+msgid "Adding console"
+msgstr ""
+
+#: ../nova/console/manager.py:90
+#, python-format
+msgid "Tried to remove non-existant console %(console_id)s."
+msgstr ""
+
+#: ../nova/api/direct.py:149
+msgid "not available"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:62
+#, python-format
+msgid "The key_pair %s already exists"
+msgstr ""
+
+#. TODO(vish): Do this with M2Crypto instead
+#: ../nova/api/ec2/cloud.py:118
+#, python-format
+msgid "Generating root CA: %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:303
+#, python-format
+msgid "Create key pair %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:311
+#, python-format
+msgid "Delete key pair %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:386
+#, python-format
+msgid "%s is not a valid ipProtocol"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:390
+msgid "Invalid port range"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:421
+#, python-format
+msgid "Revoke security group ingress %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459
+msgid "Not enough parameters to build a valid rule."
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:443
+msgid "No rule for the specified parameters."
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:450
+#, python-format
+msgid "Authorize security group ingress %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:464
+#, python-format
+msgid "This rule already exists in group %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:492
+#, python-format
+msgid "Create Security Group %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:495
+#, python-format
+msgid "group %s already exists"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:507
+#, python-format
+msgid "Delete security group %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:584
+#, python-format
+msgid "Create volume of %s GB"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:612
+#, python-format
+msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:629
+#, python-format
+msgid "Detach volume %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:761
+msgid "Allocate address"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:766
+#, python-format
+msgid "Release address %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:771
+#, python-format
+msgid "Associate address %(public_ip)s to instance %(instance_id)s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:780
+#, python-format
+msgid "Disassociate address %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:807
+msgid "Going to start terminating instances"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:815
+#, python-format
+msgid "Reboot instance %r"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:867
+#, python-format
+msgid "De-registering image %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:875
+#, python-format
+msgid "Registered image %(image_location)s with id %(image_id)s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900
+#, python-format
+msgid "attribute not supported: %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:890
+#, python-format
+msgid "invalid id: %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:903
+msgid "user or group not specified"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:905
+msgid "only group \"all\" is supported"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:907
+msgid "operation_type must be add or remove"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:908
+#, python-format
+msgid "Updating image %s publicity"
+msgstr ""
+
+#: ../bin/nova-api.py:52
+#, python-format
+msgid "Using paste.deploy config at: %s"
+msgstr ""
+
+#: ../bin/nova-api.py:57
+#, python-format
+msgid "No paste configuration for app: %s"
+msgstr ""
+
+#: ../bin/nova-api.py:59
+#, python-format
+msgid ""
+"App Config: %(api)s\n"
+"%(config)r"
+msgstr ""
+
+#: ../bin/nova-api.py:64
+#, python-format
+msgid "Running %s API"
+msgstr ""
+
+#: ../bin/nova-api.py:69
+#, python-format
+msgid "No known API applications configured in %s."
+msgstr ""
+
+#: ../bin/nova-api.py:83
+#, python-format
+msgid "Starting nova-api node (version %s)"
+msgstr ""
+
+#: ../bin/nova-api.py:89
+#, python-format
+msgid "No paste configuration found for: %s"
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84
+#, python-format
+msgid "Argument %(key)s value %(value)s is too short."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89
+#, python-format
+msgid "Argument %(key)s value %(value)s contains invalid characters."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94
+#, python-format
+msgid "Argument %(key)s value %(value)s starts with a hyphen."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:102
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:130
+#, python-format
+msgid "Argument %s is required."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117
+#, python-format
+msgid ""
+"Argument %(key)s may not take value %(value)s. Valid values are ['true', "
+"'false']."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:163
+#, python-format
+msgid ""
+"Created VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) on %(sr_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:67
+#, python-format
+msgid "Attempted to create non-unique name %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:73
+#, python-format
+msgid "instance %(name)s: not enough free memory"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:148
+#, python-format
+msgid "Starting VM %s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:151
+#, python-format
+msgid "Spawning VM %(instance_name)s created %(vm_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:162
+#, python-format
+msgid "Invalid value for onset_files: '%s'"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:167
+#, python-format
+msgid "Injecting file path: '%s'"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:180
+#, python-format
+msgid "Instance %s: booted"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:232
+#, python-format
+msgid "Instance not present %s"
+msgstr ""
+
+#. TODO(sirp): Add quiesce and VSS locking support when Windows support
+#. is added
+#: ../nova/virt/xenapi/vmops.py:261
+#, python-format
+msgid "Starting snapshot for VM %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:269
+#, python-format
+msgid "Unable to Snapshot %(vm_ref)s: %(exc)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:280
+#, python-format
+msgid "Finished snapshot and upload for VM %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:356
+#, python-format
+msgid "VM %(vm)s already halted, skipping shutdown..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:389
+msgid "Removing kernel/ramdisk files"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:399
+msgid "kernel/ramdisk files removed"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:561
+#, python-format
+msgid ""
+"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; "
+"args=%(strargs)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:564
+#, python-format
+msgid ""
+"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM "
+"id=%(instance_id)s; args=%(strargs)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:569
+#, python-format
+msgid ""
+"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; "
+"args=%(strargs)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:760
+#, python-format
+msgid "OpenSSL error: %s"
+msgstr ""
+
+#: ../nova/tests/test_compute.py:148
+#, python-format
+msgid "Running instances: %s"
+msgstr ""
+
+#: ../nova/tests/test_compute.py:154
+#, python-format
+msgid "After terminating instances: %s"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:45
+msgid "Template for script to run on cloudpipe instance boot"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:48
+msgid "Network to push into openvpn config"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:51
+msgid "Netmask to push into openvpn config"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:97
+#, python-format
+msgid "Launching VPN for %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/migration.py:35
+msgid "python-migrate is not installed. Exiting."
+msgstr ""
+
+#: ../nova/image/s3.py:99
+#, python-format
+msgid "Image %s could not be found"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:121
+msgid "Too many failed authentications."
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:131
+#, python-format
+msgid ""
+"Access key %(access_key)s has had %(failures)d failed authentications and "
+"will be locked out for %(lock_mins)d minutes."
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140
+#, python-format
+msgid "Authentication Failure: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:182
+#, python-format
+msgid "Authenticated Request For %(uname)s:%(pname)s)"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:207
+#, python-format
+msgid "action: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:209
+#, python-format
+msgid "arg: %(key)s\t\tval: %(value)s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:281
+#, python-format
+msgid ""
+"Unauthorized request for controller=%(controller)s and action=%(action)s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:314
+#, python-format
+msgid "InstanceNotFound raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:320
+#, python-format
+msgid "VolumeNotFound raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:326
+#, python-format
+msgid "NotFound raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:329
+#, python-format
+msgid "ApiError raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:338
+#, python-format
+msgid "Unexpected error raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:343
+msgid "An unknown error has occurred. Please try your request again."
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:84
+#, python-format
+msgid "User %s already exists"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232
+#, python-format
+msgid "Project can't be created because manager %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243
+#, python-format
+msgid "Project can't be created because user %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229
+#, python-format
+msgid "Project can't be created because project %s already exists"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268
+#, python-format
+msgid "Project can't be modified because manager %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:245
+#, python-format
+msgid "User \"%s\" not found"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:248
+#, python-format
+msgid "Project \"%s\" not found"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:129
+msgid ""
+"Must specify xenapi_connection_url, xenapi_connection_username (optionally), "
+"and xenapi_connection_password to use connection_type=xenapi"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:311
+#, python-format
+msgid "Task [%(name)s] %(task)s status: success %(result)s"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:317
+#, python-format
+msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344
+#, python-format
+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"
+msgstr ""
+
+#: ../nova/api/ec2/apirequest.py:100
+#, python-format
+msgid ""
+"Unsupported API request: controller = %(controller)s, action = %(action)s"
+msgstr ""
+
+#: ../nova/api/openstack/__init__.py:55
+#, python-format
+msgid "Caught error: %s"
+msgstr ""
+
+#: ../nova/api/openstack/__init__.py:76
+msgid "Including admin operations in API."
+msgstr ""
+
+#: ../nova/console/xvp.py:99
+msgid "Rebuilding xvp conf"
+msgstr ""
+
+#: ../nova/console/xvp.py:116
+#, python-format
+msgid "Re-wrote %s"
+msgstr ""
+
+#: ../nova/console/xvp.py:121
+msgid "Stopping xvp"
+msgstr ""
+
+#: ../nova/console/xvp.py:134
+msgid "Starting xvp"
+msgstr ""
+
+#: ../nova/console/xvp.py:141
+#, python-format
+msgid "Error starting xvp: %s"
+msgstr ""
+
+#: ../nova/console/xvp.py:144
+msgid "Restarting xvp"
+msgstr ""
+
+#: ../nova/console/xvp.py:146
+msgid "xvp not running..."
+msgstr ""
+
+#: ../bin/nova-manage.py:272
+msgid ""
+"The above error may show that the database has not been created.\n"
+"Please create a database using nova-manage sync db before running this "
+"command."
+msgstr ""
+
+#: ../bin/nova-manage.py:426
+msgid ""
+"No more networks available. If this is a new installation, you need\n"
+"to call something like this:\n"
+"\n"
+" nova-manage network create 10.0.0.0/8 10 64\n"
+"\n"
+msgstr ""
+
+#: ../bin/nova-manage.py:431
+msgid ""
+"The above error may show that the certificate db has not been created.\n"
+"Please create a database by running a nova-api server on this host."
+msgstr ""
+
+#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536
+msgid "network"
+msgstr ""
+
+#: ../bin/nova-manage.py:448
+msgid "IP address"
+msgstr ""
+
+#: ../bin/nova-manage.py:449
+msgid "MAC address"
+msgstr ""
+
+#: ../bin/nova-manage.py:450
+msgid "hostname"
+msgstr ""
+
+#: ../bin/nova-manage.py:451
+msgid "host"
+msgstr ""
+
+#: ../bin/nova-manage.py:537
+msgid "netmask"
+msgstr ""
+
+#: ../bin/nova-manage.py:538
+msgid "start address"
+msgstr ""
+
+#: ../nova/virt/disk.py:69
+#, python-format
+msgid "Failed to load partition: %s"
+msgstr ""
+
+#: ../nova/virt/disk.py:91
+#, python-format
+msgid "Failed to mount filesystem: %s"
+msgstr ""
+
+#: ../nova/virt/disk.py:124
+#, python-format
+msgid "nbd device %s did not show up"
+msgstr ""
+
+#: ../nova/virt/disk.py:128
+#, python-format
+msgid "Could not attach image to loopback: %s"
+msgstr ""
+
+#: ../nova/virt/disk.py:151
+msgid "No free nbd devices"
+msgstr ""
+
+#: ../doc/ext/nova_todo.py:46
+#, python-format
+msgid "%(filename)s, line %(line_info)d"
+msgstr ""
+
+#. FIXME(chiradeep): implement this
+#: ../nova/virt/hyperv.py:118
+msgid "In init host"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:131
+#, python-format
+msgid "Attempt to create duplicate vm %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:148
+#, python-format
+msgid "Starting VM %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:150
+#, python-format
+msgid "Started VM %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:152
+#, python-format
+msgid "spawn vm failed: %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:169
+#, python-format
+msgid "Failed to create VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:188
+#, python-format
+msgid "Set memory for vm %s..."
+msgstr ""
+
+#: ../nova/virt/hyperv.py:198
+#, python-format
+msgid "Set vcpus for vm %s..."
+msgstr ""
+
+#: ../nova/virt/hyperv.py:202
+#, python-format
+msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:227
+#, python-format
+msgid "Failed to add diskdrive to VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:230
+#, python-format
+msgid "New disk drive path is %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:247
+#, python-format
+msgid "Failed to add vhd file to VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:249
+#, python-format
+msgid "Created disk for %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:253
+#, python-format
+msgid "Creating nic for %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:272
+msgid "Failed creating a port on the external vswitch"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:273
+#, python-format
+msgid "Failed creating port for %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:276
+#, python-format
+msgid "Created switch port %(vm_name)s on switch %(ext_path)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:286
+#, python-format
+msgid "Failed to add nic to VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:288
+#, python-format
+msgid "Created nic for %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:321
+#, python-format
+msgid "WMI job failed: %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:325
+#, python-format
+msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:361
+#, python-format
+msgid "Got request to destroy vm %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:386
+#, python-format
+msgid "Failed to destroy vm %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:393
+#, python-format
+msgid "Del: disk %(vhdfile)s vm %(instance_name)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:415
+#, python-format
+msgid ""
+"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, "
+"num_cpu=%(numprocs)s, cpu_time=%(uptime)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:451
+#, python-format
+msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:454
+#, python-format
+msgid "Failed to change vm state of %(vm_name)s to %(req_state)s"
+msgstr ""
+
+#: ../nova/compute/api.py:71
+#, python-format
+msgid "Instance %d was not found in get_network_topic"
+msgstr ""
+
+#: ../nova/compute/api.py:77
+#, python-format
+msgid "Instance %d has no host"
+msgstr ""
+
+#: ../nova/compute/api.py:97
+#, python-format
+msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances"
+msgstr ""
+
+#: ../nova/compute/api.py:99
+#, python-format
+msgid ""
+"Instance quota exceeded. You can only run %s more instances of this type."
+msgstr ""
+
+#: ../nova/compute/api.py:112
+msgid "Creating a raw instance"
+msgstr ""
+
+#: ../nova/compute/api.py:160
+#, python-format
+msgid "Going to run %s instances..."
+msgstr ""
+
+#: ../nova/compute/api.py:187
+#, python-format
+msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s"
+msgstr ""
+
+#: ../nova/compute/api.py:292
+#, python-format
+msgid "Going to try to terminate %s"
+msgstr ""
+
+#: ../nova/compute/api.py:296
+#, python-format
+msgid "Instance %d was not found during terminate"
+msgstr ""
+
+#: ../nova/compute/api.py:301
+#, python-format
+msgid "Instance %d is already being terminated"
+msgstr ""
+
+#: ../nova/compute/api.py:481
+#, python-format
+msgid "Invalid device specified: %s. Example device: /dev/vdb"
+msgstr ""
+
+#: ../nova/compute/api.py:496
+msgid "Volume isn't attached to anything!"
+msgstr ""
+
+#: ../nova/rpc.py:98
+#, python-format
+msgid ""
+"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in "
+"%(fl_intv)d seconds."
+msgstr ""
+
+#: ../nova/rpc.py:103
+#, python-format
+msgid "Unable to connect to AMQP server after %d tries. Shutting down."
+msgstr ""
+
+#: ../nova/rpc.py:122
+msgid "Reconnected to queue"
+msgstr ""
+
+#: ../nova/rpc.py:129
+msgid "Failed to fetch message from queue"
+msgstr ""
+
+#: ../nova/rpc.py:159
+#, python-format
+msgid "Initing the Adapter Consumer for %s"
+msgstr ""
+
+#: ../nova/rpc.py:178
+#, python-format
+msgid "received %s"
+msgstr ""
+
+#. NOTE(vish): we may not want to ack here, but that means that bad
+#. messages stay in the queue indefinitely, so for now
+#. we just log the message and send an error string
+#. back to the caller
+#: ../nova/rpc.py:191
+#, python-format
+msgid "no method for message: %s"
+msgstr ""
+
+#: ../nova/rpc.py:192
+#, python-format
+msgid "No method for message: %s"
+msgstr ""
+
+#: ../nova/rpc.py:253
+#, python-format
+msgid "Returning exception %s to caller"
+msgstr ""
+
+#: ../nova/rpc.py:294
+#, python-format
+msgid "unpacked context: %s"
+msgstr ""
+
+#: ../nova/rpc.py:313
+msgid "Making asynchronous call..."
+msgstr ""
+
+#: ../nova/rpc.py:316
+#, python-format
+msgid "MSG_ID is %s"
+msgstr ""
+
+#: ../nova/rpc.py:354
+msgid "Making asynchronous cast..."
+msgstr ""
+
+#: ../nova/rpc.py:364
+#, python-format
+msgid "response %s"
+msgstr ""
+
+#: ../nova/rpc.py:373
+#, python-format
+msgid "topic is %s"
+msgstr ""
+
+#: ../nova/rpc.py:374
+#, python-format
+msgid "message %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:78
+#, python-format
+msgid "Recovering from a failed execute. Try number %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:87
+#, python-format
+msgid "volume group %s doesn't exist"
+msgstr ""
+
+#: ../nova/volume/driver.py:220
+#, python-format
+msgid "FAKE AOE: %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:233
+msgid "Skipping ensure_export. No iscsi_target "
+msgstr ""
+
+#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288
+msgid "Skipping remove_export. No iscsi_target "
+msgstr ""
+
+#: ../nova/volume/driver.py:347
+#, python-format
+msgid "FAKE ISCSI: %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:359
+#, python-format
+msgid "rbd has no pool %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:414
+#, python-format
+msgid "Sheepdog is not working: %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:416
+msgid "Sheepdog is not working"
+msgstr ""
+
+#: ../nova/wsgi.py:68
+#, python-format
+msgid "Starting %(arg0)s on %(host)s:%(port)s"
+msgstr ""
+
+#: ../nova/wsgi.py:147
+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 ""
+
+#: ../bin/nova-dhcpbridge.py:73
+msgid "Adopted old lease or got a change of mac/hostname"
+msgstr ""
+
+#: ../bin/nova-dhcpbridge.py:80
+msgid "releasing ip"
+msgstr ""
+
+#: ../bin/nova-dhcpbridge.py:123
+#, python-format
+msgid ""
+"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s "
+"on interface %(interface)s"
+msgstr ""
+
+#: ../nova/virt/fake.py:239
+#, python-format
+msgid "Instance %s Not Found"
+msgstr ""
+
+#: ../nova/network/manager.py:153
+#, python-format
+msgid "Dissassociated %s stale fixed ip(s)"
+msgstr ""
+
+#: ../nova/network/manager.py:157
+msgid "setting network host"
+msgstr ""
+
+#: ../nova/network/manager.py:212
+#, python-format
+msgid "Leasing IP %s"
+msgstr ""
+
+#: ../nova/network/manager.py:216
+#, python-format
+msgid "IP %s leased that isn't associated"
+msgstr ""
+
+#: ../nova/network/manager.py:220
+#, python-format
+msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s"
+msgstr ""
+
+#: ../nova/network/manager.py:228
+#, python-format
+msgid "IP %s leased that was already deallocated"
+msgstr ""
+
+#: ../nova/network/manager.py:233
+#, python-format
+msgid "Releasing IP %s"
+msgstr ""
+
+#: ../nova/network/manager.py:237
+#, python-format
+msgid "IP %s released that isn't associated"
+msgstr ""
+
+#: ../nova/network/manager.py:241
+#, python-format
+msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s"
+msgstr ""
+
+#: ../nova/network/manager.py:244
+#, python-format
+msgid "IP %s released that was not leased"
+msgstr ""
+
+#: ../nova/network/manager.py:519
+msgid ""
+"The sum between the number of networks and the vlan start cannot be greater "
+"than 4094"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:57
+#, python-format
+msgid "Introducing %s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:74
+#, python-format
+msgid "Introduced %(label)s as %(sr_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:78
+msgid "Unable to create Storage Repository"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:90
+#, python-format
+msgid "Unable to find SR from VBD %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:96
+#, python-format
+msgid "Forgetting SR %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:101
+#, python-format
+msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:107
+#, python-format
+msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:111
+#, python-format
+msgid "Forgetting SR %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:113
+#, python-format
+msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:123
+#, python-format
+msgid "Unable to introduce VDI on SR %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:128
+#, python-format
+msgid "Unable to get record of VDI %s on"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:146
+#, python-format
+msgid "Unable to introduce VDI for SR %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:175
+#, python-format
+msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:197
+#, python-format
+msgid "Mountpoint cannot be translated: %s"
+msgstr ""
+
+#: ../nova/objectstore/image.py:262
+#, python-format
+msgid "Failed to decrypt private key: %s"
+msgstr ""
+
+#: ../nova/objectstore/image.py:269
+#, python-format
+msgid "Failed to decrypt initialization vector: %s"
+msgstr ""
+
+#: ../nova/objectstore/image.py:277
+#, python-format
+msgid "Failed to decrypt image file %(image_file)s: %(err)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:106
+#, python-format
+msgid "Unknown S3 value type %r"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:137
+msgid "Authenticated request"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:182
+msgid "List of buckets requested"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:209
+#, python-format
+msgid "List keys for bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:217
+#, python-format
+msgid "Unauthorized attempt to access bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:235
+#, python-format
+msgid "Creating bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:245
+#, python-format
+msgid "Deleting bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:249
+#, python-format
+msgid "Unauthorized attempt to delete bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:273
+#, python-format
+msgid "Getting object: %(bname)s / %(nm)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:276
+#, python-format
+msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:296
+#, python-format
+msgid "Putting object: %(bname)s / %(nm)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:299
+#, python-format
+msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:318
+#, python-format
+msgid "Deleting object: %(bname)s / %(nm)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:322
+#, python-format
+msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:396
+#, python-format
+msgid "Not authorized to upload image: invalid directory %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:404
+#, python-format
+msgid "Not authorized to upload image: unauthorized bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:409
+#, python-format
+msgid "Starting image upload: %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:423
+#, python-format
+msgid "Not authorized to update attributes of image %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:431
+#, python-format
+msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r"
+msgstr ""
+
+#. other attributes imply update
+#: ../nova/objectstore/handler.py:436
+#, python-format
+msgid "Updating user fields on image %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:450
+#, python-format
+msgid "Unauthorized attempt to delete image %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:455
+#, python-format
+msgid "Deleted image: %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:259
+#, python-format
+msgid "Looking up user: %r"
+msgstr ""
+
+#: ../nova/auth/manager.py:263
+#, python-format
+msgid "Failed authorization for access key %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:264
+#, python-format
+msgid "No user found for access key %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:270
+#, python-format
+msgid "Using project name = user name (%s)"
+msgstr ""
+
+#: ../nova/auth/manager.py:277
+#, python-format
+msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)"
+msgstr ""
+
+#: ../nova/auth/manager.py:279
+#, python-format
+msgid "No project called %s could be found"
+msgstr ""
+
+#: ../nova/auth/manager.py:287
+#, python-format
+msgid ""
+"Failed authorization: user %(uname)s not admin and not member of project "
+"%(pjname)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:289
+#, python-format
+msgid "User %(uid)s is not a member of project %(pjid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309
+#, python-format
+msgid "Invalid signature for user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310
+msgid "Signature does not match"
+msgstr ""
+
+#: ../nova/auth/manager.py:380
+msgid "Must specify project"
+msgstr ""
+
+#: ../nova/auth/manager.py:414
+#, python-format
+msgid "The %s role can not be found"
+msgstr ""
+
+#: ../nova/auth/manager.py:416
+#, python-format
+msgid "The %s role is global only"
+msgstr ""
+
+#: ../nova/auth/manager.py:420
+#, python-format
+msgid "Adding role %(role)s to user %(uid)s in project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:423
+#, python-format
+msgid "Adding sitewide role %(role)s to user %(uid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:448
+#, python-format
+msgid "Removing role %(role)s from user %(uid)s on project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:451
+#, python-format
+msgid "Removing sitewide role %(role)s from user %(uid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:515
+#, python-format
+msgid "Created project %(name)s with manager %(manager_user)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:533
+#, python-format
+msgid "modifying project %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:545
+#, python-format
+msgid "Adding user %(uid)s to project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:566
+#, python-format
+msgid "Remove user %(uid)s from project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:592
+#, python-format
+msgid "Deleting project %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:650
+#, python-format
+msgid "Created user %(rvname)s (admin: %(rvadmin)r)"
+msgstr ""
+
+#: ../nova/auth/manager.py:659
+#, python-format
+msgid "Deleting user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:669
+#, python-format
+msgid "Access Key change for user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:671
+#, python-format
+msgid "Secret Key change for user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:673
+#, python-format
+msgid "Admin status set to %(admin)r for user %(uid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:722
+#, python-format
+msgid "No vpn data for project %s"
+msgstr ""
+
+#: ../nova/service.py:161
+#, python-format
+msgid "Starting %(topic)s node (version %(vcs_string)s)"
+msgstr ""
+
+#: ../nova/service.py:174
+msgid "Service killed that has no database entry"
+msgstr ""
+
+#: ../nova/service.py:195
+msgid "The service database object disappeared, Recreating it."
+msgstr ""
+
+#: ../nova/service.py:207
+msgid "Recovered model server connection!"
+msgstr ""
+
+#: ../nova/service.py:213
+msgid "model server went away"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:174
+#, python-format
+msgid "LDAP user %s already exists"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:205
+#, python-format
+msgid "LDAP object for %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:348
+#, python-format
+msgid "User %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:472
+#, python-format
+msgid "Group can't be created because group %s already exists"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:478
+#, python-format
+msgid "Group can't be created because user %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:495
+#, python-format
+msgid "User %s can't be searched in group because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:507
+#, python-format
+msgid "User %s can't be added to the group because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521
+#, python-format
+msgid "The group at dn %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:513
+#, python-format
+msgid "User %(uid)s is already a member of the group %(group_dn)s"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:524
+#, python-format
+msgid ""
+"User %s can't be removed from the group because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:528
+#, python-format
+msgid "User %s is not a member of the group"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:542
+#, python-format
+msgid ""
+"Attempted to remove the last member of a group. Deleting the group at %s "
+"instead."
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:549
+#, python-format
+msgid "User %s can't be removed from all because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:564
+#, python-format
+msgid "Group at dn %s doesn't exist"
+msgstr ""
+
+#: ../nova/virt/xenapi/network_utils.py:40
+#, python-format
+msgid "Found non-unique network for bridge %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/network_utils.py:43
+#, python-format
+msgid "Found no network for bridge %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:97
+#, python-format
+msgid "Creating new user: %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:105
+#, python-format
+msgid "Deleting user: %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:127
+#, python-format
+msgid "Adding role %(role)s to user %(user)s for project %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:131
+#, python-format
+msgid "Adding sitewide role %(role)s to user %(user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:137
+#, python-format
+msgid "Removing role %(role)s from user %(user)s for project %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:141
+#, python-format
+msgid "Removing sitewide role %(role)s from user %(user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223
+msgid "operation must be add or remove"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:159
+#, python-format
+msgid "Getting x509 for user: %(name)s on project: %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:177
+#, python-format
+msgid "Create project %(name)s managed by %(manager_user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:190
+#, python-format
+msgid "Modify project: %(name)s managed by %(manager_user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:200
+#, python-format
+msgid "Delete project: %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:214
+#, python-format
+msgid "Adding user %(user)s to project %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:218
+#, python-format
+msgid "Removing user %(user)s from project %(project)s"
+msgstr ""
diff --git a/po/es.po b/po/es.po
index a54260db8..eeaf209a9 100644
--- a/po/es.po
+++ b/po/es.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: nova\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-02-21 10:03-0500\n"
-"PO-Revision-Date: 2011-03-17 15:54+0000\n"
-"Last-Translator: Erick Huezo <erickhuezo@gmail.com>\n"
+"PO-Revision-Date: 2011-06-30 16:42+0000\n"
+"Last-Translator: David Caro <Unknown>\n"
"Language-Team: Spanish <es@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-03-19 06:19+0000\n"
-"X-Generator: Launchpad (build 12559)\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
#: ../nova/scheduler/chance.py:37 ../nova/scheduler/zone.py:55
#: ../nova/scheduler/simple.py:75 ../nova/scheduler/simple.py:110
@@ -36,10 +36,15 @@ msgid ""
"Stdout: %(stdout)r\n"
"Stderr: %(stderr)r"
msgstr ""
+"%(description)s\n"
+"Comando: %(cmd)s\n"
+"Código de salida: %(exit_code)s\n"
+"Stdout: %(stdout)r\n"
+"Stderr: %(stderr)r"
#: ../nova/exception.py:107
msgid "DB exception wrapped"
-msgstr ""
+msgstr "Excepción DB encapsulada"
#. exc_type, exc_value, exc_traceback = sys.exc_info()
#: ../nova/exception.py:120
@@ -49,12 +54,12 @@ msgstr "Excepción no controlada"
#: ../nova/volume/api.py:45
#, python-format
msgid "Quota exceeeded for %(pid)s, tried to create %(size)sG volume"
-msgstr ""
+msgstr "Cuota excedida por %(pid)s, se intentó crear el volumen %(size)sG"
#: ../nova/volume/api.py:47
#, python-format
msgid "Volume quota exceeded. You cannot create a volume of size %sG"
-msgstr "Cuota excedida. No puedes crear un volumen con tamaño %sG"
+msgstr "Cuota excedida. No puede crear un volumen con tamaño %sG"
#: ../nova/volume/api.py:71 ../nova/volume/api.py:96
msgid "Volume status must be available"
@@ -83,7 +88,7 @@ msgstr "%(param)s propiedad no encontrada para la imagen %(_image_id)s"
#: ../nova/api/openstack/servers.py:168
msgid "No keypairs defined"
-msgstr "No se definio una Keypairs"
+msgstr "No se definio un par de llaves (Keypair)"
#: ../nova/api/openstack/servers.py:238
#, python-format
@@ -103,7 +108,7 @@ msgstr "Compute.api::get_lock %s"
#: ../nova/api/openstack/servers.py:281
#, python-format
msgid "Compute.api::reset_network %s"
-msgstr ""
+msgstr "Compute.api::reset_network %s"
#: ../nova/api/openstack/servers.py:292
#, python-format
@@ -127,16 +132,16 @@ msgstr "compute.api::resume %s"
#: ../nova/twistd.py:157
msgid "Wrong number of arguments."
-msgstr "Numero de argumentos incorrectos"
+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. ¿No estará el demonio parado?\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 se encontró proceso"
+msgstr "No existe el proceso"
#: ../nova/twistd.py:230 ../nova/service.py:224
#, python-format
@@ -145,12 +150,12 @@ msgstr "Sirviendo %s"
#: ../nova/twistd.py:262 ../nova/service.py:225
msgid "Full set of FLAGS:"
-msgstr "Conjunto completo de opciones:"
+msgstr "Conjunto completo de opciones (FLAGS):"
#: ../nova/twistd.py:266
#, python-format
msgid "Starting %s"
-msgstr "Comenzando %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
@@ -163,17 +168,19 @@ msgstr "La instancia %s no se ha encontrado"
#: ../nova/virt/xenapi/volumeops.py:51
#, python-format
msgid "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s"
-msgstr ""
+msgstr "Volumen_unido: %(instance_name)s, %(device_path)s, %(mountpoint)s"
#: ../nova/virt/xenapi/volumeops.py:69
#, python-format
msgid "Unable to create VDI on SR %(sr_ref)s for instance %(instance_name)s"
msgstr ""
+"No es posible crear el VDI en SR %(sr_ref)s para la instancia "
+"%(instance_name)s"
#: ../nova/virt/xenapi/volumeops.py:80
#, python-format
msgid "Unable to use SR %(sr_ref)s for instance %(instance_name)s"
-msgstr ""
+msgstr "No es posible usar SR %(sr_ref)s para la instancia %(instance_name)s"
#: ../nova/virt/xenapi/volumeops.py:91
#, python-format
@@ -184,12 +191,14 @@ msgstr "Imposible adjuntar volumen a la instancia %s"
#, python-format
msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s"
msgstr ""
+"El punto de montaje %(mountpoint)s esta unido a la instancia "
+"%(instance_name)s"
#. Detach VBD from VM
#: ../nova/virt/xenapi/volumeops.py:104
#, python-format
msgid "Detach_volume: %(instance_name)s, %(mountpoint)s"
-msgstr ""
+msgstr "Volume_separado: %(instance_name)s, %(mountpoint)s"
#: ../nova/virt/xenapi/volumeops.py:112
#, python-format
@@ -205,6 +214,8 @@ msgstr "Imposible desasociar volumen %s"
#, python-format
msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s"
msgstr ""
+"El punto de montaje %(mountpoint)s se desligó de la instancia "
+"%(instance_name)s"
#: ../nova/compute/instance_types.py:41
#, python-format
@@ -259,7 +270,7 @@ msgstr ""
#: ../nova/crypto.py:258
#, python-format
msgid "Flags path: %s"
-msgstr ""
+msgstr "Ruta a las opciones: %s"
#: ../nova/scheduler/manager.py:69
#, python-format
@@ -276,6 +287,7 @@ msgstr "check_instance_lock: decorating: |%s|"
msgid ""
"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|"
msgstr ""
+"check_instance_lock: argumentos: |%(self)s| |%(context)s| |%(instance_id)s|"
#: ../nova/compute/manager.py:84
#, python-format
@@ -338,6 +350,8 @@ msgid ""
"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s "
"expected: %(running)s)"
msgstr ""
+"intentando reiniciar una instancia no ejecutada: %(instance_id)s (state: "
+"%(state)s expected: %(running)s)"
#: ../nova/compute/manager.py:311
#, python-format
@@ -350,6 +364,8 @@ msgid ""
"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s "
"expected: %(running)s)"
msgstr ""
+"intentando crear una imagen instantanea(snapshot) de una maquina no "
+"ejecutada: %(instance_id)s (state: %(state)s expected: %(running)s)"
#: ../nova/compute/manager.py:332
#, python-format
@@ -357,11 +373,13 @@ msgid ""
"trying to reset the password on a non-running instance: %(instance_id)s "
"(state: %(instance_state)s expected: %(expected_state)s)"
msgstr ""
+"intentando restablecer el password en una instancia: %(instance_id)s "
+"(estado: %(instance_state)s esperado: %(expected_state)s)"
#: ../nova/compute/manager.py:335
#, python-format
msgid "instance %s: setting admin password"
-msgstr ""
+msgstr "instancia %s: estableciendo password de administrador"
#: ../nova/compute/manager.py:353
#, python-format
@@ -369,11 +387,13 @@ msgid ""
"trying to inject a file into a non-running instance: %(instance_id)s (state: "
"%(instance_state)s expected: %(expected_state)s)"
msgstr ""
+"intentando inyectar un archivo dentro de una instancia parada: "
+"%(instance_id)s (estado: %(instance_state)s esperado: %(expected_state)s)"
#: ../nova/compute/manager.py:362
#, python-format
msgid "instance %(nm)s: injecting file to %(plain_path)s"
-msgstr ""
+msgstr "instancia %(nm)s: inyectando archivo en %(plain_path)s"
#: ../nova/compute/manager.py:372
#, python-format
@@ -393,7 +413,7 @@ msgstr "instancia %s: pausando"
#: ../nova/compute/manager.py:423
#, python-format
msgid "instance %s: unpausing"
-msgstr "instnacia %s: continuando tras pausa"
+msgstr "instancia %s: continuando tras pausa"
#: ../nova/compute/manager.py:440
#, python-format
@@ -403,7 +423,7 @@ msgstr "instancia %s: obteniendo los diagnosticos"
#: ../nova/compute/manager.py:453
#, python-format
msgid "instance %s: suspending"
-msgstr ""
+msgstr "instancia %s: suspendiendo"
#: ../nova/compute/manager.py:472
#, python-format
@@ -501,7 +521,7 @@ msgstr "Exportando de nuevo los volumenes %s"
#: ../nova/volume/manager.py:90
#, python-format
msgid "volume %s: skipping export"
-msgstr ""
+msgstr "volume %s: saltando exportación"
#: ../nova/volume/manager.py:96
#, python-format
@@ -511,7 +531,7 @@ msgstr "volumen %s: creando"
#: ../nova/volume/manager.py:108
#, python-format
msgid "volume %(vol_name)s: creating lv of size %(vol_size)sG"
-msgstr ""
+msgstr "volume %(vol_name)s: creando lv del tamaño %(vol_size)sG"
#: ../nova/volume/manager.py:112
#, python-format
@@ -549,7 +569,7 @@ msgstr "volumen %s: eliminado satisfactoriamente"
#: ../nova/virt/xenapi/fake.py:74
#, python-format
msgid "%(text)s: _db_content => %(content)s"
-msgstr ""
+msgstr "%(text)s: _db_content => %(content)s"
#: ../nova/virt/xenapi/fake.py:304 ../nova/virt/xenapi/fake.py:404
#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478
@@ -564,7 +584,7 @@ msgstr "xenapi.fake no tiene una implementación para %s"
#: ../nova/virt/xenapi/fake.py:341
#, python-format
msgid "Calling %(localname)s %(impl)s"
-msgstr ""
+msgstr "Llamando %(localname)s %(impl)s"
#: ../nova/virt/xenapi/fake.py:346
#, python-format
@@ -618,12 +638,12 @@ msgstr "El pid %d está pasado, relanzando dnsmasq"
#: ../nova/network/linux_net.py:358
#, python-format
msgid "killing radvd threw %s"
-msgstr ""
+msgstr "Matando radvd lanzado %s"
#: ../nova/network/linux_net.py:360
#, python-format
msgid "Pid %d is stale, relaunching radvd"
-msgstr ""
+msgstr "Pid %d corrupto, relanzando radvd"
#. pylint: disable=W0703
#: ../nova/network/linux_net.py:449
@@ -659,7 +679,7 @@ msgstr "El resultado fue %s"
#: ../nova/utils.py:159
#, python-format
msgid "Running cmd (SSH): %s"
-msgstr ""
+msgstr "corriendo cmd (SSH): %s"
#: ../nova/utils.py:217
#, python-format
@@ -674,12 +694,12 @@ msgstr "Ejecutando %s"
#: ../nova/utils.py:262
#, python-format
msgid "Link Local address is not found.:%s"
-msgstr ""
+msgstr "No se encuentra la dirección del enlace local.:%s"
#: ../nova/utils.py:265
#, python-format
msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s"
-msgstr ""
+msgstr "No se pudo obtener enlace de la ip local de %(interface)s :%(ex)s"
#: ../nova/utils.py:363
#, python-format
@@ -694,7 +714,7 @@ msgstr "backend %s"
#: ../nova/fakerabbit.py:49
#, python-format
msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s"
-msgstr ""
+msgstr "(%(nm)s) publica (key: %(routing_key)s) %(message)s"
#: ../nova/fakerabbit.py:54
#, python-format
@@ -714,12 +734,12 @@ msgstr "Declarando intercambio %s"
#: ../nova/fakerabbit.py:96
#, python-format
msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s"
-msgstr ""
+msgstr "Enlazando %(queue)s a %(exchange)s con la llave %(routing_key)s"
#: ../nova/fakerabbit.py:121
#, python-format
msgid "Getting from %(queue)s: %(message)s"
-msgstr ""
+msgstr "Obtendiendo desde %(queue)s: %(message)s"
#: ../nova/virt/xenapi/vm_utils.py:135 ../nova/virt/hyperv.py:171
#, python-format
@@ -729,17 +749,17 @@ msgstr "Creada VM %s..."
#: ../nova/virt/xenapi/vm_utils.py:138
#, python-format
msgid "Created VM %(instance_name)s as %(vm_ref)s."
-msgstr ""
+msgstr "VM creada %(instance_name)s como %(vm_ref)s."
#: ../nova/virt/xenapi/vm_utils.py:168
#, python-format
msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... "
-msgstr ""
+msgstr "Creando VBD para VM %(vm_ref)s, VDI %(vdi_ref)s ... "
#: ../nova/virt/xenapi/vm_utils.py:171
#, python-format
msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s."
-msgstr ""
+msgstr "Creado el VBD %(vbd_ref)s para VM %(vm_ref)s, VDI %(vdi_ref)s"
#: ../nova/virt/xenapi/vm_utils.py:187
#, python-format
@@ -759,12 +779,12 @@ msgstr "Imposible destruir VBD %s"
#: ../nova/virt/xenapi/vm_utils.py:224
#, python-format
msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s."
-msgstr ""
+msgstr "Creando VIF para VM %(vm_ref)s, red %(network_ref)s."
#: ../nova/virt/xenapi/vm_utils.py:227
#, python-format
msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s."
-msgstr ""
+msgstr "Creado el VIF %(vif_ref)s para VM %(vm_ref)s, red %(network_ref)s."
#: ../nova/virt/xenapi/vm_utils.py:246
#, python-format
@@ -772,50 +792,52 @@ msgid ""
"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on "
"%(sr_ref)s."
msgstr ""
+"VDI creado %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) "
+"sobre %(sr_ref)s."
#. TODO(sirp): Add quiesce and VSS locking support when Windows support
#. is added
#: ../nova/virt/xenapi/vm_utils.py:258
#, python-format
msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..."
-msgstr ""
+msgstr "Creando snapshot de la VM %(vm_ref)s con etiqueta '%(label)s'..."
#: ../nova/virt/xenapi/vm_utils.py:272
#, python-format
msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s."
-msgstr ""
+msgstr "Instantánea creada %(template_vm_ref)s de la VM %(vm_ref)s."
#: ../nova/virt/xenapi/vm_utils.py:286
#, python-format
msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s"
-msgstr ""
+msgstr "Pidiendo xapi a subir %(vdi_uuids)s como ID %(image_id)s"
#: ../nova/virt/xenapi/vm_utils.py:327
#, python-format
msgid "Size for image %(image)s:%(virtual_size)d"
-msgstr ""
+msgstr "Tamaño para imagen %(image)s:%(virtual_size)d"
#: ../nova/virt/xenapi/vm_utils.py:332
#, python-format
msgid "Glance image %s"
-msgstr ""
+msgstr "Imagen Glance %s"
#. we need to invoke a plugin for copying VDI's
#. content into proper path
#: ../nova/virt/xenapi/vm_utils.py:342
#, python-format
msgid "Copying VDI %s to /boot/guest on dom0"
-msgstr ""
+msgstr "Copiando VDI %s a /boot/guest on dom0"
#: ../nova/virt/xenapi/vm_utils.py:352
#, python-format
msgid "Kernel/Ramdisk VDI %s destroyed"
-msgstr ""
+msgstr "Kernel/Ramdisk VDI %s destruído"
#: ../nova/virt/xenapi/vm_utils.py:361
#, python-format
msgid "Asking xapi to fetch %(url)s as %(access)s"
-msgstr ""
+msgstr "Pidiendo a xapi que descargue %(url)s como %(access)s"
#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402
#, python-format
@@ -825,21 +847,21 @@ msgstr "Buscando vid %s para el kernel PV"
#: ../nova/virt/xenapi/vm_utils.py:397
#, python-format
msgid "PV Kernel in VDI:%s"
-msgstr ""
+msgstr "Kernel PV en VDI:%s"
#: ../nova/virt/xenapi/vm_utils.py:405
#, python-format
msgid "Running pygrub against %s"
-msgstr ""
+msgstr "Ejecutando pygrub contra %s"
#: ../nova/virt/xenapi/vm_utils.py:411
#, python-format
msgid "Found Xen kernel %s"
-msgstr ""
+msgstr "Kernel Xen Encontrado %s"
#: ../nova/virt/xenapi/vm_utils.py:413
msgid "No Xen kernel found. Booting HVM."
-msgstr ""
+msgstr "Kernel Xen no encontrado. Reiniciando HVM"
#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431
#, python-format
@@ -864,7 +886,7 @@ msgstr "(VM_UTILS) xenapi power_state -> |%s|"
#: ../nova/virt/xenapi/vm_utils.py:525
#, python-format
msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s"
-msgstr ""
+msgstr "VHD %(vdi_uuid)s tiene origen en %(parent_ref)s"
#: ../nova/virt/xenapi/vm_utils.py:542
#, python-format
@@ -893,18 +915,19 @@ msgstr "No se han encontrado VDI's para VM %s"
#, python-format
msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s"
msgstr ""
+"Numero de VDIs inesperado (%(num_vdis)s) encontrados por VM %(vm_ref)s"
#: ../nova/virt/xenapi/vm_utils.py:653
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188
#, python-format
msgid "Creating VBD for VDI %s ... "
-msgstr ""
+msgstr "Creando VBD para VDI %s ... "
#: ../nova/virt/xenapi/vm_utils.py:655
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190
#, python-format
msgid "Creating VBD for VDI %s done."
-msgstr ""
+msgstr "Creando VBF para VDI %s terminado"
#: ../nova/virt/xenapi/vm_utils.py:657
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192
@@ -2850,12 +2873,12 @@ msgstr ""
#: ../nova/api/ec2/admin.py:177
#, python-format
msgid "Create project %(name)s managed by %(manager_user)s"
-msgstr ""
+msgstr "Crear proyecto %(name)s administrador por %(manager_user)s"
#: ../nova/api/ec2/admin.py:190
#, python-format
msgid "Modify project: %(name)s managed by %(manager_user)s"
-msgstr ""
+msgstr "Modificar proyecto: %(name)s administrado por %(manager_user)s"
#: ../nova/api/ec2/admin.py:200
#, python-format
@@ -2865,12 +2888,12 @@ msgstr "Borrar proyecto: %s"
#: ../nova/api/ec2/admin.py:214
#, python-format
msgid "Adding user %(user)s to project %(project)s"
-msgstr ""
+msgstr "Agregando usuario %(user)s al proyecto %(project)s"
#: ../nova/api/ec2/admin.py:218
#, python-format
msgid "Removing user %(user)s from project %(project)s"
-msgstr ""
+msgstr "Eliminando el usuario %(user)s del proyecto %(project)s"
#, python-format
#~ msgid ""
diff --git a/po/fr.po b/po/fr.po
new file mode 100644
index 000000000..9dd789b3c
--- /dev/null
+++ b/po/fr.po
@@ -0,0 +1,2992 @@
+# French translation for nova
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the nova package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: nova\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-02-21 10:03-0500\n"
+"PO-Revision-Date: 2011-05-27 16:50+0000\n"
+"Last-Translator: Capashen <Unknown>\n"
+"Language-Team: French <fr@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
+
+#: ../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
+msgid "No hosts found"
+msgstr "Pas d'hôte trouvé"
+
+#: ../nova/exception.py:33
+msgid "Unexpected error while running command."
+msgstr "Erreur imprévue lors de l'éxecution de la commande"
+
+#: ../nova/exception.py:36
+#, python-format
+msgid ""
+"%(description)s\n"
+"Command: %(cmd)s\n"
+"Exit code: %(exit_code)s\n"
+"Stdout: %(stdout)r\n"
+"Stderr: %(stderr)r"
+msgstr ""
+"%(description)s\n"
+"Commande : %(cmd)s\n"
+"Valeur retournée : %(exit_code)s\n"
+"Sortie standard : %(stdout)r\n"
+"Sortie d'erreur : %(stderr)r"
+
+#: ../nova/exception.py:107
+msgid "DB exception wrapped"
+msgstr "Remontée d'exception de la base de données"
+
+#. exc_type, exc_value, exc_traceback = sys.exc_info()
+#: ../nova/exception.py:120
+msgid "Uncaught exception"
+msgstr "Exception non prévue"
+
+#: ../nova/volume/api.py:45
+#, python-format
+msgid "Quota exceeeded for %(pid)s, tried to create %(size)sG volume"
+msgstr ""
+"Quota dépassé pour %(pid)s lors d'une tentative de création d'un volume de "
+"%(size)sG"
+
+#: ../nova/volume/api.py:47
+#, python-format
+msgid "Volume quota exceeded. You cannot create a volume of size %sG"
+msgstr "Quota de volume dépassé. Vous ne pouvez pas créer un volume de %sG"
+
+#: ../nova/volume/api.py:71 ../nova/volume/api.py:96
+msgid "Volume status must be available"
+msgstr "Le status du volume doit être disponible"
+
+#: ../nova/volume/api.py:98
+msgid "Volume is already attached"
+msgstr "Volume déjà attaché"
+
+#: ../nova/volume/api.py:104
+msgid "Volume is already detached"
+msgstr "Volume déjà déttaché"
+
+#: ../nova/api/openstack/servers.py:72
+msgid "Failed to read private ip"
+msgstr "Echec lors de la lecture de l'ip privée"
+
+#: ../nova/api/openstack/servers.py:79
+msgid "Failed to read public ip(s)"
+msgstr "Echec lors de la lecture de l'ip(s) privée(s)"
+
+#: ../nova/api/openstack/servers.py:152
+#, python-format
+msgid "%(param)s property not found for image %(_image_id)s"
+msgstr ""
+"La propriété %(param)s n'a pas été trouvée pour l'image %(_image_id)s"
+
+#: ../nova/api/openstack/servers.py:168
+msgid "No keypairs defined"
+msgstr "Pas de paire de clés définie"
+
+#: ../nova/api/openstack/servers.py:238
+#, python-format
+msgid "Compute.api::lock %s"
+msgstr "Compute.api::lock %s"
+
+#: ../nova/api/openstack/servers.py:253
+#, python-format
+msgid "Compute.api::unlock %s"
+msgstr "Compute.api::unlock %s"
+
+#: ../nova/api/openstack/servers.py:267
+#, python-format
+msgid "Compute.api::get_lock %s"
+msgstr "Compute.api::get_lock %s"
+
+#: ../nova/api/openstack/servers.py:281
+#, python-format
+msgid "Compute.api::reset_network %s"
+msgstr "Compute.api::reset_network %s"
+
+#: ../nova/api/openstack/servers.py:292
+#, python-format
+msgid "Compute.api::pause %s"
+msgstr "Compute.api::pause %s"
+
+#: ../nova/api/openstack/servers.py:303
+#, python-format
+msgid "Compute.api::unpause %s"
+msgstr "Compute.api::unpause %s"
+
+#: ../nova/api/openstack/servers.py:314
+#, python-format
+msgid "compute.api::suspend %s"
+msgstr "compute.api::suspend %s"
+
+#: ../nova/api/openstack/servers.py:325
+#, python-format
+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
+#, python-format
+msgid "Instance %s not found"
+msgstr "Instance %s non trouvée"
+
+#. NOTE: No Resource Pool concept so far
+#: ../nova/virt/xenapi/volumeops.py:51
+#, python-format
+msgid "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s"
+msgstr "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s"
+
+#: ../nova/virt/xenapi/volumeops.py:69
+#, python-format
+msgid "Unable to create VDI on SR %(sr_ref)s for instance %(instance_name)s"
+msgstr ""
+"Impossible de créer VDI sur SR %(sr_ref)s pour l'instance %(instance_name)s"
+
+#: ../nova/virt/xenapi/volumeops.py:80
+#, python-format
+msgid "Unable to use SR %(sr_ref)s for instance %(instance_name)s"
+msgstr ""
+"Impossible d'utiliser SR %(sr_ref)s pour l'instance %(instance_name)s"
+
+#: ../nova/virt/xenapi/volumeops.py:91
+#, python-format
+msgid "Unable to attach volume to instance %s"
+msgstr "Impossible d'attacher le volume à l'instance %s"
+
+#: ../nova/virt/xenapi/volumeops.py:93
+#, python-format
+msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s"
+msgstr ""
+"Le point de montage %(mountpoint)s a été attaché à l'instance "
+"%(instance_name)s"
+
+#. Detach VBD from VM
+#: ../nova/virt/xenapi/volumeops.py:104
+#, python-format
+msgid "Detach_volume: %(instance_name)s, %(mountpoint)s"
+msgstr "Detach_volume: %(instance_name)s, %(mountpoint)s"
+
+#: ../nova/virt/xenapi/volumeops.py:112
+#, python-format
+msgid "Unable to locate volume %s"
+msgstr "Impossible de trouver le volume %s"
+
+#: ../nova/virt/xenapi/volumeops.py:120
+#, python-format
+msgid "Unable to detach volume %s"
+msgstr "Impossible de détacher le volume %s"
+
+#: ../nova/virt/xenapi/volumeops.py:127
+#, python-format
+msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s"
+msgstr ""
+"Le point de montage %(mountpoint)s à été détaché de l'instance "
+"%(instance_name)s"
+
+#: ../nova/compute/instance_types.py:41
+#, python-format
+msgid "Unknown instance type: %s"
+msgstr "Type d'instance inconnu: %s"
+
+#: ../nova/crypto.py:46
+msgid "Filename of root CA"
+msgstr "Nom du fichier contenant la racine de l'autorité de certification"
+
+#: ../nova/crypto.py:49
+msgid "Filename of private key"
+msgstr "Nom de fichier de la clé privée"
+
+#: ../nova/crypto.py:51
+msgid "Filename of root Certificate Revokation List"
+msgstr "Nom de fichier de la racine de liste de révocation (CRL)"
+
+#: ../nova/crypto.py:53
+msgid "Where we keep our keys"
+msgstr "Emplacement de sauvegarde des clefs"
+
+#: ../nova/crypto.py:55
+msgid "Where we keep our root CA"
+msgstr "Emplacement de sauvegarde des racines d'autorité de certification"
+
+#: ../nova/crypto.py:57
+msgid "Should we use a CA for each project?"
+msgstr "Doit-on utiliser une autorité de certification pour chaque projet ?"
+
+#: ../nova/crypto.py:61
+#, python-format
+msgid "Subject for certificate for users, %s for project, user, timestamp"
+msgstr ""
+"Sujet pour les certificats utilisateurs, %s pour le projet, utilisateur, "
+"timestamp"
+
+#: ../nova/crypto.py:66
+#, python-format
+msgid "Subject for certificate for projects, %s for project, timestamp"
+msgstr "Sujet de certificat pour projets, %s pour le projet, timestamp"
+
+#: ../nova/crypto.py:71
+#, python-format
+msgid "Subject for certificate for vpns, %s for project, timestamp"
+msgstr "Suject de certificat pour les vpns, %s pour le projet, timestamp"
+
+#: ../nova/crypto.py:258
+#, python-format
+msgid "Flags path: %s"
+msgstr "Chemin des propriétés: %s"
+
+#: ../nova/scheduler/manager.py:69
+#, python-format
+msgid "Casting to %(topic)s %(host)s for %(method)s"
+msgstr "Typage de %(topic)s %(host)s pour %(method)s"
+
+#: ../nova/compute/manager.py:78
+#, python-format
+msgid "check_instance_lock: decorating: |%s|"
+msgstr "check_instance_lock: décoration : |%s|"
+
+#: ../nova/compute/manager.py:80
+#, python-format
+msgid ""
+"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|"
+msgstr ""
+"check_instance_lock: arguments : |%(self)s| |%(context)s| |%(instance_id)s|"
+
+#: ../nova/compute/manager.py:84
+#, python-format
+msgid "check_instance_lock: locked: |%s|"
+msgstr "check_instance_lock: vérouillé : |%s|"
+
+#: ../nova/compute/manager.py:86
+#, python-format
+msgid "check_instance_lock: admin: |%s|"
+msgstr "check_instance_lock: admin : |%s|"
+
+#: ../nova/compute/manager.py:91
+#, python-format
+msgid "check_instance_lock: executing: |%s|"
+msgstr "check_instance_lock: exécution : |%s|"
+
+#: ../nova/compute/manager.py:95
+#, python-format
+msgid "check_instance_lock: not executing |%s|"
+msgstr "check_instance_lock: ne s'éxécute pas |%s|"
+
+#: ../nova/compute/manager.py:179
+msgid "Instance has already been created"
+msgstr "L'instance a déjà été crée"
+
+#: ../nova/compute/manager.py:180
+#, python-format
+msgid "instance %s: starting..."
+msgstr "L'instance %s: est en train d'être démarée..."
+
+#. pylint: disable=W0702
+#: ../nova/compute/manager.py:219
+#, python-format
+msgid "instance %s: Failed to spawn"
+msgstr "instance %s: n'a pas pu être crée"
+
+#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286
+#, python-format
+msgid "Terminating instance %s"
+msgstr "Arrêt de l'instance %s"
+
+#: ../nova/compute/manager.py:255
+#, python-format
+msgid "Deallocating address %s"
+msgstr "Dé-allocation de l'adresss %s"
+
+#: ../nova/compute/manager.py:268
+#, python-format
+msgid "trying to destroy already destroyed instance: %s"
+msgstr "Tentative de destruction d'une instance déjà détruite: %s"
+
+#: ../nova/compute/manager.py:282
+#, python-format
+msgid "Rebooting instance %s"
+msgstr "Redémarrage de l'instance %s"
+
+#: ../nova/compute/manager.py:287
+#, python-format
+msgid ""
+"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s "
+"expected: %(running)s)"
+msgstr ""
+"Tentative de redémarrage d'une instance non démarrée: %(instance_id)s "
+"(state: %(state)s s'attendait à : %(running)s)"
+
+#: ../nova/compute/manager.py:311
+#, python-format
+msgid "instance %s: snapshotting"
+msgstr "instance %s: création d'un instantané (snapshot)"
+
+#: ../nova/compute/manager.py:316
+#, python-format
+msgid ""
+"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s "
+"expected: %(running)s)"
+msgstr ""
+"Tentative de création d'un instantané (snapshot) pour une instance non "
+"démarrée: %(instance_id)s (state: %(state)s sattendait à : %(running)s)"
+
+#: ../nova/compute/manager.py:332
+#, python-format
+msgid ""
+"trying to reset the password on a non-running instance: %(instance_id)s "
+"(state: %(instance_state)s expected: %(expected_state)s)"
+msgstr ""
+"Tentative de ré-initialisation du mot de passe pour une instance non "
+"démarrée: %(instance_id)s (state: %(instance_state)s expected: "
+"%(expected_state)s)"
+
+#: ../nova/compute/manager.py:335
+#, python-format
+msgid "instance %s: setting admin password"
+msgstr "instance %s: configuration du mot de passe admin"
+
+#: ../nova/compute/manager.py:353
+#, python-format
+msgid ""
+"trying to inject a file into a non-running instance: %(instance_id)s (state: "
+"%(instance_state)s expected: %(expected_state)s)"
+msgstr ""
+"Tentative d'injection d'un fichier pour une instance non "
+"démarrée:%(instance_id)s (state: %(instance_state)s s'attendait à : "
+"%(expected_state)s)"
+
+#: ../nova/compute/manager.py:362
+#, python-format
+msgid "instance %(nm)s: injecting file to %(plain_path)s"
+msgstr "instance %(nm)s: injection de fichier vers %(plain_path)s"
+
+#: ../nova/compute/manager.py:372
+#, python-format
+msgid "instance %s: rescuing"
+msgstr "instance %s: récupération"
+
+#: ../nova/compute/manager.py:387
+#, python-format
+msgid "instance %s: unrescuing"
+msgstr "instance %s: dé-récupération"
+
+#: ../nova/compute/manager.py:406
+#, python-format
+msgid "instance %s: pausing"
+msgstr "instance %s: mise en pause"
+
+#: ../nova/compute/manager.py:423
+#, python-format
+msgid "instance %s: unpausing"
+msgstr "instance %s: reprise après pause"
+
+#: ../nova/compute/manager.py:440
+#, python-format
+msgid "instance %s: retrieving diagnostics"
+msgstr "instance %s: récupération des diagnostiques"
+
+#: ../nova/compute/manager.py:453
+#, python-format
+msgid "instance %s: suspending"
+msgstr "instance %s: suspension"
+
+#: ../nova/compute/manager.py:472
+#, python-format
+msgid "instance %s: resuming"
+msgstr "instance %s: reprise après suspension"
+
+#: ../nova/compute/manager.py:491
+#, python-format
+msgid "instance %s: locking"
+msgstr "instance %s: vérrouillage"
+
+#: ../nova/compute/manager.py:503
+#, python-format
+msgid "instance %s: unlocking"
+msgstr "instance %s: déverrouillage"
+
+#: ../nova/compute/manager.py:513
+#, python-format
+msgid "instance %s: getting locked state"
+msgstr "instance %s: récupération de l'état de vérouillage"
+
+#: ../nova/compute/manager.py:526
+#, python-format
+msgid "instance %s: reset network"
+msgstr "instance %s: redémarrage du réseau"
+
+#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515
+#, python-format
+msgid "Get console output for instance %s"
+msgstr "Récupération de la sortie de la console de l'instance %s"
+
+#: ../nova/compute/manager.py:543
+#, python-format
+msgid "instance %s: getting ajax console"
+msgstr "instance %s: préparation d'une console ajax"
+
+#: ../nova/compute/manager.py:553
+#, python-format
+msgid ""
+"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s"
+msgstr ""
+"instance %(instance_id)s: montage du volume %(volume_id)s à %(mountpoint)s"
+
+#. pylint: disable=W0702
+#. NOTE(vish): The inline callback eats the exception info so we
+#. log the traceback here and reraise the same
+#. ecxception below.
+#: ../nova/compute/manager.py:569
+#, python-format
+msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing"
+msgstr ""
+"instance %(instance_id)s: Échec de montage %(mountpoint)s, supression"
+
+#: ../nova/compute/manager.py:585
+#, python-format
+msgid ""
+"Detach volume %(volume_id)s from mountpoint %(mp)s on instance "
+"%(instance_id)s"
+msgstr ""
+"Démontage du volume %(volume_id)s du point de montage %(mp)s sur l'instance "
+"%(instance_id)s"
+
+#: ../nova/compute/manager.py:588
+#, python-format
+msgid "Detaching volume from unknown instance %s"
+msgstr "Démontage de volume d'une instance inconnue %s"
+
+#: ../nova/scheduler/simple.py:53
+#, python-format
+msgid "Host %s is not alive"
+msgstr "Host %s n'est pas en fonction"
+
+#: ../nova/scheduler/simple.py:65
+msgid "All hosts have too many cores"
+msgstr "Tous les hôtes ont trop de coeurs"
+
+#: ../nova/scheduler/simple.py:87
+#, python-format
+msgid "Host %s not available"
+msgstr "Hôte %s non disponible"
+
+#: ../nova/scheduler/simple.py:99
+msgid "All hosts have too many gigabytes"
+msgstr "Tous les hôtes ont trop de mémoire"
+
+#: ../nova/scheduler/simple.py:119
+msgid "All hosts have too many networks"
+msgstr "Tous les hôtes ont trop de réseaux"
+
+#: ../nova/volume/manager.py:85
+#, python-format
+msgid "Re-exporting %s volumes"
+msgstr "Ré-exportation de %s volumes"
+
+#: ../nova/volume/manager.py:90
+#, python-format
+msgid "volume %s: skipping export"
+msgstr "volume %s : exportation évitée"
+
+#: ../nova/volume/manager.py:96
+#, python-format
+msgid "volume %s: creating"
+msgstr "volume %s: création"
+
+#: ../nova/volume/manager.py:108
+#, python-format
+msgid "volume %(vol_name)s: creating lv of size %(vol_size)sG"
+msgstr "volume %(vol_name)s: cŕeation d'un volume logique de %(vol_size)sG"
+
+#: ../nova/volume/manager.py:112
+#, python-format
+msgid "volume %s: creating export"
+msgstr "volume %s: exportation en cours"
+
+#: ../nova/volume/manager.py:123
+#, python-format
+msgid "volume %s: created successfully"
+msgstr "volume %s: crée avec succès"
+
+#: ../nova/volume/manager.py:131
+msgid "Volume is still attached"
+msgstr "Le volume est encore attaché"
+
+#: ../nova/volume/manager.py:133
+msgid "Volume is not local to this node"
+msgstr "Le volume n'est pas local à ce noeud"
+
+#: ../nova/volume/manager.py:136
+#, python-format
+msgid "volume %s: removing export"
+msgstr "volume %s: suppression de l'exportation"
+
+#: ../nova/volume/manager.py:138
+#, python-format
+msgid "volume %s: deleting"
+msgstr "volume %s: suppression"
+
+#: ../nova/volume/manager.py:147
+#, python-format
+msgid "volume %s: deleted successfully"
+msgstr "volume %s: supprimé avec succès"
+
+#: ../nova/virt/xenapi/fake.py:74
+#, python-format
+msgid "%(text)s: _db_content => %(content)s"
+msgstr "%(text)s: _db_content => %(content)s"
+
+#: ../nova/virt/xenapi/fake.py:304 ../nova/virt/xenapi/fake.py:404
+#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478
+msgid "Raising NotImplemented"
+msgstr "Fonction non implémentée"
+
+#: ../nova/virt/xenapi/fake.py:306
+#, python-format
+msgid "xenapi.fake does not have an implementation for %s"
+msgstr "xenapi.fake n'a pas d'implémentation pour %s"
+
+#: ../nova/virt/xenapi/fake.py:341
+#, python-format
+msgid "Calling %(localname)s %(impl)s"
+msgstr "Appel %(localname)s %(impl)s"
+
+#: ../nova/virt/xenapi/fake.py:346
+#, python-format
+msgid "Calling getter %s"
+msgstr "Appel du getter %s"
+
+#: ../nova/virt/xenapi/fake.py:406
+#, python-format
+msgid ""
+"xenapi.fake does not have an implementation for %s or it has been called "
+"with the wrong number of arguments"
+msgstr ""
+"xenapi.fake n'a pas d'implementation pour %s ou il a été appelé avec le "
+"mauvais nombre d'arguments"
+
+#: ../nova/tests/test_cloud.py:256
+msgid "Can't test instances without a real virtual env."
+msgstr "Ne peut pas tester les instances sans un env virtuel."
+
+#: ../nova/tests/test_cloud.py:268
+#, python-format
+msgid "Need to watch instance %s until it's running..."
+msgstr "Besoin de surveiller l'instance %s jusqu'à son démarrage..."
+
+#: ../nova/virt/connection.py:73
+msgid "Failed to open connection to the hypervisor"
+msgstr "Échec lors de l'ouverture d'une connexion à l'hyperviseur"
+
+#: ../nova/network/linux_net.py:187
+#, python-format
+msgid "Starting VLAN inteface %s"
+msgstr "Démarrage de l'interface VLAN %s"
+
+#: ../nova/network/linux_net.py:208
+#, python-format
+msgid "Starting Bridge interface for %s"
+msgstr "Démarrage de l'interface de Bridge %s"
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:314
+#, python-format
+msgid "Hupping dnsmasq threw %s"
+msgstr "Hupping dnsmasq à renvoyé %s"
+
+#: ../nova/network/linux_net.py:316
+#, python-format
+msgid "Pid %d is stale, relaunching dnsmasq"
+msgstr "Pid %d est dépassé, re-démarrage de dnsmasq"
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:358
+#, python-format
+msgid "killing radvd threw %s"
+msgstr "La destruction de radvd à renvoyé %s"
+
+#: ../nova/network/linux_net.py:360
+#, python-format
+msgid "Pid %d is stale, relaunching radvd"
+msgstr "Pid %d est dépassé, re-démarrage radvd"
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:449
+#, python-format
+msgid "Killing dnsmasq threw %s"
+msgstr "La destruction de dnsmasq à renvoyé %s"
+
+#: ../nova/utils.py:58
+#, python-format
+msgid "Inner Exception: %s"
+msgstr "Exception interne : %s"
+
+#: ../nova/utils.py:59
+#, python-format
+msgid "Class %s cannot be found"
+msgstr "La classe %s n'a pas pu être trouvée"
+
+#: ../nova/utils.py:118
+#, python-format
+msgid "Fetching %s"
+msgstr "Récupèration de %s"
+
+#: ../nova/utils.py:130
+#, python-format
+msgid "Running cmd (subprocess): %s"
+msgstr "Execution de la commande (sous-processus) : %s"
+
+#: ../nova/utils.py:143 ../nova/utils.py:183
+#, python-format
+msgid "Result was %s"
+msgstr "Le résultat était %s"
+
+#: ../nova/utils.py:159
+#, python-format
+msgid "Running cmd (SSH): %s"
+msgstr "Execution de la cmd (SSH): %s"
+
+#: ../nova/utils.py:217
+#, python-format
+msgid "debug in callback: %s"
+msgstr "Debug dans le rappel : %s"
+
+#: ../nova/utils.py:222
+#, python-format
+msgid "Running %s"
+msgstr "Exécution de %s"
+
+#: ../nova/utils.py:262
+#, python-format
+msgid "Link Local address is not found.:%s"
+msgstr "L'adresse du lien local n'a pas été trouvé :%s"
+
+#: ../nova/utils.py:265
+#, python-format
+msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s"
+msgstr "Impossible de trouver l'IP du lien local de %(interface)s :%(ex)s"
+
+#: ../nova/utils.py:363
+#, python-format
+msgid "Invalid backend: %s"
+msgstr "Backend invalide : %s"
+
+#: ../nova/utils.py:374
+#, python-format
+msgid "backend %s"
+msgstr "backend %s"
+
+#: ../nova/fakerabbit.py:49
+#, python-format
+msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s"
+msgstr "(%(nm)s) publication (key: %(routing_key)s) %(message)s"
+
+#: ../nova/fakerabbit.py:54
+#, python-format
+msgid "Publishing to route %s"
+msgstr "Publication vers la route %s"
+
+#: ../nova/fakerabbit.py:84
+#, python-format
+msgid "Declaring queue %s"
+msgstr "Déclaration de la queue %s"
+
+#: ../nova/fakerabbit.py:90
+#, python-format
+msgid "Declaring exchange %s"
+msgstr "Déclaration de l'échange %s"
+
+#: ../nova/fakerabbit.py:96
+#, python-format
+msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s"
+msgstr ""
+"Rattachement de %(queue)s vers %(exchange)s avec la clef %(routing_key)s"
+
+#: ../nova/fakerabbit.py:121
+#, python-format
+msgid "Getting from %(queue)s: %(message)s"
+msgstr "Récupération depuis %(queue)s: %(message)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:135 ../nova/virt/hyperv.py:171
+#, python-format
+msgid "Created VM %s..."
+msgstr "VM %s crée..."
+
+#: ../nova/virt/xenapi/vm_utils.py:138
+#, python-format
+msgid "Created VM %(instance_name)s as %(vm_ref)s."
+msgstr "VM %(instance_name)s crée en tant que %(vm_ref)s."
+
+#: ../nova/virt/xenapi/vm_utils.py:168
+#, python-format
+msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... "
+msgstr "Création de VBD pour VM %(vm_ref)s, VDI %(vdi_ref)s ... "
+
+#: ../nova/virt/xenapi/vm_utils.py:171
+#, python-format
+msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s."
+msgstr "VBD créé %(vbd_ref)s pour VM %(vm_ref)s, VDI %(vdi_ref)s."
+
+#: ../nova/virt/xenapi/vm_utils.py:187
+#, python-format
+msgid "VBD not found in instance %s"
+msgstr "VBD non trouvé dans l'instance %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:197
+#, python-format
+msgid "Unable to unplug VBD %s"
+msgstr "Impossible de deconnecter le VBD %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:209
+#, python-format
+msgid "Unable to destroy VBD %s"
+msgstr "Impossible de supprimer le VBD %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:224
+#, python-format
+msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s."
+msgstr "Création du VIF pour la VM %(vm_ref)s, réseau %(network_ref)s."
+
+#: ../nova/virt/xenapi/vm_utils.py:227
+#, python-format
+msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s."
+msgstr "VIF créé %(vif_ref)s pour la VM %(vm_ref)s, network %(network_ref)s."
+
+#: ../nova/virt/xenapi/vm_utils.py:246
+#, python-format
+msgid ""
+"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on "
+"%(sr_ref)s."
+msgstr ""
+"VDI créé %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on "
+"%(sr_ref)s."
+
+#. TODO(sirp): Add quiesce and VSS locking support when Windows support
+#. is added
+#: ../nova/virt/xenapi/vm_utils.py:258
+#, python-format
+msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..."
+msgstr ""
+"Création de l'instantané (snapshot) pour la VM %(vm_ref)s avec le label "
+"'%(label)s'..."
+
+#: ../nova/virt/xenapi/vm_utils.py:272
+#, python-format
+msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s."
+msgstr ""
+"Instantané (snapshot) créé %(template_vm_ref)s pour la VM %(vm_ref)s."
+
+#: ../nova/virt/xenapi/vm_utils.py:286
+#, python-format
+msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s"
+msgstr ""
+"Demande de chargement à xapi de %(vdi_uuids)s en tant qu'ID %(image_id)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:327
+#, python-format
+msgid "Size for image %(image)s:%(virtual_size)d"
+msgstr "Taille de l'image %(image)s:%(virtual_size)d"
+
+#: ../nova/virt/xenapi/vm_utils.py:332
+#, python-format
+msgid "Glance image %s"
+msgstr "Image Glance %s"
+
+#. we need to invoke a plugin for copying VDI's
+#. content into proper path
+#: ../nova/virt/xenapi/vm_utils.py:342
+#, python-format
+msgid "Copying VDI %s to /boot/guest on dom0"
+msgstr "Copie de VDI %s vers /boot/guest sur dom0"
+
+#: ../nova/virt/xenapi/vm_utils.py:352
+#, python-format
+msgid "Kernel/Ramdisk VDI %s destroyed"
+msgstr "Noyau/Ramdisk VDI %s détruit"
+
+#: ../nova/virt/xenapi/vm_utils.py:361
+#, python-format
+msgid "Asking xapi to fetch %(url)s as %(access)s"
+msgstr "Demande de récupération à xapi de %(url)s as %(access)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402
+#, python-format
+msgid "Looking up vdi %s for PV kernel"
+msgstr "Recherche du VDI %s pour le PV kernel"
+
+#: ../nova/virt/xenapi/vm_utils.py:397
+#, python-format
+msgid "PV Kernel in VDI:%s"
+msgstr "PV Kernel sur VDI :%s"
+
+#: ../nova/virt/xenapi/vm_utils.py:405
+#, python-format
+msgid "Running pygrub against %s"
+msgstr "Exécution de pygrub sur %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:411
+#, python-format
+msgid "Found Xen kernel %s"
+msgstr "Kernel Xen %s trouvé"
+
+#: ../nova/virt/xenapi/vm_utils.py:413
+msgid "No Xen kernel found. Booting HVM."
+msgstr "Pas de kernel Xen trouvé. Démarrage en HVM."
+
+#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431
+#, python-format
+msgid "duplicate name found: %s"
+msgstr "Doublon de nom trouvé : %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:442
+#, python-format
+msgid "VDI %s is still available"
+msgstr "Le VDI %s est toujours disponible"
+
+#: ../nova/virt/xenapi/vm_utils.py:463
+#, python-format
+msgid "(VM_UTILS) xenserver vm state -> |%s|"
+msgstr "(VM_UTILS) état xenserver vm -> |%s|"
+
+#: ../nova/virt/xenapi/vm_utils.py:465
+#, python-format
+msgid "(VM_UTILS) xenapi power_state -> |%s|"
+msgstr "(VM_UTILS) xenapi power_state -> |%s|"
+
+#: ../nova/virt/xenapi/vm_utils.py:525
+#, python-format
+msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s"
+msgstr "VHD %(vdi_uuid)s à pour parent %(parent_ref)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:542
+#, python-format
+msgid "Re-scanning SR %s"
+msgstr "Re-parcours de SR %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:567
+#, python-format
+msgid ""
+"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..."
+msgstr ""
+"VHD tentatives de coalesence dépassé (%(counter)d > %(max_attempts)d), "
+"abandon..."
+
+#: ../nova/virt/xenapi/vm_utils.py:574
+#, python-format
+msgid ""
+"Parent %(parent_uuid)s doesn't match original parent "
+"%(original_parent_uuid)s, waiting for coalesce..."
+msgstr ""
+"L'UUID parent %(parent_uuid)s ne correspond pas au parent originel "
+"%(original_parent_uuid)s, attente de coalesence..."
+
+#: ../nova/virt/xenapi/vm_utils.py:590
+#, python-format
+msgid "No VDIs found for VM %s"
+msgstr "Pas de VDIs trouvé pour la VM %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:594
+#, python-format
+msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s"
+msgstr ""
+"Nombre de VDIs non attendu (%(num_vdis)s) trouvés pour la VM %(vm_ref)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:653
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188
+#, python-format
+msgid "Creating VBD for VDI %s ... "
+msgstr "Création de VBD pour la VDI %s ... "
+
+#: ../nova/virt/xenapi/vm_utils.py:655
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190
+#, python-format
+msgid "Creating VBD for VDI %s done."
+msgstr "La création de VBD pour la VDI %s est terminée."
+
+#: ../nova/virt/xenapi/vm_utils.py:657
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192
+#, python-format
+msgid "Plugging VBD %s ... "
+msgstr "Connexion de VBD %s ... "
+
+#: ../nova/virt/xenapi/vm_utils.py:659
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:194
+#, python-format
+msgid "Plugging VBD %s done."
+msgstr "Connexion de VBD %s terminée."
+
+#: ../nova/virt/xenapi/vm_utils.py:661
+#, python-format
+msgid "VBD %(vbd)s plugged as %(orig_dev)s"
+msgstr "VBD %(vbd)s connecté en tant que %(orig_dev)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:664
+#, python-format
+msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s"
+msgstr "VBD %(vbd)s connecté au mauvais device, re-connexion vers %(dev)s"
+
+#: ../nova/virt/xenapi/vm_utils.py:668
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:197
+#, python-format
+msgid "Destroying VBD for VDI %s ... "
+msgstr "Destruction de VBD pour la VDI %s ... "
+
+#: ../nova/virt/xenapi/vm_utils.py:671
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:200
+#, python-format
+msgid "Destroying VBD for VDI %s done."
+msgstr "Destruction de VBD pour la VDI %s terminée."
+
+#: ../nova/virt/xenapi/vm_utils.py:683
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211
+msgid "VBD.unplug successful first time."
+msgstr "VBD.unplug terminé dés la première tentative."
+
+#: ../nova/virt/xenapi/vm_utils.py:688
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216
+msgid "VBD.unplug rejected: retrying..."
+msgstr "VBD.unplug refusé : nouvel essai..."
+
+#: ../nova/virt/xenapi/vm_utils.py:692
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220
+msgid "VBD.unplug successful eventually."
+msgstr "VBD.unplug à enfin été achevée."
+
+#: ../nova/virt/xenapi/vm_utils.py:695
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:223
+#, python-format
+msgid "Ignoring XenAPI.Failure in VBD.unplug: %s"
+msgstr "XenAPI.Failure ignorée dans VBD.unplug: %s"
+
+#: ../nova/virt/xenapi/vm_utils.py:704
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:66
+#, python-format
+msgid "Ignoring XenAPI.Failure %s"
+msgstr "XenAPI.Failure %s ignorée"
+
+#: ../nova/virt/xenapi/vm_utils.py:735
+#, python-format
+msgid ""
+"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..."
+msgstr ""
+"Ecriture de la table de partitionnement %(primary_first)d %(primary_last)d "
+"vers %(dest)s..."
+
+#: ../nova/virt/xenapi/vm_utils.py:747
+#, python-format
+msgid "Writing partition table %s done."
+msgstr "Ecriture de la table de partitionnement %s terminée."
+
+#: ../nova/tests/test_rpc.py:89
+#, python-format
+msgid "Nested received %(queue)s, %(value)s"
+msgstr "Reception par Nested %(queue)s, %(value)s"
+
+#: ../nova/tests/test_rpc.py:95
+#, python-format
+msgid "Nested return %s"
+msgstr "Nested renvoi %s"
+
+#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126
+#, python-format
+msgid "Received %s"
+msgstr "%s Reçu"
+
+#: ../nova/db/sqlalchemy/api.py:44
+msgid "Use of empty request context is deprecated"
+msgstr "L'utilisation d'une requête de contexte vide est dévalué"
+
+#: ../nova/db/sqlalchemy/api.py:133
+#, python-format
+msgid "No service for id %s"
+msgstr "Pas de service pour l'id %s"
+
+#: ../nova/db/sqlalchemy/api.py:251
+#, python-format
+msgid "No service for %(host)s, %(binary)s"
+msgstr "Pas de service pour %(host)s, %(binary)s"
+
+#: ../nova/db/sqlalchemy/api.py:592
+msgid "No fixed ips defined"
+msgstr "Aucune IP fixe définie"
+
+#: ../nova/db/sqlalchemy/api.py:608
+#, python-format
+msgid "No floating ip for address %s"
+msgstr "Pas d'IP flottante pour l'addresse %s"
+
+#: ../nova/db/sqlalchemy/api.py:629
+#, python-format
+msgid "No address for instance %s"
+msgstr "Pas d'adresse pour l'instance %s"
+
+#: ../nova/db/sqlalchemy/api.py:961
+#, python-format
+msgid "no keypair for user %(user_id)s, name %(name)s"
+msgstr "Pas de bi-clef pour l'utilisation %(user_id)s, nommé %(name)s"
+
+#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156
+#, python-format
+msgid "No network for id %s"
+msgstr "Pas de réseau pourl'id %s"
+
+#: ../nova/db/sqlalchemy/api.py:1086
+msgid "No networks defined"
+msgstr "Pas de réseau défini"
+
+#: ../nova/db/sqlalchemy/api.py:1115
+#, python-format
+msgid "No network for bridge %s"
+msgstr "Pas de réseau pour le bridge %s"
+
+#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142
+#, python-format
+msgid "No network for instance %s"
+msgstr "Pas de réseau pour l'instance %s"
+
+#: ../nova/db/sqlalchemy/api.py:1277
+#, python-format
+msgid "Token %s does not exist"
+msgstr "Le jeton %s n'existe pas"
+
+#: ../nova/db/sqlalchemy/api.py:1302
+#, python-format
+msgid "No quota for project_id %s"
+msgstr "Pas de quota pour l'ID projet %s"
+
+#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501
+#: ../nova/api/ec2/__init__.py:323
+#, python-format
+msgid "Volume %s not found"
+msgstr "Volume %s non trouvé"
+
+#: ../nova/db/sqlalchemy/api.py:1514
+#, python-format
+msgid "No export device found for volume %s"
+msgstr "Pas de device d'exportation pour le volume %s"
+
+#: ../nova/db/sqlalchemy/api.py:1527
+#, python-format
+msgid "No target id found for volume %s"
+msgstr "Pas d'id de destination trouvée pour le volume %s"
+
+#: ../nova/db/sqlalchemy/api.py:1572
+#, python-format
+msgid "No security group with id %s"
+msgstr "Aucun groupe de sécurité avec l'id %s"
+
+#: ../nova/db/sqlalchemy/api.py:1589
+#, python-format
+msgid "No security group named %(group_name)s for project: %(project_id)s"
+msgstr ""
+"Aucun groupe de sécurité nommé %(group_name)s pour le projet : %(project_id)s"
+
+#: ../nova/db/sqlalchemy/api.py:1682
+#, python-format
+msgid "No secuity group rule with id %s"
+msgstr "Pas de groupe de sécurité ayant pour ID %s"
+
+#: ../nova/db/sqlalchemy/api.py:1756
+#, python-format
+msgid "No user for id %s"
+msgstr "Pas d'utilisateur ayant pour ID %s"
+
+#: ../nova/db/sqlalchemy/api.py:1772
+#, python-format
+msgid "No user for access key %s"
+msgstr "Pas d'utilisateur avec la clef d'accès %s"
+
+#: ../nova/db/sqlalchemy/api.py:1834
+#, python-format
+msgid "No project with id %s"
+msgstr "Pas de projet ayant pour ID %s"
+
+#: ../nova/db/sqlalchemy/api.py:1979
+#, python-format
+msgid "No console pool with id %(pool_id)s"
+msgstr "Pas de groupe de console ayant pour ID %(pool_id)s"
+
+#: ../nova/db/sqlalchemy/api.py:1996
+#, python-format
+msgid ""
+"No console pool of type %(console_type)s for compute host %(compute_host)s "
+"on proxy host %(host)s"
+msgstr ""
+"Pas de groupe de console de type %(console_type)s pour l'hote de calcul "
+"%(compute_host)s sur le proxy %(host)s"
+
+#: ../nova/db/sqlalchemy/api.py:2035
+#, python-format
+msgid "No console for instance %(instance_id)s in pool %(pool_id)s"
+msgstr ""
+"Pas de console pour l'intance %(instance_id)s dans le groupe %(pool_id)s"
+
+#: ../nova/db/sqlalchemy/api.py:2057
+#, python-format
+msgid "on instance %s"
+msgstr "sur l'intance %s"
+
+#: ../nova/db/sqlalchemy/api.py:2058
+#, python-format
+msgid "No console with id %(console_id)s %(idesc)s"
+msgstr "Pas de console ayant pour ID %(console_id)s %(idesc)s"
+
+#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097
+#, python-format
+msgid "No zone with id %(zone_id)s"
+msgstr "Pas de zone ayant pour ID %(zone_id)s"
+
+#: ../nova/virt/libvirt_conn.py:160
+#, python-format
+msgid "Checking state of %s"
+msgstr "Vérification de l'état de %s"
+
+#: ../nova/virt/libvirt_conn.py:165
+#, python-format
+msgid "Current state of %(name)s was %(state)s."
+msgstr "L'état de %(name)s est %(state)s."
+
+#: ../nova/virt/libvirt_conn.py:183
+#, python-format
+msgid "Connecting to libvirt: %s"
+msgstr "Connexion à libvirt: %s"
+
+#: ../nova/virt/libvirt_conn.py:196
+msgid "Connection to libvirt broke"
+msgstr "Connexion à libvirt interrompue"
+
+#: ../nova/virt/libvirt_conn.py:258
+#, python-format
+msgid "instance %(instance_name)s: deleting instance files %(target)s"
+msgstr ""
+"instance %(instance_name)s: suppression des fichiers d'instance %(target)s"
+
+#: ../nova/virt/libvirt_conn.py:283
+#, python-format
+msgid "Invalid device path %s"
+msgstr "Chemin de device invalide %s"
+
+#: ../nova/virt/libvirt_conn.py:313
+#, python-format
+msgid "No disk at %s"
+msgstr "Pas de disque sur %s"
+
+#: ../nova/virt/libvirt_conn.py:320
+msgid "Instance snapshotting is not supported for libvirtat this time"
+msgstr ""
+"Les instantanés (snapshot) d'instance ne sont pas disponible avec libvirt "
+"pour le moment"
+
+#: ../nova/virt/libvirt_conn.py:336
+#, python-format
+msgid "instance %s: rebooted"
+msgstr "instance %s: re-démarrée"
+
+#: ../nova/virt/libvirt_conn.py:339
+#, python-format
+msgid "_wait_for_reboot failed: %s"
+msgstr "_wait_for_reboot échouée : %s"
+
+#: ../nova/virt/libvirt_conn.py:382
+#, python-format
+msgid "instance %s: rescued"
+msgstr "instance %s: récupérée"
+
+#: ../nova/virt/libvirt_conn.py:385
+#, python-format
+msgid "_wait_for_rescue failed: %s"
+msgstr "_wait_for_rescue échouée : %s"
+
+#: ../nova/virt/libvirt_conn.py:411
+#, python-format
+msgid "instance %s: is running"
+msgstr "instance %s: est active"
+
+#: ../nova/virt/libvirt_conn.py:422
+#, python-format
+msgid "instance %s: booted"
+msgstr "instance %s: a démarrée"
+
+#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186
+#, python-format
+msgid "instance %s: failed to boot"
+msgstr "instance %s: n'a pas réussie à démarrer"
+
+#: ../nova/virt/libvirt_conn.py:436
+#, python-format
+msgid "virsh said: %r"
+msgstr "virsh a retourné : %r"
+
+#: ../nova/virt/libvirt_conn.py:440
+msgid "cool, it's a device"
+msgstr "super, c'est un device"
+
+#: ../nova/virt/libvirt_conn.py:448
+#, python-format
+msgid "data: %(data)r, fpath: %(fpath)r"
+msgstr "data: %(data)r, fpath: %(fpath)r"
+
+#: ../nova/virt/libvirt_conn.py:456
+#, python-format
+msgid "Contents of file %(fpath)s: %(contents)r"
+msgstr "Contenu du fichier %(fpath)s: %(contents)r"
+
+#: ../nova/virt/libvirt_conn.py:489
+msgid "Unable to find an open port"
+msgstr "Impossible de trouver un port ouvert"
+
+#: ../nova/virt/libvirt_conn.py:563
+#, python-format
+msgid "instance %s: Creating image"
+msgstr "instance %s : Création de l'image"
+
+#: ../nova/virt/libvirt_conn.py:646
+#, python-format
+msgid "instance %(inst_name)s: injecting key into image %(img_id)s"
+msgstr "instance %(inst_name)s : injection de clef dans l'image %(img_id)s"
+
+#: ../nova/virt/libvirt_conn.py:649
+#, python-format
+msgid "instance %(inst_name)s: injecting net into image %(img_id)s"
+msgstr "instance %(inst_name)s : injection de réseau dans l'image %(img_id)s"
+
+#. This could be a windows image, or a vmdk format disk
+#: ../nova/virt/libvirt_conn.py:657
+#, python-format
+msgid ""
+"instance %(inst_name)s: ignoring error injecting data into image %(img_id)s "
+"(%(e)s)"
+msgstr ""
+"instance %(inst_name)s : l'erreur d'injection de donné dans l'image "
+"%(img_id)s (%(e)s) a été ignorée"
+
+#. TODO(termie): cache?
+#: ../nova/virt/libvirt_conn.py:665
+#, python-format
+msgid "instance %s: starting toXML method"
+msgstr "instance %s: démarrage de la méthode toXML"
+
+#: ../nova/virt/libvirt_conn.py:732
+#, python-format
+msgid "instance %s: finished toXML method"
+msgstr "instance %s: fin d'éxécution de la méthode toXML"
+
+#: ../nova/virt/libvirt_conn.py:751
+msgid "diagnostics are not supported for libvirt"
+msgstr "Les diagnostiques ne sont pas disponibles pour libvirt"
+
+#: ../nova/virt/libvirt_conn.py:1225
+#, python-format
+msgid "Attempted to unfilter instance %s which is not filtered"
+msgstr ""
+"Tentative de suppression de filtre pour l'intance %s qui n'est pas filtrée"
+
+#: ../nova/api/ec2/metadatarequesthandler.py:76
+#, python-format
+msgid "Failed to get metadata for ip: %s"
+msgstr "Impossible de récupérer les méta-donnérs pour l'IP : %s"
+
+#: ../nova/auth/fakeldap.py:33
+msgid "Attempted to instantiate singleton"
+msgstr "Tentative d'instanciation d'un singleton"
+
+#: ../nova/network/api.py:39
+#, python-format
+msgid "Quota exceeeded for %s, tried to allocate address"
+msgstr "Quota dépassé pour %s lors de la tentative d'allocation d'adresse"
+
+#: ../nova/network/api.py:42
+msgid "Address quota exceeded. You cannot allocate any more addresses"
+msgstr "Quota d'adresse dépassé. Vous ne pouvez pas allouer d'autre adresse"
+
+#: ../nova/tests/test_volume.py:162
+#, python-format
+msgid "Target %s allocated"
+msgstr "Destination %s allouée"
+
+#: ../nova/virt/images.py:70
+#, python-format
+msgid "Finished retreving %(url)s -- placed in %(path)s"
+msgstr "Fin de récupération de %(url)s -- placé dans %(path)s"
+
+#: ../nova/scheduler/driver.py:66
+msgid "Must implement a fallback schedule"
+msgstr "Doit mettre en oeuvre un calendrier de retrait"
+
+#: ../nova/console/manager.py:70
+msgid "Adding console"
+msgstr "Ajout de console"
+
+#: ../nova/console/manager.py:90
+#, python-format
+msgid "Tried to remove non-existant console %(console_id)s."
+msgstr "Tentative de suppression d'une console non existante %(console_id)s."
+
+#: ../nova/api/direct.py:149
+msgid "not available"
+msgstr "non disponible"
+
+#: ../nova/api/ec2/cloud.py:62
+#, python-format
+msgid "The key_pair %s already exists"
+msgstr "Le bi-clef %s existe déjà"
+
+#. TODO(vish): Do this with M2Crypto instead
+#: ../nova/api/ec2/cloud.py:118
+#, python-format
+msgid "Generating root CA: %s"
+msgstr "Génération de la racine d'autorité de certification : %s"
+
+#: ../nova/api/ec2/cloud.py:303
+#, python-format
+msgid "Create key pair %s"
+msgstr "Création du bi-clef %s"
+
+#: ../nova/api/ec2/cloud.py:311
+#, python-format
+msgid "Delete key pair %s"
+msgstr "Suppression du bi-clef %s"
+
+#: ../nova/api/ec2/cloud.py:386
+#, python-format
+msgid "%s is not a valid ipProtocol"
+msgstr "%s n'est pas un protocol ip valide"
+
+#: ../nova/api/ec2/cloud.py:390
+msgid "Invalid port range"
+msgstr "Interval de port invalide"
+
+#: ../nova/api/ec2/cloud.py:421
+#, python-format
+msgid "Revoke security group ingress %s"
+msgstr "Révocation de groupe de sécurité %s"
+
+#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459
+msgid "Not enough parameters to build a valid rule."
+msgstr "Pas assez de parametres pour contruire un règle valide."
+
+#: ../nova/api/ec2/cloud.py:443
+msgid "No rule for the specified parameters."
+msgstr "Pas de règle pour les paramètres spécifiés."
+
+#: ../nova/api/ec2/cloud.py:450
+#, python-format
+msgid "Authorize security group ingress %s"
+msgstr "Authorisation du groupe de sécurité %s"
+
+#: ../nova/api/ec2/cloud.py:464
+#, python-format
+msgid "This rule already exists in group %s"
+msgstr "Cette règle existe déjà dans le groupe %s"
+
+#: ../nova/api/ec2/cloud.py:492
+#, python-format
+msgid "Create Security Group %s"
+msgstr "Création du groupe de sécurité %s"
+
+#: ../nova/api/ec2/cloud.py:495
+#, python-format
+msgid "group %s already exists"
+msgstr "le groupe %s existe déjà"
+
+#: ../nova/api/ec2/cloud.py:507
+#, python-format
+msgid "Delete security group %s"
+msgstr "Suppression du groupe de sécurité %s"
+
+#: ../nova/api/ec2/cloud.py:584
+#, python-format
+msgid "Create volume of %s GB"
+msgstr "Création d'un volume de %s Go"
+
+#: ../nova/api/ec2/cloud.py:612
+#, python-format
+msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s"
+msgstr ""
+"Montage du volume %(volume_id)s sur l'instance %(instance_id)s en tant que "
+"%(device)s"
+
+#: ../nova/api/ec2/cloud.py:629
+#, python-format
+msgid "Detach volume %s"
+msgstr "Dé-montage du volume %s"
+
+#: ../nova/api/ec2/cloud.py:761
+msgid "Allocate address"
+msgstr "Allocation d'adresse"
+
+#: ../nova/api/ec2/cloud.py:766
+#, python-format
+msgid "Release address %s"
+msgstr "Désallocation de l'adresse %s"
+
+#: ../nova/api/ec2/cloud.py:771
+#, python-format
+msgid "Associate address %(public_ip)s to instance %(instance_id)s"
+msgstr ""
+"Association de l'adresse %(public_ip)s avec l'instance %(instance_id)s"
+
+#: ../nova/api/ec2/cloud.py:780
+#, python-format
+msgid "Disassociate address %s"
+msgstr "Désassociation de l'adresse %s"
+
+#: ../nova/api/ec2/cloud.py:807
+msgid "Going to start terminating instances"
+msgstr "Début de la destruction d'instance"
+
+#: ../nova/api/ec2/cloud.py:815
+#, python-format
+msgid "Reboot instance %r"
+msgstr "Re-démarrage de l'instance %r"
+
+#: ../nova/api/ec2/cloud.py:867
+#, python-format
+msgid "De-registering image %s"
+msgstr "Dé-enregitrement de l'image %s"
+
+#: ../nova/api/ec2/cloud.py:875
+#, python-format
+msgid "Registered image %(image_location)s with id %(image_id)s"
+msgstr "Image %(image_location)s enregistré avec l'id %(image_id)s"
+
+#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900
+#, python-format
+msgid "attribute not supported: %s"
+msgstr "attribut non reconnu : %s"
+
+#: ../nova/api/ec2/cloud.py:890
+#, python-format
+msgid "invalid id: %s"
+msgstr "ID invalide : %s"
+
+#: ../nova/api/ec2/cloud.py:903
+msgid "user or group not specified"
+msgstr "Utilisateur ou groupe non spécifié"
+
+#: ../nova/api/ec2/cloud.py:905
+msgid "only group \"all\" is supported"
+msgstr "Seul le group \"tous\" est supporté"
+
+#: ../nova/api/ec2/cloud.py:907
+msgid "operation_type must be add or remove"
+msgstr ""
+"le type d'opération (operation_type) doit être ajout (add) ou suppression "
+"(remove)"
+
+#: ../nova/api/ec2/cloud.py:908
+#, python-format
+msgid "Updating image %s publicity"
+msgstr "Mis à jour de la publication de l'image %s"
+
+#: ../bin/nova-api.py:52
+#, python-format
+msgid "Using paste.deploy config at: %s"
+msgstr "Utilisation de la configuration paste.deploy sur : %s"
+
+#: ../bin/nova-api.py:57
+#, python-format
+msgid "No paste configuration for app: %s"
+msgstr "Pas de configuration collé pour l'application : %s"
+
+#: ../bin/nova-api.py:59
+#, python-format
+msgid ""
+"App Config: %(api)s\n"
+"%(config)r"
+msgstr ""
+"App Config: %(api)s\n"
+"%(config)r"
+
+#: ../bin/nova-api.py:64
+#, python-format
+msgid "Running %s API"
+msgstr "API %s en cours d'éxécution"
+
+#: ../bin/nova-api.py:69
+#, python-format
+msgid "No known API applications configured in %s."
+msgstr "Pas d'API d'applications connue configurée pour %s."
+
+#: ../bin/nova-api.py:83
+#, python-format
+msgid "Starting nova-api node (version %s)"
+msgstr "Démarrage du noeud nova-api (version %s)"
+
+#: ../bin/nova-api.py:89
+#, python-format
+msgid "No paste configuration found for: %s"
+msgstr "Pas de configuration collée trouvée : %s"
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84
+#, python-format
+msgid "Argument %(key)s value %(value)s is too short."
+msgstr "La valeur %(value)s pour l'argument %(key)s est trop courte."
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89
+#, python-format
+msgid "Argument %(key)s value %(value)s contains invalid characters."
+msgstr ""
+"La valeur %(value)s pour l'argument %(key)s contient des caractères "
+"interdits."
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94
+#, python-format
+msgid "Argument %(key)s value %(value)s starts with a hyphen."
+msgstr ""
+"La valeur %(value)s pour l'argument %(key)s débute par un trait d'union."
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:102
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:130
+#, python-format
+msgid "Argument %s is required."
+msgstr "L'argument %s est requis."
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117
+#, python-format
+msgid ""
+"Argument %(key)s may not take value %(value)s. Valid values are ['true', "
+"'false']."
+msgstr ""
+"La valeur %(value)s pour l'argument %(key)s n'est pas valide. Les valeurs "
+"autorisées sont ['true', 'false']."
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:163
+#, python-format
+msgid ""
+"Created VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) on %(sr_ref)s."
+msgstr ""
+"La VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) a été créée sur "
+"%(sr_ref)s."
+
+#: ../nova/virt/xenapi/vmops.py:67
+#, python-format
+msgid "Attempted to create non-unique name %s"
+msgstr "Tentative de création d'un nom non unique %s"
+
+#: ../nova/virt/xenapi/vmops.py:73
+#, python-format
+msgid "instance %(name)s: not enough free memory"
+msgstr "instance %(name)s: pas assez de mémoire"
+
+#: ../nova/virt/xenapi/vmops.py:148
+#, python-format
+msgid "Starting VM %s..."
+msgstr "Démarrage de la VM %s..."
+
+#: ../nova/virt/xenapi/vmops.py:151
+#, python-format
+msgid "Spawning VM %(instance_name)s created %(vm_ref)s."
+msgstr "La VM %(instance_name)s a créé %(vm_ref)s."
+
+#: ../nova/virt/xenapi/vmops.py:162
+#, python-format
+msgid "Invalid value for onset_files: '%s'"
+msgstr "Valeur interdite pour onset_files : '%s'"
+
+#: ../nova/virt/xenapi/vmops.py:167
+#, python-format
+msgid "Injecting file path: '%s'"
+msgstr "Injection du chemin d'accès : '%s'"
+
+#: ../nova/virt/xenapi/vmops.py:180
+#, python-format
+msgid "Instance %s: booted"
+msgstr "Instance %s : démarée"
+
+#: ../nova/virt/xenapi/vmops.py:232
+#, python-format
+msgid "Instance not present %s"
+msgstr "Instance non présente %s"
+
+#. TODO(sirp): Add quiesce and VSS locking support when Windows support
+#. is added
+#: ../nova/virt/xenapi/vmops.py:261
+#, python-format
+msgid "Starting snapshot for VM %s"
+msgstr "Début de création d'instantané (snapshot) pour la VM %s"
+
+#: ../nova/virt/xenapi/vmops.py:269
+#, python-format
+msgid "Unable to Snapshot %(vm_ref)s: %(exc)s"
+msgstr "Impossible de faire un instantané de %(vm_ref)s: %(exc)s"
+
+#: ../nova/virt/xenapi/vmops.py:280
+#, python-format
+msgid "Finished snapshot and upload for VM %s"
+msgstr "Fin de l'instantané et du chargement de VM %s"
+
+#: ../nova/virt/xenapi/vmops.py:356
+#, python-format
+msgid "VM %(vm)s already halted, skipping shutdown..."
+msgstr "La VM %(vm)s est déjà arrété, exctinction évitée."
+
+#: ../nova/virt/xenapi/vmops.py:389
+msgid "Removing kernel/ramdisk files"
+msgstr "Suppression des fichiers noyau/ramdisk"
+
+#: ../nova/virt/xenapi/vmops.py:399
+msgid "kernel/ramdisk files removed"
+msgstr "Fichiers noyau/ramdisk supprimés"
+
+#: ../nova/virt/xenapi/vmops.py:561
+#, python-format
+msgid ""
+"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; "
+"args=%(strargs)s"
+msgstr ""
+"DELAI DEPASSE : L'appel de %(method)s à depasser de délai de réponse "
+"maximal. VM id=%(instance_id)s; args=%(strargs)s"
+
+#: ../nova/virt/xenapi/vmops.py:564
+#, python-format
+msgid ""
+"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM "
+"id=%(instance_id)s; args=%(strargs)s"
+msgstr ""
+"NON IMPLEMENTE : l'appel de %(method)s n'est pas pris en compte par l'agent. "
+"VM id=%(instance_id)s; args=%(strargs)s"
+
+#: ../nova/virt/xenapi/vmops.py:569
+#, python-format
+msgid ""
+"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; "
+"args=%(strargs)s"
+msgstr ""
+"L'appel de %(method)s à renvoyé l'erreur : %(e)s. VM id=%(instance_id)s; "
+"args=%(strargs)s"
+
+#: ../nova/virt/xenapi/vmops.py:760
+#, python-format
+msgid "OpenSSL error: %s"
+msgstr "Erreur OpenSSL : %s"
+
+#: ../nova/tests/test_compute.py:148
+#, python-format
+msgid "Running instances: %s"
+msgstr "Instance actives : %s"
+
+#: ../nova/tests/test_compute.py:154
+#, python-format
+msgid "After terminating instances: %s"
+msgstr "Après l'arrêt d'instances : %s"
+
+#: ../nova/cloudpipe/pipelib.py:45
+msgid "Template for script to run on cloudpipe instance boot"
+msgstr "Patron du script à exécuter au boot d'instance cloudpipe"
+
+#: ../nova/cloudpipe/pipelib.py:48
+msgid "Network to push into openvpn config"
+msgstr "Réseau à passer à la configuration d'openvpn"
+
+#: ../nova/cloudpipe/pipelib.py:51
+msgid "Netmask to push into openvpn config"
+msgstr "Masque réseau à passer à la configuration d'openvpn"
+
+#: ../nova/cloudpipe/pipelib.py:97
+#, python-format
+msgid "Launching VPN for %s"
+msgstr "Démarrage du VPN pour %s"
+
+#: ../nova/db/sqlalchemy/migration.py:35
+msgid "python-migrate is not installed. Exiting."
+msgstr "python-migrate n'est pas installé. Fin d'éxécution."
+
+#: ../nova/image/s3.py:99
+#, python-format
+msgid "Image %s could not be found"
+msgstr "L'image %s n'a pas été trouvée"
+
+#: ../nova/api/ec2/__init__.py:121
+msgid "Too many failed authentications."
+msgstr "Trop d'erreur d'authentification"
+
+#: ../nova/api/ec2/__init__.py:131
+#, python-format
+msgid ""
+"Access key %(access_key)s has had %(failures)d failed authentications and "
+"will be locked out for %(lock_mins)d minutes."
+msgstr ""
+"La clef d'accès %(access_key)s a rencontrée %(failures)d echecs "
+"d'authentification et sera par conséquent vérouillée pour %(lock_mins)d "
+"minutes."
+
+#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140
+#, python-format
+msgid "Authentication Failure: %s"
+msgstr "Echec d'authentification : %s"
+
+#: ../nova/api/ec2/__init__.py:182
+#, python-format
+msgid "Authenticated Request For %(uname)s:%(pname)s)"
+msgstr "Requête authentifiée pour : %(uname)s:%(pname)s)"
+
+#: ../nova/api/ec2/__init__.py:207
+#, python-format
+msgid "action: %s"
+msgstr "action: %s"
+
+#: ../nova/api/ec2/__init__.py:209
+#, python-format
+msgid "arg: %(key)s\t\tval: %(value)s"
+msgstr "arg: %(key)s\t\tval: %(value)s"
+
+#: ../nova/api/ec2/__init__.py:281
+#, python-format
+msgid ""
+"Unauthorized request for controller=%(controller)s and action=%(action)s"
+msgstr ""
+"Requête non authorisé pour le controlleur=%(controller)s et "
+"l'action=%(action)s"
+
+#: ../nova/api/ec2/__init__.py:314
+#, python-format
+msgid "InstanceNotFound raised: %s"
+msgstr "\"Instance non trouvée\" remontée : %s"
+
+#: ../nova/api/ec2/__init__.py:320
+#, python-format
+msgid "VolumeNotFound raised: %s"
+msgstr "\"Volume non trouvé\" remonté : %s"
+
+#: ../nova/api/ec2/__init__.py:326
+#, python-format
+msgid "NotFound raised: %s"
+msgstr "\"Non trouvé\" remonté : %s"
+
+#: ../nova/api/ec2/__init__.py:329
+#, python-format
+msgid "ApiError raised: %s"
+msgstr "\"Erreur API\" remontée : %s"
+
+#: ../nova/api/ec2/__init__.py:338
+#, python-format
+msgid "Unexpected error raised: %s"
+msgstr "\"Erreur inopinée\" remontée : %s"
+
+#: ../nova/api/ec2/__init__.py:343
+msgid "An unknown error has occurred. Please try your request again."
+msgstr ""
+"Une erreur inopinée à eu lieu. Merci d'essayer votre requête à nouveau."
+
+#: ../nova/auth/dbdriver.py:84
+#, python-format
+msgid "User %s already exists"
+msgstr "L'utilisateur %s existe déjà"
+
+#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232
+#, python-format
+msgid "Project can't be created because manager %s doesn't exist"
+msgstr "Le projet ne peut pas être créé car le manager %s n'existe pas"
+
+#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243
+#, python-format
+msgid "Project can't be created because user %s doesn't exist"
+msgstr "Le projet ne peut pas être créé car l'utiisateur %s n'existe pas"
+
+#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229
+#, python-format
+msgid "Project can't be created because project %s already exists"
+msgstr "Le projet ne peut pas être créé car projet %s existe déjà"
+
+#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268
+#, python-format
+msgid "Project can't be modified because manager %s doesn't exist"
+msgstr "Le projet ne peut pas être modifié car le manager %s n'existe pas"
+
+#: ../nova/auth/dbdriver.py:245
+#, python-format
+msgid "User \"%s\" not found"
+msgstr "Utilisateur \"%s\" non trouvé"
+
+#: ../nova/auth/dbdriver.py:248
+#, python-format
+msgid "Project \"%s\" not found"
+msgstr "Projet %s non trouvé"
+
+#: ../nova/virt/xenapi_conn.py:129
+msgid ""
+"Must specify xenapi_connection_url, xenapi_connection_username (optionally), "
+"and xenapi_connection_password to use connection_type=xenapi"
+msgstr ""
+"Doit spécifier xenapi_connection_url, xenapi_connection_username (optionel), "
+"et xenapi_connection_password pour utiliser connection_type=xenapi"
+
+#: ../nova/virt/xenapi_conn.py:311
+#, python-format
+msgid "Task [%(name)s] %(task)s status: success %(result)s"
+msgstr "Tâche [%(name)s] %(task)s état : succès %(result)s"
+
+#: ../nova/virt/xenapi_conn.py:317
+#, python-format
+msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s"
+msgstr "Tâche [%(name)s] %(task)s état : %(status)s %(error_info)s"
+
+#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344
+#, python-format
+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"
+msgstr "Imposible de trouver une exportation iSCSI pour le volume %s"
+
+#: ../nova/api/ec2/apirequest.py:100
+#, python-format
+msgid ""
+"Unsupported API request: controller = %(controller)s, action = %(action)s"
+msgstr ""
+"Requête API non supportée : controleur = %(controller)s, action = %(action)s"
+
+#: ../nova/api/openstack/__init__.py:55
+#, python-format
+msgid "Caught error: %s"
+msgstr "Erreur interceptée : %s"
+
+#: ../nova/api/openstack/__init__.py:76
+msgid "Including admin operations in API."
+msgstr "Inclusion des opérations d'admin dans l'API."
+
+#: ../nova/console/xvp.py:99
+msgid "Rebuilding xvp conf"
+msgstr "Reconstruction de la configuration xvp"
+
+#: ../nova/console/xvp.py:116
+#, python-format
+msgid "Re-wrote %s"
+msgstr "Ré-écriture de %s"
+
+#: ../nova/console/xvp.py:121
+msgid "Stopping xvp"
+msgstr "Arrêt xvp"
+
+#: ../nova/console/xvp.py:134
+msgid "Starting xvp"
+msgstr "Démarrage xvp"
+
+#: ../nova/console/xvp.py:141
+#, python-format
+msgid "Error starting xvp: %s"
+msgstr "Erreur au démarrage xvp : %s"
+
+#: ../nova/console/xvp.py:144
+msgid "Restarting xvp"
+msgstr "Re-démarrage xvp"
+
+#: ../nova/console/xvp.py:146
+msgid "xvp not running..."
+msgstr "xvp non actif..."
+
+#: ../bin/nova-manage.py:272
+msgid ""
+"The above error may show that the database has not been created.\n"
+"Please create a database using nova-manage sync db before running this "
+"command."
+msgstr ""
+"L'erreur çi dessus peut indiquer que la base de données n'a pas été créée.\n"
+"Veuillez créer une base de données en utilisant nova-manage sync db avant "
+"d'utiliser cette commande."
+
+#: ../bin/nova-manage.py:426
+msgid ""
+"No more networks available. If this is a new installation, you need\n"
+"to call something like this:\n"
+"\n"
+" nova-manage network create 10.0.0.0/8 10 64\n"
+"\n"
+msgstr ""
+"Plus de réseaux disponibles. Si vous venez d'installer nova, vous devez "
+"exécuter une commande telle que :\n"
+"\n"
+" nova-manage network create 10.0.0.0/8 10 64\n"
+"\n"
+
+#: ../bin/nova-manage.py:431
+msgid ""
+"The above error may show that the certificate db has not been created.\n"
+"Please create a database by running a nova-api server on this host."
+msgstr ""
+"L'erreur çi dessus peut indiquer que la base de données de certificats n'a "
+"pas été créée.\n"
+"Veuillez créer une base de données en exécutant nova-api server sur cet hôte."
+
+#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536
+msgid "network"
+msgstr "réseau"
+
+#: ../bin/nova-manage.py:448
+msgid "IP address"
+msgstr "adresse IP"
+
+#: ../bin/nova-manage.py:449
+msgid "MAC address"
+msgstr "adresse MAC"
+
+#: ../bin/nova-manage.py:450
+msgid "hostname"
+msgstr "nom du serveur"
+
+#: ../bin/nova-manage.py:451
+msgid "host"
+msgstr "hôte"
+
+#: ../bin/nova-manage.py:537
+msgid "netmask"
+msgstr "masque de réseau"
+
+#: ../bin/nova-manage.py:538
+msgid "start address"
+msgstr "adresse de départ"
+
+#: ../nova/virt/disk.py:69
+#, python-format
+msgid "Failed to load partition: %s"
+msgstr "Impossible de charger la partition: %s"
+
+#: ../nova/virt/disk.py:91
+#, python-format
+msgid "Failed to mount filesystem: %s"
+msgstr "Impossible de monter le système de fichier : %s"
+
+#: ../nova/virt/disk.py:124
+#, python-format
+msgid "nbd device %s did not show up"
+msgstr "Device nbd %s n'est pas apparu"
+
+#: ../nova/virt/disk.py:128
+#, python-format
+msgid "Could not attach image to loopback: %s"
+msgstr "Impossible de lier l'image au loopback : %s"
+
+#: ../nova/virt/disk.py:151
+msgid "No free nbd devices"
+msgstr "Pas de device nbd libre"
+
+#: ../doc/ext/nova_todo.py:46
+#, python-format
+msgid "%(filename)s, line %(line_info)d"
+msgstr "%(filename)s, ligne %(line_info)d"
+
+#. FIXME(chiradeep): implement this
+#: ../nova/virt/hyperv.py:118
+msgid "In init host"
+msgstr "Dans init host"
+
+#: ../nova/virt/hyperv.py:131
+#, python-format
+msgid "Attempt to create duplicate vm %s"
+msgstr "Tentative de création de vm en doublon %s"
+
+#: ../nova/virt/hyperv.py:148
+#, python-format
+msgid "Starting VM %s "
+msgstr "Démarrage VM %s "
+
+#: ../nova/virt/hyperv.py:150
+#, python-format
+msgid "Started VM %s "
+msgstr "VM %s démarrée "
+
+#: ../nova/virt/hyperv.py:152
+#, python-format
+msgid "spawn vm failed: %s"
+msgstr "Erreur à l'activation VM : %s"
+
+#: ../nova/virt/hyperv.py:169
+#, python-format
+msgid "Failed to create VM %s"
+msgstr "Erreur de création VM %s"
+
+#: ../nova/virt/hyperv.py:188
+#, python-format
+msgid "Set memory for vm %s..."
+msgstr "Réglage de la mémoire sur VM %s..."
+
+#: ../nova/virt/hyperv.py:198
+#, python-format
+msgid "Set vcpus for vm %s..."
+msgstr "Réglage vcpus sur vm %s..."
+
+#: ../nova/virt/hyperv.py:202
+#, python-format
+msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s"
+msgstr ""
+"Création du disque pour %(vm_name)s par liaison avec le fichier disque "
+"%(vhdfile)s"
+
+#: ../nova/virt/hyperv.py:227
+#, python-format
+msgid "Failed to add diskdrive to VM %s"
+msgstr "Impossible d'ajouter le disque à la VM %s"
+
+#: ../nova/virt/hyperv.py:230
+#, python-format
+msgid "New disk drive path is %s"
+msgstr "Nouveau chemin d'accès pour le disque : %s"
+
+#: ../nova/virt/hyperv.py:247
+#, python-format
+msgid "Failed to add vhd file to VM %s"
+msgstr "Impossible d'ajouter le fichier vhd à la VM %s"
+
+#: ../nova/virt/hyperv.py:249
+#, python-format
+msgid "Created disk for %s"
+msgstr "Disque créé pour %s"
+
+#: ../nova/virt/hyperv.py:253
+#, python-format
+msgid "Creating nic for %s "
+msgstr "Création de l'interface réseau pour %s "
+
+#: ../nova/virt/hyperv.py:272
+msgid "Failed creating a port on the external vswitch"
+msgstr "Erreur de création de port sur le vswitch externe"
+
+#: ../nova/virt/hyperv.py:273
+#, python-format
+msgid "Failed creating port for %s"
+msgstr "Erreur de création de port pour %s"
+
+#: ../nova/virt/hyperv.py:276
+#, python-format
+msgid "Created switch port %(vm_name)s on switch %(ext_path)s"
+msgstr "Le port switch %(vm_name)s a été créé sur le switch %(ext_path)s"
+
+#: ../nova/virt/hyperv.py:286
+#, python-format
+msgid "Failed to add nic to VM %s"
+msgstr "Impossible d'ajouter une interface réseau à la VM %s"
+
+#: ../nova/virt/hyperv.py:288
+#, python-format
+msgid "Created nic for %s "
+msgstr "Interface réseau créée pour %s "
+
+#: ../nova/virt/hyperv.py:321
+#, python-format
+msgid "WMI job failed: %s"
+msgstr "Tâche WMI echouée : %s"
+
+#: ../nova/virt/hyperv.py:325
+#, python-format
+msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s "
+msgstr "Tâche WMI réussie : %(desc)s, Elapsed=%(elap)s "
+
+#: ../nova/virt/hyperv.py:361
+#, python-format
+msgid "Got request to destroy vm %s"
+msgstr "Requête de suppression de la VM %s reçue"
+
+#: ../nova/virt/hyperv.py:386
+#, python-format
+msgid "Failed to destroy vm %s"
+msgstr "Impossible de supprimer la VM %s"
+
+#: ../nova/virt/hyperv.py:393
+#, python-format
+msgid "Del: disk %(vhdfile)s vm %(instance_name)s"
+msgstr "Suppression: disque %(vhdfile)s vm %(instance_name)s"
+
+#: ../nova/virt/hyperv.py:415
+#, python-format
+msgid ""
+"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, "
+"num_cpu=%(numprocs)s, cpu_time=%(uptime)s"
+msgstr ""
+"Informations reçues pour la VM %(instance_id)s: état=%(state)s, "
+"mem=%(memusage)s, num_cpu=%(numprocs)s, cpu_time=%(uptime)s"
+
+#: ../nova/virt/hyperv.py:451
+#, python-format
+msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s"
+msgstr "Changement d'état de la VM %(vm_name)s en %(req_state)s réussi"
+
+#: ../nova/virt/hyperv.py:454
+#, python-format
+msgid "Failed to change vm state of %(vm_name)s to %(req_state)s"
+msgstr "Impossible de changer l'état de la vm %(vm_name)s en %(req_state)s"
+
+#: ../nova/compute/api.py:71
+#, python-format
+msgid "Instance %d was not found in get_network_topic"
+msgstr "Instance %d non trouvée dans get_network_topic"
+
+#: ../nova/compute/api.py:77
+#, python-format
+msgid "Instance %d has no host"
+msgstr "Instance %d n'a pas d'hôte"
+
+#: ../nova/compute/api.py:97
+#, python-format
+msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances"
+msgstr ""
+"Quota dépassé pour %(pid)s, lors de la tentative d'exécution de "
+"%(min_count)s instances"
+
+#: ../nova/compute/api.py:99
+#, python-format
+msgid ""
+"Instance quota exceeded. You can only run %s more instances of this type."
+msgstr ""
+"Quota d'instances dépassé. Vous ne pouvez éxécuter que %s instances de ce "
+"type de plus."
+
+#: ../nova/compute/api.py:112
+msgid "Creating a raw instance"
+msgstr "Création d'une instance raw"
+
+#: ../nova/compute/api.py:160
+#, python-format
+msgid "Going to run %s instances..."
+msgstr "Démarrage de %s instances..."
+
+#: ../nova/compute/api.py:187
+#, python-format
+msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s"
+msgstr "Envoi au scheduler de %(pid)s/%(uid)s's instance %(instance_id)s"
+
+#: ../nova/compute/api.py:292
+#, python-format
+msgid "Going to try to terminate %s"
+msgstr "Va essayer d'arrêter %s"
+
+#: ../nova/compute/api.py:296
+#, python-format
+msgid "Instance %d was not found during terminate"
+msgstr "L'instance %d n'a pas été trouvée durant l'arrêt"
+
+#: ../nova/compute/api.py:301
+#, python-format
+msgid "Instance %d is already being terminated"
+msgstr "L'instance %d est déjà en cours d'arrêt"
+
+#: ../nova/compute/api.py:481
+#, python-format
+msgid "Invalid device specified: %s. Example device: /dev/vdb"
+msgstr "Device spécifié invalide : %s. Exemple de device: /dev/vdb"
+
+#: ../nova/compute/api.py:496
+msgid "Volume isn't attached to anything!"
+msgstr "Le volume n'est pas attaché à quoi que ce soit!"
+
+#: ../nova/rpc.py:98
+#, python-format
+msgid ""
+"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in "
+"%(fl_intv)d seconds."
+msgstr ""
+"Le serveur AMQP sur %(fl_host)s:%(fl_port)d n'est pas joignable. Nouvel "
+"essai dans %(fl_intv)d secondes."
+
+#: ../nova/rpc.py:103
+#, python-format
+msgid "Unable to connect to AMQP server after %d tries. Shutting down."
+msgstr ""
+"Impossible de se connecter au serveur AMQP après %d essais. Extinction."
+
+#: ../nova/rpc.py:122
+msgid "Reconnected to queue"
+msgstr "Reconnection à la queue"
+
+#: ../nova/rpc.py:129
+msgid "Failed to fetch message from queue"
+msgstr "Impossible de récuperrer les message de la queue"
+
+#: ../nova/rpc.py:159
+#, python-format
+msgid "Initing the Adapter Consumer for %s"
+msgstr "Initialisation du Consomateur d'Adapteur pour %s"
+
+#: ../nova/rpc.py:178
+#, python-format
+msgid "received %s"
+msgstr "%s reçu"
+
+#. NOTE(vish): we may not want to ack here, but that means that bad
+#. messages stay in the queue indefinitely, so for now
+#. we just log the message and send an error string
+#. back to the caller
+#: ../nova/rpc.py:191
+#, python-format
+msgid "no method for message: %s"
+msgstr "Pas de méthode pour le message : %s"
+
+#: ../nova/rpc.py:192
+#, python-format
+msgid "No method for message: %s"
+msgstr "Pas de méthode pour le message : %s"
+
+#: ../nova/rpc.py:253
+#, python-format
+msgid "Returning exception %s to caller"
+msgstr "Renvoi de l'exception %s à l'appelant"
+
+#: ../nova/rpc.py:294
+#, python-format
+msgid "unpacked context: %s"
+msgstr "Contexte décompacté : %s"
+
+#: ../nova/rpc.py:313
+msgid "Making asynchronous call..."
+msgstr "En cours d'appel assynchrone..."
+
+#: ../nova/rpc.py:316
+#, python-format
+msgid "MSG_ID is %s"
+msgstr "MSG_ID est %s"
+
+#: ../nova/rpc.py:354
+msgid "Making asynchronous cast..."
+msgstr "En cours de diffusion assynchrone"
+
+#: ../nova/rpc.py:364
+#, python-format
+msgid "response %s"
+msgstr "réponse %s"
+
+#: ../nova/rpc.py:373
+#, python-format
+msgid "topic is %s"
+msgstr "le sujet est %s"
+
+#: ../nova/rpc.py:374
+#, python-format
+msgid "message %s"
+msgstr "message %s"
+
+#: ../nova/volume/driver.py:78
+#, python-format
+msgid "Recovering from a failed execute. Try number %s"
+msgstr "Récupération après une exécution erronée. Tentative numéro %s"
+
+#: ../nova/volume/driver.py:87
+#, python-format
+msgid "volume group %s doesn't exist"
+msgstr "Le groupe de volume %s n'existe pas"
+
+#: ../nova/volume/driver.py:220
+#, python-format
+msgid "FAKE AOE: %s"
+msgstr "FAUX AOE: %s"
+
+#: ../nova/volume/driver.py:233
+msgid "Skipping ensure_export. No iscsi_target "
+msgstr "ensure_export sauté. Pas d'iscsi_target "
+
+#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288
+msgid "Skipping remove_export. No iscsi_target "
+msgstr "remove_export sauté. Pas d'iscsi_target "
+
+#: ../nova/volume/driver.py:347
+#, python-format
+msgid "FAKE ISCSI: %s"
+msgstr "FAUX ISCSI: %s"
+
+#: ../nova/volume/driver.py:359
+#, python-format
+msgid "rbd has no pool %s"
+msgstr "rbd n'as pas de file %s"
+
+#: ../nova/volume/driver.py:414
+#, python-format
+msgid "Sheepdog is not working: %s"
+msgstr "Sheepdog n'est pas actif : %s"
+
+#: ../nova/volume/driver.py:416
+msgid "Sheepdog is not working"
+msgstr "Sheepdog n'est pas actif"
+
+#: ../nova/wsgi.py:68
+#, python-format
+msgid "Starting %(arg0)s on %(host)s:%(port)s"
+msgstr "Démarrage %(arg0)s sur %(host)s:%(port)s"
+
+#: ../nova/wsgi.py:147
+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"
+
+#: ../bin/nova-dhcpbridge.py:73
+msgid "Adopted old lease or got a change of mac/hostname"
+msgstr "Allocation périmée accepté ou changement de nom/adresse MAC d'hôte"
+
+#: ../bin/nova-dhcpbridge.py:80
+msgid "releasing ip"
+msgstr "Libération IP"
+
+#: ../bin/nova-dhcpbridge.py:123
+#, python-format
+msgid ""
+"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s "
+"on interface %(interface)s"
+msgstr ""
+"%(action)s appelée pour MAC %(mac)s avec IP %(ip)s nom d'hôte %(hostname)s "
+"sur l'interface %(interface)s"
+
+#: ../nova/virt/fake.py:239
+#, python-format
+msgid "Instance %s Not Found"
+msgstr "Instance %s Non trouvée"
+
+#: ../nova/network/manager.py:153
+#, python-format
+msgid "Dissassociated %s stale fixed ip(s)"
+msgstr "Désassociation de %s ip(s) fixes périmées"
+
+#: ../nova/network/manager.py:157
+msgid "setting network host"
+msgstr "réglage de l'hôte réseau"
+
+#: ../nova/network/manager.py:212
+#, python-format
+msgid "Leasing IP %s"
+msgstr "Allocation IP %s"
+
+#: ../nova/network/manager.py:216
+#, python-format
+msgid "IP %s leased that isn't associated"
+msgstr "IP %s allouée qui n'est pas associée"
+
+#: ../nova/network/manager.py:220
+#, python-format
+msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s"
+msgstr "IP %(address)s allouée à une mauvaise MAC %(inst_addr)s pour %(mac)s"
+
+#: ../nova/network/manager.py:228
+#, python-format
+msgid "IP %s leased that was already deallocated"
+msgstr "IP %s alloué qui était déjà désallouée"
+
+#: ../nova/network/manager.py:233
+#, python-format
+msgid "Releasing IP %s"
+msgstr "Libération IP %s"
+
+#: ../nova/network/manager.py:237
+#, python-format
+msgid "IP %s released that isn't associated"
+msgstr "IP %s libérée qui n'était pas associée"
+
+#: ../nova/network/manager.py:241
+#, python-format
+msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s"
+msgstr ""
+"IP %(address)s libérée par une mauvaise MAC %(inst_addr)s pour %(mac)s"
+
+#: ../nova/network/manager.py:244
+#, python-format
+msgid "IP %s released that was not leased"
+msgstr "IP %s libérée qui n'était pas allouée"
+
+#: ../nova/network/manager.py:519
+msgid ""
+"The sum between the number of networks and the vlan start cannot be greater "
+"than 4094"
+msgstr ""
+"La somme du nombre de réseau et le début de vlan ne peut excéder 4094"
+
+#: ../nova/virt/xenapi/volume_utils.py:57
+#, python-format
+msgid "Introducing %s..."
+msgstr "Introduction de %s"
+
+#: ../nova/virt/xenapi/volume_utils.py:74
+#, python-format
+msgid "Introduced %(label)s as %(sr_ref)s."
+msgstr "%(label)s introduit comme %(sr_ref)s."
+
+#: ../nova/virt/xenapi/volume_utils.py:78
+msgid "Unable to create Storage Repository"
+msgstr "Impossible de créer le dépot de stockage"
+
+#: ../nova/virt/xenapi/volume_utils.py:90
+#, python-format
+msgid "Unable to find SR from VBD %s"
+msgstr "Impossible de trouver SR du VDB %s"
+
+#: ../nova/virt/xenapi/volume_utils.py:96
+#, python-format
+msgid "Forgetting SR %s ... "
+msgstr "Démémorisation du SR %s "
+
+#: ../nova/virt/xenapi/volume_utils.py:101
+#, python-format
+msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s"
+msgstr ""
+"Exception %(exc)s ignorée pendant l'obtention de PBDs pour %(sr_ref)s"
+
+#: ../nova/virt/xenapi/volume_utils.py:107
+#, python-format
+msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s"
+msgstr "Exception %(exc)s ignorée pendant la deconnexion du PBD %(pbd)s"
+
+#: ../nova/virt/xenapi/volume_utils.py:111
+#, python-format
+msgid "Forgetting SR %s done."
+msgstr "Démémorisation du SR %s terminée"
+
+#: ../nova/virt/xenapi/volume_utils.py:113
+#, python-format
+msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s"
+msgstr "Exception %(exc)s ignorée pendant la démémorisation du SR %(sr_ref)s"
+
+#: ../nova/virt/xenapi/volume_utils.py:123
+#, python-format
+msgid "Unable to introduce VDI on SR %s"
+msgstr "Impossible d'introduire VDI sur SR %s"
+
+#: ../nova/virt/xenapi/volume_utils.py:128
+#, python-format
+msgid "Unable to get record of VDI %s on"
+msgstr "Impossible de récuppérer l'enregistrement du VDI %s sur"
+
+#: ../nova/virt/xenapi/volume_utils.py:146
+#, python-format
+msgid "Unable to introduce VDI for SR %s"
+msgstr "Impossible d'introduire le VDI pour SR %s"
+
+#: ../nova/virt/xenapi/volume_utils.py:175
+#, python-format
+msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s"
+msgstr ""
+"Impossible de récuppérer les informations de destination %(device_path)s, "
+"%(mountpoint)s"
+
+#: ../nova/virt/xenapi/volume_utils.py:197
+#, python-format
+msgid "Mountpoint cannot be translated: %s"
+msgstr "Le point de montage ne peut pas être traduit : %s"
+
+#: ../nova/objectstore/image.py:262
+#, python-format
+msgid "Failed to decrypt private key: %s"
+msgstr "Impossible de déchiffrer la clef privée : %s"
+
+#: ../nova/objectstore/image.py:269
+#, python-format
+msgid "Failed to decrypt initialization vector: %s"
+msgstr "Impossible de déchiffrer le vecteur d'initialisation : %s"
+
+#: ../nova/objectstore/image.py:277
+#, python-format
+msgid "Failed to decrypt image file %(image_file)s: %(err)s"
+msgstr "Impossible de déchiffrer le fichier image %(image_file)s: %(err)s"
+
+#: ../nova/objectstore/handler.py:106
+#, python-format
+msgid "Unknown S3 value type %r"
+msgstr "Type de valeur S3 inconnu %r"
+
+#: ../nova/objectstore/handler.py:137
+msgid "Authenticated request"
+msgstr "Requête authentifiée"
+
+#: ../nova/objectstore/handler.py:182
+msgid "List of buckets requested"
+msgstr "Listes de conteneurs (buckets) demandée"
+
+#: ../nova/objectstore/handler.py:209
+#, python-format
+msgid "List keys for bucket %s"
+msgstr "List des clefs pour le conteneur (bucket) %s"
+
+#: ../nova/objectstore/handler.py:217
+#, python-format
+msgid "Unauthorized attempt to access bucket %s"
+msgstr "Demande d'accès au conteneur %s non autorisé"
+
+#: ../nova/objectstore/handler.py:235
+#, python-format
+msgid "Creating bucket %s"
+msgstr "Création du conteneur %s"
+
+#: ../nova/objectstore/handler.py:245
+#, python-format
+msgid "Deleting bucket %s"
+msgstr "Suppression du conteneur %s"
+
+#: ../nova/objectstore/handler.py:249
+#, python-format
+msgid "Unauthorized attempt to delete bucket %s"
+msgstr "Tentative de suppression du conteneur %s non autorisée"
+
+#: ../nova/objectstore/handler.py:273
+#, python-format
+msgid "Getting object: %(bname)s / %(nm)s"
+msgstr "Récupération de l'objet : %(bname)s / %(nm)s"
+
+#: ../nova/objectstore/handler.py:276
+#, python-format
+msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s"
+msgstr ""
+"Tentative d'accès à l'objet %(nm)s non autorisée pour le conteneur %(bname)s"
+
+#: ../nova/objectstore/handler.py:296
+#, python-format
+msgid "Putting object: %(bname)s / %(nm)s"
+msgstr "Injection d'objet : %(bname)s / %(nm)s"
+
+#: ../nova/objectstore/handler.py:299
+#, python-format
+msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s"
+msgstr ""
+"Tentative de chargement de l'objet %(nm)s vers le conteneur %(bname)s non "
+"autorisée"
+
+#: ../nova/objectstore/handler.py:318
+#, python-format
+msgid "Deleting object: %(bname)s / %(nm)s"
+msgstr "Suppression de l'objet : %(bname)s / %(nm)s"
+
+#: ../nova/objectstore/handler.py:322
+#, python-format
+msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s"
+msgstr ""
+"Tentative de suppression de l'objet %(nm)s non autorisé pour le conteneur "
+"%(bname)s"
+
+#: ../nova/objectstore/handler.py:396
+#, python-format
+msgid "Not authorized to upload image: invalid directory %s"
+msgstr "Chargement d'image non autorisé : répertoire invalide %s"
+
+#: ../nova/objectstore/handler.py:404
+#, python-format
+msgid "Not authorized to upload image: unauthorized bucket %s"
+msgstr "Chargement d'image non autorisé : conteneur non autorisé %s"
+
+#: ../nova/objectstore/handler.py:409
+#, python-format
+msgid "Starting image upload: %s"
+msgstr "Début de chargement d'image: %s"
+
+#: ../nova/objectstore/handler.py:423
+#, python-format
+msgid "Not authorized to update attributes of image %s"
+msgstr "Tentative de mise a jour d'attributs non autorisée pour l'image %s"
+
+#: ../nova/objectstore/handler.py:431
+#, python-format
+msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r"
+msgstr ""
+"Basculement de l'attribut public de l'image %(image_id)s %(newstatus)r"
+
+#. other attributes imply update
+#: ../nova/objectstore/handler.py:436
+#, python-format
+msgid "Updating user fields on image %s"
+msgstr "Mise à jour des champs utilisateurs sur l'image %s"
+
+#: ../nova/objectstore/handler.py:450
+#, python-format
+msgid "Unauthorized attempt to delete image %s"
+msgstr "Tentative de suppression de l'image %s non autorisée"
+
+#: ../nova/objectstore/handler.py:455
+#, python-format
+msgid "Deleted image: %s"
+msgstr "Image supprimée : %s"
+
+#: ../nova/auth/manager.py:259
+#, python-format
+msgid "Looking up user: %r"
+msgstr "Recherche de l'utilisateur : %r"
+
+#: ../nova/auth/manager.py:263
+#, python-format
+msgid "Failed authorization for access key %s"
+msgstr "Autorisation refusée pour la clef d'accès %s"
+
+#: ../nova/auth/manager.py:264
+#, python-format
+msgid "No user found for access key %s"
+msgstr "Pas d'utilisateur trouvé pour la clef d'accès %s"
+
+#: ../nova/auth/manager.py:270
+#, python-format
+msgid "Using project name = user name (%s)"
+msgstr "Nom de projet utilisé = nom d'utilisateur (%s)"
+
+#: ../nova/auth/manager.py:277
+#, python-format
+msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)"
+msgstr ""
+"Autorisation refusée : pas de projet nommé %(pjid)s (utilisateur=%(uname)s)"
+
+#: ../nova/auth/manager.py:279
+#, python-format
+msgid "No project called %s could be found"
+msgstr "Aucun projet nommé %s trouvé"
+
+#: ../nova/auth/manager.py:287
+#, python-format
+msgid ""
+"Failed authorization: user %(uname)s not admin and not member of project "
+"%(pjname)s"
+msgstr ""
+"Autorisation refusée : utilisateur %(uname)s n'est ni admin ni membre du "
+"projet %(pjname)s"
+
+#: ../nova/auth/manager.py:289
+#, python-format
+msgid "User %(uid)s is not a member of project %(pjid)s"
+msgstr "L'utilisateur %(uid)s n'est pas membre du projet %(pjid)s"
+
+#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309
+#, python-format
+msgid "Invalid signature for user %s"
+msgstr "Signature non valide pour l'utilisateur %s"
+
+#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310
+msgid "Signature does not match"
+msgstr "La signature ne correspond pas"
+
+#: ../nova/auth/manager.py:380
+msgid "Must specify project"
+msgstr "Le projet doit être spécifié"
+
+#: ../nova/auth/manager.py:414
+#, python-format
+msgid "The %s role can not be found"
+msgstr "Le rôle %s n'a pas été trouvé"
+
+#: ../nova/auth/manager.py:416
+#, python-format
+msgid "The %s role is global only"
+msgstr "Le rôle %s est obligatoirement global"
+
+#: ../nova/auth/manager.py:420
+#, python-format
+msgid "Adding role %(role)s to user %(uid)s in project %(pid)s"
+msgstr ""
+"Ajout du rôle %(role)s à l'utilisateur %(uid)s pour le projet %(pid)s"
+
+#: ../nova/auth/manager.py:423
+#, python-format
+msgid "Adding sitewide role %(role)s to user %(uid)s"
+msgstr "Ajout du rôle global %(role)s pour l'utilisateur %(uid)s"
+
+#: ../nova/auth/manager.py:448
+#, python-format
+msgid "Removing role %(role)s from user %(uid)s on project %(pid)s"
+msgstr ""
+"Suppression du rôle %(role)s pour l'utilisateur %(uid)s dans le projet "
+"%(pid)s"
+
+#: ../nova/auth/manager.py:451
+#, python-format
+msgid "Removing sitewide role %(role)s from user %(uid)s"
+msgstr "Suppression du role global %(role)s pour l'utilisateur %(uid)s"
+
+#: ../nova/auth/manager.py:515
+#, python-format
+msgid "Created project %(name)s with manager %(manager_user)s"
+msgstr "Création du projet %(name)s ayant pour manager %(manager_user)s"
+
+#: ../nova/auth/manager.py:533
+#, python-format
+msgid "modifying project %s"
+msgstr "modification du projet %s"
+
+#: ../nova/auth/manager.py:545
+#, python-format
+msgid "Adding user %(uid)s to project %(pid)s"
+msgstr "Ajout de l'utilisateur %(uid)s au projet %(pid)s"
+
+#: ../nova/auth/manager.py:566
+#, python-format
+msgid "Remove user %(uid)s from project %(pid)s"
+msgstr "Suppression de l'utilisateur %(uid)s du projet %(pid)s"
+
+#: ../nova/auth/manager.py:592
+#, python-format
+msgid "Deleting project %s"
+msgstr "Suppression du projet %s"
+
+#: ../nova/auth/manager.py:650
+#, python-format
+msgid "Created user %(rvname)s (admin: %(rvadmin)r)"
+msgstr "Utilisateur créé %(rvname)s (admin: %(rvadmin)r)"
+
+#: ../nova/auth/manager.py:659
+#, python-format
+msgid "Deleting user %s"
+msgstr "Suppression de l'utilisateur %s"
+
+#: ../nova/auth/manager.py:669
+#, python-format
+msgid "Access Key change for user %s"
+msgstr "Clef d'accès changée pour l'utilisateur %s"
+
+#: ../nova/auth/manager.py:671
+#, python-format
+msgid "Secret Key change for user %s"
+msgstr "Clef secrète changée pour l'utilisateur %s"
+
+#: ../nova/auth/manager.py:673
+#, python-format
+msgid "Admin status set to %(admin)r for user %(uid)s"
+msgstr "Statut admin changé en %(admin)r pour l'utilisateur %(uid)s"
+
+#: ../nova/auth/manager.py:722
+#, python-format
+msgid "No vpn data for project %s"
+msgstr "Pas de données VPN pour le projet %s"
+
+#: ../nova/service.py:161
+#, python-format
+msgid "Starting %(topic)s node (version %(vcs_string)s)"
+msgstr "Démarrage du noeud %(topic)s (version %(vcs_string)s)"
+
+#: ../nova/service.py:174
+msgid "Service killed that has no database entry"
+msgstr "Service détruit sans entrée dans la base de données"
+
+#: ../nova/service.py:195
+msgid "The service database object disappeared, Recreating it."
+msgstr ""
+"L'objet du service de base de données à disparru, re-création en cours."
+
+#: ../nova/service.py:207
+msgid "Recovered model server connection!"
+msgstr "Récupération du modelle de connexion serveur terminée!"
+
+#: ../nova/service.py:213
+msgid "model server went away"
+msgstr "Le modèle de serveur à disparu"
+
+#: ../nova/auth/ldapdriver.py:174
+#, python-format
+msgid "LDAP user %s already exists"
+msgstr "L'utilisateur LDAP %s existe déjà"
+
+#: ../nova/auth/ldapdriver.py:205
+#, python-format
+msgid "LDAP object for %s doesn't exist"
+msgstr "L'objet LDAP pour %s n'existe pas"
+
+#: ../nova/auth/ldapdriver.py:348
+#, python-format
+msgid "User %s doesn't exist"
+msgstr "L'utilisateur %s n'existe pas"
+
+#: ../nova/auth/ldapdriver.py:472
+#, python-format
+msgid "Group can't be created because group %s already exists"
+msgstr "Un groupe nommé %s existe déjà"
+
+#: ../nova/auth/ldapdriver.py:478
+#, python-format
+msgid "Group can't be created because user %s doesn't exist"
+msgstr "Le groupe n'a pu être créé car l'utilisateur %s n'existe pas"
+
+#: ../nova/auth/ldapdriver.py:495
+#, python-format
+msgid "User %s can't be searched in group because the user doesn't exist"
+msgstr ""
+"L'utilisateur %s ne peut pas être trouvé dans le groupe car cet utilisateur "
+"n'existe pas"
+
+#: ../nova/auth/ldapdriver.py:507
+#, python-format
+msgid "User %s can't be added to the group because the user doesn't exist"
+msgstr ""
+"L'utilisateur %s ne peut être ajouté au groupe car cet utilisateur n'existe "
+"pas"
+
+#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521
+#, python-format
+msgid "The group at dn %s doesn't exist"
+msgstr "Le group ayant pour dn %s n'existe pas"
+
+#: ../nova/auth/ldapdriver.py:513
+#, python-format
+msgid "User %(uid)s is already a member of the group %(group_dn)s"
+msgstr "L'utilisateur %(uid)s est déjà membre du groupe %(group_dn)s"
+
+#: ../nova/auth/ldapdriver.py:524
+#, python-format
+msgid ""
+"User %s can't be removed from the group because the user doesn't exist"
+msgstr ""
+"L'utilisateur %s ne peut être supprimé du groupe car cet utilisateur "
+"n'existe pas"
+
+#: ../nova/auth/ldapdriver.py:528
+#, python-format
+msgid "User %s is not a member of the group"
+msgstr "L'utilisateur %s n'est pas membre du groupe"
+
+#: ../nova/auth/ldapdriver.py:542
+#, python-format
+msgid ""
+"Attempted to remove the last member of a group. Deleting the group at %s "
+"instead."
+msgstr ""
+"Tentative de suppression du dernier membre d'un groupe. Essayez plutôt de "
+"supprimer le group sur %s."
+
+#: ../nova/auth/ldapdriver.py:549
+#, python-format
+msgid "User %s can't be removed from all because the user doesn't exist"
+msgstr ""
+"L'utilisateur %s ne peut être supprimé partout car l'utilisateur n'existe pas"
+
+#: ../nova/auth/ldapdriver.py:564
+#, python-format
+msgid "Group at dn %s doesn't exist"
+msgstr "Le groupe ayant pour dn %s n'existe pas"
+
+#: ../nova/virt/xenapi/network_utils.py:40
+#, python-format
+msgid "Found non-unique network for bridge %s"
+msgstr "Réseau non unique trouvé pour le bridge %s"
+
+#: ../nova/virt/xenapi/network_utils.py:43
+#, python-format
+msgid "Found no network for bridge %s"
+msgstr "Aucun réseau trouvé pour le bridge %s"
+
+#: ../nova/api/ec2/admin.py:97
+#, python-format
+msgid "Creating new user: %s"
+msgstr "Création d'un nouvel utilisateur : %s"
+
+#: ../nova/api/ec2/admin.py:105
+#, python-format
+msgid "Deleting user: %s"
+msgstr "Suppression de l'utilisateur : %s"
+
+#: ../nova/api/ec2/admin.py:127
+#, python-format
+msgid "Adding role %(role)s to user %(user)s for project %(project)s"
+msgstr ""
+"Ajout du rôle %(role)s à l'utilisateur %(user)s pour le projet %(project)s"
+
+#: ../nova/api/ec2/admin.py:131
+#, python-format
+msgid "Adding sitewide role %(role)s to user %(user)s"
+msgstr "Ajout du rôle global %(role)s à l'utilisateur %(user)s"
+
+#: ../nova/api/ec2/admin.py:137
+#, python-format
+msgid "Removing role %(role)s from user %(user)s for project %(project)s"
+msgstr ""
+"Suppresion du rôle %(role)s de l'utilisateur %(user)s pour le projet "
+"%(project)s"
+
+#: ../nova/api/ec2/admin.py:141
+#, python-format
+msgid "Removing sitewide role %(role)s from user %(user)s"
+msgstr "Suppression du rôle global %(role)s pour l'utilisateur %(user)s"
+
+#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223
+msgid "operation must be add or remove"
+msgstr "L'opération doit être ajout ou suppression"
+
+#: ../nova/api/ec2/admin.py:159
+#, python-format
+msgid "Getting x509 for user: %(name)s on project: %(project)s"
+msgstr ""
+"Récupération de x509 pour l'utilisateur : %(name)s sur le projet : "
+"%(project)s"
+
+#: ../nova/api/ec2/admin.py:177
+#, python-format
+msgid "Create project %(name)s managed by %(manager_user)s"
+msgstr "Création du projet %(name)s géré par %(manager_user)s"
+
+#: ../nova/api/ec2/admin.py:190
+#, python-format
+msgid "Modify project: %(name)s managed by %(manager_user)s"
+msgstr "Modification du projet: %(name)s géré par %(manager_user)s"
+
+#: ../nova/api/ec2/admin.py:200
+#, python-format
+msgid "Delete project: %s"
+msgstr "Supprimer le projet : %s"
+
+#: ../nova/api/ec2/admin.py:214
+#, python-format
+msgid "Adding user %(user)s to project %(project)s"
+msgstr "Ajout de l'utilisateur %(user)s au projet %(project)s"
+
+#: ../nova/api/ec2/admin.py:218
+#, python-format
+msgid "Removing user %(user)s from project %(project)s"
+msgstr "Suppression de l'utilisateur %(user)s du projet %(project)s"
diff --git a/po/it.po b/po/it.po
index 1beb116a3..60c3a388a 100644
--- a/po/it.po
+++ b/po/it.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-03-19 06:19+0000\n"
-"X-Generator: Launchpad (build 12559)\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
#: ../nova/scheduler/chance.py:37 ../nova/scheduler/zone.py:55
#: ../nova/scheduler/simple.py:75 ../nova/scheduler/simple.py:110
diff --git a/po/ja.po b/po/ja.po
index 87065d778..09d17af3b 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -8,20 +8,20 @@ msgstr ""
"Project-Id-Version: nova\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-02-21 10:03-0500\n"
-"PO-Revision-Date: 2011-03-29 07:27+0000\n"
-"Last-Translator: Koji Iida <Unknown>\n"
+"PO-Revision-Date: 2011-05-10 10:26+0000\n"
+"Last-Translator: Akira YOSHIYAMA <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-03-30 05:22+0000\n"
-"X-Generator: Launchpad (build 12559)\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
#: ../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
msgid "No hosts found"
-msgstr "é©åˆ‡ãªãƒ›ã‚¹ãƒˆãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
+msgstr "ホストãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
#: ../nova/exception.py:33
msgid "Unexpected error while running command."
@@ -36,10 +36,15 @@ msgid ""
"Stdout: %(stdout)r\n"
"Stderr: %(stderr)r"
msgstr ""
+"%(description)s\n"
+"コマンド: %(cmd)s\n"
+"終了コード: %(exit_code)s\n"
+"標準出力: %(stdout)r\n"
+"標準エラー出力: %(stderr)r"
#: ../nova/exception.py:107
msgid "DB exception wrapped"
-msgstr ""
+msgstr "DB 例外ãŒãƒ©ãƒƒãƒ—(wrapped)ã•れã¾ã—ãŸ"
#. exc_type, exc_value, exc_traceback = sys.exc_info()
#: ../nova/exception.py:120
@@ -49,32 +54,32 @@ msgstr "キャッãƒã•れãªã‹ã£ãŸä¾‹å¤–"
#: ../nova/volume/api.py:45
#, python-format
msgid "Quota exceeeded for %(pid)s, tried to create %(size)sG volume"
-msgstr "サイズ %(size)sG ã®ãƒœãƒªãƒ¥ãƒ¼ãƒ ã®ä½œæˆã‚’行ãŠã†ã¨ã—ã¾ã—ãŸãŒã€%(pid)sã®ã‚¯ã‚ªãƒ¼ã‚¿ã‚’è¶…ãˆã¦ã„ã¾ã™ã€‚"
+msgstr "サイズ %(size)s GB ã®ãƒœãƒªãƒ¥ãƒ¼ãƒ ä½œæˆã‚’行ãŠã†ã¨ã—ã¾ã—ãŸãŒã€%(pid)s ã®ã‚µã‚¤ã‚ºåˆ¶é™ã‚’è¶…ãˆã¦ã„ã¾ã™ã€‚"
#: ../nova/volume/api.py:47
#, python-format
msgid "Volume quota exceeded. You cannot create a volume of size %sG"
-msgstr "ボリュームã®ã‚¯ã‚ªãƒ¼ã‚¿ã‚’è¶…ãˆã¦ã„ã¾ã™ã€‚%sã®å¤§ãã•ã®ãƒœãƒªãƒ¥ãƒ¼ãƒ ã¯ä½œæˆã§ãã¾ã›ã‚“。"
+msgstr "ボリュームã®ã‚µã‚¤ã‚ºåˆ¶é™ã‚’è¶…ãˆã¦ã„ã¾ã™ã€‚サイズ %s GB ã®ãƒœãƒªãƒ¥ãƒ¼ãƒ ã¯ä½œæˆã§ãã¾ã›ã‚“。"
#: ../nova/volume/api.py:71 ../nova/volume/api.py:96
msgid "Volume status must be available"
-msgstr "ボリュームã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹(status)㌠available ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。"
+msgstr "ボリュームã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹(status)㯠available ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。"
#: ../nova/volume/api.py:98
msgid "Volume is already attached"
-msgstr "ãƒœãƒªãƒ¥ãƒ¼ãƒ ã¯æ—¢ã«ã‚¢ã‚¿ãƒƒãƒã•れã¦ã„ã¾ã™(attached)。"
+msgstr "ãƒœãƒªãƒ¥ãƒ¼ãƒ ã¯æ—¢ã«æŽ¥ç¶š(attached)ã•れã¦ã„ã¾ã™ã€‚"
#: ../nova/volume/api.py:104
msgid "Volume is already detached"
-msgstr "ãƒœãƒªãƒ¥ãƒ¼ãƒ ã¯æ—¢ã«ãƒ‡ã‚¿ãƒƒãƒã•れã¦ã„ã¾ã™(detached)。"
+msgstr "ãƒœãƒªãƒ¥ãƒ¼ãƒ ã¯æ—¢ã«åˆ‡æ–­(detached)ã•れã¦ã„ã¾ã™ã€‚"
#: ../nova/api/openstack/servers.py:72
msgid "Failed to read private ip"
-msgstr ""
+msgstr "プライベート IP アドレスã®ãƒªãƒ¼ãƒ‰ã«å¤±æ•—ã—ã¾ã—ãŸ"
#: ../nova/api/openstack/servers.py:79
msgid "Failed to read public ip(s)"
-msgstr ""
+msgstr "パブリック IP アドレスã®ãƒªãƒ¼ãƒ‰ã«å¤±æ•—ã—ã¾ã—ãŸ"
#: ../nova/api/openstack/servers.py:152
#, python-format
@@ -83,7 +88,7 @@ msgstr "イメージ %(_image_id)s ã«å¯¾ã™ã‚‹ãƒ—ロパティ %(param)s ãŒè¦‹ã
#: ../nova/api/openstack/servers.py:168
msgid "No keypairs defined"
-msgstr "キーペアãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“。"
+msgstr "キーペアãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“"
#: ../nova/api/openstack/servers.py:238
#, python-format
@@ -103,7 +108,7 @@ msgstr "例外: Compute.api::get_lock %s"
#: ../nova/api/openstack/servers.py:281
#, python-format
msgid "Compute.api::reset_network %s"
-msgstr ""
+msgstr "例外: Compute.api::reset_network %s"
#: ../nova/api/openstack/servers.py:292
#, python-format
@@ -150,7 +155,7 @@ msgstr "FLAGSã®ä¸€è¦§:"
#: ../nova/twistd.py:266
#, python-format
msgid "Starting %s"
-msgstr "%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
@@ -163,33 +168,33 @@ msgstr "インスタンス %s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
#: ../nova/virt/xenapi/volumeops.py:51
#, python-format
msgid "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s"
-msgstr ""
+msgstr "ボリューム接続: %(instance_name)s, %(device_path)s, %(mountpoint)s"
#: ../nova/virt/xenapi/volumeops.py:69
#, python-format
msgid "Unable to create VDI on SR %(sr_ref)s for instance %(instance_name)s"
-msgstr ""
+msgstr "インスタンス %(instance_name)s 用ã®SR %(sr_ref)s ã«ãŠã‘ã‚‹ VDI を作æˆã§ãã¾ã›ã‚“"
#: ../nova/virt/xenapi/volumeops.py:80
#, python-format
msgid "Unable to use SR %(sr_ref)s for instance %(instance_name)s"
-msgstr ""
+msgstr "インスタンス %(instance_name)s 用ã®SR %(sr_ref)s ãŒä½¿ç”¨ã§ãã¾ã›ã‚“"
#: ../nova/virt/xenapi/volumeops.py:91
#, python-format
msgid "Unable to attach volume to instance %s"
-msgstr "インスタンス %s ã«ãƒœãƒªãƒ¥ãƒ¼ãƒ ã‚’アタッãƒã§ãã¾ã›ã‚“。"
+msgstr "インスタンス %s ã«ãƒœãƒªãƒ¥ãƒ¼ãƒ ã‚’接続(attach)ã§ãã¾ã›ã‚“。"
#: ../nova/virt/xenapi/volumeops.py:93
#, python-format
msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s"
-msgstr "インスタンス %(instance_name)s ã«ãƒžã‚¦ãƒ³ãƒˆãƒã‚¤ãƒ³ãƒˆ %(mountpoint)s をアタッãƒã—ã¾ã—ãŸã€‚"
+msgstr "インスタンス %(instance_name)s ã«ãƒžã‚¦ãƒ³ãƒˆãƒã‚¤ãƒ³ãƒˆ %(mountpoint)s を接続(attach)ã—ã¾ã—ãŸ"
#. Detach VBD from VM
#: ../nova/virt/xenapi/volumeops.py:104
#, python-format
msgid "Detach_volume: %(instance_name)s, %(mountpoint)s"
-msgstr ""
+msgstr "ボリューム切断: %(instance_name)s, %(mountpoint)s"
#: ../nova/virt/xenapi/volumeops.py:112
#, python-format
@@ -199,17 +204,17 @@ msgstr "ボリューム %s ã®å­˜åœ¨ãŒç¢ºèªã§ãã¾ã›ã‚“。"
#: ../nova/virt/xenapi/volumeops.py:120
#, python-format
msgid "Unable to detach volume %s"
-msgstr "ボリューム %s ã®ãƒ‡ã‚¿ãƒƒãƒãŒã§ãã¾ã›ã‚“。"
+msgstr "ボリューム %s を切断(detach)ã§ãã¾ã›ã‚“"
#: ../nova/virt/xenapi/volumeops.py:127
#, python-format
msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s"
-msgstr "インスタンス %(instance_name)s ã‹ã‚‰ãƒžã‚¦ãƒ³ãƒˆãƒã‚¤ãƒ³ãƒˆ %(mountpoint)s をデタッãƒã—ã¾ã—ãŸã€‚"
+msgstr "インスタンス %(instance_name)s ã‹ã‚‰ãƒžã‚¦ãƒ³ãƒˆãƒã‚¤ãƒ³ãƒˆ %(mountpoint)s を切断(detach)ã—ã¾ã—ãŸ"
#: ../nova/compute/instance_types.py:41
#, python-format
msgid "Unknown instance type: %s"
-msgstr "%s ã¯æœªçŸ¥ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚¿ã‚¤ãƒ—ã§ã™ã€‚"
+msgstr "未知ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚¿ã‚¤ãƒ—: %s"
#: ../nova/crypto.py:46
msgid "Filename of root CA"
@@ -258,7 +263,7 @@ msgstr "Flags ã®ãƒ‘ス: %s"
#: ../nova/scheduler/manager.py:69
#, python-format
msgid "Casting to %(topic)s %(host)s for %(method)s"
-msgstr ""
+msgstr "%(method)s 用㫠%(topic)s %(host)s を割り当ã¦ä¸­"
#: ../nova/compute/manager.py:78
#, python-format
@@ -269,7 +274,7 @@ msgstr "check_instance_lock: decorating: |%s|"
#, python-format
msgid ""
"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|"
-msgstr ""
+msgstr "check_instance_lock: 引数: |%(self)s| |%(context)s| |%(instance_id)s|"
#: ../nova/compute/manager.py:84
#, python-format
@@ -298,23 +303,23 @@ msgstr "ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã¯æ—¢ã«ç”Ÿæˆã•れã¦ã„ã¾ã™ã€‚"
#: ../nova/compute/manager.py:180
#, python-format
msgid "instance %s: starting..."
-msgstr "インスタンス %s ã‚’é–‹å§‹ã—ã¾ã™ã€‚"
+msgstr "インスタンス %s: 起動中…"
#. pylint: disable=W0702
#: ../nova/compute/manager.py:219
#, python-format
msgid "instance %s: Failed to spawn"
-msgstr "インスタンス %s ã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
+msgstr "インスタンス %s: èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸ"
#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286
#, python-format
msgid "Terminating instance %s"
-msgstr "Terminating instance: インスタンス %s を終了ã—ã¾ã™ã€‚"
+msgstr "インスタンス %s ã‚’åœæ­¢ä¸­"
#: ../nova/compute/manager.py:255
#, python-format
msgid "Deallocating address %s"
-msgstr "アドレス %s ã®å‰²å½“を解除(deallocate)ã—ã¾ã™ã€‚"
+msgstr "アドレス %s ã®å‰²å½“を解除中(deallocating)"
#: ../nova/compute/manager.py:268
#, python-format
@@ -338,7 +343,7 @@ msgstr ""
#: ../nova/compute/manager.py:311
#, python-format
msgid "instance %s: snapshotting"
-msgstr "snapshotting: インスタンス %s ã®ã‚¹ãƒŠãƒƒãƒ—ショットをå–å¾—ã—ã¾ã™ã€‚"
+msgstr "snapshotting: インスタンス %s ã®ã‚¹ãƒŠãƒƒãƒ—ショットをå–得中"
#: ../nova/compute/manager.py:316
#, python-format
@@ -361,7 +366,7 @@ msgstr ""
#: ../nova/compute/manager.py:335
#, python-format
msgid "instance %s: setting admin password"
-msgstr "インスタンス %s: admin password をセットã—ã¾ã™"
+msgstr "インスタンス %s: 管ç†è€…用パスワードをセット中"
#: ../nova/compute/manager.py:353
#, python-format
@@ -375,7 +380,7 @@ msgstr ""
#: ../nova/compute/manager.py:362
#, python-format
msgid "instance %(nm)s: injecting file to %(plain_path)s"
-msgstr "インスタンス %(nm)s: ファイルを %(plain_path)s ã«ã‚¤ãƒ³ã‚¸ã‚§ã‚¯ãƒˆã—ã¾ã™"
+msgstr "インスタンス %(nm)s: ファイルを %(plain_path)s ã«åŸ‹ã‚è¾¼ã¿ä¸­"
#: ../nova/compute/manager.py:372
#, python-format
@@ -447,7 +452,7 @@ msgstr "インスタンス %s: ajax consoleを接続ã—ã¾ã™"
msgid ""
"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s"
msgstr ""
-"インスタンス %(instance_id)s: ボリューム %(volume_id)s ã‚’ %(mountpoint)s ã«ã‚¢ã‚¿ãƒƒãƒã—ã¾ã™"
+"インスタンス %(instance_id)s: ボリューム %(volume_id)s ã‚’ %(mountpoint)s ã«æŽ¥ç¶šä¸­(attaching)"
#. pylint: disable=W0702
#. NOTE(vish): The inline callback eats the exception info so we
@@ -549,7 +554,7 @@ msgstr "ボリューム %s ã®å‰Šé™¤ã«æˆåŠŸã—ã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/fake.py:74
#, python-format
msgid "%(text)s: _db_content => %(content)s"
-msgstr ""
+msgstr "%(text)s: _db_content => %(content)s"
#: ../nova/virt/xenapi/fake.py:304 ../nova/virt/xenapi/fake.py:404
#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478
@@ -616,12 +621,12 @@ msgstr "Pid %d ã¯ç„¡åйã§ã™ã€‚dnsmasqã‚’å†å®Ÿè¡Œã—ã¾ã™ã€‚"
#: ../nova/network/linux_net.py:358
#, python-format
msgid "killing radvd threw %s"
-msgstr ""
+msgstr "radvd åœæ­¢ãŒ %s 例外を発行ã—ã¾ã—ãŸ"
#: ../nova/network/linux_net.py:360
#, python-format
msgid "Pid %d is stale, relaunching radvd"
-msgstr ""
+msgstr "Pid %d ãŒã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ã„ã‚‹ã®ã§ radvd ã‚’å†å®Ÿè¡Œã—ã¦ã„ã¾ã™â€¦"
#. pylint: disable=W0703
#: ../nova/network/linux_net.py:449
@@ -677,7 +682,7 @@ msgstr "リンクローカルアドレスãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
#: ../nova/utils.py:265
#, python-format
msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s"
-msgstr ""
+msgstr "%(interface)s ã®ãƒ­ãƒ¼ã‚«ãƒ«IPアドレスã®ãƒªãƒ³ã‚¯ãŒå–å¾—ã§ãã¾ã›ã‚“:%(ex)s"
#: ../nova/utils.py:363
#, python-format
@@ -692,7 +697,7 @@ msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ã¯ %s ã§ã™ã€‚"
#: ../nova/fakerabbit.py:49
#, python-format
msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s"
-msgstr ""
+msgstr "(%(nm)s) 公開 (キー: %(routing_key)s) %(message)s"
#: ../nova/fakerabbit.py:54
#, python-format
@@ -712,12 +717,12 @@ msgstr "exchange %s ã®å®£è¨€"
#: ../nova/fakerabbit.py:96
#, python-format
msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s"
-msgstr ""
+msgstr "キー %(routing_key)s 付ãã§ %(exchange)s ã« %(queue)s ã‚’ãƒã‚¤ãƒ³ãƒ‰ã—ã¦ã„ã¾ã™"
#: ../nova/fakerabbit.py:121
#, python-format
msgid "Getting from %(queue)s: %(message)s"
-msgstr ""
+msgstr "%(queue)s ã‹ã‚‰å–å¾—ã—ã¦ã„ã¾ã™: %(message)s"
#: ../nova/virt/xenapi/vm_utils.py:135 ../nova/virt/hyperv.py:171
#, python-format
@@ -727,17 +732,17 @@ msgstr "VM %s を作æˆã—ã¾ã™ã€‚"
#: ../nova/virt/xenapi/vm_utils.py:138
#, python-format
msgid "Created VM %(instance_name)s as %(vm_ref)s."
-msgstr ""
+msgstr "%(vm_ref)s ã¨ã—㦠VM %(instance_name)s を作æˆã—ã¦ã„ã¾ã™"
#: ../nova/virt/xenapi/vm_utils.py:168
#, python-format
msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... "
-msgstr ""
+msgstr "VM %(vm_ref)s, VDI %(vdi_ref)s 用 VBD を作æˆã—ã¦ã„ã¾ã™â€¦ "
#: ../nova/virt/xenapi/vm_utils.py:171
#, python-format
msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s."
-msgstr ""
+msgstr "VM %(vm_ref)s, VDI %(vdi_ref)s 用仮想ブロックデãƒã‚¤ã‚¹(VBD) %(vbd_ref)s を作æˆã—ã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/vm_utils.py:187
#, python-format
@@ -757,12 +762,12 @@ msgstr "VBD %s ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/vm_utils.py:224
#, python-format
msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s."
-msgstr ""
+msgstr "VM %(vm_ref)s, network %(network_ref)s 用仮想インターフェース(VIF)を作æˆã—ã¦ã„ã¾ã™ã€‚"
#: ../nova/virt/xenapi/vm_utils.py:227
#, python-format
msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s."
-msgstr ""
+msgstr "VM %(vm_ref)s, network %(network_ref)s 用 VIF %(vif_ref)s を作æˆã—ã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/vm_utils.py:246
#, python-format
@@ -770,50 +775,52 @@ msgid ""
"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on "
"%(sr_ref)s."
msgstr ""
+"%(sr_ref)s 上㫠VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, "
+"%(read_only)s) を作æˆã—ã¾ã—ãŸã€‚"
#. TODO(sirp): Add quiesce and VSS locking support when Windows support
#. is added
#: ../nova/virt/xenapi/vm_utils.py:258
#, python-format
msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..."
-msgstr ""
+msgstr "ラベル '%(label)s' 付ã VM %(vm_ref)s ã®ã‚¹ãƒŠãƒƒãƒ—ショットを作æˆã—ã¦ã„ã¾ã™â€¦"
#: ../nova/virt/xenapi/vm_utils.py:272
#, python-format
msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s."
-msgstr ""
+msgstr "VM %(vm_ref)s ã‹ã‚‰ã‚¹ãƒŠãƒƒãƒ—ショット %(template_vm_ref)s を作æˆã—ã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/vm_utils.py:286
#, python-format
msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s"
-msgstr ""
+msgstr "ID %(image_id)s ã¨ã—㦠%(vdi_uuids)s ã®ã‚¢ãƒƒãƒ—ロードã®ç‚ºã« xapi ã‚’å•ã„åˆã‚ã›ã—ã¦ã„ã¾ã™"
#: ../nova/virt/xenapi/vm_utils.py:327
#, python-format
msgid "Size for image %(image)s:%(virtual_size)d"
-msgstr ""
+msgstr "イメージ %(image)s ã®ã‚µã‚¤ã‚º:%(virtual_size)d"
#: ../nova/virt/xenapi/vm_utils.py:332
#, python-format
msgid "Glance image %s"
-msgstr ""
+msgstr "Glance イメージ %s"
#. we need to invoke a plugin for copying VDI's
#. content into proper path
#: ../nova/virt/xenapi/vm_utils.py:342
#, python-format
msgid "Copying VDI %s to /boot/guest on dom0"
-msgstr ""
+msgstr "ドメイン0 上㮠/boot/guest 㫠VDI %s をコピー中"
#: ../nova/virt/xenapi/vm_utils.py:352
#, python-format
msgid "Kernel/Ramdisk VDI %s destroyed"
-msgstr ""
+msgstr "カーãƒãƒ«/RAMディスク VDI %s ãŒå‰Šé™¤ã•れã¾ã—ãŸ"
#: ../nova/virt/xenapi/vm_utils.py:361
#, python-format
msgid "Asking xapi to fetch %(url)s as %(access)s"
-msgstr ""
+msgstr "%(access)s ã¨ã—㦠%(url)s å–å¾—ã®ç‚ºã« xapi ã‚’å•ã„åˆã‚ã›ã—ã¦ã„ã¾ã™"
#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402
#, python-format
@@ -823,12 +830,12 @@ msgstr "PV kernelã®vdi %s ã‚’å–å¾—ã—ã¾ã™ã€‚"
#: ../nova/virt/xenapi/vm_utils.py:397
#, python-format
msgid "PV Kernel in VDI:%s"
-msgstr ""
+msgstr "VDI 中㮠PV カーãƒãƒ«:%s"
#: ../nova/virt/xenapi/vm_utils.py:405
#, python-format
msgid "Running pygrub against %s"
-msgstr ""
+msgstr "%s ã«å¯¾ã—㦠pygrub を実行ã—ã¦ã„ã¾ã™"
#: ../nova/virt/xenapi/vm_utils.py:411
#, python-format
@@ -838,6 +845,8 @@ msgstr "Xen Kernel %s ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/vm_utils.py:413
msgid "No Xen kernel found. Booting HVM."
msgstr ""
+"No Xen kernel found. Booting HVM.\r\n"
+"Xen 用カーãƒãƒ«ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。完全仮想化モード(HVM)ã§èµ·å‹•ã—ã¦ã„ã¾ã™ã€‚"
#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431
#, python-format
@@ -862,7 +871,7 @@ msgstr "(VM_UTILS) xenapi ã® power_state -> |%s|"
#: ../nova/virt/xenapi/vm_utils.py:525
#, python-format
msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s"
-msgstr ""
+msgstr "VHD %(vdi_uuid)s ã®è¦ªã¯ %(parent_ref)s ã§ã™"
#: ../nova/virt/xenapi/vm_utils.py:542
#, python-format
@@ -873,14 +882,14 @@ msgstr "SR %s ã‚’å†ã‚¹ã‚­ãƒ£ãƒ³ã—ã¾ã™ã€‚"
#, python-format
msgid ""
"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..."
-msgstr ""
+msgstr "VHD 作æˆãŒåˆ¶é™ã‚’è¶Šãˆã¾ã—ãŸ(%(counter)d > %(max_attempts)d)ã®ã§ã€ä¸­æ­¢ã—ã¦ã„ã¾ã™â€¦"
#: ../nova/virt/xenapi/vm_utils.py:574
#, python-format
msgid ""
"Parent %(parent_uuid)s doesn't match original parent "
"%(original_parent_uuid)s, waiting for coalesce..."
-msgstr ""
+msgstr "親 %(parent_uuid)s ãŒå…ƒã€…ã®è¦ª %(original_parent_uuid)s ã¨ä¸€è‡´ã—ã¾ã›ã‚“。作æˆã‚’待機ã—ã¦ã„ã¾ã™â€¦"
#: ../nova/virt/xenapi/vm_utils.py:590
#, python-format
@@ -890,96 +899,96 @@ msgstr "VM %s ã«VDIãŒå­˜åœ¨ã—ã¾ã›ã‚“。"
#: ../nova/virt/xenapi/vm_utils.py:594
#, python-format
msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s"
-msgstr ""
+msgstr "VM %(vm_ref)s 用ã«äºˆæœŸã—ãªã„æ•°ã® VDI (%(num_vdis)s) ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ"
#: ../nova/virt/xenapi/vm_utils.py:653
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188
#, python-format
msgid "Creating VBD for VDI %s ... "
-msgstr ""
+msgstr "VDI %s 用㫠VBD を作æˆã—ã¦ã„ã¾ã™â€¦ "
#: ../nova/virt/xenapi/vm_utils.py:655
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190
#, python-format
msgid "Creating VBD for VDI %s done."
-msgstr ""
+msgstr "VDI %s 用 VBD ã®ä½œæˆãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/vm_utils.py:657
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192
#, python-format
msgid "Plugging VBD %s ... "
-msgstr ""
+msgstr "VBD %s を接続ã—ã¦ã„ã¾ã™â€¦ "
#: ../nova/virt/xenapi/vm_utils.py:659
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:194
#, python-format
msgid "Plugging VBD %s done."
-msgstr ""
+msgstr "仮想ブロックデãƒã‚¤ã‚¹(VBD) %s ã®æŽ¥ç¶šãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/vm_utils.py:661
#, python-format
msgid "VBD %(vbd)s plugged as %(orig_dev)s"
-msgstr ""
+msgstr "%(orig_dev)s ã¨ã—ã¦ä»®æƒ³ãƒ–ロックデãƒã‚¤ã‚¹(VBD) %(vbd)s を接続ã—ã¾ã—ãŸ"
#: ../nova/virt/xenapi/vm_utils.py:664
#, python-format
msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s"
-msgstr ""
+msgstr "仮想ブロックデãƒã‚¤ã‚¹(VBD) %(vbd)s ã¯ä¸æ­£ãªãƒ‡ãƒã‚¤ã‚¹ã«æŽ¥ç¶šã•れã¾ã—ãŸã®ã§ã€%(dev)s ã«å†ãƒžãƒƒãƒ”ングã—ã¦ã„ã¾ã™"
#: ../nova/virt/xenapi/vm_utils.py:668
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:197
#, python-format
msgid "Destroying VBD for VDI %s ... "
-msgstr ""
+msgstr "VDI %s 用ã®ä»®æƒ³ãƒ–ロックデãƒã‚¤ã‚¹(VBD)を削除ã—ã¦ã„ã¾ã™â€¦ "
#: ../nova/virt/xenapi/vm_utils.py:671
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:200
#, python-format
msgid "Destroying VBD for VDI %s done."
-msgstr ""
+msgstr "VDI %s 用ã®ä»®æƒ³ãƒ–ロックデãƒã‚¤ã‚¹(VBD)ã®å‰Šé™¤ãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/vm_utils.py:683
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211
msgid "VBD.unplug successful first time."
-msgstr ""
+msgstr "VBD.unplug ã¯ï¼‘å›žç›®ã§æˆåŠŸã—ã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/vm_utils.py:688
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216
msgid "VBD.unplug rejected: retrying..."
-msgstr ""
+msgstr "VBD.unplug ãŒæ‹’å¦ã•れã¾ã—ãŸ: å†è©¦è¡Œã—ã¦ã„ã¾ã™â€¦"
#: ../nova/virt/xenapi/vm_utils.py:692
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220
msgid "VBD.unplug successful eventually."
-msgstr ""
+msgstr "VBD.unplug ã¯æœ€çµ‚çš„ã«æˆåŠŸã—ã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/vm_utils.py:695
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:223
#, python-format
msgid "Ignoring XenAPI.Failure in VBD.unplug: %s"
-msgstr ""
+msgstr "VBD.unplug 中㮠XenAPI.Failure を無視ã—ã¦ã„ã¾ã™: %s"
#: ../nova/virt/xenapi/vm_utils.py:704
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:66
#, python-format
msgid "Ignoring XenAPI.Failure %s"
-msgstr ""
+msgstr "XenAPI.Failure %s を無視ã—ã¦ã„ã¾ã™"
#: ../nova/virt/xenapi/vm_utils.py:735
#, python-format
msgid ""
"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..."
-msgstr ""
+msgstr "%(dest)s ã«ãƒ‘ーティションテーブル %(primary_first)d %(primary_last)d を書ã込んã§ã„ã¾ã™â€¦"
#: ../nova/virt/xenapi/vm_utils.py:747
#, python-format
msgid "Writing partition table %s done."
-msgstr ""
+msgstr "パーティションテーブル %s ã®æ›¸ãè¾¼ã¿ãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
#: ../nova/tests/test_rpc.py:89
#, python-format
msgid "Nested received %(queue)s, %(value)s"
-msgstr ""
+msgstr "Nested received %(queue)s, %(value)s"
#: ../nova/tests/test_rpc.py:95
#, python-format
@@ -1003,7 +1012,7 @@ msgstr "id %s ã®serviceãŒå­˜åœ¨ã—ã¾ã›ã‚“。"
#: ../nova/db/sqlalchemy/api.py:251
#, python-format
msgid "No service for %(host)s, %(binary)s"
-msgstr ""
+msgstr "%(host)s, %(binary)s 用ã®ã‚µãƒ¼ãƒ“スãŒã‚りã¾ã›ã‚“"
#: ../nova/db/sqlalchemy/api.py:592
msgid "No fixed ips defined"
@@ -1110,6 +1119,8 @@ msgid ""
"No console pool of type %(console_type)s for compute host %(compute_host)s "
"on proxy host %(host)s"
msgstr ""
+"コンピュータホスト %(compute_host)s 用 %(console_type)s 型コンソールプールãŒãƒ—ロキシホスト %(host)s "
+"上ã«ã‚りã¾ã›ã‚“"
#: ../nova/db/sqlalchemy/api.py:2035
#, python-format
@@ -1119,27 +1130,27 @@ msgstr "プール %(pool_id)s ã« %(instance_id)s ã®ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ãŒã‚りã¾
#: ../nova/db/sqlalchemy/api.py:2057
#, python-format
msgid "on instance %s"
-msgstr ""
+msgstr "インスタンス %s 上"
#: ../nova/db/sqlalchemy/api.py:2058
#, python-format
msgid "No console with id %(console_id)s %(idesc)s"
-msgstr ""
+msgstr "ID %(console_id)s %(idesc)s ã‚’æŒã¤ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ãŒã‚りã¾ã›ã‚“"
#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097
#, python-format
msgid "No zone with id %(zone_id)s"
-msgstr ""
+msgstr "ID %(zone_id)s ã‚’æŒã¤ã‚¾ãƒ¼ãƒ³ãŒã‚りã¾ã›ã‚“"
#: ../nova/virt/libvirt_conn.py:160
#, python-format
msgid "Checking state of %s"
-msgstr ""
+msgstr "%s ã®çŠ¶æ…‹ã‚’ç¢ºèªã—ã¦ã„ã¾ã™"
#: ../nova/virt/libvirt_conn.py:165
#, python-format
msgid "Current state of %(name)s was %(state)s."
-msgstr ""
+msgstr "%(name)s ã®ç¾åœ¨ã®çŠ¶æ…‹ã¯ %(state)s ã§ã™"
#: ../nova/virt/libvirt_conn.py:183
#, python-format
@@ -1153,12 +1164,12 @@ msgstr "libvirtã¸ã®æŽ¥ç¶šãŒåˆ‡ã‚Œã¦ã„ã¾ã™ã€‚"
#: ../nova/virt/libvirt_conn.py:258
#, python-format
msgid "instance %(instance_name)s: deleting instance files %(target)s"
-msgstr ""
+msgstr "インスタンス %(instance_name)s: インスタンスファイル群 %(target)s を削除ã—ã¦ã„ã¾ã™"
#: ../nova/virt/libvirt_conn.py:283
#, python-format
msgid "Invalid device path %s"
-msgstr ""
+msgstr "%s ã¯ä¸æ­£ãªãƒ‡ãƒã‚¤ã‚¹ãƒ‘スã§ã™"
#: ../nova/virt/libvirt_conn.py:313
#, python-format
@@ -1216,16 +1227,16 @@ msgstr "デãƒã‚¤ã‚¹ã§ã™ã€‚"
#: ../nova/virt/libvirt_conn.py:448
#, python-format
msgid "data: %(data)r, fpath: %(fpath)r"
-msgstr ""
+msgstr "データ: %(data)r, ファイルパス: %(fpath)r"
#: ../nova/virt/libvirt_conn.py:456
#, python-format
msgid "Contents of file %(fpath)s: %(contents)r"
-msgstr ""
+msgstr "ファイル %(fpath)s ã®å†…容: %(contents)r"
#: ../nova/virt/libvirt_conn.py:489
msgid "Unable to find an open port"
-msgstr ""
+msgstr "é–‹ã„ãŸãƒãƒ¼ãƒˆãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
#: ../nova/virt/libvirt_conn.py:563
#, python-format
@@ -1235,12 +1246,12 @@ msgstr "インスタンス %s ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’生æˆã—ã¾ã™ã€‚"
#: ../nova/virt/libvirt_conn.py:646
#, python-format
msgid "instance %(inst_name)s: injecting key into image %(img_id)s"
-msgstr ""
+msgstr "インスタンス %(inst_name)s: イメージ %(img_id)s ã«éµæƒ…報を埋ã‚込んã§ã„ã¾ã™"
#: ../nova/virt/libvirt_conn.py:649
#, python-format
msgid "instance %(inst_name)s: injecting net into image %(img_id)s"
-msgstr ""
+msgstr "インスタンス %(inst_name)s: イメージ %(img_id)s ã«ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æƒ…報を埋ã‚込んã§ã„ã¾ã™"
#. This could be a windows image, or a vmdk format disk
#: ../nova/virt/libvirt_conn.py:657
@@ -1248,7 +1259,7 @@ msgstr ""
msgid ""
"instance %(inst_name)s: ignoring error injecting data into image %(img_id)s "
"(%(e)s)"
-msgstr ""
+msgstr "インスタンス %(inst_name)s: イメージ %(img_id)s ã¸ã®ãƒ‡ãƒ¼ã‚¿åŸ‹ã‚è¾¼ã¿ã®ã‚¨ãƒ©ãƒ¼ã‚’無視ã—ã¦ã„ã¾ã™ (%(e)s)"
#. TODO(termie): cache?
#: ../nova/virt/libvirt_conn.py:665
@@ -1263,12 +1274,12 @@ msgstr "インスタンス %s: toXML メソッドを完了。"
#: ../nova/virt/libvirt_conn.py:751
msgid "diagnostics are not supported for libvirt"
-msgstr ""
+msgstr "libvirt ã§ã¯è¨ºæ–­(diagnostics)ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
#: ../nova/virt/libvirt_conn.py:1225
#, python-format
msgid "Attempted to unfilter instance %s which is not filtered"
-msgstr ""
+msgstr "フィルタã•れã¦ã„ãªã„インスタンス %s ã®ãƒ•ィルタ解除を試行ã—ã¾ã—ãŸ"
#: ../nova/api/ec2/metadatarequesthandler.py:76
#, python-format
@@ -1296,7 +1307,7 @@ msgstr "ターゲット %s をアロケートã—ã¾ã—ãŸã€‚"
#: ../nova/virt/images.py:70
#, python-format
msgid "Finished retreving %(url)s -- placed in %(path)s"
-msgstr ""
+msgstr "%(url)s ã®å–得を完了ã—ã¾ã—㟠-- %(path)s ã«é…ç½®ã•れã¾ã—ãŸ"
#: ../nova/scheduler/driver.py:66
msgid "Must implement a fallback schedule"
@@ -1304,21 +1315,21 @@ msgstr "予備ã®(fallback)スケジューラを実装ã™ã‚‹å¿…è¦ãŒã‚りã¾ã
#: ../nova/console/manager.py:70
msgid "Adding console"
-msgstr ""
+msgstr "コンソールを追加ã—ã¦ã„ã¾ã™"
#: ../nova/console/manager.py:90
#, python-format
msgid "Tried to remove non-existant console %(console_id)s."
-msgstr ""
+msgstr "存在ã—ãªã„コンソール %(console_id)s を削除ã—よã†ã¨ã—ã¾ã—ãŸ"
#: ../nova/api/direct.py:149
msgid "not available"
-msgstr ""
+msgstr "利用ã§ãã¾ã›ã‚“"
#: ../nova/api/ec2/cloud.py:62
#, python-format
msgid "The key_pair %s already exists"
-msgstr ""
+msgstr "キーペア %s ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™"
#. TODO(vish): Do this with M2Crypto instead
#: ../nova/api/ec2/cloud.py:118
@@ -1352,7 +1363,7 @@ msgstr "Revoke security group ingress: ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ã‚°ãƒ«ãƒ¼ãƒ—è¨±å¯ %s ã
#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459
msgid "Not enough parameters to build a valid rule."
-msgstr ""
+msgstr "有効ãªãƒ«ãƒ¼ãƒ«ã‚’作æˆã™ã‚‹ç‚ºã®å分ãªãƒ‘ラメータãŒã‚りã¾ã›ã‚“"
#: ../nova/api/ec2/cloud.py:443
msgid "No rule for the specified parameters."
@@ -1391,7 +1402,7 @@ msgstr "Create volume: %s GBã®ãƒœãƒªãƒ¥ãƒ¼ãƒ ã‚’作æˆã—ã¾ã™ã€‚"
#: ../nova/api/ec2/cloud.py:612
#, python-format
msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s"
-msgstr ""
+msgstr "ボリューム %(volume_id)s をインスタンス %(instance_id)s ã®ãƒ‡ãƒã‚¤ã‚¹ %(device)s ã«æŽ¥ç¶š"
#: ../nova/api/ec2/cloud.py:629
#, python-format
@@ -1410,7 +1421,7 @@ msgstr "Release address: アドレス %s を開放ã—ã¾ã™ã€‚"
#: ../nova/api/ec2/cloud.py:771
#, python-format
msgid "Associate address %(public_ip)s to instance %(instance_id)s"
-msgstr ""
+msgstr "インスタンス %(instance_id)s ã«ã‚¢ãƒ‰ãƒ¬ã‚¹ %(public_ip)s を割り当ã¦"
#: ../nova/api/ec2/cloud.py:780
#, python-format
@@ -1434,7 +1445,7 @@ msgstr "De-registering image: イメージ %s を登録解除ã—ã¾ã™ã€‚"
#: ../nova/api/ec2/cloud.py:875
#, python-format
msgid "Registered image %(image_location)s with id %(image_id)s"
-msgstr ""
+msgstr "イメージ %(image_location)s ㌠ID %(image_id)s ã§ç™»éŒ²ã•れã¾ã—ãŸ"
#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900
#, python-format
@@ -1466,12 +1477,12 @@ msgstr "イメージ %s ã®å…¬é–‹è¨­å®šã‚’æ›´æ–°ã—ã¾ã™ã€‚"
#: ../bin/nova-api.py:52
#, python-format
msgid "Using paste.deploy config at: %s"
-msgstr ""
+msgstr "%s ã«ã‚ã‚‹ paste.deploy 設定を使用ã—ã¦ã„ã¾ã™"
#: ../bin/nova-api.py:57
#, python-format
msgid "No paste configuration for app: %s"
-msgstr ""
+msgstr "アプリケーション用 paste 設定ãŒã‚りã¾ã›ã‚“: %s"
#: ../bin/nova-api.py:59
#, python-format
@@ -1479,60 +1490,63 @@ msgid ""
"App Config: %(api)s\n"
"%(config)r"
msgstr ""
+"アプリケーション設定 %(api)s\n"
+"%(config)r"
#: ../bin/nova-api.py:64
#, python-format
msgid "Running %s API"
-msgstr ""
+msgstr "%s API を実行ã—ã¦ã„ã¾ã™"
#: ../bin/nova-api.py:69
#, python-format
msgid "No known API applications configured in %s."
-msgstr ""
+msgstr "%s ä¸­ã«æ—¢çŸ¥ã® API アプリケーション設定ãŒã‚りã¾ã›ã‚“。"
#: ../bin/nova-api.py:83
#, python-format
msgid "Starting nova-api node (version %s)"
-msgstr ""
+msgstr "nova-api ノードを起動ã—ã¦ã„ã¾ã™ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s)"
#: ../bin/nova-api.py:89
#, python-format
msgid "No paste configuration found for: %s"
-msgstr ""
+msgstr "%s 用㮠paste 設定ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84
#, python-format
msgid "Argument %(key)s value %(value)s is too short."
-msgstr ""
+msgstr "引数 %(key)s ã®å€¤ %(value)s ãŒçŸ­ã™ãŽã¾ã™ã€‚"
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89
#, python-format
msgid "Argument %(key)s value %(value)s contains invalid characters."
-msgstr ""
+msgstr "引数 %(key)s ã®å€¤ %(value)s ãŒä¸æ­£ãªæ–‡å­—ã‚’å«ã‚“ã§ã„ã¾ã™ã€‚"
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94
#, python-format
msgid "Argument %(key)s value %(value)s starts with a hyphen."
-msgstr ""
+msgstr "引数 %(key)s ã®å€¤ %(value)s ãŒãƒã‚¤ãƒ•ン(-)ã‹ã‚‰å§‹ã¾ã£ã¦ã„ã¾ã™ã€‚"
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:102
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:130
#, python-format
msgid "Argument %s is required."
-msgstr ""
+msgstr "引数 %s ãŒå¿…è¦ã§ã™ã€‚"
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117
#, python-format
msgid ""
"Argument %(key)s may not take value %(value)s. Valid values are ['true', "
"'false']."
-msgstr ""
+msgstr "引数 %(key)s ã¯å€¤ %(value)s ãŒè¨±å¯ã•れã¦ã„ã¾ã›ã‚“。有効ãªå€¤ã¯ ['true', 'false'] ã§ã™ã€‚"
#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:163
#, python-format
msgid ""
"Created VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) on %(sr_ref)s."
msgstr ""
+"%(sr_ref)s 上㫠VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) を作æˆã—ã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/vmops.py:67
#, python-format
@@ -1542,7 +1556,7 @@ msgstr "ユニークã§ã¯ãªã„name %s を作æˆã—よã†ã¨ã—ã¾ã—ãŸã€‚"
#: ../nova/virt/xenapi/vmops.py:73
#, python-format
msgid "instance %(name)s: not enough free memory"
-msgstr ""
+msgstr "インスタンス %(name)s: å分ãªç©ºãメモリãŒã‚りã¾ã›ã‚“"
#: ../nova/virt/xenapi/vmops.py:148
#, python-format
@@ -1552,17 +1566,17 @@ msgstr "VM %s ã‚’é–‹å§‹ã—ã¾ã™â€¦"
#: ../nova/virt/xenapi/vmops.py:151
#, python-format
msgid "Spawning VM %(instance_name)s created %(vm_ref)s."
-msgstr ""
+msgstr "%(vm_ref)s ã‹ã‚‰ä½œæˆã•れ㟠VM %(instance_name)s ã®å®Ÿè¡ŒãŒç¹°ã‚Šã‹ãˆã•れã¦ã„ã¾ã™ã€‚"
#: ../nova/virt/xenapi/vmops.py:162
#, python-format
msgid "Invalid value for onset_files: '%s'"
-msgstr ""
+msgstr "onset_files 用ã®ä¸æ­£ãªå€¤: '%s'"
#: ../nova/virt/xenapi/vmops.py:167
#, python-format
msgid "Injecting file path: '%s'"
-msgstr ""
+msgstr "ファイルパス '%s' を埋ã‚込んã§ã„ã¾ã™"
#: ../nova/virt/xenapi/vmops.py:180
#, python-format
@@ -1584,7 +1598,7 @@ msgstr "VM %s ã«å¯¾ã™ã‚‹ã‚¹ãƒŠãƒƒãƒ—ショットを開始ã—ã¾ã™ã€‚"
#: ../nova/virt/xenapi/vmops.py:269
#, python-format
msgid "Unable to Snapshot %(vm_ref)s: %(exc)s"
-msgstr ""
+msgstr "%(vm_ref)s ã®ã‚¹ãƒŠãƒƒãƒ—ショットãŒä½œæˆå‡ºæ¥ã¾ã›ã‚“: %(exc)s"
#: ../nova/virt/xenapi/vmops.py:280
#, python-format
@@ -1594,15 +1608,15 @@ msgstr "VM %s ã®ã‚¹ãƒŠãƒƒãƒ—ショットã¨ã‚¢ãƒƒãƒ—ロードãŒå®Œäº†ã—ã¾ã—
#: ../nova/virt/xenapi/vmops.py:356
#, python-format
msgid "VM %(vm)s already halted, skipping shutdown..."
-msgstr ""
+msgstr "VM %(vm)s ã¯æ—¢ã«åœæ­¢ã—ã¦ã„ã¾ã™ã®ã§ã€ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã‚’çœç•¥ã—ã¾ã™â€¦"
#: ../nova/virt/xenapi/vmops.py:389
msgid "Removing kernel/ramdisk files"
-msgstr ""
+msgstr "カーãƒãƒ«/RAMディスクファイルを削除ã—ã¦ã„ã¾ã™"
#: ../nova/virt/xenapi/vmops.py:399
msgid "kernel/ramdisk files removed"
-msgstr ""
+msgstr "カーãƒãƒ«/RAMディスクファイルãŒå‰Šé™¤ã•れã¾ã—ãŸ"
#: ../nova/virt/xenapi/vmops.py:561
#, python-format
@@ -1610,6 +1624,7 @@ msgid ""
"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; "
"args=%(strargs)s"
msgstr ""
+"タイムアウト: %(method)s ã®å‘¼ã³å‡ºã—ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸã€‚VM id=%(instance_id)s; 引数=%(strargs)s"
#: ../nova/virt/xenapi/vmops.py:564
#, python-format
@@ -1617,6 +1632,7 @@ msgid ""
"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM "
"id=%(instance_id)s; args=%(strargs)s"
msgstr ""
+"未実装: %(method)s ã®å‘¼ã³å‡ºã—ã¯ã‚¨ãƒ¼ã‚¸ã‚§ãƒ³ãƒˆã«å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“。VM id=%(instance_id)s; 引数=%(strargs)s"
#: ../nova/virt/xenapi/vmops.py:569
#, python-format
@@ -1624,11 +1640,12 @@ msgid ""
"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; "
"args=%(strargs)s"
msgstr ""
+"%(method)s 呼ã³å‡ºã—ãŒã‚¨ãƒ©ãƒ¼ã‚’è¿”ã—ã¾ã—ãŸ: %(e)s. VM id=%(instance_id)s; 引数=%(strargs)s"
#: ../nova/virt/xenapi/vmops.py:760
#, python-format
msgid "OpenSSL error: %s"
-msgstr ""
+msgstr "OpenSSL エラー: %s"
#: ../nova/tests/test_compute.py:148
#, python-format
@@ -1659,7 +1676,7 @@ msgstr "%s 用ã®VPNã‚’èµ·å‹•ã—ã¾ã™ã€‚"
#: ../nova/db/sqlalchemy/migration.py:35
msgid "python-migrate is not installed. Exiting."
-msgstr ""
+msgstr "python-migrate ãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“。終了ã—ã¾ã™ã€‚"
#: ../nova/image/s3.py:99
#, python-format
@@ -1676,6 +1693,7 @@ msgid ""
"Access key %(access_key)s has had %(failures)d failed authentications and "
"will be locked out for %(lock_mins)d minutes."
msgstr ""
+"アクセスキー %(access_key)s 㯠%(failures)d 回èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸã®ã§ã€%(lock_mins)d 分間ロックã—ã¾ã™ã€‚"
#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140
#, python-format
@@ -1685,7 +1703,7 @@ msgstr "%s ã®èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
#: ../nova/api/ec2/__init__.py:182
#, python-format
msgid "Authenticated Request For %(uname)s:%(pname)s)"
-msgstr ""
+msgstr "%(uname)s 用ã®èªè¨¼ãƒªã‚¯ã‚¨ã‚¹ãƒˆ:%(pname)s)"
#: ../nova/api/ec2/__init__.py:207
#, python-format
@@ -1695,23 +1713,23 @@ msgstr "アクション(action): %s"
#: ../nova/api/ec2/__init__.py:209
#, python-format
msgid "arg: %(key)s\t\tval: %(value)s"
-msgstr ""
+msgstr "引数: %(key)s\t\t値: %(value)s"
#: ../nova/api/ec2/__init__.py:281
#, python-format
msgid ""
"Unauthorized request for controller=%(controller)s and action=%(action)s"
-msgstr ""
+msgstr "コントローラ=%(controller)s ã¨ã‚¢ã‚¯ã‚·ãƒ§ãƒ³=%(action)s 用ã®è¨±å¯ã•れã¦ã„ãªã„リクエスト"
#: ../nova/api/ec2/__init__.py:314
#, python-format
msgid "InstanceNotFound raised: %s"
-msgstr ""
+msgstr "InstanceNotFound ãŒç™ºè¡Œã•れã¾ã—ãŸ: %s"
#: ../nova/api/ec2/__init__.py:320
#, python-format
msgid "VolumeNotFound raised: %s"
-msgstr ""
+msgstr "VolumeNotFound ãŒç™ºè¡Œã•れã¾ã—ãŸ: %s"
#: ../nova/api/ec2/__init__.py:326
#, python-format
@@ -1778,12 +1796,12 @@ msgstr ""
#: ../nova/virt/xenapi_conn.py:311
#, python-format
msgid "Task [%(name)s] %(task)s status: success %(result)s"
-msgstr ""
+msgstr "タスク [%(name)s] %(task)s 状態: æˆåŠŸ %(result)s"
#: ../nova/virt/xenapi_conn.py:317
#, python-format
msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s"
-msgstr ""
+msgstr "タスク [%(name)s] %(task)s 状態: %(status)s %(error_info)s"
#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344
#, python-format
@@ -1802,12 +1820,12 @@ msgstr "æ›´æ–°ã®æœ€ä¸­ã«äºˆæœŸã—ãªã„エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
#: ../nova/compute/monitor.py:356
#, python-format
msgid "Cannot get blockstats for \"%(disk)s\" on \"%(iid)s\""
-msgstr ""
+msgstr "\"%(iid)s\" 上㮠\"%(disk)s\" 用ã®ãƒ–ロック統計(blockstats)ãŒå–å¾—ã§ãã¾ã›ã‚“"
#: ../nova/compute/monitor.py:379
#, python-format
msgid "Cannot get ifstats for \"%(interface)s\" on \"%(iid)s\""
-msgstr ""
+msgstr "\"%(iid)s\" 上㮠%(interface)s\" 用インターフェース統計(ifstats)ãŒå–å¾—ã§ãã¾ã›ã‚“"
#: ../nova/compute/monitor.py:414
msgid "unexpected exception getting connection"
@@ -1821,13 +1839,13 @@ msgstr "インスタンス %s ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚"
#: ../nova/volume/san.py:67
#, python-format
msgid "Could not find iSCSI export for volume %s"
-msgstr ""
+msgstr "ボリューム %s 用㮠iSCSI エクスãƒãƒ¼ãƒˆãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
#: ../nova/api/ec2/apirequest.py:100
#, python-format
msgid ""
"Unsupported API request: controller = %(controller)s, action = %(action)s"
-msgstr ""
+msgstr "未サãƒãƒ¼ãƒˆã® API リクエスト: コントローラ = %(controller)s, アクション = %(action)s"
#: ../nova/api/openstack/__init__.py:55
#, python-format
@@ -1840,33 +1858,33 @@ msgstr "管ç†ç”¨ã‚ªãƒšãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ï¼ˆadmin operation)ã‚’APIã«ç™»éŒ²ã—ã¾ã
#: ../nova/console/xvp.py:99
msgid "Rebuilding xvp conf"
-msgstr ""
+msgstr "xvp è¨­å®šã‚’å†æ§‹ç¯‰ã—ã¦ã„ã¾ã™"
#: ../nova/console/xvp.py:116
#, python-format
msgid "Re-wrote %s"
-msgstr ""
+msgstr "%s ã‚’å†åº¦æ›¸ãè¾¼ã¿ã¾ã—ãŸ"
#: ../nova/console/xvp.py:121
msgid "Stopping xvp"
-msgstr ""
+msgstr "xvp ã‚’åœæ­¢ã—ã¦ã„ã¾ã™"
#: ../nova/console/xvp.py:134
msgid "Starting xvp"
-msgstr ""
+msgstr "xvp ã‚’é–‹å§‹ã—ã¦ã„ã¾ã™"
#: ../nova/console/xvp.py:141
#, python-format
msgid "Error starting xvp: %s"
-msgstr ""
+msgstr "xvp ã®é–‹å§‹ä¸­ã«ã‚¨ãƒ©ãƒ¼: %s"
#: ../nova/console/xvp.py:144
msgid "Restarting xvp"
-msgstr ""
+msgstr "xvp ã‚’å†èµ·å‹•ã—ã¦ã„ã¾ã™"
#: ../nova/console/xvp.py:146
msgid "xvp not running..."
-msgstr ""
+msgstr "xvp ãŒå®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“…"
#: ../bin/nova-manage.py:272
msgid ""
@@ -1874,6 +1892,8 @@ msgid ""
"Please create a database using nova-manage sync db before running this "
"command."
msgstr ""
+"上記ã®ã‚¨ãƒ©ãƒ¼ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãŒä½œæˆã•れã¦ã„ãªã„為ã«è¡¨ç¤ºã•れãŸã®ã‹ã‚‚知れã¾ã›ã‚“。\n"
+"ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’実行ã™ã‚‹å‰ã«ã€nova-manage db sync を使用ã—ã¦ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’作æˆã—ã¦ä¸‹ã•ã„。"
#: ../bin/nova-manage.py:426
msgid ""
@@ -1883,40 +1903,47 @@ msgid ""
" nova-manage network create 10.0.0.0/8 10 64\n"
"\n"
msgstr ""
+"ã“れ以上利用å¯èƒ½ãªãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ãŒã‚りã¾ã›ã‚“。ã“ã‚ŒãŒæ–°è¦ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã§ã‚れã°ã€\n"
+"下記ã®ã‚ˆã†ãªã‚³ãƒžãƒ³ãƒ‰ã‚’実行ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™:\n"
+"\n"
+" nova-manage network create 10.0.0.0/8 10 64\n"
+"\n"
#: ../bin/nova-manage.py:431
msgid ""
"The above error may show that the certificate db has not been created.\n"
"Please create a database by running a nova-api server on this host."
msgstr ""
+"上記ã®ã‚¨ãƒ©ãƒ¼ã¯èªè¨¼ DB ãŒä½œæˆã•れã¦ã„ãªã„為ã«è¡¨ç¤ºã•れるã®ã‹ã‚‚知れã¾ã›ã‚“。\n"
+"ã“ã®ãƒ›ã‚¹ãƒˆä¸Šã§ nova-api を実行ã—ã¦ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’作æˆã—ã¦ä¸‹ã•ã„。"
#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536
msgid "network"
-msgstr ""
+msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯"
#: ../bin/nova-manage.py:448
msgid "IP address"
-msgstr ""
+msgstr "IPアドレス"
#: ../bin/nova-manage.py:449
msgid "MAC address"
-msgstr ""
+msgstr "MAC アドレス"
#: ../bin/nova-manage.py:450
msgid "hostname"
-msgstr ""
+msgstr "ホストå"
#: ../bin/nova-manage.py:451
msgid "host"
-msgstr ""
+msgstr "ホスト"
#: ../bin/nova-manage.py:537
msgid "netmask"
-msgstr ""
+msgstr "ãƒãƒƒãƒˆãƒžã‚¹ã‚¯"
#: ../bin/nova-manage.py:538
msgid "start address"
-msgstr ""
+msgstr "開始アドレス"
#: ../nova/virt/disk.py:69
#, python-format
@@ -1931,7 +1958,7 @@ msgstr "ファイルシステム %s ã®ãƒžã‚¦ãƒ³ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
#: ../nova/virt/disk.py:124
#, python-format
msgid "nbd device %s did not show up"
-msgstr ""
+msgstr "nbd デãƒã‚¤ã‚¹ %s ãŒå‡ºç¾ã—ã¾ã›ã‚“"
#: ../nova/virt/disk.py:128
#, python-format
@@ -1940,12 +1967,12 @@ msgstr "イメージをループãƒãƒƒã‚¯ %s ã«ã‚¢ã‚¿ãƒƒãƒã§ãã¾ã›ã‚“。"
#: ../nova/virt/disk.py:151
msgid "No free nbd devices"
-msgstr ""
+msgstr "空ãã® nbd デãƒã‚¤ã‚¹ãŒã‚りã¾ã›ã‚“"
#: ../doc/ext/nova_todo.py:46
#, python-format
msgid "%(filename)s, line %(line_info)d"
-msgstr ""
+msgstr "%(filename)s, %(line_info)d 行目"
#. FIXME(chiradeep): implement this
#: ../nova/virt/hyperv.py:118
@@ -1990,7 +2017,7 @@ msgstr "vm %s ã®vcpus を設定ã—ã¾ã™ã€‚"
#: ../nova/virt/hyperv.py:202
#, python-format
msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s"
-msgstr ""
+msgstr "ディスクファイル %(vhdfile)s 接続ã«ã‚ˆã‚Šã€%(vm_name)s 用ディスクを作æˆã—ã¦ã„ã¾ã™"
#: ../nova/virt/hyperv.py:227
#, python-format
@@ -2029,7 +2056,7 @@ msgstr "ãƒãƒ¼ãƒˆ %s ã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
#: ../nova/virt/hyperv.py:276
#, python-format
msgid "Created switch port %(vm_name)s on switch %(ext_path)s"
-msgstr ""
+msgstr "スイッム%(ext_path)s 上ã®ã‚¹ã‚¤ãƒƒãƒãƒãƒ¼ãƒˆ %(vm_name)s ãŒä½œæˆã•れã¾ã—ãŸ"
#: ../nova/virt/hyperv.py:286
#, python-format
@@ -2049,7 +2076,7 @@ msgstr "WMIジョブã«å¤±æ•—ã—ã¾ã—ãŸ: %s"
#: ../nova/virt/hyperv.py:325
#, python-format
msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s "
-msgstr ""
+msgstr "WMI ジョブæˆåŠŸ: %(desc)s, çµŒéŽæ™‚é–“=%(elap)s "
#: ../nova/virt/hyperv.py:361
#, python-format
@@ -2064,7 +2091,7 @@ msgstr "vm %s ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
#: ../nova/virt/hyperv.py:393
#, python-format
msgid "Del: disk %(vhdfile)s vm %(instance_name)s"
-msgstr ""
+msgstr "削除: ディスク %(vhdfile)s VM %(instance_name)s"
#: ../nova/virt/hyperv.py:415
#, python-format
@@ -2072,16 +2099,20 @@ msgid ""
"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, "
"num_cpu=%(numprocs)s, cpu_time=%(uptime)s"
msgstr ""
+"VM %(instance_id)s 用情報å–å¾—: 状態=%(state)s, メモリ=%(memusage)s, CPUæ•°=%(numprocs)s, "
+"CPU時間=%(uptime)s"
#: ../nova/virt/hyperv.py:451
#, python-format
msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s"
-msgstr ""
+msgstr "VM ã®çŠ¶æ…‹ãŒ %(vm_name)s ã‹ã‚‰ %(req_state)s ã«ç„¡äº‹å¤‰æ›´ã•れã¾ã—ãŸ"
#: ../nova/virt/hyperv.py:454
#, python-format
msgid "Failed to change vm state of %(vm_name)s to %(req_state)s"
msgstr ""
+"Failed to change vm state of \r\n"
+"%(vm_name)s ã‹ã‚‰ %(req_state)s ã¸ã®VM ã®çŠ¶æ…‹å¤‰æ›´ã«å¤±æ•—ã—ã¾ã—ãŸ"
#: ../nova/compute/api.py:71
#, python-format
@@ -2096,7 +2127,7 @@ msgstr "インスタンス %d ã«ãƒ›ã‚¹ãƒˆãŒç™»éŒ²ã•れã¦ã„ã¾ã›ã‚“。"
#: ../nova/compute/api.py:97
#, python-format
msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances"
-msgstr ""
+msgstr "%(pid)s 用ã®åˆ¶é™(Quota)è¶…éŽã€%(min_count)s 個ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚’実行ã—よã†ã¨ã—ã¾ã—ãŸ"
#: ../nova/compute/api.py:99
#, python-format
@@ -2117,11 +2148,14 @@ msgstr "%s 個ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã®èµ·å‹•ã‚’å§‹ã‚ã¾ã™â€¦"
#, python-format
msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s"
msgstr ""
+"Casting to scheduler for \r\n"
+"\r\n"
+"%(pid)s/%(uid)s ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ %(instance_id)s 用ã®ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ©ã‚’割り当ã¦"
#: ../nova/compute/api.py:292
#, python-format
msgid "Going to try to terminate %s"
-msgstr ""
+msgstr "%s ã‚’åœæ­¢ã—よã†ã¨ã—ã¦ã„ã¾ã™"
#: ../nova/compute/api.py:296
#, python-format
@@ -2148,6 +2182,8 @@ msgid ""
"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in "
"%(fl_intv)d seconds."
msgstr ""
+"%(fl_host)s 上㮠AMQP サーãƒ:%(fl_port)d ãŒåˆ°é”ä¸èƒ½(unreachable)ã§ã™ã€‚%(fl_intv)d "
+"秒後ã«å†è©¦è¡Œã—ã¾ã™ã€‚"
#: ../nova/rpc.py:103
#, python-format
@@ -2207,7 +2243,7 @@ msgstr "MSG_ID㯠%s ã§ã™ã€‚"
#: ../nova/rpc.py:354
msgid "Making asynchronous cast..."
-msgstr ""
+msgstr "éžåŒæœŸã®å‰²ã‚Šå½“ã¦ã‚’作æˆã—ã¦ã„ã¾ã™â€¦"
#: ../nova/rpc.py:364
#, python-format
@@ -2241,11 +2277,11 @@ msgstr "å½ã®AOE: %s"
#: ../nova/volume/driver.py:233
msgid "Skipping ensure_export. No iscsi_target "
-msgstr ""
+msgstr "ensure_export ã‚’çœç•¥ã—ã¦ã„ã¾ã™ã€‚iscsi_target ãŒã‚りã¾ã›ã‚“。 "
#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288
msgid "Skipping remove_export. No iscsi_target "
-msgstr ""
+msgstr "remove_export ã‚’çœç•¥ã—ã¦ã„ã¾ã™ã€‚iscsi_target ãŒã‚りã¾ã›ã‚“ "
#: ../nova/volume/driver.py:347
#, python-format
@@ -2255,41 +2291,41 @@ msgstr "å½ã®ISCSI: %s"
#: ../nova/volume/driver.py:359
#, python-format
msgid "rbd has no pool %s"
-msgstr ""
+msgstr "rbd ã«ãƒ—ール %s ãŒã‚りã¾ã›ã‚“。"
#: ../nova/volume/driver.py:414
#, python-format
msgid "Sheepdog is not working: %s"
-msgstr ""
+msgstr "Sheepdog ãŒå‹•作ã—ã¦ã„ã¾ã›ã‚“: %s"
#: ../nova/volume/driver.py:416
msgid "Sheepdog is not working"
-msgstr ""
+msgstr "Sheepdog ãŒæ©Ÿèƒ½ã—ã¦ã„ã¾ã›ã‚“"
#: ../nova/wsgi.py:68
#, python-format
msgid "Starting %(arg0)s on %(host)s:%(port)s"
-msgstr ""
+msgstr "%(host)s:%(port)s 上㧠%(arg0)s ã‚’é–‹å§‹ã—ã¦ã„ã¾ã™"
#: ../nova/wsgi.py:147
msgid "You must implement __call__"
-msgstr ""
+msgstr "__call__ を実装ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: ../bin/nova-instancemonitor.py:55
msgid "Starting instance monitor"
-msgstr ""
+msgstr "インスタンスモニタを開始ã—ã¦ã„ã¾ã™"
#: ../bin/nova-dhcpbridge.py:58
msgid "leasing ip"
-msgstr ""
+msgstr "IP アドレスをリースã—ã¾ã—ãŸ"
#: ../bin/nova-dhcpbridge.py:73
msgid "Adopted old lease or got a change of mac/hostname"
-msgstr ""
+msgstr "以å‰ã®ãƒªãƒ¼ã‚¹ã‚’採用ã—ãŸã‹ã€MAC/ホストåã®å¤‰æ›´ã‚’å–å¾—ã—ã¾ã—ãŸ"
#: ../bin/nova-dhcpbridge.py:80
msgid "releasing ip"
-msgstr ""
+msgstr "IP アドレスを開放ã—ã¦ã„ã¾ã™"
#: ../bin/nova-dhcpbridge.py:123
#, python-format
@@ -2297,6 +2333,8 @@ msgid ""
"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s "
"on interface %(interface)s"
msgstr ""
+"インターフェース %(interface)s 上㫠IP アドレス %(ip)sã€ãƒ›ã‚¹ãƒˆå %(hostname)s ã‚’æŒã£ãŸ MAC アドレス "
+"%(mac)s 用㮠%(action)s を呼ã³å‡ºã—ã¾ã—ãŸ"
#: ../nova/virt/fake.py:239
#, python-format
@@ -2325,7 +2363,7 @@ msgstr "IP %s ãŒãƒªãƒ¼ã‚¹ã•れã¾ã—ãŸãŒé–¢é€£ä»˜ã‘られã¦ã„ã¾ã›ã‚“。
#: ../nova/network/manager.py:220
#, python-format
msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s"
-msgstr ""
+msgstr "IP アドレス %(address)s ãŒä¸æ­£ãª MAC アドレス %(inst_addr)s 対 %(mac)s ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã—ãŸ"
#: ../nova/network/manager.py:228
#, python-format
@@ -2335,7 +2373,7 @@ msgstr "æ—¢ã«å‰²å½“解除ã—ã¦ã„ã‚‹IP %s ãŒãƒªãƒ¼ã‚¹ã•れã¾ã—ãŸã€‚"
#: ../nova/network/manager.py:233
#, python-format
msgid "Releasing IP %s"
-msgstr ""
+msgstr "IP アドレス %s を開放ã—ã¦ã„ã¾ã™"
#: ../nova/network/manager.py:237
#, python-format
@@ -2345,7 +2383,7 @@ msgstr "割り当ã¦ã¦ã„ãªã„IP %s ãŒé–‹æ”¾ã•れã¾ã—ãŸã€‚"
#: ../nova/network/manager.py:241
#, python-format
msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s"
-msgstr ""
+msgstr "䏿­£ãª MAC アドレス %(inst_addr)s 対 %(mac)s ã‹ã‚‰ IP アドレス %(address)s ãŒé–‹æ”¾ã•れã¾ã—ãŸ"
#: ../nova/network/manager.py:244
#, python-format
@@ -2356,7 +2394,7 @@ msgstr "リースã—ã¦ã„ãªã„IP %s ãŒé–‹æ”¾ã•れã¾ã—ãŸã€‚"
msgid ""
"The sum between the number of networks and the vlan start cannot be greater "
"than 4094"
-msgstr ""
+msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã®æ•°ã¨VLANã®é–‹å§‹ç•ªå·ã®å’Œã¯ 4094 より大ããã§ãã¾ã›ã‚“。"
#: ../nova/virt/xenapi/volume_utils.py:57
#, python-format
@@ -2366,7 +2404,7 @@ msgstr "%s ã‚’ introduce ã—ã¾ã™â€¦"
#: ../nova/virt/xenapi/volume_utils.py:74
#, python-format
msgid "Introduced %(label)s as %(sr_ref)s."
-msgstr ""
+msgstr "%(sr_ref)s ã¨ã—㦠%(label)s ã‚’å°Žå…¥ã—ã¾ã—ãŸ"
#: ../nova/virt/xenapi/volume_utils.py:78
msgid "Unable to create Storage Repository"
@@ -2385,12 +2423,12 @@ msgstr "SR %s ã‚’forgetã—ã¾ã™ã€‚ "
#: ../nova/virt/xenapi/volume_utils.py:101
#, python-format
msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s"
-msgstr ""
+msgstr "%(sr_ref)s 用ã®ç‰©ç†ãƒ–ロックデãƒã‚¤ã‚¹(PBD)å–得時ã«ä¾‹å¤– %(exc)s を無視ã—ã¦ã„ã¾ã™"
#: ../nova/virt/xenapi/volume_utils.py:107
#, python-format
msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s"
-msgstr ""
+msgstr "物ç†ãƒ–ロックデãƒã‚¤ã‚¹(PBD) %(pbd)s ã®å–ã‚Šå¤–ã—æ™‚ã«ä¾‹å¤– %(exc)s を無視ã—ã¦ã„ã¾ã™"
#: ../nova/virt/xenapi/volume_utils.py:111
#, python-format
@@ -2400,7 +2438,7 @@ msgstr "SR %s ã®forgetãŒå®Œäº†ã€‚"
#: ../nova/virt/xenapi/volume_utils.py:113
#, python-format
msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s"
-msgstr ""
+msgstr "SR %(sr_ref)s ã®ç™»éŒ²å‰Šé™¤æ™‚ã«ä¾‹å¤– %(exc)s を無視ã—ã¦ã„ã¾ã™"
#: ../nova/virt/xenapi/volume_utils.py:123
#, python-format
@@ -2420,7 +2458,7 @@ msgstr "SR %s ã®VDIã‚’introduceã§ãã¾ã›ã‚“。"
#: ../nova/virt/xenapi/volume_utils.py:175
#, python-format
msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s"
-msgstr ""
+msgstr "ターゲット情報 %(device_path)s, %(mountpoint)s ã‚’å–å¾—ã§ãã¾ã›ã‚“"
#: ../nova/virt/xenapi/volume_utils.py:197
#, python-format
@@ -2430,17 +2468,17 @@ msgstr "マウントãƒã‚¤ãƒ³ãƒˆã‚’変æ›ã§ãã¾ã›ã‚“。 %s"
#: ../nova/objectstore/image.py:262
#, python-format
msgid "Failed to decrypt private key: %s"
-msgstr ""
+msgstr "プライベートキーã®å¾©å·ã«å¤±æ•—ã—ã¾ã—ãŸ: %s"
#: ../nova/objectstore/image.py:269
#, python-format
msgid "Failed to decrypt initialization vector: %s"
-msgstr ""
+msgstr "åˆæœŸåŒ–ベクタã®å¾©å·ã«å¤±æ•—ã—ã¾ã—ãŸ: %s"
#: ../nova/objectstore/image.py:277
#, python-format
msgid "Failed to decrypt image file %(image_file)s: %(err)s"
-msgstr ""
+msgstr "イメージファイル %(image_file)s ã®å¾©å·ã«å¤±æ•—ã—ã¾ã—ãŸ: %(err)s"
#: ../nova/objectstore/handler.py:106
#, python-format
@@ -2483,32 +2521,32 @@ msgstr "Unauthorized attempt to delete bucket: ãƒã‚±ãƒƒãƒˆ %s ã«å¯¾ã™ã‚‹å‰Šé™
#: ../nova/objectstore/handler.py:273
#, python-format
msgid "Getting object: %(bname)s / %(nm)s"
-msgstr ""
+msgstr "オブジェクトをå–å¾—ã—ã¦ã„ã¾ã™: %(bname)s / %(nm)s"
#: ../nova/objectstore/handler.py:276
#, python-format
msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s"
-msgstr ""
+msgstr "ãƒã‚±ãƒƒãƒˆ %(bname)s ã‹ã‚‰ã®ã‚ªãƒ–ジェクト %(nm)s å–å¾—ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
#: ../nova/objectstore/handler.py:296
#, python-format
msgid "Putting object: %(bname)s / %(nm)s"
-msgstr ""
+msgstr "オブジェクトをアップロードã—ã¦ã„ã¾ã™: %(bname)s / %(nm)s"
#: ../nova/objectstore/handler.py:299
#, python-format
msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s"
-msgstr ""
+msgstr "ãƒã‚±ãƒƒãƒˆ %(bname)s ã¸ã®ã‚ªãƒ–ジェクト %(nm)s ã®ã‚¢ãƒƒãƒ—ロードã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
#: ../nova/objectstore/handler.py:318
#, python-format
msgid "Deleting object: %(bname)s / %(nm)s"
-msgstr ""
+msgstr "オブジェクトを削除ã—ã¦ã„ã¾ã™: %(bname)s / %(nm)s"
#: ../nova/objectstore/handler.py:322
#, python-format
msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s"
-msgstr ""
+msgstr "ãƒã‚±ãƒƒãƒˆ %(bname)s 上ã®ã‚ªãƒ–ジェクト %(nm)s ã®å‰Šé™¤ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
#: ../nova/objectstore/handler.py:396
#, python-format
@@ -2535,7 +2573,7 @@ msgstr "Not authorized to update attributes: イメージ %s ã®ã‚¢ãƒˆãƒªãƒ“ュã
#: ../nova/objectstore/handler.py:431
#, python-format
msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r"
-msgstr ""
+msgstr "イメージ %(image_id)s %(newstatus)r ã®å…¬é–‹ãƒ•ラグを切り替ãˆã¦ã„ã¾ã™"
#. other attributes imply update
#: ../nova/objectstore/handler.py:436
@@ -2576,7 +2614,7 @@ msgstr "ユーザå (%s) をプロジェクトåã¨ã—ã¦ä½¿ç”¨ã—ã¾ã™ã€‚"
#: ../nova/auth/manager.py:277
#, python-format
msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)"
-msgstr ""
+msgstr "許å¯ã•れã¾ã›ã‚“: %(pjid)s ã¨ã„ã†åç§°ã®ãƒ—ロジェクトã¯ã‚りã¾ã›ã‚“ (ユーザ=%(uname)s)"
#: ../nova/auth/manager.py:279
#, python-format
@@ -2588,12 +2626,12 @@ msgstr "プロジェクト %s ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid ""
"Failed authorization: user %(uname)s not admin and not member of project "
"%(pjname)s"
-msgstr ""
+msgstr "許å¯ã•れã¾ã›ã‚“: ユーザ %(uname)s ã¯ç®¡ç†è€…ã§ã‚‚プロジェクト %(pjname)s ã®ãƒ¡ãƒ³ãƒã§ã‚‚ã‚りã¾ã›ã‚“。"
#: ../nova/auth/manager.py:289
#, python-format
msgid "User %(uid)s is not a member of project %(pjid)s"
-msgstr ""
+msgstr "ユーザ %(uid)s ã¯ãƒ—ロジェクト %(pjid)s ã®ãƒ¡ãƒ³ãƒã§ã¯ã‚りã¾ã›ã‚“。"
#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309
#, python-format
@@ -2621,27 +2659,27 @@ msgstr "ロール %s ã¯ã‚°ãƒ­ãƒ¼ãƒãƒ«ã§ã®ã¿ä½¿ç”¨å¯èƒ½ã§ã™ã€‚"
#: ../nova/auth/manager.py:420
#, python-format
msgid "Adding role %(role)s to user %(uid)s in project %(pid)s"
-msgstr ""
+msgstr "プロジェクト %(pid)s ã®ãƒ¦ãƒ¼ã‚¶ %(uid)s ã«ãƒ­ãƒ¼ãƒ« %(role)s を付与ã—ã¾ã™ã€‚"
#: ../nova/auth/manager.py:423
#, python-format
msgid "Adding sitewide role %(role)s to user %(uid)s"
-msgstr ""
+msgstr "サイト共通ã®ãƒ­ãƒ¼ãƒ« %(role)s をユーザ %(uid)s ã«ä»˜ä¸Žã—ã¾ã™ã€‚"
#: ../nova/auth/manager.py:448
#, python-format
msgid "Removing role %(role)s from user %(uid)s on project %(pid)s"
-msgstr ""
+msgstr "プロジェクト %(pid)s ã®ãƒ¦ãƒ¼ã‚¶ %(uid)s ã‹ã‚‰ãƒ­ãƒ¼ãƒ« %(role)s を削除ã—ã¾ã™ã€‚"
#: ../nova/auth/manager.py:451
#, python-format
msgid "Removing sitewide role %(role)s from user %(uid)s"
-msgstr ""
+msgstr "ユーザ %(uid)s ã‹ã‚‰ã‚µã‚¤ãƒˆå…±é€šã®ãƒ­ãƒ¼ãƒ« %(role)s を削除ã—ã¾ã™ã€‚"
#: ../nova/auth/manager.py:515
#, python-format
msgid "Created project %(name)s with manager %(manager_user)s"
-msgstr ""
+msgstr "プロジェクト %(name)s を管ç†è€… %(manager_user)s ã§ä½œæˆã—ã¾ã—ãŸã€‚"
#: ../nova/auth/manager.py:533
#, python-format
@@ -2651,12 +2689,12 @@ msgstr "modifying project: プロジェクト %s ã‚’æ›´æ–°ã—ã¾ã™ã€‚"
#: ../nova/auth/manager.py:545
#, python-format
msgid "Adding user %(uid)s to project %(pid)s"
-msgstr ""
+msgstr "ユーザ %(uid)s をプロジェクト %(pid)s ã«è¿½åŠ ã—ã¾ã™ã€‚"
#: ../nova/auth/manager.py:566
#, python-format
msgid "Remove user %(uid)s from project %(pid)s"
-msgstr ""
+msgstr "ユーザ %(uid)s をプロジェクト %(pid)s ã‹ã‚‰å‰Šé™¤ã—ã¾ã™ã€‚"
#: ../nova/auth/manager.py:592
#, python-format
@@ -2666,7 +2704,7 @@ msgstr "Deleting project: プロジェクト %s を削除ã—ã¾ã™ã€‚"
#: ../nova/auth/manager.py:650
#, python-format
msgid "Created user %(rvname)s (admin: %(rvadmin)r)"
-msgstr ""
+msgstr "ユーザ %(rvname)s を作æˆã—ã¾ã—ãŸã€‚(管ç†è€…: %(rvadmin)r)"
#: ../nova/auth/manager.py:659
#, python-format
@@ -2686,7 +2724,7 @@ msgstr "Secret Key change: ユーザ %s ã®ã‚·ãƒ¼ã‚¯ãƒ¬ãƒƒãƒˆã‚­ãƒ¼ã‚’æ›´æ–°ã—ã
#: ../nova/auth/manager.py:673
#, python-format
msgid "Admin status set to %(admin)r for user %(uid)s"
-msgstr ""
+msgstr "ユーザ %(uid)s ã«å¯¾ã—ã¦ç®¡ç†è€…状態㌠%(admin)r ã«è¨­å®šã•れã¾ã—ãŸã€‚"
#: ../nova/auth/manager.py:722
#, python-format
@@ -2696,7 +2734,7 @@ msgstr "プロジェクト %s ã«é–¢ã™ã‚‹vpnデータãŒã‚りã¾ã›ã‚“。"
#: ../nova/service.py:161
#, python-format
msgid "Starting %(topic)s node (version %(vcs_string)s)"
-msgstr ""
+msgstr "%(topic)s ノードを開始ã—ã¦ã„ã¾ã™ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %(vcs_string)s)"
#: ../nova/service.py:174
msgid "Service killed that has no database entry"
@@ -2717,7 +2755,7 @@ msgstr "モデルサーãƒãŒæ¶ˆæ»…ã—ã¾ã—ãŸã€‚"
#: ../nova/auth/ldapdriver.py:174
#, python-format
msgid "LDAP user %s already exists"
-msgstr ""
+msgstr "LDAPユーザ %s ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚"
#: ../nova/auth/ldapdriver.py:205
#, python-format
@@ -2727,48 +2765,48 @@ msgstr "LDAPオブジェクト %s ãŒå­˜åœ¨ã—ã¾ã›ã‚“。"
#: ../nova/auth/ldapdriver.py:348
#, python-format
msgid "User %s doesn't exist"
-msgstr ""
+msgstr "ユーザ %s ã¯å­˜åœ¨ã—ã¾ã›ã‚“"
#: ../nova/auth/ldapdriver.py:472
#, python-format
msgid "Group can't be created because group %s already exists"
-msgstr ""
+msgstr "グループ %s ã¯æ—¢ã«å­˜åœ¨ã™ã‚‹ãŸã‚ã€ä½œæˆã§ãã¾ã›ã‚“。"
#: ../nova/auth/ldapdriver.py:478
#, python-format
msgid "Group can't be created because user %s doesn't exist"
-msgstr ""
+msgstr "ユーザ %s ã¯å­˜åœ¨ã—ãªã„ãŸã‚ã€ã‚°ãƒ«ãƒ¼ãƒ—ã®ä½œæˆã¯ã§ãã¾ã›ã‚“。"
#: ../nova/auth/ldapdriver.py:495
#, python-format
msgid "User %s can't be searched in group because the user doesn't exist"
-msgstr ""
+msgstr "ユーザ %s ã¯å­˜åœ¨ã—ãªã„ãŸã‚ã€ã‚°ãƒ«ãƒ¼ãƒ—å†…ã§æ¤œç´¢ã§ãã¾ã›ã‚“。"
#: ../nova/auth/ldapdriver.py:507
#, python-format
msgid "User %s can't be added to the group because the user doesn't exist"
-msgstr ""
+msgstr "ユーザ %s ã¯å­˜åœ¨ã—ãªã„ãŸã‚ã€å½“該グループã«è¿½åŠ ã§ãã¾ã›ã‚“。"
#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521
#, python-format
msgid "The group at dn %s doesn't exist"
-msgstr ""
+msgstr "識別å(DN) %s ã®ã‚°ãƒ«ãƒ¼ãƒ—ã¯å­˜åœ¨ã—ã¾ã›ã‚“。"
#: ../nova/auth/ldapdriver.py:513
#, python-format
msgid "User %(uid)s is already a member of the group %(group_dn)s"
-msgstr ""
+msgstr "ユーザ %(uid)s ã¯ã™ã§ã«ã‚°ãƒ«ãƒ¼ãƒ— %(group_dn)s ã®ãƒ¡ãƒ³ãƒã§ã™ã€‚"
#: ../nova/auth/ldapdriver.py:524
#, python-format
msgid ""
"User %s can't be removed from the group because the user doesn't exist"
-msgstr ""
+msgstr "ユーザ %s ã¯å­˜åœ¨ã—ãªã„ãŸã‚ã€å½“該グループã‹ã‚‰å‰Šé™¤ã§ãã¾ã›ã‚“。"
#: ../nova/auth/ldapdriver.py:528
#, python-format
msgid "User %s is not a member of the group"
-msgstr ""
+msgstr "ユーザ %s ã¯å½“該グループã®ãƒ¡ãƒ³ãƒã§ã¯ã‚りã¾ã›ã‚“。"
#: ../nova/auth/ldapdriver.py:542
#, python-format
@@ -2780,7 +2818,7 @@ msgstr "ã‚°ãƒ«ãƒ¼ãƒ—ã®æœ€å¾Œã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’削除ã—よã†ã¨ã—ã¾ã—ãŸã€‚
#: ../nova/auth/ldapdriver.py:549
#, python-format
msgid "User %s can't be removed from all because the user doesn't exist"
-msgstr ""
+msgstr "ユーザ %s ã¯å­˜åœ¨ã—ãªã„ãŸã‚ã€å…¨ãƒ­ãƒ¼ãƒ«ã‹ã‚‰ã®å‰Šé™¤ã¯ã§ãã¾ã›ã‚“。"
#: ../nova/auth/ldapdriver.py:564
#, python-format
@@ -2810,22 +2848,22 @@ msgstr "Deleting user: ユーザ %s を削除ã—ã¾ã™ã€‚"
#: ../nova/api/ec2/admin.py:127
#, python-format
msgid "Adding role %(role)s to user %(user)s for project %(project)s"
-msgstr ""
+msgstr "プロジェクト %(project)s ã®ãƒ¦ãƒ¼ã‚¶ %(user)s ã«ãƒ­ãƒ¼ãƒ« %(role)s を付与ã—ã¾ã™ã€‚"
#: ../nova/api/ec2/admin.py:131
#, python-format
msgid "Adding sitewide role %(role)s to user %(user)s"
-msgstr ""
+msgstr "ユーザ %(user)s ã«ã‚µã‚¤ãƒˆå…±é€šãªãƒ­ãƒ¼ãƒ« %(role)s を追加中"
#: ../nova/api/ec2/admin.py:137
#, python-format
msgid "Removing role %(role)s from user %(user)s for project %(project)s"
-msgstr ""
+msgstr "プロジェクト %(project)s ã®ãƒ¦ãƒ¼ã‚¶ %(user)s ã‹ã‚‰ãƒ­ãƒ¼ãƒ« %(role)s を削除ã—ã¾ã™ã€‚"
#: ../nova/api/ec2/admin.py:141
#, python-format
msgid "Removing sitewide role %(role)s from user %(user)s"
-msgstr ""
+msgstr "ユーザ %(user)s ã‹ã‚‰ã‚µã‚¤ãƒˆå…±é€šãªãƒ­ãƒ¼ãƒ« %(role)s を削除中"
#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223
msgid "operation must be add or remove"
@@ -2834,17 +2872,17 @@ msgstr "operation 㯠add ã¾ãŸã¯ remove ã®ä½•れã‹ã§ã‚ã‚‹å¿…è¦ãŒã‚りã
#: ../nova/api/ec2/admin.py:159
#, python-format
msgid "Getting x509 for user: %(name)s on project: %(project)s"
-msgstr ""
+msgstr "プロジェクト %(project)s ã®ãƒ¦ãƒ¼ã‚¶ %(name)s ã® x509 証明書をå–å¾—ã—ã¾ã™ã€‚"
#: ../nova/api/ec2/admin.py:177
#, python-format
msgid "Create project %(name)s managed by %(manager_user)s"
-msgstr ""
+msgstr "管ç†è€… %(manager_user)s ã«ã‚ˆã£ã¦ç®¡ç†ã•れるプロジェクト %(name)s を作æˆã—ã¾ã™ã€‚"
#: ../nova/api/ec2/admin.py:190
#, python-format
msgid "Modify project: %(name)s managed by %(manager_user)s"
-msgstr ""
+msgstr "管ç†è€… %(manager_user)s ã«ã‚ˆã£ã¦ç®¡ç†ã•れるプロジェクト %(name)s を変更ã—ã¾ã™ã€‚"
#: ../nova/api/ec2/admin.py:200
#, python-format
@@ -2854,12 +2892,12 @@ msgstr "Delete project: プロジェクト %s を削除ã—ã¾ã—ãŸã€‚"
#: ../nova/api/ec2/admin.py:214
#, python-format
msgid "Adding user %(user)s to project %(project)s"
-msgstr ""
+msgstr "ユーザ %(user)s をプロジェクト %(project)s ã«è¿½åŠ ã—ã¾ã™ã€‚"
#: ../nova/api/ec2/admin.py:218
#, python-format
msgid "Removing user %(user)s from project %(project)s"
-msgstr ""
+msgstr "ユーザ %(user)s をプロジェクト %(project)s ã‹ã‚‰å‰Šé™¤ã—ã¾ã™ã€‚"
#, python-format
#~ msgid ""
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 887c32597..f067a69e0 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-03-25 05:22+0000\n"
-"X-Generator: Launchpad (build 12559)\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
#: ../nova/scheduler/chance.py:37 ../nova/scheduler/zone.py:55
#: ../nova/scheduler/simple.py:75 ../nova/scheduler/simple.py:110
diff --git a/po/ru.po b/po/ru.po
index bbfcfb19f..5d8532f2e 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -8,20 +8,20 @@ msgstr ""
"Project-Id-Version: nova\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-02-21 10:03-0500\n"
-"PO-Revision-Date: 2011-03-30 07:06+0000\n"
-"Last-Translator: Andrey Olykainen <Unknown>\n"
+"PO-Revision-Date: 2011-07-09 07:20+0000\n"
+"Last-Translator: ilya kislicyn <Unknown>\n"
"Language-Team: Russian <ru@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-03-31 05:58+0000\n"
-"X-Generator: Launchpad (build 12559)\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
#: ../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
msgid "No hosts found"
-msgstr ""
+msgstr "Узлы не найдены"
#: ../nova/exception.py:33
msgid "Unexpected error while running command."
@@ -54,7 +54,7 @@ msgstr ""
#: ../nova/volume/api.py:47
#, python-format
msgid "Volume quota exceeded. You cannot create a volume of size %sG"
-msgstr ""
+msgstr "Квота тома превышена. Ð’Ñ‹ не можете Ñоздать том размером %sG"
#: ../nova/volume/api.py:71 ../nova/volume/api.py:96
msgid "Volume status must be available"
@@ -62,19 +62,19 @@ msgstr ""
#: ../nova/volume/api.py:98
msgid "Volume is already attached"
-msgstr ""
+msgstr "Том уже Ñмотирован"
#: ../nova/volume/api.py:104
msgid "Volume is already detached"
-msgstr ""
+msgstr "Том уже отмонтирован"
#: ../nova/api/openstack/servers.py:72
msgid "Failed to read private ip"
-msgstr ""
+msgstr "Ошибка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ð²Ð°Ñ‚Ð½Ð¾Ð³Ð¾ IP адреÑа"
#: ../nova/api/openstack/servers.py:79
msgid "Failed to read public ip(s)"
-msgstr ""
+msgstr "Ошибка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ñ‹Ñ… IP адреÑов"
#: ../nova/api/openstack/servers.py:152
#, python-format
@@ -83,7 +83,7 @@ msgstr ""
#: ../nova/api/openstack/servers.py:168
msgid "No keypairs defined"
-msgstr ""
+msgstr "Ðе определены ключевые пары"
#: ../nova/api/openstack/servers.py:238
#, python-format
diff --git a/po/tl.po b/po/tl.po
new file mode 100644
index 000000000..7f600e8f1
--- /dev/null
+++ b/po/tl.po
@@ -0,0 +1,2855 @@
+# Tagalog translation for nova
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the nova package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: nova\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-02-21 10:03-0500\n"
+"PO-Revision-Date: 2011-02-17 03:24+0000\n"
+"Last-Translator: John Michael Baterna <Unknown>\n"
+"Language-Team: Tagalog <tl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
+
+#: ../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
+msgid "No hosts found"
+msgstr ""
+
+#: ../nova/exception.py:33
+msgid "Unexpected error while running command."
+msgstr "Merong hindi-inaasahang pagkakamali habang tumatakbo ang command."
+
+#: ../nova/exception.py:36
+#, python-format
+msgid ""
+"%(description)s\n"
+"Command: %(cmd)s\n"
+"Exit code: %(exit_code)s\n"
+"Stdout: %(stdout)r\n"
+"Stderr: %(stderr)r"
+msgstr ""
+
+#: ../nova/exception.py:107
+msgid "DB exception wrapped"
+msgstr ""
+
+#. exc_type, exc_value, exc_traceback = sys.exc_info()
+#: ../nova/exception.py:120
+msgid "Uncaught exception"
+msgstr ""
+
+#: ../nova/volume/api.py:45
+#, python-format
+msgid "Quota exceeeded for %(pid)s, tried to create %(size)sG volume"
+msgstr ""
+
+#: ../nova/volume/api.py:47
+#, python-format
+msgid "Volume quota exceeded. You cannot create a volume of size %sG"
+msgstr ""
+
+#: ../nova/volume/api.py:71 ../nova/volume/api.py:96
+msgid "Volume status must be available"
+msgstr ""
+
+#: ../nova/volume/api.py:98
+msgid "Volume is already attached"
+msgstr ""
+
+#: ../nova/volume/api.py:104
+msgid "Volume is already detached"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:72
+msgid "Failed to read private ip"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:79
+msgid "Failed to read public ip(s)"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:152
+#, python-format
+msgid "%(param)s property not found for image %(_image_id)s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:168
+msgid "No keypairs defined"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:238
+#, python-format
+msgid "Compute.api::lock %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:253
+#, python-format
+msgid "Compute.api::unlock %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:267
+#, python-format
+msgid "Compute.api::get_lock %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:281
+#, python-format
+msgid "Compute.api::reset_network %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:292
+#, python-format
+msgid "Compute.api::pause %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:303
+#, python-format
+msgid "Compute.api::unpause %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:314
+#, python-format
+msgid "compute.api::suspend %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:325
+#, python-format
+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
+#, python-format
+msgid "Instance %s not found"
+msgstr ""
+
+#. NOTE: No Resource Pool concept so far
+#: ../nova/virt/xenapi/volumeops.py:51
+#, python-format
+msgid "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:69
+#, python-format
+msgid "Unable to create VDI on SR %(sr_ref)s for instance %(instance_name)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:80
+#, python-format
+msgid "Unable to use SR %(sr_ref)s for instance %(instance_name)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:91
+#, python-format
+msgid "Unable to attach volume to instance %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:93
+#, python-format
+msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s"
+msgstr ""
+
+#. Detach VBD from VM
+#: ../nova/virt/xenapi/volumeops.py:104
+#, python-format
+msgid "Detach_volume: %(instance_name)s, %(mountpoint)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:112
+#, python-format
+msgid "Unable to locate volume %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:120
+#, python-format
+msgid "Unable to detach volume %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:127
+#, python-format
+msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s"
+msgstr ""
+
+#: ../nova/compute/instance_types.py:41
+#, python-format
+msgid "Unknown instance type: %s"
+msgstr ""
+
+#: ../nova/crypto.py:46
+msgid "Filename of root CA"
+msgstr ""
+
+#: ../nova/crypto.py:49
+msgid "Filename of private key"
+msgstr ""
+
+#: ../nova/crypto.py:51
+msgid "Filename of root Certificate Revokation List"
+msgstr ""
+
+#: ../nova/crypto.py:53
+msgid "Where we keep our keys"
+msgstr ""
+
+#: ../nova/crypto.py:55
+msgid "Where we keep our root CA"
+msgstr ""
+
+#: ../nova/crypto.py:57
+msgid "Should we use a CA for each project?"
+msgstr "Kailangan bang gumamit ng CA bawat proyekto?"
+
+#: ../nova/crypto.py:61
+#, python-format
+msgid "Subject for certificate for users, %s for project, user, timestamp"
+msgstr ""
+
+#: ../nova/crypto.py:66
+#, python-format
+msgid "Subject for certificate for projects, %s for project, timestamp"
+msgstr ""
+
+#: ../nova/crypto.py:71
+#, python-format
+msgid "Subject for certificate for vpns, %s for project, timestamp"
+msgstr ""
+
+#: ../nova/crypto.py:258
+#, python-format
+msgid "Flags path: %s"
+msgstr ""
+
+#: ../nova/scheduler/manager.py:69
+#, python-format
+msgid "Casting to %(topic)s %(host)s for %(method)s"
+msgstr ""
+
+#: ../nova/compute/manager.py:78
+#, python-format
+msgid "check_instance_lock: decorating: |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:80
+#, python-format
+msgid ""
+"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:84
+#, python-format
+msgid "check_instance_lock: locked: |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:86
+#, python-format
+msgid "check_instance_lock: admin: |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:91
+#, python-format
+msgid "check_instance_lock: executing: |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:95
+#, python-format
+msgid "check_instance_lock: not executing |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:179
+msgid "Instance has already been created"
+msgstr ""
+
+#: ../nova/compute/manager.py:180
+#, python-format
+msgid "instance %s: starting..."
+msgstr ""
+
+#. pylint: disable=W0702
+#: ../nova/compute/manager.py:219
+#, python-format
+msgid "instance %s: Failed to spawn"
+msgstr ""
+
+#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286
+#, python-format
+msgid "Terminating instance %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:255
+#, python-format
+msgid "Deallocating address %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:268
+#, python-format
+msgid "trying to destroy already destroyed instance: %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:282
+#, python-format
+msgid "Rebooting instance %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:287
+#, python-format
+msgid ""
+"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s "
+"expected: %(running)s)"
+msgstr ""
+
+#: ../nova/compute/manager.py:311
+#, python-format
+msgid "instance %s: snapshotting"
+msgstr ""
+
+#: ../nova/compute/manager.py:316
+#, python-format
+msgid ""
+"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s "
+"expected: %(running)s)"
+msgstr ""
+
+#: ../nova/compute/manager.py:332
+#, python-format
+msgid ""
+"trying to reset the password on a non-running instance: %(instance_id)s "
+"(state: %(instance_state)s expected: %(expected_state)s)"
+msgstr ""
+
+#: ../nova/compute/manager.py:335
+#, python-format
+msgid "instance %s: setting admin password"
+msgstr ""
+
+#: ../nova/compute/manager.py:353
+#, python-format
+msgid ""
+"trying to inject a file into a non-running instance: %(instance_id)s (state: "
+"%(instance_state)s expected: %(expected_state)s)"
+msgstr ""
+
+#: ../nova/compute/manager.py:362
+#, python-format
+msgid "instance %(nm)s: injecting file to %(plain_path)s"
+msgstr ""
+
+#: ../nova/compute/manager.py:372
+#, python-format
+msgid "instance %s: rescuing"
+msgstr ""
+
+#: ../nova/compute/manager.py:387
+#, python-format
+msgid "instance %s: unrescuing"
+msgstr ""
+
+#: ../nova/compute/manager.py:406
+#, python-format
+msgid "instance %s: pausing"
+msgstr ""
+
+#: ../nova/compute/manager.py:423
+#, python-format
+msgid "instance %s: unpausing"
+msgstr ""
+
+#: ../nova/compute/manager.py:440
+#, python-format
+msgid "instance %s: retrieving diagnostics"
+msgstr ""
+
+#: ../nova/compute/manager.py:453
+#, python-format
+msgid "instance %s: suspending"
+msgstr ""
+
+#: ../nova/compute/manager.py:472
+#, python-format
+msgid "instance %s: resuming"
+msgstr ""
+
+#: ../nova/compute/manager.py:491
+#, python-format
+msgid "instance %s: locking"
+msgstr ""
+
+#: ../nova/compute/manager.py:503
+#, python-format
+msgid "instance %s: unlocking"
+msgstr ""
+
+#: ../nova/compute/manager.py:513
+#, python-format
+msgid "instance %s: getting locked state"
+msgstr ""
+
+#: ../nova/compute/manager.py:526
+#, python-format
+msgid "instance %s: reset network"
+msgstr ""
+
+#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515
+#, python-format
+msgid "Get console output for instance %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:543
+#, python-format
+msgid "instance %s: getting ajax console"
+msgstr ""
+
+#: ../nova/compute/manager.py:553
+#, python-format
+msgid ""
+"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s"
+msgstr ""
+
+#. pylint: disable=W0702
+#. NOTE(vish): The inline callback eats the exception info so we
+#. log the traceback here and reraise the same
+#. ecxception below.
+#: ../nova/compute/manager.py:569
+#, python-format
+msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing"
+msgstr ""
+
+#: ../nova/compute/manager.py:585
+#, python-format
+msgid ""
+"Detach volume %(volume_id)s from mountpoint %(mp)s on instance "
+"%(instance_id)s"
+msgstr ""
+
+#: ../nova/compute/manager.py:588
+#, python-format
+msgid "Detaching volume from unknown instance %s"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:53
+#, python-format
+msgid "Host %s is not alive"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:65
+msgid "All hosts have too many cores"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:87
+#, python-format
+msgid "Host %s not available"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:99
+msgid "All hosts have too many gigabytes"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:119
+msgid "All hosts have too many networks"
+msgstr ""
+
+#: ../nova/volume/manager.py:85
+#, python-format
+msgid "Re-exporting %s volumes"
+msgstr ""
+
+#: ../nova/volume/manager.py:90
+#, python-format
+msgid "volume %s: skipping export"
+msgstr ""
+
+#: ../nova/volume/manager.py:96
+#, python-format
+msgid "volume %s: creating"
+msgstr ""
+
+#: ../nova/volume/manager.py:108
+#, python-format
+msgid "volume %(vol_name)s: creating lv of size %(vol_size)sG"
+msgstr ""
+
+#: ../nova/volume/manager.py:112
+#, python-format
+msgid "volume %s: creating export"
+msgstr ""
+
+#: ../nova/volume/manager.py:123
+#, python-format
+msgid "volume %s: created successfully"
+msgstr ""
+
+#: ../nova/volume/manager.py:131
+msgid "Volume is still attached"
+msgstr ""
+
+#: ../nova/volume/manager.py:133
+msgid "Volume is not local to this node"
+msgstr ""
+
+#: ../nova/volume/manager.py:136
+#, python-format
+msgid "volume %s: removing export"
+msgstr ""
+
+#: ../nova/volume/manager.py:138
+#, python-format
+msgid "volume %s: deleting"
+msgstr ""
+
+#: ../nova/volume/manager.py:147
+#, python-format
+msgid "volume %s: deleted successfully"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:74
+#, python-format
+msgid "%(text)s: _db_content => %(content)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:304 ../nova/virt/xenapi/fake.py:404
+#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478
+msgid "Raising NotImplemented"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:306
+#, python-format
+msgid "xenapi.fake does not have an implementation for %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:341
+#, python-format
+msgid "Calling %(localname)s %(impl)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:346
+#, python-format
+msgid "Calling getter %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:406
+#, python-format
+msgid ""
+"xenapi.fake does not have an implementation for %s or it has been called "
+"with the wrong number of arguments"
+msgstr ""
+
+#: ../nova/tests/test_cloud.py:256
+msgid "Can't test instances without a real virtual env."
+msgstr ""
+
+#: ../nova/tests/test_cloud.py:268
+#, python-format
+msgid "Need to watch instance %s until it's running..."
+msgstr ""
+
+#: ../nova/virt/connection.py:73
+msgid "Failed to open connection to the hypervisor"
+msgstr ""
+
+#: ../nova/network/linux_net.py:187
+#, python-format
+msgid "Starting VLAN inteface %s"
+msgstr ""
+
+#: ../nova/network/linux_net.py:208
+#, python-format
+msgid "Starting Bridge interface for %s"
+msgstr ""
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:314
+#, python-format
+msgid "Hupping dnsmasq threw %s"
+msgstr ""
+
+#: ../nova/network/linux_net.py:316
+#, python-format
+msgid "Pid %d is stale, relaunching dnsmasq"
+msgstr ""
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:358
+#, python-format
+msgid "killing radvd threw %s"
+msgstr ""
+
+#: ../nova/network/linux_net.py:360
+#, python-format
+msgid "Pid %d is stale, relaunching radvd"
+msgstr ""
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:449
+#, python-format
+msgid "Killing dnsmasq threw %s"
+msgstr ""
+
+#: ../nova/utils.py:58
+#, python-format
+msgid "Inner Exception: %s"
+msgstr ""
+
+#: ../nova/utils.py:59
+#, python-format
+msgid "Class %s cannot be found"
+msgstr ""
+
+#: ../nova/utils.py:118
+#, python-format
+msgid "Fetching %s"
+msgstr ""
+
+#: ../nova/utils.py:130
+#, python-format
+msgid "Running cmd (subprocess): %s"
+msgstr ""
+
+#: ../nova/utils.py:143 ../nova/utils.py:183
+#, python-format
+msgid "Result was %s"
+msgstr ""
+
+#: ../nova/utils.py:159
+#, python-format
+msgid "Running cmd (SSH): %s"
+msgstr ""
+
+#: ../nova/utils.py:217
+#, python-format
+msgid "debug in callback: %s"
+msgstr ""
+
+#: ../nova/utils.py:222
+#, python-format
+msgid "Running %s"
+msgstr ""
+
+#: ../nova/utils.py:262
+#, python-format
+msgid "Link Local address is not found.:%s"
+msgstr ""
+
+#: ../nova/utils.py:265
+#, python-format
+msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s"
+msgstr ""
+
+#: ../nova/utils.py:363
+#, python-format
+msgid "Invalid backend: %s"
+msgstr ""
+
+#: ../nova/utils.py:374
+#, python-format
+msgid "backend %s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:49
+#, python-format
+msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:54
+#, python-format
+msgid "Publishing to route %s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:84
+#, python-format
+msgid "Declaring queue %s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:90
+#, python-format
+msgid "Declaring exchange %s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:96
+#, python-format
+msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:121
+#, python-format
+msgid "Getting from %(queue)s: %(message)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:135 ../nova/virt/hyperv.py:171
+#, python-format
+msgid "Created VM %s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:138
+#, python-format
+msgid "Created VM %(instance_name)s as %(vm_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:168
+#, python-format
+msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:171
+#, python-format
+msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:187
+#, python-format
+msgid "VBD not found in instance %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:197
+#, python-format
+msgid "Unable to unplug VBD %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:209
+#, python-format
+msgid "Unable to destroy VBD %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:224
+#, python-format
+msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:227
+#, python-format
+msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:246
+#, python-format
+msgid ""
+"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on "
+"%(sr_ref)s."
+msgstr ""
+
+#. TODO(sirp): Add quiesce and VSS locking support when Windows support
+#. is added
+#: ../nova/virt/xenapi/vm_utils.py:258
+#, python-format
+msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:272
+#, python-format
+msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:286
+#, python-format
+msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:327
+#, python-format
+msgid "Size for image %(image)s:%(virtual_size)d"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:332
+#, python-format
+msgid "Glance image %s"
+msgstr ""
+
+#. we need to invoke a plugin for copying VDI's
+#. content into proper path
+#: ../nova/virt/xenapi/vm_utils.py:342
+#, python-format
+msgid "Copying VDI %s to /boot/guest on dom0"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:352
+#, python-format
+msgid "Kernel/Ramdisk VDI %s destroyed"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:361
+#, python-format
+msgid "Asking xapi to fetch %(url)s as %(access)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402
+#, python-format
+msgid "Looking up vdi %s for PV kernel"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:397
+#, python-format
+msgid "PV Kernel in VDI:%s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:405
+#, python-format
+msgid "Running pygrub against %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:411
+#, python-format
+msgid "Found Xen kernel %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:413
+msgid "No Xen kernel found. Booting HVM."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431
+#, python-format
+msgid "duplicate name found: %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:442
+#, python-format
+msgid "VDI %s is still available"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:463
+#, python-format
+msgid "(VM_UTILS) xenserver vm state -> |%s|"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:465
+#, python-format
+msgid "(VM_UTILS) xenapi power_state -> |%s|"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:525
+#, python-format
+msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:542
+#, python-format
+msgid "Re-scanning SR %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:567
+#, python-format
+msgid ""
+"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:574
+#, python-format
+msgid ""
+"Parent %(parent_uuid)s doesn't match original parent "
+"%(original_parent_uuid)s, waiting for coalesce..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:590
+#, python-format
+msgid "No VDIs found for VM %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:594
+#, python-format
+msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:653
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188
+#, python-format
+msgid "Creating VBD for VDI %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:655
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190
+#, python-format
+msgid "Creating VBD for VDI %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:657
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192
+#, python-format
+msgid "Plugging VBD %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:659
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:194
+#, python-format
+msgid "Plugging VBD %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:661
+#, python-format
+msgid "VBD %(vbd)s plugged as %(orig_dev)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:664
+#, python-format
+msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:668
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:197
+#, python-format
+msgid "Destroying VBD for VDI %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:671
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:200
+#, python-format
+msgid "Destroying VBD for VDI %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:683
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211
+msgid "VBD.unplug successful first time."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:688
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216
+msgid "VBD.unplug rejected: retrying..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:692
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220
+msgid "VBD.unplug successful eventually."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:695
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:223
+#, python-format
+msgid "Ignoring XenAPI.Failure in VBD.unplug: %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:704
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:66
+#, python-format
+msgid "Ignoring XenAPI.Failure %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:735
+#, python-format
+msgid ""
+"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:747
+#, python-format
+msgid "Writing partition table %s done."
+msgstr ""
+
+#: ../nova/tests/test_rpc.py:89
+#, python-format
+msgid "Nested received %(queue)s, %(value)s"
+msgstr ""
+
+#: ../nova/tests/test_rpc.py:95
+#, python-format
+msgid "Nested return %s"
+msgstr ""
+
+#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126
+#, python-format
+msgid "Received %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:44
+msgid "Use of empty request context is deprecated"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:133
+#, python-format
+msgid "No service for id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:251
+#, python-format
+msgid "No service for %(host)s, %(binary)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:592
+msgid "No fixed ips defined"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:608
+#, python-format
+msgid "No floating ip for address %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:629
+#, python-format
+msgid "No address for instance %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:961
+#, python-format
+msgid "no keypair for user %(user_id)s, name %(name)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156
+#, python-format
+msgid "No network for id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1086
+msgid "No networks defined"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1115
+#, python-format
+msgid "No network for bridge %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142
+#, python-format
+msgid "No network for instance %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1277
+#, python-format
+msgid "Token %s does not exist"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1302
+#, python-format
+msgid "No quota for project_id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501
+#: ../nova/api/ec2/__init__.py:323
+#, python-format
+msgid "Volume %s not found"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1514
+#, python-format
+msgid "No export device found for volume %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1527
+#, python-format
+msgid "No target id found for volume %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1572
+#, python-format
+msgid "No security group with id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1589
+#, python-format
+msgid "No security group named %(group_name)s for project: %(project_id)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1682
+#, python-format
+msgid "No secuity group rule with id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1756
+#, python-format
+msgid "No user for id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1772
+#, python-format
+msgid "No user for access key %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1834
+#, python-format
+msgid "No project with id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1979
+#, python-format
+msgid "No console pool with id %(pool_id)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1996
+#, python-format
+msgid ""
+"No console pool of type %(console_type)s for compute host %(compute_host)s "
+"on proxy host %(host)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2035
+#, python-format
+msgid "No console for instance %(instance_id)s in pool %(pool_id)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2057
+#, python-format
+msgid "on instance %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2058
+#, python-format
+msgid "No console with id %(console_id)s %(idesc)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097
+#, python-format
+msgid "No zone with id %(zone_id)s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:160
+#, python-format
+msgid "Checking state of %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:165
+#, python-format
+msgid "Current state of %(name)s was %(state)s."
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:183
+#, python-format
+msgid "Connecting to libvirt: %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:196
+msgid "Connection to libvirt broke"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:258
+#, python-format
+msgid "instance %(instance_name)s: deleting instance files %(target)s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:283
+#, python-format
+msgid "Invalid device path %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:313
+#, python-format
+msgid "No disk at %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:320
+msgid "Instance snapshotting is not supported for libvirtat this time"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:336
+#, python-format
+msgid "instance %s: rebooted"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:339
+#, python-format
+msgid "_wait_for_reboot failed: %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:382
+#, python-format
+msgid "instance %s: rescued"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:385
+#, python-format
+msgid "_wait_for_rescue failed: %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:411
+#, python-format
+msgid "instance %s: is running"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:422
+#, python-format
+msgid "instance %s: booted"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186
+#, python-format
+msgid "instance %s: failed to boot"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:436
+#, python-format
+msgid "virsh said: %r"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:440
+msgid "cool, it's a device"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:448
+#, python-format
+msgid "data: %(data)r, fpath: %(fpath)r"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:456
+#, python-format
+msgid "Contents of file %(fpath)s: %(contents)r"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:489
+msgid "Unable to find an open port"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:563
+#, python-format
+msgid "instance %s: Creating image"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:646
+#, python-format
+msgid "instance %(inst_name)s: injecting key into image %(img_id)s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:649
+#, python-format
+msgid "instance %(inst_name)s: injecting net into image %(img_id)s"
+msgstr ""
+
+#. This could be a windows image, or a vmdk format disk
+#: ../nova/virt/libvirt_conn.py:657
+#, python-format
+msgid ""
+"instance %(inst_name)s: ignoring error injecting data into image %(img_id)s "
+"(%(e)s)"
+msgstr ""
+
+#. TODO(termie): cache?
+#: ../nova/virt/libvirt_conn.py:665
+#, python-format
+msgid "instance %s: starting toXML method"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:732
+#, python-format
+msgid "instance %s: finished toXML method"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:751
+msgid "diagnostics are not supported for libvirt"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:1225
+#, python-format
+msgid "Attempted to unfilter instance %s which is not filtered"
+msgstr ""
+
+#: ../nova/api/ec2/metadatarequesthandler.py:76
+#, python-format
+msgid "Failed to get metadata for ip: %s"
+msgstr ""
+
+#: ../nova/auth/fakeldap.py:33
+msgid "Attempted to instantiate singleton"
+msgstr ""
+
+#: ../nova/network/api.py:39
+#, python-format
+msgid "Quota exceeeded for %s, tried to allocate address"
+msgstr ""
+
+#: ../nova/network/api.py:42
+msgid "Address quota exceeded. You cannot allocate any more addresses"
+msgstr ""
+
+#: ../nova/tests/test_volume.py:162
+#, python-format
+msgid "Target %s allocated"
+msgstr ""
+
+#: ../nova/virt/images.py:70
+#, python-format
+msgid "Finished retreving %(url)s -- placed in %(path)s"
+msgstr ""
+
+#: ../nova/scheduler/driver.py:66
+msgid "Must implement a fallback schedule"
+msgstr ""
+
+#: ../nova/console/manager.py:70
+msgid "Adding console"
+msgstr ""
+
+#: ../nova/console/manager.py:90
+#, python-format
+msgid "Tried to remove non-existant console %(console_id)s."
+msgstr ""
+
+#: ../nova/api/direct.py:149
+msgid "not available"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:62
+#, python-format
+msgid "The key_pair %s already exists"
+msgstr ""
+
+#. TODO(vish): Do this with M2Crypto instead
+#: ../nova/api/ec2/cloud.py:118
+#, python-format
+msgid "Generating root CA: %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:303
+#, python-format
+msgid "Create key pair %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:311
+#, python-format
+msgid "Delete key pair %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:386
+#, python-format
+msgid "%s is not a valid ipProtocol"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:390
+msgid "Invalid port range"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:421
+#, python-format
+msgid "Revoke security group ingress %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459
+msgid "Not enough parameters to build a valid rule."
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:443
+msgid "No rule for the specified parameters."
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:450
+#, python-format
+msgid "Authorize security group ingress %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:464
+#, python-format
+msgid "This rule already exists in group %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:492
+#, python-format
+msgid "Create Security Group %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:495
+#, python-format
+msgid "group %s already exists"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:507
+#, python-format
+msgid "Delete security group %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:584
+#, python-format
+msgid "Create volume of %s GB"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:612
+#, python-format
+msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:629
+#, python-format
+msgid "Detach volume %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:761
+msgid "Allocate address"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:766
+#, python-format
+msgid "Release address %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:771
+#, python-format
+msgid "Associate address %(public_ip)s to instance %(instance_id)s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:780
+#, python-format
+msgid "Disassociate address %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:807
+msgid "Going to start terminating instances"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:815
+#, python-format
+msgid "Reboot instance %r"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:867
+#, python-format
+msgid "De-registering image %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:875
+#, python-format
+msgid "Registered image %(image_location)s with id %(image_id)s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900
+#, python-format
+msgid "attribute not supported: %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:890
+#, python-format
+msgid "invalid id: %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:903
+msgid "user or group not specified"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:905
+msgid "only group \"all\" is supported"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:907
+msgid "operation_type must be add or remove"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:908
+#, python-format
+msgid "Updating image %s publicity"
+msgstr ""
+
+#: ../bin/nova-api.py:52
+#, python-format
+msgid "Using paste.deploy config at: %s"
+msgstr ""
+
+#: ../bin/nova-api.py:57
+#, python-format
+msgid "No paste configuration for app: %s"
+msgstr ""
+
+#: ../bin/nova-api.py:59
+#, python-format
+msgid ""
+"App Config: %(api)s\n"
+"%(config)r"
+msgstr ""
+
+#: ../bin/nova-api.py:64
+#, python-format
+msgid "Running %s API"
+msgstr ""
+
+#: ../bin/nova-api.py:69
+#, python-format
+msgid "No known API applications configured in %s."
+msgstr ""
+
+#: ../bin/nova-api.py:83
+#, python-format
+msgid "Starting nova-api node (version %s)"
+msgstr ""
+
+#: ../bin/nova-api.py:89
+#, python-format
+msgid "No paste configuration found for: %s"
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84
+#, python-format
+msgid "Argument %(key)s value %(value)s is too short."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89
+#, python-format
+msgid "Argument %(key)s value %(value)s contains invalid characters."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94
+#, python-format
+msgid "Argument %(key)s value %(value)s starts with a hyphen."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:102
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:130
+#, python-format
+msgid "Argument %s is required."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117
+#, python-format
+msgid ""
+"Argument %(key)s may not take value %(value)s. Valid values are ['true', "
+"'false']."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:163
+#, python-format
+msgid ""
+"Created VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) on %(sr_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:67
+#, python-format
+msgid "Attempted to create non-unique name %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:73
+#, python-format
+msgid "instance %(name)s: not enough free memory"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:148
+#, python-format
+msgid "Starting VM %s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:151
+#, python-format
+msgid "Spawning VM %(instance_name)s created %(vm_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:162
+#, python-format
+msgid "Invalid value for onset_files: '%s'"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:167
+#, python-format
+msgid "Injecting file path: '%s'"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:180
+#, python-format
+msgid "Instance %s: booted"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:232
+#, python-format
+msgid "Instance not present %s"
+msgstr ""
+
+#. TODO(sirp): Add quiesce and VSS locking support when Windows support
+#. is added
+#: ../nova/virt/xenapi/vmops.py:261
+#, python-format
+msgid "Starting snapshot for VM %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:269
+#, python-format
+msgid "Unable to Snapshot %(vm_ref)s: %(exc)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:280
+#, python-format
+msgid "Finished snapshot and upload for VM %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:356
+#, python-format
+msgid "VM %(vm)s already halted, skipping shutdown..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:389
+msgid "Removing kernel/ramdisk files"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:399
+msgid "kernel/ramdisk files removed"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:561
+#, python-format
+msgid ""
+"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; "
+"args=%(strargs)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:564
+#, python-format
+msgid ""
+"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM "
+"id=%(instance_id)s; args=%(strargs)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:569
+#, python-format
+msgid ""
+"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; "
+"args=%(strargs)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:760
+#, python-format
+msgid "OpenSSL error: %s"
+msgstr ""
+
+#: ../nova/tests/test_compute.py:148
+#, python-format
+msgid "Running instances: %s"
+msgstr ""
+
+#: ../nova/tests/test_compute.py:154
+#, python-format
+msgid "After terminating instances: %s"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:45
+msgid "Template for script to run on cloudpipe instance boot"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:48
+msgid "Network to push into openvpn config"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:51
+msgid "Netmask to push into openvpn config"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:97
+#, python-format
+msgid "Launching VPN for %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/migration.py:35
+msgid "python-migrate is not installed. Exiting."
+msgstr ""
+
+#: ../nova/image/s3.py:99
+#, python-format
+msgid "Image %s could not be found"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:121
+msgid "Too many failed authentications."
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:131
+#, python-format
+msgid ""
+"Access key %(access_key)s has had %(failures)d failed authentications and "
+"will be locked out for %(lock_mins)d minutes."
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140
+#, python-format
+msgid "Authentication Failure: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:182
+#, python-format
+msgid "Authenticated Request For %(uname)s:%(pname)s)"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:207
+#, python-format
+msgid "action: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:209
+#, python-format
+msgid "arg: %(key)s\t\tval: %(value)s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:281
+#, python-format
+msgid ""
+"Unauthorized request for controller=%(controller)s and action=%(action)s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:314
+#, python-format
+msgid "InstanceNotFound raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:320
+#, python-format
+msgid "VolumeNotFound raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:326
+#, python-format
+msgid "NotFound raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:329
+#, python-format
+msgid "ApiError raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:338
+#, python-format
+msgid "Unexpected error raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:343
+msgid "An unknown error has occurred. Please try your request again."
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:84
+#, python-format
+msgid "User %s already exists"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232
+#, python-format
+msgid "Project can't be created because manager %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243
+#, python-format
+msgid "Project can't be created because user %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229
+#, python-format
+msgid "Project can't be created because project %s already exists"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268
+#, python-format
+msgid "Project can't be modified because manager %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:245
+#, python-format
+msgid "User \"%s\" not found"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:248
+#, python-format
+msgid "Project \"%s\" not found"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:129
+msgid ""
+"Must specify xenapi_connection_url, xenapi_connection_username (optionally), "
+"and xenapi_connection_password to use connection_type=xenapi"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:311
+#, python-format
+msgid "Task [%(name)s] %(task)s status: success %(result)s"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:317
+#, python-format
+msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344
+#, python-format
+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"
+msgstr ""
+
+#: ../nova/api/ec2/apirequest.py:100
+#, python-format
+msgid ""
+"Unsupported API request: controller = %(controller)s, action = %(action)s"
+msgstr ""
+
+#: ../nova/api/openstack/__init__.py:55
+#, python-format
+msgid "Caught error: %s"
+msgstr ""
+
+#: ../nova/api/openstack/__init__.py:76
+msgid "Including admin operations in API."
+msgstr ""
+
+#: ../nova/console/xvp.py:99
+msgid "Rebuilding xvp conf"
+msgstr ""
+
+#: ../nova/console/xvp.py:116
+#, python-format
+msgid "Re-wrote %s"
+msgstr ""
+
+#: ../nova/console/xvp.py:121
+msgid "Stopping xvp"
+msgstr ""
+
+#: ../nova/console/xvp.py:134
+msgid "Starting xvp"
+msgstr ""
+
+#: ../nova/console/xvp.py:141
+#, python-format
+msgid "Error starting xvp: %s"
+msgstr ""
+
+#: ../nova/console/xvp.py:144
+msgid "Restarting xvp"
+msgstr ""
+
+#: ../nova/console/xvp.py:146
+msgid "xvp not running..."
+msgstr ""
+
+#: ../bin/nova-manage.py:272
+msgid ""
+"The above error may show that the database has not been created.\n"
+"Please create a database using nova-manage sync db before running this "
+"command."
+msgstr ""
+
+#: ../bin/nova-manage.py:426
+msgid ""
+"No more networks available. If this is a new installation, you need\n"
+"to call something like this:\n"
+"\n"
+" nova-manage network create 10.0.0.0/8 10 64\n"
+"\n"
+msgstr ""
+
+#: ../bin/nova-manage.py:431
+msgid ""
+"The above error may show that the certificate db has not been created.\n"
+"Please create a database by running a nova-api server on this host."
+msgstr ""
+
+#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536
+msgid "network"
+msgstr ""
+
+#: ../bin/nova-manage.py:448
+msgid "IP address"
+msgstr ""
+
+#: ../bin/nova-manage.py:449
+msgid "MAC address"
+msgstr ""
+
+#: ../bin/nova-manage.py:450
+msgid "hostname"
+msgstr ""
+
+#: ../bin/nova-manage.py:451
+msgid "host"
+msgstr ""
+
+#: ../bin/nova-manage.py:537
+msgid "netmask"
+msgstr ""
+
+#: ../bin/nova-manage.py:538
+msgid "start address"
+msgstr ""
+
+#: ../nova/virt/disk.py:69
+#, python-format
+msgid "Failed to load partition: %s"
+msgstr ""
+
+#: ../nova/virt/disk.py:91
+#, python-format
+msgid "Failed to mount filesystem: %s"
+msgstr ""
+
+#: ../nova/virt/disk.py:124
+#, python-format
+msgid "nbd device %s did not show up"
+msgstr ""
+
+#: ../nova/virt/disk.py:128
+#, python-format
+msgid "Could not attach image to loopback: %s"
+msgstr ""
+
+#: ../nova/virt/disk.py:151
+msgid "No free nbd devices"
+msgstr ""
+
+#: ../doc/ext/nova_todo.py:46
+#, python-format
+msgid "%(filename)s, line %(line_info)d"
+msgstr ""
+
+#. FIXME(chiradeep): implement this
+#: ../nova/virt/hyperv.py:118
+msgid "In init host"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:131
+#, python-format
+msgid "Attempt to create duplicate vm %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:148
+#, python-format
+msgid "Starting VM %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:150
+#, python-format
+msgid "Started VM %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:152
+#, python-format
+msgid "spawn vm failed: %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:169
+#, python-format
+msgid "Failed to create VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:188
+#, python-format
+msgid "Set memory for vm %s..."
+msgstr ""
+
+#: ../nova/virt/hyperv.py:198
+#, python-format
+msgid "Set vcpus for vm %s..."
+msgstr ""
+
+#: ../nova/virt/hyperv.py:202
+#, python-format
+msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:227
+#, python-format
+msgid "Failed to add diskdrive to VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:230
+#, python-format
+msgid "New disk drive path is %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:247
+#, python-format
+msgid "Failed to add vhd file to VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:249
+#, python-format
+msgid "Created disk for %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:253
+#, python-format
+msgid "Creating nic for %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:272
+msgid "Failed creating a port on the external vswitch"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:273
+#, python-format
+msgid "Failed creating port for %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:276
+#, python-format
+msgid "Created switch port %(vm_name)s on switch %(ext_path)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:286
+#, python-format
+msgid "Failed to add nic to VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:288
+#, python-format
+msgid "Created nic for %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:321
+#, python-format
+msgid "WMI job failed: %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:325
+#, python-format
+msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:361
+#, python-format
+msgid "Got request to destroy vm %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:386
+#, python-format
+msgid "Failed to destroy vm %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:393
+#, python-format
+msgid "Del: disk %(vhdfile)s vm %(instance_name)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:415
+#, python-format
+msgid ""
+"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, "
+"num_cpu=%(numprocs)s, cpu_time=%(uptime)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:451
+#, python-format
+msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:454
+#, python-format
+msgid "Failed to change vm state of %(vm_name)s to %(req_state)s"
+msgstr ""
+
+#: ../nova/compute/api.py:71
+#, python-format
+msgid "Instance %d was not found in get_network_topic"
+msgstr ""
+
+#: ../nova/compute/api.py:77
+#, python-format
+msgid "Instance %d has no host"
+msgstr ""
+
+#: ../nova/compute/api.py:97
+#, python-format
+msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances"
+msgstr ""
+
+#: ../nova/compute/api.py:99
+#, python-format
+msgid ""
+"Instance quota exceeded. You can only run %s more instances of this type."
+msgstr ""
+
+#: ../nova/compute/api.py:112
+msgid "Creating a raw instance"
+msgstr ""
+
+#: ../nova/compute/api.py:160
+#, python-format
+msgid "Going to run %s instances..."
+msgstr ""
+
+#: ../nova/compute/api.py:187
+#, python-format
+msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s"
+msgstr ""
+
+#: ../nova/compute/api.py:292
+#, python-format
+msgid "Going to try to terminate %s"
+msgstr ""
+
+#: ../nova/compute/api.py:296
+#, python-format
+msgid "Instance %d was not found during terminate"
+msgstr ""
+
+#: ../nova/compute/api.py:301
+#, python-format
+msgid "Instance %d is already being terminated"
+msgstr ""
+
+#: ../nova/compute/api.py:481
+#, python-format
+msgid "Invalid device specified: %s. Example device: /dev/vdb"
+msgstr ""
+
+#: ../nova/compute/api.py:496
+msgid "Volume isn't attached to anything!"
+msgstr ""
+
+#: ../nova/rpc.py:98
+#, python-format
+msgid ""
+"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in "
+"%(fl_intv)d seconds."
+msgstr ""
+
+#: ../nova/rpc.py:103
+#, python-format
+msgid "Unable to connect to AMQP server after %d tries. Shutting down."
+msgstr ""
+"Hindi maka-konekta sa AMQP server pagkatapos ng %d ulit. Isasara na ang "
+"sistema."
+
+#: ../nova/rpc.py:122
+msgid "Reconnected to queue"
+msgstr "Muling kumonekta sa queue"
+
+#: ../nova/rpc.py:129
+msgid "Failed to fetch message from queue"
+msgstr "Hindi nai-abot ang mensahe buhat sa queue"
+
+#: ../nova/rpc.py:159
+#, python-format
+msgid "Initing the Adapter Consumer for %s"
+msgstr ""
+
+#: ../nova/rpc.py:178
+#, python-format
+msgid "received %s"
+msgstr "natanggap %s"
+
+#. NOTE(vish): we may not want to ack here, but that means that bad
+#. messages stay in the queue indefinitely, so for now
+#. we just log the message and send an error string
+#. back to the caller
+#: ../nova/rpc.py:191
+#, python-format
+msgid "no method for message: %s"
+msgstr "walang paraan para sa mensahe: %s"
+
+#: ../nova/rpc.py:192
+#, python-format
+msgid "No method for message: %s"
+msgstr "Walang paraan para sa mensahe: %s"
+
+#: ../nova/rpc.py:253
+#, python-format
+msgid "Returning exception %s to caller"
+msgstr ""
+
+#: ../nova/rpc.py:294
+#, python-format
+msgid "unpacked context: %s"
+msgstr ""
+
+#: ../nova/rpc.py:313
+msgid "Making asynchronous call..."
+msgstr ""
+
+#: ../nova/rpc.py:316
+#, python-format
+msgid "MSG_ID is %s"
+msgstr ""
+
+#: ../nova/rpc.py:354
+msgid "Making asynchronous cast..."
+msgstr ""
+
+#: ../nova/rpc.py:364
+#, python-format
+msgid "response %s"
+msgstr ""
+
+#: ../nova/rpc.py:373
+#, python-format
+msgid "topic is %s"
+msgstr ""
+
+#: ../nova/rpc.py:374
+#, python-format
+msgid "message %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:78
+#, python-format
+msgid "Recovering from a failed execute. Try number %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:87
+#, python-format
+msgid "volume group %s doesn't exist"
+msgstr ""
+
+#: ../nova/volume/driver.py:220
+#, python-format
+msgid "FAKE AOE: %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:233
+msgid "Skipping ensure_export. No iscsi_target "
+msgstr ""
+
+#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288
+msgid "Skipping remove_export. No iscsi_target "
+msgstr ""
+
+#: ../nova/volume/driver.py:347
+#, python-format
+msgid "FAKE ISCSI: %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:359
+#, python-format
+msgid "rbd has no pool %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:414
+#, python-format
+msgid "Sheepdog is not working: %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:416
+msgid "Sheepdog is not working"
+msgstr ""
+
+#: ../nova/wsgi.py:68
+#, python-format
+msgid "Starting %(arg0)s on %(host)s:%(port)s"
+msgstr ""
+
+#: ../nova/wsgi.py:147
+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 ""
+
+#: ../bin/nova-dhcpbridge.py:73
+msgid "Adopted old lease or got a change of mac/hostname"
+msgstr ""
+
+#: ../bin/nova-dhcpbridge.py:80
+msgid "releasing ip"
+msgstr ""
+
+#: ../bin/nova-dhcpbridge.py:123
+#, python-format
+msgid ""
+"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s "
+"on interface %(interface)s"
+msgstr ""
+
+#: ../nova/virt/fake.py:239
+#, python-format
+msgid "Instance %s Not Found"
+msgstr ""
+
+#: ../nova/network/manager.py:153
+#, python-format
+msgid "Dissassociated %s stale fixed ip(s)"
+msgstr ""
+
+#: ../nova/network/manager.py:157
+msgid "setting network host"
+msgstr ""
+
+#: ../nova/network/manager.py:212
+#, python-format
+msgid "Leasing IP %s"
+msgstr ""
+
+#: ../nova/network/manager.py:216
+#, python-format
+msgid "IP %s leased that isn't associated"
+msgstr ""
+
+#: ../nova/network/manager.py:220
+#, python-format
+msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s"
+msgstr ""
+
+#: ../nova/network/manager.py:228
+#, python-format
+msgid "IP %s leased that was already deallocated"
+msgstr ""
+
+#: ../nova/network/manager.py:233
+#, python-format
+msgid "Releasing IP %s"
+msgstr ""
+
+#: ../nova/network/manager.py:237
+#, python-format
+msgid "IP %s released that isn't associated"
+msgstr ""
+
+#: ../nova/network/manager.py:241
+#, python-format
+msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s"
+msgstr ""
+
+#: ../nova/network/manager.py:244
+#, python-format
+msgid "IP %s released that was not leased"
+msgstr ""
+
+#: ../nova/network/manager.py:519
+msgid ""
+"The sum between the number of networks and the vlan start cannot be greater "
+"than 4094"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:57
+#, python-format
+msgid "Introducing %s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:74
+#, python-format
+msgid "Introduced %(label)s as %(sr_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:78
+msgid "Unable to create Storage Repository"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:90
+#, python-format
+msgid "Unable to find SR from VBD %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:96
+#, python-format
+msgid "Forgetting SR %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:101
+#, python-format
+msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:107
+#, python-format
+msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:111
+#, python-format
+msgid "Forgetting SR %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:113
+#, python-format
+msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:123
+#, python-format
+msgid "Unable to introduce VDI on SR %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:128
+#, python-format
+msgid "Unable to get record of VDI %s on"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:146
+#, python-format
+msgid "Unable to introduce VDI for SR %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:175
+#, python-format
+msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:197
+#, python-format
+msgid "Mountpoint cannot be translated: %s"
+msgstr ""
+
+#: ../nova/objectstore/image.py:262
+#, python-format
+msgid "Failed to decrypt private key: %s"
+msgstr ""
+
+#: ../nova/objectstore/image.py:269
+#, python-format
+msgid "Failed to decrypt initialization vector: %s"
+msgstr ""
+
+#: ../nova/objectstore/image.py:277
+#, python-format
+msgid "Failed to decrypt image file %(image_file)s: %(err)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:106
+#, python-format
+msgid "Unknown S3 value type %r"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:137
+msgid "Authenticated request"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:182
+msgid "List of buckets requested"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:209
+#, python-format
+msgid "List keys for bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:217
+#, python-format
+msgid "Unauthorized attempt to access bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:235
+#, python-format
+msgid "Creating bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:245
+#, python-format
+msgid "Deleting bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:249
+#, python-format
+msgid "Unauthorized attempt to delete bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:273
+#, python-format
+msgid "Getting object: %(bname)s / %(nm)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:276
+#, python-format
+msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:296
+#, python-format
+msgid "Putting object: %(bname)s / %(nm)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:299
+#, python-format
+msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:318
+#, python-format
+msgid "Deleting object: %(bname)s / %(nm)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:322
+#, python-format
+msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:396
+#, python-format
+msgid "Not authorized to upload image: invalid directory %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:404
+#, python-format
+msgid "Not authorized to upload image: unauthorized bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:409
+#, python-format
+msgid "Starting image upload: %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:423
+#, python-format
+msgid "Not authorized to update attributes of image %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:431
+#, python-format
+msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r"
+msgstr ""
+
+#. other attributes imply update
+#: ../nova/objectstore/handler.py:436
+#, python-format
+msgid "Updating user fields on image %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:450
+#, python-format
+msgid "Unauthorized attempt to delete image %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:455
+#, python-format
+msgid "Deleted image: %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:259
+#, python-format
+msgid "Looking up user: %r"
+msgstr ""
+
+#: ../nova/auth/manager.py:263
+#, python-format
+msgid "Failed authorization for access key %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:264
+#, python-format
+msgid "No user found for access key %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:270
+#, python-format
+msgid "Using project name = user name (%s)"
+msgstr ""
+
+#: ../nova/auth/manager.py:277
+#, python-format
+msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)"
+msgstr ""
+
+#: ../nova/auth/manager.py:279
+#, python-format
+msgid "No project called %s could be found"
+msgstr ""
+
+#: ../nova/auth/manager.py:287
+#, python-format
+msgid ""
+"Failed authorization: user %(uname)s not admin and not member of project "
+"%(pjname)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:289
+#, python-format
+msgid "User %(uid)s is not a member of project %(pjid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309
+#, python-format
+msgid "Invalid signature for user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310
+msgid "Signature does not match"
+msgstr ""
+
+#: ../nova/auth/manager.py:380
+msgid "Must specify project"
+msgstr ""
+
+#: ../nova/auth/manager.py:414
+#, python-format
+msgid "The %s role can not be found"
+msgstr ""
+
+#: ../nova/auth/manager.py:416
+#, python-format
+msgid "The %s role is global only"
+msgstr ""
+
+#: ../nova/auth/manager.py:420
+#, python-format
+msgid "Adding role %(role)s to user %(uid)s in project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:423
+#, python-format
+msgid "Adding sitewide role %(role)s to user %(uid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:448
+#, python-format
+msgid "Removing role %(role)s from user %(uid)s on project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:451
+#, python-format
+msgid "Removing sitewide role %(role)s from user %(uid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:515
+#, python-format
+msgid "Created project %(name)s with manager %(manager_user)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:533
+#, python-format
+msgid "modifying project %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:545
+#, python-format
+msgid "Adding user %(uid)s to project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:566
+#, python-format
+msgid "Remove user %(uid)s from project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:592
+#, python-format
+msgid "Deleting project %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:650
+#, python-format
+msgid "Created user %(rvname)s (admin: %(rvadmin)r)"
+msgstr ""
+
+#: ../nova/auth/manager.py:659
+#, python-format
+msgid "Deleting user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:669
+#, python-format
+msgid "Access Key change for user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:671
+#, python-format
+msgid "Secret Key change for user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:673
+#, python-format
+msgid "Admin status set to %(admin)r for user %(uid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:722
+#, python-format
+msgid "No vpn data for project %s"
+msgstr ""
+
+#: ../nova/service.py:161
+#, python-format
+msgid "Starting %(topic)s node (version %(vcs_string)s)"
+msgstr ""
+
+#: ../nova/service.py:174
+msgid "Service killed that has no database entry"
+msgstr ""
+
+#: ../nova/service.py:195
+msgid "The service database object disappeared, Recreating it."
+msgstr ""
+
+#: ../nova/service.py:207
+msgid "Recovered model server connection!"
+msgstr ""
+
+#: ../nova/service.py:213
+msgid "model server went away"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:174
+#, python-format
+msgid "LDAP user %s already exists"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:205
+#, python-format
+msgid "LDAP object for %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:348
+#, python-format
+msgid "User %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:472
+#, python-format
+msgid "Group can't be created because group %s already exists"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:478
+#, python-format
+msgid "Group can't be created because user %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:495
+#, python-format
+msgid "User %s can't be searched in group because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:507
+#, python-format
+msgid "User %s can't be added to the group because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521
+#, python-format
+msgid "The group at dn %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:513
+#, python-format
+msgid "User %(uid)s is already a member of the group %(group_dn)s"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:524
+#, python-format
+msgid ""
+"User %s can't be removed from the group because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:528
+#, python-format
+msgid "User %s is not a member of the group"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:542
+#, python-format
+msgid ""
+"Attempted to remove the last member of a group. Deleting the group at %s "
+"instead."
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:549
+#, python-format
+msgid "User %s can't be removed from all because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:564
+#, python-format
+msgid "Group at dn %s doesn't exist"
+msgstr ""
+
+#: ../nova/virt/xenapi/network_utils.py:40
+#, python-format
+msgid "Found non-unique network for bridge %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/network_utils.py:43
+#, python-format
+msgid "Found no network for bridge %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:97
+#, python-format
+msgid "Creating new user: %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:105
+#, python-format
+msgid "Deleting user: %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:127
+#, python-format
+msgid "Adding role %(role)s to user %(user)s for project %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:131
+#, python-format
+msgid "Adding sitewide role %(role)s to user %(user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:137
+#, python-format
+msgid "Removing role %(role)s from user %(user)s for project %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:141
+#, python-format
+msgid "Removing sitewide role %(role)s from user %(user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223
+msgid "operation must be add or remove"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:159
+#, python-format
+msgid "Getting x509 for user: %(name)s on project: %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:177
+#, python-format
+msgid "Create project %(name)s managed by %(manager_user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:190
+#, python-format
+msgid "Modify project: %(name)s managed by %(manager_user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:200
+#, python-format
+msgid "Delete project: %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:214
+#, python-format
+msgid "Adding user %(user)s to project %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:218
+#, python-format
+msgid "Removing user %(user)s from project %(project)s"
+msgstr ""
+
+#, python-format
+#~ msgid "AMQP server on %s:%d is unreachable. Trying again in %d seconds."
+#~ msgstr ""
+#~ "Hindi makita o maabot ang AMQP server sa %s:%d. Muling subukan sa %d segundo."
diff --git a/po/uk.po b/po/uk.po
index d28860c9b..bbd831de9 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-03-19 06:19+0000\n"
-"X-Generator: Launchpad (build 12559)\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
#: ../nova/scheduler/chance.py:37 ../nova/scheduler/zone.py:55
#: ../nova/scheduler/simple.py:75 ../nova/scheduler/simple.py:110
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 9690356f5..c3d292a93 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: nova\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-02-21 10:03-0500\n"
-"PO-Revision-Date: 2011-04-07 05:01+0000\n"
-"Last-Translator: ben <Unknown>\n"
+"PO-Revision-Date: 2011-06-14 14:44+0000\n"
+"Last-Translator: chong <Unknown>\n"
"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-04-08 05:28+0000\n"
-"X-Generator: Launchpad (build 12735)\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
#: ../nova/twistd.py:266
#, python-format
@@ -26,7 +26,7 @@ msgstr "å¯åЍ %s 中"
#: ../nova/scheduler/simple.py:75 ../nova/scheduler/simple.py:110
#: ../nova/scheduler/simple.py:122
msgid "No hosts found"
-msgstr "未找到主机"
+msgstr "没有找到主机"
#: ../nova/exception.py:33
msgid "Unexpected error while running command."
@@ -41,6 +41,11 @@ msgid ""
"Stdout: %(stdout)r\n"
"Stderr: %(stderr)r"
msgstr ""
+"%(description)s\n"
+"命令: %(cmd)s\n"
+"退出代ç : %(exit_code)s\n"
+"标准输出: %(stdout)r\n"
+"标准出错: %(stderr)r"
#: ../nova/exception.py:107
msgid "DB exception wrapped"
@@ -309,17 +314,17 @@ msgstr ""
#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286
#, python-format
msgid "Terminating instance %s"
-msgstr ""
+msgstr "正在结æŸå®žä¾‹ %s"
#: ../nova/compute/manager.py:255
#, python-format
msgid "Deallocating address %s"
-msgstr ""
+msgstr "å–æ¶ˆåˆ†é…åœ°å€ %s"
#: ../nova/compute/manager.py:268
#, python-format
msgid "trying to destroy already destroyed instance: %s"
-msgstr ""
+msgstr "å°è¯•销æ¯å·²ç»é”€æ¯çš„实例: %s"
#: ../nova/compute/manager.py:282
#, python-format
@@ -331,12 +336,12 @@ msgstr "é‡å¯è™šæ‹Ÿæœº %s"
msgid ""
"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s "
"expected: %(running)s)"
-msgstr ""
+msgstr "å°è¯•é‡å¯æ²¡æœ‰åœ¨è¿è¡Œä¸­å®žä¾‹: %(instance_id)s (状æ€: %(state)s 预料: %(running)s)"
#: ../nova/compute/manager.py:311
#, python-format
msgid "instance %s: snapshotting"
-msgstr ""
+msgstr "实例 %s: 快照中"
#: ../nova/compute/manager.py:316
#, python-format
@@ -351,6 +356,8 @@ msgid ""
"trying to reset the password on a non-running instance: %(instance_id)s "
"(state: %(instance_state)s expected: %(expected_state)s)"
msgstr ""
+"å°è¯•对没有在è¿è¡Œçš„实例é‡ç½®å¯†ç : %(instance_id)s (状æ€: %(instance_state)s 预料: "
+"%(expected_state)s)"
#: ../nova/compute/manager.py:335
#, python-format
diff --git a/po/zh_TW.po b/po/zh_TW.po
new file mode 100644
index 000000000..ad14c0e32
--- /dev/null
+++ b/po/zh_TW.po
@@ -0,0 +1,2848 @@
+# Chinese (Traditional) translation for nova
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the nova package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: nova\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-02-21 10:03-0500\n"
+"PO-Revision-Date: 2011-03-25 07:14+0000\n"
+"Last-Translator: Hugo Kou <Unknown>\n"
+"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-07-23 05:12+0000\n"
+"X-Generator: Launchpad (build 13405)\n"
+
+#: ../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
+msgid "No hosts found"
+msgstr "找ä¸åˆ°ä¸»æ©Ÿ"
+
+#: ../nova/exception.py:33
+msgid "Unexpected error while running command."
+msgstr "éžé æœŸçš„執行錯誤"
+
+#: ../nova/exception.py:36
+#, python-format
+msgid ""
+"%(description)s\n"
+"Command: %(cmd)s\n"
+"Exit code: %(exit_code)s\n"
+"Stdout: %(stdout)r\n"
+"Stderr: %(stderr)r"
+msgstr ""
+
+#: ../nova/exception.py:107
+msgid "DB exception wrapped"
+msgstr ""
+
+#. exc_type, exc_value, exc_traceback = sys.exc_info()
+#: ../nova/exception.py:120
+msgid "Uncaught exception"
+msgstr ""
+
+#: ../nova/volume/api.py:45
+#, python-format
+msgid "Quota exceeeded for %(pid)s, tried to create %(size)sG volume"
+msgstr ""
+
+#: ../nova/volume/api.py:47
+#, python-format
+msgid "Volume quota exceeded. You cannot create a volume of size %sG"
+msgstr "Volume è¶…éŽé™åˆ¶ã€‚無法創建 volume å¤§å° %sG"
+
+#: ../nova/volume/api.py:71 ../nova/volume/api.py:96
+msgid "Volume status must be available"
+msgstr "Volume 狀態需è¦å¯è¢«ä½¿ç”¨"
+
+#: ../nova/volume/api.py:98
+msgid "Volume is already attached"
+msgstr "Volume 已掛載"
+
+#: ../nova/volume/api.py:104
+msgid "Volume is already detached"
+msgstr "Volume 已經å¸è¼‰"
+
+#: ../nova/api/openstack/servers.py:72
+msgid "Failed to read private ip"
+msgstr "讀å–private ip 失敗"
+
+#: ../nova/api/openstack/servers.py:79
+msgid "Failed to read public ip(s)"
+msgstr "讀å–public ip 失敗"
+
+#: ../nova/api/openstack/servers.py:152
+#, python-format
+msgid "%(param)s property not found for image %(_image_id)s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:168
+msgid "No keypairs defined"
+msgstr "沒有定義的金鑰(keypair)é…å°"
+
+#: ../nova/api/openstack/servers.py:238
+#, python-format
+msgid "Compute.api::lock %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:253
+#, python-format
+msgid "Compute.api::unlock %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:267
+#, python-format
+msgid "Compute.api::get_lock %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:281
+#, python-format
+msgid "Compute.api::reset_network %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:292
+#, python-format
+msgid "Compute.api::pause %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:303
+#, python-format
+msgid "Compute.api::unpause %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:314
+#, python-format
+msgid "compute.api::suspend %s"
+msgstr ""
+
+#: ../nova/api/openstack/servers.py:325
+#, python-format
+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
+#, python-format
+msgid "Instance %s not found"
+msgstr "找ä¸åˆ°è™›æ“¬æ©Ÿå™¨ %s"
+
+#. NOTE: No Resource Pool concept so far
+#: ../nova/virt/xenapi/volumeops.py:51
+#, python-format
+msgid "Attach_volume: %(instance_name)s, %(device_path)s, %(mountpoint)s"
+msgstr "掛載_Volume: %(instance_name)s, %(device_path)s, %(mountpoint)s"
+
+#: ../nova/virt/xenapi/volumeops.py:69
+#, python-format
+msgid "Unable to create VDI on SR %(sr_ref)s for instance %(instance_name)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:80
+#, python-format
+msgid "Unable to use SR %(sr_ref)s for instance %(instance_name)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volumeops.py:91
+#, python-format
+msgid "Unable to attach volume to instance %s"
+msgstr "無法掛載Volume 到虛擬機器 %s"
+
+#: ../nova/virt/xenapi/volumeops.py:93
+#, python-format
+msgid "Mountpoint %(mountpoint)s attached to instance %(instance_name)s"
+msgstr "掛載點 %(mountpoint)s 掛載到虛擬機器 %(instance_name)s"
+
+#. Detach VBD from VM
+#: ../nova/virt/xenapi/volumeops.py:104
+#, python-format
+msgid "Detach_volume: %(instance_name)s, %(mountpoint)s"
+msgstr "å¸è¼‰_Volume: %(instance_name)s, %(mountpoint)s"
+
+#: ../nova/virt/xenapi/volumeops.py:112
+#, python-format
+msgid "Unable to locate volume %s"
+msgstr "找ä¸åˆ°Volume %s"
+
+#: ../nova/virt/xenapi/volumeops.py:120
+#, python-format
+msgid "Unable to detach volume %s"
+msgstr "無法å¸è¼‰ Volume %s"
+
+#: ../nova/virt/xenapi/volumeops.py:127
+#, python-format
+msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s"
+msgstr "掛載點 %(mountpoint)s 從虛擬機器 %(instance_name)s å¸è¼‰"
+
+#: ../nova/compute/instance_types.py:41
+#, python-format
+msgid "Unknown instance type: %s"
+msgstr "æœªçŸ¥çš„è™›æ“¬æ©Ÿå™¨è¦æ ¼: %s"
+
+#: ../nova/crypto.py:46
+msgid "Filename of root CA"
+msgstr ""
+
+#: ../nova/crypto.py:49
+msgid "Filename of private key"
+msgstr "Private key ç§é‘°æª”案å稱"
+
+#: ../nova/crypto.py:51
+msgid "Filename of root Certificate Revokation List"
+msgstr ""
+
+#: ../nova/crypto.py:53
+msgid "Where we keep our keys"
+msgstr ""
+
+#: ../nova/crypto.py:55
+msgid "Where we keep our root CA"
+msgstr ""
+
+#: ../nova/crypto.py:57
+msgid "Should we use a CA for each project?"
+msgstr ""
+
+#: ../nova/crypto.py:61
+#, python-format
+msgid "Subject for certificate for users, %s for project, user, timestamp"
+msgstr ""
+
+#: ../nova/crypto.py:66
+#, python-format
+msgid "Subject for certificate for projects, %s for project, timestamp"
+msgstr ""
+
+#: ../nova/crypto.py:71
+#, python-format
+msgid "Subject for certificate for vpns, %s for project, timestamp"
+msgstr ""
+
+#: ../nova/crypto.py:258
+#, python-format
+msgid "Flags path: %s"
+msgstr ""
+
+#: ../nova/scheduler/manager.py:69
+#, python-format
+msgid "Casting to %(topic)s %(host)s for %(method)s"
+msgstr ""
+
+#: ../nova/compute/manager.py:78
+#, python-format
+msgid "check_instance_lock: decorating: |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:80
+#, python-format
+msgid ""
+"check_instance_lock: arguments: |%(self)s| |%(context)s| |%(instance_id)s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:84
+#, python-format
+msgid "check_instance_lock: locked: |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:86
+#, python-format
+msgid "check_instance_lock: admin: |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:91
+#, python-format
+msgid "check_instance_lock: executing: |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:95
+#, python-format
+msgid "check_instance_lock: not executing |%s|"
+msgstr ""
+
+#: ../nova/compute/manager.py:179
+msgid "Instance has already been created"
+msgstr ""
+
+#: ../nova/compute/manager.py:180
+#, python-format
+msgid "instance %s: starting..."
+msgstr ""
+
+#. pylint: disable=W0702
+#: ../nova/compute/manager.py:219
+#, python-format
+msgid "instance %s: Failed to spawn"
+msgstr ""
+
+#: ../nova/compute/manager.py:233 ../nova/tests/test_cloud.py:286
+#, python-format
+msgid "Terminating instance %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:255
+#, python-format
+msgid "Deallocating address %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:268
+#, python-format
+msgid "trying to destroy already destroyed instance: %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:282
+#, python-format
+msgid "Rebooting instance %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:287
+#, python-format
+msgid ""
+"trying to reboot a non-running instance: %(instance_id)s (state: %(state)s "
+"expected: %(running)s)"
+msgstr ""
+
+#: ../nova/compute/manager.py:311
+#, python-format
+msgid "instance %s: snapshotting"
+msgstr ""
+
+#: ../nova/compute/manager.py:316
+#, python-format
+msgid ""
+"trying to snapshot a non-running instance: %(instance_id)s (state: %(state)s "
+"expected: %(running)s)"
+msgstr ""
+
+#: ../nova/compute/manager.py:332
+#, python-format
+msgid ""
+"trying to reset the password on a non-running instance: %(instance_id)s "
+"(state: %(instance_state)s expected: %(expected_state)s)"
+msgstr ""
+
+#: ../nova/compute/manager.py:335
+#, python-format
+msgid "instance %s: setting admin password"
+msgstr ""
+
+#: ../nova/compute/manager.py:353
+#, python-format
+msgid ""
+"trying to inject a file into a non-running instance: %(instance_id)s (state: "
+"%(instance_state)s expected: %(expected_state)s)"
+msgstr ""
+
+#: ../nova/compute/manager.py:362
+#, python-format
+msgid "instance %(nm)s: injecting file to %(plain_path)s"
+msgstr ""
+
+#: ../nova/compute/manager.py:372
+#, python-format
+msgid "instance %s: rescuing"
+msgstr ""
+
+#: ../nova/compute/manager.py:387
+#, python-format
+msgid "instance %s: unrescuing"
+msgstr ""
+
+#: ../nova/compute/manager.py:406
+#, python-format
+msgid "instance %s: pausing"
+msgstr ""
+
+#: ../nova/compute/manager.py:423
+#, python-format
+msgid "instance %s: unpausing"
+msgstr ""
+
+#: ../nova/compute/manager.py:440
+#, python-format
+msgid "instance %s: retrieving diagnostics"
+msgstr ""
+
+#: ../nova/compute/manager.py:453
+#, python-format
+msgid "instance %s: suspending"
+msgstr ""
+
+#: ../nova/compute/manager.py:472
+#, python-format
+msgid "instance %s: resuming"
+msgstr ""
+
+#: ../nova/compute/manager.py:491
+#, python-format
+msgid "instance %s: locking"
+msgstr ""
+
+#: ../nova/compute/manager.py:503
+#, python-format
+msgid "instance %s: unlocking"
+msgstr ""
+
+#: ../nova/compute/manager.py:513
+#, python-format
+msgid "instance %s: getting locked state"
+msgstr ""
+
+#: ../nova/compute/manager.py:526
+#, python-format
+msgid "instance %s: reset network"
+msgstr ""
+
+#: ../nova/compute/manager.py:535 ../nova/api/ec2/cloud.py:515
+#, python-format
+msgid "Get console output for instance %s"
+msgstr ""
+
+#: ../nova/compute/manager.py:543
+#, python-format
+msgid "instance %s: getting ajax console"
+msgstr ""
+
+#: ../nova/compute/manager.py:553
+#, python-format
+msgid ""
+"instance %(instance_id)s: attaching volume %(volume_id)s to %(mountpoint)s"
+msgstr ""
+
+#. pylint: disable=W0702
+#. NOTE(vish): The inline callback eats the exception info so we
+#. log the traceback here and reraise the same
+#. ecxception below.
+#: ../nova/compute/manager.py:569
+#, python-format
+msgid "instance %(instance_id)s: attach failed %(mountpoint)s, removing"
+msgstr ""
+
+#: ../nova/compute/manager.py:585
+#, python-format
+msgid ""
+"Detach volume %(volume_id)s from mountpoint %(mp)s on instance "
+"%(instance_id)s"
+msgstr ""
+
+#: ../nova/compute/manager.py:588
+#, python-format
+msgid "Detaching volume from unknown instance %s"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:53
+#, python-format
+msgid "Host %s is not alive"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:65
+msgid "All hosts have too many cores"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:87
+#, python-format
+msgid "Host %s not available"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:99
+msgid "All hosts have too many gigabytes"
+msgstr ""
+
+#: ../nova/scheduler/simple.py:119
+msgid "All hosts have too many networks"
+msgstr ""
+
+#: ../nova/volume/manager.py:85
+#, python-format
+msgid "Re-exporting %s volumes"
+msgstr ""
+
+#: ../nova/volume/manager.py:90
+#, python-format
+msgid "volume %s: skipping export"
+msgstr ""
+
+#: ../nova/volume/manager.py:96
+#, python-format
+msgid "volume %s: creating"
+msgstr ""
+
+#: ../nova/volume/manager.py:108
+#, python-format
+msgid "volume %(vol_name)s: creating lv of size %(vol_size)sG"
+msgstr ""
+
+#: ../nova/volume/manager.py:112
+#, python-format
+msgid "volume %s: creating export"
+msgstr ""
+
+#: ../nova/volume/manager.py:123
+#, python-format
+msgid "volume %s: created successfully"
+msgstr ""
+
+#: ../nova/volume/manager.py:131
+msgid "Volume is still attached"
+msgstr ""
+
+#: ../nova/volume/manager.py:133
+msgid "Volume is not local to this node"
+msgstr ""
+
+#: ../nova/volume/manager.py:136
+#, python-format
+msgid "volume %s: removing export"
+msgstr ""
+
+#: ../nova/volume/manager.py:138
+#, python-format
+msgid "volume %s: deleting"
+msgstr ""
+
+#: ../nova/volume/manager.py:147
+#, python-format
+msgid "volume %s: deleted successfully"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:74
+#, python-format
+msgid "%(text)s: _db_content => %(content)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:304 ../nova/virt/xenapi/fake.py:404
+#: ../nova/virt/xenapi/fake.py:422 ../nova/virt/xenapi/fake.py:478
+msgid "Raising NotImplemented"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:306
+#, python-format
+msgid "xenapi.fake does not have an implementation for %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:341
+#, python-format
+msgid "Calling %(localname)s %(impl)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:346
+#, python-format
+msgid "Calling getter %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/fake.py:406
+#, python-format
+msgid ""
+"xenapi.fake does not have an implementation for %s or it has been called "
+"with the wrong number of arguments"
+msgstr ""
+
+#: ../nova/tests/test_cloud.py:256
+msgid "Can't test instances without a real virtual env."
+msgstr ""
+
+#: ../nova/tests/test_cloud.py:268
+#, python-format
+msgid "Need to watch instance %s until it's running..."
+msgstr ""
+
+#: ../nova/virt/connection.py:73
+msgid "Failed to open connection to the hypervisor"
+msgstr ""
+
+#: ../nova/network/linux_net.py:187
+#, python-format
+msgid "Starting VLAN inteface %s"
+msgstr ""
+
+#: ../nova/network/linux_net.py:208
+#, python-format
+msgid "Starting Bridge interface for %s"
+msgstr ""
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:314
+#, python-format
+msgid "Hupping dnsmasq threw %s"
+msgstr ""
+
+#: ../nova/network/linux_net.py:316
+#, python-format
+msgid "Pid %d is stale, relaunching dnsmasq"
+msgstr ""
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:358
+#, python-format
+msgid "killing radvd threw %s"
+msgstr ""
+
+#: ../nova/network/linux_net.py:360
+#, python-format
+msgid "Pid %d is stale, relaunching radvd"
+msgstr ""
+
+#. pylint: disable=W0703
+#: ../nova/network/linux_net.py:449
+#, python-format
+msgid "Killing dnsmasq threw %s"
+msgstr ""
+
+#: ../nova/utils.py:58
+#, python-format
+msgid "Inner Exception: %s"
+msgstr ""
+
+#: ../nova/utils.py:59
+#, python-format
+msgid "Class %s cannot be found"
+msgstr ""
+
+#: ../nova/utils.py:118
+#, python-format
+msgid "Fetching %s"
+msgstr ""
+
+#: ../nova/utils.py:130
+#, python-format
+msgid "Running cmd (subprocess): %s"
+msgstr ""
+
+#: ../nova/utils.py:143 ../nova/utils.py:183
+#, python-format
+msgid "Result was %s"
+msgstr ""
+
+#: ../nova/utils.py:159
+#, python-format
+msgid "Running cmd (SSH): %s"
+msgstr ""
+
+#: ../nova/utils.py:217
+#, python-format
+msgid "debug in callback: %s"
+msgstr ""
+
+#: ../nova/utils.py:222
+#, python-format
+msgid "Running %s"
+msgstr ""
+
+#: ../nova/utils.py:262
+#, python-format
+msgid "Link Local address is not found.:%s"
+msgstr ""
+
+#: ../nova/utils.py:265
+#, python-format
+msgid "Couldn't get Link Local IP of %(interface)s :%(ex)s"
+msgstr ""
+
+#: ../nova/utils.py:363
+#, python-format
+msgid "Invalid backend: %s"
+msgstr ""
+
+#: ../nova/utils.py:374
+#, python-format
+msgid "backend %s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:49
+#, python-format
+msgid "(%(nm)s) publish (key: %(routing_key)s) %(message)s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:54
+#, python-format
+msgid "Publishing to route %s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:84
+#, python-format
+msgid "Declaring queue %s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:90
+#, python-format
+msgid "Declaring exchange %s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:96
+#, python-format
+msgid "Binding %(queue)s to %(exchange)s with key %(routing_key)s"
+msgstr ""
+
+#: ../nova/fakerabbit.py:121
+#, python-format
+msgid "Getting from %(queue)s: %(message)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:135 ../nova/virt/hyperv.py:171
+#, python-format
+msgid "Created VM %s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:138
+#, python-format
+msgid "Created VM %(instance_name)s as %(vm_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:168
+#, python-format
+msgid "Creating VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:171
+#, python-format
+msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:187
+#, python-format
+msgid "VBD not found in instance %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:197
+#, python-format
+msgid "Unable to unplug VBD %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:209
+#, python-format
+msgid "Unable to destroy VBD %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:224
+#, python-format
+msgid "Creating VIF for VM %(vm_ref)s, network %(network_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:227
+#, python-format
+msgid "Created VIF %(vif_ref)s for VM %(vm_ref)s, network %(network_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:246
+#, python-format
+msgid ""
+"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s) on "
+"%(sr_ref)s."
+msgstr ""
+
+#. TODO(sirp): Add quiesce and VSS locking support when Windows support
+#. is added
+#: ../nova/virt/xenapi/vm_utils.py:258
+#, python-format
+msgid "Snapshotting VM %(vm_ref)s with label '%(label)s'..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:272
+#, python-format
+msgid "Created snapshot %(template_vm_ref)s from VM %(vm_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:286
+#, python-format
+msgid "Asking xapi to upload %(vdi_uuids)s as ID %(image_id)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:327
+#, python-format
+msgid "Size for image %(image)s:%(virtual_size)d"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:332
+#, python-format
+msgid "Glance image %s"
+msgstr ""
+
+#. we need to invoke a plugin for copying VDI's
+#. content into proper path
+#: ../nova/virt/xenapi/vm_utils.py:342
+#, python-format
+msgid "Copying VDI %s to /boot/guest on dom0"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:352
+#, python-format
+msgid "Kernel/Ramdisk VDI %s destroyed"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:361
+#, python-format
+msgid "Asking xapi to fetch %(url)s as %(access)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:386 ../nova/virt/xenapi/vm_utils.py:402
+#, python-format
+msgid "Looking up vdi %s for PV kernel"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:397
+#, python-format
+msgid "PV Kernel in VDI:%s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:405
+#, python-format
+msgid "Running pygrub against %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:411
+#, python-format
+msgid "Found Xen kernel %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:413
+msgid "No Xen kernel found. Booting HVM."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:425 ../nova/virt/hyperv.py:431
+#, python-format
+msgid "duplicate name found: %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:442
+#, python-format
+msgid "VDI %s is still available"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:463
+#, python-format
+msgid "(VM_UTILS) xenserver vm state -> |%s|"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:465
+#, python-format
+msgid "(VM_UTILS) xenapi power_state -> |%s|"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:525
+#, python-format
+msgid "VHD %(vdi_uuid)s has parent %(parent_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:542
+#, python-format
+msgid "Re-scanning SR %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:567
+#, python-format
+msgid ""
+"VHD coalesce attempts exceeded (%(counter)d > %(max_attempts)d), giving up..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:574
+#, python-format
+msgid ""
+"Parent %(parent_uuid)s doesn't match original parent "
+"%(original_parent_uuid)s, waiting for coalesce..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:590
+#, python-format
+msgid "No VDIs found for VM %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:594
+#, python-format
+msgid "Unexpected number of VDIs (%(num_vdis)s) found for VM %(vm_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:653
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:188
+#, python-format
+msgid "Creating VBD for VDI %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:655
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:190
+#, python-format
+msgid "Creating VBD for VDI %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:657
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:192
+#, python-format
+msgid "Plugging VBD %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:659
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:194
+#, python-format
+msgid "Plugging VBD %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:661
+#, python-format
+msgid "VBD %(vbd)s plugged as %(orig_dev)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:664
+#, python-format
+msgid "VBD %(vbd)s plugged into wrong dev, remapping to %(dev)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:668
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:197
+#, python-format
+msgid "Destroying VBD for VDI %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:671
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:200
+#, python-format
+msgid "Destroying VBD for VDI %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:683
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:211
+msgid "VBD.unplug successful first time."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:688
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:216
+msgid "VBD.unplug rejected: retrying..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:692
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:220
+msgid "VBD.unplug successful eventually."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:695
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:223
+#, python-format
+msgid "Ignoring XenAPI.Failure in VBD.unplug: %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:704
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:66
+#, python-format
+msgid "Ignoring XenAPI.Failure %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:735
+#, python-format
+msgid ""
+"Writing partition table %(primary_first)d %(primary_last)d to %(dest)s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vm_utils.py:747
+#, python-format
+msgid "Writing partition table %s done."
+msgstr ""
+
+#: ../nova/tests/test_rpc.py:89
+#, python-format
+msgid "Nested received %(queue)s, %(value)s"
+msgstr ""
+
+#: ../nova/tests/test_rpc.py:95
+#, python-format
+msgid "Nested return %s"
+msgstr ""
+
+#: ../nova/tests/test_rpc.py:120 ../nova/tests/test_rpc.py:126
+#, python-format
+msgid "Received %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:44
+msgid "Use of empty request context is deprecated"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:133
+#, python-format
+msgid "No service for id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:251
+#, python-format
+msgid "No service for %(host)s, %(binary)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:592
+msgid "No fixed ips defined"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:608
+#, python-format
+msgid "No floating ip for address %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:629
+#, python-format
+msgid "No address for instance %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:961
+#, python-format
+msgid "no keypair for user %(user_id)s, name %(name)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1076 ../nova/db/sqlalchemy/api.py:1156
+#, python-format
+msgid "No network for id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1086
+msgid "No networks defined"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1115
+#, python-format
+msgid "No network for bridge %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1129 ../nova/db/sqlalchemy/api.py:1142
+#, python-format
+msgid "No network for instance %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1277
+#, python-format
+msgid "Token %s does not exist"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1302
+#, python-format
+msgid "No quota for project_id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1455 ../nova/db/sqlalchemy/api.py:1501
+#: ../nova/api/ec2/__init__.py:323
+#, python-format
+msgid "Volume %s not found"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1514
+#, python-format
+msgid "No export device found for volume %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1527
+#, python-format
+msgid "No target id found for volume %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1572
+#, python-format
+msgid "No security group with id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1589
+#, python-format
+msgid "No security group named %(group_name)s for project: %(project_id)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1682
+#, python-format
+msgid "No secuity group rule with id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1756
+#, python-format
+msgid "No user for id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1772
+#, python-format
+msgid "No user for access key %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1834
+#, python-format
+msgid "No project with id %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1979
+#, python-format
+msgid "No console pool with id %(pool_id)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:1996
+#, python-format
+msgid ""
+"No console pool of type %(console_type)s for compute host %(compute_host)s "
+"on proxy host %(host)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2035
+#, python-format
+msgid "No console for instance %(instance_id)s in pool %(pool_id)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2057
+#, python-format
+msgid "on instance %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2058
+#, python-format
+msgid "No console with id %(console_id)s %(idesc)s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/api.py:2078 ../nova/db/sqlalchemy/api.py:2097
+#, python-format
+msgid "No zone with id %(zone_id)s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:160
+#, python-format
+msgid "Checking state of %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:165
+#, python-format
+msgid "Current state of %(name)s was %(state)s."
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:183
+#, python-format
+msgid "Connecting to libvirt: %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:196
+msgid "Connection to libvirt broke"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:258
+#, python-format
+msgid "instance %(instance_name)s: deleting instance files %(target)s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:283
+#, python-format
+msgid "Invalid device path %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:313
+#, python-format
+msgid "No disk at %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:320
+msgid "Instance snapshotting is not supported for libvirtat this time"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:336
+#, python-format
+msgid "instance %s: rebooted"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:339
+#, python-format
+msgid "_wait_for_reboot failed: %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:382
+#, python-format
+msgid "instance %s: rescued"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:385
+#, python-format
+msgid "_wait_for_rescue failed: %s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:411
+#, python-format
+msgid "instance %s: is running"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:422
+#, python-format
+msgid "instance %s: booted"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:425 ../nova/virt/xenapi/vmops.py:186
+#, python-format
+msgid "instance %s: failed to boot"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:436
+#, python-format
+msgid "virsh said: %r"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:440
+msgid "cool, it's a device"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:448
+#, python-format
+msgid "data: %(data)r, fpath: %(fpath)r"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:456
+#, python-format
+msgid "Contents of file %(fpath)s: %(contents)r"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:489
+msgid "Unable to find an open port"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:563
+#, python-format
+msgid "instance %s: Creating image"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:646
+#, python-format
+msgid "instance %(inst_name)s: injecting key into image %(img_id)s"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:649
+#, python-format
+msgid "instance %(inst_name)s: injecting net into image %(img_id)s"
+msgstr ""
+
+#. This could be a windows image, or a vmdk format disk
+#: ../nova/virt/libvirt_conn.py:657
+#, python-format
+msgid ""
+"instance %(inst_name)s: ignoring error injecting data into image %(img_id)s "
+"(%(e)s)"
+msgstr ""
+
+#. TODO(termie): cache?
+#: ../nova/virt/libvirt_conn.py:665
+#, python-format
+msgid "instance %s: starting toXML method"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:732
+#, python-format
+msgid "instance %s: finished toXML method"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:751
+msgid "diagnostics are not supported for libvirt"
+msgstr ""
+
+#: ../nova/virt/libvirt_conn.py:1225
+#, python-format
+msgid "Attempted to unfilter instance %s which is not filtered"
+msgstr ""
+
+#: ../nova/api/ec2/metadatarequesthandler.py:76
+#, python-format
+msgid "Failed to get metadata for ip: %s"
+msgstr ""
+
+#: ../nova/auth/fakeldap.py:33
+msgid "Attempted to instantiate singleton"
+msgstr ""
+
+#: ../nova/network/api.py:39
+#, python-format
+msgid "Quota exceeeded for %s, tried to allocate address"
+msgstr ""
+
+#: ../nova/network/api.py:42
+msgid "Address quota exceeded. You cannot allocate any more addresses"
+msgstr ""
+
+#: ../nova/tests/test_volume.py:162
+#, python-format
+msgid "Target %s allocated"
+msgstr ""
+
+#: ../nova/virt/images.py:70
+#, python-format
+msgid "Finished retreving %(url)s -- placed in %(path)s"
+msgstr ""
+
+#: ../nova/scheduler/driver.py:66
+msgid "Must implement a fallback schedule"
+msgstr ""
+
+#: ../nova/console/manager.py:70
+msgid "Adding console"
+msgstr ""
+
+#: ../nova/console/manager.py:90
+#, python-format
+msgid "Tried to remove non-existant console %(console_id)s."
+msgstr ""
+
+#: ../nova/api/direct.py:149
+msgid "not available"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:62
+#, python-format
+msgid "The key_pair %s already exists"
+msgstr ""
+
+#. TODO(vish): Do this with M2Crypto instead
+#: ../nova/api/ec2/cloud.py:118
+#, python-format
+msgid "Generating root CA: %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:303
+#, python-format
+msgid "Create key pair %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:311
+#, python-format
+msgid "Delete key pair %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:386
+#, python-format
+msgid "%s is not a valid ipProtocol"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:390
+msgid "Invalid port range"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:421
+#, python-format
+msgid "Revoke security group ingress %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:430 ../nova/api/ec2/cloud.py:459
+msgid "Not enough parameters to build a valid rule."
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:443
+msgid "No rule for the specified parameters."
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:450
+#, python-format
+msgid "Authorize security group ingress %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:464
+#, python-format
+msgid "This rule already exists in group %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:492
+#, python-format
+msgid "Create Security Group %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:495
+#, python-format
+msgid "group %s already exists"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:507
+#, python-format
+msgid "Delete security group %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:584
+#, python-format
+msgid "Create volume of %s GB"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:612
+#, python-format
+msgid "Attach volume %(volume_id)s to instance %(instance_id)s at %(device)s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:629
+#, python-format
+msgid "Detach volume %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:761
+msgid "Allocate address"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:766
+#, python-format
+msgid "Release address %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:771
+#, python-format
+msgid "Associate address %(public_ip)s to instance %(instance_id)s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:780
+#, python-format
+msgid "Disassociate address %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:807
+msgid "Going to start terminating instances"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:815
+#, python-format
+msgid "Reboot instance %r"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:867
+#, python-format
+msgid "De-registering image %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:875
+#, python-format
+msgid "Registered image %(image_location)s with id %(image_id)s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:882 ../nova/api/ec2/cloud.py:900
+#, python-format
+msgid "attribute not supported: %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:890
+#, python-format
+msgid "invalid id: %s"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:903
+msgid "user or group not specified"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:905
+msgid "only group \"all\" is supported"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:907
+msgid "operation_type must be add or remove"
+msgstr ""
+
+#: ../nova/api/ec2/cloud.py:908
+#, python-format
+msgid "Updating image %s publicity"
+msgstr ""
+
+#: ../bin/nova-api.py:52
+#, python-format
+msgid "Using paste.deploy config at: %s"
+msgstr ""
+
+#: ../bin/nova-api.py:57
+#, python-format
+msgid "No paste configuration for app: %s"
+msgstr ""
+
+#: ../bin/nova-api.py:59
+#, python-format
+msgid ""
+"App Config: %(api)s\n"
+"%(config)r"
+msgstr ""
+
+#: ../bin/nova-api.py:64
+#, python-format
+msgid "Running %s API"
+msgstr ""
+
+#: ../bin/nova-api.py:69
+#, python-format
+msgid "No known API applications configured in %s."
+msgstr ""
+
+#: ../bin/nova-api.py:83
+#, python-format
+msgid "Starting nova-api node (version %s)"
+msgstr ""
+
+#: ../bin/nova-api.py:89
+#, python-format
+msgid "No paste configuration found for: %s"
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:84
+#, python-format
+msgid "Argument %(key)s value %(value)s is too short."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:89
+#, python-format
+msgid "Argument %(key)s value %(value)s contains invalid characters."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:94
+#, python-format
+msgid "Argument %(key)s value %(value)s starts with a hyphen."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:102
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:130
+#, python-format
+msgid "Argument %s is required."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:117
+#, python-format
+msgid ""
+"Argument %(key)s may not take value %(value)s. Valid values are ['true', "
+"'false']."
+msgstr ""
+
+#: ../plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py:163
+#, python-format
+msgid ""
+"Created VDI %(vdi_ref)s (%(label)s, %(size)s, %(read_only)s) on %(sr_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:67
+#, python-format
+msgid "Attempted to create non-unique name %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:73
+#, python-format
+msgid "instance %(name)s: not enough free memory"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:148
+#, python-format
+msgid "Starting VM %s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:151
+#, python-format
+msgid "Spawning VM %(instance_name)s created %(vm_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:162
+#, python-format
+msgid "Invalid value for onset_files: '%s'"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:167
+#, python-format
+msgid "Injecting file path: '%s'"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:180
+#, python-format
+msgid "Instance %s: booted"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:232
+#, python-format
+msgid "Instance not present %s"
+msgstr ""
+
+#. TODO(sirp): Add quiesce and VSS locking support when Windows support
+#. is added
+#: ../nova/virt/xenapi/vmops.py:261
+#, python-format
+msgid "Starting snapshot for VM %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:269
+#, python-format
+msgid "Unable to Snapshot %(vm_ref)s: %(exc)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:280
+#, python-format
+msgid "Finished snapshot and upload for VM %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:356
+#, python-format
+msgid "VM %(vm)s already halted, skipping shutdown..."
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:389
+msgid "Removing kernel/ramdisk files"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:399
+msgid "kernel/ramdisk files removed"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:561
+#, python-format
+msgid ""
+"TIMEOUT: The call to %(method)s timed out. VM id=%(instance_id)s; "
+"args=%(strargs)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:564
+#, python-format
+msgid ""
+"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. VM "
+"id=%(instance_id)s; args=%(strargs)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:569
+#, python-format
+msgid ""
+"The call to %(method)s returned an error: %(e)s. VM id=%(instance_id)s; "
+"args=%(strargs)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/vmops.py:760
+#, python-format
+msgid "OpenSSL error: %s"
+msgstr ""
+
+#: ../nova/tests/test_compute.py:148
+#, python-format
+msgid "Running instances: %s"
+msgstr ""
+
+#: ../nova/tests/test_compute.py:154
+#, python-format
+msgid "After terminating instances: %s"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:45
+msgid "Template for script to run on cloudpipe instance boot"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:48
+msgid "Network to push into openvpn config"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:51
+msgid "Netmask to push into openvpn config"
+msgstr ""
+
+#: ../nova/cloudpipe/pipelib.py:97
+#, python-format
+msgid "Launching VPN for %s"
+msgstr ""
+
+#: ../nova/db/sqlalchemy/migration.py:35
+msgid "python-migrate is not installed. Exiting."
+msgstr ""
+
+#: ../nova/image/s3.py:99
+#, python-format
+msgid "Image %s could not be found"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:121
+msgid "Too many failed authentications."
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:131
+#, python-format
+msgid ""
+"Access key %(access_key)s has had %(failures)d failed authentications and "
+"will be locked out for %(lock_mins)d minutes."
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:169 ../nova/objectstore/handler.py:140
+#, python-format
+msgid "Authentication Failure: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:182
+#, python-format
+msgid "Authenticated Request For %(uname)s:%(pname)s)"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:207
+#, python-format
+msgid "action: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:209
+#, python-format
+msgid "arg: %(key)s\t\tval: %(value)s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:281
+#, python-format
+msgid ""
+"Unauthorized request for controller=%(controller)s and action=%(action)s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:314
+#, python-format
+msgid "InstanceNotFound raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:320
+#, python-format
+msgid "VolumeNotFound raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:326
+#, python-format
+msgid "NotFound raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:329
+#, python-format
+msgid "ApiError raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:338
+#, python-format
+msgid "Unexpected error raised: %s"
+msgstr ""
+
+#: ../nova/api/ec2/__init__.py:343
+msgid "An unknown error has occurred. Please try your request again."
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:84
+#, python-format
+msgid "User %s already exists"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:106 ../nova/auth/ldapdriver.py:232
+#, python-format
+msgid "Project can't be created because manager %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:122 ../nova/auth/ldapdriver.py:243
+#, python-format
+msgid "Project can't be created because user %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:135 ../nova/auth/ldapdriver.py:229
+#, python-format
+msgid "Project can't be created because project %s already exists"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:157 ../nova/auth/ldapdriver.py:268
+#, python-format
+msgid "Project can't be modified because manager %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:245
+#, python-format
+msgid "User \"%s\" not found"
+msgstr ""
+
+#: ../nova/auth/dbdriver.py:248
+#, python-format
+msgid "Project \"%s\" not found"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:129
+msgid ""
+"Must specify xenapi_connection_url, xenapi_connection_username (optionally), "
+"and xenapi_connection_password to use connection_type=xenapi"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:311
+#, python-format
+msgid "Task [%(name)s] %(task)s status: success %(result)s"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:317
+#, python-format
+msgid "Task [%(name)s] %(task)s status: %(status)s %(error_info)s"
+msgstr ""
+
+#: ../nova/virt/xenapi_conn.py:331 ../nova/virt/xenapi_conn.py:344
+#, python-format
+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"
+msgstr ""
+
+#: ../nova/api/ec2/apirequest.py:100
+#, python-format
+msgid ""
+"Unsupported API request: controller = %(controller)s, action = %(action)s"
+msgstr ""
+
+#: ../nova/api/openstack/__init__.py:55
+#, python-format
+msgid "Caught error: %s"
+msgstr ""
+
+#: ../nova/api/openstack/__init__.py:76
+msgid "Including admin operations in API."
+msgstr ""
+
+#: ../nova/console/xvp.py:99
+msgid "Rebuilding xvp conf"
+msgstr ""
+
+#: ../nova/console/xvp.py:116
+#, python-format
+msgid "Re-wrote %s"
+msgstr ""
+
+#: ../nova/console/xvp.py:121
+msgid "Stopping xvp"
+msgstr ""
+
+#: ../nova/console/xvp.py:134
+msgid "Starting xvp"
+msgstr ""
+
+#: ../nova/console/xvp.py:141
+#, python-format
+msgid "Error starting xvp: %s"
+msgstr ""
+
+#: ../nova/console/xvp.py:144
+msgid "Restarting xvp"
+msgstr ""
+
+#: ../nova/console/xvp.py:146
+msgid "xvp not running..."
+msgstr ""
+
+#: ../bin/nova-manage.py:272
+msgid ""
+"The above error may show that the database has not been created.\n"
+"Please create a database using nova-manage sync db before running this "
+"command."
+msgstr ""
+
+#: ../bin/nova-manage.py:426
+msgid ""
+"No more networks available. If this is a new installation, you need\n"
+"to call something like this:\n"
+"\n"
+" nova-manage network create 10.0.0.0/8 10 64\n"
+"\n"
+msgstr ""
+
+#: ../bin/nova-manage.py:431
+msgid ""
+"The above error may show that the certificate db has not been created.\n"
+"Please create a database by running a nova-api server on this host."
+msgstr ""
+
+#: ../bin/nova-manage.py:447 ../bin/nova-manage.py:536
+msgid "network"
+msgstr ""
+
+#: ../bin/nova-manage.py:448
+msgid "IP address"
+msgstr ""
+
+#: ../bin/nova-manage.py:449
+msgid "MAC address"
+msgstr ""
+
+#: ../bin/nova-manage.py:450
+msgid "hostname"
+msgstr ""
+
+#: ../bin/nova-manage.py:451
+msgid "host"
+msgstr ""
+
+#: ../bin/nova-manage.py:537
+msgid "netmask"
+msgstr ""
+
+#: ../bin/nova-manage.py:538
+msgid "start address"
+msgstr ""
+
+#: ../nova/virt/disk.py:69
+#, python-format
+msgid "Failed to load partition: %s"
+msgstr ""
+
+#: ../nova/virt/disk.py:91
+#, python-format
+msgid "Failed to mount filesystem: %s"
+msgstr ""
+
+#: ../nova/virt/disk.py:124
+#, python-format
+msgid "nbd device %s did not show up"
+msgstr ""
+
+#: ../nova/virt/disk.py:128
+#, python-format
+msgid "Could not attach image to loopback: %s"
+msgstr ""
+
+#: ../nova/virt/disk.py:151
+msgid "No free nbd devices"
+msgstr ""
+
+#: ../doc/ext/nova_todo.py:46
+#, python-format
+msgid "%(filename)s, line %(line_info)d"
+msgstr ""
+
+#. FIXME(chiradeep): implement this
+#: ../nova/virt/hyperv.py:118
+msgid "In init host"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:131
+#, python-format
+msgid "Attempt to create duplicate vm %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:148
+#, python-format
+msgid "Starting VM %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:150
+#, python-format
+msgid "Started VM %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:152
+#, python-format
+msgid "spawn vm failed: %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:169
+#, python-format
+msgid "Failed to create VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:188
+#, python-format
+msgid "Set memory for vm %s..."
+msgstr ""
+
+#: ../nova/virt/hyperv.py:198
+#, python-format
+msgid "Set vcpus for vm %s..."
+msgstr ""
+
+#: ../nova/virt/hyperv.py:202
+#, python-format
+msgid "Creating disk for %(vm_name)s by attaching disk file %(vhdfile)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:227
+#, python-format
+msgid "Failed to add diskdrive to VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:230
+#, python-format
+msgid "New disk drive path is %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:247
+#, python-format
+msgid "Failed to add vhd file to VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:249
+#, python-format
+msgid "Created disk for %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:253
+#, python-format
+msgid "Creating nic for %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:272
+msgid "Failed creating a port on the external vswitch"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:273
+#, python-format
+msgid "Failed creating port for %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:276
+#, python-format
+msgid "Created switch port %(vm_name)s on switch %(ext_path)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:286
+#, python-format
+msgid "Failed to add nic to VM %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:288
+#, python-format
+msgid "Created nic for %s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:321
+#, python-format
+msgid "WMI job failed: %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:325
+#, python-format
+msgid "WMI job succeeded: %(desc)s, Elapsed=%(elap)s "
+msgstr ""
+
+#: ../nova/virt/hyperv.py:361
+#, python-format
+msgid "Got request to destroy vm %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:386
+#, python-format
+msgid "Failed to destroy vm %s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:393
+#, python-format
+msgid "Del: disk %(vhdfile)s vm %(instance_name)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:415
+#, python-format
+msgid ""
+"Got Info for vm %(instance_id)s: state=%(state)s, mem=%(memusage)s, "
+"num_cpu=%(numprocs)s, cpu_time=%(uptime)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:451
+#, python-format
+msgid "Successfully changed vm state of %(vm_name)s to %(req_state)s"
+msgstr ""
+
+#: ../nova/virt/hyperv.py:454
+#, python-format
+msgid "Failed to change vm state of %(vm_name)s to %(req_state)s"
+msgstr ""
+
+#: ../nova/compute/api.py:71
+#, python-format
+msgid "Instance %d was not found in get_network_topic"
+msgstr ""
+
+#: ../nova/compute/api.py:77
+#, python-format
+msgid "Instance %d has no host"
+msgstr ""
+
+#: ../nova/compute/api.py:97
+#, python-format
+msgid "Quota exceeeded for %(pid)s, tried to run %(min_count)s instances"
+msgstr ""
+
+#: ../nova/compute/api.py:99
+#, python-format
+msgid ""
+"Instance quota exceeded. You can only run %s more instances of this type."
+msgstr ""
+
+#: ../nova/compute/api.py:112
+msgid "Creating a raw instance"
+msgstr ""
+
+#: ../nova/compute/api.py:160
+#, python-format
+msgid "Going to run %s instances..."
+msgstr ""
+
+#: ../nova/compute/api.py:187
+#, python-format
+msgid "Casting to scheduler for %(pid)s/%(uid)s's instance %(instance_id)s"
+msgstr ""
+
+#: ../nova/compute/api.py:292
+#, python-format
+msgid "Going to try to terminate %s"
+msgstr ""
+
+#: ../nova/compute/api.py:296
+#, python-format
+msgid "Instance %d was not found during terminate"
+msgstr ""
+
+#: ../nova/compute/api.py:301
+#, python-format
+msgid "Instance %d is already being terminated"
+msgstr ""
+
+#: ../nova/compute/api.py:481
+#, python-format
+msgid "Invalid device specified: %s. Example device: /dev/vdb"
+msgstr ""
+
+#: ../nova/compute/api.py:496
+msgid "Volume isn't attached to anything!"
+msgstr ""
+
+#: ../nova/rpc.py:98
+#, python-format
+msgid ""
+"AMQP server on %(fl_host)s:%(fl_port)d is unreachable. Trying again in "
+"%(fl_intv)d seconds."
+msgstr ""
+
+#: ../nova/rpc.py:103
+#, python-format
+msgid "Unable to connect to AMQP server after %d tries. Shutting down."
+msgstr ""
+
+#: ../nova/rpc.py:122
+msgid "Reconnected to queue"
+msgstr ""
+
+#: ../nova/rpc.py:129
+msgid "Failed to fetch message from queue"
+msgstr ""
+
+#: ../nova/rpc.py:159
+#, python-format
+msgid "Initing the Adapter Consumer for %s"
+msgstr ""
+
+#: ../nova/rpc.py:178
+#, python-format
+msgid "received %s"
+msgstr ""
+
+#. NOTE(vish): we may not want to ack here, but that means that bad
+#. messages stay in the queue indefinitely, so for now
+#. we just log the message and send an error string
+#. back to the caller
+#: ../nova/rpc.py:191
+#, python-format
+msgid "no method for message: %s"
+msgstr ""
+
+#: ../nova/rpc.py:192
+#, python-format
+msgid "No method for message: %s"
+msgstr ""
+
+#: ../nova/rpc.py:253
+#, python-format
+msgid "Returning exception %s to caller"
+msgstr ""
+
+#: ../nova/rpc.py:294
+#, python-format
+msgid "unpacked context: %s"
+msgstr ""
+
+#: ../nova/rpc.py:313
+msgid "Making asynchronous call..."
+msgstr ""
+
+#: ../nova/rpc.py:316
+#, python-format
+msgid "MSG_ID is %s"
+msgstr ""
+
+#: ../nova/rpc.py:354
+msgid "Making asynchronous cast..."
+msgstr ""
+
+#: ../nova/rpc.py:364
+#, python-format
+msgid "response %s"
+msgstr ""
+
+#: ../nova/rpc.py:373
+#, python-format
+msgid "topic is %s"
+msgstr ""
+
+#: ../nova/rpc.py:374
+#, python-format
+msgid "message %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:78
+#, python-format
+msgid "Recovering from a failed execute. Try number %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:87
+#, python-format
+msgid "volume group %s doesn't exist"
+msgstr ""
+
+#: ../nova/volume/driver.py:220
+#, python-format
+msgid "FAKE AOE: %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:233
+msgid "Skipping ensure_export. No iscsi_target "
+msgstr ""
+
+#: ../nova/volume/driver.py:279 ../nova/volume/driver.py:288
+msgid "Skipping remove_export. No iscsi_target "
+msgstr ""
+
+#: ../nova/volume/driver.py:347
+#, python-format
+msgid "FAKE ISCSI: %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:359
+#, python-format
+msgid "rbd has no pool %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:414
+#, python-format
+msgid "Sheepdog is not working: %s"
+msgstr ""
+
+#: ../nova/volume/driver.py:416
+msgid "Sheepdog is not working"
+msgstr ""
+
+#: ../nova/wsgi.py:68
+#, python-format
+msgid "Starting %(arg0)s on %(host)s:%(port)s"
+msgstr ""
+
+#: ../nova/wsgi.py:147
+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 ""
+
+#: ../bin/nova-dhcpbridge.py:73
+msgid "Adopted old lease or got a change of mac/hostname"
+msgstr ""
+
+#: ../bin/nova-dhcpbridge.py:80
+msgid "releasing ip"
+msgstr ""
+
+#: ../bin/nova-dhcpbridge.py:123
+#, python-format
+msgid ""
+"Called %(action)s for mac %(mac)s with ip %(ip)s and hostname %(hostname)s "
+"on interface %(interface)s"
+msgstr ""
+
+#: ../nova/virt/fake.py:239
+#, python-format
+msgid "Instance %s Not Found"
+msgstr ""
+
+#: ../nova/network/manager.py:153
+#, python-format
+msgid "Dissassociated %s stale fixed ip(s)"
+msgstr ""
+
+#: ../nova/network/manager.py:157
+msgid "setting network host"
+msgstr ""
+
+#: ../nova/network/manager.py:212
+#, python-format
+msgid "Leasing IP %s"
+msgstr ""
+
+#: ../nova/network/manager.py:216
+#, python-format
+msgid "IP %s leased that isn't associated"
+msgstr ""
+
+#: ../nova/network/manager.py:220
+#, python-format
+msgid "IP %(address)s leased to bad mac %(inst_addr)s vs %(mac)s"
+msgstr ""
+
+#: ../nova/network/manager.py:228
+#, python-format
+msgid "IP %s leased that was already deallocated"
+msgstr ""
+
+#: ../nova/network/manager.py:233
+#, python-format
+msgid "Releasing IP %s"
+msgstr ""
+
+#: ../nova/network/manager.py:237
+#, python-format
+msgid "IP %s released that isn't associated"
+msgstr ""
+
+#: ../nova/network/manager.py:241
+#, python-format
+msgid "IP %(address)s released from bad mac %(inst_addr)s vs %(mac)s"
+msgstr ""
+
+#: ../nova/network/manager.py:244
+#, python-format
+msgid "IP %s released that was not leased"
+msgstr ""
+
+#: ../nova/network/manager.py:519
+msgid ""
+"The sum between the number of networks and the vlan start cannot be greater "
+"than 4094"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:57
+#, python-format
+msgid "Introducing %s..."
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:74
+#, python-format
+msgid "Introduced %(label)s as %(sr_ref)s."
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:78
+msgid "Unable to create Storage Repository"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:90
+#, python-format
+msgid "Unable to find SR from VBD %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:96
+#, python-format
+msgid "Forgetting SR %s ... "
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:101
+#, python-format
+msgid "Ignoring exception %(exc)s when getting PBDs for %(sr_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:107
+#, python-format
+msgid "Ignoring exception %(exc)s when unplugging PBD %(pbd)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:111
+#, python-format
+msgid "Forgetting SR %s done."
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:113
+#, python-format
+msgid "Ignoring exception %(exc)s when forgetting SR %(sr_ref)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:123
+#, python-format
+msgid "Unable to introduce VDI on SR %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:128
+#, python-format
+msgid "Unable to get record of VDI %s on"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:146
+#, python-format
+msgid "Unable to introduce VDI for SR %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:175
+#, python-format
+msgid "Unable to obtain target information %(device_path)s, %(mountpoint)s"
+msgstr ""
+
+#: ../nova/virt/xenapi/volume_utils.py:197
+#, python-format
+msgid "Mountpoint cannot be translated: %s"
+msgstr ""
+
+#: ../nova/objectstore/image.py:262
+#, python-format
+msgid "Failed to decrypt private key: %s"
+msgstr ""
+
+#: ../nova/objectstore/image.py:269
+#, python-format
+msgid "Failed to decrypt initialization vector: %s"
+msgstr ""
+
+#: ../nova/objectstore/image.py:277
+#, python-format
+msgid "Failed to decrypt image file %(image_file)s: %(err)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:106
+#, python-format
+msgid "Unknown S3 value type %r"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:137
+msgid "Authenticated request"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:182
+msgid "List of buckets requested"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:209
+#, python-format
+msgid "List keys for bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:217
+#, python-format
+msgid "Unauthorized attempt to access bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:235
+#, python-format
+msgid "Creating bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:245
+#, python-format
+msgid "Deleting bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:249
+#, python-format
+msgid "Unauthorized attempt to delete bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:273
+#, python-format
+msgid "Getting object: %(bname)s / %(nm)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:276
+#, python-format
+msgid "Unauthorized attempt to get object %(nm)s from bucket %(bname)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:296
+#, python-format
+msgid "Putting object: %(bname)s / %(nm)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:299
+#, python-format
+msgid "Unauthorized attempt to upload object %(nm)s to bucket %(bname)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:318
+#, python-format
+msgid "Deleting object: %(bname)s / %(nm)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:322
+#, python-format
+msgid "Unauthorized attempt to delete object %(nm)s from bucket %(bname)s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:396
+#, python-format
+msgid "Not authorized to upload image: invalid directory %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:404
+#, python-format
+msgid "Not authorized to upload image: unauthorized bucket %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:409
+#, python-format
+msgid "Starting image upload: %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:423
+#, python-format
+msgid "Not authorized to update attributes of image %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:431
+#, python-format
+msgid "Toggling publicity flag of image %(image_id)s %(newstatus)r"
+msgstr ""
+
+#. other attributes imply update
+#: ../nova/objectstore/handler.py:436
+#, python-format
+msgid "Updating user fields on image %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:450
+#, python-format
+msgid "Unauthorized attempt to delete image %s"
+msgstr ""
+
+#: ../nova/objectstore/handler.py:455
+#, python-format
+msgid "Deleted image: %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:259
+#, python-format
+msgid "Looking up user: %r"
+msgstr ""
+
+#: ../nova/auth/manager.py:263
+#, python-format
+msgid "Failed authorization for access key %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:264
+#, python-format
+msgid "No user found for access key %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:270
+#, python-format
+msgid "Using project name = user name (%s)"
+msgstr ""
+
+#: ../nova/auth/manager.py:277
+#, python-format
+msgid "failed authorization: no project named %(pjid)s (user=%(uname)s)"
+msgstr ""
+
+#: ../nova/auth/manager.py:279
+#, python-format
+msgid "No project called %s could be found"
+msgstr ""
+
+#: ../nova/auth/manager.py:287
+#, python-format
+msgid ""
+"Failed authorization: user %(uname)s not admin and not member of project "
+"%(pjname)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:289
+#, python-format
+msgid "User %(uid)s is not a member of project %(pjid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:298 ../nova/auth/manager.py:309
+#, python-format
+msgid "Invalid signature for user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:299 ../nova/auth/manager.py:310
+msgid "Signature does not match"
+msgstr ""
+
+#: ../nova/auth/manager.py:380
+msgid "Must specify project"
+msgstr ""
+
+#: ../nova/auth/manager.py:414
+#, python-format
+msgid "The %s role can not be found"
+msgstr ""
+
+#: ../nova/auth/manager.py:416
+#, python-format
+msgid "The %s role is global only"
+msgstr ""
+
+#: ../nova/auth/manager.py:420
+#, python-format
+msgid "Adding role %(role)s to user %(uid)s in project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:423
+#, python-format
+msgid "Adding sitewide role %(role)s to user %(uid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:448
+#, python-format
+msgid "Removing role %(role)s from user %(uid)s on project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:451
+#, python-format
+msgid "Removing sitewide role %(role)s from user %(uid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:515
+#, python-format
+msgid "Created project %(name)s with manager %(manager_user)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:533
+#, python-format
+msgid "modifying project %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:545
+#, python-format
+msgid "Adding user %(uid)s to project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:566
+#, python-format
+msgid "Remove user %(uid)s from project %(pid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:592
+#, python-format
+msgid "Deleting project %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:650
+#, python-format
+msgid "Created user %(rvname)s (admin: %(rvadmin)r)"
+msgstr ""
+
+#: ../nova/auth/manager.py:659
+#, python-format
+msgid "Deleting user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:669
+#, python-format
+msgid "Access Key change for user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:671
+#, python-format
+msgid "Secret Key change for user %s"
+msgstr ""
+
+#: ../nova/auth/manager.py:673
+#, python-format
+msgid "Admin status set to %(admin)r for user %(uid)s"
+msgstr ""
+
+#: ../nova/auth/manager.py:722
+#, python-format
+msgid "No vpn data for project %s"
+msgstr ""
+
+#: ../nova/service.py:161
+#, python-format
+msgid "Starting %(topic)s node (version %(vcs_string)s)"
+msgstr ""
+
+#: ../nova/service.py:174
+msgid "Service killed that has no database entry"
+msgstr ""
+
+#: ../nova/service.py:195
+msgid "The service database object disappeared, Recreating it."
+msgstr ""
+
+#: ../nova/service.py:207
+msgid "Recovered model server connection!"
+msgstr ""
+
+#: ../nova/service.py:213
+msgid "model server went away"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:174
+#, python-format
+msgid "LDAP user %s already exists"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:205
+#, python-format
+msgid "LDAP object for %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:348
+#, python-format
+msgid "User %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:472
+#, python-format
+msgid "Group can't be created because group %s already exists"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:478
+#, python-format
+msgid "Group can't be created because user %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:495
+#, python-format
+msgid "User %s can't be searched in group because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:507
+#, python-format
+msgid "User %s can't be added to the group because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:510 ../nova/auth/ldapdriver.py:521
+#, python-format
+msgid "The group at dn %s doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:513
+#, python-format
+msgid "User %(uid)s is already a member of the group %(group_dn)s"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:524
+#, python-format
+msgid ""
+"User %s can't be removed from the group because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:528
+#, python-format
+msgid "User %s is not a member of the group"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:542
+#, python-format
+msgid ""
+"Attempted to remove the last member of a group. Deleting the group at %s "
+"instead."
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:549
+#, python-format
+msgid "User %s can't be removed from all because the user doesn't exist"
+msgstr ""
+
+#: ../nova/auth/ldapdriver.py:564
+#, python-format
+msgid "Group at dn %s doesn't exist"
+msgstr ""
+
+#: ../nova/virt/xenapi/network_utils.py:40
+#, python-format
+msgid "Found non-unique network for bridge %s"
+msgstr ""
+
+#: ../nova/virt/xenapi/network_utils.py:43
+#, python-format
+msgid "Found no network for bridge %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:97
+#, python-format
+msgid "Creating new user: %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:105
+#, python-format
+msgid "Deleting user: %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:127
+#, python-format
+msgid "Adding role %(role)s to user %(user)s for project %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:131
+#, python-format
+msgid "Adding sitewide role %(role)s to user %(user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:137
+#, python-format
+msgid "Removing role %(role)s from user %(user)s for project %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:141
+#, python-format
+msgid "Removing sitewide role %(role)s from user %(user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:146 ../nova/api/ec2/admin.py:223
+msgid "operation must be add or remove"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:159
+#, python-format
+msgid "Getting x509 for user: %(name)s on project: %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:177
+#, python-format
+msgid "Create project %(name)s managed by %(manager_user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:190
+#, python-format
+msgid "Modify project: %(name)s managed by %(manager_user)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:200
+#, python-format
+msgid "Delete project: %s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:214
+#, python-format
+msgid "Adding user %(user)s to project %(project)s"
+msgstr ""
+
+#: ../nova/api/ec2/admin.py:218
+#, python-format
+msgid "Removing user %(user)s from project %(project)s"
+msgstr ""
diff --git a/run_tests.sh b/run_tests.sh
index b8078e150..8f2b51757 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -11,6 +11,7 @@ function usage {
echo " -x, --stop Stop running tests after the first error or failure."
echo " -f, --force Force a clean re-build of the virtual environment. Useful when dependencies have been added."
echo " -p, --pep8 Just run pep8"
+ echo " -c, --coverage Generate coverage report"
echo " -h, --help Print this usage message"
echo " --hide-elapsed Don't print the elapsed time for each test along with slow test list"
echo ""
@@ -29,6 +30,7 @@ function process_option {
-n|--no-recreate-db) let recreate_db=0;;
-f|--force) let force=1;;
-p|--pep8) let just_pep8=1;;
+ -c|--coverage) let coverage=1;;
-*) noseopts="$noseopts $1";;
*) noseargs="$noseargs $1"
esac
@@ -43,12 +45,18 @@ noseargs=
noseopts=
wrapper=""
just_pep8=0
+coverage=0
recreate_db=1
for arg in "$@"; do
process_option $arg
done
+# If enabled, tell nose to collect coverage data
+if [ $coverage -eq 1 ]; then
+ noseopts="$noseopts --with-coverage --cover-package=nova"
+fi
+
function run_tests {
# Just run the test suites in current environment
${wrapper} $NOSETESTS 2> run_tests.log
@@ -108,6 +116,11 @@ then
fi
fi
+# Delete old coverage data from previous runs
+if [ $coverage -eq 1 ]; then
+ ${wrapper} coverage erase
+fi
+
if [ $just_pep8 -eq 1 ]; then
run_pep8
exit
@@ -126,3 +139,8 @@ run_tests || exit
if [ -z "$noseargs" ]; then
run_pep8
fi
+
+if [ $coverage -eq 1 ]; then
+ echo "Generating coverage report in covhtml/"
+ ${wrapper} coverage html -d covhtml -i
+fi
diff --git a/smoketests/test_sysadmin.py b/smoketests/test_sysadmin.py
index 268d9865b..454f6f1d5 100644
--- a/smoketests/test_sysadmin.py
+++ b/smoketests/test_sysadmin.py
@@ -103,27 +103,48 @@ class ImageTests(base.UserSmokeTestCase):
'launchPermission')
self.assert_(attrs.name, 'launch_permission')
- def test_009_can_modify_image_launch_permission(self):
+ def test_009_can_add_image_launch_permission(self):
+ image = self.conn.get_image(self.data['image_id'])
+ self.assertEqual(image.id, self.data['image_id'])
+ self.assertEqual(image.is_public, False)
self.conn.modify_image_attribute(image_id=self.data['image_id'],
operation='add',
attribute='launchPermission',
groups='all')
image = self.conn.get_image(self.data['image_id'])
self.assertEqual(image.id, self.data['image_id'])
+ self.assertEqual(image.is_public, True)
def test_010_can_see_launch_permission(self):
attrs = self.conn.get_image_attribute(self.data['image_id'],
'launchPermission')
- self.assert_(attrs.name, 'launch_permission')
- self.assert_(attrs.attrs['groups'][0], 'all')
+ self.assertEqual(attrs.name, 'launch_permission')
+ self.assertEqual(attrs.attrs['groups'][0], 'all')
+
+ def test_011_can_remove_image_launch_permission(self):
+ image = self.conn.get_image(self.data['image_id'])
+ self.assertEqual(image.id, self.data['image_id'])
+ self.assertEqual(image.is_public, True)
+ self.conn.modify_image_attribute(image_id=self.data['image_id'],
+ operation='remove',
+ attribute='launchPermission',
+ groups='all')
+ image = self.conn.get_image(self.data['image_id'])
+ self.assertEqual(image.id, self.data['image_id'])
+ self.assertEqual(image.is_public, False)
+
+ def test_012_private_image_shows_in_list(self):
+ images = self.conn.get_all_images()
+ image_ids = [image.id for image in images]
+ self.assertTrue(self.data['image_id'] in image_ids)
- def test_011_user_can_deregister_kernel(self):
+ def test_013_user_can_deregister_kernel(self):
self.assertTrue(self.conn.deregister_image(self.data['kernel_id']))
- def test_012_can_deregister_image(self):
+ def test_014_can_deregister_image(self):
self.assertTrue(self.conn.deregister_image(self.data['image_id']))
- def test_013_can_delete_bundle(self):
+ def test_015_can_delete_bundle(self):
self.assertTrue(self.delete_bundle_bucket(TEST_BUCKET))
diff --git a/tools/esx/guest_tool.py b/tools/esx/guest_tool.py
index 13b0f8d33..97b5302ba 100644
--- a/tools/esx/guest_tool.py
+++ b/tools/esx/guest_tool.py
@@ -21,6 +21,7 @@ On Windows we require pyWin32 installed on Python.
"""
import array
+import gettext
import logging
import os
import platform
@@ -30,6 +31,8 @@ import subprocess
import sys
import time
+gettext.install('nova', unicode=1)
+
PLATFORM_WIN = 'win32'
PLATFORM_LINUX = 'linux2'
ARCH_32_BIT = '32bit'
@@ -275,7 +278,8 @@ def _filter_duplicates(all_entries):
return final_list
-def _set_rhel_networking(network_details=[]):
+def _set_rhel_networking(network_details=None):
+ network_details = network_details or []
all_dns_servers = []
for network_detail in network_details:
mac_address, ip_address, subnet_mask, gateway, broadcast,\
@@ -315,6 +319,46 @@ def _set_rhel_networking(network_details=[]):
_execute(['/sbin/service', 'network', 'restart'])
+def _set_ubuntu_networking(network_details=None):
+ network_details = network_details or []
+ """ Set IPv4 network settings for Ubuntu """
+ all_dns_servers = []
+ for network_detail in network_details:
+ mac_address, ip_address, subnet_mask, gateway, broadcast,\
+ dns_servers = network_detail
+ all_dns_servers.extend(dns_servers)
+ adapter_name, current_ip_address = \
+ _get_linux_adapter_name_and_ip_address(mac_address)
+
+ if adapter_name and not ip_address == current_ip_address:
+ interface_file_name = \
+ '/etc/network/interfaces'
+ # Remove file
+ os.remove(interface_file_name)
+ # Touch file
+ _execute(['touch', interface_file_name])
+ interface_file = open(interface_file_name, 'w')
+ interface_file.write('\nauto %s' % adapter_name)
+ interface_file.write('\niface %s inet static' % adapter_name)
+ interface_file.write('\nbroadcast %s' % broadcast)
+ interface_file.write('\ngateway %s' % gateway)
+ interface_file.write('\nnetmask %s' % subnet_mask)
+ interface_file.write('\naddress %s' % ip_address)
+ interface_file.close()
+ if all_dns_servers:
+ dns_file_name = "/etc/resolv.conf"
+ os.remove(dns_file_name)
+ _execute(['touch', dns_file_name])
+ dns_file = open(dns_file_name, 'w')
+ dns_file.write("; generated by OpenStack guest tools")
+ unique_entries = _filter_duplicates(all_dns_servers)
+ for dns_server in unique_entries:
+ dns_file.write("\nnameserver %s" % dns_server)
+ dns_file.close()
+ print "\nRestarting networking....\n"
+ _execute(['/etc/init.d/networking', 'restart'])
+
+
def _linux_set_networking():
"""Set IP address for the Linux VM."""
vmware_tools_bin = None
@@ -330,8 +374,13 @@ def _linux_set_networking():
cmd = [vmware_tools_bin, '--cmd', 'machine.id.get']
network_details = _parse_network_details(_execute(cmd,
check_exit_code=False))
- # TODO(sateesh): For other distros like ubuntu, suse, debian, BSD, etc.
- _set_rhel_networking(network_details)
+ # TODO(sateesh): For other distros like suse, debian, BSD, etc.
+ if(platform.dist()[0] == 'Ubuntu'):
+ _set_ubuntu_networking(network_details)
+ elif (platform.dist()[0] == 'redhat'):
+ _set_rhel_networking(network_details)
+ else:
+ logging.warn(_("Distro '%s' not supported") % platform.dist()[0])
else:
logging.warn(_("VMware Tools is not installed"))