merged recent trunk

This commit is contained in:
Kei Masumoto
2011-07-27 21:46:44 +09:00
27 changed files with 15428 additions and 549 deletions

View File

@@ -13,3 +13,7 @@ nova/vcsversion.py
clean.sqlite
run_tests.log
tests.sqlite
nova/tests/instance-*
tags
.coverage
covhtml

View File

@@ -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>

View File

@@ -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>

View File

@@ -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():

View File

@@ -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)
@@ -518,7 +585,7 @@ class FixedIpCommands(object):
instance = fixed_ip['instance']
hostname = instance['hostname']
host = instance['host']
mac_address = fixed_ip['mac_address']['address']
mac_address = fixed_ip['virtual_interface']['address']
print "%-18s\t%-15s\t%-17s\t%-15s\t%s" % (
fixed_ip['network']['cidr'],
fixed_ip['address'],
@@ -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,19 +630,32 @@ class FloatingIpCommands(object):
class NetworkCommands(object):
"""Class for managing networks."""
@args('--label', dest="label", metavar='<label>',
help='Label(ex: public)')
@args('--network', dest="fixed_range", metavar='<x.x.x.x/yy>',
help='Network')
@args('--num_networks', dest="num_networks", metavar='<number>',
help='How many networks create')
@args('--network_size', dest="network_size", metavar='<number>',
help='How many hosts in 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='fixed ipv6 range')
@args('--gateway_v6', dest="gateway_v6", help='ipv6 gateway')
@args('--flat_network_bridge', dest="flat_network_bridge",
metavar='<flat network bridge>', help='Flat_network_bridge')
@args('--bridge_interface', dest="bridge_interface",
metavar='<bridge interface>', help='Bridge_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=None, num_networks=None,
network_size=None, vlan_start=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
"""
flat_network_bridge=None, bridge_interface=None,
dns1=None, dns2=None):
"""Creates fixed ips for host by range"""
if not label:
msg = _('a label (ex: public) is required to create networks.')
print msg
@@ -589,6 +669,10 @@ class NetworkCommands(object):
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:
@@ -601,12 +685,15 @@ class NetworkCommands(object):
bridge_interface = FLAGS.flat_interface or FLAGS.vlan_interface
if not gateway_v6:
gateway_v6 = FLAGS.gateway_v6
if not dns1 and FLAGS.flat_network_dns:
dns1 = FLAGS.flat_network_dns
net_manager = utils.import_object(FLAGS.network_manager)
try:
net_manager.create_networks(context.get_admin_context(),
label=label,
cidr=fixed_range,
multi_host=multi_host,
num_networks=int(num_networks),
network_size=int(network_size),
vlan_start=int(vlan_start),
@@ -614,27 +701,35 @@ class NetworkCommands(object):
cidr_v6=fixed_range_v6,
gateway_v6=gateway_v6,
bridge=flat_network_bridge,
bridge_interface=bridge_interface)
bridge_interface=bridge_interface,
dns1=dns1,
dns2=dns2)
except ValueError, e:
print e
raise e
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 +743,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'),
@@ -693,10 +786,9 @@ class VmCommands(object):
def _migration(self, ec2_id, dest, block_migration=False):
"""Migrates a running instance to a new machine.
:param ec2_id: instance id which comes from euca-describe-instance.
:param dest: destination host name.
:param block_migration: if True, do block_migration.
:param ec2_id: instance id which comes from euca-describe-instance.
:param dest: destination host name.
:param block_migration: if True, do block_migration.
"""
@@ -725,31 +817,33 @@ class VmCommands(object):
print _('Migration of %s initiated.'
'Check its progress using euca-describe-instances.') % ec2_id
@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.
"""Migrates a running instance to a new machine."""
:param ec2_id: instance id which comes from euca-describe-instance.
:param dest: destination host name.
"""
self._migration(ec2_id, dest)
@args('--ec2_id', dest='ec2_id', metavar='<ec2 id>', help='EC2 ID')
@args('--dest', dest='dest', metavar='<Destanation>',
help='destanation node')
def block_migration(self, ec2_id, dest):
"""Migrates a running instance to a new machine with storage data.
"""Migrates a running instance to a new machine with storage data."""
:param ec2_id: instance id which comes from euca-describe-instance.
:param dest: destination host name.
"""
self._migration(ec2_id, dest, True)
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)
@@ -768,9 +862,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:
@@ -778,9 +874,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:
@@ -788,12 +886,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,
@@ -831,12 +926,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)
@@ -880,6 +972,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)
@@ -899,14 +993,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']
@@ -927,11 +1025,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']:
@@ -958,12 +1057,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)
@@ -986,9 +1096,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)
@@ -1007,9 +1118,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()
@@ -1057,11 +1169,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,
@@ -1070,31 +1189,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)
@@ -1143,9 +1282,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)
@@ -1170,8 +1310,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,
@@ -1182,8 +1321,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)
@@ -1217,9 +1355,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)
@@ -1315,21 +1451,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")

View File

@@ -15,6 +15,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mox
from base64 import b64decode
from M2Crypto import BIO
@@ -29,6 +30,7 @@ from nova import db
from nova import exception
from nova import flags
from nova import log as logging
from nova import network
from nova import rpc
from nova import test
from nova import utils
@@ -132,6 +134,33 @@ class CloudTestCase(test.TestCase):
allocate,
self.context)
def test_release_address(self):
address = "10.10.10.10"
allocate = self.cloud.allocate_address
db.floating_ip_create(self.context,
{'address': address,
'host': self.network.host})
result = self.cloud.release_address(self.context, address)
self.assertEqual(result['releaseResponse'], ['Address released.'])
def test_release_address_still_associated(self):
address = "10.10.10.10"
fixed_ip = {'instance': {'id': 1}}
floating_ip = {'id': 0,
'address': address,
'fixed_ip_id': 0,
'fixed_ip': fixed_ip,
'project_id': None,
'auto_assigned': False}
network_api = network.api.API()
self.mox.StubOutWithMock(network_api.db, 'floating_ip_get_by_address')
network_api.db.floating_ip_get_by_address(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(floating_ip)
self.mox.ReplayAll()
release = self.cloud.release_address
# 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"""
@@ -240,25 +269,64 @@ 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_ingress_ip_permissions_groups(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'},
'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,
@@ -879,6 +947,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',

View File

@@ -424,11 +424,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
@@ -441,14 +442,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]
@@ -471,13 +473,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)
@@ -519,6 +523,57 @@ class ComputeTestCase(test.TestCase):
self.compute.terminate_instance(context, instance_id)
def test_finish_revert_resize(self):
"""Ensure that the flavor is reverted to the original on revert"""
context = self.context.elevated()
instance_id = self._create_instance()
def fake(*args, **kwargs):
pass
self.stubs.Set(self.compute.driver, 'finish_resize', fake)
self.stubs.Set(self.compute.driver, 'revert_resize', fake)
self.stubs.Set(self.compute.network_api, 'get_instance_nw_info', fake)
self.compute.run_instance(self.context, instance_id)
# Confirm the instance size before the resize starts
inst_ref = db.instance_get(context, instance_id)
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, inst_ref['uuid'], 3)
migration_ref = db.migration_get_by_instance_and_status(context,
inst_ref['uuid'], 'pre-migrating')
self.compute.resize_instance(context, inst_ref['uuid'],
migration_ref['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(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, inst_ref['uuid'],
migration_ref['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(context,
inst_ref['instance_type_id'])
self.assertEqual(instance_type_ref['flavorid'], 1)
self.compute.terminate_instance(context, instance_id)
def test_get_by_flavor_id(self):
type = instance_types.get_instance_type_by_flavor_id(1)
self.assertEqual(type['name'], 'm1.tiny')
@@ -569,7 +624,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)
@@ -577,12 +631,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()
@@ -597,18 +650,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()
@@ -629,18 +680,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,
@@ -789,7 +842,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, [])
self.mox.StubOutWithMock(rpc, 'call')
rpc.call(c, db.queue_get_for(c, FLAGS.compute_topic, dest),
{"method": "post_live_migration_at_destination",

84
nova/tests/test_db_api.py Normal file
View File

@@ -0,0 +1,84 @@
# 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')

View File

@@ -55,10 +55,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}]}
@@ -219,9 +224,19 @@ 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)
# Creating mocks
fake = FakeLibvirtConnection()
fakeip = FakeIptablesFirewallDriver
fakevif = FakeVIFDriver()
# Customizing above fake if necessary
for key, val in kwargs.items():
fake.__setattr__(key, val)
@@ -229,6 +244,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
@@ -280,22 +297,6 @@ 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)
@@ -722,13 +723,19 @@ class LibvirtConnTestCase(test.TestCase):
return vdmock
self.create_fake_libvirt_mock(lookupByName=fake_lookup)
# self.mox.StubOutWithMock(self.compute, "recover_live_migration")
self.mox.StubOutWithMock(self.compute, "rollback_live_migration")
# self.compute.recover_live_migration(self.context, instance_ref,
# dest='dest')
self.compute.rollback_live_migration(self.context, instance_ref,
'dest', False)
# Start test
#start test
self.mox.ReplayAll()
conn = connection.LibvirtConnection(False)
self.assertRaises(libvirt.libvirtError,
conn._live_migration,
self.context, instance_ref, 'dest', '',
self.context, instance_ref, 'dest', False,
self.compute.rollback_live_migration)
instance_ref = db.instance_get(self.context, instance_ref['id'])

View File

@@ -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',

View File

@@ -647,7 +647,7 @@ class XenAPIVMTestCase(test.TestCase):
self.flags(xenapi_inject_image=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()

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

2848
po/en_AU.po Normal file

File diff suppressed because it is too large Load Diff

2873
po/en_GB.po Normal file

File diff suppressed because it is too large Load Diff

139
po/es.po
View File

@@ -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 ""

2992
po/fr.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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

482
po/ja.po

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

2855
po/tl.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

2848
po/zh_TW.po Normal file

File diff suppressed because it is too large Load Diff