summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/nova-all2
-rwxr-xr-xbin/nova-api2
-rwxr-xr-xbin/nova-api-ec22
-rwxr-xr-xbin/nova-api-metadata2
-rwxr-xr-xbin/nova-api-os-compute2
-rwxr-xr-xbin/nova-baremetal-deploy-helper42
-rwxr-xr-xbin/nova-cells3
-rwxr-xr-xbin/nova-cert2
-rwxr-xr-xbin/nova-compute2
-rwxr-xr-xbin/nova-conductor2
-rwxr-xr-xbin/nova-console2
-rwxr-xr-xbin/nova-consoleauth2
-rwxr-xr-xbin/nova-manage46
-rwxr-xr-xbin/nova-network2
-rwxr-xr-xbin/nova-novncproxy3
-rwxr-xr-xbin/nova-objectstore2
-rwxr-xr-xbin/nova-spicehtml5proxy3
-rwxr-xr-xbin/nova-xvpvncproxy2
-rw-r--r--doc/api_samples/os-quota-class-sets/quota-classes-show-get-resp.json4
-rw-r--r--doc/api_samples/os-quota-class-sets/quota-classes-show-get-resp.xml4
-rw-r--r--doc/api_samples/os-quota-class-sets/quota-classes-update-post-resp.json4
-rw-r--r--doc/api_samples/os-quota-class-sets/quota-classes-update-post-resp.xml4
-rw-r--r--doc/api_samples/os-quota-sets/quotas-show-defaults-get-resp.json4
-rw-r--r--doc/api_samples/os-quota-sets/quotas-show-defaults-get-resp.xml4
-rw-r--r--doc/api_samples/os-quota-sets/quotas-show-get-resp.json4
-rw-r--r--doc/api_samples/os-quota-sets/quotas-show-get-resp.xml4
-rw-r--r--doc/api_samples/os-quota-sets/quotas-update-post-resp.json4
-rw-r--r--doc/api_samples/os-quota-sets/quotas-update-post-resp.xml4
-rw-r--r--doc/source/devref/il8n.rst5
-rw-r--r--etc/nova/rootwrap.d/baremetal-deploy-helper.filters2
-rw-r--r--nova/__init__.py5
-rw-r--r--nova/api/metadata/base.py5
-rw-r--r--nova/api/openstack/compute/contrib/extended_availability_zone.py2
-rw-r--r--nova/api/openstack/compute/contrib/security_group_default_rules.py8
-rw-r--r--nova/api/openstack/compute/contrib/security_groups.py54
-rw-r--r--nova/api/openstack/compute/contrib/simple_tenant_usage.py2
-rw-r--r--nova/compute/api.py16
-rwxr-xr-xnova/compute/manager.py34
-rw-r--r--nova/conductor/api.py9
-rw-r--r--nova/conductor/manager.py5
-rw-r--r--nova/conductor/rpcapi.py8
-rw-r--r--nova/exception.py9
-rw-r--r--nova/locale/nova.pot344
-rw-r--r--nova/network/linux_net.py74
-rw-r--r--nova/network/manager.py10
-rw-r--r--nova/network/security_group/quantum_driver.py38
-rw-r--r--nova/network/security_group/security_group_base.py3
-rw-r--r--nova/openstack/common/db/sqlalchemy/session.py3
-rw-r--r--nova/openstack/common/db/sqlalchemy/utils.py2
-rw-r--r--nova/openstack/common/gettextutils.py2
-rw-r--r--nova/openstack/common/rpc/impl_qpid.py4
-rw-r--r--nova/openstack/common/rpc/matchmaker.py4
-rw-r--r--nova/quota.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_flavor_access.py36
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py56
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_quota_classes.py16
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_quotas.py26
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_security_groups.py20
-rw-r--r--nova/tests/baremetal/db/utils.py14
-rw-r--r--nova/tests/compute/test_compute.py69
-rw-r--r--nova/tests/conductor/test_conductor.py10
-rw-r--r--nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-show-get-resp.json.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-show-get-resp.xml.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-req.json.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-req.xml.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-resp.json.tpl4
-rw-r--r--nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-resp.xml.tpl4
-rw-r--r--nova/tests/integrated/api_samples/os-quota-sets/quotas-show-defaults-get-resp.json.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-quota-sets/quotas-show-defaults-get-resp.xml.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-quota-sets/quotas-show-get-resp.json.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-quota-sets/quotas-show-get-resp.xml.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-quota-sets/quotas-update-post-resp.json.tpl2
-rw-r--r--nova/tests/integrated/api_samples/os-quota-sets/quotas-update-post-resp.xml.tpl2
-rw-r--r--nova/tests/network/test_linux_net.py55
-rw-r--r--nova/tests/network/test_manager.py31
-rw-r--r--nova/tests/test_metadata.py11
-rw-r--r--nova/tests/test_nova_manage.py3
-rwxr-xr-xtools/hacking.py2
78 files changed, 763 insertions, 427 deletions
diff --git a/bin/nova-all b/bin/nova-all
index d96b71604..af947d36d 100755
--- a/bin/nova-all
+++ b/bin/nova-all
@@ -30,6 +30,7 @@ continue attempting to launch the rest of the services.
import eventlet
eventlet.monkey_patch(os=False)
+import gettext
import os
import sys
@@ -40,6 +41,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(
if os.path.exists(os.path.join(possible_topdir, "nova", "__init__.py")):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
from nova import config
from nova.objectstore import s3server
diff --git a/bin/nova-api b/bin/nova-api
index d21d955cf..171a23ea0 100755
--- a/bin/nova-api
+++ b/bin/nova-api
@@ -26,6 +26,7 @@ Starts both the EC2 and OpenStack APIs in separate greenthreads.
import eventlet
eventlet.monkey_patch(os=False)
+import gettext
import os
import sys
@@ -36,6 +37,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(
if os.path.exists(os.path.join(possible_topdir, "nova", "__init__.py")):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
from nova import config
from nova.openstack.common import log as logging
diff --git a/bin/nova-api-ec2 b/bin/nova-api-ec2
index d1b3d45ea..a3e1be018 100755
--- a/bin/nova-api-ec2
+++ b/bin/nova-api-ec2
@@ -22,6 +22,7 @@
import eventlet
eventlet.monkey_patch(os=False)
+import gettext
import os
import sys
@@ -31,6 +32,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(
if os.path.exists(os.path.join(possible_topdir, "nova", "__init__.py")):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
from nova import config
from nova.openstack.common import log as logging
diff --git a/bin/nova-api-metadata b/bin/nova-api-metadata
index e7cac260d..2005d6714 100755
--- a/bin/nova-api-metadata
+++ b/bin/nova-api-metadata
@@ -22,6 +22,7 @@
import eventlet
eventlet.monkey_patch(os=False)
+import gettext
import os
import sys
@@ -31,6 +32,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(
if os.path.exists(os.path.join(possible_topdir, "nova", "__init__.py")):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
from nova import config
from nova.openstack.common import log as logging
diff --git a/bin/nova-api-os-compute b/bin/nova-api-os-compute
index 02f16a04a..c2aa9e57c 100755
--- a/bin/nova-api-os-compute
+++ b/bin/nova-api-os-compute
@@ -22,6 +22,7 @@
import eventlet
eventlet.monkey_patch(os=False)
+import gettext
import os
import sys
@@ -31,6 +32,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(
if os.path.exists(os.path.join(possible_topdir, "nova", "__init__.py")):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
from nova import config
from nova.openstack.common import log as logging
diff --git a/bin/nova-baremetal-deploy-helper b/bin/nova-baremetal-deploy-helper
index 756305776..a9d5ecfc7 100755
--- a/bin/nova-baremetal-deploy-helper
+++ b/bin/nova-baremetal-deploy-helper
@@ -23,6 +23,7 @@ import eventlet
if __name__ == '__main__':
eventlet.monkey_patch()
+import gettext
import os
import sys
import threading
@@ -36,6 +37,8 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
+
import cgi
import Queue
import re
@@ -45,6 +48,7 @@ from wsgiref import simple_server
from nova import config
from nova import context as nova_context
+from nova import exception
from nova.openstack.common import log as logging
from nova import utils
from nova.virt.baremetal import baremetal_states
@@ -95,18 +99,27 @@ def logout_iscsi(portal_address, portal_port, target_iqn):
def make_partitions(dev, root_mb, swap_mb):
"""Create partitions for root and swap on a disk device."""
- commands = ['o,w',
- 'n,p,1,,+%dM,t,1,83,w' % root_mb,
- 'n,p,2,,+%dM,t,2,82,w' % swap_mb,
- ]
- for command in commands:
- command = command.replace(',', '\n')
- utils.execute('fdisk', dev,
- process_input=command,
- run_as_root=True,
- check_exit_code=[0])
- # avoid "device is busy"
- time.sleep(3)
+ stdin_command = ('0 0;\n0 0;\n0 0;\n0 0;\n')
+ utils.execute('sfdisk', '-D', '-uM', dev, process_input=stdin_command,
+ run_as_root=True,
+ check_exit_code=[0])
+ # create new partitions
+ commandp1 = '- %d 83;\n;\n;\n;' % root_mb
+ p1outraw, err = utils.execute('sfdisk', '-D', '-uM', '-N1', dev,
+ process_input=commandp1,
+ run_as_root=True,
+ check_exit_code=[0])
+ # get end location of 1st partition
+ p1re = re.compile('^%s-part1.*$' % dev, re.U + re.M)
+ p1balist = p1re.findall(p1outraw)
+ p1endraw = p1balist[1]
+ p1end = int(p1endraw.split()[2])
+ commandp2 = ('%d %d 82\n;\n;' % (p1end + 1, swap_mb))
+ utils.execute('sfdisk', '-D', '-uM', '-N2', dev, process_input=commandp2,
+ run_as_root=True,
+ check_exit_code=[0])
+ # avoid "device is busy"
+ time.sleep(3)
def is_block_device(dev):
@@ -215,6 +228,11 @@ def deploy(address, port, iqn, lun, image_path, pxe_config_path,
login_iscsi(address, port, iqn)
try:
root_uuid = work_on_disk(dev, root_mb, swap_mb, image_path)
+ except exception.ProcessExecutionError, err:
+ # Log output if there was a error
+ LOG.error("Cmd : %s" % err.cmd)
+ LOG.error("StdOut : %s" % err.stdout)
+ LOG.error("StdErr : %s" % err.stderr)
finally:
logout_iscsi(address, port, iqn)
switch_pxe_config(pxe_config_path, root_uuid)
diff --git a/bin/nova-cells b/bin/nova-cells
index bb955e9ec..380e71266 100755
--- a/bin/nova-cells
+++ b/bin/nova-cells
@@ -21,6 +21,7 @@
import eventlet
eventlet.monkey_patch()
+import gettext
import os
import sys
@@ -34,6 +35,8 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
+
from nova import config
from nova.openstack.common import log as logging
from nova import service
diff --git a/bin/nova-cert b/bin/nova-cert
index c6d9ddbad..861f3ba8f 100755
--- a/bin/nova-cert
+++ b/bin/nova-cert
@@ -20,6 +20,7 @@
import eventlet
eventlet.monkey_patch()
+import gettext
import os
import sys
@@ -33,6 +34,7 @@ POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'nova', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
+gettext.install('nova', unicode=1)
from nova import config
from nova.openstack.common import log as logging
diff --git a/bin/nova-compute b/bin/nova-compute
index 26d81d8cc..a7ca4de5b 100755
--- a/bin/nova-compute
+++ b/bin/nova-compute
@@ -29,6 +29,7 @@ if os.name == 'nt':
else:
eventlet.monkey_patch()
+import gettext
import os
import sys
import traceback
@@ -43,6 +44,7 @@ POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'nova', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
+gettext.install('nova', unicode=1)
from nova import config
import nova.db.api
diff --git a/bin/nova-conductor b/bin/nova-conductor
index 30d426f42..72e89804f 100755
--- a/bin/nova-conductor
+++ b/bin/nova-conductor
@@ -20,6 +20,7 @@
import eventlet
eventlet.monkey_patch()
+import gettext
import os
import sys
@@ -33,6 +34,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
from nova import config
from nova.openstack.common import log as logging
diff --git a/bin/nova-console b/bin/nova-console
index 6d6569104..af037bb3c 100755
--- a/bin/nova-console
+++ b/bin/nova-console
@@ -21,6 +21,7 @@
import eventlet
eventlet.monkey_patch()
+import gettext
import os
import sys
@@ -34,6 +35,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
from nova import config
from nova.openstack.common import log as logging
diff --git a/bin/nova-consoleauth b/bin/nova-consoleauth
index 0cbec669a..f867c8c7b 100755
--- a/bin/nova-consoleauth
+++ b/bin/nova-consoleauth
@@ -21,6 +21,7 @@
import eventlet
eventlet.monkey_patch()
+import gettext
import os
import sys
@@ -32,6 +33,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
from nova import config
from nova.consoleauth import manager
diff --git a/bin/nova-manage b/bin/nova-manage
index f80660010..3bcccfcce 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -227,26 +227,44 @@ class ProjectCommands(object):
@args('--key', metavar='<key>', help='Key')
@args('--value', metavar='<value>', help='Value')
def quota(self, project_id, key=None, value=None):
- """Set or display quotas for project."""
+ """
+ Create, update or display quotas for project
+
+ If no quota key is provided, the quota will be displayed.
+ If a valid quota key is provided and it does not exist,
+ it will be created. Otherwise, it will be updated.
+ """
+
ctxt = context.get_admin_context()
project_quota = QUOTAS.get_project_quotas(ctxt, project_id)
- if key and key in project_quota:
- if value.lower() == 'unlimited':
- value = -1
- try:
- db.quota_update(ctxt, project_id, key, value)
- except exception.ProjectQuotaNotFound:
- db.quota_create(ctxt, project_id, key, value)
- else:
- print _('%(key)s is not a valid quota key. Valid options are: '
- '%(options)s.') % {'key': key,
- 'options': ', '.join(project_quota)}
- sys.exit(2)
+ # if key is None, that means we need to show the quotas instead
+ # of updating them
+ if key:
+ if key in project_quota:
+ if value.lower() == 'unlimited':
+ value = -1
+ try:
+ db.quota_update(ctxt, project_id, key, value)
+ except exception.ProjectQuotaNotFound:
+ db.quota_create(ctxt, project_id, key, value)
+ else:
+ print _('%(key)s is not a valid quota key. Valid options are: '
+ '%(options)s.') % {'key': key,
+ 'options': ', '.join(project_quota)}
+ sys.exit(2)
+ print_format = "%-36s %-10s %-10s %-10s"
+ print print_format % (
+ _('Quota'),
+ _('Limit'),
+ _('In Use'),
+ _('Reserved'))
+ # Retrieve the quota after update
project_quota = QUOTAS.get_project_quotas(ctxt, project_id)
for key, value in project_quota.iteritems():
if value['limit'] < 0 or value['limit'] is None:
value['limit'] = 'unlimited'
- print '%s: %s' % (key, value['limit'])
+ print print_format % (key, value['limit'], value['in_use'],
+ value['reserved'])
@args('--project', dest='project_id', metavar='<Project name>',
help='Project name')
diff --git a/bin/nova-network b/bin/nova-network
index d0ee61ed9..b79785214 100755
--- a/bin/nova-network
+++ b/bin/nova-network
@@ -22,6 +22,7 @@
import eventlet
eventlet.monkey_patch()
+import gettext
import os
import sys
@@ -35,6 +36,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
from nova import config
from nova.openstack.common import log as logging
diff --git a/bin/nova-novncproxy b/bin/nova-novncproxy
index 29981f53f..c40fdbfd5 100755
--- a/bin/nova-novncproxy
+++ b/bin/nova-novncproxy
@@ -21,11 +21,14 @@ Websocket proxy that is compatible with OpenStack Nova
noVNC consoles. Leverages websockify.py by Joel Martin
"""
+import gettext
import os
import sys
from oslo.config import cfg
+gettext.install('nova', unicode=1)
+
from nova import config
from nova.console import websocketproxy
diff --git a/bin/nova-objectstore b/bin/nova-objectstore
index 8ec9fbf35..f60868946 100755
--- a/bin/nova-objectstore
+++ b/bin/nova-objectstore
@@ -22,6 +22,7 @@
import eventlet
eventlet.monkey_patch()
+import gettext
import os
import sys
@@ -33,6 +34,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
from nova import config
from nova.objectstore import s3server
diff --git a/bin/nova-spicehtml5proxy b/bin/nova-spicehtml5proxy
index 012a202ec..1d8fe81dc 100755
--- a/bin/nova-spicehtml5proxy
+++ b/bin/nova-spicehtml5proxy
@@ -21,11 +21,14 @@ Websocket proxy that is compatible with OpenStack Nova
SPICE HTML5 consoles. Leverages websockify.py by Joel Martin
"""
+import gettext
import os
import sys
from oslo.config import cfg
+gettext.install('nova', unicode=1)
+
from nova import config
from nova.console import websocketproxy
diff --git a/bin/nova-xvpvncproxy b/bin/nova-xvpvncproxy
index 6ad61d0ba..905c3de4f 100755
--- a/bin/nova-xvpvncproxy
+++ b/bin/nova-xvpvncproxy
@@ -21,6 +21,7 @@
import eventlet
eventlet.monkey_patch()
+import gettext
import os
import sys
@@ -30,6 +31,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+gettext.install('nova', unicode=1)
from nova import config
from nova.openstack.common import log as logging
diff --git a/doc/api_samples/os-quota-class-sets/quota-classes-show-get-resp.json b/doc/api_samples/os-quota-class-sets/quota-classes-show-get-resp.json
index e5748a4cd..6e477722d 100644
--- a/doc/api_samples/os-quota-class-sets/quota-classes-show-get-resp.json
+++ b/doc/api_samples/os-quota-class-sets/quota-classes-show-get-resp.json
@@ -1,7 +1,7 @@
{
"quota_class_set": {
"cores": 20,
- "fixed_ips": 10,
+ "fixed_ips": -1,
"floating_ips": 10,
"id": "test_class",
"injected_file_content_bytes": 10240,
@@ -14,4 +14,4 @@
"security_group_rules": 20,
"security_groups": 10
}
-} \ No newline at end of file
+}
diff --git a/doc/api_samples/os-quota-class-sets/quota-classes-show-get-resp.xml b/doc/api_samples/os-quota-class-sets/quota-classes-show-get-resp.xml
index 8e7444634..91929d34a 100644
--- a/doc/api_samples/os-quota-class-sets/quota-classes-show-get-resp.xml
+++ b/doc/api_samples/os-quota-class-sets/quota-classes-show-get-resp.xml
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<quota_class_set id="test_class">
<cores>20</cores>
- <fixed_ips>10</fixed_ips>
+ <fixed_ips>-1</fixed_ips>
<floating_ips>10</floating_ips>
<injected_file_content_bytes>10240</injected_file_content_bytes>
<injected_file_path_bytes>255</injected_file_path_bytes>
@@ -12,4 +12,4 @@
<ram>51200</ram>
<security_group_rules>20</security_group_rules>
<security_groups>10</security_groups>
-</quota_class_set> \ No newline at end of file
+</quota_class_set>
diff --git a/doc/api_samples/os-quota-class-sets/quota-classes-update-post-resp.json b/doc/api_samples/os-quota-class-sets/quota-classes-update-post-resp.json
index 6325bb562..c86f86063 100644
--- a/doc/api_samples/os-quota-class-sets/quota-classes-update-post-resp.json
+++ b/doc/api_samples/os-quota-class-sets/quota-classes-update-post-resp.json
@@ -1,7 +1,7 @@
{
"quota_class_set": {
"cores": 50,
- "fixed_ips": 10,
+ "fixed_ips": -1,
"floating_ips": 10,
"injected_file_content_bytes": 10240,
"injected_file_path_bytes": 255,
@@ -13,4 +13,4 @@
"security_group_rules": 20,
"security_groups": 10
}
-} \ No newline at end of file
+}
diff --git a/doc/api_samples/os-quota-class-sets/quota-classes-update-post-resp.xml b/doc/api_samples/os-quota-class-sets/quota-classes-update-post-resp.xml
index 26a29fc23..23eb5088c 100644
--- a/doc/api_samples/os-quota-class-sets/quota-classes-update-post-resp.xml
+++ b/doc/api_samples/os-quota-class-sets/quota-classes-update-post-resp.xml
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<quota_class_set>
<cores>50</cores>
- <fixed_ips>10</fixed_ips>
+ <fixed_ips>-1</fixed_ips>
<floating_ips>10</floating_ips>
<injected_file_content_bytes>10240</injected_file_content_bytes>
<injected_file_path_bytes>255</injected_file_path_bytes>
@@ -12,4 +12,4 @@
<ram>51200</ram>
<security_group_rules>20</security_group_rules>
<security_groups>10</security_groups>
-</quota_class_set> \ No newline at end of file
+</quota_class_set>
diff --git a/doc/api_samples/os-quota-sets/quotas-show-defaults-get-resp.json b/doc/api_samples/os-quota-sets/quotas-show-defaults-get-resp.json
index efc35cf00..239c64d23 100644
--- a/doc/api_samples/os-quota-sets/quotas-show-defaults-get-resp.json
+++ b/doc/api_samples/os-quota-sets/quotas-show-defaults-get-resp.json
@@ -1,7 +1,7 @@
{
"quota_set": {
"cores": 20,
- "fixed_ips": 10,
+ "fixed_ips": -1,
"floating_ips": 10,
"id": "fake_tenant",
"injected_file_content_bytes": 10240,
@@ -14,4 +14,4 @@
"security_group_rules": 20,
"security_groups": 10
}
-} \ No newline at end of file
+}
diff --git a/doc/api_samples/os-quota-sets/quotas-show-defaults-get-resp.xml b/doc/api_samples/os-quota-sets/quotas-show-defaults-get-resp.xml
index dd4c6d66d..76a9292c1 100644
--- a/doc/api_samples/os-quota-sets/quotas-show-defaults-get-resp.xml
+++ b/doc/api_samples/os-quota-sets/quotas-show-defaults-get-resp.xml
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<quota_set id="fake_tenant">
<cores>20</cores>
- <fixed_ips>10</fixed_ips>
+ <fixed_ips>-1</fixed_ips>
<floating_ips>10</floating_ips>
<injected_file_content_bytes>10240</injected_file_content_bytes>
<injected_file_path_bytes>255</injected_file_path_bytes>
@@ -12,4 +12,4 @@
<ram>51200</ram>
<security_group_rules>20</security_group_rules>
<security_groups>10</security_groups>
-</quota_set> \ No newline at end of file
+</quota_set>
diff --git a/doc/api_samples/os-quota-sets/quotas-show-get-resp.json b/doc/api_samples/os-quota-sets/quotas-show-get-resp.json
index efc35cf00..239c64d23 100644
--- a/doc/api_samples/os-quota-sets/quotas-show-get-resp.json
+++ b/doc/api_samples/os-quota-sets/quotas-show-get-resp.json
@@ -1,7 +1,7 @@
{
"quota_set": {
"cores": 20,
- "fixed_ips": 10,
+ "fixed_ips": -1,
"floating_ips": 10,
"id": "fake_tenant",
"injected_file_content_bytes": 10240,
@@ -14,4 +14,4 @@
"security_group_rules": 20,
"security_groups": 10
}
-} \ No newline at end of file
+}
diff --git a/doc/api_samples/os-quota-sets/quotas-show-get-resp.xml b/doc/api_samples/os-quota-sets/quotas-show-get-resp.xml
index dd4c6d66d..76a9292c1 100644
--- a/doc/api_samples/os-quota-sets/quotas-show-get-resp.xml
+++ b/doc/api_samples/os-quota-sets/quotas-show-get-resp.xml
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<quota_set id="fake_tenant">
<cores>20</cores>
- <fixed_ips>10</fixed_ips>
+ <fixed_ips>-1</fixed_ips>
<floating_ips>10</floating_ips>
<injected_file_content_bytes>10240</injected_file_content_bytes>
<injected_file_path_bytes>255</injected_file_path_bytes>
@@ -12,4 +12,4 @@
<ram>51200</ram>
<security_group_rules>20</security_group_rules>
<security_groups>10</security_groups>
-</quota_set> \ No newline at end of file
+</quota_set>
diff --git a/doc/api_samples/os-quota-sets/quotas-update-post-resp.json b/doc/api_samples/os-quota-sets/quotas-update-post-resp.json
index 14324e365..2be76d472 100644
--- a/doc/api_samples/os-quota-sets/quotas-update-post-resp.json
+++ b/doc/api_samples/os-quota-sets/quotas-update-post-resp.json
@@ -1,7 +1,7 @@
{
"quota_set": {
"cores": 20,
- "fixed_ips": 10,
+ "fixed_ips": -1,
"floating_ips": 10,
"injected_file_content_bytes": 10240,
"injected_file_path_bytes": 255,
@@ -13,4 +13,4 @@
"security_group_rules": 20,
"security_groups": 45
}
-} \ No newline at end of file
+}
diff --git a/doc/api_samples/os-quota-sets/quotas-update-post-resp.xml b/doc/api_samples/os-quota-sets/quotas-update-post-resp.xml
index 5e6bb893e..e03a0bf5e 100644
--- a/doc/api_samples/os-quota-sets/quotas-update-post-resp.xml
+++ b/doc/api_samples/os-quota-sets/quotas-update-post-resp.xml
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<quota_set>
<cores>20</cores>
- <fixed_ips>10</fixed_ips>
+ <fixed_ips>-1</fixed_ips>
<floating_ips>10</floating_ips>
<injected_file_content_bytes>10240</injected_file_content_bytes>
<injected_file_path_bytes>255</injected_file_path_bytes>
@@ -12,4 +12,4 @@
<ram>51200</ram>
<security_group_rules>20</security_group_rules>
<security_groups>45</security_groups>
-</quota_set> \ No newline at end of file
+</quota_set>
diff --git a/doc/source/devref/il8n.rst b/doc/source/devref/il8n.rst
index 2264630be..ce708449d 100644
--- a/doc/source/devref/il8n.rst
+++ b/doc/source/devref/il8n.rst
@@ -27,8 +27,7 @@ The ``_()`` function is brought into the global scope by doing::
import gettext
gettext.install("nova", unicode=1)
-In general, you shouldn't need to add these to any nova files, since the lines
-are present in ``nova/__init__.py``. However, if this code is missing, it may
-result in an error that looks like like::
+These lines are needed in any toplevel script before any nova modules are
+imported. If this code is missing, it may result in an error that looks like::
NameError: name '_' is not defined
diff --git a/etc/nova/rootwrap.d/baremetal-deploy-helper.filters b/etc/nova/rootwrap.d/baremetal-deploy-helper.filters
index 65416bbf8..b4d11e24f 100644
--- a/etc/nova/rootwrap.d/baremetal-deploy-helper.filters
+++ b/etc/nova/rootwrap.d/baremetal-deploy-helper.filters
@@ -4,7 +4,7 @@
[Filters]
# nova-baremetal-deploy-helper
iscsiadm: CommandFilter, /sbin/iscsiadm, root
-fdisk: CommandFilter, /sbin/fdisk, root
+sfdisk: CommandFilter, /sbin/sfdisk, root
dd: CommandFilter, /bin/dd, root
mkswap: CommandFilter, /sbin/mkswap, root
blkid: CommandFilter, /sbin/blkid, root
diff --git a/nova/__init__.py b/nova/__init__.py
index a9eca4848..e21bdd7b4 100644
--- a/nova/__init__.py
+++ b/nova/__init__.py
@@ -24,8 +24,3 @@
:platform: Unix
:synopsis: Infrastructure-as-a-Service Cloud platform.
"""
-
-import gettext
-
-
-gettext.install('nova', unicode=1)
diff --git a/nova/api/metadata/base.py b/nova/api/metadata/base.py
index 90dcb9ca5..1f5e5b5b9 100644
--- a/nova/api/metadata/base.py
+++ b/nova/api/metadata/base.py
@@ -99,13 +99,12 @@ class InstanceMetadata():
self.extra_md = extra_md
if conductor_api:
- self.conductor_api = conductor_api
+ capi = conductor_api
else:
- self.conductor_api = conductor.API()
+ capi = conductor.API()
ctxt = context.get_admin_context()
- capi = self.conductor_api
self.availability_zone = ec2utils.get_availability_zone_by_host(
instance['host'], capi)
diff --git a/nova/api/openstack/compute/contrib/extended_availability_zone.py b/nova/api/openstack/compute/contrib/extended_availability_zone.py
index af557219f..a1ee85bcf 100644
--- a/nova/api/openstack/compute/contrib/extended_availability_zone.py
+++ b/nova/api/openstack/compute/contrib/extended_availability_zone.py
@@ -37,7 +37,7 @@ class ExtendedAZController(wsgi.Controller):
self.mc = memorycache.get_client()
def _get_host_az(self, context, instance):
- host = instance.get('host')
+ host = str(instance.get('host'))
if not host:
return None
cache_key = "azcache-%s" % host
diff --git a/nova/api/openstack/compute/contrib/security_group_default_rules.py b/nova/api/openstack/compute/contrib/security_group_default_rules.py
index e2bba8127..751a4d459 100644
--- a/nova/api/openstack/compute/contrib/security_group_default_rules.py
+++ b/nova/api/openstack/compute/contrib/security_group_default_rules.py
@@ -112,7 +112,7 @@ class SecurityGroupDefaultRulesController(sg.SecurityGroupControllerBase):
@wsgi.serializers(xml=SecurityGroupDefaultRuleTemplate)
@wsgi.deserializers(xml=SecurityGroupDefaultRulesXMLDeserializer)
def create(self, req, body):
- context = self._authorize_context(req)
+ context = sg._authorize_context(req)
authorize(context)
sg_rule = self._from_body(body, 'security_group_default_rule')
@@ -146,7 +146,7 @@ class SecurityGroupDefaultRulesController(sg.SecurityGroupControllerBase):
@wsgi.serializers(xml=SecurityGroupDefaultRuleTemplate)
def show(self, req, id):
- context = self._authorize_context(req)
+ context = sg._authorize_context(req)
authorize(context)
id = self.security_group_api.validate_id(id)
@@ -161,7 +161,7 @@ class SecurityGroupDefaultRulesController(sg.SecurityGroupControllerBase):
return {"security_group_default_rule": fmt_rule}
def delete(self, req, id):
- context = self._authorize_context(req)
+ context = sg._authorize_context(req)
authorize(context)
id = self.security_group_api.validate_id(id)
@@ -175,7 +175,7 @@ class SecurityGroupDefaultRulesController(sg.SecurityGroupControllerBase):
@wsgi.serializers(xml=SecurityGroupDefaultRulesTemplate)
def index(self, req):
- context = self._authorize_context(req)
+ context = sg._authorize_context(req)
authorize(context)
ret = {'security_group_default_rules': []}
diff --git a/nova/api/openstack/compute/contrib/security_groups.py b/nova/api/openstack/compute/contrib/security_groups.py
index 354fab647..700d9b71e 100644
--- a/nova/api/openstack/compute/contrib/security_groups.py
+++ b/nova/api/openstack/compute/contrib/security_groups.py
@@ -77,6 +77,11 @@ def make_sg(elem):
make_rule(rule)
+def _authorize_context(req):
+ context = req.environ['nova.context']
+ authorize(context)
+ return context
+
sg_nsmap = {None: wsgi.XMLNS_V11}
@@ -213,11 +218,6 @@ class SecurityGroupControllerBase(object):
context, rule)]
return security_group
- def _authorize_context(self, req):
- context = req.environ['nova.context']
- authorize(context)
- return context
-
def _from_body(self, body, key):
if not body:
raise exc.HTTPUnprocessableEntity()
@@ -233,7 +233,7 @@ class SecurityGroupController(SecurityGroupControllerBase):
@wsgi.serializers(xml=SecurityGroupTemplate)
def show(self, req, id):
"""Return data about the given security group."""
- context = self._authorize_context(req)
+ context = _authorize_context(req)
id = self.security_group_api.validate_id(id)
@@ -245,7 +245,7 @@ class SecurityGroupController(SecurityGroupControllerBase):
def delete(self, req, id):
"""Delete a security group."""
- context = self._authorize_context(req)
+ context = _authorize_context(req)
id = self.security_group_api.validate_id(id)
@@ -259,7 +259,7 @@ class SecurityGroupController(SecurityGroupControllerBase):
@wsgi.serializers(xml=SecurityGroupsTemplate)
def index(self, req):
"""Returns a list of security groups."""
- context = self._authorize_context(req)
+ context = _authorize_context(req)
search_opts = {}
search_opts.update(req.GET)
@@ -280,7 +280,7 @@ class SecurityGroupController(SecurityGroupControllerBase):
@wsgi.deserializers(xml=SecurityGroupXMLDeserializer)
def create(self, req, body):
"""Creates a new security group."""
- context = self._authorize_context(req)
+ context = _authorize_context(req)
security_group = self._from_body(body, 'security_group')
@@ -303,7 +303,7 @@ class SecurityGroupRulesController(SecurityGroupControllerBase):
@wsgi.serializers(xml=SecurityGroupRuleTemplate)
@wsgi.deserializers(xml=SecurityGroupRulesXMLDeserializer)
def create(self, req, body):
- context = self._authorize_context(req)
+ context = _authorize_context(req)
sg_rule = self._from_body(body, 'security_group_rule')
@@ -358,7 +358,7 @@ class SecurityGroupRulesController(SecurityGroupControllerBase):
cidr, ip_protocol, from_port, to_port)
def delete(self, req, id):
- context = self._authorize_context(req)
+ context = _authorize_context(req)
id = self.security_group_api.validate_id(id)
@@ -380,7 +380,7 @@ class ServerSecurityGroupController(SecurityGroupControllerBase):
@wsgi.serializers(xml=SecurityGroupsTemplate)
def index(self, req, server_id):
"""Returns a list of security groups for the given instance."""
- context = self._authorize_context(req)
+ context = _authorize_context(req)
self.security_group_api.ensure_default(context)
@@ -390,7 +390,7 @@ class ServerSecurityGroupController(SecurityGroupControllerBase):
raise exc.HTTPNotFound(explanation=exp.format_message())
groups = self.security_group_api.get_instance_security_groups(
- req, instance['id'], instance['uuid'], True)
+ context, instance['id'], instance['uuid'], True)
result = [self._format_security_group(context, group)
for group in groups]
@@ -466,7 +466,10 @@ class SecurityGroupsOutputController(wsgi.Controller):
openstack_driver.get_openstack_security_group_driver())
def _extend_servers(self, req, servers):
+ # TODO(arosen) this function should be refactored to reduce duplicate
+ # code and use get_instance_security_groups instead of get_db_instance.
key = "security_groups"
+ context = _authorize_context(req)
if not openstack_driver.is_quantum_security_groups():
for server in servers:
instance = req.get_db_instance(server['id'])
@@ -478,35 +481,38 @@ class SecurityGroupsOutputController(wsgi.Controller):
# instance from the request. The reason for this is if using
# quantum security groups the requested security groups for the
# instance are not in the db and have not been sent to quantum yet.
- instance_sgs = []
if req.method != 'POST':
+ sg_instance_bindings = (
+ self.security_group_api
+ .get_instances_security_groups_bindings(context))
for server in servers:
- instance_sgs = (
- self.security_group_api.get_instance_security_groups(
- req, server['id']))
+ groups = sg_instance_bindings.get(server['id'])
+ if groups:
+ server[key] = groups
+ # In this section of code len(servers) == 1 as you can only POST
+ # one server in an API request.
else:
try:
# try converting to json
req_obj = json.loads(req.body)
# Add security group to server, if no security group was in
# request add default since that is the group it is part of
- instance_sgs = req_obj['server'].get(
+ servers[0][key] = req_obj['server'].get(
key, [{'name': 'default'}])
except ValueError:
root = minidom.parseString(req.body)
sg_root = root.getElementsByTagName(key)
+ groups = []
if sg_root:
security_groups = sg_root[0].getElementsByTagName(
'security_group')
for security_group in security_groups:
- instance_sgs.append(
+ groups.append(
{'name': security_group.getAttribute('name')})
- if not instance_sgs:
- instance_sgs = [{'name': 'default'}]
+ if not groups:
+ groups = [{'name': 'default'}]
- if instance_sgs:
- for server in servers:
- server[key] = instance_sgs
+ servers[0][key] = groups
def _show(self, req, resp_obj):
if not softauth(req.environ['nova.context']):
diff --git a/nova/api/openstack/compute/contrib/simple_tenant_usage.py b/nova/api/openstack/compute/contrib/simple_tenant_usage.py
index 0428c8a77..b653564c0 100644
--- a/nova/api/openstack/compute/contrib/simple_tenant_usage.py
+++ b/nova/api/openstack/compute/contrib/simple_tenant_usage.py
@@ -106,7 +106,7 @@ class SimpleTenantUsageController(object):
def _get_flavor(self, context, compute_api, instance, flavors_cache):
"""Get flavor information from the instance's system_metadata,
- allowing a fallback to lookup by-id for deleted instances only"""
+ allowing a fallback to lookup by-id for deleted instances only."""
try:
return instance_types.extract_instance_type(instance)
except KeyError:
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 0d915bfc9..8b75613d2 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -40,7 +40,6 @@ from nova.compute import task_states
from nova.compute import utils as compute_utils
from nova.compute import vm_states
from nova.consoleauth import rpcapi as consoleauth_rpcapi
-from nova import context
from nova import crypto
from nova.db import base
from nova import exception
@@ -69,6 +68,10 @@ compute_opts = [
default=False,
help='Allow destination machine to match source for resize. '
'Useful when testing in single-host environments.'),
+ cfg.BoolOpt('allow_migrate_to_same_host',
+ default=False,
+ help='Allow migrate machine to the same host. '
+ 'Useful when testing in single-host environments.'),
cfg.StrOpt('default_schedule_zone',
default=None,
help='availability zone to use when user doesn\'t specify one'),
@@ -2036,6 +2039,10 @@ class API(base.Base):
if not CONF.allow_resize_to_same_host:
filter_properties['ignore_hosts'].append(instance['host'])
+ # Here when flavor_id is None, the process is considered as migrate.
+ if (not flavor_id and not CONF.allow_migrate_to_same_host):
+ filter_properties['ignore_hosts'].append(instance['host'])
+
# With cells, the best we can do right now is commit the reservations
# immediately...
if CONF.cells.enable and reservations:
@@ -3164,12 +3171,11 @@ class SecurityGroupAPI(base.Base, security_group_base.SecurityGroupBase):
self.security_group_rpcapi.refresh_instance_security_rules(
context, instance['host'], instance)
- def get_instance_security_groups(self, req, instance_id,
+ def get_instance_security_groups(self, context, instance_id,
instance_uuid=None, detailed=False):
if detailed:
- return self.db.security_group_get_by_instance(
- context.get_admin_context(), instance_id)
- instance = req.get_db_instance(instance_id)
+ return self.db.security_group_get_by_instance(context, instance_id)
+ instance = self.db.instance_get(context, instance_id)
groups = instance.get('security_groups')
if groups:
return [{'name': group['name']} for group in groups]
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 6cb0bbb94..30e33d8e0 100755
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -744,6 +744,21 @@ class ComputeManager(manager.SchedulerDependentManager):
return block_device_info
+ def _decode_files(self, injected_files):
+ """Base64 decode the list of files to inject."""
+ if not injected_files:
+ return []
+
+ def _decode(f):
+ path, contents = f
+ try:
+ decoded = base64.b64decode(contents)
+ return path, decoded
+ except TypeError:
+ raise exception.Base64Exception(path=path)
+
+ return [_decode(f) for f in injected_files]
+
def _run_instance(self, context, request_spec,
filter_properties, requested_networks, injected_files,
admin_password, is_first_time, node, instance):
@@ -788,6 +803,10 @@ class ComputeManager(manager.SchedulerDependentManager):
bdms = self.conductor_api.block_device_mapping_get_all_by_instance(
context, instance)
+ # b64 decode the files to inject:
+ injected_files_orig = injected_files
+ injected_files = self._decode_files(injected_files)
+
rt = self._get_resource_tracker(node)
try:
limits = filter_properties.get('limits', {})
@@ -833,8 +852,9 @@ class ComputeManager(manager.SchedulerDependentManager):
exc_info = sys.exc_info()
# try to re-schedule instance:
self._reschedule_or_reraise(context, instance, exc_info,
- requested_networks, admin_password, injected_files,
- is_first_time, request_spec, filter_properties, bdms)
+ requested_networks, admin_password,
+ injected_files_orig, is_first_time, request_spec,
+ filter_properties, bdms)
else:
# Spawn success:
self._notify_about_instance_usage(context, instance,
@@ -1067,6 +1087,7 @@ class ComputeManager(manager.SchedulerDependentManager):
injected_files, admin_password,
self._legacy_nw_info(network_info),
block_device_info)
+
except Exception:
with excutils.save_and_reraise_exception():
LOG.exception(_('Instance failed to spawn'), instance=instance)
@@ -1180,11 +1201,6 @@ class ComputeManager(manager.SchedulerDependentManager):
if filter_properties is None:
filter_properties = {}
- if injected_files is None:
- injected_files = []
- else:
- injected_files = [(path, base64.b64decode(contents))
- for path, contents in injected_files]
@lockutils.synchronized(instance['uuid'], 'nova-')
def do_run_instance():
@@ -3434,8 +3450,8 @@ class ComputeManager(manager.SchedulerDependentManager):
instance=instance)
continue
try:
- self.compute_api.confirm_resize(context, instance,
- migration_ref=migration)
+ self.conductor_api.compute_confirm_resize(
+ context, instance, migration_ref=migration)
except Exception, e:
msg = _("Error auto-confirming resize: %(e)s. "
"Will retry later.")
diff --git a/nova/conductor/api.py b/nova/conductor/api.py
index 1825a9e7e..cebe6bf1f 100644
--- a/nova/conductor/api.py
+++ b/nova/conductor/api.py
@@ -337,6 +337,10 @@ class LocalAPI(object):
def compute_stop(self, context, instance, do_cast=True):
return self._manager.compute_stop(context, instance, do_cast)
+ def compute_confirm_resize(self, context, instance, migration_ref):
+ return self._manager.compute_confirm_resize(context, instance,
+ migration_ref)
+
class API(object):
"""Conductor API that does updates via RPC to the ConductorManager."""
@@ -671,3 +675,8 @@ class API(object):
def compute_stop(self, context, instance, do_cast=True):
return self.conductor_rpcapi.compute_stop(context, instance, do_cast)
+
+ def compute_confirm_resize(self, context, instance, migration_ref):
+ return self.conductor_rpcapi.compute_confirm_resize(context,
+ instance,
+ migration_ref)
diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py
index 71b08bad4..b4e35066c 100644
--- a/nova/conductor/manager.py
+++ b/nova/conductor/manager.py
@@ -49,7 +49,7 @@ datetime_fields = ['launched_at', 'terminated_at', 'updated_at']
class ConductorManager(manager.Manager):
"""Mission: TBD."""
- RPC_API_VERSION = '1.45'
+ RPC_API_VERSION = '1.46'
def __init__(self, *args, **kwargs):
super(ConductorManager, self).__init__(*args, **kwargs)
@@ -422,3 +422,6 @@ class ConductorManager(manager.Manager):
def compute_stop(self, context, instance, do_cast=True):
self.compute_api.stop(context, instance, do_cast)
+
+ def compute_confirm_resize(self, context, instance, migration_ref):
+ self.compute_api.confirm_resize(context, instance, migration_ref)
diff --git a/nova/conductor/rpcapi.py b/nova/conductor/rpcapi.py
index 22b1b039f..d8daecf9c 100644
--- a/nova/conductor/rpcapi.py
+++ b/nova/conductor/rpcapi.py
@@ -83,6 +83,7 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy):
1.43 - Added compute_stop
1.44 - Added compute_node_delete
1.45 - Added project_id to quota_commit and quota_rollback
+ 1.46 - Added compute_confirm_resize
"""
BASE_RPC_API_VERSION = '1.0'
@@ -437,3 +438,10 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy):
msg = self.make_msg('compute_stop', instance=instance_p,
do_cast=do_cast)
return self.call(context, msg, version='1.43')
+
+ def compute_confirm_resize(self, context, instance, migration_ref):
+ instance_p = jsonutils.to_primitive(instance)
+ migration_p = jsonutils.to_primitive(migration_ref)
+ msg = self.make_msg('compute_confirm_resize', instance=instance_p,
+ migration_ref=migration_p)
+ return self.call(context, msg, version='1.46')
diff --git a/nova/exception.py b/nova/exception.py
index 1f32b0671..b3b3d1f1f 100644
--- a/nova/exception.py
+++ b/nova/exception.py
@@ -1083,6 +1083,11 @@ class DuplicateVlan(Duplicate):
message = _("Detected existing vlan with id %(vlan)d")
+class CidrConflict(NovaException):
+ message = _("There was a conflict when trying to complete your request.")
+ code = 409
+
+
class InstanceNotFound(NotFound):
message = _("Instance %(instance_id)s could not be found.")
@@ -1200,3 +1205,7 @@ class UnsupportedVirtType(Invalid):
class UnsupportedHardware(Invalid):
message = _("Requested hardware '%(model)s' is not supported by "
"the '%(virt)s' virt driver")
+
+
+class Base64Exception(NovaException):
+ message = _("Invalid Base 64 data for file %(path)s")
diff --git a/nova/locale/nova.pot b/nova/locale/nova.pot
index c2e0ef6c5..8593e89a3 100644
--- a/nova/locale/nova.pot
+++ b/nova/locale/nova.pot
@@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: nova jenkins.nova.propose.translation.update.200\n"
+"Project-Id-Version: nova jenkins.nova.propose.translation.update.201\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2013-03-28 00:03+0000\n"
+"POT-Creation-Date: 2013-03-29 00:03+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -1292,27 +1292,27 @@ msgstr ""
msgid "Running %(name)s post-hook: %(obj)s"
msgstr ""
-#: nova/manager.py:171
+#: nova/manager.py:172
#, python-format
msgid "Skipping periodic task %(task)s because its interval is negative"
msgstr ""
-#: nova/manager.py:176
+#: nova/manager.py:177
#, python-format
msgid "Skipping periodic task %(task)s because it is disabled"
msgstr ""
-#: nova/manager.py:237
+#: nova/manager.py:238
#, python-format
msgid "Running periodic task %(full_task_name)s"
msgstr ""
-#: nova/manager.py:245
+#: nova/manager.py:246
#, python-format
msgid "Error during %(full_task_name)s: %(e)s"
msgstr ""
-#: nova/manager.py:318
+#: nova/manager.py:315
msgid "Notifying Schedulers of capabilities ..."
msgstr ""
@@ -3232,7 +3232,7 @@ msgstr ""
msgid "stop instance"
msgstr ""
-#: nova/api/openstack/compute/contrib/simple_tenant_usage.py:199
+#: nova/api/openstack/compute/contrib/simple_tenant_usage.py:226
msgid "Invalid start time. The start time cannot occur after the end time."
msgstr ""
@@ -4845,123 +4845,123 @@ msgstr ""
msgid "This shouldn't be getting called except during testing."
msgstr ""
-#: nova/network/linux_net.py:215
+#: nova/network/linux_net.py:219
#, python-format
msgid "Attempted to remove chain %s which does not exist"
msgstr ""
-#: nova/network/linux_net.py:250
+#: nova/network/linux_net.py:254
#, python-format
msgid "Unknown chain: %r"
msgstr ""
-#: nova/network/linux_net.py:275
+#: nova/network/linux_net.py:279
#, python-format
msgid ""
"Tried to remove rule that was not there: %(chain)r %(rule)r %(wrap)r "
"%(top)r"
msgstr ""
-#: nova/network/linux_net.py:420
+#: nova/network/linux_net.py:424
msgid "IPTablesManager.apply completed with success"
msgstr ""
-#: nova/network/linux_net.py:676
+#: nova/network/linux_net.py:680
#, python-format
msgid "arping error for ip %s"
msgstr ""
-#: nova/network/linux_net.py:726
+#: nova/network/linux_net.py:730
#, python-format
msgid "Removed %(num)d duplicate rules for floating ip %(float)s"
msgstr ""
-#: nova/network/linux_net.py:962
+#: nova/network/linux_net.py:966
#, python-format
msgid "Pid %d is stale, skip killing dnsmasq"
msgstr ""
-#: nova/network/linux_net.py:1007
+#: nova/network/linux_net.py:1011
#, python-format
msgid "Hupping dnsmasq threw %s"
msgstr ""
-#: nova/network/linux_net.py:1009
+#: nova/network/linux_net.py:1013
#, python-format
msgid "Pid %d is stale, relaunching dnsmasq"
msgstr ""
-#: nova/network/linux_net.py:1084
+#: nova/network/linux_net.py:1089
#, python-format
msgid "killing radvd threw %s"
msgstr ""
-#: nova/network/linux_net.py:1086
+#: nova/network/linux_net.py:1091
#, python-format
msgid "Pid %d is stale, relaunching radvd"
msgstr ""
-#: nova/network/linux_net.py:1218
+#: nova/network/linux_net.py:1223
#, python-format
msgid "Error clearing stale veth %s"
msgstr ""
-#: nova/network/linux_net.py:1377
+#: nova/network/linux_net.py:1382
#, python-format
msgid "Starting VLAN interface %s"
msgstr ""
-#: nova/network/linux_net.py:1409
+#: nova/network/linux_net.py:1414
#, python-format
msgid "Failed unplugging VLAN interface '%s'"
msgstr ""
-#: nova/network/linux_net.py:1411
+#: nova/network/linux_net.py:1416
#, python-format
msgid "Unplugged VLAN interface '%s'"
msgstr ""
-#: nova/network/linux_net.py:1433
+#: nova/network/linux_net.py:1438
#, python-format
msgid "Starting Bridge %s"
msgstr ""
-#: nova/network/linux_net.py:1445
+#: nova/network/linux_net.py:1450
#, python-format
msgid "Adding interface %(interface)s to bridge %(bridge)s"
msgstr ""
-#: nova/network/linux_net.py:1481
+#: nova/network/linux_net.py:1486
#, python-format
msgid "Failed to add interface: %s"
msgstr ""
-#: nova/network/linux_net.py:1518
+#: nova/network/linux_net.py:1529
#, python-format
msgid "Failed unplugging bridge interface '%s'"
msgstr ""
-#: nova/network/linux_net.py:1521
+#: nova/network/linux_net.py:1532
#, python-format
msgid "Unplugged bridge interface '%s'"
msgstr ""
-#: nova/network/linux_net.py:1690
+#: nova/network/linux_net.py:1721
#, python-format
msgid "Starting bridge %s "
msgstr ""
-#: nova/network/linux_net.py:1698
+#: nova/network/linux_net.py:1729
#, python-format
msgid "Done starting bridge %s"
msgstr ""
-#: nova/network/linux_net.py:1718
+#: nova/network/linux_net.py:1749
#, python-format
msgid "Failed unplugging gateway interface '%s'"
msgstr ""
-#: nova/network/linux_net.py:1720
+#: nova/network/linux_net.py:1751
#, python-format
msgid "Unplugged gateway interface '%s'"
msgstr ""
@@ -5152,49 +5152,49 @@ msgstr ""
msgid "Fail to delete port %(portid)s with failure: %(exception)s"
msgstr ""
-#: nova/network/quantumv2/api.py:314
+#: nova/network/quantumv2/api.py:315
#, python-format
msgid "deallocate_for_instance() for %s"
msgstr ""
-#: nova/network/quantumv2/api.py:323
+#: nova/network/quantumv2/api.py:324
#, python-format
msgid "Failed to delete quantum port %(portid)s "
msgstr ""
-#: nova/network/quantumv2/api.py:342
+#: nova/network/quantumv2/api.py:343
#, python-format
msgid "Failed to delete quantum port %(port_id)s "
msgstr ""
-#: nova/network/quantumv2/api.py:364
+#: nova/network/quantumv2/api.py:365
#, python-format
msgid "get_instance_nw_info() for %s"
msgstr ""
-#: nova/network/quantumv2/api.py:396
+#: nova/network/quantumv2/api.py:397
#, python-format
msgid ""
"Unable to update port %(portid)s on subnet %(subnet_id)s with failure: "
"%(exception)s"
msgstr ""
-#: nova/network/quantumv2/api.py:426
+#: nova/network/quantumv2/api.py:427
#, python-format
msgid "Unable to update port %(portid)s with failure: %(exception)s"
msgstr ""
-#: nova/network/quantumv2/api.py:436
+#: nova/network/quantumv2/api.py:437
#, python-format
msgid "validate_networks() for %s"
msgstr ""
-#: nova/network/quantumv2/api.py:693
+#: nova/network/quantumv2/api.py:694
#, python-format
msgid "Multiple floating IP pools matches found for name '%s'"
msgstr ""
-#: nova/network/quantumv2/api.py:798
+#: nova/network/quantumv2/api.py:799
#, python-format
msgid "Network %(net)s for port %(port_id)s not found!"
msgstr ""
@@ -6263,12 +6263,12 @@ msgstr ""
msgid "uuid"
msgstr ""
-#: nova/tests/test_xenapi.py:884
+#: nova/tests/test_xenapi.py:897
#, python-format
msgid "Creating files in %s to simulate guest agent"
msgstr ""
-#: nova/tests/test_xenapi.py:895
+#: nova/tests/test_xenapi.py:908
#, python-format
msgid "Removing simulated guest agent files in %s"
msgstr ""
@@ -9215,7 +9215,7 @@ msgstr ""
msgid "Migrated VM to host %s"
msgstr ""
-#: nova/virt/vmwareapi/vmops.py:1050 nova/virt/xenapi/vmops.py:1316
+#: nova/virt/vmwareapi/vmops.py:1050 nova/virt/xenapi/vmops.py:1324
#, python-format
msgid "Found %(instance_count)d hung reboots older than %(timeout)d seconds"
msgstr ""
@@ -9373,19 +9373,19 @@ msgstr ""
msgid "Mountpoint %(mountpoint)s detached from instance %(instance_name)s"
msgstr ""
-#: nova/virt/xenapi/agent.py:88 nova/virt/xenapi/vmops.py:1556
+#: nova/virt/xenapi/agent.py:88 nova/virt/xenapi/vmops.py:1564
#, python-format
msgid "TIMEOUT: The call to %(method)s timed out. args=%(args)r"
msgstr ""
-#: nova/virt/xenapi/agent.py:92 nova/virt/xenapi/vmops.py:1560
+#: nova/virt/xenapi/agent.py:92 nova/virt/xenapi/vmops.py:1568
#, python-format
msgid ""
"NOT IMPLEMENTED: The call to %(method)s is not supported by the agent. "
"args=%(args)r"
msgstr ""
-#: nova/virt/xenapi/agent.py:97 nova/virt/xenapi/vmops.py:1565
+#: nova/virt/xenapi/agent.py:97 nova/virt/xenapi/vmops.py:1573
#, python-format
msgid "The call to %(method)s returned an error: %(e)s. args=%(args)r"
msgstr ""
@@ -9511,32 +9511,32 @@ msgstr ""
msgid "Got exception: %s"
msgstr ""
-#: nova/virt/xenapi/fake.py:680 nova/virt/xenapi/fake.py:784
-#: nova/virt/xenapi/fake.py:803 nova/virt/xenapi/fake.py:871
+#: nova/virt/xenapi/fake.py:687 nova/virt/xenapi/fake.py:791
+#: nova/virt/xenapi/fake.py:810 nova/virt/xenapi/fake.py:878
msgid "Raising NotImplemented"
msgstr ""
-#: nova/virt/xenapi/fake.py:682
+#: nova/virt/xenapi/fake.py:689
#, python-format
msgid "xenapi.fake does not have an implementation for %s"
msgstr ""
-#: nova/virt/xenapi/fake.py:716
+#: nova/virt/xenapi/fake.py:723
#, python-format
msgid "Calling %(localname)s %(impl)s"
msgstr ""
-#: nova/virt/xenapi/fake.py:721
+#: nova/virt/xenapi/fake.py:728
#, python-format
msgid "Calling getter %s"
msgstr ""
-#: nova/virt/xenapi/fake.py:724
+#: nova/virt/xenapi/fake.py:731
#, python-format
msgid "Calling setter %s"
msgstr ""
-#: nova/virt/xenapi/fake.py:786
+#: nova/virt/xenapi/fake.py:793
#, python-format
msgid ""
"xenapi.fake does not have an implementation for %s or it has been called "
@@ -9698,324 +9698,324 @@ msgstr ""
msgid "Unable to destroy VBD %s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:405
+#: nova/virt/xenapi/vm_utils.py:408
#, python-format
msgid "Creating %(vbd_type)s-type VBD for VM %(vm_ref)s, VDI %(vdi_ref)s ... "
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:408
+#: nova/virt/xenapi/vm_utils.py:411
#, python-format
msgid "Created VBD %(vbd_ref)s for VM %(vm_ref)s, VDI %(vdi_ref)s."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:424
+#: nova/virt/xenapi/vm_utils.py:437
#, python-format
msgid "Unable to destroy VDI %s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:456
+#: nova/virt/xenapi/vm_utils.py:469
#, python-format
msgid ""
"Created VDI %(vdi_ref)s (%(name_label)s, %(virtual_size)s, %(read_only)s)"
" on %(sr_ref)s."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:470
+#: nova/virt/xenapi/vm_utils.py:483
msgid "SR not present and could not be introduced"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:495
+#: nova/virt/xenapi/vm_utils.py:508
#, python-format
msgid "block device info: %s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:581
+#: nova/virt/xenapi/vm_utils.py:594
#, python-format
msgid "Cloned VDI %(vdi_ref)s from VDI %(vdi_to_clone_ref)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:601
+#: nova/virt/xenapi/vm_utils.py:614
#, python-format
msgid "No primary VDI found for %(vm_ref)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:614
+#: nova/virt/xenapi/vm_utils.py:627
msgid "Starting snapshot for VM"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:664
+#: nova/virt/xenapi/vm_utils.py:677
#, python-format
msgid "Destroying cached VDI '%(vdi_uuid)s'"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:911
+#: nova/virt/xenapi/vm_utils.py:930
#, python-format
msgid ""
"Fast cloning is only supported on default local SR of type ext. SR on "
"this system was found to be of type %(sr_type)s. Ignoring the cow flag."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:967
+#: nova/virt/xenapi/vm_utils.py:986
#, python-format
msgid "Unrecognized cache_images value '%s', defaulting to True"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1001
+#: nova/virt/xenapi/vm_utils.py:1020
#, python-format
msgid "Fetched VDIs of type '%(vdi_type)s' with UUID '%(vdi_uuid)s'"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1013
+#: nova/virt/xenapi/vm_utils.py:1032
#, python-format
msgid ""
"download_vhd %(image_id)s, attempt %(attempt_num)d/%(max_attempts)d, "
"params: %(params)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1026
+#: nova/virt/xenapi/vm_utils.py:1045
#, python-format
msgid "download_vhd failed: %r"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1060
+#: nova/virt/xenapi/vm_utils.py:1079
#, python-format
msgid "Invalid value '%s' for xenapi_torrent_images"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1071
+#: nova/virt/xenapi/vm_utils.py:1090
#, python-format
msgid "Asking xapi to fetch vhd image %(image_id)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1135
+#: nova/virt/xenapi/vm_utils.py:1154
#, python-format
msgid "vdi_uuid=%(cur_vdi_uuid)s vdi_size_bytes=%(vdi_size_bytes)d"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1150
+#: nova/virt/xenapi/vm_utils.py:1169
#, python-format
msgid "image_size_bytes=%(size_bytes)d, allowed_size_bytes=%(allowed_size_bytes)d"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1154
+#: nova/virt/xenapi/vm_utils.py:1173
#, python-format
msgid ""
"Image size %(size_bytes)d exceeded instance_type allowed size "
"%(allowed_size_bytes)d"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1176
+#: nova/virt/xenapi/vm_utils.py:1195
#, python-format
msgid "Fetching image %(image_id)s, type %(image_type_str)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1189
+#: nova/virt/xenapi/vm_utils.py:1208
#, python-format
msgid "Size for image %(image_id)s: %(virtual_size)d"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1198
+#: nova/virt/xenapi/vm_utils.py:1217
#, python-format
msgid ""
"Kernel/Ramdisk image is too large: %(vdi_size)d bytes, max %(max_size)d "
"bytes"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1217
+#: nova/virt/xenapi/vm_utils.py:1236
#, python-format
msgid "Copying VDI %s to /boot/guest on dom0"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1231
+#: nova/virt/xenapi/vm_utils.py:1250
#, python-format
msgid "Kernel/Ramdisk VDI %s destroyed"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1240
+#: nova/virt/xenapi/vm_utils.py:1259
msgid "Failed to fetch glance image"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1281
+#: nova/virt/xenapi/vm_utils.py:1300
#, python-format
msgid "Detected %(image_type_str)s format for image %(image_ref)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1312
+#: nova/virt/xenapi/vm_utils.py:1331
#, python-format
msgid "Looking up vdi %s for PV kernel"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1330
+#: nova/virt/xenapi/vm_utils.py:1349
#, python-format
msgid ""
"Image format is None: trying to determine PV status using pygrub; if "
"instance with vdi %s does not boot correctly, try with image metadata."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1336
+#: nova/virt/xenapi/vm_utils.py:1355
#, python-format
msgid "Unknown image format %(disk_image_type)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1367
+#: nova/virt/xenapi/vm_utils.py:1386
#, python-format
msgid "VDI %s is still available"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1463
+#: nova/virt/xenapi/vm_utils.py:1482
#, python-format
msgid "Unable to parse rrd of %(vm_uuid)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1490
+#: nova/virt/xenapi/vm_utils.py:1509
#, python-format
msgid "Re-scanning SR %s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1518
+#: nova/virt/xenapi/vm_utils.py:1537
#, python-format
msgid "Flag sr_matching_filter '%s' does not respect formatting convention"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1536
+#: nova/virt/xenapi/vm_utils.py:1555
msgid ""
"XenAPI is unable to find a Storage Repository to install guest instances "
"on. Please check your configuration and/or configure the flag "
"'sr_matching_filter'"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1549
+#: nova/virt/xenapi/vm_utils.py:1568
msgid "Cannot find SR of content-type ISO"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1557
+#: nova/virt/xenapi/vm_utils.py:1576
#, python-format
msgid "ISO: looking at SR %(sr_rec)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1559
+#: nova/virt/xenapi/vm_utils.py:1578
msgid "ISO: not iso content"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1562
+#: nova/virt/xenapi/vm_utils.py:1581
msgid "ISO: iso content_type, no 'i18n-key' key"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1565
+#: nova/virt/xenapi/vm_utils.py:1584
msgid "ISO: iso content_type, i18n-key value not 'local-storage-iso'"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1569
+#: nova/virt/xenapi/vm_utils.py:1588
msgid "ISO: SR MATCHing our criteria"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1571
+#: nova/virt/xenapi/vm_utils.py:1590
msgid "ISO: ISO, looking to see if it is host local"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1574
+#: nova/virt/xenapi/vm_utils.py:1593
#, python-format
msgid "ISO: PBD %(pbd_ref)s disappeared"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1577
+#: nova/virt/xenapi/vm_utils.py:1596
#, python-format
msgid "ISO: PBD matching, want %(pbd_rec)s, have %(host)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1580
+#: nova/virt/xenapi/vm_utils.py:1599
msgid "ISO: SR with local PBD"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1602
+#: nova/virt/xenapi/vm_utils.py:1621
#, python-format
msgid ""
"Unable to obtain RRD XML for VM %(vm_uuid)s with server details: "
"%(server)s."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1618
+#: nova/virt/xenapi/vm_utils.py:1637
#, python-format
msgid "Unable to obtain RRD XML updates with server details: %(server)s."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1672
+#: nova/virt/xenapi/vm_utils.py:1691
#, python-format
msgid "Invalid statistics data from Xenserver: %s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1732
+#: nova/virt/xenapi/vm_utils.py:1751
#, python-format
msgid "VHD %(vdi_uuid)s has parent %(parent_uuid)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1819
+#: nova/virt/xenapi/vm_utils.py:1838
#, 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:1829
+#: nova/virt/xenapi/vm_utils.py:1848
#, python-format
msgid "VHD coalesce attempts exceeded (%(max_attempts)d), giving up..."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1864
+#: nova/virt/xenapi/vm_utils.py:1883
#, python-format
msgid "Timeout waiting for device %s to be created"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1884
+#: nova/virt/xenapi/vm_utils.py:1903
#, python-format
msgid "Disconnecting stale VDI %s from compute domU"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1897
+#: nova/virt/xenapi/vm_utils.py:1916
#, python-format
msgid "Plugging VBD %s ... "
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1900
+#: nova/virt/xenapi/vm_utils.py:1919
#, python-format
msgid "Plugging VBD %s done."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1902
+#: nova/virt/xenapi/vm_utils.py:1921
#, python-format
msgid "VBD %(vbd_ref)s plugged as %(orig_dev)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1905
+#: nova/virt/xenapi/vm_utils.py:1924
#, python-format
msgid "VBD %(vbd_ref)s plugged into wrong dev, remapping to %(dev)s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1910
+#: nova/virt/xenapi/vm_utils.py:1929
#, python-format
msgid "Destroying VBD for VDI %s ... "
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1918
+#: nova/virt/xenapi/vm_utils.py:1937
#, python-format
msgid "Destroying VBD for VDI %s done."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1945
+#: nova/virt/xenapi/vm_utils.py:1964
#, python-format
msgid "Running pygrub against %s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1953
+#: nova/virt/xenapi/vm_utils.py:1972
#, python-format
msgid "Found Xen kernel %s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1955
+#: nova/virt/xenapi/vm_utils.py:1974
msgid "No Xen kernel found. Booting HVM."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1957
+#: nova/virt/xenapi/vm_utils.py:1976
msgid ""
"Error while executing pygrub! Please, ensure the binary is installed "
"correctly, and available in your PATH; on some Linux distros, pygrub may "
@@ -10023,251 +10023,247 @@ msgid ""
"mode."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1974
+#: nova/virt/xenapi/vm_utils.py:1993
msgid "Partitions:"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:1980
+#: nova/virt/xenapi/vm_utils.py:1999
#, python-format
msgid " %(num)s: %(ptype)s %(size)d sectors"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:2005
+#: nova/virt/xenapi/vm_utils.py:2024
#, python-format
msgid ""
"Writing partition table %(primary_first)d %(primary_last)d to "
"%(dev_path)s..."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:2018
+#: nova/virt/xenapi/vm_utils.py:2037
#, python-format
msgid "Writing partition table %s done."
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:2072
+#: nova/virt/xenapi/vm_utils.py:2091
#, python-format
msgid ""
"Starting sparse_copy src=%(src_path)s dst=%(dst_path)s "
"virtual_size=%(virtual_size)d block_size=%(block_size)d"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:2105
+#: nova/virt/xenapi/vm_utils.py:2124
#, python-format
msgid ""
"Finished sparse_copy in %(duration).2f secs, %(compression_pct).2f%% "
"reduction in size"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:2157
+#: nova/virt/xenapi/vm_utils.py:2176
msgid "Manipulating interface files directly"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:2166
+#: nova/virt/xenapi/vm_utils.py:2185
#, python-format
msgid "Failed to mount filesystem (expected for non-linux instances): %s"
msgstr ""
-#: nova/virt/xenapi/vm_utils.py:2278
+#: nova/virt/xenapi/vm_utils.py:2297
msgid "This domU must be running on the host specified by xenapi_connection_url"
msgstr ""
-#: nova/virt/xenapi/vmops.py:134 nova/virt/xenapi/vmops.py:784
+#: nova/virt/xenapi/vmops.py:139 nova/virt/xenapi/vmops.py:792
#, python-format
msgid "Updating progress to %(progress)d"
msgstr ""
-#: nova/virt/xenapi/vmops.py:169
+#: nova/virt/xenapi/vmops.py:174
#, python-format
msgid "Importing image upload handler: %s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:182
+#: nova/virt/xenapi/vmops.py:187
msgid "Error: Agent is disabled"
msgstr ""
-#: nova/virt/xenapi/vmops.py:290
+#: nova/virt/xenapi/vmops.py:295
msgid "Starting instance"
msgstr ""
-#: nova/virt/xenapi/vmops.py:376
+#: nova/virt/xenapi/vmops.py:381
msgid "Removing kernel/ramdisk files from dom0"
msgstr ""
-#: nova/virt/xenapi/vmops.py:449
+#: nova/virt/xenapi/vmops.py:454
#, python-format
msgid "Block device information present: %s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:480
+#: nova/virt/xenapi/vmops.py:485
msgid "Failed to spawn, rolling back"
msgstr ""
-#: nova/virt/xenapi/vmops.py:559
-msgid "Detected ISO image type, creating blank VM for install"
-msgstr ""
-
-#: nova/virt/xenapi/vmops.py:576
+#: nova/virt/xenapi/vmops.py:584
msgid "Auto configuring disk, attempting to resize partition..."
msgstr ""
-#: nova/virt/xenapi/vmops.py:622
+#: nova/virt/xenapi/vmops.py:630
msgid "Starting VM"
msgstr ""
-#: nova/virt/xenapi/vmops.py:628
+#: nova/virt/xenapi/vmops.py:636
msgid "Waiting for instance state to become running"
msgstr ""
-#: nova/virt/xenapi/vmops.py:642
+#: nova/virt/xenapi/vmops.py:650
#, python-format
msgid ""
"Latest agent build for %(hypervisor)s/%(os)s/%(architecture)s is "
"%(version)s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:645
+#: nova/virt/xenapi/vmops.py:653
#, python-format
msgid "No agent build found for %(hypervisor)s/%(os)s/%(architecture)s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:656
+#: nova/virt/xenapi/vmops.py:664
#, python-format
msgid "Instance agent version: %s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:687
+#: nova/virt/xenapi/vmops.py:695
msgid "Setting VCPU weight"
msgstr ""
-#: nova/virt/xenapi/vmops.py:695
+#: nova/virt/xenapi/vmops.py:703
#, python-format
msgid "Could not find VM with name %s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:753
+#: nova/virt/xenapi/vmops.py:761
msgid "Finished snapshot and upload for VM"
msgstr ""
-#: nova/virt/xenapi/vmops.py:757
+#: nova/virt/xenapi/vmops.py:765
#, python-format
msgid "Migrating VHD '%(vdi_uuid)s' with seq_num %(seq_num)d"
msgstr ""
-#: nova/virt/xenapi/vmops.py:765
+#: nova/virt/xenapi/vmops.py:773
msgid "Failed to transfer vhd to new host"
msgstr ""
-#: nova/virt/xenapi/vmops.py:802
+#: nova/virt/xenapi/vmops.py:810
#, python-format
msgid "Resizing down VDI %(vdi_uuid)s from %(old_gb)dGB to %(new_gb)dGB"
msgstr ""
-#: nova/virt/xenapi/vmops.py:808 nova/virt/xenapi/vmops.py:858
+#: nova/virt/xenapi/vmops.py:816 nova/virt/xenapi/vmops.py:866
msgid "Clean shutdown did not complete successfully, trying hard shutdown."
msgstr ""
-#: nova/virt/xenapi/vmops.py:887
+#: nova/virt/xenapi/vmops.py:895
msgid "Resize down not allowed without auto_disk_config"
msgstr ""
-#: nova/virt/xenapi/vmops.py:932
+#: nova/virt/xenapi/vmops.py:940
#, python-format
msgid "Resizing up VDI %(vdi_uuid)s from %(old_gb)dGB to %(new_gb)dGB"
msgstr ""
-#: nova/virt/xenapi/vmops.py:937
+#: nova/virt/xenapi/vmops.py:945
msgid "Resize complete"
msgstr ""
-#: nova/virt/xenapi/vmops.py:981
+#: nova/virt/xenapi/vmops.py:989
msgid "Starting halted instance found during reboot"
msgstr ""
-#: nova/virt/xenapi/vmops.py:987
+#: nova/virt/xenapi/vmops.py:995
msgid ""
"Reboot failed due to bad volumes, detaching bad volumes and starting "
"halted instance"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1081
+#: nova/virt/xenapi/vmops.py:1089
msgid "Unable to find root VBD/VDI for VM"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1085
+#: nova/virt/xenapi/vmops.py:1093
msgid "Destroying VDIs"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1112
+#: nova/virt/xenapi/vmops.py:1120
msgid "Using RAW or VHD, skipping kernel and ramdisk deletion"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1119
+#: nova/virt/xenapi/vmops.py:1127
msgid "instance has a kernel or ramdisk but not both"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1126
+#: nova/virt/xenapi/vmops.py:1134
msgid "kernel/ramdisk files removed"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1153
+#: nova/virt/xenapi/vmops.py:1161
msgid "Destroying VM"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1182
+#: nova/virt/xenapi/vmops.py:1190
msgid "VM is not present, skipping destroy..."
msgstr ""
-#: nova/virt/xenapi/vmops.py:1233
+#: nova/virt/xenapi/vmops.py:1241
#, python-format
msgid "Instance is already in Rescue Mode: %s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1267
+#: nova/virt/xenapi/vmops.py:1275
msgid "VM is not present, skipping soft delete..."
msgstr ""
-#: nova/virt/xenapi/vmops.py:1320
+#: nova/virt/xenapi/vmops.py:1328
msgid "Automatically hard rebooting"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1460
+#: nova/virt/xenapi/vmops.py:1468
msgid "Injecting network info to xenstore"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1479
+#: nova/virt/xenapi/vmops.py:1487
msgid "Creating vifs"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1488
+#: nova/virt/xenapi/vmops.py:1496
#, python-format
msgid "Creating VIF for network %(network_ref)s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1491
+#: nova/virt/xenapi/vmops.py:1499
#, python-format
msgid "Created VIF %(vif_ref)s, network %(network_ref)s"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1519
+#: nova/virt/xenapi/vmops.py:1527
msgid "Injecting hostname to xenstore"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1615
+#: nova/virt/xenapi/vmops.py:1623
#, python-format
msgid ""
"Destination host:%(hostname)s must be in the same aggregate as the source"
" server"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1647
+#: nova/virt/xenapi/vmops.py:1655
msgid "Migrate Receive failed"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1695
+#: nova/virt/xenapi/vmops.py:1703
msgid "VM.assert_can_migratefailed"
msgstr ""
-#: nova/virt/xenapi/vmops.py:1732
+#: nova/virt/xenapi/vmops.py:1740
msgid "Migrate Send failed"
msgstr ""
diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py
index a56bbfe25..4a63f275d 100644
--- a/nova/network/linux_net.py
+++ b/nova/network/linux_net.py
@@ -1019,7 +1019,6 @@ def restart_dhcp(context, dev, network_ref):
'--strict-order',
'--bind-interfaces',
'--conf-file=%s' % CONF.dnsmasq_config_file,
- '--domain=\'%s\'' % CONF.dhcp_domain,
'--pid-file=%s' % _dhcp_file(dev, 'pid'),
'--listen-address=%s' % network_ref['dhcp_server'],
'--except-interface=lo',
@@ -1033,6 +1032,11 @@ def restart_dhcp(context, dev, network_ref):
'--dhcp-script=%s' % CONF.dhcpbridge,
'--leasefile-ro']
+ # dnsmasq currently gives an error for an empty domain,
+ # rather than ignoring. So only specify it if defined.
+ if CONF.dhcp_domain:
+ cmd.append('--domain=%s' % CONF.dhcp_domain)
+
dns_servers = set(CONF.dns_server)
if CONF.use_network_dns_servers:
if network_ref.get('dns1'):
@@ -1513,14 +1517,17 @@ class LinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
for rule in get_gateway_rules(bridge):
ipv4_filter.remove_rule(*rule)
else:
- ipv4_filter.remove_rule('FORWARD',
- ('--in-interface %s -j %s'
- % (bridge,
- CONF.iptables_drop_action)))
- ipv4_filter.remove_rule('FORWARD',
- ('--out-interface %s -j %s'
- % (bridge,
- CONF.iptables_drop_action)))
+ drop_actions = ['DROP']
+ if CONF.iptables_drop_action != 'DROP':
+ drop_actions.append(CONF.iptables_drop_action)
+
+ for drop_action in drop_actions:
+ ipv4_filter.remove_rule('FORWARD',
+ ('--in-interface %s -j %s'
+ % (bridge, drop_action)))
+ ipv4_filter.remove_rule('FORWARD',
+ ('--out-interface %s -j %s'
+ % (bridge, drop_action)))
try:
utils.execute('ip', 'link', 'delete', bridge, run_as_root=True,
check_exit_code=[0, 2, 254])
@@ -1591,27 +1598,34 @@ def remove_isolate_dhcp_address(interface, address):
# NOTE(vish): the above is not possible with iptables/arptables
# block dhcp broadcast traffic across the interface
ipv4_filter = iptables_manager.ipv4['filter']
- ipv4_filter.remove_rule('FORWARD',
- ('-m physdev --physdev-in %s -d 255.255.255.255 '
- '-p udp --dport 67 -j %s'
- % (interface, CONF.iptables_drop_action)),
- top=True)
- ipv4_filter.remove_rule('FORWARD',
- ('-m physdev --physdev-out %s -d 255.255.255.255 '
- '-p udp --dport 67 -j %s'
- % (interface, CONF.iptables_drop_action)),
- top=True)
- # block ip traffic to address across the interface
- ipv4_filter.remove_rule('FORWARD',
- ('-m physdev --physdev-in %s -d %s -j %s'
- % (interface, address,
- CONF.iptables_drop_action)),
- top=True)
- ipv4_filter.remove_rule('FORWARD',
- ('-m physdev --physdev-out %s -s %s -j %s'
- % (interface, address,
- CONF.iptables_drop_action)),
- top=True)
+
+ drop_actions = ['DROP']
+ if CONF.iptables_drop_action != 'DROP':
+ drop_actions.append(CONF.iptables_drop_action)
+
+ for drop_action in drop_actions:
+ ipv4_filter.remove_rule('FORWARD',
+ ('-m physdev --physdev-in %s '
+ '-d 255.255.255.255 '
+ '-p udp --dport 67 -j %s'
+ % (interface, drop_action)),
+ top=True)
+ ipv4_filter.remove_rule('FORWARD',
+ ('-m physdev --physdev-out %s '
+ '-d 255.255.255.255 '
+ '-p udp --dport 67 -j %s'
+ % (interface, drop_action)),
+ top=True)
+
+ # block ip traffic to address across the interface
+ ipv4_filter.remove_rule('FORWARD',
+ ('-m physdev --physdev-in %s -d %s -j %s'
+ % (interface, address, drop_action)),
+ top=True)
+ ipv4_filter.remove_rule('FORWARD',
+ ('-m physdev --physdev-out %s -s %s -j %s'
+ % (interface, address, drop_action)),
+ top=True)
def get_gateway_rules(bridge):
diff --git a/nova/network/manager.py b/nova/network/manager.py
index b9c8efe44..ac413135a 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -1115,13 +1115,13 @@ class NetworkManager(manager.Manager):
subnets_v4.append(next_subnet)
subnet = next_subnet
else:
- raise ValueError(_('cidr already in use'))
+ raise exception.CidrConflict(_('cidr already in use'))
for used_subnet in used_subnets:
if subnet in used_subnet:
msg = _('requested cidr (%(cidr)s) conflicts with '
'existing supernet (%(super)s)')
- raise ValueError(msg % {'cidr': subnet,
- 'super': used_subnet})
+ raise exception.CidrConflict(
+ msg % {'cidr': subnet, 'super': used_subnet})
if used_subnet in subnet:
next_subnet = find_next(subnet)
if next_subnet:
@@ -1132,8 +1132,8 @@ class NetworkManager(manager.Manager):
msg = _('requested cidr (%(cidr)s) conflicts '
'with existing smaller cidr '
'(%(smaller)s)')
- raise ValueError(msg % {'cidr': subnet,
- 'smaller': used_subnet})
+ raise exception.CidrConflict(
+ msg % {'cidr': subnet, 'smaller': used_subnet})
networks = []
subnets = itertools.izip_longest(subnets_v4, subnets_v6)
diff --git a/nova/network/security_group/quantum_driver.py b/nova/network/security_group/quantum_driver.py
index 5a24a74ab..aecafe8d1 100644
--- a/nova/network/security_group/quantum_driver.py
+++ b/nova/network/security_group/quantum_driver.py
@@ -23,7 +23,6 @@ from quantumclient.quantum import v2_0 as quantumv20
from webob import exc
from nova.compute import api as compute_api
-from nova import context
from nova import exception
from nova.network import quantumv2
from nova.network.security_group import security_group_base
@@ -246,14 +245,43 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
raise e
return self._convert_to_nova_security_group_rule_format(rule)
- def get_instance_security_groups(self, req, instance_id,
+ def get_instances_security_groups_bindings(self, context):
+ """Returns a dict(instance_id, [security_groups]) to allow obtaining
+ all of the instances and their security groups in one shot."""
+ quantum = quantumv2.get_client(context)
+ ports = quantum.list_ports().get('ports')
+ security_groups = quantum.list_security_groups().get('security_groups')
+ security_group_lookup = {}
+ instances_security_group_bindings = {}
+ for security_group in security_groups:
+ security_group_lookup[security_group['id']] = security_group
+
+ for port in ports:
+ for port_security_group in port.get('security_groups', []):
+ try:
+ sg = security_group_lookup[port_security_group]
+ # name is optional in quantum so if not specified return id
+ if sg.get('name'):
+ sg_entry = {'name': sg['name']}
+ else:
+ sg_entry = {'name': sg['id']}
+ instances_security_group_bindings.setdefault(
+ port['device_id'], []).append(sg_entry)
+ except KeyError:
+ # This should only happen due to a race condition
+ # if the security group on a port was deleted after the
+ # ports were returned. We pass since this security
+ # group is no longer on the port.
+ pass
+ return instances_security_group_bindings
+
+ def get_instance_security_groups(self, context, instance_id,
instance_uuid=None, detailed=False):
"""Returns the security groups that are associated with an instance.
If detailed is True then it also returns the full details of the
security groups associated with an instance.
"""
- admin_context = context.get_admin_context()
- quantum = quantumv2.get_client(admin_context)
+ quantum = quantumv2.get_client(context)
if instance_uuid:
params = {'device_id': instance_uuid}
else:
@@ -281,7 +309,7 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
name = security_group['id']
ret.append({'name': name})
except KeyError:
- # If this should only happen due to a race condition
+ # This should only happen due to a race condition
# if the security group on a port was deleted after the
# ports were returned. We pass since this security
# group is no longer on the port.
diff --git a/nova/network/security_group/security_group_base.py b/nova/network/security_group/security_group_base.py
index 4a82bd881..3babf4b00 100644
--- a/nova/network/security_group/security_group_base.py
+++ b/nova/network/security_group/security_group_base.py
@@ -204,7 +204,8 @@ class SecurityGroupBase(object):
def get_rule(self, context, id):
raise NotImplementedError()
- def get_instance_security_groups(self, req, instance_id):
+ def get_instance_security_groups(self, context, instance_id,
+ instance_uuid=None, detailed=False):
raise NotImplementedError()
def add_to_instance(self, context, instance, security_group_name):
diff --git a/nova/openstack/common/db/sqlalchemy/session.py b/nova/openstack/common/db/sqlalchemy/session.py
index cf6713581..010254e7a 100644
--- a/nova/openstack/common/db/sqlalchemy/session.py
+++ b/nova/openstack/common/db/sqlalchemy/session.py
@@ -264,7 +264,8 @@ sql_opts = [
os.path.abspath(os.path.join(os.path.dirname(__file__),
'../', '$sqlite_db')),
help='The SQLAlchemy connection string used to connect to the '
- 'database'),
+ 'database',
+ secret=True),
cfg.StrOpt('sqlite_db',
default='nova.sqlite',
help='the filename to use with sqlite'),
diff --git a/nova/openstack/common/db/sqlalchemy/utils.py b/nova/openstack/common/db/sqlalchemy/utils.py
index 6a9cb846f..3f5ae737a 100644
--- a/nova/openstack/common/db/sqlalchemy/utils.py
+++ b/nova/openstack/common/db/sqlalchemy/utils.py
@@ -2,7 +2,7 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2010-2011 OpenStack Foundation
+# Copyright 2010-2011 OpenStack Foundation.
# Copyright 2012 Justin Santa Barbara
# All Rights Reserved.
#
diff --git a/nova/openstack/common/gettextutils.py b/nova/openstack/common/gettextutils.py
index d52309e62..b9993b491 100644
--- a/nova/openstack/common/gettextutils.py
+++ b/nova/openstack/common/gettextutils.py
@@ -26,7 +26,7 @@ Usual usage in an openstack.common module:
import gettext
-t = gettext.translation('openstack-common', 'locale', fallback=True)
+t = gettext.translation('nova', 'locale', fallback=True)
def _(msg):
diff --git a/nova/openstack/common/rpc/impl_qpid.py b/nova/openstack/common/rpc/impl_qpid.py
index fd4b25e7f..d3cc12d3c 100644
--- a/nova/openstack/common/rpc/impl_qpid.py
+++ b/nova/openstack/common/rpc/impl_qpid.py
@@ -40,8 +40,8 @@ qpid_opts = [
cfg.StrOpt('qpid_hostname',
default='localhost',
help='Qpid broker hostname'),
- cfg.StrOpt('qpid_port',
- default='5672',
+ cfg.IntOpt('qpid_port',
+ default=5672,
help='Qpid broker port'),
cfg.ListOpt('qpid_hosts',
default=['$qpid_hostname:$qpid_port'],
diff --git a/nova/openstack/common/rpc/matchmaker.py b/nova/openstack/common/rpc/matchmaker.py
index e4862396a..dcee752b2 100644
--- a/nova/openstack/common/rpc/matchmaker.py
+++ b/nova/openstack/common/rpc/matchmaker.py
@@ -35,10 +35,10 @@ matchmaker_opts = [
default='/etc/nova/matchmaker_ring.json',
help='Matchmaker ring file (JSON)'),
cfg.IntOpt('matchmaker_heartbeat_freq',
- default='300',
+ default=300,
help='Heartbeat frequency'),
cfg.IntOpt('matchmaker_heartbeat_ttl',
- default='600',
+ default=600,
help='Heartbeat time-to-live.'),
]
diff --git a/nova/quota.py b/nova/quota.py
index 3903a6add..8aaa3ed31 100644
--- a/nova/quota.py
+++ b/nova/quota.py
@@ -44,7 +44,7 @@ quota_opts = [
default=10,
help='number of floating ips allowed per project'),
cfg.IntOpt('quota_fixed_ips',
- default=10,
+ default=-1,
help=('number of fixed ips allowed per project (this should be '
'at least the number of instances allowed)')),
cfg.IntOpt('quota_metadata_items',
diff --git a/nova/tests/api/openstack/compute/contrib/test_flavor_access.py b/nova/tests/api/openstack/compute/contrib/test_flavor_access.py
index fc5543409..b3564dede 100644
--- a/nova/tests/api/openstack/compute/contrib/test_flavor_access.py
+++ b/nova/tests/api/openstack/compute/contrib/test_flavor_access.py
@@ -98,6 +98,20 @@ def fake_get_all_types(context, inactive=0, filters=None):
class FakeRequest(object):
environ = {"nova.context": context.get_admin_context()}
+ def get_db_flavor(self, flavor_id):
+ return INSTANCE_TYPES[flavor_id]
+
+
+class FakeResponse(object):
+ obj = {'flavor': {'id': '0'},
+ 'flavors': [
+ {'id': '0'},
+ {'id': '2'}]
+ }
+
+ def attach(self, **kwargs):
+ pass
+
class FlavorAccessTest(test.TestCase):
def setUp(self):
@@ -209,6 +223,28 @@ class FlavorAccessTest(test.TestCase):
result = self.flavor_controller.index(req)
self._verify_flavor_list(result['flavors'], expected['flavors'])
+ def test_show(self):
+ resp = FakeResponse()
+ self.flavor_action_controller.show(self.req, resp, '0')
+ self.assertEqual({'id': '0', 'os-flavor-access:is_public': True},
+ resp.obj['flavor'])
+ self.flavor_action_controller.show(self.req, resp, '2')
+ self.assertEqual({'id': '0', 'os-flavor-access:is_public': False},
+ resp.obj['flavor'])
+
+ def test_detail(self):
+ resp = FakeResponse()
+ self.flavor_action_controller.detail(self.req, resp)
+ self.assertEqual([{'id': '0', 'os-flavor-access:is_public': True},
+ {'id': '2', 'os-flavor-access:is_public': False}],
+ resp.obj['flavors'])
+
+ def test_create(self):
+ resp = FakeResponse()
+ self.flavor_action_controller.create(self.req, {}, resp)
+ self.assertEqual({'id': '0', 'os-flavor-access:is_public': True},
+ resp.obj['flavor'])
+
def test_add_tenant_access(self):
def stub_add_instance_type_access(flavorid, projectid, ctxt=None):
self.assertEqual('3', flavorid, "flavorid")
diff --git a/nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py b/nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py
index 98526bdad..94bc36b1f 100644
--- a/nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py
+++ b/nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py
@@ -31,6 +31,7 @@ import nova.db
from nova import exception
from nova.network import quantumv2
from nova.network.quantumv2 import api as quantum_api
+from nova.network.security_group import quantum_driver
from nova.openstack.common import jsonutils
from nova import test
from nova.tests.api.openstack.compute.contrib import test_security_groups
@@ -129,7 +130,7 @@ class TestQuantumSecurityGroups(
net = self._create_network()
self._create_port(
network_id=net['network']['id'], security_groups=[sg['id']],
- device_id=test_security_groups.FAKE_UUID)
+ device_id=test_security_groups.FAKE_UUID1)
expected = [{'rules': [], 'tenant_id': 'fake_tenant', 'id': sg['id'],
'name': 'test', 'description': 'test-description'}]
self.stubs.Set(nova.db, 'instance_get',
@@ -137,9 +138,9 @@ class TestQuantumSecurityGroups(
self.stubs.Set(nova.db, 'instance_get_by_uuid',
test_security_groups.return_server_by_uuid)
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s/os-security-groups'
- % test_security_groups.FAKE_UUID)
+ % test_security_groups.FAKE_UUID1)
res_dict = self.server_controller.index(
- req, test_security_groups.FAKE_UUID)['security_groups']
+ req, test_security_groups.FAKE_UUID1)['security_groups']
self.assertEquals(expected, res_dict)
def test_get_security_group_by_id(self):
@@ -191,7 +192,7 @@ class TestQuantumSecurityGroups(
net = self._create_network()
self._create_port(
network_id=net['network']['id'], security_groups=[sg['id']],
- device_id=test_security_groups.FAKE_UUID)
+ device_id=test_security_groups.FAKE_UUID1)
self.stubs.Set(nova.db, 'instance_get',
test_security_groups.return_server)
@@ -228,7 +229,7 @@ class TestQuantumSecurityGroups(
net = self._create_network()
self._create_port(
network_id=net['network']['id'], security_groups=[sg['id']],
- device_id=test_security_groups.FAKE_UUID)
+ device_id=test_security_groups.FAKE_UUID1)
self.stubs.Set(nova.db, 'instance_get',
test_security_groups.return_server)
@@ -239,6 +240,34 @@ class TestQuantumSecurityGroups(
req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action')
self.manager._removeSecurityGroup(req, '1', body)
+ def test_get_instances_security_groups_bindings(self):
+ sg1 = self._create_sg_template(name='test1').get('security_group')
+ sg2 = self._create_sg_template(name='test2').get('security_group')
+ # test name='' is replaced with id
+ sg3 = self._create_sg_template(name='').get('security_group')
+ net = self._create_network()
+ self._create_port(
+ network_id=net['network']['id'], security_groups=[sg1['id'],
+ sg2['id']],
+ device_id=test_security_groups.FAKE_UUID1)
+ self._create_port(
+ network_id=net['network']['id'], security_groups=[sg2['id'],
+ sg3['id']],
+ device_id=test_security_groups.FAKE_UUID2)
+ expected = {test_security_groups.FAKE_UUID1: [{'name': sg1['name']},
+ {'name': sg2['name']}],
+ test_security_groups.FAKE_UUID2: [{'name': sg2['name']},
+ {'name': sg3['id']}]}
+ self.stubs.Set(nova.db, 'instance_get',
+ test_security_groups.return_server)
+ self.stubs.Set(nova.db, 'instance_get_by_uuid',
+ test_security_groups.return_server_by_uuid)
+ security_group_api = self.controller.security_group_api
+ bindings = (
+ security_group_api.get_instances_security_groups_bindings(
+ context.get_admin_context()))
+ self.assertEquals(bindings, expected)
+
class TestQuantumSecurityGroupRulesTestCase(TestQuantumSecurityGroupsTestCase):
def setUp(self):
@@ -323,8 +352,14 @@ class TestQuantumSecurityGroupsOutputTest(TestQuantumSecurityGroupsTestCase):
self.controller = security_groups.SecurityGroupController()
self.stubs.Set(compute.api.API, 'get',
test_security_groups.fake_compute_get)
+ self.stubs.Set(compute.api.API, 'get_all',
+ test_security_groups.fake_compute_get_all)
self.stubs.Set(compute.api.API, 'create',
test_security_groups.fake_compute_create)
+ self.stubs.Set(quantum_driver.SecurityGroupAPI,
+ 'get_instances_security_groups_bindings',
+ (test_security_groups.
+ fake_get_instances_security_groups_bindings))
self.flags(
osapi_compute_extension=[
'nova.api.openstack.compute.contrib.select_extensions'],
@@ -371,6 +406,16 @@ class TestQuantumSecurityGroupsOutputTest(TestQuantumSecurityGroupsTestCase):
name = 'fake-2-%s' % i
self.assertEqual(group.get('name'), name)
+ def test_create_server_get_default_security_group(self):
+ url = '/v2/fake/servers'
+ image_uuid = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
+ server = dict(name='server_test', imageRef=image_uuid, flavorRef=2)
+ res = self._make_request(url, {'server': server})
+ self.assertEqual(res.status_int, 202)
+ server = self._get_server(res.body)
+ group = self._get_groups(server)[0]
+ self.assertEquals(group.get('name'), 'default')
+
def test_show(self):
url = '/v2/fake/servers'
image_uuid = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
@@ -629,7 +674,6 @@ class MockClient(object):
for port in self._fake_ports.values():
if device_id:
if device_id == port['device_id']:
- print port
ret.append(port)
else:
ret.append(port)
diff --git a/nova/tests/api/openstack/compute/contrib/test_quota_classes.py b/nova/tests/api/openstack/compute/contrib/test_quota_classes.py
index 8286661a0..c4f79118e 100644
--- a/nova/tests/api/openstack/compute/contrib/test_quota_classes.py
+++ b/nova/tests/api/openstack/compute/contrib/test_quota_classes.py
@@ -25,7 +25,7 @@ from nova.tests.api.openstack import fakes
def quota_set(class_name):
return {'quota_class_set': {'id': class_name, 'metadata_items': 128,
'ram': 51200, 'floating_ips': 10,
- 'fixed_ips': 10, 'instances': 10,
+ 'fixed_ips': -1, 'instances': 10,
'injected_files': 5, 'cores': 20,
'injected_file_content_bytes': 10240,
'security_groups': 10,
@@ -45,7 +45,7 @@ class QuotaClassSetsTest(test.TestCase):
'cores': 20,
'ram': 51200,
'floating_ips': 10,
- 'fixed_ips': 10,
+ 'fixed_ips': -1,
'metadata_items': 128,
'injected_files': 5,
'injected_file_path_bytes': 255,
@@ -64,7 +64,7 @@ class QuotaClassSetsTest(test.TestCase):
self.assertEqual(qs['cores'], 20)
self.assertEqual(qs['ram'], 51200)
self.assertEqual(qs['floating_ips'], 10)
- self.assertEqual(qs['fixed_ips'], 10)
+ self.assertEqual(qs['fixed_ips'], -1)
self.assertEqual(qs['metadata_items'], 128)
self.assertEqual(qs['injected_files'], 5)
self.assertEqual(qs['injected_file_path_bytes'], 255)
@@ -90,7 +90,7 @@ class QuotaClassSetsTest(test.TestCase):
def test_quotas_update_as_admin(self):
body = {'quota_class_set': {'instances': 50, 'cores': 50,
'ram': 51200, 'floating_ips': 10,
- 'fixed_ips': 10, 'metadata_items': 128,
+ 'fixed_ips': -1, 'metadata_items': 128,
'injected_files': 5,
'injected_file_content_bytes': 10240,
'injected_file_path_bytes': 255,
@@ -108,7 +108,7 @@ class QuotaClassSetsTest(test.TestCase):
def test_quotas_update_as_user(self):
body = {'quota_class_set': {'instances': 50, 'cores': 50,
'ram': 51200, 'floating_ips': 10,
- 'fixed_ips': 10, 'metadata_items': 128,
+ 'fixed_ips': -1, 'metadata_items': 128,
'injected_files': 5,
'injected_file_content_bytes': 10240,
'security_groups': 10,
@@ -136,7 +136,7 @@ class QuotaTemplateXMLSerializerTest(test.TestCase):
injected_file_content_bytes=20,
ram=50,
floating_ips=60,
- fixed_ips=10,
+ fixed_ips=-1,
instances=70,
injected_files=80,
security_groups=10,
@@ -161,7 +161,7 @@ class QuotaTemplateXMLSerializerTest(test.TestCase):
injected_file_content_bytes='20',
ram='50',
floating_ips='60',
- fixed_ips='10',
+ fixed_ips='-1',
instances='70',
injected_files='80',
security_groups='10',
@@ -175,7 +175,7 @@ class QuotaTemplateXMLSerializerTest(test.TestCase):
'</injected_file_content_bytes>'
'<ram>50</ram>'
'<floating_ips>60</floating_ips>'
- '<fixed_ips>10</fixed_ips>'
+ '<fixed_ips>-1</fixed_ips>'
'<instances>70</instances>'
'<injected_files>80</injected_files>'
'<cores>90</cores>'
diff --git a/nova/tests/api/openstack/compute/contrib/test_quotas.py b/nova/tests/api/openstack/compute/contrib/test_quotas.py
index 1ff7e60ab..c95c41614 100644
--- a/nova/tests/api/openstack/compute/contrib/test_quotas.py
+++ b/nova/tests/api/openstack/compute/contrib/test_quotas.py
@@ -26,7 +26,7 @@ from nova.tests.api.openstack import fakes
def quota_set(id):
return {'quota_set': {'id': id, 'metadata_items': 128,
- 'ram': 51200, 'floating_ips': 10, 'fixed_ips': 10,
+ 'ram': 51200, 'floating_ips': 10, 'fixed_ips': -1,
'instances': 10, 'injected_files': 5, 'cores': 20,
'injected_file_content_bytes': 10240,
'security_groups': 10, 'security_group_rules': 20,
@@ -45,7 +45,7 @@ class QuotaSetsTest(test.TestCase):
'cores': 20,
'ram': 51200,
'floating_ips': 10,
- 'fixed_ips': 10,
+ 'fixed_ips': -1,
'metadata_items': 128,
'injected_files': 5,
'injected_file_path_bytes': 255,
@@ -62,7 +62,7 @@ class QuotaSetsTest(test.TestCase):
self.assertEqual(qs['cores'], 20)
self.assertEqual(qs['ram'], 51200)
self.assertEqual(qs['floating_ips'], 10)
- self.assertEqual(qs['fixed_ips'], 10)
+ self.assertEqual(qs['fixed_ips'], -1)
self.assertEqual(qs['metadata_items'], 128)
self.assertEqual(qs['injected_files'], 5)
self.assertEqual(qs['injected_file_path_bytes'], 255)
@@ -83,7 +83,7 @@ class QuotaSetsTest(test.TestCase):
'cores': 20,
'ram': 51200,
'floating_ips': 10,
- 'fixed_ips': 10,
+ 'fixed_ips': -1,
'metadata_items': 128,
'injected_files': 5,
'injected_file_path_bytes': 255,
@@ -109,13 +109,13 @@ class QuotaSetsTest(test.TestCase):
def test_quotas_update_as_admin(self):
body = {'quota_set': {'instances': 50, 'cores': 50,
'ram': 51200, 'floating_ips': 10,
- 'fixed_ips': 10, 'metadata_items': 128,
+ 'fixed_ips': -1, 'metadata_items': 128,
'injected_files': 5,
'injected_file_content_bytes': 10240,
'injected_file_path_bytes': 255,
'security_groups': 10,
'security_group_rules': 20,
- 'key_pairs': 100, 'fixed_ips': 10}}
+ 'key_pairs': 100, 'fixed_ips': -1}}
req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/update_me',
use_admin_context=True)
@@ -126,7 +126,7 @@ class QuotaSetsTest(test.TestCase):
def test_quotas_update_as_user(self):
body = {'quota_set': {'instances': 50, 'cores': 50,
'ram': 51200, 'floating_ips': 10,
- 'fixed_ips': 10, 'metadata_items': 128,
+ 'fixed_ips': -1, 'metadata_items': 128,
'injected_files': 5,
'injected_file_content_bytes': 10240,
'security_groups': 10,
@@ -163,7 +163,7 @@ class QuotaSetsTest(test.TestCase):
expected_resp = {'quota_set': {
'instances': 50, 'cores': 50,
'ram': 51200, 'floating_ips': 10,
- 'fixed_ips': 10, 'metadata_items': 128,
+ 'fixed_ips': -1, 'metadata_items': 128,
'injected_files': 5,
'injected_file_content_bytes': 10240,
'injected_file_path_bytes': 255,
@@ -174,7 +174,7 @@ class QuotaSetsTest(test.TestCase):
# when PUT JSON format with empty string for quota
body = {'quota_set': {'instances': 50, 'cores': 50,
'ram': '', 'floating_ips': 10,
- 'fixed_ips': 10, 'metadata_items': 128,
+ 'fixed_ips': -1, 'metadata_items': 128,
'injected_files': 5,
'injected_file_content_bytes': 10240,
'injected_file_path_bytes': 255,
@@ -189,7 +189,7 @@ class QuotaSetsTest(test.TestCase):
# when PUT XML format with empty string for quota
body = {'quota_set': {'instances': 50, 'cores': 50,
'ram': {}, 'floating_ips': 10,
- 'fixed_ips': 10, 'metadata_items': 128,
+ 'fixed_ips': -1, 'metadata_items': 128,
'injected_files': 5,
'injected_file_content_bytes': 10240,
'injected_file_path_bytes': 255,
@@ -216,7 +216,7 @@ class QuotaXMLSerializerTest(test.TestCase):
injected_file_content_bytes=20,
ram=50,
floating_ips=60,
- fixed_ips=10,
+ fixed_ips=-1,
instances=70,
injected_files=80,
security_groups=10,
@@ -240,7 +240,7 @@ class QuotaXMLSerializerTest(test.TestCase):
injected_file_content_bytes='20',
ram='50',
floating_ips='60',
- fixed_ips='10',
+ fixed_ips='-1',
instances='70',
injected_files='80',
security_groups='10',
@@ -254,7 +254,7 @@ class QuotaXMLSerializerTest(test.TestCase):
'</injected_file_content_bytes>'
'<ram>50</ram>'
'<floating_ips>60</floating_ips>'
- '<fixed_ips>10</fixed_ips>'
+ '<fixed_ips>-1</fixed_ips>'
'<instances>70</instances>'
'<injected_files>80</injected_files>'
'<security_groups>10</security_groups>'
diff --git a/nova/tests/api/openstack/compute/contrib/test_security_groups.py b/nova/tests/api/openstack/compute/contrib/test_security_groups.py
index 6c7a8ae8c..480156b97 100644
--- a/nova/tests/api/openstack/compute/contrib/test_security_groups.py
+++ b/nova/tests/api/openstack/compute/contrib/test_security_groups.py
@@ -34,7 +34,8 @@ from nova.tests.api.openstack import fakes
from nova.tests import utils
CONF = cfg.CONF
-FAKE_UUID = 'a47ae74e-ab08-447f-8eee-ffd43fc46c16'
+FAKE_UUID1 = 'a47ae74e-ab08-447f-8eee-ffd43fc46c16'
+FAKE_UUID2 = 'c6e6430a-6563-4efa-9542-5e93c9e97d18'
class AttrDict(dict):
@@ -81,7 +82,7 @@ def return_server(context, server_id):
return {'id': int(server_id),
'power_state': 0x01,
'host': "localhost",
- 'uuid': FAKE_UUID,
+ 'uuid': FAKE_UUID1,
'name': 'asdf'}
@@ -95,12 +96,12 @@ def return_server_by_uuid(context, server_uuid):
def return_non_running_server(context, server_id):
return {'id': server_id, 'power_state': power_state.SHUTDOWN,
- 'uuid': FAKE_UUID, 'host': "localhost", 'name': 'asdf'}
+ 'uuid': FAKE_UUID1, 'host': "localhost", 'name': 'asdf'}
def return_security_group_by_name(context, project_id, group_name):
return {'id': 1, 'name': group_name,
- "instances": [{'id': 1, 'uuid': FAKE_UUID}]}
+ "instances": [{'id': 1, 'uuid': FAKE_UUID1}]}
def return_security_group_without_instances(context, project_id, group_name):
@@ -347,7 +348,7 @@ class TestSecurityGroups(test.TestCase):
expected = {'security_groups': groups}
def return_instance(context, server_id):
- self.assertEquals(server_id, FAKE_UUID)
+ self.assertEquals(server_id, FAKE_UUID1)
return return_server_by_uuid(context, server_id)
self.stubs.Set(nova.db, 'instance_get_by_uuid',
@@ -361,8 +362,8 @@ class TestSecurityGroups(test.TestCase):
return_security_groups)
req = fakes.HTTPRequest.blank('/v2/%s/servers/%s/os-security-groups' %
- ('fake', FAKE_UUID))
- res_dict = self.server_controller.index(req, FAKE_UUID)
+ ('fake', FAKE_UUID1))
+ res_dict = self.server_controller.index(req, FAKE_UUID1)
self.assertEquals(res_dict, expected)
@@ -1388,6 +1389,11 @@ def fake_compute_create(*args, **kwargs):
return ([fake_compute_get()], '')
+def fake_get_instances_security_groups_bindings(inst, context):
+ return {UUID1: [{'name': 'fake-0-0'}, {'name': 'fake-0-1'}],
+ UUID2: [{'name': 'fake-1-0'}, {'name': 'fake-1-1'}]}
+
+
class SecurityGroupsOutputTest(test.TestCase):
content_type = 'application/json'
diff --git a/nova/tests/baremetal/db/utils.py b/nova/tests/baremetal/db/utils.py
index e3a7b8489..74553f895 100644
--- a/nova/tests/baremetal/db/utils.py
+++ b/nova/tests/baremetal/db/utils.py
@@ -66,17 +66,3 @@ def new_bm_interface(**kwargs):
raise test.TestingException("unknown field: %s"
% ','.join(kwargs.keys()))
return x
-
-
-def new_bm_deployment(**kwargs):
- x = bm_models.BareMetalDeployment()
- x.id = kwargs.pop('id', None)
- x.key = kwargs.pop('key', None)
- x.image_path = kwargs.pop('image_path', None)
- x.pxe_config_path = kwargs.pop('pxe_config_path', None)
- x.root_mb = kwargs.pop('root_mb', None)
- x.swap_mb = kwargs.pop('swap_mb', None)
- if len(kwargs) > 0:
- raise test.TestingException("unknown field: %s"
- % ','.join(kwargs.keys()))
- return x
diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py
index 3a1526522..097c87848 100644
--- a/nova/tests/compute/test_compute.py
+++ b/nova/tests/compute/test_compute.py
@@ -3654,7 +3654,7 @@ class ComputeTestCase(BaseTestCase):
fake_migration_get_unconfirmed_by_dest_compute)
self.stubs.Set(self.compute.conductor_api, 'migration_update',
fake_migration_update)
- self.stubs.Set(self.compute.compute_api, 'confirm_resize',
+ self.stubs.Set(self.compute.conductor_api, 'compute_confirm_resize',
fake_confirm_resize)
def fetch_instance_migration_status(instance_uuid):
@@ -5552,6 +5552,7 @@ class ComputeAPITestCase(BaseTestCase):
self.stubs.Set(rpc, 'cast', _fake_cast)
self.flags(allow_resize_to_same_host=True)
+ self.flags(allow_migrate_to_same_host=True)
instance = self._create_fake_instance(dict(host='host2'))
instance = db.instance_get_by_uuid(self.context, instance['uuid'])
@@ -7976,3 +7977,69 @@ class EvacuateHostTestCase(BaseTestCase):
lambda x: True)
self.assertRaises(exception.InstanceRecreateNotSupported,
lambda: self._rebuild(on_shared_storage=True))
+
+
+class ComputeInjectedFilesTestCase(BaseTestCase):
+ # Test that running instances with injected_files decodes files correctly
+
+ def setUp(self):
+ super(ComputeInjectedFilesTestCase, self).setUp()
+ self.instance = self._create_fake_instance()
+ self.stubs.Set(self.compute.driver, 'spawn', self._spawn)
+
+ def _spawn(self, context, instance, image_meta, injected_files,
+ admin_password, nw_info, block_device_info):
+ self.assertEqual(self.expected, injected_files)
+
+ def _test(self, injected_files, decoded_files):
+ self.expected = decoded_files
+ self.compute.run_instance(self.context, self.instance,
+ injected_files=injected_files)
+
+ def test_injected_none(self):
+ # test an input of None for injected_files
+ self._test(None, [])
+
+ def test_injected_empty(self):
+ # test an input of [] for injected_files
+ self._test([], [])
+
+ def test_injected_success(self):
+ # test with valid b64 encoded content.
+ injected_files = [
+ ('/a/b/c', base64.b64encode('foobarbaz')),
+ ('/d/e/f', base64.b64encode('seespotrun')),
+ ]
+
+ decoded_files = [
+ ('/a/b/c', 'foobarbaz'),
+ ('/d/e/f', 'seespotrun'),
+ ]
+ self._test(injected_files, decoded_files)
+
+ def test_injected_invalid(self):
+ # test with invalid b64 encoded content
+ injected_files = [
+ ('/a/b/c', base64.b64encode('foobarbaz')),
+ ('/d/e/f', 'seespotrun'),
+ ]
+
+ self.assertRaises(exception.Base64Exception, self.compute.run_instance,
+ self.context, self.instance, injected_files=injected_files)
+
+ def test_reschedule(self):
+ # test that rescheduling is done with original encoded files
+ expected = [
+ ('/a/b/c', base64.b64encode('foobarbaz')),
+ ('/d/e/f', base64.b64encode('seespotrun')),
+ ]
+
+ def _ror(context, instance, exc_info, requested_networks,
+ admin_password, injected_files, is_first_time, request_spec,
+ filter_properties, bdms=None):
+ self.assertEqual(expected, injected_files)
+
+ self.stubs.Set(self.compute, '_reschedule_or_reraise', _ror)
+
+ self.compute.run_instance(self.context, self.instance,
+ injected_files=expected)
diff --git a/nova/tests/conductor/test_conductor.py b/nova/tests/conductor/test_conductor.py
index df0f5e73b..1c675ec61 100644
--- a/nova/tests/conductor/test_conductor.py
+++ b/nova/tests/conductor/test_conductor.py
@@ -599,6 +599,16 @@ class _BaseTestCase(object):
self.mox.ReplayAll()
self.conductor.compute_stop(self.context, 'instance')
+ def test_compute_confirm_resize(self):
+ self.mox.StubOutWithMock(self.conductor_manager.compute_api,
+ 'confirm_resize')
+ self.conductor_manager.compute_api.confirm_resize(self.context,
+ 'instance',
+ 'migration')
+ self.mox.ReplayAll()
+ self.conductor.compute_confirm_resize(self.context, 'instance',
+ 'migration')
+
class ConductorTestCase(_BaseTestCase, test.TestCase):
"""Conductor Manager Tests."""
diff --git a/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-show-get-resp.json.tpl b/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-show-get-resp.json.tpl
index c393ab0c7..f9a94e760 100644
--- a/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-show-get-resp.json.tpl
+++ b/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-show-get-resp.json.tpl
@@ -2,7 +2,7 @@
"quota_class_set": {
"cores": 20,
"floating_ips": 10,
- "fixed_ips": 10,
+ "fixed_ips": -1,
"id": "%(set_id)s",
"injected_file_content_bytes": 10240,
"injected_file_path_bytes": 255,
diff --git a/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-show-get-resp.xml.tpl b/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-show-get-resp.xml.tpl
index 8ab8436d7..fb8e7992a 100644
--- a/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-show-get-resp.xml.tpl
+++ b/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-show-get-resp.xml.tpl
@@ -2,7 +2,7 @@
<quota_class_set id="%(set_id)s">
<cores>20</cores>
<floating_ips>10</floating_ips>
- <fixed_ips>10</fixed_ips>
+ <fixed_ips>-1</fixed_ips>
<injected_file_content_bytes>10240</injected_file_content_bytes>
<injected_file_path_bytes>255</injected_file_path_bytes>
<injected_files>5</injected_files>
diff --git a/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-req.json.tpl b/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-req.json.tpl
index 3974f65db..483fda8c5 100644
--- a/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-req.json.tpl
+++ b/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-req.json.tpl
@@ -4,7 +4,7 @@
"cores": 50,
"ram": 51200,
"floating_ips": 10,
- "fixed_ips": 10,
+ "fixed_ips": -1,
"metadata_items": 128,
"injected_files": 5,
"injected_file_content_bytes": 10240,
diff --git a/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-req.xml.tpl b/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-req.xml.tpl
index f27082ab3..150fb6a42 100644
--- a/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-req.xml.tpl
+++ b/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-req.xml.tpl
@@ -2,7 +2,7 @@
<quota_class_set>
<cores>50</cores>
<floating_ips>10</floating_ips>
- <fixed_ips>10</fixed_ips>
+ <fixed_ips>-1</fixed_ips>
<injected_file_content_bytes>10240</injected_file_content_bytes>
<injected_file_path_bytes>255</injected_file_path_bytes>
<injected_files>5</injected_files>
diff --git a/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-resp.json.tpl b/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-resp.json.tpl
index 8d195b924..c36783f2f 100644
--- a/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-resp.json.tpl
+++ b/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-resp.json.tpl
@@ -2,7 +2,7 @@
"quota_class_set": {
"cores": 50,
"floating_ips": 10,
- "fixed_ips": 10,
+ "fixed_ips": -1,
"injected_file_content_bytes": 10240,
"injected_file_path_bytes": 255,
"injected_files": 5,
@@ -13,4 +13,4 @@
"security_group_rules": 20,
"security_groups": 10
}
-} \ No newline at end of file
+}
diff --git a/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-resp.xml.tpl b/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-resp.xml.tpl
index 5c12a81e7..cd674a24d 100644
--- a/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-resp.xml.tpl
+++ b/nova/tests/integrated/api_samples/os-quota-class-sets/quota-classes-update-post-resp.xml.tpl
@@ -2,7 +2,7 @@
<quota_class_set>
<cores>50</cores>
<floating_ips>10</floating_ips>
- <fixed_ips>10</fixed_ips>
+ <fixed_ips>-1</fixed_ips>
<injected_file_content_bytes>10240</injected_file_content_bytes>
<injected_file_path_bytes>255</injected_file_path_bytes>
<injected_files>5</injected_files>
@@ -12,4 +12,4 @@
<ram>51200</ram>
<security_group_rules>20</security_group_rules>
<security_groups>10</security_groups>
-</quota_class_set> \ No newline at end of file
+</quota_class_set>
diff --git a/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-defaults-get-resp.json.tpl b/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-defaults-get-resp.json.tpl
index 364a59f7a..2f0fd9857 100644
--- a/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-defaults-get-resp.json.tpl
+++ b/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-defaults-get-resp.json.tpl
@@ -2,7 +2,7 @@
"quota_set": {
"cores": 20,
"floating_ips": 10,
- "fixed_ips": 10,
+ "fixed_ips": -1,
"id": "fake_tenant",
"injected_file_content_bytes": 10240,
"injected_file_path_bytes": 255,
diff --git a/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-defaults-get-resp.xml.tpl b/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-defaults-get-resp.xml.tpl
index 36e6da544..f56987563 100644
--- a/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-defaults-get-resp.xml.tpl
+++ b/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-defaults-get-resp.xml.tpl
@@ -2,7 +2,7 @@
<quota_set id="fake_tenant">
<cores>20</cores>
<floating_ips>10</floating_ips>
- <fixed_ips>10</fixed_ips>
+ <fixed_ips>-1</fixed_ips>
<injected_file_content_bytes>10240</injected_file_content_bytes>
<injected_file_path_bytes>255</injected_file_path_bytes>
<injected_files>5</injected_files>
diff --git a/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-get-resp.json.tpl b/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-get-resp.json.tpl
index 364a59f7a..2f0fd9857 100644
--- a/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-get-resp.json.tpl
+++ b/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-get-resp.json.tpl
@@ -2,7 +2,7 @@
"quota_set": {
"cores": 20,
"floating_ips": 10,
- "fixed_ips": 10,
+ "fixed_ips": -1,
"id": "fake_tenant",
"injected_file_content_bytes": 10240,
"injected_file_path_bytes": 255,
diff --git a/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-get-resp.xml.tpl b/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-get-resp.xml.tpl
index 36e6da544..f56987563 100644
--- a/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-get-resp.xml.tpl
+++ b/nova/tests/integrated/api_samples/os-quota-sets/quotas-show-get-resp.xml.tpl
@@ -2,7 +2,7 @@
<quota_set id="fake_tenant">
<cores>20</cores>
<floating_ips>10</floating_ips>
- <fixed_ips>10</fixed_ips>
+ <fixed_ips>-1</fixed_ips>
<injected_file_content_bytes>10240</injected_file_content_bytes>
<injected_file_path_bytes>255</injected_file_path_bytes>
<injected_files>5</injected_files>
diff --git a/nova/tests/integrated/api_samples/os-quota-sets/quotas-update-post-resp.json.tpl b/nova/tests/integrated/api_samples/os-quota-sets/quotas-update-post-resp.json.tpl
index 43525cfd5..34df1fe01 100644
--- a/nova/tests/integrated/api_samples/os-quota-sets/quotas-update-post-resp.json.tpl
+++ b/nova/tests/integrated/api_samples/os-quota-sets/quotas-update-post-resp.json.tpl
@@ -2,7 +2,7 @@
"quota_set": {
"cores": 20,
"floating_ips": 10,
- "fixed_ips": 10,
+ "fixed_ips": -1,
"injected_file_content_bytes": 10240,
"injected_file_path_bytes": 255,
"injected_files": 5,
diff --git a/nova/tests/integrated/api_samples/os-quota-sets/quotas-update-post-resp.xml.tpl b/nova/tests/integrated/api_samples/os-quota-sets/quotas-update-post-resp.xml.tpl
index 3c411e8e5..91ac3a0dd 100644
--- a/nova/tests/integrated/api_samples/os-quota-sets/quotas-update-post-resp.xml.tpl
+++ b/nova/tests/integrated/api_samples/os-quota-sets/quotas-update-post-resp.xml.tpl
@@ -2,7 +2,7 @@
<quota_set>
<cores>20</cores>
<floating_ips>10</floating_ips>
- <fixed_ips>10</fixed_ips>
+ <fixed_ips>-1</fixed_ips>
<injected_file_content_bytes>10240</injected_file_content_bytes>
<injected_file_path_bytes>255</injected_file_path_bytes>
<injected_files>5</injected_files>
diff --git a/nova/tests/network/test_linux_net.py b/nova/tests/network/test_linux_net.py
index 53748ef25..4829f2d93 100644
--- a/nova/tests/network/test_linux_net.py
+++ b/nova/tests/network/test_linux_net.py
@@ -484,7 +484,6 @@ class LinuxNetworkTestCase(test.TestCase):
'dns1': '8.8.4.4',
'dhcp_start': '1.0.0.2',
'dhcp_server': '10.0.0.1'}
- executes = []
def fake_execute(*args, **kwargs):
executes.append(args)
@@ -496,29 +495,37 @@ class LinuxNetworkTestCase(test.TestCase):
self.stubs.Set(linux_net, 'write_to_file', lambda *a, **kw: None)
self.stubs.Set(linux_net, '_dnsmasq_pid_for', lambda *a, **kw: None)
dev = 'br100'
- linux_net.restart_dhcp(self.context, dev, network_ref)
- expected = ['env',
- 'CONFIG_FILE=%s' % jsonutils.dumps(CONF.dhcpbridge_flagfile),
- 'NETWORK_ID=fake',
- 'dnsmasq',
- '--strict-order',
- '--bind-interfaces',
- '--conf-file=%s' % CONF.dnsmasq_config_file,
- '--domain=\'%s\'' % CONF.dhcp_domain,
- '--pid-file=%s' % linux_net._dhcp_file(dev, 'pid'),
- '--listen-address=%s' % network_ref['dhcp_server'],
- '--except-interface=lo',
- "--dhcp-range=set:%s,%s,static,%s,%ss" % (network_ref['label'],
- network_ref['dhcp_start'],
- network_ref['netmask'],
- CONF.dhcp_lease_time),
- '--dhcp-lease-max=256',
- '--dhcp-hostsfile=%s' % linux_net._dhcp_file(dev, 'conf'),
- '--dhcp-script=%s' % CONF.dhcpbridge,
- '--leasefile-ro']
- if extra_expected:
- expected += extra_expected
- self.assertEqual([tuple(expected)], executes)
+
+ default_domain = CONF.dhcp_domain
+ for domain in ('', default_domain):
+ executes = []
+ CONF.dhcp_domain = domain
+ linux_net.restart_dhcp(self.context, dev, network_ref)
+ expected = ['env',
+ 'CONFIG_FILE=%s' % jsonutils.dumps(CONF.dhcpbridge_flagfile),
+ 'NETWORK_ID=fake',
+ 'dnsmasq',
+ '--strict-order',
+ '--bind-interfaces',
+ '--conf-file=%s' % CONF.dnsmasq_config_file,
+ '--pid-file=%s' % linux_net._dhcp_file(dev, 'pid'),
+ '--listen-address=%s' % network_ref['dhcp_server'],
+ '--except-interface=lo',
+ "--dhcp-range=set:%s,%s,static,%s,%ss" % (network_ref['label'],
+ network_ref['dhcp_start'],
+ network_ref['netmask'],
+ CONF.dhcp_lease_time),
+ '--dhcp-lease-max=256',
+ '--dhcp-hostsfile=%s' % linux_net._dhcp_file(dev, 'conf'),
+ '--dhcp-script=%s' % CONF.dhcpbridge,
+ '--leasefile-ro']
+
+ if CONF.dhcp_domain:
+ expected.append('--domain=%s' % CONF.dhcp_domain)
+
+ if extra_expected:
+ expected += extra_expected
+ self.assertEqual([tuple(expected)], executes)
def test_dnsmasq_execute(self):
self._test_dnsmasq_execute()
diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py
index c4ce649f0..f0d8e58a9 100644
--- a/nova/tests/network/test_manager.py
+++ b/nova/tests/network/test_manager.py
@@ -1309,11 +1309,12 @@ class CommonNetworkTestCase(test.TestCase):
manager.db.network_get_all(ctxt).AndReturn([{'id': 1,
'cidr': '192.168.2.9/25'}])
self.mox.ReplayAll()
- # ValueError: requested cidr (192.168.2.0/24) conflicts with
- # existing smaller cidr
+ # CidrConflict: requested cidr (192.168.2.0/24) conflicts with
+ # existing smaller cidr
args = (None, 'fake', '192.168.2.0/24', False, 1, 256, None, None,
None, None, None)
- self.assertRaises(ValueError, manager.create_networks, *args)
+ self.assertRaises(exception.CidrConflict,
+ manager.create_networks, *args)
def test_validate_cidrs_split_smaller_cidr_in_use(self):
manager = fake_network.FakeNetworkManager()
@@ -1361,10 +1362,11 @@ class CommonNetworkTestCase(test.TestCase):
self.mox.ReplayAll()
args = (None, 'fake', '192.168.2.0/24', False, 3, 64, None, None,
None, None, None)
- # ValueError: Not enough subnets avail to satisfy requested num_
- # networks - some subnets in requested range already
- # in use
- self.assertRaises(ValueError, manager.create_networks, *args)
+ # CidrConflict: Not enough subnets avail to satisfy requested num_
+ # networks - some subnets in requested range already
+ # in use
+ self.assertRaises(exception.CidrConflict,
+ manager.create_networks, *args)
def test_validate_cidrs_one_in_use(self):
manager = fake_network.FakeNetworkManager()
@@ -1380,10 +1382,11 @@ class CommonNetworkTestCase(test.TestCase):
manager.db.network_get_all(ctxt).AndReturn([{'id': 1,
'cidr': '192.168.0.0/24'}])
self.mox.ReplayAll()
- # ValueError: cidr already in use
+ # CidrConflict: cidr already in use
args = (None, 'fake', '192.168.0.0/24', False, 1, 256, None, None,
None, None, None)
- self.assertRaises(ValueError, manager.create_networks, *args)
+ self.assertRaises(exception.CidrConflict,
+ manager.create_networks, *args)
def test_validate_cidrs_too_many(self):
manager = fake_network.FakeNetworkManager()
@@ -1411,9 +1414,10 @@ class CommonNetworkTestCase(test.TestCase):
self.mox.ReplayAll()
args = (None, 'fake', '192.168.0.0/24', False, 1, 256, None, None,
None, None, None)
- # ValueError: requested cidr (192.168.0.0/24) conflicts
- # with existing supernet
- self.assertRaises(ValueError, manager.create_networks, *args)
+ # CidrConflict: requested cidr (192.168.0.0/24) conflicts
+ # with existing supernet
+ self.assertRaises(exception.CidrConflict,
+ manager.create_networks, *args)
def test_create_networks(self):
cidr = '192.168.0.0/24'
@@ -1433,7 +1437,8 @@ class CommonNetworkTestCase(test.TestCase):
self.mox.ReplayAll()
args = [None, 'foo', '192.168.0.0/24', None, 1, 256,
'fd00::/48', None, None, None, None, None]
- self.assertRaises(ValueError, manager.create_networks, *args)
+ self.assertRaises(exception.CidrConflict,
+ manager.create_networks, *args)
def test_create_networks_many(self):
cidr = '192.168.0.0/16'
diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py
index e695ab5fe..01f274f7c 100644
--- a/nova/tests/test_metadata.py
+++ b/nova/tests/test_metadata.py
@@ -25,6 +25,11 @@ import hmac
import json
import re
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+
from oslo.config import cfg
import webob
@@ -132,6 +137,12 @@ class MetadataTestCase(test.TestCase):
fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs,
spectacular=True)
+ def test_can_pickle_metadata(self):
+ # Make sure that InstanceMetadata is possible to pickle. This is
+ # required for memcache backend to work correctly.
+ md = fake_InstanceMetadata(self.stubs, copy.copy(self.instance))
+ pickle.dumps(md, protocol=0)
+
def test_user_data(self):
inst = copy.copy(self.instance)
inst['user_data'] = base64.b64encode("happy")
diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py
index 49f9f3256..727746b18 100644
--- a/nova/tests/test_nova_manage.py
+++ b/nova/tests/test_nova_manage.py
@@ -366,7 +366,8 @@ class ProjectCommandsTestCase(test.TestCase):
sys.stdout = sys.__stdout__
result = output.getvalue()
- self.assertEquals(('instances: unlimited' in result), True)
+ print_format = "%-36s %-10s" % ('instances', 'unlimited')
+ self.assertEquals((print_format in result), True)
def test_quota_update_invalid_key(self):
self.assertRaises(SystemExit,
diff --git a/tools/hacking.py b/tools/hacking.py
index 4e2331054..94053991e 100755
--- a/tools/hacking.py
+++ b/tools/hacking.py
@@ -21,6 +21,7 @@
Built on top of pep8.py
"""
+import gettext
import imp
import inspect
import logging
@@ -643,6 +644,7 @@ imports_on_separate_lines_N301_compliant = r"""
"""
if __name__ == "__main__":
+ gettext.install('nova', unicode=1)
#include nova path
sys.path.append(os.getcwd())
#Run once tests (not per line)