merged trunk
This commit is contained in:
@@ -10,6 +10,7 @@ graft bzrplugins
|
||||
graft contrib
|
||||
graft po
|
||||
graft plugins
|
||||
graft nova/api/openstack/schemas
|
||||
include nova/api/openstack/notes.txt
|
||||
include nova/auth/*.schema
|
||||
include nova/auth/novarc.template
|
||||
|
||||
@@ -726,8 +726,7 @@ class NetworkCommands(object):
|
||||
network_size = FLAGS.network_size
|
||||
subnet = 32 - int(math.log(network_size, 2))
|
||||
oversize_msg = _('Subnet(s) too large, defaulting to /%s.'
|
||||
' To override, specify network_size flag.'
|
||||
) % subnet
|
||||
' To override, specify network_size flag.') % subnet
|
||||
print oversize_msg
|
||||
else:
|
||||
network_size = fixnet.size
|
||||
@@ -1120,10 +1119,12 @@ class InstanceTypeCommands(object):
|
||||
|
||||
@args('--name', dest='name', metavar='<name>',
|
||||
help='Name of instance type/flavor')
|
||||
def delete(self, name, purge=None):
|
||||
@args('--purge', action="store_true", dest='purge', default=False,
|
||||
help='purge record from database')
|
||||
def delete(self, name, purge):
|
||||
"""Marks instance types / flavors as deleted"""
|
||||
try:
|
||||
if purge == "--purge":
|
||||
if purge:
|
||||
instance_types.purge(name)
|
||||
verb = "purged"
|
||||
else:
|
||||
|
||||
@@ -27,6 +27,7 @@ import random
|
||||
import StringIO
|
||||
import webob
|
||||
|
||||
from nova import block_device
|
||||
from nova import context
|
||||
from nova import exception
|
||||
from nova import test
|
||||
@@ -147,10 +148,12 @@ class Ec2utilsTestCase(test.TestCase):
|
||||
properties0 = {'mappings': mappings}
|
||||
properties1 = {'root_device_name': '/dev/sdb', 'mappings': mappings}
|
||||
|
||||
root_device_name = ec2utils.properties_root_device_name(properties0)
|
||||
root_device_name = block_device.properties_root_device_name(
|
||||
properties0)
|
||||
self.assertEqual(root_device_name, '/dev/sda1')
|
||||
|
||||
root_device_name = ec2utils.properties_root_device_name(properties1)
|
||||
root_device_name = block_device.properties_root_device_name(
|
||||
properties1)
|
||||
self.assertEqual(root_device_name, '/dev/sdb')
|
||||
|
||||
def test_mapping_prepend_dev(self):
|
||||
@@ -184,7 +187,7 @@ class Ec2utilsTestCase(test.TestCase):
|
||||
'device': '/dev/sdc1'},
|
||||
{'virtual': 'ephemeral1',
|
||||
'device': '/dev/sdc1'}]
|
||||
self.assertDictListMatch(ec2utils.mappings_prepend_dev(mappings),
|
||||
self.assertDictListMatch(block_device.mappings_prepend_dev(mappings),
|
||||
expected_result)
|
||||
|
||||
|
||||
@@ -336,6 +339,33 @@ class ApiEc2TestCase(test.TestCase):
|
||||
|
||||
self.ec2.delete_security_group(security_group_name)
|
||||
|
||||
def test_group_name_valid_chars_security_group(self):
|
||||
""" Test that we sanely handle invalid security group names.
|
||||
API Spec states we should only accept alphanumeric characters,
|
||||
spaces, dashes, and underscores. """
|
||||
self.expect_http()
|
||||
self.mox.ReplayAll()
|
||||
|
||||
# Test block group_name of non alphanumeric characters, spaces,
|
||||
# dashes, and underscores.
|
||||
security_group_name = "aa #^% -=99"
|
||||
|
||||
self.assertRaises(EC2ResponseError, self.ec2.create_security_group,
|
||||
security_group_name, 'test group')
|
||||
|
||||
def test_group_name_valid_length_security_group(self):
|
||||
"""Test that we sanely handle invalid security group names.
|
||||
API Spec states that the length should not exceed 255 chars """
|
||||
self.expect_http()
|
||||
self.mox.ReplayAll()
|
||||
|
||||
# Test block group_name > 255 chars
|
||||
security_group_name = "".join(random.choice("poiuytrewqasdfghjklmnbvc")
|
||||
for x in range(random.randint(256, 266)))
|
||||
|
||||
self.assertRaises(EC2ResponseError, self.ec2.create_security_group,
|
||||
security_group_name, 'test group')
|
||||
|
||||
def test_authorize_revoke_security_group_cidr(self):
|
||||
"""
|
||||
Test that we can add and remove CIDR based rules
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
# under the License.
|
||||
import mox
|
||||
|
||||
import functools
|
||||
|
||||
from base64 import b64decode
|
||||
from M2Crypto import BIO
|
||||
from M2Crypto import RSA
|
||||
@@ -892,13 +894,16 @@ class CloudTestCase(test.TestCase):
|
||||
def test_modify_image_attribute(self):
|
||||
modify_image_attribute = self.cloud.modify_image_attribute
|
||||
|
||||
fake_metadata = {'id': 1, 'container_format': 'ami',
|
||||
'properties': {'kernel_id': 1, 'ramdisk_id': 1,
|
||||
'type': 'machine'}, 'is_public': False}
|
||||
|
||||
def fake_show(meh, context, id):
|
||||
return {'id': 1, 'container_format': 'ami',
|
||||
'properties': {'kernel_id': 1, 'ramdisk_id': 1,
|
||||
'type': 'machine'}, 'is_public': False}
|
||||
return fake_metadata
|
||||
|
||||
def fake_update(meh, context, image_id, metadata, data=None):
|
||||
return metadata
|
||||
fake_metadata.update(metadata)
|
||||
return fake_metadata
|
||||
|
||||
self.stubs.Set(fake._FakeImageService, 'show', fake_show)
|
||||
self.stubs.Set(fake._FakeImageService, 'show_by_name', fake_show)
|
||||
@@ -1464,3 +1469,147 @@ class CloudTestCase(test.TestCase):
|
||||
# TODO(yamahata): clean up snapshot created by CreateImage.
|
||||
|
||||
self._restart_compute_service()
|
||||
|
||||
@staticmethod
|
||||
def _fake_bdm_get(ctxt, id):
|
||||
return [{'volume_id': 87654321,
|
||||
'snapshot_id': None,
|
||||
'no_device': None,
|
||||
'virtual_name': None,
|
||||
'delete_on_termination': True,
|
||||
'device_name': '/dev/sdh'},
|
||||
{'volume_id': None,
|
||||
'snapshot_id': 98765432,
|
||||
'no_device': None,
|
||||
'virtual_name': None,
|
||||
'delete_on_termination': True,
|
||||
'device_name': '/dev/sdi'},
|
||||
{'volume_id': None,
|
||||
'snapshot_id': None,
|
||||
'no_device': True,
|
||||
'virtual_name': None,
|
||||
'delete_on_termination': None,
|
||||
'device_name': None},
|
||||
{'volume_id': None,
|
||||
'snapshot_id': None,
|
||||
'no_device': None,
|
||||
'virtual_name': 'ephemeral0',
|
||||
'delete_on_termination': None,
|
||||
'device_name': '/dev/sdb'},
|
||||
{'volume_id': None,
|
||||
'snapshot_id': None,
|
||||
'no_device': None,
|
||||
'virtual_name': 'swap',
|
||||
'delete_on_termination': None,
|
||||
'device_name': '/dev/sdc'},
|
||||
{'volume_id': None,
|
||||
'snapshot_id': None,
|
||||
'no_device': None,
|
||||
'virtual_name': 'ephemeral1',
|
||||
'delete_on_termination': None,
|
||||
'device_name': '/dev/sdd'},
|
||||
{'volume_id': None,
|
||||
'snapshot_id': None,
|
||||
'no_device': None,
|
||||
'virtual_name': 'ephemeral2',
|
||||
'delete_on_termination': None,
|
||||
'device_name': '/dev/sd3'},
|
||||
]
|
||||
|
||||
def test_get_instance_mapping(self):
|
||||
"""Make sure that _get_instance_mapping works"""
|
||||
ctxt = None
|
||||
instance_ref0 = {'id': 0,
|
||||
'root_device_name': None}
|
||||
instance_ref1 = {'id': 0,
|
||||
'root_device_name': '/dev/sda1'}
|
||||
|
||||
self.stubs.Set(db, 'block_device_mapping_get_all_by_instance',
|
||||
self._fake_bdm_get)
|
||||
|
||||
expected = {'ami': 'sda1',
|
||||
'root': '/dev/sda1',
|
||||
'ephemeral0': '/dev/sdb',
|
||||
'swap': '/dev/sdc',
|
||||
'ephemeral1': '/dev/sdd',
|
||||
'ephemeral2': '/dev/sd3'}
|
||||
|
||||
self.assertEqual(self.cloud._format_instance_mapping(ctxt,
|
||||
instance_ref0),
|
||||
cloud._DEFAULT_MAPPINGS)
|
||||
self.assertEqual(self.cloud._format_instance_mapping(ctxt,
|
||||
instance_ref1),
|
||||
expected)
|
||||
|
||||
def test_describe_instance_attribute(self):
|
||||
"""Make sure that describe_instance_attribute works"""
|
||||
self.stubs.Set(db, 'block_device_mapping_get_all_by_instance',
|
||||
self._fake_bdm_get)
|
||||
|
||||
def fake_get(ctxt, instance_id):
|
||||
return {
|
||||
'id': 0,
|
||||
'root_device_name': '/dev/sdh',
|
||||
'security_groups': [{'name': 'fake0'}, {'name': 'fake1'}],
|
||||
'state_description': 'stopping',
|
||||
'instance_type': {'name': 'fake_type'},
|
||||
'kernel_id': 1,
|
||||
'ramdisk_id': 2,
|
||||
'user_data': 'fake-user data',
|
||||
}
|
||||
self.stubs.Set(self.cloud.compute_api, 'get', fake_get)
|
||||
|
||||
def fake_volume_get(ctxt, volume_id, session=None):
|
||||
if volume_id == 87654321:
|
||||
return {'id': volume_id,
|
||||
'attach_time': '13:56:24',
|
||||
'status': 'in-use'}
|
||||
raise exception.VolumeNotFound(volume_id=volume_id)
|
||||
self.stubs.Set(db.api, 'volume_get', fake_volume_get)
|
||||
|
||||
get_attribute = functools.partial(
|
||||
self.cloud.describe_instance_attribute,
|
||||
self.context, 'i-12345678')
|
||||
|
||||
bdm = get_attribute('blockDeviceMapping')
|
||||
bdm['blockDeviceMapping'].sort()
|
||||
|
||||
expected_bdm = {'instance_id': 'i-12345678',
|
||||
'rootDeviceType': 'ebs',
|
||||
'blockDeviceMapping': [
|
||||
{'deviceName': '/dev/sdh',
|
||||
'ebs': {'status': 'in-use',
|
||||
'deleteOnTermination': True,
|
||||
'volumeId': 87654321,
|
||||
'attachTime': '13:56:24'}}]}
|
||||
expected_bdm['blockDeviceMapping'].sort()
|
||||
self.assertEqual(bdm, expected_bdm)
|
||||
# NOTE(yamahata): this isn't supported
|
||||
# get_attribute('disableApiTermination')
|
||||
groupSet = get_attribute('groupSet')
|
||||
groupSet['groupSet'].sort()
|
||||
expected_groupSet = {'instance_id': 'i-12345678',
|
||||
'groupSet': [{'groupId': 'fake0'},
|
||||
{'groupId': 'fake1'}]}
|
||||
expected_groupSet['groupSet'].sort()
|
||||
self.assertEqual(groupSet, expected_groupSet)
|
||||
self.assertEqual(get_attribute('instanceInitiatedShutdownBehavior'),
|
||||
{'instance_id': 'i-12345678',
|
||||
'instanceInitiatedShutdownBehavior': 'stop'})
|
||||
self.assertEqual(get_attribute('instanceType'),
|
||||
{'instance_id': 'i-12345678',
|
||||
'instanceType': 'fake_type'})
|
||||
self.assertEqual(get_attribute('kernel'),
|
||||
{'instance_id': 'i-12345678',
|
||||
'kernel': 'aki-00000001'})
|
||||
self.assertEqual(get_attribute('ramdisk'),
|
||||
{'instance_id': 'i-12345678',
|
||||
'ramdisk': 'ari-00000002'})
|
||||
self.assertEqual(get_attribute('rootDeviceName'),
|
||||
{'instance_id': 'i-12345678',
|
||||
'rootDeviceName': '/dev/sdh'})
|
||||
# NOTE(yamahata): this isn't supported
|
||||
# get_attribute('sourceDestCheck')
|
||||
self.assertEqual(get_attribute('userData'),
|
||||
{'instance_id': 'i-12345678',
|
||||
'userData': '}\xa9\x1e\xba\xc7\xabu\xabZ'})
|
||||
|
||||
@@ -1333,15 +1333,17 @@ class ComputeTestCase(test.TestCase):
|
||||
return bdm
|
||||
|
||||
def test_update_block_device_mapping(self):
|
||||
swap_size = 1
|
||||
instance_type = {'swap': swap_size}
|
||||
instance_id = self._create_instance()
|
||||
mappings = [
|
||||
{'virtual': 'ami', 'device': 'sda1'},
|
||||
{'virtual': 'root', 'device': '/dev/sda1'},
|
||||
|
||||
{'virtual': 'swap', 'device': 'sdb1'},
|
||||
{'virtual': 'swap', 'device': 'sdb2'},
|
||||
{'virtual': 'swap', 'device': 'sdb3'},
|
||||
{'virtual': 'swap', 'device': 'sdb4'},
|
||||
{'virtual': 'swap', 'device': 'sdb3'},
|
||||
{'virtual': 'swap', 'device': 'sdb2'},
|
||||
{'virtual': 'swap', 'device': 'sdb1'},
|
||||
|
||||
{'virtual': 'ephemeral0', 'device': 'sdc1'},
|
||||
{'virtual': 'ephemeral1', 'device': 'sdc2'},
|
||||
@@ -1383,32 +1385,36 @@ class ComputeTestCase(test.TestCase):
|
||||
'no_device': True}]
|
||||
|
||||
self.compute_api._update_image_block_device_mapping(
|
||||
self.context, instance_id, mappings)
|
||||
self.context, instance_type, instance_id, mappings)
|
||||
|
||||
bdms = [self._parse_db_block_device_mapping(bdm_ref)
|
||||
for bdm_ref in db.block_device_mapping_get_all_by_instance(
|
||||
self.context, instance_id)]
|
||||
expected_result = [
|
||||
{'virtual_name': 'swap', 'device_name': '/dev/sdb1'},
|
||||
{'virtual_name': 'swap', 'device_name': '/dev/sdb2'},
|
||||
{'virtual_name': 'swap', 'device_name': '/dev/sdb3'},
|
||||
{'virtual_name': 'swap', 'device_name': '/dev/sdb4'},
|
||||
{'virtual_name': 'swap', 'device_name': '/dev/sdb1',
|
||||
'volume_size': swap_size},
|
||||
{'virtual_name': 'ephemeral0', 'device_name': '/dev/sdc1'},
|
||||
{'virtual_name': 'ephemeral1', 'device_name': '/dev/sdc2'},
|
||||
{'virtual_name': 'ephemeral2', 'device_name': '/dev/sdc3'}]
|
||||
|
||||
# NOTE(yamahata): ATM only ephemeral0 is supported.
|
||||
# they're ignored for now
|
||||
#{'virtual_name': 'ephemeral1', 'device_name': '/dev/sdc2'},
|
||||
#{'virtual_name': 'ephemeral2', 'device_name': '/dev/sdc3'}
|
||||
]
|
||||
bdms.sort()
|
||||
expected_result.sort()
|
||||
self.assertDictListMatch(bdms, expected_result)
|
||||
|
||||
self.compute_api._update_block_device_mapping(
|
||||
self.context, instance_id, block_device_mapping)
|
||||
self.context, instance_types.get_default_instance_type(),
|
||||
instance_id, block_device_mapping)
|
||||
bdms = [self._parse_db_block_device_mapping(bdm_ref)
|
||||
for bdm_ref in db.block_device_mapping_get_all_by_instance(
|
||||
self.context, instance_id)]
|
||||
expected_result = [
|
||||
{'snapshot_id': 0x12345678, 'device_name': '/dev/sda1'},
|
||||
|
||||
{'virtual_name': 'swap', 'device_name': '/dev/sdb1'},
|
||||
{'virtual_name': 'swap', 'device_name': '/dev/sdb1',
|
||||
'volume_size': swap_size},
|
||||
{'snapshot_id': 0x23456789, 'device_name': '/dev/sdb2'},
|
||||
{'snapshot_id': 0x3456789A, 'device_name': '/dev/sdb3'},
|
||||
{'no_device': True, 'device_name': '/dev/sdb4'},
|
||||
@@ -1430,3 +1436,13 @@ class ComputeTestCase(test.TestCase):
|
||||
self.context, instance_id):
|
||||
db.block_device_mapping_destroy(self.context, bdm['id'])
|
||||
self.compute.terminate_instance(self.context, instance_id)
|
||||
|
||||
def test_ephemeral_size(self):
|
||||
local_size = 2
|
||||
inst_type = {'local_gb': local_size}
|
||||
self.assertEqual(self.compute_api._ephemeral_size(inst_type,
|
||||
'ephemeral0'),
|
||||
local_size)
|
||||
self.assertEqual(self.compute_api._ephemeral_size(inst_type,
|
||||
'ephemeral1'),
|
||||
0)
|
||||
|
||||
@@ -169,6 +169,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
'project_id': 'fake',
|
||||
'bridge': 'br101',
|
||||
'image_ref': '123456',
|
||||
'local_gb': 20,
|
||||
'instance_type_id': '5'} # m1.small
|
||||
|
||||
def lazy_load_library_exists(self):
|
||||
@@ -744,6 +745,42 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
ip = conn.get_host_ip_addr()
|
||||
self.assertEquals(ip, FLAGS.my_ip)
|
||||
|
||||
def test_volume_in_mapping(self):
|
||||
conn = connection.LibvirtConnection(False)
|
||||
swap = {'device_name': '/dev/sdb',
|
||||
'swap_size': 1}
|
||||
ephemerals = [{'num': 0,
|
||||
'virtual_name': 'ephemeral0',
|
||||
'device_name': '/dev/sdc1',
|
||||
'size': 1},
|
||||
{'num': 2,
|
||||
'virtual_name': 'ephemeral2',
|
||||
'device_name': '/dev/sdd',
|
||||
'size': 1}]
|
||||
block_device_mapping = [{'mount_device': '/dev/sde',
|
||||
'device_path': 'fake_device'},
|
||||
{'mount_device': '/dev/sdf',
|
||||
'device_path': 'fake_device'}]
|
||||
block_device_info = {
|
||||
'root_device_name': '/dev/sda',
|
||||
'swap': swap,
|
||||
'ephemerals': ephemerals,
|
||||
'block_device_mapping': block_device_mapping}
|
||||
|
||||
def _assert_volume_in_mapping(device_name, true_or_false):
|
||||
self.assertEquals(conn._volume_in_mapping(device_name,
|
||||
block_device_info),
|
||||
true_or_false)
|
||||
|
||||
_assert_volume_in_mapping('sda', False)
|
||||
_assert_volume_in_mapping('sdb', True)
|
||||
_assert_volume_in_mapping('sdc1', True)
|
||||
_assert_volume_in_mapping('sdd', True)
|
||||
_assert_volume_in_mapping('sde', True)
|
||||
_assert_volume_in_mapping('sdf', True)
|
||||
_assert_volume_in_mapping('sdg', False)
|
||||
_assert_volume_in_mapping('sdh1', False)
|
||||
|
||||
|
||||
class NWFilterFakes:
|
||||
def __init__(self):
|
||||
|
||||
83
nova/tests/test_virt.py
Normal file
83
nova/tests/test_virt.py
Normal file
@@ -0,0 +1,83 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 Isaku Yamahata
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova import flags
|
||||
from nova import test
|
||||
from nova.virt import driver
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
|
||||
class TestVirtDriver(test.TestCase):
|
||||
def test_block_device(self):
|
||||
swap = {'device_name': '/dev/sdb',
|
||||
'swap_size': 1}
|
||||
ephemerals = [{'num': 0,
|
||||
'virtual_name': 'ephemeral0',
|
||||
'device_name': '/dev/sdc1',
|
||||
'size': 1}]
|
||||
block_device_mapping = [{'mount_device': '/dev/sde',
|
||||
'device_path': 'fake_device'}]
|
||||
block_device_info = {
|
||||
'root_device_name': '/dev/sda',
|
||||
'swap': swap,
|
||||
'ephemerals': ephemerals,
|
||||
'block_device_mapping': block_device_mapping}
|
||||
|
||||
empty_block_device_info = {}
|
||||
|
||||
self.assertEqual(
|
||||
driver.block_device_info_get_root(block_device_info), '/dev/sda')
|
||||
self.assertEqual(
|
||||
driver.block_device_info_get_root(empty_block_device_info), None)
|
||||
self.assertEqual(
|
||||
driver.block_device_info_get_root(None), None)
|
||||
|
||||
self.assertEqual(
|
||||
driver.block_device_info_get_swap(block_device_info), swap)
|
||||
self.assertEqual(driver.block_device_info_get_swap(
|
||||
empty_block_device_info)['device_name'], None)
|
||||
self.assertEqual(driver.block_device_info_get_swap(
|
||||
empty_block_device_info)['swap_size'], 0)
|
||||
self.assertEqual(
|
||||
driver.block_device_info_get_swap({'swap': None})['device_name'],
|
||||
None)
|
||||
self.assertEqual(
|
||||
driver.block_device_info_get_swap({'swap': None})['swap_size'],
|
||||
0)
|
||||
self.assertEqual(
|
||||
driver.block_device_info_get_swap(None)['device_name'], None)
|
||||
self.assertEqual(
|
||||
driver.block_device_info_get_swap(None)['swap_size'], 0)
|
||||
|
||||
self.assertEqual(
|
||||
driver.block_device_info_get_ephemerals(block_device_info),
|
||||
ephemerals)
|
||||
self.assertEqual(
|
||||
driver.block_device_info_get_ephemerals(empty_block_device_info),
|
||||
[])
|
||||
self.assertEqual(
|
||||
driver.block_device_info_get_ephemerals(None),
|
||||
[])
|
||||
|
||||
def test_swap_is_usable(self):
|
||||
self.assertFalse(driver.swap_is_usable(None))
|
||||
self.assertFalse(driver.swap_is_usable({'device_name': None}))
|
||||
self.assertFalse(driver.swap_is_usable({'device_name': '/dev/sdb',
|
||||
'swap_size': 0}))
|
||||
self.assertTrue(driver.swap_is_usable({'device_name': '/dev/sdb',
|
||||
'swap_size': 1}))
|
||||
Reference in New Issue
Block a user